Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

handle apex domain through gandi ALIAS #3855

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

tommy31
Copy link
Contributor

@tommy31 tommy31 commented Aug 10, 2023

Description

This PR allow gandi provider to redirect apex domain to an FQDN.

From my understanding, CNAME record only can be used for subdomains and external-dns force CNAME if record value is an FQDN. To fill this gap some DNS provider introduce a new record type ALIAS. ALIAS record is a type of DNS record that points your domain name to a hostname instead of an IP address. The ALIAS record is similar to a CNAME record, which is used to point subdomains to a hostname. This allow us to register a record an apex domain @ with a FQDN.

So back on this PR, the fix convert an CNAME to an ALIAS, if the record.RrsetName == "@" and record.RrsetType == "CNAME". And env var (GANDI_PREFER_ALIAS) has been added to keep old things working as expected.

What Are ALIAS Records?

This fix has been tested in our preproduction environment and work as expected.

Checklist

  • Unit tests updated
  • End user documentation updated

@k8s-ci-robot k8s-ci-robot added the cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. label Aug 10, 2023
@k8s-ci-robot k8s-ci-robot added the needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. label Aug 10, 2023
@k8s-ci-robot
Copy link
Contributor

Hi @tommy31. Thanks for your PR.

I'm waiting for a kubernetes-sigs member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@k8s-ci-robot k8s-ci-robot added the size/L Denotes a PR that changes 100-499 lines, ignoring generated files. label Aug 10, 2023
@mloiseleur
Copy link
Contributor

Hello @tommy31,

Thanks for this PR. Alias seems tested.
This PR also introduces TXTPrefix & TXTSuffix support, shouldn't this be tested also ?

@tommy31
Copy link
Contributor Author

tommy31 commented Aug 11, 2023

Hey @mloiseleur, thank for reaching me.

TXTPrefix and TXTSuffix are only used in inferZone function, to infer requested zone by removing prefix and suffix from TXT record name. Usage should be trivial.

// inferZone determines the zone based on the RrsetName
func inferZone(RrsetName string, TXTPrefix string, TXTSuffix string) string {
	cleanRrsetName := strings.Replace(RrsetName, TXTPrefix, "", 1)
	cleanRrsetName = strings.Replace(cleanRrsetName, TXTSuffix, "", 1)
	cleanRrsetName = strings.Replace(cleanRrsetName, "cname-", "", 1)

	return cleanRrsetName
} 

To better answer your question, of course we should add more tests, but my understanding of gandi_test.go... is near 0.

Maybe you could help as gandi provider miss mainteners.

Copy link
Contributor

@johngmyers johngmyers left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might want to take a look at how the AWS provider handles aliases, with providerSpecificAlias and the external-dns.alpha.kubernetes.io/alias annotation.

