feat(aws): always create AAAA alias records in route53 (#5111)

* First pass based on existing PR, what is currently on master and some
extra tests.

* Try to resolve AWS service documentation

* Add documentation on how to opt-out of AAAA record creation

* Address documentation concerns

* Add some IPv6 tests to sources

* Make recommended changes to documentation
This commit is contained in:
Rich 2025-03-03 08:21:00 +00:00 committed by GitHub
parent d4a66bdb66
commit 7c23e01e31
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 455 additions and 312 deletions

View File

@ -83,19 +83,18 @@ The targets from each parent Gateway matching the \*Route are then combined and
## Dualstack Routes
Gateway resources may be served from an external-loadbalancer which may support both IPv4 and "dualstack" (both IPv4 and IPv6) interfaces.
External DNS Controller uses the `external-dns.alpha.kubernetes.io/dualstack` annotation to determine this. If this annotation is
set to `true` then ExternalDNS will create two records (one A record
and one AAAA record) for each hostname associated with the Route resource.
Gateway resources may be served from an external-loadbalancer which may support
both IPv4 and "dualstack" (both IPv4 and IPv6) interfaces. When using the AWS
Route53 provider, External DNS Controller will always create both A and AAAA
alias DNS records by default, regardless of whether the load balancer is dual
stack or not.
Example:
## Example
```yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
annotations:
external-dns.alpha.kubernetes.io/dualstack: "true"
name: echo
spec:
hostnames:
@ -112,7 +111,3 @@ spec:
type: PathPrefix
value: /echo
```
The above HTTPRoute resource is backed by a dualstack Gateway.
ExternalDNS will create both an A `echoserver.example.org` record and
an AAAA record of the same name, that each are aliases for the same LB.

View File

@ -101,11 +101,17 @@ spec:
The above should result in the creation of an (ipv4) ALB in AWS which will forward
traffic to the echoserver application.
If the `source=ingress` argument is specified, then ExternalDNS will create DNS
records based on the hosts specified in ingress objects. The above example would
result in two alias records being created, `echoserver.mycluster.example.org` and
`echoserver.example.org`, which both alias the ALB that is associated with the
Ingress object.
If the `--source=ingress` argument is specified, then ExternalDNS will create
DNS records based on the hosts specified in ingress objects. The above example
would result in two alias records (A and AAAA) being created for each of the
domains: `echoserver.mycluster.example.org` and `echoserver.example.org`. All
four records alias the ALB that is associated with the Ingress object. As the
ALB is IPv4 only, the AAAA alias records have no effect.
If you would like ExternalDNS to not create AAAA records at all, you can add the
following command line parameter: `--exclude-record-types=AAAA`. Please be
aware, this will disable AAAA record creation even for dualstack enabled load
balancers.
Note that the above example makes use of the YAML anchor feature to avoid having
to repeat the http section for multiple hosts that use the exact same paths. If
@ -138,15 +144,17 @@ In the above example we create a default path that works for any hostname, and
make use of the `external-dns.alpha.kubernetes.io/hostname` annotation to create
multiple aliases for the resulting ALB.
## Dualstack ALBs
## Dualstack Load Balancers
AWS [supports][4] both IPv4 and "dualstack" (both IPv4 and IPv6) interfaces for ALBs.
The AWS Load Balancer Controller uses the `alb.ingress.kubernetes.io/ip-address-type`
annotation (which defaults to `ipv4`) to determine this. If this annotation is
set to `dualstack` then ExternalDNS will create two alias records (one A record
and one AAAA record) for each hostname associated with the Ingress object.
AWS [supports both IPv4 and "dualstack" (both IPv4 and IPv6) interfaces for ALBs][4]
and [NLBs][5]. The AWS Load Balancer Controller uses the `alb.ingress.kubernetes.io/ip-address-type`
annotation (which defaults to `ipv4`) to determine this. ExternalDNS creates
both A and AAAA alias DNS records by default, regardless of this annotation.
It's possible to create only A records with the following command line
parameter: `--exclude-record-types=AAAA`
[4]: https://docs.aws.amazon.com/elasticloadbalancing/latest/application/application-load-balancers.html#ip-address-type
[5]: https://docs.aws.amazon.com/elasticloadbalancing/latest/network/network-load-balancers.html#ip-address-type
Example:
@ -174,5 +182,4 @@ spec:
```
The above Ingress object will result in the creation of an ALB with a dualstack
interface. ExternalDNS will create both an A `echoserver.example.org` record and
an AAAA record of the same name, that each are aliases for the same ALB.
interface.

View File

@ -536,7 +536,7 @@ Annotations which are specific to AWS.
### alias
`external-dns.alpha.kubernetes.io/alias` if set to `true` on an ingress, it will create an ALIAS record when the target is an ALIAS as well.
`external-dns.alpha.kubernetes.io/alias` if set to `true` on an ingress, it will create two ALIAS records (one 'A' for IPv4 and one 'AAAA' for IPv6) when the target is an ALIAS as well.
To make the target an alias, the ingress needs to be configured correctly as described in [the docs](./gke-nginx.md#with-a-separate-tcp-load-balancer).
In particular, the argument `--publish-service=default/nginx-ingress-controller` has to be set on the `nginx-ingress-controller` container.
If one uses the `nginx-ingress` Helm chart, this flag can be set with the `controller.publishService.enabled` configuration option.
@ -650,6 +650,32 @@ This should show something like:
]
```
Or for IPv6 (AAAA) records:
```bash
aws route53 list-resource-record-sets --output json --hosted-zone-id $ZONE_ID \
--query "ResourceRecordSets[?Name == 'nginx.example.com.']|[?Type == 'AAAA']"
```
This should show something like:
```json
[
{
"Name": "nginx.example.com.",
"Type": "AAAA",
"AliasTarget": {
"HostedZoneId": "ZEWFWZ4R16P7IB",
"DNSName": "ae11c2360188411e7951602725593fd1-1224345803.eu-central-1.elb.amazonaws.com.",
"EvaluateTargetHealth": true
}
}
]
```
IPv6 (AAAA) records are created when ALIAS is enabled even for load balancers that do not have dualstack enabled.
However, Route53 returns empty sets when querying such records, meaning they are harmless and IPv4 will work as normal.
You can also fetch the corresponding text records:
```bash
@ -674,9 +700,9 @@ This will show something like:
]
```
Note created TXT record alongside ALIAS record. TXT record signifies that the corresponding ALIAS record is managed by ExternalDNS. This makes ExternalDNS safe for running in environments where there are other records managed via other means.
Note created TXT record alongside ALIAS records. TXT record signifies that the corresponding ALIAS records are managed by ExternalDNS. This makes ExternalDNS safe for running in environments where there are other records managed via other means.
For more information about ALIAS record, see [Choosing between alias and non-alias records](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resource-record-sets-choosing-alias-non-alias.html).
For more information about ALIAS records, see [Choosing between alias and non-alias records](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resource-record-sets-choosing-alias-non-alias.html).
Let's check that we can resolve this DNS name. We'll ask the nameservers assigned to your zone first.
@ -876,6 +902,11 @@ env:
The DynamoDB Registry can be used to store dns records metadata. See the [DynamoDB Registry Tutorial](../registry/dynamodb.md) for more information.
## Disable AAAA Record Creation
If you would like ExternalDNS to not create AAAA records at all, you can add the following command line parameter: `--exclude-record-types=AAAA`.
Please be aware, this will disable AAAA record creation even for dualstack enabled load balancers.
## Clean up
Make sure to delete all Service objects before terminating the cluster so all load balancers get cleaned up correctly.

View File

@ -161,11 +161,17 @@ spec:
The above should result in the creation of an (ipv4) ALB in AWS which will forward
traffic to skipper which will forward to the echoserver application.
If the `--source=ingress` argument is specified, then ExternalDNS will create DNS
records based on the hosts specified in ingress objects. The above example would
result in two alias records being created, `echoserver.mycluster.example.org` and
`echoserver.example.org`, which both alias the ALB that is associated with the
Ingress object.
If the `--source=ingress` argument is specified, then ExternalDNS will create
DNS records based on the hosts specified in ingress objects. The above example
would result in two alias records (A and AAAA) being created for each of the
domains: `echoserver.mycluster.example.org` and `echoserver.example.org`. All
four records alias the ALB that is associated with the Ingress object. As the
ALB is IPv4 only, the AAAA alias records have no effect.
If you would like ExternalDNS to not create AAAA records at all, you can add the
following command line parameter: `--exclude-record-types=AAAA`. Please be
aware, this will disable AAAA record creation even for dualstack enabled load
balancers.
Note that the above example makes use of the YAML anchor feature to avoid having
to repeat the http section for multiple hosts that use the exact same paths. If
@ -197,42 +203,6 @@ In the above example we create a default path that works for any hostname, and
make use of the `external-dns.alpha.kubernetes.io/hostname` annotation to create
multiple aliases for the resulting ALB.
## Dualstack ALBs
AWS [supports](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/application-load-balancers.html#ip-address-type) both IPv4 and "dualstack" (both IPv4 and IPv6) interfaces for ALBs.
The Kubernetes Ingress AWS controller supports the `alb.ingress.kubernetes.io/ip-address-type`
annotation (which defaults to `ipv4`) to determine this. If this annotation is
set to `dualstack` then ExternalDNS will create two alias records (one A record
and one AAAA record) for each hostname associated with the Ingress object.
Example:
```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
alb.ingress.kubernetes.io/ip-address-type: dualstack
name: echoserver
spec:
ingressClassName: skipper
rules:
- host: echoserver.example.org
http:
paths:
- path: /
backend:
service:
name: echoserver
port:
number: 80
pathType: Prefix
```
The above Ingress object will result in the creation of an ALB with a dualstack
interface. ExternalDNS will create both an A `echoserver.example.org` record and
an AAAA record of the same name, that each are aliases for the same ALB.
## NLBs
AWS has
@ -277,8 +247,48 @@ status:
- hostname: kube-ing-lb-atedkrlml7iu-1681027139.$region.elb.amazonaws.com
```
ExternalDNS will create a A-records `echoserver.example.org`, that
use AWS ALIAS record to automatically maintain IP addresses of the NLB.
ExternalDNS will create A and AAAA alias records for: `echoserver.example.org`.
ExternalDNS will use these alias records to automatically maintain IP addresses
of the NLB.
## Dualstack Load Balancers
AWS [supports both IPv4 and "dualstack" (both IPv4 and IPv6) interfaces for ALBs][5]
and [NLBs][6]. The Kubernetes Ingress AWS controller supports the `alb.ingress.kubernetes.io/ip-address-type`
annotation (which defaults to `ipv4`) to determine this. ExternalDNS creates
both A and AAAA alias DNS records by default, regardless of this annotation.
It's possible to create only A records with the following command line
parameter: `--exclude-record-types=AAAA`
[5]: https://docs.aws.amazon.com/elasticloadbalancing/latest/application/application-load-balancers.html#ip-address-type
[6]: https://docs.aws.amazon.com/elasticloadbalancing/latest/network/network-load-balancers.html#ip-address-type
Example:
```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
alb.ingress.kubernetes.io/ip-address-type: dualstack
name: echoserver
spec:
ingressClassName: skipper
rules:
- host: echoserver.example.org
http:
paths:
- path: /
backend:
service:
name: echoserver
port:
number: 80
pathType: Prefix
```
The above Ingress object will result in the creation of an ALB with a dualstack
interface.
## RouteGroup (optional)

View File

@ -41,9 +41,6 @@ const (
// supposed to be inserted by AWS SD Provider, and parsed into OwnerLabelKey and ResourceLabelKey key by AWS SD Registry
AWSSDDescriptionLabel = "aws-sd-description"
// DualstackLabelKey is the name of the label that identifies dualstack endpoints
DualstackLabelKey = "dualstack"
// txtEncryptionNonce label for keep same nonce for same txt records, for prevent different result of encryption for same txt record, it can cause issues for some providers
txtEncryptionNonce = "txt-encryption-nonce"
)

View File

@ -21,6 +21,7 @@ import (
"errors"
"fmt"
"regexp"
"slices"
"sort"
"strconv"
"strings"
@ -508,7 +509,7 @@ func (p *AWSProvider) records(ctx context.Context, zones map[string]*profiledZon
ttl = recordTTL
}
ep := endpoint.
NewEndpointWithTTL(name, endpoint.RecordTypeA, ttl, *r.AliasTarget.DNSName).
NewEndpointWithTTL(name, string(r.Type), ttl, *r.AliasTarget.DNSName).
WithProviderSpecific(providerSpecificEvaluateTargetHealth, fmt.Sprintf("%t", r.AliasTarget.EvaluateTargetHealth)).
WithProviderSpecific(providerSpecificAlias, "true")
newEndpoints = append(newEndpoints, ep)
@ -756,17 +757,8 @@ func (p *AWSProvider) newChanges(action route53types.ChangeAction, endpoints []*
changes := make(Route53Changes, 0, len(endpoints))
for _, endpoint := range endpoints {
change, dualstack := p.newChange(action, endpoint)
change := p.newChange(action, endpoint)
changes = append(changes, change)
if dualstack {
// make a copy of change, modify RRS type to AAAA, then add new change
rrs := *change.ResourceRecordSet
change2 := &Route53Change{
Change: route53types.Change{Action: change.Action, ResourceRecordSet: &rrs},
}
change2.ResourceRecordSet.Type = route53types.RRTypeAaaa
changes = append(changes, change2)
}
}
return changes
@ -778,13 +770,17 @@ func (p *AWSProvider) newChanges(action route53types.ChangeAction, endpoints []*
// Example: CNAME endpoints pointing to ELBs will have a `alias` provider-specific property
// added to match the endpoints generated from existing alias records in Route53.
func (p *AWSProvider) AdjustEndpoints(endpoints []*endpoint.Endpoint) ([]*endpoint.Endpoint, error) {
// Holds CNAME targets that we will treat as Alias records. Such records are
// hard coded to 'A' type aliases but we also need their 'AAAA' counterparts.
var aliasCnameAaaaEndpoints []*endpoint.Endpoint
for _, ep := range endpoints {
alias := false
if aliasString, ok := ep.GetProviderSpecificProperty(providerSpecificAlias); ok {
alias = aliasString == "true"
if alias {
if ep.RecordType != endpoint.RecordTypeA && ep.RecordType != endpoint.RecordTypeCNAME {
if !slices.Contains([]string{endpoint.RecordTypeA, endpoint.RecordTypeAAAA, endpoint.RecordTypeCNAME}, ep.RecordType) {
ep.DeleteProviderSpecificProperty(providerSpecificAlias)
}
} else {
@ -803,7 +799,6 @@ func (p *AWSProvider) AdjustEndpoints(endpoints []*endpoint.Endpoint) ([]*endpoi
}
if alias {
ep.RecordType = endpoint.RecordTypeA
if ep.RecordTTL.IsConfigured() {
log.Debugf("Modifying endpoint: %v, setting ttl=%v", ep, recordTTL)
ep.RecordTTL = recordTTL
@ -815,18 +810,35 @@ func (p *AWSProvider) AdjustEndpoints(endpoints []*endpoint.Endpoint) ([]*endpoi
} else {
ep.SetProviderSpecificProperty(providerSpecificEvaluateTargetHealth, strconv.FormatBool(p.evaluateTargetHealth))
}
if ep.RecordType == endpoint.RecordTypeCNAME {
// This needs to match two records from Route53, one alias for 'A' (IPv4)
// and one alias for 'AAAA' (IPv6).
aliasCnameAaaaEndpoints = append(aliasCnameAaaaEndpoints, &endpoint.Endpoint{
DNSName: ep.DNSName,
Targets: ep.Targets,
RecordType: endpoint.RecordTypeAAAA,
RecordTTL: ep.RecordTTL,
Labels: ep.Labels,
ProviderSpecific: ep.ProviderSpecific,
SetIdentifier: ep.SetIdentifier,
})
ep.RecordType = endpoint.RecordTypeA
}
} else {
ep.DeleteProviderSpecificProperty(providerSpecificEvaluateTargetHealth)
}
}
endpoints = append(endpoints, aliasCnameAaaaEndpoints...)
return endpoints, nil
}
// newChange returns a route53 Change and a boolean indicating if there should also be a change to a AAAA record
// newChange returns a route53 Change
// returned Change is based on the given record by the given action, e.g.
// action=ChangeActionCreate returns a change for creation of the record and
// action=ChangeActionDelete returns a change for deletion of the record.
func (p *AWSProvider) newChange(action route53types.ChangeAction, ep *endpoint.Endpoint) (*Route53Change, bool) {
func (p *AWSProvider) newChange(action route53types.ChangeAction, ep *endpoint.Endpoint) *Route53Change {
change := &Route53Change{
Change: route53types.Change{
Action: action,
@ -835,17 +847,12 @@ func (p *AWSProvider) newChange(action route53types.ChangeAction, ep *endpoint.E
},
},
}
dualstack := false
change.ResourceRecordSet.Type = route53types.RRType(ep.RecordType)
if targetHostedZone := isAWSAlias(ep); targetHostedZone != "" {
evalTargetHealth := p.evaluateTargetHealth
if prop, ok := ep.GetProviderSpecificProperty(providerSpecificEvaluateTargetHealth); ok {
evalTargetHealth = prop == "true"
}
// If the endpoint has a Dualstack label, append a change for AAAA record as well.
if val, ok := ep.Labels[endpoint.DualstackLabelKey]; ok {
dualstack = val == "true"
}
change.ResourceRecordSet.Type = route53types.RRTypeA
change.ResourceRecordSet.AliasTarget = &route53types.AliasTarget{
DNSName: aws.String(ep.Targets[0]),
HostedZoneId: aws.String(cleanZoneID(targetHostedZone)),
@ -854,7 +861,6 @@ func (p *AWSProvider) newChange(action route53types.ChangeAction, ep *endpoint.E
change.sizeBytes += len([]byte(ep.Targets[0]))
change.sizeValues += 1
} else {
change.ResourceRecordSet.Type = route53types.RRType(ep.RecordType)
if !ep.RecordTTL.IsConfigured() {
change.ResourceRecordSet.TTL = aws.Int64(recordTTL)
} else {
@ -926,7 +932,7 @@ func (p *AWSProvider) newChange(action route53types.ChangeAction, ep *endpoint.E
change.OwnedRecord = ownedRecord
}
return change, dualstack
return change
}
// searches for `changes` that are contained in `queue` and returns the `changes` separated by whether they were found in the queue (`foundChanges`) or not (`notFoundChanges`)
@ -1175,7 +1181,7 @@ func useAlias(ep *endpoint.Endpoint, preferCNAME bool) bool {
// and (if so) returns the target hosted zone ID
func isAWSAlias(ep *endpoint.Endpoint) string {
isAlias, exists := ep.GetProviderSpecificProperty(providerSpecificAlias)
if exists && isAlias == "true" && ep.RecordType == endpoint.RecordTypeA && len(ep.Targets) > 0 {
if exists && isAlias == "true" && slices.Contains([]string{endpoint.RecordTypeA, endpoint.RecordTypeAAAA}, ep.RecordType) && len(ep.Targets) > 0 {
// alias records can only point to canonical hosted zones (e.g. to ELBs) or other records in the same zone
if hostedZoneID, ok := ep.GetProviderSpecificProperty(providerSpecificTargetHostedZone); ok {

View File

@ -437,6 +437,16 @@ func TestAWSRecords(t *testing.T) {
HostedZoneId: aws.String("Z215JYRZR1TBD5"),
},
},
{
Name: aws.String(specialCharactersEscape("escape-%!s(<nil>)-codes-alias.zone-2.ext-dns-test-2.teapot.zalan.do.")),
Type: route53types.RRTypeAaaa,
TTL: aws.Int64(recordTTL),
AliasTarget: &route53types.AliasTarget{
DNSName: aws.String("escape-codes.eu-central-1.elb.amazonaws.com."),
EvaluateTargetHealth: false,
HostedZoneId: aws.String("Z215JYRZR1TBD5"),
},
},
{
Name: aws.String("list-test-alias.zone-1.ext-dns-test-2.teapot.zalan.do."),
Type: route53types.RRTypeA,
@ -446,6 +456,15 @@ func TestAWSRecords(t *testing.T) {
HostedZoneId: aws.String("Z215JYRZR1TBD5"),
},
},
{
Name: aws.String("list-test-alias.zone-1.ext-dns-test-2.teapot.zalan.do."),
Type: route53types.RRTypeAaaa,
AliasTarget: &route53types.AliasTarget{
DNSName: aws.String("foo.eu-central-1.elb.amazonaws.com."),
EvaluateTargetHealth: false,
HostedZoneId: aws.String("Z215JYRZR1TBD5"),
},
},
{
Name: aws.String("*.wildcard-test-alias.zone-1.ext-dns-test-2.teapot.zalan.do."),
Type: route53types.RRTypeA,
@ -455,6 +474,15 @@ func TestAWSRecords(t *testing.T) {
HostedZoneId: aws.String("Z215JYRZR1TBD5"),
},
},
{
Name: aws.String("*.wildcard-test-alias.zone-1.ext-dns-test-2.teapot.zalan.do."),
Type: route53types.RRTypeAaaa,
AliasTarget: &route53types.AliasTarget{
DNSName: aws.String("foo.eu-central-1.elb.amazonaws.com."),
EvaluateTargetHealth: false,
HostedZoneId: aws.String("Z215JYRZR1TBD5"),
},
},
{
Name: aws.String("list-test-alias-evaluate.zone-1.ext-dns-test-2.teapot.zalan.do."),
Type: route53types.RRTypeA,
@ -464,6 +492,15 @@ func TestAWSRecords(t *testing.T) {
HostedZoneId: aws.String("Z215JYRZR1TBD5"),
},
},
{
Name: aws.String("list-test-alias-evaluate.zone-1.ext-dns-test-2.teapot.zalan.do."),
Type: route53types.RRTypeAaaa,
AliasTarget: &route53types.AliasTarget{
DNSName: aws.String("foo.eu-central-1.elb.amazonaws.com."),
EvaluateTargetHealth: true,
HostedZoneId: aws.String("Z215JYRZR1TBD5"),
},
},
{
Name: aws.String("list-test-multiple.zone-1.ext-dns-test-2.teapot.zalan.do."),
Type: route53types.RRTypeA,
@ -582,9 +619,13 @@ func TestAWSRecords(t *testing.T) {
endpoint.NewEndpointWithTTL("escape-%!s(<nil>)-codes.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "example").WithProviderSpecific(providerSpecificAlias, "false"),
endpoint.NewEndpointWithTTL("escape-%!s(<nil>)-codes-a.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4"),
endpoint.NewEndpointWithTTL("escape-%!s(<nil>)-codes-alias.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "escape-codes.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "false").WithProviderSpecific(providerSpecificAlias, "true"),
endpoint.NewEndpointWithTTL("escape-%!s(<nil>)-codes-alias.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeAAAA, endpoint.TTL(recordTTL), "escape-codes.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "false").WithProviderSpecific(providerSpecificAlias, "true"),
endpoint.NewEndpointWithTTL("list-test-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "false").WithProviderSpecific(providerSpecificAlias, "true"),
endpoint.NewEndpointWithTTL("list-test-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeAAAA, endpoint.TTL(recordTTL), "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "false").WithProviderSpecific(providerSpecificAlias, "true"),
endpoint.NewEndpointWithTTL("*.wildcard-test-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "false").WithProviderSpecific(providerSpecificAlias, "true"),
endpoint.NewEndpointWithTTL("*.wildcard-test-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeAAAA, endpoint.TTL(recordTTL), "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "false").WithProviderSpecific(providerSpecificAlias, "true"),
endpoint.NewEndpointWithTTL("list-test-alias-evaluate.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "true").WithProviderSpecific(providerSpecificAlias, "true"),
endpoint.NewEndpointWithTTL("list-test-alias-evaluate.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeAAAA, endpoint.TTL(recordTTL), "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "true").WithProviderSpecific(providerSpecificAlias, "true"),
endpoint.NewEndpointWithTTL("list-test-multiple.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.8.8", "8.8.4.4"),
endpoint.NewEndpointWithTTL("prefix-*.wildcard.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeTXT, endpoint.TTL(recordTTL), "random"),
endpoint.NewEndpointWithTTL("weight-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4").WithSetIdentifier("test-set-1").WithProviderSpecific(providerSpecificWeight, "10"),
@ -624,6 +665,7 @@ func TestAWSAdjustEndpoints(t *testing.T) {
endpoint.NewEndpoint("a-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "8.8.8.8"),
endpoint.NewEndpoint("cname-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.example.com"),
endpoint.NewEndpointWithTTL("cname-test-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, 60, "alias-target.zone-2.ext-dns-test-2.teapot.zalan.do").WithProviderSpecific(providerSpecificAlias, "true"),
endpoint.NewEndpointWithTTL("cname-test-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeAAAA, 60, "alias-target.zone-2.ext-dns-test-2.teapot.zalan.do").WithProviderSpecific(providerSpecificAlias, "true"),
endpoint.NewEndpoint("cname-test-elb.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.eu-central-1.elb.amazonaws.com"),
endpoint.NewEndpoint("cname-test-elb-no-alias.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificAlias, "false"),
endpoint.NewEndpoint("cname-test-elb-no-eth.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "false"), // eth = evaluate target health
@ -637,10 +679,14 @@ func TestAWSAdjustEndpoints(t *testing.T) {
endpoint.NewEndpoint("a-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "8.8.8.8"),
endpoint.NewEndpoint("cname-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.example.com").WithProviderSpecific(providerSpecificAlias, "false"),
endpoint.NewEndpointWithTTL("cname-test-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, 300, "alias-target.zone-2.ext-dns-test-2.teapot.zalan.do").WithProviderSpecific(providerSpecificAlias, "true").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "true"),
endpoint.NewEndpointWithTTL("cname-test-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeAAAA, 300, "alias-target.zone-2.ext-dns-test-2.teapot.zalan.do").WithProviderSpecific(providerSpecificAlias, "true").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "true"),
endpoint.NewEndpoint("cname-test-elb.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificAlias, "true").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "true"),
endpoint.NewEndpoint("cname-test-elb.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeAAAA, "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificAlias, "true").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "true"),
endpoint.NewEndpoint("cname-test-elb-no-alias.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificAlias, "false"),
endpoint.NewEndpoint("cname-test-elb-no-eth.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificAlias, "true").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "false"), // eth = evaluate target health
endpoint.NewEndpoint("cname-test-elb-no-eth.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificAlias, "true").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "false"), // eth = evaluate target health
endpoint.NewEndpoint("cname-test-elb-no-eth.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeAAAA, "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificAlias, "true").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "false"), // eth = evaluate target health
endpoint.NewEndpoint("cname-test-elb-alias.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificAlias, "true").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "true"),
endpoint.NewEndpoint("cname-test-elb-alias.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeAAAA, "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificAlias, "true").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "true"),
})
}
@ -667,24 +713,48 @@ func TestAWSApplyChanges(t *testing.T) {
TTL: aws.Int64(recordTTL),
ResourceRecords: []route53types.ResourceRecord{{Value: aws.String("8.8.8.8")}},
},
{
Name: aws.String("update-test-aaaa.zone-1.ext-dns-test-2.teapot.zalan.do."),
Type: route53types.RRTypeAaaa,
TTL: aws.Int64(recordTTL),
ResourceRecords: []route53types.ResourceRecord{{Value: aws.String("2606:4700:4700::1111")}},
},
{
Name: aws.String("delete-test.zone-1.ext-dns-test-2.teapot.zalan.do."),
Type: route53types.RRTypeA,
TTL: aws.Int64(recordTTL),
ResourceRecords: []route53types.ResourceRecord{{Value: aws.String("8.8.8.8")}},
},
{
Name: aws.String("delete-test-aaaa.zone-1.ext-dns-test-2.teapot.zalan.do."),
Type: route53types.RRTypeAaaa,
TTL: aws.Int64(recordTTL),
ResourceRecords: []route53types.ResourceRecord{{Value: aws.String("2606:4700:4700::1111")}},
},
{
Name: aws.String("update-test.zone-2.ext-dns-test-2.teapot.zalan.do."),
Type: route53types.RRTypeA,
TTL: aws.Int64(recordTTL),
ResourceRecords: []route53types.ResourceRecord{{Value: aws.String("8.8.4.4")}},
},
{
Name: aws.String("update-test-aaaa.zone-2.ext-dns-test-2.teapot.zalan.do."),
Type: route53types.RRTypeAaaa,
TTL: aws.Int64(recordTTL),
ResourceRecords: []route53types.ResourceRecord{{Value: aws.String("2606:4700:4700::1001")}},
},
{
Name: aws.String("delete-test.zone-2.ext-dns-test-2.teapot.zalan.do."),
Type: route53types.RRTypeA,
TTL: aws.Int64(recordTTL),
ResourceRecords: []route53types.ResourceRecord{{Value: aws.String("8.8.4.4")}},
},
{
Name: aws.String("delete-test-aaaa.zone-2.ext-dns-test-2.teapot.zalan.do."),
Type: route53types.RRTypeAaaa,
TTL: aws.Int64(recordTTL),
ResourceRecords: []route53types.ResourceRecord{{Value: aws.String("2606:4700:4700::1001")}},
},
{
Name: aws.String("update-test-a-to-cname.zone-1.ext-dns-test-2.teapot.zalan.do."),
Type: route53types.RRTypeA,
@ -700,12 +770,39 @@ func TestAWSApplyChanges(t *testing.T) {
HostedZoneId: aws.String("Z215JYRZR1TBD5"),
},
},
{
Name: aws.String("update-test-alias-to-cname.zone-1.ext-dns-test-2.teapot.zalan.do."),
Type: route53types.RRTypeAaaa,
AliasTarget: &route53types.AliasTarget{
DNSName: aws.String("foo.eu-central-1.elb.amazonaws.com."),
EvaluateTargetHealth: true,
HostedZoneId: aws.String("Z215JYRZR1TBD5"),
},
},
{
Name: aws.String("update-test-cname.zone-1.ext-dns-test-2.teapot.zalan.do."),
Type: route53types.RRTypeCname,
TTL: aws.Int64(recordTTL),
ResourceRecords: []route53types.ResourceRecord{{Value: aws.String("bar.elb.amazonaws.com")}},
},
{
Name: aws.String("update-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do."),
Type: route53types.RRTypeA,
AliasTarget: &route53types.AliasTarget{
DNSName: aws.String("bar.elb.amazonaws.com."),
EvaluateTargetHealth: true,
HostedZoneId: aws.String("Z215JYRZR1TBD5"),
},
},
{
Name: aws.String("update-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do."),
Type: route53types.RRTypeAaaa,
AliasTarget: &route53types.AliasTarget{
DNSName: aws.String("bar.elb.amazonaws.com."),
EvaluateTargetHealth: true,
HostedZoneId: aws.String("Z215JYRZR1TBD5"),
},
},
{
Name: aws.String("delete-test-cname.zone-1.ext-dns-test-2.teapot.zalan.do."),
Type: route53types.RRTypeCname,
@ -713,16 +810,22 @@ func TestAWSApplyChanges(t *testing.T) {
ResourceRecords: []route53types.ResourceRecord{{Value: aws.String("qux.elb.amazonaws.com")}},
},
{
Name: aws.String("update-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do."),
Type: route53types.RRTypeCname,
TTL: aws.Int64(recordTTL),
ResourceRecords: []route53types.ResourceRecord{{Value: aws.String("bar.elb.amazonaws.com")}},
Name: aws.String("delete-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do."),
Type: route53types.RRTypeA,
AliasTarget: &route53types.AliasTarget{
DNSName: aws.String("qux.elb.amazonaws.com."),
EvaluateTargetHealth: true,
HostedZoneId: aws.String("Z215JYRZR1TBD5"),
},
},
{
Name: aws.String("delete-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do."),
Type: route53types.RRTypeCname,
TTL: aws.Int64(recordTTL),
ResourceRecords: []route53types.ResourceRecord{{Value: aws.String("qux.elb.amazonaws.com")}},
Name: aws.String("delete-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do."),
Type: route53types.RRTypeAaaa,
AliasTarget: &route53types.AliasTarget{
DNSName: aws.String("qux.elb.amazonaws.com."),
EvaluateTargetHealth: true,
HostedZoneId: aws.String("Z215JYRZR1TBD5"),
},
},
{
Name: aws.String("update-test-multiple.zone-2.ext-dns-test-2.teapot.zalan.do."),
@ -736,6 +839,12 @@ func TestAWSApplyChanges(t *testing.T) {
TTL: aws.Int64(recordTTL),
ResourceRecords: []route53types.ResourceRecord{{Value: aws.String("1.2.3.4")}, {Value: aws.String("4.3.2.1")}},
},
{
Name: aws.String("delete-test-multiple-aaaa.zone-2.ext-dns-test-2.teapot.zalan.do."),
Type: route53types.RRTypeAaaa,
TTL: aws.Int64(recordTTL),
ResourceRecords: []route53types.ResourceRecord{{Value: aws.String("2606:4700:4700::1111")}, {Value: aws.String("2606:4700:4700::1001")}},
},
{
Name: aws.String("weighted-to-simple.zone-1.ext-dns-test-2.teapot.zalan.do."),
Type: route53types.RRTypeA,
@ -799,20 +908,28 @@ func TestAWSApplyChanges(t *testing.T) {
createRecords := []*endpoint.Endpoint{
endpoint.NewEndpoint("create-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "8.8.8.8"),
endpoint.NewEndpoint("create-test.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "8.8.4.4"),
endpoint.NewEndpoint("create-test-aaaa.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeAAAA, "2606:4700:4700::1111"),
endpoint.NewEndpoint("create-test-aaaa.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeAAAA, "2606:4700:4700::1001"),
endpoint.NewEndpoint("create-test-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.elb.amazonaws.com"),
endpoint.NewEndpoint("create-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.elb.amazonaws.com"),
endpoint.NewEndpoint("create-test-multiple.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "8.8.8.8", "8.8.4.4"),
endpoint.NewEndpoint("create-test-multiple-aaaa.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeAAAA, "2606:4700:4700::1111", "2606:4700:4700::1001"),
endpoint.NewEndpoint("create-test-mx.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeMX, "10 mailhost1.foo.elb.amazonaws.com"),
}
currentRecords := []*endpoint.Endpoint{
endpoint.NewEndpoint("update-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "8.8.8.8"),
endpoint.NewEndpoint("update-test.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "8.8.4.4"),
endpoint.NewEndpoint("update-test-aaaa.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeAAAA, "2606:4700:4700::1111"),
endpoint.NewEndpoint("update-test-aaaa.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeAAAA, "2606:4700:4700::1001"),
endpoint.NewEndpoint("update-test-a-to-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "1.1.1.1"),
endpoint.NewEndpoint("update-test-alias-to-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificAlias, "true"),
endpoint.NewEndpoint("update-test-alias-to-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeAAAA, "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificAlias, "true"),
endpoint.NewEndpoint("update-test-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "bar.elb.amazonaws.com"),
endpoint.NewEndpoint("update-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "bar.elb.amazonaws.com"),
endpoint.NewEndpoint("update-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "bar.elb.amazonaws.com").WithProviderSpecific(providerSpecificAlias, "true"),
endpoint.NewEndpoint("update-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeAAAA, "bar.elb.amazonaws.com").WithProviderSpecific(providerSpecificAlias, "true"),
endpoint.NewEndpoint("update-test-multiple.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "8.8.8.8", "8.8.4.4"),
endpoint.NewEndpoint("update-test-multiple-aaaa.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeAAAA, "2606:4700:4700::1111", "2606:4700:4700::1001"),
endpoint.NewEndpoint("weighted-to-simple.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "1.2.3.4").WithSetIdentifier("weighted-to-simple").WithProviderSpecific(providerSpecificWeight, "10"),
endpoint.NewEndpoint("simple-to-weighted.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "1.2.3.4"),
endpoint.NewEndpoint("policy-change.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "1.2.3.4").WithSetIdentifier("policy-change").WithProviderSpecific(providerSpecificWeight, "10"),
@ -824,11 +941,16 @@ func TestAWSApplyChanges(t *testing.T) {
updatedRecords := []*endpoint.Endpoint{
endpoint.NewEndpoint("update-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "1.2.3.4"),
endpoint.NewEndpoint("update-test.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "4.3.2.1"),
endpoint.NewEndpoint("update-test-aaaa.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeAAAA, "2606:4700:4700::1001"),
endpoint.NewEndpoint("update-test-aaaa.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeAAAA, "2606:4700:4700::1111"),
endpoint.NewEndpoint("update-test-a-to-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "foo.elb.amazonaws.com").WithProviderSpecific(providerSpecificAlias, "true"),
endpoint.NewEndpoint("update-test-a-to-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeAAAA, "foo.elb.amazonaws.com").WithProviderSpecific(providerSpecificAlias, "true"),
endpoint.NewEndpoint("update-test-alias-to-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "my-internal-host.example.com"),
endpoint.NewEndpoint("update-test-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "baz.elb.amazonaws.com"),
endpoint.NewEndpoint("update-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "baz.elb.amazonaws.com"),
endpoint.NewEndpoint("update-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "baz.elb.amazonaws.com").WithProviderSpecific(providerSpecificAlias, "true"),
endpoint.NewEndpoint("update-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeAAAA, "baz.elb.amazonaws.com").WithProviderSpecific(providerSpecificAlias, "true"),
endpoint.NewEndpoint("update-test-multiple.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "1.2.3.4", "4.3.2.1"),
endpoint.NewEndpoint("update-test-multiple-aaaa.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeAAAA, "2606:4700:4700::1001", "2606:4700:4700::1111"),
endpoint.NewEndpoint("weighted-to-simple.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "1.2.3.4"),
endpoint.NewEndpoint("simple-to-weighted.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "1.2.3.4").WithSetIdentifier("simple-to-weighted").WithProviderSpecific(providerSpecificWeight, "10"),
endpoint.NewEndpoint("policy-change.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "1.2.3.4").WithSetIdentifier("policy-change").WithProviderSpecific(providerSpecificRegion, "us-east-1"),
@ -840,9 +962,13 @@ func TestAWSApplyChanges(t *testing.T) {
deleteRecords := []*endpoint.Endpoint{
endpoint.NewEndpoint("delete-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "8.8.8.8"),
endpoint.NewEndpoint("delete-test.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "8.8.4.4"),
endpoint.NewEndpoint("delete-test-aaaa.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeAAAA, "2606:4700:4700::1111"),
endpoint.NewEndpoint("delete-test-aaaa.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeAAAA, "2606:4700:4700::1001"),
endpoint.NewEndpoint("delete-test-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "qux.elb.amazonaws.com"),
endpoint.NewEndpoint("delete-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "qux.elb.amazonaws.com"),
endpoint.NewEndpoint("delete-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "qux.elb.amazonaws.com").WithProviderSpecific(providerSpecificAlias, "true"),
endpoint.NewEndpoint("delete-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeAAAA, "qux.elb.amazonaws.com").WithProviderSpecific(providerSpecificAlias, "true"),
endpoint.NewEndpoint("delete-test-multiple.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "1.2.3.4", "4.3.2.1"),
endpoint.NewEndpoint("delete-test-multiple-aaaa.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeAAAA, "2606:4700:4700::1111", "2606:4700:4700::1001"),
endpoint.NewEndpoint("delete-test-mx.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeMX, "30 mailhost1.foo.elb.amazonaws.com"),
}
@ -870,12 +996,24 @@ func TestAWSApplyChanges(t *testing.T) {
TTL: aws.Int64(recordTTL),
ResourceRecords: []route53types.ResourceRecord{{Value: aws.String("8.8.8.8")}},
},
{
Name: aws.String("create-test-aaaa.zone-1.ext-dns-test-2.teapot.zalan.do."),
Type: route53types.RRTypeAaaa,
TTL: aws.Int64(recordTTL),
ResourceRecords: []route53types.ResourceRecord{{Value: aws.String("2606:4700:4700::1111")}},
},
{
Name: aws.String("update-test.zone-1.ext-dns-test-2.teapot.zalan.do."),
Type: route53types.RRTypeA,
TTL: aws.Int64(recordTTL),
ResourceRecords: []route53types.ResourceRecord{{Value: aws.String("1.2.3.4")}},
},
{
Name: aws.String("update-test-aaaa.zone-1.ext-dns-test-2.teapot.zalan.do."),
Type: route53types.RRTypeAaaa,
TTL: aws.Int64(recordTTL),
ResourceRecords: []route53types.ResourceRecord{{Value: aws.String("2606:4700:4700::1001")}},
},
{
Name: aws.String("update-test-a-to-cname.zone-1.ext-dns-test-2.teapot.zalan.do."),
Type: route53types.RRTypeA,
@ -885,6 +1023,15 @@ func TestAWSApplyChanges(t *testing.T) {
HostedZoneId: aws.String("zone-1.ext-dns-test-2.teapot.zalan.do."),
},
},
{
Name: aws.String("update-test-a-to-cname.zone-1.ext-dns-test-2.teapot.zalan.do."),
Type: route53types.RRTypeAaaa,
AliasTarget: &route53types.AliasTarget{
DNSName: aws.String("foo.elb.amazonaws.com."),
EvaluateTargetHealth: true,
HostedZoneId: aws.String("zone-1.ext-dns-test-2.teapot.zalan.do."),
},
},
{
Name: aws.String("update-test-alias-to-cname.zone-1.ext-dns-test-2.teapot.zalan.do."),
Type: route53types.RRTypeCname,
@ -910,10 +1057,22 @@ func TestAWSApplyChanges(t *testing.T) {
ResourceRecords: []route53types.ResourceRecord{{Value: aws.String("foo.elb.amazonaws.com")}},
},
{
Name: aws.String("update-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do."),
Type: route53types.RRTypeCname,
TTL: aws.Int64(recordTTL),
ResourceRecords: []route53types.ResourceRecord{{Value: aws.String("baz.elb.amazonaws.com")}},
Name: aws.String("update-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do."),
Type: route53types.RRTypeA,
AliasTarget: &route53types.AliasTarget{
DNSName: aws.String("baz.elb.amazonaws.com."),
EvaluateTargetHealth: true,
HostedZoneId: aws.String("zone-1.ext-dns-test-2.teapot.zalan.do."),
},
},
{
Name: aws.String("update-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do."),
Type: route53types.RRTypeAaaa,
AliasTarget: &route53types.AliasTarget{
DNSName: aws.String("baz.elb.amazonaws.com."),
EvaluateTargetHealth: true,
HostedZoneId: aws.String("zone-1.ext-dns-test-2.teapot.zalan.do."),
},
},
{
Name: aws.String("weighted-to-simple.zone-1.ext-dns-test-2.teapot.zalan.do."),
@ -975,24 +1134,48 @@ func TestAWSApplyChanges(t *testing.T) {
TTL: aws.Int64(recordTTL),
ResourceRecords: []route53types.ResourceRecord{{Value: aws.String("8.8.4.4")}},
},
{
Name: aws.String("create-test-aaaa.zone-2.ext-dns-test-2.teapot.zalan.do."),
Type: route53types.RRTypeAaaa,
TTL: aws.Int64(recordTTL),
ResourceRecords: []route53types.ResourceRecord{{Value: aws.String("2606:4700:4700::1001")}},
},
{
Name: aws.String("update-test.zone-2.ext-dns-test-2.teapot.zalan.do."),
Type: route53types.RRTypeA,
TTL: aws.Int64(recordTTL),
ResourceRecords: []route53types.ResourceRecord{{Value: aws.String("4.3.2.1")}},
},
{
Name: aws.String("update-test-aaaa.zone-2.ext-dns-test-2.teapot.zalan.do."),
Type: route53types.RRTypeAaaa,
TTL: aws.Int64(recordTTL),
ResourceRecords: []route53types.ResourceRecord{{Value: aws.String("2606:4700:4700::1111")}},
},
{
Name: aws.String("create-test-multiple.zone-2.ext-dns-test-2.teapot.zalan.do."),
Type: route53types.RRTypeA,
TTL: aws.Int64(recordTTL),
ResourceRecords: []route53types.ResourceRecord{{Value: aws.String("8.8.8.8")}, {Value: aws.String("8.8.4.4")}},
},
{
Name: aws.String("create-test-multiple-aaaa.zone-2.ext-dns-test-2.teapot.zalan.do."),
Type: route53types.RRTypeAaaa,
TTL: aws.Int64(recordTTL),
ResourceRecords: []route53types.ResourceRecord{{Value: aws.String("2606:4700:4700::1111")}, {Value: aws.String("2606:4700:4700::1001")}},
},
{
Name: aws.String("update-test-multiple.zone-2.ext-dns-test-2.teapot.zalan.do."),
Type: route53types.RRTypeA,
TTL: aws.Int64(recordTTL),
ResourceRecords: []route53types.ResourceRecord{{Value: aws.String("1.2.3.4")}, {Value: aws.String("4.3.2.1")}},
},
{
Name: aws.String("update-test-multiple-aaaa.zone-2.ext-dns-test-2.teapot.zalan.do."),
Type: route53types.RRTypeAaaa,
TTL: aws.Int64(recordTTL),
ResourceRecords: []route53types.ResourceRecord{{Value: aws.String("2606:4700:4700::1001")}, {Value: aws.String("2606:4700:4700::1111")}},
},
{
Name: aws.String("update-test-mx.zone-2.ext-dns-test-2.teapot.zalan.do."),
Type: route53types.RRTypeMx,
@ -1785,8 +1968,6 @@ func TestAWSCreateRecordsWithALIAS(t *testing.T) {
"": false,
} {
provider, _ := newAWSProvider(t, endpoint.NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), provider.NewZoneIDFilter([]string{}), provider.NewZoneTypeFilter(""), defaultEvaluateTargetHealth, false, nil)
// Test dualstack and ipv4 load balancer targets
records := []*endpoint.Endpoint{
{
DNSName: "create-test.zone-1.ext-dns-test-2.teapot.zalan.do",
@ -1804,9 +1985,9 @@ func TestAWSCreateRecordsWithALIAS(t *testing.T) {
},
},
{
DNSName: "create-test-dualstack.zone-1.ext-dns-test-2.teapot.zalan.do",
Targets: endpoint.Targets{"bar.eu-central-1.elb.amazonaws.com"},
RecordType: endpoint.RecordTypeA,
DNSName: "create-test.zone-1.ext-dns-test-2.teapot.zalan.do",
Targets: endpoint.Targets{"foo.eu-central-1.elb.amazonaws.com"},
RecordType: endpoint.RecordTypeAAAA,
ProviderSpecific: endpoint.ProviderSpecific{
endpoint.ProviderSpecificProperty{
Name: providerSpecificAlias,
@ -1817,7 +1998,6 @@ func TestAWSCreateRecordsWithALIAS(t *testing.T) {
Value: key,
},
},
Labels: map[string]string{endpoint.DualstackLabelKey: "true"},
},
}
adjusted, err := provider.AdjustEndpoints(records)
@ -1840,20 +2020,11 @@ func TestAWSCreateRecordsWithALIAS(t *testing.T) {
},
{
AliasTarget: &route53types.AliasTarget{
DNSName: aws.String("bar.eu-central-1.elb.amazonaws.com."),
DNSName: aws.String("foo.eu-central-1.elb.amazonaws.com."),
EvaluateTargetHealth: evaluateTargetHealth,
HostedZoneId: aws.String("Z215JYRZR1TBD5"),
},
Name: aws.String("create-test-dualstack.zone-1.ext-dns-test-2.teapot.zalan.do."),
Type: route53types.RRTypeA,
},
{
AliasTarget: &route53types.AliasTarget{
DNSName: aws.String("bar.eu-central-1.elb.amazonaws.com."),
EvaluateTargetHealth: evaluateTargetHealth,
HostedZoneId: aws.String("Z215JYRZR1TBD5"),
},
Name: aws.String("create-test-dualstack.zone-1.ext-dns-test-2.teapot.zalan.do."),
Name: aws.String("create-test.zone-1.ext-dns-test-2.teapot.zalan.do."),
Type: route53types.RRTypeAaaa,
},
})
@ -1887,10 +2058,14 @@ func TestAWSisAWSAlias(t *testing.T) {
alias bool
hz string
}{
{"foo.example.org", endpoint.RecordTypeA, false, ""}, // normal A record
{"bar.eu-central-1.elb.amazonaws.com", endpoint.RecordTypeA, true, "Z215JYRZR1TBD5"}, // pointing to ELB DNS name
{"foobar.example.org", endpoint.RecordTypeA, true, "Z1234567890ABC"}, // HZID retrieved by Route53
{"baz.example.org", endpoint.RecordTypeA, true, sameZoneAlias}, // record to be created
{"foo.example.org", endpoint.RecordTypeA, false, ""}, // normal A record
{"foo.example.org", endpoint.RecordTypeAAAA, false, ""}, // normal AAAA record
{"bar.eu-central-1.elb.amazonaws.com", endpoint.RecordTypeA, true, "Z215JYRZR1TBD5"}, // pointing to ELB DNS name (alias A)
{"bar.eu-central-1.elb.amazonaws.com", endpoint.RecordTypeAAAA, true, "Z215JYRZR1TBD5"}, // pointing to ELB DNS name (alias AAAA)
{"foobar.example.org", endpoint.RecordTypeA, true, "Z1234567890ABC"}, // HZID retrieved by Route53 (alias A)
{"foobar.example.org", endpoint.RecordTypeAAAA, true, "Z1234567890ABC"}, // HZID retrieved by Route53 (alias AAAA)
{"baz.example.org", endpoint.RecordTypeA, true, sameZoneAlias}, // record to be created (alias A)
{"baz.example.org", endpoint.RecordTypeAAAA, true, sameZoneAlias}, // record to be created (alias AAAA)
} {
ep := &endpoint.Endpoint{
Targets: endpoint.Targets{tc.target},

View File

@ -45,10 +45,6 @@ import (
const (
gatewayGroup = "gateway.networking.k8s.io"
gatewayKind = "Gateway"
// gatewayAPIDualstackAnnotationKey is the annotation used for determining if a Gateway Route is dualstack
gatewayAPIDualstackAnnotationKey = "external-dns.alpha.kubernetes.io/dualstack"
// gatewayAPIDualstackAnnotationValue is the value of the Gateway Route dualstack annotation that indicates it is dualstack
gatewayAPIDualstackAnnotationValue = "true"
)
type gatewayRoute interface {
@ -241,7 +237,6 @@ func (src *gatewayRouteSource) Endpoints(ctx context.Context) ([]*endpoint.Endpo
for host, targets := range hostTargets {
routeEndpoints = append(routeEndpoints, endpointsForHostname(host, targets, ttl, providerSpecific, setIdentifier, resource)...)
}
setDualstackLabel(rt, routeEndpoints)
log.Debugf("Endpoints generated from %s %s/%s: %v", src.rtKind, meta.Namespace, meta.Name, routeEndpoints)
endpoints = append(endpoints, routeEndpoints...)
@ -618,13 +613,3 @@ func selectorsEqual(a, b labels.Selector) bool {
}
return true
}
func setDualstackLabel(rt gatewayRoute, endpoints []*endpoint.Endpoint) {
val, ok := rt.Metadata().Annotations[gatewayAPIDualstackAnnotationKey]
if ok && val == gatewayAPIDualstackAnnotationValue {
log.Debugf("Adding dualstack label to GatewayRoute %s/%s.", rt.Metadata().Namespace, rt.Metadata().Name)
for _, ep := range endpoints {
ep.Labels[endpoint.DualstackLabelKey] = "true"
}
}
}

View File

@ -20,7 +20,6 @@ import (
"strings"
"testing"
"sigs.k8s.io/external-dns/endpoint"
v1 "sigs.k8s.io/gateway-api/apis/v1"
)
@ -246,47 +245,3 @@ func TestIsDNS1123Domain(t *testing.T) {
})
}
}
func TestDualStackLabel(t *testing.T) {
tests := []struct {
desc string
in map[string](string)
setsLabel bool
}{
{
desc: "empty-annotation",
setsLabel: false,
},
{
desc: "correct-annotation-key-and-value",
in: map[string]string{gatewayAPIDualstackAnnotationKey: gatewayAPIDualstackAnnotationValue},
setsLabel: true,
},
{
desc: "correct-annotation-key-incorrect-value",
in: map[string]string{gatewayAPIDualstackAnnotationKey: "foo"},
setsLabel: false,
},
{
desc: "incorrect-annotation-key-correct-value",
in: map[string]string{"FOO": gatewayAPIDualstackAnnotationValue},
setsLabel: false,
},
}
for _, tt := range tests {
t.Run(tt.desc, func(t *testing.T) {
endpoints := make([]*endpoint.Endpoint, 0)
endpoints = append(endpoints, endpoint.NewEndpoint("www.example.com", endpoint.RecordTypeA, "10.0.0.2", "10.0.0.3"))
rt := &gatewayHTTPRoute{}
rt.Metadata().Annotations = tt.in
setDualstackLabel(rt, endpoints)
got := endpoints[0].Labels[endpoint.DualstackLabelKey] == "true"
if got != tt.setsLabel {
t.Errorf("setDualstackLabel(%q); got: %v; want: %v", tt.in, got, tt.setsLabel)
}
})
}
}

View File

@ -37,11 +37,6 @@ import (
)
const (
// ALBDualstackAnnotationKey is the annotation used for determining if an ALB ingress is dualstack
ALBDualstackAnnotationKey = "alb.ingress.kubernetes.io/ip-address-type"
// ALBDualstackAnnotationValue is the value of the ALB dualstack annotation that indicates it is dualstack
ALBDualstackAnnotationValue = "dualstack"
// Possible values for the ingress-hostname-source annotation
IngressHostnameSourceAnnotationOnlyValue = "annotation-only"
IngressHostnameSourceDefinedHostsOnlyValue = "defined-hosts-only"
@ -171,7 +166,6 @@ func (sc *ingressSource) Endpoints(ctx context.Context) ([]*endpoint.Endpoint, e
}
log.Debugf("Endpoints generated from ingress: %s/%s: %v", ing.Namespace, ing.Name, ingEndpoints)
sc.setDualstackLabel(ing, ingEndpoints)
endpoints = append(endpoints, ingEndpoints...)
}
@ -274,16 +268,6 @@ func (sc *ingressSource) filterByIngressClass(ingresses []*networkv1.Ingress) ([
return filteredList, nil
}
func (sc *ingressSource) setDualstackLabel(ingress *networkv1.Ingress, endpoints []*endpoint.Endpoint) {
val, ok := ingress.Annotations[ALBDualstackAnnotationKey]
if ok && val == ALBDualstackAnnotationValue {
log.Debugf("Adding dualstack label to ingress %s/%s.", ingress.Namespace, ingress.Name)
for _, ep := range endpoints {
ep.Labels[endpoint.DualstackLabelKey] = "true"
}
}
}
// endpointsFromIngress extracts the endpoints from ingress object
func endpointsFromIngress(ing *networkv1.Ingress, ignoreHostnameAnnotation bool, ignoreIngressTLSSpec bool, ignoreIngressRulesSpec bool) []*endpoint.Endpoint {
resource := fmt.Sprintf("ingress/%s/%s", ing.Namespace, ing.Name)

View File

@ -44,12 +44,11 @@ func (suite *IngressSuite) SetupTest() {
fakeClient := fake.NewSimpleClientset()
suite.fooWithTargets = (fakeIngress{
name: "foo-with-targets",
namespace: "default",
dnsnames: []string{"foo"},
ips: []string{"8.8.8.8"},
hostnames: []string{"v1"},
annotations: map[string]string{ALBDualstackAnnotationKey: ALBDualstackAnnotationValue},
name: "foo-with-targets",
namespace: "default",
dnsnames: []string{"foo"},
ips: []string{"8.8.8.8", "2606:4700:4700::1111"},
hostnames: []string{"v1"},
}).Ingress()
_, err := fakeClient.NetworkingV1().Ingresses(suite.fooWithTargets.Namespace).Create(context.Background(), suite.fooWithTargets, metav1.CreateOptions{})
suite.NoError(err, "should succeed")
@ -77,13 +76,6 @@ func (suite *IngressSuite) TestResourceLabelIsSet() {
}
}
func (suite *IngressSuite) TestDualstackLabelIsSet() {
endpoints, _ := suite.sc.Endpoints(context.Background())
for _, ep := range endpoints {
suite.Equal("true", ep.Labels[endpoint.DualstackLabelKey], "should set dualstack label to true")
}
}
func TestIngress(t *testing.T) {
t.Parallel()
@ -212,10 +204,24 @@ func testEndpointsFromIngress(t *testing.T) {
},
},
{
title: "one rule.host two lb.IP and two lb.Hostname",
title: "one rule.host one lb.IPv6",
ingress: fakeIngress{
dnsnames: []string{"foo.bar"},
ips: []string{"2606:4700:4700::1111"},
},
expected: []*endpoint.Endpoint{
{
DNSName: "foo.bar",
RecordType: endpoint.RecordTypeAAAA,
Targets: endpoint.Targets{"2606:4700:4700::1111"},
},
},
},
{
title: "one rule.host two lb.IP, two lb.IPv6 and two lb.Hostname",
ingress: fakeIngress{
dnsnames: []string{"foo.bar"},
ips: []string{"8.8.8.8", "127.0.0.1"},
ips: []string{"8.8.8.8", "127.0.0.1", "2606:4700:4700::1111", "2606:4700:4700::1001"},
hostnames: []string{"elb.com", "alb.com"},
},
expected: []*endpoint.Endpoint{
@ -224,6 +230,11 @@ func testEndpointsFromIngress(t *testing.T) {
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8", "127.0.0.1"},
},
{
DNSName: "foo.bar",
RecordType: endpoint.RecordTypeAAAA,
Targets: endpoint.Targets{"2606:4700:4700::1111", "2606:4700:4700::1001"},
},
{
DNSName: "foo.bar",
RecordType: endpoint.RecordTypeCNAME,
@ -450,6 +461,30 @@ func testIngressEndpoints(t *testing.T) {
},
},
},
{
title: "dualstack ingress",
targetNamespace: "",
ingressItems: []fakeIngress{
{
name: "fake1",
namespace: namespace,
dnsnames: []string{"example.org"},
ips: []string{"8.8.8.8", "2001:DB8::1"},
},
},
expected: []*endpoint.Endpoint{
{
DNSName: "example.org",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8"},
},
{
DNSName: "example.org",
RecordType: endpoint.RecordTypeAAAA,
Targets: endpoint.Targets{"2001:DB8::1"},
},
},
},
{
title: "ignore rules",
targetNamespace: "",

View File

@ -150,7 +150,6 @@ func (sc *kongTCPIngressSource) Endpoints(ctx context.Context) ([]*endpoint.Endp
}
log.Debugf("Endpoints generated from TCPIngress: %s: %v", fullname, ingressEndpoints)
sc.setDualstackLabel(tcpIngress, ingressEndpoints)
endpoints = append(endpoints, ingressEndpoints...)
}
@ -192,16 +191,6 @@ func (sc *kongTCPIngressSource) filterByAnnotations(tcpIngresses []*TCPIngress)
return filteredList, nil
}
func (sc *kongTCPIngressSource) setDualstackLabel(tcpIngress *TCPIngress, endpoints []*endpoint.Endpoint) {
val, ok := tcpIngress.Annotations[ALBDualstackAnnotationKey]
if ok && val == ALBDualstackAnnotationValue {
log.Debugf("Adding dualstack label to TCPIngress %s/%s.", tcpIngress.Namespace, tcpIngress.Name)
for _, ep := range endpoints {
ep.Labels[endpoint.DualstackLabelKey] = "true"
}
}
}
// endpointsFromTCPIngress extracts the endpoints from a TCPIngress object
func (sc *kongTCPIngressSource) endpointsFromTCPIngress(tcpIngress *TCPIngress, targets endpoint.Targets) ([]*endpoint.Endpoint, error) {
var endpoints []*endpoint.Endpoint

View File

@ -280,7 +280,6 @@ func (sc *routeGroupSource) Endpoints(ctx context.Context) ([]*endpoint.Endpoint
}
log.Debugf("Endpoints generated from ingress: %s/%s: %v", rg.Metadata.Namespace, rg.Metadata.Name, eps)
sc.setRouteGroupDualstackLabel(rg, eps)
endpoints = append(endpoints, eps...)
}
@ -324,16 +323,6 @@ func (sc *routeGroupSource) endpointsFromTemplate(rg *routeGroup) ([]*endpoint.E
return endpoints, nil
}
func (sc *routeGroupSource) setRouteGroupDualstackLabel(rg *routeGroup, eps []*endpoint.Endpoint) {
val, ok := rg.Metadata.Annotations[ALBDualstackAnnotationKey]
if ok && val == ALBDualstackAnnotationValue {
log.Debugf("Adding dualstack label to routegroup %s/%s.", rg.Metadata.Namespace, rg.Metadata.Name)
for _, ep := range eps {
ep.Labels[endpoint.DualstackLabelKey] = "true"
}
}
}
// annotation logic ported from source/ingress.go without Spec.TLS part, because it'S not supported in RouteGroup
func (sc *routeGroupSource) endpointsFromRouteGroup(rg *routeGroup) []*endpoint.Endpoint {
endpoints := []*endpoint.Endpoint{}

View File

@ -196,6 +196,28 @@ func TestEndpointsFromRouteGroups(t *testing.T) {
},
},
},
{
name: "Routegroup with hosts and destination IPv6 creates an endpoint",
source: &routeGroupSource{},
rg: createTestRouteGroup(
"namespace1",
"rg1",
nil,
[]string{"rg1.k8s.example"},
[]routeGroupLoadBalancer{
{
IP: "2001:DB8::1",
},
},
),
want: []*endpoint.Endpoint{
{
DNSName: "rg1.k8s.example",
RecordType: endpoint.RecordTypeAAAA,
Targets: endpoint.Targets([]string{"2001:DB8::1"}),
},
},
},
{
name: "Routegroup with hosts and mixed destinations creates endpoints",
source: &routeGroupSource{},
@ -224,6 +246,34 @@ func TestEndpointsFromRouteGroups(t *testing.T) {
},
},
},
{
name: "Routegroup with hosts and mixed destinations (IPv6) creates endpoints",
source: &routeGroupSource{},
rg: createTestRouteGroup(
"namespace1",
"rg1",
nil,
[]string{"rg1.k8s.example"},
[]routeGroupLoadBalancer{
{
Hostname: "lb.example.org",
IP: "2001:DB8::1",
},
},
),
want: []*endpoint.Endpoint{
{
DNSName: "rg1.k8s.example",
RecordType: endpoint.RecordTypeAAAA,
Targets: endpoint.Targets([]string{"2001:DB8::1"}),
},
{
DNSName: "rg1.k8s.example",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets([]string{"lb.example.org"}),
},
},
},
} {
t.Run(tt.name, func(t *testing.T) {
got := tt.source.endpointsFromRouteGroup(tt.rg)
@ -787,37 +837,6 @@ func TestResourceLabelIsSet(t *testing.T) {
}
}
func TestDualstackLabelIsSet(t *testing.T) {
source := &routeGroupSource{
cli: &fakeRouteGroupClient{
rg: &routeGroupList{
Items: []*routeGroup{
createTestRouteGroup(
"namespace1",
"rg1",
map[string]string{
ALBDualstackAnnotationKey: ALBDualstackAnnotationValue,
},
[]string{"rg1.k8s.example"},
[]routeGroupLoadBalancer{
{
Hostname: "lb.example.org",
},
},
),
},
},
},
}
got, _ := source.Endpoints(context.Background())
for _, ep := range got {
if v, ok := ep.Labels[endpoint.DualstackLabelKey]; !ok || v != "true" {
t.Errorf("Failed to set resource label on ep %v", ep)
}
}
}
func TestParseTemplate(t *testing.T) {
for _, tt := range []struct {
name string

View File

@ -269,7 +269,6 @@ func (ts *traefikSource) ingressRouteEndpoints() ([]*endpoint.Endpoint, error) {
}
log.Debugf("Endpoints generated from IngressRoute: %s: %v", fullname, ingressEndpoints)
ts.setDualstackLabelIngressRoute(ingressRoute, ingressEndpoints)
endpoints = append(endpoints, ingressEndpoints...)
}
@ -322,7 +321,6 @@ func (ts *traefikSource) ingressRouteTCPEndpoints() ([]*endpoint.Endpoint, error
}
log.Debugf("Endpoints generated from IngressRouteTCP: %s: %v", fullname, ingressEndpoints)
ts.setDualstackLabelIngressRouteTCP(ingressRouteTCP, ingressEndpoints)
endpoints = append(endpoints, ingressEndpoints...)
}
@ -375,7 +373,6 @@ func (ts *traefikSource) ingressRouteUDPEndpoints() ([]*endpoint.Endpoint, error
}
log.Debugf("Endpoints generated from IngressRouteUDP: %s: %v", fullname, ingressEndpoints)
ts.setDualstackLabelIngressRouteUDP(ingressRouteUDP, ingressEndpoints)
endpoints = append(endpoints, ingressEndpoints...)
}
@ -428,7 +425,6 @@ func (ts *traefikSource) oldIngressRouteEndpoints() ([]*endpoint.Endpoint, error
}
log.Debugf("Endpoints generated from IngressRoute: %s: %v", fullname, ingressEndpoints)
ts.setDualstackLabelIngressRoute(ingressRoute, ingressEndpoints)
endpoints = append(endpoints, ingressEndpoints...)
}
@ -481,7 +477,6 @@ func (ts *traefikSource) oldIngressRouteTCPEndpoints() ([]*endpoint.Endpoint, er
}
log.Debugf("Endpoints generated from IngressRouteTCP: %s: %v", fullname, ingressEndpoints)
ts.setDualstackLabelIngressRouteTCP(ingressRouteTCP, ingressEndpoints)
endpoints = append(endpoints, ingressEndpoints...)
}
@ -534,7 +529,6 @@ func (ts *traefikSource) oldIngressRouteUDPEndpoints() ([]*endpoint.Endpoint, er
}
log.Debugf("Endpoints generated from IngressRouteUDP: %s: %v", fullname, ingressEndpoints)
ts.setDualstackLabelIngressRouteUDP(ingressRouteUDP, ingressEndpoints)
endpoints = append(endpoints, ingressEndpoints...)
}
@ -634,34 +628,6 @@ func (ts *traefikSource) filterIngressRouteUdpByAnnotations(ingressRoutes []*Ing
return filteredList, nil
}
func (ts *traefikSource) setDualstackLabelIngressRoute(ingressRoute *IngressRoute, endpoints []*endpoint.Endpoint) {
val, ok := ingressRoute.Annotations[ALBDualstackAnnotationKey]
if ok && val == ALBDualstackAnnotationValue {
log.Debugf("Adding dualstack label to IngressRoute %s/%s.", ingressRoute.Namespace, ingressRoute.Name)
for _, ep := range endpoints {
ep.Labels[endpoint.DualstackLabelKey] = "true"
}
}
}
func (ts *traefikSource) setDualstackLabelIngressRouteTCP(ingressRoute *IngressRouteTCP, endpoints []*endpoint.Endpoint) {
val, ok := ingressRoute.Annotations[ALBDualstackAnnotationKey]
if ok && val == ALBDualstackAnnotationValue {
log.Debugf("Adding dualstack label to IngressRouteTCP %s/%s.", ingressRoute.Namespace, ingressRoute.Name)
for _, ep := range endpoints {
ep.Labels[endpoint.DualstackLabelKey] = "true"
}
}
}
func (ts *traefikSource) setDualstackLabelIngressRouteUDP(ingressRoute *IngressRouteUDP, endpoints []*endpoint.Endpoint) {
val, ok := ingressRoute.Annotations[ALBDualstackAnnotationKey]
if ok && val == ALBDualstackAnnotationValue {
log.Debugf("Adding dualstack label to IngressRouteUDP %s/%s.", ingressRoute.Namespace, ingressRoute.Name)
for _, ep := range endpoints {
ep.Labels[endpoint.DualstackLabelKey] = "true"
}
}
}
// endpointsFromIngressRoute extracts the endpoints from a IngressRoute object
func (ts *traefikSource) endpointsFromIngressRoute(ingressRoute *IngressRoute, targets endpoint.Targets) ([]*endpoint.Endpoint, error) {
var endpoints []*endpoint.Endpoint