mirror of
https://github.com/kubernetes-sigs/external-dns.git
synced 2025-08-06 01:26:59 +02:00
add dualstack support for AWS provider with ALB ingress controllers
This commit is contained in:
parent
58c9b2e321
commit
d68d06f17c
@ -38,6 +38,9 @@ const (
|
||||
// AWSSDDescriptionLabel label responsible for storing raw owner/resource combination information in the Labels
|
||||
// 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"
|
||||
)
|
||||
|
||||
// Labels store metadata related to the endpoint
|
||||
|
@ -407,60 +407,74 @@ func (p *AWSProvider) newChanges(action string, endpoints []*endpoint.Endpoint,
|
||||
changes := make([]*route53.Change, 0, len(endpoints))
|
||||
|
||||
for _, endpoint := range endpoints {
|
||||
changes = append(changes, p.newChange(action, endpoint, recordsCache, zones))
|
||||
change, dualstack := p.newChange(action, endpoint, recordsCache, zones)
|
||||
changes = append(changes, change)
|
||||
if dualstack {
|
||||
// make a copy of change, modify RRS type to AAAA, then add new change
|
||||
rrs := *change.ResourceRecordSet
|
||||
change2 := &route53.Change{Action: change.Action, ResourceRecordSet: &rrs}
|
||||
change2.ResourceRecordSet.Type = aws.String(route53.RRTypeAaaa)
|
||||
changes = append(changes, change2)
|
||||
}
|
||||
}
|
||||
|
||||
return changes
|
||||
}
|
||||
|
||||
// newChange returns a Change of the given record by the given action, e.g.
|
||||
// newChange returns a route53 Change and a boolean indicating if there should also be a change to a AAAA record
|
||||
// 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 string, endpoint *endpoint.Endpoint, recordsCache []*endpoint.Endpoint, zones map[string]*route53.HostedZone) *route53.Change {
|
||||
func (p *AWSProvider) newChange(action string, ep *endpoint.Endpoint, recordsCache []*endpoint.Endpoint, zones map[string]*route53.HostedZone) (*route53.Change, bool) {
|
||||
change := &route53.Change{
|
||||
Action: aws.String(action),
|
||||
ResourceRecordSet: &route53.ResourceRecordSet{
|
||||
Name: aws.String(endpoint.DNSName),
|
||||
Name: aws.String(ep.DNSName),
|
||||
},
|
||||
}
|
||||
dualstack := false
|
||||
|
||||
if isAWSLoadBalancer(endpoint) {
|
||||
if isAWSLoadBalancer(ep) {
|
||||
evalTargetHealth := p.evaluateTargetHealth
|
||||
if prop, ok := endpoint.GetProviderSpecificProperty(providerSpecificEvaluateTargetHealth); ok {
|
||||
if prop, ok := ep.GetProviderSpecificProperty(providerSpecificEvaluateTargetHealth); ok {
|
||||
evalTargetHealth = prop.Value == "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 = aws.String(route53.RRTypeA)
|
||||
change.ResourceRecordSet.AliasTarget = &route53.AliasTarget{
|
||||
DNSName: aws.String(endpoint.Targets[0]),
|
||||
HostedZoneId: aws.String(canonicalHostedZone(endpoint.Targets[0])),
|
||||
DNSName: aws.String(ep.Targets[0]),
|
||||
HostedZoneId: aws.String(canonicalHostedZone(ep.Targets[0])),
|
||||
EvaluateTargetHealth: aws.Bool(evalTargetHealth),
|
||||
}
|
||||
} else if hostedZone := isAWSAlias(endpoint, recordsCache); hostedZone != "" {
|
||||
} else if hostedZone := isAWSAlias(ep, recordsCache); hostedZone != "" {
|
||||
for _, zone := range zones {
|
||||
change.ResourceRecordSet.Type = aws.String(route53.RRTypeA)
|
||||
change.ResourceRecordSet.AliasTarget = &route53.AliasTarget{
|
||||
DNSName: aws.String(endpoint.Targets[0]),
|
||||
DNSName: aws.String(ep.Targets[0]),
|
||||
HostedZoneId: aws.String(cleanZoneID(*zone.Id)),
|
||||
EvaluateTargetHealth: aws.Bool(p.evaluateTargetHealth),
|
||||
}
|
||||
}
|
||||
} else {
|
||||
change.ResourceRecordSet.Type = aws.String(endpoint.RecordType)
|
||||
if !endpoint.RecordTTL.IsConfigured() {
|
||||
change.ResourceRecordSet.Type = aws.String(ep.RecordType)
|
||||
if !ep.RecordTTL.IsConfigured() {
|
||||
change.ResourceRecordSet.TTL = aws.Int64(recordTTL)
|
||||
} else {
|
||||
change.ResourceRecordSet.TTL = aws.Int64(int64(endpoint.RecordTTL))
|
||||
change.ResourceRecordSet.TTL = aws.Int64(int64(ep.RecordTTL))
|
||||
}
|
||||
change.ResourceRecordSet.ResourceRecords = make([]*route53.ResourceRecord, len(endpoint.Targets))
|
||||
for idx, val := range endpoint.Targets {
|
||||
change.ResourceRecordSet.ResourceRecords = make([]*route53.ResourceRecord, len(ep.Targets))
|
||||
for idx, val := range ep.Targets {
|
||||
change.ResourceRecordSet.ResourceRecords[idx] = &route53.ResourceRecord{
|
||||
Value: aws.String(val),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return change
|
||||
return change, dualstack
|
||||
}
|
||||
|
||||
func (p *AWSProvider) tagsForZone(zoneID string) (map[string]string, error) {
|
||||
|
@ -37,6 +37,13 @@ import (
|
||||
"k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
const (
|
||||
// The annotation used for determining if an ALB ingress is dualstack
|
||||
ALBDualstackAnnotationKey = "alb.ingress.kubernetes.io/ip-address-type"
|
||||
// The value of the ALB dualstack annotation that indicates it is dualstack
|
||||
ALBDualstackAnnotationValue = "dualstack"
|
||||
)
|
||||
|
||||
// ingressSource is an implementation of Source for Kubernetes ingress objects.
|
||||
// Ingress implementation will use the spec.rules.host value for the hostname
|
||||
// Use targetAnnotationKey to explicitly set Endpoint. (useful if the ingress
|
||||
@ -148,6 +155,7 @@ func (sc *ingressSource) Endpoints() ([]*endpoint.Endpoint, error) {
|
||||
|
||||
log.Debugf("Endpoints generated from ingress: %s/%s: %v", ing.Namespace, ing.Name, ingEndpoints)
|
||||
sc.setResourceLabel(ing, ingEndpoints)
|
||||
sc.setDualstackLabel(ing, ingEndpoints)
|
||||
endpoints = append(endpoints, ingEndpoints...)
|
||||
}
|
||||
|
||||
@ -228,6 +236,14 @@ func (sc *ingressSource) setResourceLabel(ingress *v1beta1.Ingress, endpoints []
|
||||
}
|
||||
}
|
||||
|
||||
func (sc *ingressSource) setDualstackLabel(ingress *v1beta1.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 *v1beta1.Ingress, ignoreHostnameAnnotation bool) []*endpoint.Endpoint {
|
||||
var endpoints []*endpoint.Endpoint
|
||||
|
Loading…
Reference in New Issue
Block a user