sharingID, _ := os.LookupEnv("GANDI_SHARING_ID")
_, PreferALIAS := os.LookupEnv("GANDI_PREFER_ALIAS")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we taking configuration from environment variables? Shouldn't we be using the flags mechanism that everything else uses?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "PREFER_ALIAS" config was added to be "retro-compatible" with previous behaviour - which is to fail and raise an error. If it's alright we'd like to get rid of this config altogether and use the "CNAME is an ALIAS in gandi" feature by default
(I'll be working on this PR with @tommy31 - thanks for your review!)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated in 2892142 - the fixed behaviour is now the default, and we stopped using an extra environment variable for this


// isGandiAlias determines if a given endpoint is supposed to create an Gandi Alias record
func isGandiAlias(r livedns.DomainRecord, preferALIAS bool) bool {
return preferALIAS && r.RrsetType == RecordTypeALIAS
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does the setting of preferAlias affect whether an existing DomainRecord is an alias?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we removed the "prefer alias" mechanism, I think this is no longer an issue?

@@ -113,16 +151,24 @@ func (p *GandiProvider) Records(ctx context.Context) ([]*endpoint.Endpoint, erro
}

for _, r := range records {
if isGandiAlias(r, p.PreferALIAS) {
// Convert back ALIAS to CNAME
r.RrsetType = endpoint.RecordTypeCNAME
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this set a provider-specific property to indicate the underlying record is an alias?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is already manipulating a provider-specific object - Gandi's livedns.DomainRecord

Do you think this should be set before in the endpoint.ProviderSpecificProperty prop and reused later?

Comment on lines 64 to 67
func inferZone(RrsetName string, TXTPrefix string, TXTSuffix string) string {
cleanRrsetName := strings.Replace(RrsetName, TXTPrefix, "", 1)
cleanRrsetName = strings.Replace(cleanRrsetName, TXTSuffix, "", 1)
cleanRrsetName = strings.Replace(cleanRrsetName, "cname-", "", 1)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This just screams layering violation to me. Why is the provider mucking about with things that are in the purview of the TXT registry? Why is this only removing a prefix of cname-?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There probably is a better way to do it but not sure how - the issue is that gandi's API requires us explicitly declare which "zone" the records we are manipulating are in.
When working on a CNAME on an apex domain, TXTRegistry creates the old and new txt records, with and without the type prefix. When we receive the endpoint with value cname-example.com 0 IN TXT \"heritage=external-dns,external-dns/owner=default\" [], we have no way to reliability find the zone without this kind of tomfoolery, do we?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have tried to improve this with 83a1fcd - I still feel like we have no better way to compute a "zone" from an Endpoint

We can spin this change in a new PR if you think it is necessary?

if change.Record.RrsetType == endpoint.RecordTypeCNAME && !strings.HasSuffix(change.Record.RrsetValues[0], ".") {
change.Record.RrsetValues[0] += "."
}

// Prepare record name
recordName := strings.TrimSuffix(change.Record.RrsetName, "."+change.ZoneName)
if recordName == change.ZoneName {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the zone is example.com and the change.Record.RrsetName is example.com.example.com, then this code will incorrectly replace recordName with @.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To reduce noise on this PR, I have fixed this in #3893

@k8s-ci-robot k8s-ci-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Sep 16, 2023
@gfaugere gfaugere force-pushed the feat/gandi_apex_domain branch from 83a1fcd to 8704636 Compare September 18, 2023 10:25
@linux-foundation-easycla
Copy link

linux-foundation-easycla bot commented Sep 18, 2023

CLA Signed

The committers listed above are authorized under a signed CLA.

  • ✅ login: gfaugere / name: Gaëtan Faugère (ff45612)

@k8s-ci-robot k8s-ci-robot added cncf-cla: no Indicates the PR's author has not signed the CNCF CLA. and removed cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. labels Sep 18, 2023
@gfaugere gfaugere force-pushed the feat/gandi_apex_domain branch from 8704636 to 84990a9 Compare September 18, 2023 10:35
@k8s-ci-robot k8s-ci-robot added cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. and removed cncf-cla: no Indicates the PR's author has not signed the CNCF CLA. labels Sep 18, 2023
@gfaugere
Copy link
Contributor

This has been updated with new tests following #3893 !

@mloiseleur
Copy link
Contributor

/ok-to-test

@k8s-ci-robot k8s-ci-robot added ok-to-test Indicates a non-member PR verified by an org member that is safe to test. and removed needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. labels Sep 18, 2023
Copy link
Contributor

@mloiseleur mloiseleur left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand from this PR that MX record type is not supported.
=> If that's the case, I guess you need to improve documentation about this.

For TXT registry, we are trying to fix it. See #3757 and #3774.
Wdyt about adding the zone at the end of the record when it's not here ?

@gfaugere
Copy link
Contributor

Regarding MX records, I think the current doc (https://github.com/kubernetes-sigs/external-dns/blob/master/docs/tutorials/mx-record.md) is clear enough about the providers that support this record type?

@gfaugere
Copy link
Contributor

gfaugere commented Sep 18, 2023

Thanks for your work on the TXT registry side! It is the only confusing thing about external-dns for me

I have added test cases (in 48e9d6d), I think we are handling them correctly?

@gfaugere
Copy link
Contributor

Wdyt about adding the zone at the end of the record when it's not here ?

During which actions? Not sure what you mean here

@mloiseleur
Copy link
Contributor

mloiseleur commented Sep 18, 2023

Wdyt about adding the zone at the end of the record when it's not here ?

During which actions? Not sure what you mean here

I agree with @johngmyers that we should try our best to avoid dependency between Txt Registry logic and provider logic.

Following this, adding Gandi constraints you described:

gandi's API requires us explicitly declare which "zone" the records we are manipulating are in.

The idea would be instead of adding the zone (L174)

				name := r.RrsetName + "." + zone

and removing it a few lines after if/when it comes from TXT registry.

Something like

  if ! strings.HasSuffix(r.RrsetName, zone) {
     r.RrsetName := r.RrsetName + "." + zone
  }

Without any need to check wheither it's coming from TXT Registry or not.

It seems quite a naive idea, so I'm unsure and I feel I missed something.

@gfaugere
Copy link
Contributor

You're right, this is hair-pulling for no benefits - I'll update this today to drop the prefix/suffix part

Should we mark this as holding for #3774? I feel like it is cleaner to wait for it to drop

@mloiseleur
Copy link
Contributor

/hold for #3774

@k8s-ci-robot k8s-ci-robot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Sep 22, 2023
@gfaugere gfaugere force-pushed the feat/gandi_apex_domain branch 2 times, most recently from 95003c4 to 53dbf49 Compare September 26, 2023 09:10
@k8s-ci-robot k8s-ci-robot added size/M Denotes a PR that changes 30-99 lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Sep 26, 2023
@gfaugere gfaugere force-pushed the feat/gandi_apex_domain branch from 53dbf49 to ff45612 Compare September 26, 2023 09:11
@mloiseleur
Copy link
Contributor

/lgtm

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Sep 26, 2023
@k8s-triage-robot
Copy link

The Kubernetes project currently lacks enough contributors to adequately respond to all PRs.

This bot triages PRs according to the following rules:

  • After 90d of inactivity, lifecycle/stale is applied
  • After 30d of inactivity since lifecycle/stale was applied, lifecycle/rotten is applied
  • After 30d of inactivity since lifecycle/rotten was applied, the PR is closed

You can:

  • Mark this PR as fresh with /remove-lifecycle stale
  • Close this PR with /close
  • Offer to help out with Issue Triage

Please send feedback to sig-contributor-experience at kubernetes/community.

/lifecycle stale

@k8s-ci-robot k8s-ci-robot added the lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. label Jan 21, 2024
@mloiseleur
Copy link
Contributor

/remove-lifecycle stale

@k8s-ci-robot k8s-ci-robot removed the lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. label Jan 22, 2024
@k8s-ci-robot k8s-ci-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Feb 28, 2024
@k8s-ci-robot
Copy link
Contributor

PR needs rebase.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@k8s-triage-robot
Copy link

The Kubernetes project currently lacks enough contributors to adequately respond to all PRs.

This bot triages PRs according to the following rules:

  • After 90d of inactivity, lifecycle/stale is applied
  • After 30d of inactivity since lifecycle/stale was applied, lifecycle/rotten is applied
  • After 30d of inactivity since lifecycle/rotten was applied, the PR is closed

You can:

  • Mark this PR as fresh with /remove-lifecycle stale
  • Close this PR with /close
  • Offer to help out with Issue Triage

Please send feedback to sig-contributor-experience at kubernetes/community.

/lifecycle stale

@k8s-ci-robot k8s-ci-robot added the lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. label May 28, 2024
@k8s-triage-robot
Copy link

The Kubernetes project currently lacks enough active contributors to adequately respond to all PRs.

This bot triages PRs according to the following rules:

  • After 90d of inactivity, lifecycle/stale is applied
  • After 30d of inactivity since lifecycle/stale was applied, lifecycle/rotten is applied
  • After 30d of inactivity since lifecycle/rotten was applied, the PR is closed

You can:

  • Mark this PR as fresh with /remove-lifecycle rotten
  • Close this PR with /close
  • Offer to help out with Issue Triage

Please send feedback to sig-contributor-experience at kubernetes/community.

/lifecycle rotten

@k8s-ci-robot k8s-ci-robot added lifecycle/rotten Denotes an issue or PR that has aged beyond stale and will be auto-closed. and removed lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. labels Jun 27, 2024
@k8s-triage-robot
Copy link

The Kubernetes project currently lacks enough active contributors to adequately respond to all issues and PRs.

This bot triages PRs according to the following rules:

  • After 90d of inactivity, lifecycle/stale is applied
  • After 30d of inactivity since lifecycle/stale was applied, lifecycle/rotten is applied
  • After 30d of inactivity since lifecycle/rotten was applied, the PR is closed

You can:

  • Reopen this PR with /reopen
  • Mark this PR as fresh with /remove-lifecycle rotten
  • Offer to help out with Issue Triage

Please send feedback to sig-contributor-experience at kubernetes/community.

/close

@k8s-ci-robot
Copy link
Contributor

@k8s-triage-robot: Closed this PR.

In response to this:

The Kubernetes project currently lacks enough active contributors to adequately respond to all issues and PRs.

This bot triages PRs according to the following rules:

  • After 90d of inactivity, lifecycle/stale is applied
  • After 30d of inactivity since lifecycle/stale was applied, lifecycle/rotten is applied
  • After 30d of inactivity since lifecycle/rotten was applied, the PR is closed

You can:

  • Reopen this PR with /reopen
  • Mark this PR as fresh with /remove-lifecycle rotten
  • Offer to help out with Issue Triage

Please send feedback to sig-contributor-experience at kubernetes/community.

/close

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@tommy31
Copy link
Contributor Author

tommy31 commented Dec 6, 2024

Can we reopen this PR ? As we still wait for #3774

@mloiseleur
Copy link
Contributor

/reopen

@k8s-ci-robot k8s-ci-robot reopened this Dec 6, 2024
@k8s-ci-robot
Copy link
Contributor

@mloiseleur: Reopened this PR.

In response to this:

/reopen

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please ask for approval from mloiseleur. For more information see the Kubernetes Code Review Process.

The full list of commands accepted by this bot can be found here.

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. lgtm "Looks good to me", indicates that a PR is ready to be merged. lifecycle/rotten Denotes an issue or PR that has aged beyond stale and will be auto-closed. needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. ok-to-test Indicates a non-member PR verified by an org member that is safe to test. size/M Denotes a PR that changes 30-99 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants