mirror of
https://github.com/kubernetes-sigs/external-dns.git
synced 2025-08-06 01:26:59 +02:00
Merge pull request #3674 from johngmyers/provider-specific
Route53 update configuration of target health checks
This commit is contained in:
commit
d867cc8059
@ -222,22 +222,43 @@ func (e *Endpoint) WithSetIdentifier(setIdentifier string) *Endpoint {
|
||||
// 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 = append(e.ProviderSpecific, ProviderSpecificProperty{Name: key, Value: value})
|
||||
e.SetProviderSpecificProperty(key, value)
|
||||
return e
|
||||
}
|
||||
|
||||
// GetProviderSpecificProperty returns a ProviderSpecificProperty if the property exists.
|
||||
func (e *Endpoint) GetProviderSpecificProperty(key string) (ProviderSpecificProperty, bool) {
|
||||
// GetProviderSpecificProperty returns the value of a ProviderSpecificProperty if the property exists.
|
||||
func (e *Endpoint) GetProviderSpecificProperty(key string) (string, bool) {
|
||||
for _, providerSpecific := range e.ProviderSpecific {
|
||||
if providerSpecific.Name == key {
|
||||
return providerSpecific, true
|
||||
return providerSpecific.Value, true
|
||||
}
|
||||
}
|
||||
return "", false
|
||||
}
|
||||
|
||||
// SetProviderSpecificProperty sets the value of a ProviderSpecificProperty.
|
||||
func (e *Endpoint) SetProviderSpecificProperty(key string, value string) {
|
||||
for i, providerSpecific := range e.ProviderSpecific {
|
||||
if providerSpecific.Name == key {
|
||||
e.ProviderSpecific[i] = ProviderSpecificProperty{
|
||||
Name: key,
|
||||
Value: value,
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
e.ProviderSpecific = append(e.ProviderSpecific, ProviderSpecificProperty{Name: key, Value: value})
|
||||
}
|
||||
|
||||
// DeleteProviderSpecificProperty deletes any ProviderSpecificProperty of the specified name.
|
||||
func (e *Endpoint) DeleteProviderSpecificProperty(key string) {
|
||||
for i, providerSpecific := range e.ProviderSpecific {
|
||||
if providerSpecific.Name == key {
|
||||
e.ProviderSpecific = append(e.ProviderSpecific[:i], e.ProviderSpecific[i+1:]...)
|
||||
return
|
||||
}
|
||||
}
|
||||
return ProviderSpecificProperty{}, false
|
||||
}
|
||||
|
||||
func (e *Endpoint) String() string {
|
||||
|
@ -47,10 +47,12 @@ const (
|
||||
// As we are using the standard AWS client, this should already be compliant.
|
||||
// Hence, ifever AWS decides to raise this limit, we will automatically reduce the pressure on rate limits
|
||||
route53PageSize = "300"
|
||||
// provider specific key that designates whether an AWS ALIAS record has the EvaluateTargetHealth
|
||||
// field set to true.
|
||||
providerSpecificAlias = "alias"
|
||||
providerSpecificTargetHostedZone = "aws/target-hosted-zone"
|
||||
// providerSpecificAlias specifies whether a CNAME endpoint maps to an AWS ALIAS record.
|
||||
providerSpecificAlias = "alias"
|
||||
providerSpecificTargetHostedZone = "aws/target-hosted-zone"
|
||||
// providerSpecificEvaluateTargetHealth specifies whether an AWS ALIAS record
|
||||
// has the EvaluateTargetHealth field set to true. Present iff the endpoint
|
||||
// has a `providerSpecificAlias` value of `true`.
|
||||
providerSpecificEvaluateTargetHealth = "aws/evaluate-target-health"
|
||||
providerSpecificWeight = "aws/weight"
|
||||
providerSpecificRegion = "aws/region"
|
||||
@ -283,13 +285,6 @@ func NewAWSProvider(awsConfig AWSConfig) (*AWSProvider, error) {
|
||||
return provider, nil
|
||||
}
|
||||
|
||||
func (p *AWSProvider) PropertyValuesEqual(name string, previous string, current string) bool {
|
||||
if name == "aws/evaluate-target-health" {
|
||||
return true
|
||||
}
|
||||
return p.BaseProvider.PropertyValuesEqual(name, previous, current)
|
||||
}
|
||||
|
||||
// Zones returns the list of hosted zones.
|
||||
func (p *AWSProvider) Zones(ctx context.Context) (map[string]*route53.HostedZone, error) {
|
||||
if p.zonesCache.zones != nil && time.Since(p.zonesCache.age) < p.zonesCache.duration {
|
||||
@ -390,7 +385,11 @@ func (p *AWSProvider) records(ctx context.Context, zones map[string]*route53.Hos
|
||||
targets[idx] = aws.StringValue(rr.Value)
|
||||
}
|
||||
|
||||
newEndpoints = append(newEndpoints, endpoint.NewEndpointWithTTL(wildcardUnescape(aws.StringValue(r.Name)), aws.StringValue(r.Type), ttl, targets...))
|
||||
ep := endpoint.NewEndpointWithTTL(wildcardUnescape(aws.StringValue(r.Name)), aws.StringValue(r.Type), ttl, targets...)
|
||||
if aws.StringValue(r.Type) == endpoint.RecordTypeCNAME {
|
||||
ep = ep.WithProviderSpecific(providerSpecificAlias, "false")
|
||||
}
|
||||
newEndpoints = append(newEndpoints, ep)
|
||||
}
|
||||
|
||||
if r.AliasTarget != nil {
|
||||
@ -466,8 +465,12 @@ func (p *AWSProvider) requiresDeleteCreate(old *endpoint.Endpoint, new *endpoint
|
||||
}
|
||||
|
||||
// an ALIAS record change to/from a CNAME
|
||||
if old.RecordType == endpoint.RecordTypeCNAME && useAlias(old, p.preferCNAME) != useAlias(new, p.preferCNAME) {
|
||||
return true
|
||||
if old.RecordType == endpoint.RecordTypeCNAME {
|
||||
oldAlias, _ := old.GetProviderSpecificProperty(providerSpecificAlias)
|
||||
newAlias, _ := new.GetProviderSpecificProperty(providerSpecificAlias)
|
||||
if oldAlias != newAlias {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// a set identifier change
|
||||
@ -667,23 +670,29 @@ func (p *AWSProvider) newChanges(action string, endpoints []*endpoint.Endpoint)
|
||||
func (p *AWSProvider) AdjustEndpoints(endpoints []*endpoint.Endpoint) []*endpoint.Endpoint {
|
||||
for _, ep := range endpoints {
|
||||
alias := false
|
||||
if aliasString, ok := ep.GetProviderSpecificProperty(providerSpecificAlias); ok {
|
||||
alias = aliasString.Value == "true"
|
||||
} else if useAlias(ep, p.preferCNAME) {
|
||||
alias = true
|
||||
log.Debugf("Modifying endpoint: %v, setting %s=true", ep, providerSpecificAlias)
|
||||
ep.ProviderSpecific = append(ep.ProviderSpecific, endpoint.ProviderSpecificProperty{
|
||||
Name: providerSpecificAlias,
|
||||
Value: "true",
|
||||
})
|
||||
if ep.RecordType != endpoint.RecordTypeCNAME {
|
||||
ep.DeleteProviderSpecificProperty(providerSpecificAlias)
|
||||
} else if aliasString, ok := ep.GetProviderSpecificProperty(providerSpecificAlias); ok {
|
||||
alias = aliasString == "true"
|
||||
if !alias && aliasString != "false" {
|
||||
ep.SetProviderSpecificProperty(providerSpecificAlias, "false")
|
||||
}
|
||||
} else {
|
||||
alias = useAlias(ep, p.preferCNAME)
|
||||
log.Debugf("Modifying endpoint: %v, setting %s=%v", ep, providerSpecificAlias, alias)
|
||||
ep.SetProviderSpecificProperty(providerSpecificAlias, strconv.FormatBool(alias))
|
||||
}
|
||||
|
||||
if _, ok := ep.GetProviderSpecificProperty(providerSpecificEvaluateTargetHealth); alias && !ok {
|
||||
log.Debugf("Modifying endpoint: %v, setting %s=%t", ep, providerSpecificEvaluateTargetHealth, p.evaluateTargetHealth)
|
||||
ep.ProviderSpecific = append(ep.ProviderSpecific, endpoint.ProviderSpecificProperty{
|
||||
Name: providerSpecificEvaluateTargetHealth,
|
||||
Value: fmt.Sprintf("%t", p.evaluateTargetHealth),
|
||||
})
|
||||
if alias {
|
||||
if prop, ok := ep.GetProviderSpecificProperty(providerSpecificEvaluateTargetHealth); ok {
|
||||
if prop != "true" && prop != "false" {
|
||||
ep.SetProviderSpecificProperty(providerSpecificEvaluateTargetHealth, "false")
|
||||
}
|
||||
} else {
|
||||
ep.SetProviderSpecificProperty(providerSpecificEvaluateTargetHealth, strconv.FormatBool(p.evaluateTargetHealth))
|
||||
}
|
||||
} else {
|
||||
ep.DeleteProviderSpecificProperty(providerSpecificEvaluateTargetHealth)
|
||||
}
|
||||
}
|
||||
return endpoints
|
||||
@ -706,7 +715,7 @@ func (p *AWSProvider) newChange(action string, ep *endpoint.Endpoint) (*Route53C
|
||||
if targetHostedZone := isAWSAlias(ep); targetHostedZone != "" {
|
||||
evalTargetHealth := p.evaluateTargetHealth
|
||||
if prop, ok := ep.GetProviderSpecificProperty(providerSpecificEvaluateTargetHealth); ok {
|
||||
evalTargetHealth = prop.Value == "true"
|
||||
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 {
|
||||
@ -737,18 +746,18 @@ func (p *AWSProvider) newChange(action string, ep *endpoint.Endpoint) (*Route53C
|
||||
if setIdentifier != "" {
|
||||
change.ResourceRecordSet.SetIdentifier = aws.String(setIdentifier)
|
||||
if prop, ok := ep.GetProviderSpecificProperty(providerSpecificWeight); ok {
|
||||
weight, err := strconv.ParseInt(prop.Value, 10, 64)
|
||||
weight, err := strconv.ParseInt(prop, 10, 64)
|
||||
if err != nil {
|
||||
log.Errorf("Failed parsing value of %s: %s: %v; using weight of 0", providerSpecificWeight, prop.Value, err)
|
||||
log.Errorf("Failed parsing value of %s: %s: %v; using weight of 0", providerSpecificWeight, prop, err)
|
||||
weight = 0
|
||||
}
|
||||
change.ResourceRecordSet.Weight = aws.Int64(weight)
|
||||
}
|
||||
if prop, ok := ep.GetProviderSpecificProperty(providerSpecificRegion); ok {
|
||||
change.ResourceRecordSet.Region = aws.String(prop.Value)
|
||||
change.ResourceRecordSet.Region = aws.String(prop)
|
||||
}
|
||||
if prop, ok := ep.GetProviderSpecificProperty(providerSpecificFailover); ok {
|
||||
change.ResourceRecordSet.Failover = aws.String(prop.Value)
|
||||
change.ResourceRecordSet.Failover = aws.String(prop)
|
||||
}
|
||||
if _, ok := ep.GetProviderSpecificProperty(providerSpecificMultiValueAnswer); ok {
|
||||
change.ResourceRecordSet.MultiValueAnswer = aws.Bool(true)
|
||||
@ -757,15 +766,15 @@ func (p *AWSProvider) newChange(action string, ep *endpoint.Endpoint) (*Route53C
|
||||
geolocation := &route53.GeoLocation{}
|
||||
useGeolocation := false
|
||||
if prop, ok := ep.GetProviderSpecificProperty(providerSpecificGeolocationContinentCode); ok {
|
||||
geolocation.ContinentCode = aws.String(prop.Value)
|
||||
geolocation.ContinentCode = aws.String(prop)
|
||||
useGeolocation = true
|
||||
} else {
|
||||
if prop, ok := ep.GetProviderSpecificProperty(providerSpecificGeolocationCountryCode); ok {
|
||||
geolocation.CountryCode = aws.String(prop.Value)
|
||||
geolocation.CountryCode = aws.String(prop)
|
||||
useGeolocation = true
|
||||
}
|
||||
if prop, ok := ep.GetProviderSpecificProperty(providerSpecificGeolocationSubdivisionCode); ok {
|
||||
geolocation.SubdivisionCode = aws.String(prop.Value)
|
||||
geolocation.SubdivisionCode = aws.String(prop)
|
||||
useGeolocation = true
|
||||
}
|
||||
}
|
||||
@ -775,7 +784,7 @@ func (p *AWSProvider) newChange(action string, ep *endpoint.Endpoint) (*Route53C
|
||||
}
|
||||
|
||||
if prop, ok := ep.GetProviderSpecificProperty(providerSpecificHealthCheckID); ok {
|
||||
change.ResourceRecordSet.HealthCheckId = aws.String(prop.Value)
|
||||
change.ResourceRecordSet.HealthCheckId = aws.String(prop)
|
||||
}
|
||||
|
||||
if ownedRecord, ok := ep.Labels[endpoint.OwnedRecordLabelKey]; ok {
|
||||
@ -989,13 +998,13 @@ func useAlias(ep *endpoint.Endpoint, preferCNAME bool) bool {
|
||||
// isAWSAlias determines if a given endpoint is supposed to create an AWS Alias record
|
||||
// and (if so) returns the target hosted zone ID
|
||||
func isAWSAlias(ep *endpoint.Endpoint) string {
|
||||
prop, exists := ep.GetProviderSpecificProperty(providerSpecificAlias)
|
||||
if exists && prop.Value == "true" && ep.RecordType == endpoint.RecordTypeCNAME && len(ep.Targets) > 0 {
|
||||
isAlias, exists := ep.GetProviderSpecificProperty(providerSpecificAlias)
|
||||
if exists && isAlias == "true" && ep.RecordType == endpoint.RecordTypeCNAME && 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 {
|
||||
// existing Endpoint where we got the target hosted zone from the Route53 data
|
||||
return hostedZoneID.Value
|
||||
return hostedZoneID
|
||||
}
|
||||
|
||||
// check if the target is in a canonical hosted zone
|
||||
|
@ -494,7 +494,7 @@ func TestAWSRecords(t *testing.T) {
|
||||
records, err := provider.Records(context.Background())
|
||||
require.NoError(t, err)
|
||||
|
||||
validateEndpoints(t, records, []*endpoint.Endpoint{
|
||||
validateEndpoints(t, provider, records, []*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-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"),
|
||||
@ -511,7 +511,7 @@ func TestAWSRecords(t *testing.T) {
|
||||
endpoint.NewEndpointWithTTL("geolocation-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4").WithSetIdentifier("test-set-1").WithProviderSpecific(providerSpecificGeolocationContinentCode, "EU"),
|
||||
endpoint.NewEndpointWithTTL("geolocation-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "4.3.2.1").WithSetIdentifier("test-set-2").WithProviderSpecific(providerSpecificGeolocationCountryCode, "DE"),
|
||||
endpoint.NewEndpointWithTTL("geolocation-subdivision-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4").WithSetIdentifier("test-set-1").WithProviderSpecific(providerSpecificGeolocationSubdivisionCode, "NY"),
|
||||
endpoint.NewEndpointWithTTL("healthcheck-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "foo.example.com").WithSetIdentifier("test-set-1").WithProviderSpecific(providerSpecificWeight, "10").WithProviderSpecific(providerSpecificHealthCheckID, "foo-bar-healthcheck-id"),
|
||||
endpoint.NewEndpointWithTTL("healthcheck-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "foo.example.com").WithSetIdentifier("test-set-1").WithProviderSpecific(providerSpecificWeight, "10").WithProviderSpecific(providerSpecificHealthCheckID, "foo-bar-healthcheck-id").WithProviderSpecific(providerSpecificAlias, "false"),
|
||||
endpoint.NewEndpointWithTTL("healthcheck-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "4.3.2.1").WithSetIdentifier("test-set-2").WithProviderSpecific(providerSpecificWeight, "20").WithProviderSpecific(providerSpecificHealthCheckID, "abc-def-healthcheck-id"),
|
||||
endpoint.NewEndpointWithTTL("mail.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeMX, endpoint.TTL(recordTTL), "10 mailhost1.example.com", "20 mailhost2.example.com"),
|
||||
})
|
||||
@ -529,11 +529,11 @@ func TestAWSAdjustEndpoints(t *testing.T) {
|
||||
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
|
||||
}
|
||||
|
||||
provider.AdjustEndpoints(records)
|
||||
records = provider.AdjustEndpoints(records)
|
||||
|
||||
validateEndpoints(t, records, []*endpoint.Endpoint{
|
||||
validateEndpoints(t, provider, records, []*endpoint.Endpoint{
|
||||
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.NewEndpoint("cname-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.example.com").WithProviderSpecific(providerSpecificAlias, "false"),
|
||||
endpoint.NewEndpoint("cname-test-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "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.RecordTypeCNAME, "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"),
|
||||
@ -1426,7 +1426,7 @@ func TestAWSsubmitChanges(t *testing.T) {
|
||||
records, err := provider.Records(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
validateEndpoints(t, records, endpoints)
|
||||
validateEndpoints(t, provider, records, endpoints)
|
||||
}
|
||||
|
||||
func TestAWSsubmitChangesError(t *testing.T) {
|
||||
@ -1607,8 +1607,11 @@ func TestAWSBatchChangeSetExceedingNameChange(t *testing.T) {
|
||||
require.Equal(t, 0, len(batchCs))
|
||||
}
|
||||
|
||||
func validateEndpoints(t *testing.T, endpoints []*endpoint.Endpoint, expected []*endpoint.Endpoint) {
|
||||
func validateEndpoints(t *testing.T, provider *AWSProvider, endpoints []*endpoint.Endpoint, expected []*endpoint.Endpoint) {
|
||||
assert.True(t, testutils.SameEndpoints(endpoints, expected), "actual and expected endpoints don't match. %+v:%+v", endpoints, expected)
|
||||
|
||||
normalized := provider.AdjustEndpoints(endpoints)
|
||||
assert.True(t, testutils.SameEndpoints(normalized, expected), "actual and normalized endpoints don't match. %+v:%+v", endpoints, normalized)
|
||||
}
|
||||
|
||||
func validateAWSZones(t *testing.T, zones map[string]*route53.HostedZone, expected map[string]*route53.HostedZone) {
|
||||
@ -1840,51 +1843,6 @@ func TestAWSSuitableZones(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestAWSHealthTargetAnnotation(tt *testing.T) {
|
||||
comparator := func(name, previous, current string) bool {
|
||||
return previous == current
|
||||
}
|
||||
for _, test := range []struct {
|
||||
name string
|
||||
current *endpoint.Endpoint
|
||||
desired *endpoint.Endpoint
|
||||
propertyComparator func(name, previous, current string) bool
|
||||
shouldUpdate bool
|
||||
}{
|
||||
{
|
||||
name: "skip AWS target health",
|
||||
current: &endpoint.Endpoint{
|
||||
RecordType: "A",
|
||||
DNSName: "foo.com",
|
||||
ProviderSpecific: []endpoint.ProviderSpecificProperty{
|
||||
{Name: "aws/evaluate-target-health", Value: "true"},
|
||||
},
|
||||
},
|
||||
desired: &endpoint.Endpoint{
|
||||
DNSName: "foo.com",
|
||||
RecordType: "A",
|
||||
ProviderSpecific: []endpoint.ProviderSpecificProperty{
|
||||
{Name: "aws/evaluate-target-health", Value: "false"},
|
||||
},
|
||||
},
|
||||
propertyComparator: comparator,
|
||||
shouldUpdate: false,
|
||||
},
|
||||
} {
|
||||
tt.Run(test.name, func(t *testing.T) {
|
||||
provider := &AWSProvider{}
|
||||
plan := &plan.Plan{
|
||||
Current: []*endpoint.Endpoint{test.current},
|
||||
Desired: []*endpoint.Endpoint{test.desired},
|
||||
PropertyComparator: provider.PropertyValuesEqual,
|
||||
ManagedRecords: []string{endpoint.RecordTypeA, endpoint.RecordTypeCNAME},
|
||||
}
|
||||
plan = plan.Calculate()
|
||||
assert.Equal(t, test.shouldUpdate, len(plan.Changes.UpdateNew) == 1)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func createAWSZone(t *testing.T, provider *AWSProvider, zone *route53.HostedZone) {
|
||||
params := &route53.CreateHostedZoneInput{
|
||||
CallerReference: aws.String("external-dns.alpha.kubernetes.io/test-zone"),
|
||||
@ -1908,7 +1866,7 @@ func setAWSRecords(t *testing.T, provider *AWSProvider, records []*route53.Resou
|
||||
endpoints, err := provider.Records(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
validateEndpoints(t, endpoints, []*endpoint.Endpoint{})
|
||||
validateEndpoints(t, provider, endpoints, []*endpoint.Endpoint{})
|
||||
|
||||
var changes Route53Changes
|
||||
for _, record := range records {
|
||||
@ -2071,13 +2029,13 @@ func TestRequiresDeleteCreate(t *testing.T) {
|
||||
provider, _ := newAWSProvider(t, endpoint.NewDomainFilter([]string{"foo.bar."}), provider.NewZoneIDFilter([]string{}), provider.NewZoneTypeFilter(""), defaultEvaluateTargetHealth, false, nil)
|
||||
|
||||
oldRecordType := endpoint.NewEndpointWithTTL("recordType", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.8.8")
|
||||
newRecordType := endpoint.NewEndpointWithTTL("recordType", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "bar")
|
||||
newRecordType := endpoint.NewEndpointWithTTL("recordType", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "bar").WithProviderSpecific(providerSpecificAlias, "false")
|
||||
|
||||
assert.False(t, provider.requiresDeleteCreate(oldRecordType, oldRecordType), "actual and expected endpoints don't match. %+v:%+v", oldRecordType, oldRecordType)
|
||||
assert.True(t, provider.requiresDeleteCreate(oldRecordType, newRecordType), "actual and expected endpoints don't match. %+v:%+v", oldRecordType, newRecordType)
|
||||
|
||||
oldCNAMEAlias := endpoint.NewEndpointWithTTL("CNAMEAlias", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "bar")
|
||||
newCNAMEAlias := endpoint.NewEndpointWithTTL("CNAMEAlias", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "bar.us-east-1.elb.amazonaws.com")
|
||||
oldCNAMEAlias := endpoint.NewEndpointWithTTL("CNAMEAlias", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "bar").WithProviderSpecific(providerSpecificAlias, "false")
|
||||
newCNAMEAlias := endpoint.NewEndpointWithTTL("CNAMEAlias", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "bar.us-east-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificAlias, "true")
|
||||
|
||||
assert.False(t, provider.requiresDeleteCreate(oldCNAMEAlias, oldCNAMEAlias), "actual and expected endpoints don't match. %+v:%+v", oldCNAMEAlias, oldCNAMEAlias.DNSName)
|
||||
assert.True(t, provider.requiresDeleteCreate(oldCNAMEAlias, newCNAMEAlias), "actual and expected endpoints don't match. %+v:%+v", oldCNAMEAlias, newCNAMEAlias)
|
||||
|
@ -30,6 +30,13 @@ type Provider interface {
|
||||
Records(ctx context.Context) ([]*endpoint.Endpoint, error)
|
||||
ApplyChanges(ctx context.Context, changes *plan.Changes) error
|
||||
PropertyValuesEqual(name string, previous string, current string) bool
|
||||
// AdjustEndpoints canonicalizes a set of candidate endpoints.
|
||||
// It is called with a set of candidate endpoints obtained from the various sources.
|
||||
// It returns a set modified as required by the provider. The provider is responsible for
|
||||
// adding, removing, and modifying the ProviderSpecific properties to match
|
||||
// the endpoints that the provider returns in `Records` so that the change plan will not have
|
||||
// unnecessary (potentially failing) changes. It may also modify other fields, add, or remove
|
||||
// Endpoints. It is permitted to modify the supplied endpoints.
|
||||
AdjustEndpoints(endpoints []*endpoint.Endpoint) []*endpoint.Endpoint
|
||||
GetDomainFilter() endpoint.DomainFilterInterface
|
||||
}
|
||||
|
@ -278,9 +278,9 @@ func endpointToScalewayRecords(zoneName string, ep *endpoint.Endpoint) []*domain
|
||||
}
|
||||
priority := scalewayDefaultPriority
|
||||
if prop, ok := ep.GetProviderSpecificProperty(scalewayPriorityKey); ok {
|
||||
prio, err := strconv.ParseUint(prop.Value, 10, 32)
|
||||
prio, err := strconv.ParseUint(prop, 10, 32)
|
||||
if err != nil {
|
||||
log.Errorf("Failed parsing value of %s: %s: %v; using priority of %d", scalewayPriorityKey, prop.Value, err, scalewayDefaultPriority)
|
||||
log.Errorf("Failed parsing value of %s: %s: %v; using priority of %d", scalewayPriorityKey, prop, err, scalewayDefaultPriority)
|
||||
} else {
|
||||
priority = uint32(prio)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user