mirror of
https://github.com/kubernetes-sigs/external-dns.git
synced 2025-08-06 09:36:58 +02:00
Handle the migration to the new TXT format: missing records to be created separately
This commit is contained in:
parent
f48408a83c
commit
0feb32de3c
@ -188,11 +188,33 @@ func (c *Controller) RunOnce(ctx context.Context) error {
|
|||||||
verifiedARecords.Set(float64(len(vRecords)))
|
verifiedARecords.Set(float64(len(vRecords)))
|
||||||
endpoints = c.Registry.AdjustEndpoints(endpoints)
|
endpoints = c.Registry.AdjustEndpoints(endpoints)
|
||||||
|
|
||||||
|
if len(missingRecords) > 0 {
|
||||||
|
// Add missing records before the actual plan is applied.
|
||||||
|
// This prevents the problems when the missing TXT record needs to be
|
||||||
|
// created and deleted/upserted in the same batch.
|
||||||
|
missingRecordsPlan := &plan.Plan{
|
||||||
|
Policies: []plan.Policy{c.Policy},
|
||||||
|
Missing: missingRecords,
|
||||||
|
DomainFilter: endpoint.MatchAllDomainFilters{c.DomainFilter, c.Registry.GetDomainFilter()},
|
||||||
|
PropertyComparator: c.Registry.PropertyValuesEqual,
|
||||||
|
ManagedRecords: c.ManagedRecordTypes,
|
||||||
|
}
|
||||||
|
missingRecordsPlan = missingRecordsPlan.Calculate()
|
||||||
|
if missingRecordsPlan.Changes.HasChanges() {
|
||||||
|
err = c.Registry.ApplyChanges(ctx, missingRecordsPlan.Changes)
|
||||||
|
if err != nil {
|
||||||
|
registryErrorsTotal.Inc()
|
||||||
|
deprecatedRegistryErrors.Inc()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
log.Info("All missing records are created")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
plan := &plan.Plan{
|
plan := &plan.Plan{
|
||||||
Policies: []plan.Policy{c.Policy},
|
Policies: []plan.Policy{c.Policy},
|
||||||
Current: records,
|
Current: records,
|
||||||
Desired: endpoints,
|
Desired: endpoints,
|
||||||
Missing: missingRecords,
|
|
||||||
DomainFilter: endpoint.MatchAllDomainFilters{c.DomainFilter, c.Registry.GetDomainFilter()},
|
DomainFilter: endpoint.MatchAllDomainFilters{c.DomainFilter, c.Registry.GetDomainFilter()},
|
||||||
PropertyComparator: c.Registry.PropertyValuesEqual,
|
PropertyComparator: c.Registry.PropertyValuesEqual,
|
||||||
ManagedRecords: c.ManagedRecordTypes,
|
ManagedRecords: c.ManagedRecordTypes,
|
||||||
|
@ -270,6 +270,51 @@ func testControllerFiltersDomains(t *testing.T, configuredEndpoints []*endpoint.
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type noopRegistryWithMissing struct {
|
||||||
|
*registry.NoopRegistry
|
||||||
|
missingRecords []*endpoint.Endpoint
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *noopRegistryWithMissing) MissingRecords() []*endpoint.Endpoint {
|
||||||
|
return r.missingRecords
|
||||||
|
}
|
||||||
|
|
||||||
|
func testControllerFiltersDomainsWithMissing(t *testing.T, configuredEndpoints []*endpoint.Endpoint, domainFilter endpoint.DomainFilterInterface, providerEndpoints, missingEndpoints []*endpoint.Endpoint, expectedChanges []*plan.Changes) {
|
||||||
|
t.Helper()
|
||||||
|
cfg := externaldns.NewConfig()
|
||||||
|
cfg.ManagedDNSRecordTypes = []string{endpoint.RecordTypeA, endpoint.RecordTypeCNAME}
|
||||||
|
|
||||||
|
source := new(testutils.MockSource)
|
||||||
|
source.On("Endpoints").Return(configuredEndpoints, nil)
|
||||||
|
|
||||||
|
// Fake some existing records in our DNS provider and validate some desired changes.
|
||||||
|
provider := &filteredMockProvider{
|
||||||
|
RecordsStore: providerEndpoints,
|
||||||
|
}
|
||||||
|
noop, err := registry.NewNoopRegistry(provider)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
r := &noopRegistryWithMissing{
|
||||||
|
NoopRegistry: noop,
|
||||||
|
missingRecords: missingEndpoints,
|
||||||
|
}
|
||||||
|
|
||||||
|
ctrl := &Controller{
|
||||||
|
Source: source,
|
||||||
|
Registry: r,
|
||||||
|
Policy: &plan.SyncPolicy{},
|
||||||
|
DomainFilter: domainFilter,
|
||||||
|
ManagedRecordTypes: cfg.ManagedDNSRecordTypes,
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.NoError(t, ctrl.RunOnce(context.Background()))
|
||||||
|
assert.Equal(t, 1, provider.RecordsCallCount)
|
||||||
|
require.Len(t, provider.ApplyChangesCalls, len(expectedChanges))
|
||||||
|
for i, change := range expectedChanges {
|
||||||
|
assert.Equal(t, *change, *provider.ApplyChangesCalls[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestControllerSkipsEmptyChanges(t *testing.T) {
|
func TestControllerSkipsEmptyChanges(t *testing.T) {
|
||||||
testControllerFiltersDomains(
|
testControllerFiltersDomains(
|
||||||
t,
|
t,
|
||||||
@ -517,3 +562,57 @@ func TestARecords(t *testing.T) {
|
|||||||
assert.Equal(t, math.Float64bits(2), valueFromMetric(sourceARecords))
|
assert.Equal(t, math.Float64bits(2), valueFromMetric(sourceARecords))
|
||||||
assert.Equal(t, math.Float64bits(1), valueFromMetric(registryARecords))
|
assert.Equal(t, math.Float64bits(1), valueFromMetric(registryARecords))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestMissingRecordsApply validates that the missing records result in the dedicated plan apply.
|
||||||
|
func TestMissingRecordsApply(t *testing.T) {
|
||||||
|
testControllerFiltersDomainsWithMissing(
|
||||||
|
t,
|
||||||
|
[]*endpoint.Endpoint{
|
||||||
|
{
|
||||||
|
DNSName: "record1.used.tld",
|
||||||
|
RecordType: endpoint.RecordTypeA,
|
||||||
|
Targets: endpoint.Targets{"1.2.3.4"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
DNSName: "record2.used.tld",
|
||||||
|
RecordType: endpoint.RecordTypeA,
|
||||||
|
Targets: endpoint.Targets{"8.8.8.8"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
endpoint.NewDomainFilter([]string{"used.tld"}),
|
||||||
|
[]*endpoint.Endpoint{
|
||||||
|
{
|
||||||
|
DNSName: "record1.used.tld",
|
||||||
|
RecordType: endpoint.RecordTypeA,
|
||||||
|
Targets: endpoint.Targets{"1.2.3.4"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[]*endpoint.Endpoint{
|
||||||
|
{
|
||||||
|
DNSName: "a-record1.used.tld",
|
||||||
|
RecordType: endpoint.RecordTypeTXT,
|
||||||
|
Targets: endpoint.Targets{"\"heritage=external-dns,external-dns/owner=owner\""},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[]*plan.Changes{
|
||||||
|
// Missing record had its own plan applied.
|
||||||
|
{
|
||||||
|
Create: []*endpoint.Endpoint{
|
||||||
|
{
|
||||||
|
DNSName: "a-record1.used.tld",
|
||||||
|
RecordType: endpoint.RecordTypeTXT,
|
||||||
|
Targets: endpoint.Targets{"\"heritage=external-dns,external-dns/owner=owner\""},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Create: []*endpoint.Endpoint{
|
||||||
|
{
|
||||||
|
DNSName: "record2.used.tld",
|
||||||
|
RecordType: endpoint.RecordTypeA,
|
||||||
|
Targets: endpoint.Targets{"8.8.8.8"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user