-
Notifications
You must be signed in to change notification settings - Fork 2.8k
feat(aws): add aws/alias-disable-a and aws/alias-disable-aaaa provider-specific options #5997
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
base: master
Are you sure you want to change the base?
Conversation
…r-specific options) Signed-off-by: u-kai <[email protected]>
|
Hi @u-kai. Thanks for your PR. I'm waiting for a github.com member to verify that this patch is reasonable to test. If it is, they should reply with Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. DetailsInstructions 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. |
|
@u-kai thanks for this interesting PR. Wdyt of re-use existing annotation, It could be configurable like this :
|
|
@mloiseleur |
|
/ok-to-test |
Pull Request Test Coverage Report for Build 20000357394Warning: This coverage report may be inaccurate.This pull request's base commit is no longer the HEAD commit of its target branch. This means it includes changes from outside the original pull request, including, potentially, unrelated coverage changes.
Details
💛 - Coveralls |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Documentation with use cases for this properties is missing, and how it was tested on a real cluster
| return endpoints, nil | ||
| } | ||
|
|
||
| func aliasDisableARecord(ep *endpoint.Endpoint) bool { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My opinion, we will benefit to have a generic,centralised method on Endpoint object for all annotations that contains booleans like true/false
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
something like
func (ep *endpoint.Endpoint) GetProviderSpecificBool(key string bool) bool {
val, ok := ep.GetProviderSpecificProperty(key)
if !ok {
return false
}
// Normalize whitespace and case; accept common truthy values
v := strings.TrimSpace(strings.ToLower(val))
switch v {
case "1", "t", "true", "yes", "y":
return true
case "0", "f", "false", "no", "n":
return false
default:
return false
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That does sound like a good idea.
However, in this change we’re going to use values other than just true/false, as @mloiseleur mentioned, and I’m a bit concerned that introducing a generic, centralized method here would make the scope of this PR too large.
I’d prefer to handle that refactor in a separate PR that can apply the change across the whole codebase. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok
|
While creating comprehensive tests for supporting annotations like Should I include this fix in this PR, or would it be better to submit it as a separate PR? Discovered IssueWhen a ProviderSpecific property
Reproductionep := &endpoint.Endpoint{
RecordType: endpoint.RecordTypeMX,
RecordTTL: 600,
ProviderSpecific: endpoint.ProviderSpecific{
{Name: "alias", Value: "true"},
},
}
// Expected: TTL=600, ProviderSpecific=empty
// But result is: TTL=300, evaluateTargetHealth=false gets added
While this affects cases with incorrectly configured ProviderSpecific properties, I believe the behavior should be consistent. |
It's better as a separate PR. It's easier to review & test this way. |
|
I’ve submitted the fix in a separate PR here: #6017. |
|
Refactoring, bug fixes, new features - all should be in they own PRs. We are trying to de-resk releases. Way too many issues opened ;-) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No update to:
- docs/tutorials/aws.md
- docs/examples/aws.md
This should include:
New provider-specific annotations:
external-dns.alpha.kubernetes.io/aws-alias-disable-a: "true"
external-dns.alpha.kubernetes.io/aws-alias-disable-aaaa: "true"
or
external-dns.alpha.kubernetes.io/alias-disable-a: "true"
external-dns.alpha.kubernetes.io/alias-disable-aaaa: "true"And more important, what are the use cases, as at the moment this is just added annotation for no reasons
| } | ||
| if enableAandAAAA { | ||
| // Add a new endpoint for the AAAA record | ||
| aliasCnameAaaaEndpoints = append(aliasCnameAaaaEndpoints, &endpoint.Endpoint{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make sure not to use &endpoint.Endpoint{}, but methods available in the package. This will create tech debt for us.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd say it should be clone or similar function in Endpoint package, to make sure we do not mutate original
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
aEp := ep.DeepCopy()
|
|
||
| func aliasDisableARecord(ep *endpoint.Endpoint) bool { | ||
| disable, ok := ep.GetProviderSpecificProperty(providerSpecificAliasDisableA) | ||
| return ok && disable == "true" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use constants instead of strings for "true".
| disableAlias := disableA && disableAaaa | ||
| enableAandAAAA := !disableA && !disableAaaa | ||
|
|
||
| if ep.RecordType == endpoint.RecordTypeCNAME && !disableAlias { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something does not sound here. This most likely could and should be a method on it's own, so we could add tests just for this method
something like
log.Debugf("Modifying endpoint: %v, changing record type from %s to %s", ep, ....)
if ep.RecordType == endpoint.RecordTypeCNAME && strings.CutPrefix(k, disableAliasPrefix) {
epModified = .....modify me...
or
epC = ep.DeepCopy()
epC.RecordType = modifyMe(......)
}
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
I'm unsure how big is the problem. At the moment this change affects only AWS. It could be that same behaviour is relevant for other providers as well. In such case we could have annotation without a provider prefix, and modify type in post processor wrapper https://github.com/kubernetes-sigs/external-dns/blob/master/source/wrappers/post_processor.go |
I'm not sure about 4 state solution, need to double check. Same time this feets wrapper case, so it should not be in |
|
Would be nice to get some sort of mermaid diagram https://mermaid.live/edit or similar before and after change behavoir hightlight. |
|
My understanding is that alias itself is an AWS-specific feature. Given that, I think it’s worth taking a step back and clarifying |
|
I spent some time reading through the codebase, and my current understanding is:
Given these trade-offs, I think it’s not obvious what the right approach is here yet. To make the trade-offs more explicit, here is how I see the current vs desired dependency graph: Current flowchart LR
EndpointPkg["endpoint package
(provider-agnostic)"]
TxtRegistry["registry/txt
(TXT Registry)"]
AwsProvider["provider/aws
(AWS provider)"]
ProviderIface["provider interface"]
%% code dependencies (imports)
TxtRegistry -->|depends on| EndpointPkg
TxtRegistry -->|depends on| ProviderIface
AwsProvider -->|depends on| ProviderIface
AwsProvider -->|depends on| EndpointPkg
%% problematic knowledge leak
TxtRegistry -->|knows AWS alias semantics| AwsProvider
%% emphasis
TxtRegistry:::problem
My desired flowchart LR
EndpointPkg["endpoint package
(provider-agnostic)"]
TxtRegistry["registry/txt
(TXT Registry)"]
AwsProvider["provider/aws
(AWS provider)"]
ProviderIface["provider interface"]
%% code dependencies (imports)
TxtRegistry -->|depends on| EndpointPkg
TxtRegistry -->|depends on| ProviderIface
AwsProvider -->|depends on| ProviderIface
AwsProvider -->|depends on| EndpointPkg
|
|
Personally, even if it takes time, I’d like to focus on eventually removing |
Not sure. I thought very same concept is at least in GCP and Azure. Major clouds mirroring this functionality. |
|
Keep digging. This is definately one of those designs that needs a resolution at some point. How easy is to find a solution, hard to say. |
I’m not seeing this reflected in the ExternalDNS codebase. Alias-like semantics appear to be implemented only in the AWS provider, If there’s a concrete example I’m missing, could you point me to it? |
What does it do ?
Fixes: #5815
This PR adds support for selective control over A and AAAA alias record creation in the AWS Route53 provider through two new
ProviderSpecificannotations:aws/alias-disable-a: "true"- prevents creation of A alias recordsaws/alias-disable-aaaa: "true"- prevents creation of AAAA alias recordsWhen a CNAME endpoint creates alias records, external-dns automatically creates both A and AAAA alias records by default. These new annotations allow users to disable specific record types on a per-endpoint basis, providing granular control without affecting other DNS records.
Motivation
Issue #5815 requested the ability to selectively disable AAAA alias records for specific use cases. Currently, the only option is the global
--exclude-record-types=AAAAflag, which affects all records across all providers.This feature is particularly important for same-zone alias records where CNAME endpoints point to other records within the same hosted zone. While AWS managed services (like ELBs, CloudFront) typically support both IPv4 and IPv6, custom applications and services within the same zone often have different connectivity requirements.
Unlike AWS managed resources which are generally dual-stack capable, user-managed records in the same zone frequently have single-stack limitations, making this granular control essential for proper DNS configuration.
This enhancement provides the targeted control needed for these scenarios while maintaining full backward compatibility.
More