mirror of
https://github.com/kubernetes-sigs/external-dns.git
synced 2025-08-06 17:46:57 +02:00
fix(aws): correctly populate target health check on existing records
This commit is contained in:
parent
7dbd6b0fa9
commit
f21f45b15d
@ -151,8 +151,21 @@ func NewEndpointWithTTL(dnsName, recordType string, ttl TTL, targets ...string)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithProviderSpecific attaches a key/value pair to the Endpoint and returns the Endpoint.
|
||||||
|
// This can be used to pass additional data through the stages of ExternalDNS's Endpoint processing.
|
||||||
|
// The assumption is that most of the time this will be provider specific metadata that doesn't
|
||||||
|
// warrant its own field on the Endpoint object itself. It differs from Labels in the fact that it's
|
||||||
|
// not persisted in the Registry but only kept in memory during a single record synchronization.
|
||||||
|
func (e *Endpoint) WithProviderSpecific(key, value string) *Endpoint {
|
||||||
|
if e.ProviderSpecific == nil {
|
||||||
|
e.ProviderSpecific = ProviderSpecific{}
|
||||||
|
}
|
||||||
|
e.ProviderSpecific[key] = value
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
func (e *Endpoint) String() string {
|
func (e *Endpoint) String() string {
|
||||||
return fmt.Sprintf("%s %d IN %s %s", e.DNSName, e.RecordTTL, e.RecordType, e.Targets)
|
return fmt.Sprintf("%s %d IN %s %s %s", e.DNSName, e.RecordTTL, e.RecordType, e.Targets, e.ProviderSpecific)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DNSEndpointSpec defines the desired state of DNSEndpoint
|
// DNSEndpointSpec defines the desired state of DNSEndpoint
|
||||||
|
@ -48,7 +48,8 @@ func (b byAllFields) Less(i, j int) bool {
|
|||||||
func SameEndpoint(a, b *endpoint.Endpoint) bool {
|
func SameEndpoint(a, b *endpoint.Endpoint) bool {
|
||||||
return a.DNSName == b.DNSName && a.Targets.Same(b.Targets) && a.RecordType == b.RecordType &&
|
return a.DNSName == b.DNSName && a.Targets.Same(b.Targets) && a.RecordType == b.RecordType &&
|
||||||
a.Labels[endpoint.OwnerLabelKey] == b.Labels[endpoint.OwnerLabelKey] && a.RecordTTL == b.RecordTTL &&
|
a.Labels[endpoint.OwnerLabelKey] == b.Labels[endpoint.OwnerLabelKey] && a.RecordTTL == b.RecordTTL &&
|
||||||
a.Labels[endpoint.ResourceLabelKey] == b.Labels[endpoint.ResourceLabelKey]
|
a.Labels[endpoint.ResourceLabelKey] == b.Labels[endpoint.ResourceLabelKey] &&
|
||||||
|
SameMap(a.ProviderSpecific, b.ProviderSpecific)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SameEndpoints compares two slices of endpoints regardless of order
|
// SameEndpoints compares two slices of endpoints regardless of order
|
||||||
@ -79,3 +80,18 @@ func SamePlanChanges(a, b map[string][]*endpoint.Endpoint) bool {
|
|||||||
return SameEndpoints(a["Create"], b["Create"]) && SameEndpoints(a["Delete"], b["Delete"]) &&
|
return SameEndpoints(a["Create"], b["Create"]) && SameEndpoints(a["Delete"], b["Delete"]) &&
|
||||||
SameEndpoints(a["UpdateOld"], b["UpdateOld"]) && SameEndpoints(a["UpdateNew"], b["UpdateNew"])
|
SameEndpoints(a["UpdateOld"], b["UpdateOld"]) && SameEndpoints(a["UpdateNew"], b["UpdateNew"])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SameMap verifies that two maps contain the same string/string key/value pairs
|
||||||
|
func SameMap(a, b map[string]string) bool {
|
||||||
|
if len(a) != len(b) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
for k, v := range a {
|
||||||
|
if v != b[k] {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
@ -55,16 +55,22 @@ func ExampleSameEndpoints() {
|
|||||||
RecordType: "CNAME",
|
RecordType: "CNAME",
|
||||||
RecordTTL: endpoint.TTL(60),
|
RecordTTL: endpoint.TTL(60),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
DNSName: "example.org",
|
||||||
|
Targets: endpoint.Targets{"load-balancer.org"},
|
||||||
|
ProviderSpecific: endpoint.ProviderSpecific{"foo": "bar"},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
sort.Sort(byAllFields(eps))
|
sort.Sort(byAllFields(eps))
|
||||||
for _, ep := range eps {
|
for _, ep := range eps {
|
||||||
fmt.Println(ep)
|
fmt.Println(ep)
|
||||||
}
|
}
|
||||||
// Output:
|
// Output:
|
||||||
// abc.com 0 IN A 1.2.3.4
|
// abc.com 0 IN A 1.2.3.4 map[]
|
||||||
// abc.com 0 IN TXT something
|
// abc.com 0 IN TXT something map[]
|
||||||
// bbc.com 0 IN CNAME foo.com
|
// bbc.com 0 IN CNAME foo.com map[]
|
||||||
// cbc.com 60 IN CNAME foo.com
|
// cbc.com 60 IN CNAME foo.com map[]
|
||||||
// example.org 0 IN load-balancer.org
|
// example.org 0 IN load-balancer.org map[]
|
||||||
// example.org 0 IN TXT load-balancer.org
|
// example.org 0 IN load-balancer.org map[foo:bar]
|
||||||
|
// example.org 0 IN TXT load-balancer.org map[]
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,9 @@ import (
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
recordTTL = 300
|
recordTTL = 300
|
||||||
|
// provider specific key that designates whether an AWS ALIAS record has the EvaluateTargetHealth
|
||||||
|
// field set to true.
|
||||||
|
providerSpecificEvaluateTargetHealth = "aws/evaluate-target-health"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -227,7 +230,10 @@ func (p *AWSProvider) Records() (endpoints []*endpoint.Endpoint, _ error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if r.AliasTarget != nil {
|
if r.AliasTarget != nil {
|
||||||
endpoints = append(endpoints, endpoint.NewEndpointWithTTL(wildcardUnescape(aws.StringValue(r.Name)), endpoint.RecordTypeCNAME, ttl, aws.StringValue(r.AliasTarget.DNSName)))
|
ep := endpoint.
|
||||||
|
NewEndpointWithTTL(wildcardUnescape(aws.StringValue(r.Name)), endpoint.RecordTypeCNAME, ttl, aws.StringValue(r.AliasTarget.DNSName)).
|
||||||
|
WithProviderSpecific(providerSpecificEvaluateTargetHealth, fmt.Sprintf("%t", aws.BoolValue(r.AliasTarget.EvaluateTargetHealth)))
|
||||||
|
endpoints = append(endpoints, ep)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -359,11 +365,16 @@ func (p *AWSProvider) newChange(action string, endpoint *endpoint.Endpoint) *rou
|
|||||||
}
|
}
|
||||||
|
|
||||||
if isAWSLoadBalancer(endpoint) {
|
if isAWSLoadBalancer(endpoint) {
|
||||||
|
evalTargetHealth := p.evaluateTargetHealth
|
||||||
|
if _, ok := endpoint.ProviderSpecific[providerSpecificEvaluateTargetHealth]; ok {
|
||||||
|
evalTargetHealth = endpoint.ProviderSpecific[providerSpecificEvaluateTargetHealth] == "true"
|
||||||
|
}
|
||||||
|
|
||||||
change.ResourceRecordSet.Type = aws.String(route53.RRTypeA)
|
change.ResourceRecordSet.Type = aws.String(route53.RRTypeA)
|
||||||
change.ResourceRecordSet.AliasTarget = &route53.AliasTarget{
|
change.ResourceRecordSet.AliasTarget = &route53.AliasTarget{
|
||||||
DNSName: aws.String(endpoint.Targets[0]),
|
DNSName: aws.String(endpoint.Targets[0]),
|
||||||
HostedZoneId: aws.String(canonicalHostedZone(endpoint.Targets[0])),
|
HostedZoneId: aws.String(canonicalHostedZone(endpoint.Targets[0])),
|
||||||
EvaluateTargetHealth: aws.Bool(p.evaluateTargetHealth),
|
EvaluateTargetHealth: aws.Bool(evalTargetHealth),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
change.ResourceRecordSet.Type = aws.String(endpoint.RecordType)
|
change.ResourceRecordSet.Type = aws.String(endpoint.RecordType)
|
||||||
|
@ -22,6 +22,7 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
"github.com/aws/aws-sdk-go/service/route53"
|
"github.com/aws/aws-sdk-go/service/route53"
|
||||||
@ -31,7 +32,6 @@ import (
|
|||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/mock"
|
"github.com/stretchr/testify/mock"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -249,12 +249,13 @@ func TestAWSZones(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestAWSRecords(t *testing.T) {
|
func TestAWSRecords(t *testing.T) {
|
||||||
provider, _ := newAWSProvider(t, NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), NewZoneIDFilter([]string{}), NewZoneTypeFilter(""), defaultEvaluateTargetHealth, false, []*endpoint.Endpoint{
|
provider, _ := newAWSProvider(t, NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), NewZoneIDFilter([]string{}), NewZoneTypeFilter(""), false, false, []*endpoint.Endpoint{
|
||||||
endpoint.NewEndpointWithTTL("list-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4"),
|
endpoint.NewEndpointWithTTL("list-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4"),
|
||||||
endpoint.NewEndpointWithTTL("list-test.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.8.8"),
|
endpoint.NewEndpointWithTTL("list-test.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.8.8"),
|
||||||
endpoint.NewEndpointWithTTL("*.wildcard-test.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.8.8"),
|
endpoint.NewEndpointWithTTL("*.wildcard-test.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.8.8"),
|
||||||
endpoint.NewEndpoint("list-test-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.eu-central-1.elb.amazonaws.com"),
|
endpoint.NewEndpoint("list-test-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "false"),
|
||||||
endpoint.NewEndpoint("*.wildcard-test-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.eu-central-1.elb.amazonaws.com"),
|
endpoint.NewEndpoint("*.wildcard-test-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "false"),
|
||||||
|
endpoint.NewEndpoint("list-test-alias-evaluate.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "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("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"),
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -265,8 +266,9 @@ func TestAWSRecords(t *testing.T) {
|
|||||||
endpoint.NewEndpointWithTTL("list-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4"),
|
endpoint.NewEndpointWithTTL("list-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4"),
|
||||||
endpoint.NewEndpointWithTTL("list-test.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.8.8"),
|
endpoint.NewEndpointWithTTL("list-test.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.8.8"),
|
||||||
endpoint.NewEndpointWithTTL("*.wildcard-test.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.8.8"),
|
endpoint.NewEndpointWithTTL("*.wildcard-test.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.8.8"),
|
||||||
endpoint.NewEndpoint("list-test-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.eu-central-1.elb.amazonaws.com"),
|
endpoint.NewEndpoint("list-test-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "false"),
|
||||||
endpoint.NewEndpoint("*.wildcard-test-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.eu-central-1.elb.amazonaws.com"),
|
endpoint.NewEndpoint("*.wildcard-test-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "false"),
|
||||||
|
endpoint.NewEndpoint("list-test-alias-evaluate.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "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("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"),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -336,12 +338,12 @@ func TestAWSDeleteRecords(t *testing.T) {
|
|||||||
endpoint.NewEndpointWithTTL("delete-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4"),
|
endpoint.NewEndpointWithTTL("delete-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4"),
|
||||||
endpoint.NewEndpointWithTTL("delete-test.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.8.8"),
|
endpoint.NewEndpointWithTTL("delete-test.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.8.8"),
|
||||||
endpoint.NewEndpointWithTTL("delete-test-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "baz.elb.amazonaws.com"),
|
endpoint.NewEndpointWithTTL("delete-test-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "baz.elb.amazonaws.com"),
|
||||||
endpoint.NewEndpoint("delete-test-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.eu-central-1.elb.amazonaws.com"),
|
endpoint.NewEndpoint("delete-test-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "false"),
|
||||||
endpoint.NewEndpoint("delete-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.eu-central-1.elb.amazonaws.com"),
|
endpoint.NewEndpoint("delete-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "true"),
|
||||||
endpoint.NewEndpointWithTTL("delete-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("delete-test-multiple.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.8.8", "8.8.4.4"),
|
||||||
}
|
}
|
||||||
|
|
||||||
provider, _ := newAWSProvider(t, NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), NewZoneIDFilter([]string{}), NewZoneTypeFilter(""), defaultEvaluateTargetHealth, false, originalEndpoints)
|
provider, _ := newAWSProvider(t, NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), NewZoneIDFilter([]string{}), NewZoneTypeFilter(""), false, false, originalEndpoints)
|
||||||
|
|
||||||
require.NoError(t, provider.DeleteRecords(originalEndpoints))
|
require.NoError(t, provider.DeleteRecords(originalEndpoints))
|
||||||
|
|
||||||
@ -764,14 +766,22 @@ func TestAWSCreateRecordsWithCNAME(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestAWSCreateRecordsWithALIAS(t *testing.T) {
|
func TestAWSCreateRecordsWithALIAS(t *testing.T) {
|
||||||
for _, evaluateTargetHealth := range []bool{
|
for key, evaluateTargetHealth := range map[string]bool{
|
||||||
true,
|
"true": true,
|
||||||
false,
|
"false": false,
|
||||||
|
"": false,
|
||||||
} {
|
} {
|
||||||
provider, _ := newAWSProvider(t, NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), NewZoneIDFilter([]string{}), NewZoneTypeFilter(""), evaluateTargetHealth, false, []*endpoint.Endpoint{})
|
provider, _ := newAWSProvider(t, NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), NewZoneIDFilter([]string{}), NewZoneTypeFilter(""), defaultEvaluateTargetHealth, false, []*endpoint.Endpoint{})
|
||||||
|
|
||||||
records := []*endpoint.Endpoint{
|
records := []*endpoint.Endpoint{
|
||||||
{DNSName: "create-test.zone-1.ext-dns-test-2.teapot.zalan.do", Targets: endpoint.Targets{"foo.eu-central-1.elb.amazonaws.com"}, RecordType: endpoint.RecordTypeCNAME},
|
{
|
||||||
|
DNSName: "create-test.zone-1.ext-dns-test-2.teapot.zalan.do",
|
||||||
|
Targets: endpoint.Targets{"foo.eu-central-1.elb.amazonaws.com"},
|
||||||
|
RecordType: endpoint.RecordTypeCNAME,
|
||||||
|
ProviderSpecific: endpoint.ProviderSpecific{
|
||||||
|
providerSpecificEvaluateTargetHealth: key,
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
require.NoError(t, provider.CreateRecords(records))
|
require.NoError(t, provider.CreateRecords(records))
|
||||||
|
Loading…
Reference in New Issue
Block a user