diff --git a/provider/pdns/pdns.go b/provider/pdns/pdns.go index 1c83a091e4..fbc7cc22fa 100644 --- a/provider/pdns/pdns.go +++ b/provider/pdns/pdns.go @@ -316,12 +316,15 @@ func (p *PDNSProvider) ConvertEndpointsToZones(eps []*endpoint.Endpoint, changet for _, t := range ep.Targets { if ep.RecordType == "CNAME" || ep.RecordType == "ALIAS" { t = provider.EnsureTrailingDot(t) - if t != zone.Name && !strings.HasSuffix(t, "."+zone.Name) { - RecordType_ = "ALIAS" - } } records = append(records, pgo.Record{Content: t}) } + + if dnsname == zone.Name && ep.RecordType == "CNAME" { + log.Debugf("Converting APEX record %s from CNAME to ALIAS", dnsname) + RecordType_ = "ALIAS" + } + rrset := pgo.RrSet{ Name: dnsname, Type_: RecordType_, diff --git a/provider/pdns/pdns_test.go b/provider/pdns/pdns_test.go index 2837ef81ee..01489da9c7 100644 --- a/provider/pdns/pdns_test.go +++ b/provider/pdns/pdns_test.go @@ -178,6 +178,12 @@ var ( endpoint.NewEndpointWithTTL("test.simexample.com", endpoint.RecordTypeA, endpoint.TTL(300), "9.9.9.9"), endpoint.NewEndpointWithTTL("test.simexample.com", endpoint.RecordTypeTXT, endpoint.TTL(300), "\"heritage=external-dns,external-dns/owner=tower-pdns\""), } + endpointsApexRecords = []*endpoint.Endpoint{ + endpoint.NewEndpointWithTTL("cname.example.com", endpoint.RecordTypeTXT, endpoint.TTL(300), "\"heritage=external-dns,external-dns/owner=tower-pdns\""), + endpoint.NewEndpointWithTTL("cname.example.com", endpoint.RecordTypeCNAME, endpoint.TTL(300), "example.by.any.other.name.com"), + endpoint.NewEndpointWithTTL("example.com", endpoint.RecordTypeTXT, endpoint.TTL(300), "\"heritage=external-dns,external-dns/owner=tower-pdns\""), + endpoint.NewEndpointWithTTL("example.com", endpoint.RecordTypeCNAME, endpoint.TTL(300), "example.by.any.other.name.com"), + } ZoneEmpty = pgo.Zone{ // Opaque zone id (string), assigned by the server, should not be interpreted by the application. Guaranteed to be safe for embedding in URLs. @@ -484,6 +490,72 @@ var ( }, } + ZoneEmptyToApexPatch = pgo.Zone{ + Id: "example.com.", + Name: "example.com.", + Type_: "Zone", + Url: "/api/v1/servers/localhost/zones/example.com.", + Kind: "Native", + Rrsets: []pgo.RrSet{ + { + Name: "cname.example.com.", + Type_: "CNAME", + Ttl: 300, + Changetype: "REPLACE", + Records: []pgo.Record{ + { + Content: "example.by.any.other.name.com.", + Disabled: false, + SetPtr: false, + }, + }, + Comments: []pgo.Comment(nil), + }, + { + Name: "cname.example.com.", + Type_: "TXT", + Ttl: 300, + Changetype: "REPLACE", + Records: []pgo.Record{ + { + Content: "\"heritage=external-dns,external-dns/owner=tower-pdns\"", + Disabled: false, + SetPtr: false, + }, + }, + Comments: []pgo.Comment(nil), + }, + { + Name: "example.com.", + Type_: "ALIAS", + Ttl: 300, + Changetype: "REPLACE", + Records: []pgo.Record{ + { + Content: "example.by.any.other.name.com.", + Disabled: false, + SetPtr: false, + }, + }, + Comments: []pgo.Comment(nil), + }, + { + Name: "example.com.", + Type_: "TXT", + Ttl: 300, + Changetype: "REPLACE", + Records: []pgo.Record{ + { + Content: "\"heritage=external-dns,external-dns/owner=tower-pdns\"", + Disabled: false, + SetPtr: false, + }, + }, + Comments: []pgo.Comment(nil), + }, + }, + } + DomainFilterListSingle = endpoint.DomainFilter{ Filters: []string{ "example.com", @@ -871,6 +943,11 @@ func (suite *NewPDNSProviderTestSuite) TestPDNSConvertEndpointsToZones() { } } } + + // Check endpoints of type CNAME are converted to ALIAS on the domain apex + zlist, err = p.ConvertEndpointsToZones(endpointsApexRecords, PdnsReplace) + assert.Nil(suite.T(), err) + assert.Equal(suite.T(), []pgo.Zone{ZoneEmptyToApexPatch}, zlist) } func (suite *NewPDNSProviderTestSuite) TestPDNSConvertEndpointsToZonesPartitionZones() {