Commit 62905a3b authored by Martin Linkhorst's avatar Martin Linkhorst Committed by Henning Jacobs
Browse files

initial support for AWS ALIAS records (#144)

* feat(aws): support for creating DNS records with ALIAS type

* fix(aws): increase code coverage by listing ALIAS records

* chore: update changelog with support for ALIAS records

* ref(aws): generalize naming of ELB to load balancer

* ref(google): remove superflous check for non-existing record

* fix(aws): return the correctly typed alias record
parent 0b43cf51
master Raffo-patch-1 add-infoblox-maintainers bugfix/style-faq cdp changelog-for-v0.7.3 cloudflare-ttl correctly-update-aws-records-when-type-changes dansimone/support-prefer-ingress-annotations dependabot/go_modules/github.com/Azure/azure-sdk-for-go-61.4.0incompatible dependabot/go_modules/github.com/aliyun/alibaba-cloud-sdk-go-1.61.1473 dependabot/go_modules/github.com/exoscale/egoscale-1.19.0 dependabot/go_modules/github.com/projectcontour/contour-1.20.0 dependabot/go_modules/k8s.io/apimachinery-0.23.3 doc/aws-rbac-nodes docs/update-versions eval-target-health fake-source-refactor feature/cloudflare-provider feature/new-provider-digital-ocean fix-1820 fix/fatal-on-first-iteration gh-pages go-1.12.7 gometalinter-timeout google-panic-assignment hotfix/swap-parameters ideahitme-refactor-common-parts improve-logging incubator-kep infoblox-multiple-A-records-fix insensitive-compare ipv6 istalker2-designate labeler linki-patch-1 linki-patch-2 linki-patch-3 linki-patch-4 linki-patch-5 linki-patch-6 logging njuettner-patch-1 njuettner/go_modules/github.com/akamai/AkamaiOPEN-edgegrid-golang-0.9.11 njuettner/go_modules/github.com/alecthomas/kingpin-2.2.6incompatible njuettner/go_modules/github.com/digitalocean/godo-1.34.0 njuettner/go_modules/github.com/pkg/errors-0.9.1 njuettner/go_modules/github.com/prometheus/client_golang-1.5.1 normalize pagination-cloudflare-zones pagination-cloudflare-zones-patch pr/531 pr/624 pr/674 pr/675 pr/697 pr/702 provider-specific provider-specific2 raffo-fix-2348 raffo/add-dependabot raffo/add-kustomize-base raffo/add-trivy-scanning raffo/arm raffo/arm32v7 raffo/bump-ci-timeout raffo/bump-cloudbuild-timeout raffo/bump-deps-sec raffo/bump-kustomize raffo/bump-kustomize-1 raffo/bump-kustomize-version-0.7.5 raffo/bump-modules raffo/codeQL raffo/drop-the-changelog raffo/e2e-aws raffo/edit-infoblox-maintainers raffo/fix-1820 raffo/fix-1936 raffo/fix-build raffo/fix-dependabot raffo/fix-ns-deletion raffo/fix-scaleway-security raffo/fix-that-typo raffo/fix-trivy raffo/fix-trivy-again raffo/fix-vulnerabilities raffo/goarm raffo/gpr-docker-image raffo/knolog raffo/kustomize-endpoints raffo/multiarch raffo/multiarch-docs raffo/new-ingress-resource raffo/new-maintainers raffo/provider-structure-refactor raffo/release-conventions raffo/release-note-patch raffo/release-script raffo/release-script-update raffo/release-v0.7.2 raffo/remove-azure-test raffo/remove-broken-link raffo/remove-incubator-readme raffo/remove-masters raffo/revert-tzdata raffo/split-sources raffo/update-kustomize-080 raffo/update-v0.10-role raffo/use-actions raffo/v0.7.6 ratelimit refactor-common-parts refactor/dns-provider-interface revert-736-fix-domainfilter revert-963-ns1-provider-ammended rework-source-registration sagor999/infoblox-multiple-A-records stability-matrix test-ideahitme/demonstrate-plan-miscalc test-things travis-test update-changelog v0.5.15 v0.5.17 v0.5.9-changelog validate-txt-prefix v1.0.0-mf v0.10.2 v0.10.1 v0.10.0 v0.9.0 v0.8.0 v0.7.6 v0.7.5 v0.7.4 v0.7.3 v0.7.2 v0.7.1 v0.7.0 v0.6.0 v0.5.18 v0.5.17 v0.5.16 v0.5.15 v0.5.14 v0.5.13 v0.5.12 v0.5.11 v0.5.10 v0.5.9 v0.5.8 v0.5.7 v0.5.6 v0.5.5 v0.5.4 v0.5.3 v0.5.2 v0.5.1 v0.5.0 v0.5.0-alpha.3 v0.5.0-alpha.2 v0.5.0-alpha.1 v0.5.0-alpha.0 v0.4.8 v0.4.7 v0.4.6 v0.4.5 v0.4.4 v0.4.3 v0.4.2 v0.4.1 v0.4.0 v0.4.0-alpha.2 v0.4.0-alpha.1 v0.4.0-alpha.0 v0.3.0 v0.3.0-beta.2 v0.3.0-beta.1 v0.3.0-beta.0 v0.3.0-alpha.5 v0.3.0-alpha.4 v0.3.0-alpha.3 v0.3.0-alpha.2 v0.3.0-alpha.1 v0.3.0-alpha.0 external-dns-helm-chart-1.7.1 external-dns-helm-chart-1.7.0 external-dns-helm-chart-1.6.0 external-dns-helm-chart-1.5.0 external-dns-helm-chart-1.4.1 external-dns-helm-chart-1.4.0 external-dns-helm-chart-1.3.2 external-dns-helm-chart-1.3.1 external-dns-helm-chart-1.3.0 external-dns-helm-chart-1.2.0
No related merge requests found
Showing with 216 additions and 46 deletions
+216 -46
Features:
- Route 53: Support creation of ALIAS records when endpoint target is a ELB/ALB.
- Ownership via TXT records
1. Create TXT records to mark the records managed by External DNS
2. Supported for AWS Route53 and Google CloudDNS
......
......@@ -30,7 +30,30 @@ import (
)
const (
hostedZonePrefix = "/hostedzone/"
hostedZonePrefix = "/hostedzone/"
elbHostnameSuffix = ".elb.amazonaws.com"
evaluateTargetHealth = true
recordTTL = 300
)
var (
// see: https://docs.aws.amazon.com/general/latest/gr/rande.html
canonicalHostedZones = map[string]string{
"us-east-1" + elbHostnameSuffix: "Z35SXDOTRQ7X7K",
"us-east-2" + elbHostnameSuffix: "Z3AADJGX6KTTL2",
"us-west-1" + elbHostnameSuffix: "Z368ELLRRE2KJ0",
"us-west-2" + elbHostnameSuffix: "Z1H1FL5HABSF5",
"ca-central-1" + elbHostnameSuffix: "ZQSVJUPU6J1EY",
"ap-south-1" + elbHostnameSuffix: "ZP97RAFLXTNZK",
"ap-northeast-2" + elbHostnameSuffix: "ZWKZPGTI48KDX",
"ap-southeast-1" + elbHostnameSuffix: "Z1LMS91P8CMLE5",
"ap-southeast-2" + elbHostnameSuffix: "Z1GM3OXH4ZPM65",
"ap-northeast-1" + elbHostnameSuffix: "Z14GRHDCWA56QT",
"eu-central-1" + elbHostnameSuffix: "Z215JYRZR1TBD5",
"eu-west-1" + elbHostnameSuffix: "Z32O12XQLNTSW2",
"eu-west-2" + elbHostnameSuffix: "ZHURV8PSTC4K8",
"sa-east-1" + elbHostnameSuffix: "Z2P70J7HTTTPLU",
}
)
// Route53API is the subset of the AWS Route53 API that we actually use. Add methods as required. Signatures must match exactly.
......@@ -85,6 +108,10 @@ func (p *AWSProvider) Records(zone string) ([]*endpoint.Endpoint, error) {
for _, rr := range r.ResourceRecords {
endpoints = append(endpoints, endpoint.NewEndpoint(aws.StringValue(r.Name), aws.StringValue(rr.Value), aws.StringValue(r.Type)))
}
if r.AliasTarget != nil {
endpoints = append(endpoints, endpoint.NewEndpoint(aws.StringValue(r.Name), aws.StringValue(r.AliasTarget.DNSName), "ALIAS"))
}
}
return true
......@@ -175,19 +202,43 @@ func newChange(action string, endpoint *endpoint.Endpoint) *route53.Change {
Action: aws.String(action),
ResourceRecordSet: &route53.ResourceRecordSet{
Name: aws.String(endpoint.DNSName),
ResourceRecords: []*route53.ResourceRecord{
{
Value: aws.String(endpoint.Target),
},
},
TTL: aws.Int64(300),
Type: aws.String(suitableType(endpoint)),
},
}
if isAWSLoadBalancer(endpoint.Target) {
change.ResourceRecordSet.Type = aws.String(route53.RRTypeA)
change.ResourceRecordSet.AliasTarget = &route53.AliasTarget{
DNSName: aws.String(endpoint.Target),
HostedZoneId: aws.String(canonicalHostedZone(endpoint.Target)),
EvaluateTargetHealth: aws.Bool(evaluateTargetHealth),
}
} else {
change.ResourceRecordSet.Type = aws.String(suitableType(endpoint))
change.ResourceRecordSet.TTL = aws.Int64(recordTTL)
change.ResourceRecordSet.ResourceRecords = []*route53.ResourceRecord{
{
Value: aws.String(endpoint.Target),
},
}
}
return change
}
func isAWSLoadBalancer(hostname string) bool {
return canonicalHostedZone(hostname) != ""
}
func canonicalHostedZone(hostname string) string {
for suffix, zone := range canonicalHostedZones {
if strings.HasSuffix(hostname, suffix) {
return zone
}
}
return ""
}
func expandedHostedZoneID(zone string) string {
return hostedZonePrefix + strings.TrimPrefix(zone, hostedZonePrefix)
}
......@@ -19,6 +19,8 @@ package provider
import (
"fmt"
"net"
"reflect"
"strings"
"testing"
"github.com/aws/aws-sdk-go/aws"
......@@ -98,6 +100,12 @@ func (r *Route53APIStub) ChangeResourceRecordSets(input *route53.ChangeResourceR
}
}
change.ResourceRecordSet.Name = aws.String(ensureTrailingDot(aws.StringValue(change.ResourceRecordSet.Name)))
if change.ResourceRecordSet.AliasTarget != nil {
change.ResourceRecordSet.AliasTarget.DNSName = aws.String(ensureTrailingDot(aws.StringValue(change.ResourceRecordSet.AliasTarget.DNSName)))
}
key := aws.StringValue(change.ResourceRecordSet.Name) + "::" + aws.StringValue(change.ResourceRecordSet.Type)
switch aws.StringValue(change.Action) {
case route53.ChangeActionCreate:
......@@ -134,6 +142,7 @@ func (r *Route53APIStub) CreateHostedZone(input *route53.CreateHostedZoneInput)
func TestAWSRecords(t *testing.T) {
provider := newAWSProvider(t, false, []*endpoint.Endpoint{
endpoint.NewEndpoint("list-test.ext-dns-test.teapot.zalan.do", "8.8.8.8", "A"),
endpoint.NewEndpoint("list-test-alias.ext-dns-test.teapot.zalan.do", "foo.eu-central-1.elb.amazonaws.com", "ALIAS"),
})
records, err := provider.Records(testZone)
......@@ -142,6 +151,7 @@ func TestAWSRecords(t *testing.T) {
}
validateEndpoints(t, records, []*endpoint.Endpoint{
endpoint.NewEndpoint("list-test.ext-dns-test.teapot.zalan.do", "8.8.8.8", "A"),
endpoint.NewEndpoint("list-test-alias.ext-dns-test.teapot.zalan.do", "foo.eu-central-1.elb.amazonaws.com", "ALIAS"),
})
}
......@@ -379,7 +389,7 @@ func TestAWSCreateRecordsCNAME(t *testing.T) {
provider := newAWSProvider(t, false, []*endpoint.Endpoint{})
records := []*endpoint.Endpoint{
endpoint.NewEndpoint("create-test.ext-dns-test.teapot.zalan.do", "foo.elb.amazonaws.com", ""),
endpoint.NewEndpoint("create-test.ext-dns-test.teapot.zalan.do", "foo.example.org", ""),
}
if err := provider.CreateRecords(testZone, records); err != nil {
......@@ -392,20 +402,20 @@ func TestAWSCreateRecordsCNAME(t *testing.T) {
}
validateEndpoints(t, records, []*endpoint.Endpoint{
endpoint.NewEndpoint("create-test.ext-dns-test.teapot.zalan.do", "foo.elb.amazonaws.com", "CNAME"),
endpoint.NewEndpoint("create-test.ext-dns-test.teapot.zalan.do", "foo.example.org", "CNAME"),
})
}
func TestAWSUpdateRecordsCNAME(t *testing.T) {
provider := newAWSProvider(t, false, []*endpoint.Endpoint{
endpoint.NewEndpoint("update-test.ext-dns-test.teapot.zalan.do", "foo.elb.amazonaws.com", "CNAME"),
endpoint.NewEndpoint("update-test.ext-dns-test.teapot.zalan.do", "foo.example.org", "CNAME"),
})
currentRecords := []*endpoint.Endpoint{
endpoint.NewEndpoint("update-test.ext-dns-test.teapot.zalan.do", "foo.elb.amazonaws.com", ""),
endpoint.NewEndpoint("update-test.ext-dns-test.teapot.zalan.do", "foo.example.org", ""),
}
updatedRecords := []*endpoint.Endpoint{
endpoint.NewEndpoint("update-test.ext-dns-test.teapot.zalan.do", "bar.elb.amazonaws.com", ""),
endpoint.NewEndpoint("update-test.ext-dns-test.teapot.zalan.do", "bar.example.org", ""),
}
if err := provider.UpdateRecords(testZone, updatedRecords, currentRecords); err != nil {
......@@ -418,17 +428,17 @@ func TestAWSUpdateRecordsCNAME(t *testing.T) {
}
validateEndpoints(t, records, []*endpoint.Endpoint{
endpoint.NewEndpoint("update-test.ext-dns-test.teapot.zalan.do", "bar.elb.amazonaws.com", "CNAME"),
endpoint.NewEndpoint("update-test.ext-dns-test.teapot.zalan.do", "bar.example.org", "CNAME"),
})
}
func TestAWSDeleteRecordsCNAME(t *testing.T) {
provider := newAWSProvider(t, false, []*endpoint.Endpoint{
endpoint.NewEndpoint("delete-test.ext-dns-test.teapot.zalan.do", "baz.elb.amazonaws.com", "CNAME"),
endpoint.NewEndpoint("delete-test.ext-dns-test.teapot.zalan.do", "baz.example.org", "CNAME"),
})
currentRecords := []*endpoint.Endpoint{
endpoint.NewEndpoint("delete-test.ext-dns-test.teapot.zalan.do", "baz.elb.amazonaws.com", ""),
endpoint.NewEndpoint("delete-test.ext-dns-test.teapot.zalan.do", "baz.example.org", ""),
}
if err := provider.DeleteRecords(testZone, currentRecords); err != nil {
......@@ -445,23 +455,23 @@ func TestAWSDeleteRecordsCNAME(t *testing.T) {
func TestAWSApplyChangesCNAME(t *testing.T) {
provider := newAWSProvider(t, false, []*endpoint.Endpoint{
endpoint.NewEndpoint("update-test.ext-dns-test.teapot.zalan.do", "foo.elb.amazonaws.com", "CNAME"),
endpoint.NewEndpoint("delete-test.ext-dns-test.teapot.zalan.do", "qux.elb.amazonaws.com", "CNAME"),
endpoint.NewEndpoint("update-test.ext-dns-test.teapot.zalan.do", "foo.example.org", "CNAME"),
endpoint.NewEndpoint("delete-test.ext-dns-test.teapot.zalan.do", "qux.example.org", "CNAME"),
})
createRecords := []*endpoint.Endpoint{
endpoint.NewEndpoint("create-test.ext-dns-test.teapot.zalan.do", "foo.elb.amazonaws.com", ""),
endpoint.NewEndpoint("create-test.ext-dns-test.teapot.zalan.do", "foo.example.org", ""),
}
currentRecords := []*endpoint.Endpoint{
endpoint.NewEndpoint("update-test.ext-dns-test.teapot.zalan.do", "bar.elb.amazonaws.com", ""),
endpoint.NewEndpoint("update-test.ext-dns-test.teapot.zalan.do", "bar.example.org", ""),
}
updatedRecords := []*endpoint.Endpoint{
endpoint.NewEndpoint("update-test.ext-dns-test.teapot.zalan.do", "baz.elb.amazonaws.com", ""),
endpoint.NewEndpoint("update-test.ext-dns-test.teapot.zalan.do", "baz.example.org", ""),
}
deleteRecords := []*endpoint.Endpoint{
endpoint.NewEndpoint("delete-test.ext-dns-test.teapot.zalan.do", "qux.elb.amazonaws.com", ""),
endpoint.NewEndpoint("delete-test.ext-dns-test.teapot.zalan.do", "qux.example.org", ""),
}
changes := &plan.Changes{
......@@ -481,11 +491,109 @@ func TestAWSApplyChangesCNAME(t *testing.T) {
}
validateEndpoints(t, records, []*endpoint.Endpoint{
endpoint.NewEndpoint("create-test.ext-dns-test.teapot.zalan.do", "foo.elb.amazonaws.com", "CNAME"),
endpoint.NewEndpoint("update-test.ext-dns-test.teapot.zalan.do", "baz.elb.amazonaws.com", "CNAME"),
endpoint.NewEndpoint("create-test.ext-dns-test.teapot.zalan.do", "foo.example.org", "CNAME"),
endpoint.NewEndpoint("update-test.ext-dns-test.teapot.zalan.do", "baz.example.org", "CNAME"),
})
}
func TestAWSCreateRecordsWithCNAME(t *testing.T) {
provider := newAWSProvider(t, false, []*endpoint.Endpoint{})
records := []*endpoint.Endpoint{
{DNSName: "create-test.ext-dns-test.teapot.zalan.do", Target: "foo.example.org"},
}
if err := provider.CreateRecords(testZone, records); err != nil {
t.Fatal(err)
}
recordSets := listRecords(t, provider.Client)
validateRecords(t, recordSets, []*route53.ResourceRecordSet{
{
Name: aws.String("create-test.ext-dns-test.teapot.zalan.do."),
Type: aws.String("CNAME"),
TTL: aws.Int64(300),
ResourceRecords: []*route53.ResourceRecord{
{
Value: aws.String("foo.example.org"),
},
},
},
})
}
func TestAWSCreateRecordsWithALIAS(t *testing.T) {
provider := newAWSProvider(t, false, []*endpoint.Endpoint{})
records := []*endpoint.Endpoint{
{DNSName: "create-test.ext-dns-test.teapot.zalan.do", Target: "foo.eu-central-1.elb.amazonaws.com"},
}
if err := provider.CreateRecords(testZone, records); err != nil {
t.Fatal(err)
}
recordSets := listRecords(t, provider.Client)
validateRecords(t, recordSets, []*route53.ResourceRecordSet{
{
AliasTarget: &route53.AliasTarget{
DNSName: aws.String("foo.eu-central-1.elb.amazonaws.com."),
EvaluateTargetHealth: aws.Bool(true),
HostedZoneId: aws.String("Z215JYRZR1TBD5"),
},
Name: aws.String("create-test.ext-dns-test.teapot.zalan.do."),
Type: aws.String("A"),
},
})
}
func TestAWSisAWSLoadBalancer(t *testing.T) {
for _, tc := range []struct {
hostname string
expected bool
}{
{"bar.eu-central-1.elb.amazonaws.com", true},
{"foo.example.org", false},
} {
isLB := isAWSLoadBalancer(tc.hostname)
if isLB != tc.expected {
t.Errorf("expected %t, got %t", tc.expected, isLB)
}
}
}
func TestAWSCanonicalHostedZone(t *testing.T) {
for _, tc := range []struct {
hostname string
expected string
}{
{"foo.us-east-1.elb.amazonaws.com", "Z35SXDOTRQ7X7K"},
{"foo.us-east-2.elb.amazonaws.com", "Z3AADJGX6KTTL2"},
{"foo.us-west-1.elb.amazonaws.com", "Z368ELLRRE2KJ0"},
{"foo.us-west-2.elb.amazonaws.com", "Z1H1FL5HABSF5"},
{"foo.ca-central-1.elb.amazonaws.com", "ZQSVJUPU6J1EY"},
{"foo.ap-south-1.elb.amazonaws.com", "ZP97RAFLXTNZK"},
{"foo.ap-northeast-2.elb.amazonaws.com", "ZWKZPGTI48KDX"},
{"foo.ap-southeast-1.elb.amazonaws.com", "Z1LMS91P8CMLE5"},
{"foo.ap-southeast-2.elb.amazonaws.com", "Z1GM3OXH4ZPM65"},
{"foo.ap-northeast-1.elb.amazonaws.com", "Z14GRHDCWA56QT"},
{"foo.eu-central-1.elb.amazonaws.com", "Z215JYRZR1TBD5"},
{"foo.eu-west-1.elb.amazonaws.com", "Z32O12XQLNTSW2"},
{"foo.eu-west-2.elb.amazonaws.com", "ZHURV8PSTC4K8"},
{"foo.sa-east-1.elb.amazonaws.com", "Z2P70J7HTTTPLU"},
{"foo.example.org", ""},
} {
zone := canonicalHostedZone(tc.hostname)
if zone != tc.expected {
t.Errorf("expected %v, got %v", tc.expected, zone)
}
}
}
func TestAWSSanitizeZone(t *testing.T) {
provider := newAWSProvider(t, false, []*endpoint.Endpoint{
endpoint.NewEndpoint("list-test.ext-dns-test.teapot.zalan.do", "8.8.8.8", "A"),
......@@ -510,12 +618,6 @@ func TestAWSSanitizeZone(t *testing.T) {
})
}
func validateEndpoints(t *testing.T, endpoints []*endpoint.Endpoint, expected []*endpoint.Endpoint) {
if !testutils.SameEndpoints(endpoints, expected) {
t.Fatalf("expected %v, got %v", expected, endpoints)
}
}
func newAWSProvider(t *testing.T, dryRun bool, records []*endpoint.Endpoint) *AWSProvider {
client := NewRoute53APIStub()
......@@ -554,10 +656,10 @@ func setupRecords(t *testing.T, provider *AWSProvider, endpoints []*endpoint.End
validateEndpoints(t, records, endpoints)
}
func clearRecords(t *testing.T, provider *AWSProvider) {
func listRecords(t *testing.T, client Route53API) []*route53.ResourceRecordSet {
recordSets := []*route53.ResourceRecordSet{}
if err := provider.Client.ListResourceRecordSetsPages(&route53.ListResourceRecordSetsInput{
HostedZoneId: aws.String(testZone),
if err := client.ListResourceRecordSetsPages(&route53.ListResourceRecordSetsInput{
HostedZoneId: aws.String(expandedHostedZoneID(testZone)),
}, func(resp *route53.ListResourceRecordSetsOutput, _ bool) bool {
for _, recordSet := range resp.ResourceRecordSets {
switch aws.StringValue(recordSet.Type) {
......@@ -569,6 +671,11 @@ func clearRecords(t *testing.T, provider *AWSProvider) {
}); err != nil {
t.Fatal(err)
}
return recordSets
}
func clearRecords(t *testing.T, provider *AWSProvider) {
recordSets := listRecords(t, provider.Client)
changes := make([]*route53.Change, 0, len(recordSets))
for _, recordSet := range recordSets {
......@@ -596,3 +703,25 @@ func clearRecords(t *testing.T, provider *AWSProvider) {
validateEndpoints(t, records, []*endpoint.Endpoint{})
}
func validateEndpoints(t *testing.T, endpoints []*endpoint.Endpoint, expected []*endpoint.Endpoint) {
if !testutils.SameEndpoints(endpoints, expected) {
t.Errorf("expected %v, got %v", expected, endpoints)
}
}
func validateRecords(t *testing.T, records []*route53.ResourceRecordSet, expected []*route53.ResourceRecordSet) {
if len(records) != len(expected) {
t.Errorf("expected %d records, got %d", len(records), len(expected))
}
for i := range records {
if !reflect.DeepEqual(records[i], expected[i]) {
t.Errorf("record is wrong")
}
}
}
func ensureTrailingDot(hostname string) string {
return strings.TrimSuffix(hostname, ".") + "."
}
......@@ -17,8 +17,6 @@ limitations under the License.
package provider
import (
"strings"
log "github.com/Sirupsen/logrus"
"golang.org/x/net/context"
......@@ -170,9 +168,7 @@ func (p *googleProvider) CreateZone(name, domain string) error {
func (p *googleProvider) DeleteZone(name string) error {
err := p.managedZonesClient.Delete(p.project, name).Do()
if err != nil {
if !isNotFound(err) {
return err
}
return err
}
return nil
......@@ -269,9 +265,7 @@ func (p *googleProvider) submitChange(zone string, change *dns.Change) error {
_, err := p.changesClient.Create(p.project, zone, change).Do()
if err != nil {
if !isNotFound(err) {
return err
}
return err
}
return nil
......@@ -297,8 +291,3 @@ func newRecord(endpoint *endpoint.Endpoint) *dns.ResourceRecordSet {
Type: suitableType(endpoint),
}
}
// isNotFound returns true if a given error is due to a resource not being found.
func isNotFound(err error) bool {
return strings.Contains(err.Error(), "notFound")
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment