diff --git a/registry/txt.go b/registry/txt.go index e00136cc9..f7d79a686 100644 --- a/registry/txt.go +++ b/registry/txt.go @@ -30,7 +30,10 @@ import ( "sigs.k8s.io/external-dns/provider" ) -const recordTemplate = "%{record_type}" +const ( + recordTemplate = "%{record_type}" + providerSpecificForceUpdate = "txt/force-update" +) // TXTRegistry implements registry interface with ownership implemented via associated TXT records type TXTRegistry struct { @@ -172,7 +175,7 @@ func (im *TXTRegistry) Records(ctx context.Context) ([]*endpoint.Endpoint, error desiredTXTs := im.generateTXTRecord(ep) for _, desiredTXT := range desiredTXTs { if _, exists := txtRecordsMap[desiredTXT.DNSName]; !exists { - ep.ForceUpdate = true + ep.WithProviderSpecific(providerSpecificForceUpdate, "true") } } } @@ -283,6 +286,9 @@ func (im *TXTRegistry) ApplyChanges(ctx context.Context, changes *plan.Changes) // PropertyValuesEqual compares two attribute values for equality func (im *TXTRegistry) PropertyValuesEqual(name string, previous string, current string) bool { + if name == "txt/force-update" { + return false + } return im.provider.PropertyValuesEqual(name, previous, current) } diff --git a/registry/txt_test.go b/registry/txt_test.go index 0e1fe3c83..2493fbb11 100644 --- a/registry/txt_test.go +++ b/registry/txt_test.go @@ -868,71 +868,75 @@ func testTXTRegistryMissingRecordsNoPrefix(t *testing.T) { }) expectedRecords := []*endpoint.Endpoint{ { - DNSName: "oldformat.test-zone.example.org", - Targets: endpoint.Targets{"foo.loadbalancer.com"}, - RecordType: endpoint.RecordTypeCNAME, - ForceUpdate: true, + DNSName: "oldformat.test-zone.example.org", + Targets: endpoint.Targets{"foo.loadbalancer.com"}, + RecordType: endpoint.RecordTypeCNAME, Labels: map[string]string{ // owner was added from the TXT record's target endpoint.OwnerLabelKey: "owner", }, - }, - { - DNSName: "oldformat2.test-zone.example.org", - Targets: endpoint.Targets{"bar.loadbalancer.com"}, - RecordType: endpoint.RecordTypeA, - ForceUpdate: true, - Labels: map[string]string{ - endpoint.OwnerLabelKey: "owner", + ProviderSpecific: []endpoint.ProviderSpecificProperty{ + { + Name: "txt/force-update", + Value: "true", + }, }, }, { - DNSName: "newformat.test-zone.example.org", - Targets: endpoint.Targets{"foobar.nameserver.com"}, - RecordType: endpoint.RecordTypeNS, - ForceUpdate: false, + DNSName: "oldformat2.test-zone.example.org", + Targets: endpoint.Targets{"bar.loadbalancer.com"}, + RecordType: endpoint.RecordTypeA, + Labels: map[string]string{ + endpoint.OwnerLabelKey: "owner", + }, + ProviderSpecific: []endpoint.ProviderSpecificProperty{ + { + Name: "txt/force-update", + Value: "true", + }, + }, + }, + { + DNSName: "newformat.test-zone.example.org", + Targets: endpoint.Targets{"foobar.nameserver.com"}, + RecordType: endpoint.RecordTypeNS, Labels: map[string]string{ endpoint.OwnerLabelKey: "owner", }, }, // Only TXT records with the wrong heritage are returned by Records() { - DNSName: "noheritage.test-zone.example.org", - Targets: endpoint.Targets{"random"}, - RecordType: endpoint.RecordTypeTXT, - ForceUpdate: false, + DNSName: "noheritage.test-zone.example.org", + Targets: endpoint.Targets{"random"}, + RecordType: endpoint.RecordTypeTXT, Labels: map[string]string{ // No owner because it's not external-dns heritage endpoint.OwnerLabelKey: "", }, }, { - DNSName: "oldformat-otherowner.test-zone.example.org", - Targets: endpoint.Targets{"bar.loadbalancer.com"}, - RecordType: endpoint.RecordTypeA, - ForceUpdate: false, + DNSName: "oldformat-otherowner.test-zone.example.org", + Targets: endpoint.Targets{"bar.loadbalancer.com"}, + RecordType: endpoint.RecordTypeA, Labels: map[string]string{ // Records() retrieves all the records of the zone, no matter the owner endpoint.OwnerLabelKey: "otherowner", }, }, { - DNSName: "unmanaged1.test-zone.example.org", - Targets: endpoint.Targets{"unmanaged1.loadbalancer.com"}, - RecordType: endpoint.RecordTypeA, - ForceUpdate: false, + DNSName: "unmanaged1.test-zone.example.org", + Targets: endpoint.Targets{"unmanaged1.loadbalancer.com"}, + RecordType: endpoint.RecordTypeA, }, { - DNSName: "unmanaged2.test-zone.example.org", - Targets: endpoint.Targets{"unmanaged2.loadbalancer.com"}, - RecordType: endpoint.RecordTypeCNAME, - ForceUpdate: false, + DNSName: "unmanaged2.test-zone.example.org", + Targets: endpoint.Targets{"unmanaged2.loadbalancer.com"}, + RecordType: endpoint.RecordTypeCNAME, }, { - DNSName: "this-is-a-63-characters-long-label-that-we-do-expect-will-work.test-zone.example.org", - Targets: endpoint.Targets{"foo.loadbalancer.com"}, - RecordType: endpoint.RecordTypeCNAME, - ForceUpdate: false, + DNSName: "this-is-a-63-characters-long-label-that-we-do-expect-will-work.test-zone.example.org", + Targets: endpoint.Targets{"foo.loadbalancer.com"}, + RecordType: endpoint.RecordTypeCNAME, Labels: map[string]string{ endpoint.OwnerLabelKey: "owner", }, @@ -967,64 +971,69 @@ func testTXTRegistryMissingRecordsWithPrefix(t *testing.T) { }) expectedRecords := []*endpoint.Endpoint{ { - DNSName: "oldformat.test-zone.example.org", - Targets: endpoint.Targets{"foo.loadbalancer.com"}, - RecordType: endpoint.RecordTypeCNAME, - ForceUpdate: true, + DNSName: "oldformat.test-zone.example.org", + Targets: endpoint.Targets{"foo.loadbalancer.com"}, + RecordType: endpoint.RecordTypeCNAME, Labels: map[string]string{ // owner was added from the TXT record's target endpoint.OwnerLabelKey: "owner", }, + ProviderSpecific: []endpoint.ProviderSpecificProperty{ + { + Name: "txt/force-update", + Value: "true", + }, + }, }, { - DNSName: "oldformat2.test-zone.example.org", - Targets: endpoint.Targets{"bar.loadbalancer.com"}, - RecordType: endpoint.RecordTypeA, - ForceUpdate: true, + DNSName: "oldformat2.test-zone.example.org", + Targets: endpoint.Targets{"bar.loadbalancer.com"}, + RecordType: endpoint.RecordTypeA, + Labels: map[string]string{ + endpoint.OwnerLabelKey: "owner", + }, + ProviderSpecific: []endpoint.ProviderSpecificProperty{ + { + Name: "txt/force-update", + Value: "true", + }, + }, + }, + { + DNSName: "newformat.test-zone.example.org", + Targets: endpoint.Targets{"foobar.nameserver.com"}, + RecordType: endpoint.RecordTypeNS, Labels: map[string]string{ endpoint.OwnerLabelKey: "owner", }, }, { - DNSName: "newformat.test-zone.example.org", - Targets: endpoint.Targets{"foobar.nameserver.com"}, - RecordType: endpoint.RecordTypeNS, - ForceUpdate: false, - Labels: map[string]string{ - endpoint.OwnerLabelKey: "owner", - }, - }, - { - DNSName: "noheritage.test-zone.example.org", - Targets: endpoint.Targets{"random"}, - RecordType: endpoint.RecordTypeTXT, - ForceUpdate: false, + DNSName: "noheritage.test-zone.example.org", + Targets: endpoint.Targets{"random"}, + RecordType: endpoint.RecordTypeTXT, Labels: map[string]string{ // No owner because it's not external-dns heritage endpoint.OwnerLabelKey: "", }, }, { - DNSName: "oldformat-otherowner.test-zone.example.org", - Targets: endpoint.Targets{"bar.loadbalancer.com"}, - RecordType: endpoint.RecordTypeA, - ForceUpdate: false, + DNSName: "oldformat-otherowner.test-zone.example.org", + Targets: endpoint.Targets{"bar.loadbalancer.com"}, + RecordType: endpoint.RecordTypeA, Labels: map[string]string{ // All the records of the zone are retrieved, no matter the owner endpoint.OwnerLabelKey: "otherowner", }, }, { - DNSName: "unmanaged1.test-zone.example.org", - Targets: endpoint.Targets{"unmanaged1.loadbalancer.com"}, - RecordType: endpoint.RecordTypeA, - ForceUpdate: false, + DNSName: "unmanaged1.test-zone.example.org", + Targets: endpoint.Targets{"unmanaged1.loadbalancer.com"}, + RecordType: endpoint.RecordTypeA, }, { - DNSName: "unmanaged2.test-zone.example.org", - Targets: endpoint.Targets{"unmanaged2.loadbalancer.com"}, - RecordType: endpoint.RecordTypeCNAME, - ForceUpdate: false, + DNSName: "unmanaged2.test-zone.example.org", + Targets: endpoint.Targets{"unmanaged2.loadbalancer.com"}, + RecordType: endpoint.RecordTypeCNAME, }, }