From 32b7452fbe23e7cbe8b104a0098ba3f5a7d6bb95 Mon Sep 17 00:00:00 2001 From: Rajat Jindal Date: Thu, 21 Nov 2019 13:32:55 +0530 Subject: [PATCH 1/4] allow to associate dns records with health checks --- provider/aws/aws.go | 9 +++++++++ provider/aws/aws_test.go | 4 ++++ 2 files changed, 13 insertions(+) diff --git a/provider/aws/aws.go b/provider/aws/aws.go index 22d6f2a6f..824018637 100644 --- a/provider/aws/aws.go +++ b/provider/aws/aws.go @@ -50,6 +50,7 @@ const ( providerSpecificGeolocationCountryCode = "aws/geolocation-country-code" providerSpecificGeolocationSubdivisionCode = "aws/geolocation-subdivision-code" providerSpecificMultiValueAnswer = "aws/multi-value-answer" + providerSpecificHealthCheckID = "aws/health-check-id" ) var ( @@ -348,6 +349,10 @@ func (p *AWSProvider) records(ctx context.Context, zones map[string]*route53.Hos default: // one of the above needs to be set, otherwise SetIdentifier doesn't make sense } + + if r.HealthCheckId != nil { + ep.WithProviderSpecific(providerSpecificHealthCheckID, aws.StringValue(r.HealthCheckId)) + } } endpoints = append(endpoints, ep) } @@ -593,6 +598,10 @@ func (p *AWSProvider) newChange(action string, ep *endpoint.Endpoint, recordsCac if useGeolocation { change.ResourceRecordSet.GeoLocation = geolocation } + + if prop, ok := ep.GetProviderSpecificProperty(providerSpecificHealthCheckID); ok { + change.ResourceRecordSet.HealthCheckId = aws.String(prop.Value) + } } return change, dualstack diff --git a/provider/aws/aws_test.go b/provider/aws/aws_test.go index 3de6cff1e..b399da87e 100644 --- a/provider/aws/aws_test.go +++ b/provider/aws/aws_test.go @@ -326,6 +326,8 @@ func TestAWSRecords(t *testing.T) { endpoint.NewEndpointWithTTL("multi-value-answer-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4").WithSetIdentifier("test-set").WithProviderSpecific(providerSpecificMultiValueAnswer, ""), 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("healthcheck-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").WithProviderSpecific(providerSpecificHealthCheckID, "foo-bar-healthcheck-id"), + 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"), }) records, err := provider.Records(context.Background()) @@ -347,6 +349,8 @@ func TestAWSRecords(t *testing.T) { endpoint.NewEndpointWithTTL("multi-value-answer-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4").WithSetIdentifier("test-set").WithProviderSpecific(providerSpecificMultiValueAnswer, ""), 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("healthcheck-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").WithProviderSpecific(providerSpecificHealthCheckID, "foo-bar-healthcheck-id"), + 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"), }) } From 72544c38c381581bfae5cdaafcdf366e1243bb91 Mon Sep 17 00:00:00 2001 From: Rajat Jindal Date: Wed, 5 Feb 2020 21:53:34 +0530 Subject: [PATCH 2/4] allow setting healthCheckId when identifier not provided --- provider/aws/aws.go | 9 +++++---- provider/aws/aws_test.go | 4 ++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/provider/aws/aws.go b/provider/aws/aws.go index 824018637..a7226d98b 100644 --- a/provider/aws/aws.go +++ b/provider/aws/aws.go @@ -349,11 +349,12 @@ func (p *AWSProvider) records(ctx context.Context, zones map[string]*route53.Hos default: // one of the above needs to be set, otherwise SetIdentifier doesn't make sense } - - if r.HealthCheckId != nil { - ep.WithProviderSpecific(providerSpecificHealthCheckID, aws.StringValue(r.HealthCheckId)) - } } + + if r.HealthCheckId != nil { + ep.WithProviderSpecific(providerSpecificHealthCheckID, aws.StringValue(r.HealthCheckId)) + } + endpoints = append(endpoints, ep) } } diff --git a/provider/aws/aws_test.go b/provider/aws/aws_test.go index b399da87e..b56057e8f 100644 --- a/provider/aws/aws_test.go +++ b/provider/aws/aws_test.go @@ -326,7 +326,7 @@ func TestAWSRecords(t *testing.T) { endpoint.NewEndpointWithTTL("multi-value-answer-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4").WithSetIdentifier("test-set").WithProviderSpecific(providerSpecificMultiValueAnswer, ""), 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("healthcheck-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").WithProviderSpecific(providerSpecificHealthCheckID, "foo-bar-healthcheck-id"), + endpoint.NewEndpoint("healthcheck-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "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.RecordTypeA, endpoint.TTL(recordTTL), "4.3.2.1").WithSetIdentifier("test-set-2").WithProviderSpecific(providerSpecificWeight, "20").WithProviderSpecific(providerSpecificHealthCheckID, "abc-def-healthcheck-id"), }) @@ -349,7 +349,7 @@ func TestAWSRecords(t *testing.T) { endpoint.NewEndpointWithTTL("multi-value-answer-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4").WithSetIdentifier("test-set").WithProviderSpecific(providerSpecificMultiValueAnswer, ""), 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("healthcheck-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").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"), 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"), }) } From 625eaf48677e55cd819c661bc5a4d7b8024328db Mon Sep 17 00:00:00 2001 From: Rajat Jindal Date: Tue, 29 Sep 2020 14:39:28 +0530 Subject: [PATCH 3/4] get healthcheckid whether set-identifier is set or not --- provider/aws/aws.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/provider/aws/aws.go b/provider/aws/aws.go index a7226d98b..16db34c12 100644 --- a/provider/aws/aws.go +++ b/provider/aws/aws.go @@ -599,10 +599,10 @@ func (p *AWSProvider) newChange(action string, ep *endpoint.Endpoint, recordsCac if useGeolocation { change.ResourceRecordSet.GeoLocation = geolocation } + } - if prop, ok := ep.GetProviderSpecificProperty(providerSpecificHealthCheckID); ok { - change.ResourceRecordSet.HealthCheckId = aws.String(prop.Value) - } + if prop, ok := ep.GetProviderSpecificProperty(providerSpecificHealthCheckID); ok { + change.ResourceRecordSet.HealthCheckId = aws.String(prop.Value) } return change, dualstack From a3dc3e85797617c32146e1fa5bb4041f67e37eb3 Mon Sep 17 00:00:00 2001 From: Rajat Jindal Date: Tue, 29 Sep 2020 15:10:29 +0530 Subject: [PATCH 4/4] add documentation for aws health check id --- docs/tutorials/aws.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/tutorials/aws.md b/docs/tutorials/aws.md index e708cafe2..36705b9b4 100644 --- a/docs/tutorials/aws.md +++ b/docs/tutorials/aws.md @@ -407,6 +407,13 @@ For any given DNS name, only **one** of the following routing policies can be us * `external-dns.alpha.kubernetes.io/aws-geolocation-subdivision-code` * Multi-value answer:`external-dns.alpha.kubernetes.io/aws-multi-value-answer` +## Associating DNS records with healthchecks + +You can configure Route53 to associate DNS records with healthchecks for automated DNS failover using +`external-dns.alpha.kubernetes.io/health-check-id: ` annotation. + +Note: ExternalDNS does not support creating healthchecks, and assumes that `` already exists. + ## Clean up Make sure to delete all Service objects before terminating the cluster so all load balancers get cleaned up correctly.