From 94713c20c6fabe89e8994b6f2362bf54dadf16eb Mon Sep 17 00:00:00 2001 From: John Gardiner Myers Date: Wed, 28 Jun 2023 20:02:54 -0700 Subject: [PATCH] Add --exclude-record-types flag --- controller/controller.go | 5 ++- main.go | 5 +-- pkg/apis/externaldns/types.go | 5 ++- plan/plan.go | 19 +++++++---- plan/plan_test.go | 23 ++++++++++++++ registry/dynamodb.go | 6 ++-- registry/dynamodb_test.go | 24 +++++++------- registry/txt.go | 6 ++-- registry/txt_test.go | 60 +++++++++++++++++------------------ 9 files changed, 97 insertions(+), 56 deletions(-) diff --git a/controller/controller.go b/controller/controller.go index 6058af46aa..ccafc9db6c 100644 --- a/controller/controller.go +++ b/controller/controller.go @@ -181,8 +181,10 @@ type Controller struct { nextRunAt time.Time // The nextRunAtMux is for atomic updating of nextRunAt nextRunAtMux sync.Mutex - // DNS record types that will be considered for management + // MangedRecordTypes are DNS record types that will be considered for management. ManagedRecordTypes []string + // ExcludeRecordTypes are DNS record types that will be excluded from management. + ExcludeRecordTypes []string // MinEventSyncInterval is used as window for batching events MinEventSyncInterval time.Duration } @@ -227,6 +229,7 @@ func (c *Controller) RunOnce(ctx context.Context) error { Desired: endpoints, DomainFilter: endpoint.MatchAllDomainFilters{&c.DomainFilter, ®istryFilter}, ManagedRecords: c.ManagedRecordTypes, + ExcludeRecords: c.ExcludeRecordTypes, OwnerID: c.Registry.OwnerID(), } diff --git a/main.go b/main.go index 81140abbee..89c392381b 100644 --- a/main.go +++ b/main.go @@ -416,11 +416,11 @@ func main() { if cfg.AWSDynamoDBRegion != "" { config = config.WithRegion(cfg.AWSDynamoDBRegion) } - r, err = registry.NewDynamoDBRegistry(p, cfg.TXTOwnerID, dynamodb.New(awsSession, config), cfg.AWSDynamoDBTable, cfg.TXTPrefix, cfg.TXTSuffix, cfg.TXTWildcardReplacement, cfg.ManagedDNSRecordTypes, []byte(cfg.TXTEncryptAESKey), cfg.TXTCacheInterval) + r, err = registry.NewDynamoDBRegistry(p, cfg.TXTOwnerID, dynamodb.New(awsSession, config), cfg.AWSDynamoDBTable, cfg.TXTPrefix, cfg.TXTSuffix, cfg.TXTWildcardReplacement, cfg.ManagedDNSRecordTypes, cfg.ExcludeDNSRecordTypes, []byte(cfg.TXTEncryptAESKey), cfg.TXTCacheInterval) case "noop": r, err = registry.NewNoopRegistry(p) case "txt": - r, err = registry.NewTXTRegistry(p, cfg.TXTPrefix, cfg.TXTSuffix, cfg.TXTOwnerID, cfg.TXTCacheInterval, cfg.TXTWildcardReplacement, cfg.ManagedDNSRecordTypes, cfg.TXTEncryptEnabled, []byte(cfg.TXTEncryptAESKey)) + r, err = registry.NewTXTRegistry(p, cfg.TXTPrefix, cfg.TXTSuffix, cfg.TXTOwnerID, cfg.TXTCacheInterval, cfg.TXTWildcardReplacement, cfg.ManagedDNSRecordTypes, cfg.ExcludeDNSRecordTypes, cfg.TXTEncryptEnabled, []byte(cfg.TXTEncryptAESKey)) case "aws-sd": r, err = registry.NewAWSSDRegistry(p.(*awssd.AWSSDProvider), cfg.TXTOwnerID) default: @@ -443,6 +443,7 @@ func main() { Interval: cfg.Interval, DomainFilter: domainFilter, ManagedRecordTypes: cfg.ManagedDNSRecordTypes, + ExcludeRecordTypes: cfg.ExcludeDNSRecordTypes, MinEventSyncInterval: cfg.MinEventSyncInterval, } diff --git a/pkg/apis/externaldns/types.go b/pkg/apis/externaldns/types.go index b88f93d619..a4baf3cd17 100644 --- a/pkg/apis/externaldns/types.go +++ b/pkg/apis/externaldns/types.go @@ -194,6 +194,7 @@ type Config struct { TransIPPrivateKeyFile string DigitalOceanAPIPageSize int ManagedDNSRecordTypes []string + ExcludeDNSRecordTypes []string GoDaddyAPIKey string `secure:"yes"` GoDaddySecretKey string `secure:"yes"` GoDaddyTTL int64 @@ -342,6 +343,7 @@ var defaultConfig = &Config{ TransIPPrivateKeyFile: "", DigitalOceanAPIPageSize: 50, ManagedDNSRecordTypes: []string{endpoint.RecordTypeA, endpoint.RecordTypeAAAA, endpoint.RecordTypeCNAME}, + ExcludeDNSRecordTypes: []string{}, GoDaddyAPIKey: "", GoDaddySecretKey: "", GoDaddyTTL: 600, @@ -437,7 +439,8 @@ func (cfg *Config) ParseFlags(args []string) error { app.Flag("crd-source-apiversion", "API version of the CRD for crd source, e.g. `externaldns.k8s.io/v1alpha1`, valid only when using crd source").Default(defaultConfig.CRDSourceAPIVersion).StringVar(&cfg.CRDSourceAPIVersion) app.Flag("crd-source-kind", "Kind of the CRD for the crd source in API group and version specified by crd-source-apiversion").Default(defaultConfig.CRDSourceKind).StringVar(&cfg.CRDSourceKind) app.Flag("service-type-filter", "The service types to take care about (default: all, expected: ClusterIP, NodePort, LoadBalancer or ExternalName)").StringsVar(&cfg.ServiceTypeFilter) - app.Flag("managed-record-types", "Record types to manage; specify multiple times to include many; (default: A, AAAA, CNAME) (supported records: CNAME, A, AAAA, NS").Default("A", "AAAA", "CNAME").StringsVar(&cfg.ManagedDNSRecordTypes) + app.Flag("managed-record-types", "Record types to manage; specify multiple times to include many; (default: A, AAAA, CNAME) (supported records: A, AAAA, CNAME, NS, SRV, TXT)").Default("A", "AAAA", "CNAME").StringsVar(&cfg.ManagedDNSRecordTypes) + app.Flag("exclude-record-types", "Record types to exclude from management; specify multiple times to exclude many; (optional)").Default().StringsVar(&cfg.ExcludeDNSRecordTypes) app.Flag("default-targets", "Set globally default host/IP that will apply as a target instead of source addresses. Specify multiple times for multiple targets (optional)").StringsVar(&cfg.DefaultTargets) app.Flag("target-net-filter", "Limit possible targets by a net filter; specify multiple times for multiple possible nets (optional)").StringsVar(&cfg.TargetNetFilter) app.Flag("exclude-target-net", "Exclude target nets (optional)").StringsVar(&cfg.ExcludeTargetNets) diff --git a/plan/plan.go b/plan/plan.go index a9299cf9cc..c8087130b6 100644 --- a/plan/plan.go +++ b/plan/plan.go @@ -44,8 +44,10 @@ type Plan struct { Changes *Changes // DomainFilter matches DNS names DomainFilter endpoint.MatchAllDomainFilters - // DNS record types that will be considered for management + // ManagedRecords are DNS record types that will be considered for management. ManagedRecords []string + // ExcludeRecords are DNS record types that will be excluded from management. + ExcludeRecords []string // OwnerID of records to manage OwnerID string } @@ -170,10 +172,10 @@ func (p *Plan) Calculate() *Plan { p.DomainFilter = endpoint.MatchAllDomainFilters(nil) } - for _, current := range filterRecordsForPlan(p.Current, p.DomainFilter, p.ManagedRecords) { + for _, current := range filterRecordsForPlan(p.Current, p.DomainFilter, p.ManagedRecords, p.ExcludeRecords) { t.addCurrent(current) } - for _, desired := range filterRecordsForPlan(p.Desired, p.DomainFilter, p.ManagedRecords) { + for _, desired := range filterRecordsForPlan(p.Desired, p.DomainFilter, p.ManagedRecords, p.ExcludeRecords) { t.addCandidate(desired) } @@ -313,7 +315,7 @@ func (p *Plan) shouldUpdateProviderSpecific(desired, current *endpoint.Endpoint) // Per RFC 1034, CNAME records conflict with all other records - it is the // only record with this property. The behavior of the planner may need to be // made more sophisticated to codify this. -func filterRecordsForPlan(records []*endpoint.Endpoint, domainFilter endpoint.MatchAllDomainFilters, managedRecords []string) []*endpoint.Endpoint { +func filterRecordsForPlan(records []*endpoint.Endpoint, domainFilter endpoint.MatchAllDomainFilters, managedRecords, excludeRecords []string) []*endpoint.Endpoint { filtered := []*endpoint.Endpoint{} for _, record := range records { @@ -322,7 +324,7 @@ func filterRecordsForPlan(records []*endpoint.Endpoint, domainFilter endpoint.Ma log.Debugf("ignoring record %s that does not match domain filter", record.DNSName) continue } - if IsManagedRecord(record.RecordType, managedRecords) { + if IsManagedRecord(record.RecordType, managedRecords, excludeRecords) { filtered = append(filtered, record) } } @@ -365,7 +367,12 @@ func CompareBoolean(defaultValue bool, name, current, previous string) bool { return v1 == v2 } -func IsManagedRecord(record string, managedRecords []string) bool { +func IsManagedRecord(record string, managedRecords, excludeRecords []string) bool { + for _, r := range excludeRecords { + if record == r { + return false + } + } for _, r := range managedRecords { if record == r { return true diff --git a/plan/plan_test.go b/plan/plan_test.go index a98d115a6a..664b4054a8 100644 --- a/plan/plan_test.go +++ b/plan/plan_test.go @@ -681,6 +681,29 @@ func (suite *PlanTestSuite) TestIgnoreTXT() { validateEntries(suite.T(), changes.Delete, expectedDelete) } +func (suite *PlanTestSuite) TestExcludeTXT() { + current := []*endpoint.Endpoint{suite.fooV2TXT} + desired := []*endpoint.Endpoint{suite.fooV2Cname} + expectedCreate := []*endpoint.Endpoint{suite.fooV2Cname} + expectedUpdateOld := []*endpoint.Endpoint{} + expectedUpdateNew := []*endpoint.Endpoint{} + expectedDelete := []*endpoint.Endpoint{} + + p := &Plan{ + Policies: []Policy{&SyncPolicy{}}, + Current: current, + Desired: desired, + ManagedRecords: []string{endpoint.RecordTypeA, endpoint.RecordTypeCNAME, endpoint.RecordTypeTXT}, + ExcludeRecords: []string{endpoint.RecordTypeTXT}, + } + + changes := p.Calculate().Changes + validateEntries(suite.T(), changes.Create, expectedCreate) + validateEntries(suite.T(), changes.UpdateNew, expectedUpdateNew) + validateEntries(suite.T(), changes.UpdateOld, expectedUpdateOld) + validateEntries(suite.T(), changes.Delete, expectedDelete) +} + func (suite *PlanTestSuite) TestIgnoreTargetCase() { current := []*endpoint.Endpoint{suite.fooV2Cname} desired := []*endpoint.Endpoint{suite.fooV2CnameUppercase} diff --git a/registry/dynamodb.go b/registry/dynamodb.go index 334e228720..a9732d4d46 100644 --- a/registry/dynamodb.go +++ b/registry/dynamodb.go @@ -53,6 +53,7 @@ type DynamoDBRegistry struct { mapper nameMapper wildcardReplacement string managedRecordTypes []string + excludeRecordTypes []string txtEncryptAESKey []byte // cache the dynamodb records owned by us. @@ -68,7 +69,7 @@ type DynamoDBRegistry struct { const dynamodbAttributeMigrate = "dynamodb/needs-migration" // NewDynamoDBRegistry returns a new DynamoDBRegistry object. -func NewDynamoDBRegistry(provider provider.Provider, ownerID string, dynamodbAPI DynamoDBAPI, table string, txtPrefix, txtSuffix, txtWildcardReplacement string, managedRecordTypes []string, txtEncryptAESKey []byte, cacheInterval time.Duration) (*DynamoDBRegistry, error) { +func NewDynamoDBRegistry(provider provider.Provider, ownerID string, dynamodbAPI DynamoDBAPI, table string, txtPrefix, txtSuffix, txtWildcardReplacement string, managedRecordTypes, excludeRecordTypes []string, txtEncryptAESKey []byte, cacheInterval time.Duration) (*DynamoDBRegistry, error) { if ownerID == "" { return nil, errors.New("owner id cannot be empty") } @@ -95,6 +96,7 @@ func NewDynamoDBRegistry(provider provider.Provider, ownerID string, dynamodbAPI mapper: mapper, wildcardReplacement: txtWildcardReplacement, managedRecordTypes: managedRecordTypes, + excludeRecordTypes: excludeRecordTypes, txtEncryptAESKey: txtEncryptAESKey, cacheInterval: cacheInterval, }, nil @@ -194,7 +196,7 @@ func (im *DynamoDBRegistry) Records(ctx context.Context) ([]*endpoint.Endpoint, } // Remove any unused TXT ownership records owned by us - if len(txtRecordsMap) > 0 && !plan.IsManagedRecord(endpoint.RecordTypeTXT, im.managedRecordTypes) { + if len(txtRecordsMap) > 0 && !plan.IsManagedRecord(endpoint.RecordTypeTXT, im.managedRecordTypes, im.excludeRecordTypes) { log.Infof("Old TXT ownership records will not be deleted because \"TXT\" is not in the set of managed record types.") } for _, record := range txtRecordsMap { diff --git a/registry/dynamodb_test.go b/registry/dynamodb_test.go index 9f0627e96d..7c3531b355 100644 --- a/registry/dynamodb_test.go +++ b/registry/dynamodb_test.go @@ -38,31 +38,31 @@ import ( func TestDynamoDBRegistryNew(t *testing.T) { api, p := newDynamoDBAPIStub(t, nil) - _, err := NewDynamoDBRegistry(p, "test-owner", api, "test-table", "", "", "", []string{}, []byte(""), time.Hour) + _, err := NewDynamoDBRegistry(p, "test-owner", api, "test-table", "", "", "", []string{}, []string{}, []byte(""), time.Hour) require.NoError(t, err) - _, err = NewDynamoDBRegistry(p, "test-owner", api, "test-table", "testPrefix", "", "", []string{}, []byte(""), time.Hour) + _, err = NewDynamoDBRegistry(p, "test-owner", api, "test-table", "testPrefix", "", "", []string{}, []string{}, []byte(""), time.Hour) require.NoError(t, err) - _, err = NewDynamoDBRegistry(p, "test-owner", api, "test-table", "", "testSuffix", "", []string{}, []byte(""), time.Hour) + _, err = NewDynamoDBRegistry(p, "test-owner", api, "test-table", "", "testSuffix", "", []string{}, []string{}, []byte(""), time.Hour) require.NoError(t, err) - _, err = NewDynamoDBRegistry(p, "test-owner", api, "test-table", "", "", "testWildcard", []string{}, []byte(""), time.Hour) + _, err = NewDynamoDBRegistry(p, "test-owner", api, "test-table", "", "", "testWildcard", []string{}, []string{}, []byte(""), time.Hour) require.NoError(t, err) - _, err = NewDynamoDBRegistry(p, "test-owner", api, "test-table", "", "", "testWildcard", []string{}, []byte(";k&l)nUC/33:{?d{3)54+,AD?]SX%yh^"), time.Hour) + _, err = NewDynamoDBRegistry(p, "test-owner", api, "test-table", "", "", "testWildcard", []string{}, []string{}, []byte(";k&l)nUC/33:{?d{3)54+,AD?]SX%yh^"), time.Hour) require.NoError(t, err) - _, err = NewDynamoDBRegistry(p, "", api, "test-table", "", "", "", []string{}, []byte(""), time.Hour) + _, err = NewDynamoDBRegistry(p, "", api, "test-table", "", "", "", []string{}, []string{}, []byte(""), time.Hour) require.EqualError(t, err, "owner id cannot be empty") - _, err = NewDynamoDBRegistry(p, "test-owner", api, "", "", "", "", []string{}, []byte(""), time.Hour) + _, err = NewDynamoDBRegistry(p, "test-owner", api, "", "", "", "", []string{}, []string{}, []byte(""), time.Hour) require.EqualError(t, err, "table cannot be empty") - _, err = NewDynamoDBRegistry(p, "test-owner", api, "test-table", "", "", "", []string{}, []byte(";k&l)nUC/33:{?d{3)54+,AD?]SX%yh^x"), time.Hour) + _, err = NewDynamoDBRegistry(p, "test-owner", api, "test-table", "", "", "", []string{}, []string{}, []byte(";k&l)nUC/33:{?d{3)54+,AD?]SX%yh^x"), time.Hour) require.EqualError(t, err, "the AES Encryption key must have a length of 32 bytes") - _, err = NewDynamoDBRegistry(p, "test-owner", api, "test-table", "testPrefix", "testSuffix", "", []string{}, []byte(""), time.Hour) + _, err = NewDynamoDBRegistry(p, "test-owner", api, "test-table", "testPrefix", "testSuffix", "", []string{}, []string{}, []byte(""), time.Hour) require.EqualError(t, err, "txt-prefix and txt-suffix are mutually exclusive") } @@ -112,7 +112,7 @@ func TestDynamoDBRegistryRecordsBadTable(t *testing.T) { api, p := newDynamoDBAPIStub(t, nil) tc.setup(&api.tableDescription) - r, _ := NewDynamoDBRegistry(p, "test-owner", api, "test-table", "", "", "", []string{}, nil, time.Hour) + r, _ := NewDynamoDBRegistry(p, "test-owner", api, "test-table", "", "", "", []string{}, []string{}, nil, time.Hour) _, err := r.Records(context.Background()) assert.EqualError(t, err, tc.expected) @@ -198,7 +198,7 @@ func TestDynamoDBRegistryRecords(t *testing.T) { }, } - r, _ := NewDynamoDBRegistry(p, "test-owner", api, "test-table", "txt.", "", "", []string{}, nil, time.Hour) + r, _ := NewDynamoDBRegistry(p, "test-owner", api, "test-table", "txt.", "", "", []string{}, []string{}, nil, time.Hour) _ = p.(*wrappedProvider).Provider.ApplyChanges(context.Background(), &plan.Changes{ Create: []*endpoint.Endpoint{ endpoint.NewEndpoint("migrate.test-zone.example.org", endpoint.RecordTypeA, "3.3.3.3").WithSetIdentifier("set-3"), @@ -920,7 +920,7 @@ func TestDynamoDBRegistryApplyChanges(t *testing.T) { ctx := context.Background() - r, _ := NewDynamoDBRegistry(p, "test-owner", api, "test-table", "txt.", "", "", []string{}, nil, time.Hour) + r, _ := NewDynamoDBRegistry(p, "test-owner", api, "test-table", "txt.", "", "", []string{}, []string{}, nil, time.Hour) _, err := r.Records(ctx) require.Nil(t, err) diff --git a/registry/txt.go b/registry/txt.go index b19aff7e63..c956077a3f 100644 --- a/registry/txt.go +++ b/registry/txt.go @@ -51,6 +51,7 @@ type TXTRegistry struct { wildcardReplacement string managedRecordTypes []string + excludeRecordTypes []string // encrypt text records txtEncryptEnabled bool @@ -58,7 +59,7 @@ type TXTRegistry struct { } // NewTXTRegistry returns new TXTRegistry object -func NewTXTRegistry(provider provider.Provider, txtPrefix, txtSuffix, ownerID string, cacheInterval time.Duration, txtWildcardReplacement string, managedRecordTypes []string, txtEncryptEnabled bool, txtEncryptAESKey []byte) (*TXTRegistry, error) { +func NewTXTRegistry(provider provider.Provider, txtPrefix, txtSuffix, ownerID string, cacheInterval time.Duration, txtWildcardReplacement string, managedRecordTypes, excludeRecordTypes []string, txtEncryptEnabled bool, txtEncryptAESKey []byte) (*TXTRegistry, error) { if ownerID == "" { return nil, errors.New("owner id cannot be empty") } @@ -84,6 +85,7 @@ func NewTXTRegistry(provider provider.Provider, txtPrefix, txtSuffix, ownerID st cacheInterval: cacheInterval, wildcardReplacement: txtWildcardReplacement, managedRecordTypes: managedRecordTypes, + excludeRecordTypes: excludeRecordTypes, txtEncryptEnabled: txtEncryptEnabled, txtEncryptAESKey: txtEncryptAESKey, }, nil @@ -181,7 +183,7 @@ func (im *TXTRegistry) Records(ctx context.Context) ([]*endpoint.Endpoint, error // Handle the migration of TXT records created before the new format (introduced in v0.12.0). // The migration is done for the TXT records owned by this instance only. if len(txtRecordsMap) > 0 && ep.Labels[endpoint.OwnerLabelKey] == im.ownerID { - if plan.IsManagedRecord(ep.RecordType, im.managedRecordTypes) { + if plan.IsManagedRecord(ep.RecordType, im.managedRecordTypes, im.excludeRecordTypes) { // Get desired TXT records and detect the missing ones desiredTXTs := im.generateTXTRecord(ep) for _, desiredTXT := range desiredTXTs { diff --git a/registry/txt_test.go b/registry/txt_test.go index 27f1047c70..4a598c0bd1 100644 --- a/registry/txt_test.go +++ b/registry/txt_test.go @@ -46,20 +46,20 @@ func TestTXTRegistry(t *testing.T) { func testTXTRegistryNew(t *testing.T) { p := inmemory.NewInMemoryProvider() - _, err := NewTXTRegistry(p, "txt", "", "", time.Hour, "", []string{}, false, nil) + _, err := NewTXTRegistry(p, "txt", "", "", time.Hour, "", []string{}, []string{}, false, nil) require.Error(t, err) - _, err = NewTXTRegistry(p, "", "txt", "", time.Hour, "", []string{}, false, nil) + _, err = NewTXTRegistry(p, "", "txt", "", time.Hour, "", []string{}, []string{}, false, nil) require.Error(t, err) - r, err := NewTXTRegistry(p, "txt", "", "owner", time.Hour, "", []string{}, false, nil) + r, err := NewTXTRegistry(p, "txt", "", "owner", time.Hour, "", []string{}, []string{}, false, nil) require.NoError(t, err) assert.Equal(t, p, r.provider) - r, err = NewTXTRegistry(p, "", "txt", "owner", time.Hour, "", []string{}, false, nil) + r, err = NewTXTRegistry(p, "", "txt", "owner", time.Hour, "", []string{}, []string{}, false, nil) require.NoError(t, err) - _, err = NewTXTRegistry(p, "txt", "txt", "owner", time.Hour, "", []string{}, false, nil) + _, err = NewTXTRegistry(p, "txt", "txt", "owner", time.Hour, "", []string{}, []string{}, false, nil) require.Error(t, err) _, ok := r.mapper.(affixNameMapper) @@ -68,16 +68,16 @@ func testTXTRegistryNew(t *testing.T) { assert.Equal(t, p, r.provider) aesKey := []byte(";k&l)nUC/33:{?d{3)54+,AD?]SX%yh^") - _, err = NewTXTRegistry(p, "", "", "owner", time.Hour, "", []string{}, false, nil) + _, err = NewTXTRegistry(p, "", "", "owner", time.Hour, "", []string{}, []string{}, false, nil) require.NoError(t, err) - _, err = NewTXTRegistry(p, "", "", "owner", time.Hour, "", []string{}, false, aesKey) + _, err = NewTXTRegistry(p, "", "", "owner", time.Hour, "", []string{}, []string{}, false, aesKey) require.NoError(t, err) - _, err = NewTXTRegistry(p, "", "", "owner", time.Hour, "", []string{}, true, nil) + _, err = NewTXTRegistry(p, "", "", "owner", time.Hour, "", []string{}, []string{}, true, nil) require.Error(t, err) - r, err = NewTXTRegistry(p, "", "", "owner", time.Hour, "", []string{}, true, aesKey) + r, err = NewTXTRegistry(p, "", "", "owner", time.Hour, "", []string{}, []string{}, true, aesKey) require.NoError(t, err) _, ok = r.mapper.(affixNameMapper) @@ -215,13 +215,13 @@ func testTXTRegistryRecordsPrefixed(t *testing.T) { }, } - r, _ := NewTXTRegistry(p, "txt.", "", "owner", time.Hour, "wc", []string{}, false, nil) + r, _ := NewTXTRegistry(p, "txt.", "", "owner", time.Hour, "wc", []string{}, []string{}, false, nil) records, _ := r.Records(ctx) assert.True(t, testutils.SameEndpoints(records, expectedRecords)) // Ensure prefix is case-insensitive - r, _ = NewTXTRegistry(p, "TxT.", "", "owner", time.Hour, "wc", []string{}, false, nil) + r, _ = NewTXTRegistry(p, "TxT.", "", "owner", time.Hour, "wc", []string{}, []string{}, false, nil) records, _ = r.Records(ctx) assert.True(t, testutils.SameEndpoints(records, expectedRecords)) @@ -340,13 +340,13 @@ func testTXTRegistryRecordsSuffixed(t *testing.T) { }, } - r, _ := NewTXTRegistry(p, "", "-txt", "owner", time.Hour, "", []string{}, false, nil) + r, _ := NewTXTRegistry(p, "", "-txt", "owner", time.Hour, "", []string{}, []string{}, false, nil) records, _ := r.Records(ctx) assert.True(t, testutils.SameEndpoints(records, expectedRecords)) // Ensure prefix is case-insensitive - r, _ = NewTXTRegistry(p, "", "-TxT", "owner", time.Hour, "", []string{}, false, nil) + r, _ = NewTXTRegistry(p, "", "-TxT", "owner", time.Hour, "", []string{}, []string{}, false, nil) records, _ = r.Records(ctx) assert.True(t, testutils.SameEndpointLabels(records, expectedRecords)) @@ -441,7 +441,7 @@ func testTXTRegistryRecordsNoPrefix(t *testing.T) { }, } - r, _ := NewTXTRegistry(p, "", "", "owner", time.Hour, "", []string{}, false, nil) + r, _ := NewTXTRegistry(p, "", "", "owner", time.Hour, "", []string{}, []string{}, false, nil) records, _ := r.Records(ctx) assert.True(t, testutils.SameEndpoints(records, expectedRecords)) @@ -468,12 +468,12 @@ func testTXTRegistryRecordsPrefixedTemplated(t *testing.T) { }, } - r, _ := NewTXTRegistry(p, "txt-%{record_type}.", "", "owner", time.Hour, "wc", []string{}, false, nil) + r, _ := NewTXTRegistry(p, "txt-%{record_type}.", "", "owner", time.Hour, "wc", []string{}, []string{}, false, nil) records, _ := r.Records(ctx) assert.True(t, testutils.SameEndpoints(records, expectedRecords)) - r, _ = NewTXTRegistry(p, "TxT-%{record_type}.", "", "owner", time.Hour, "wc", []string{}, false, nil) + r, _ = NewTXTRegistry(p, "TxT-%{record_type}.", "", "owner", time.Hour, "wc", []string{}, []string{}, false, nil) records, _ = r.Records(ctx) assert.True(t, testutils.SameEndpoints(records, expectedRecords)) @@ -500,12 +500,12 @@ func testTXTRegistryRecordsSuffixedTemplated(t *testing.T) { }, } - r, _ := NewTXTRegistry(p, "", "txt%{record_type}", "owner", time.Hour, "wc", []string{}, false, nil) + r, _ := NewTXTRegistry(p, "", "txt%{record_type}", "owner", time.Hour, "wc", []string{}, []string{}, false, nil) records, _ := r.Records(ctx) assert.True(t, testutils.SameEndpoints(records, expectedRecords)) - r, _ = NewTXTRegistry(p, "", "TxT%{record_type}", "owner", time.Hour, "wc", []string{}, false, nil) + r, _ = NewTXTRegistry(p, "", "TxT%{record_type}", "owner", time.Hour, "wc", []string{}, []string{}, false, nil) records, _ = r.Records(ctx) assert.True(t, testutils.SameEndpoints(records, expectedRecords)) @@ -548,7 +548,7 @@ func testTXTRegistryApplyChangesWithPrefix(t *testing.T) { newEndpointWithOwner("txt.cname-multiple.test-zone.example.org", "\"heritage=external-dns,external-dns/owner=owner\"", endpoint.RecordTypeTXT, "").WithSetIdentifier("test-set-2"), }, }) - r, _ := NewTXTRegistry(p, "txt.", "", "owner", time.Hour, "", []string{}, false, nil) + r, _ := NewTXTRegistry(p, "txt.", "", "owner", time.Hour, "", []string{}, []string{}, false, nil) changes := &plan.Changes{ Create: []*endpoint.Endpoint{ @@ -637,7 +637,7 @@ func testTXTRegistryApplyChangesWithTemplatedPrefix(t *testing.T) { p.ApplyChanges(ctx, &plan.Changes{ Create: []*endpoint.Endpoint{}, }) - r, _ := NewTXTRegistry(p, "prefix%{record_type}.", "", "owner", time.Hour, "", []string{}, false, nil) + r, _ := NewTXTRegistry(p, "prefix%{record_type}.", "", "owner", time.Hour, "", []string{}, []string{}, false, nil) changes := &plan.Changes{ Create: []*endpoint.Endpoint{ newEndpointWithOwnerResource("new-record-1.test-zone.example.org", "new-loadbalancer-1.lb.com", endpoint.RecordTypeCNAME, "", "ingress/default/my-ingress"), @@ -680,7 +680,7 @@ func testTXTRegistryApplyChangesWithTemplatedSuffix(t *testing.T) { p.OnApplyChanges = func(ctx context.Context, got *plan.Changes) { assert.Equal(t, ctxEndpoints, ctx.Value(provider.RecordsContextKey)) } - r, _ := NewTXTRegistry(p, "", "-%{record_type}suffix", "owner", time.Hour, "", []string{}, false, nil) + r, _ := NewTXTRegistry(p, "", "-%{record_type}suffix", "owner", time.Hour, "", []string{}, []string{}, false, nil) changes := &plan.Changes{ Create: []*endpoint.Endpoint{ newEndpointWithOwnerResource("new-record-1.test-zone.example.org", "new-loadbalancer-1.lb.com", endpoint.RecordTypeCNAME, "", "ingress/default/my-ingress"), @@ -745,7 +745,7 @@ func testTXTRegistryApplyChangesWithSuffix(t *testing.T) { newEndpointWithOwner("cname-multiple-txt.test-zone.example.org", "\"heritage=external-dns,external-dns/owner=owner\"", endpoint.RecordTypeTXT, "").WithSetIdentifier("test-set-2"), }, }) - r, _ := NewTXTRegistry(p, "", "-txt", "owner", time.Hour, "wildcard", []string{}, false, nil) + r, _ := NewTXTRegistry(p, "", "-txt", "owner", time.Hour, "wildcard", []string{}, []string{}, false, nil) changes := &plan.Changes{ Create: []*endpoint.Endpoint{ @@ -849,7 +849,7 @@ func testTXTRegistryApplyChangesNoPrefix(t *testing.T) { newEndpointWithOwner("cname-foobar.test-zone.example.org", "\"heritage=external-dns,external-dns/owner=owner\"", endpoint.RecordTypeTXT, ""), }, }) - r, _ := NewTXTRegistry(p, "", "", "owner", time.Hour, "", []string{}, false, nil) + r, _ := NewTXTRegistry(p, "", "", "owner", time.Hour, "", []string{}, []string{}, false, nil) changes := &plan.Changes{ Create: []*endpoint.Endpoint{ @@ -1007,7 +1007,7 @@ func testTXTRegistryMissingRecordsNoPrefix(t *testing.T) { }, } - r, _ := NewTXTRegistry(p, "", "", "owner", time.Hour, "wc", []string{endpoint.RecordTypeCNAME, endpoint.RecordTypeA, endpoint.RecordTypeNS}, false, nil) + r, _ := NewTXTRegistry(p, "", "", "owner", time.Hour, "wc", []string{endpoint.RecordTypeCNAME, endpoint.RecordTypeA, endpoint.RecordTypeNS}, []string{}, false, nil) records, _ := r.Records(ctx) assert.True(t, testutils.SameEndpoints(records, expectedRecords)) @@ -1101,7 +1101,7 @@ func testTXTRegistryMissingRecordsWithPrefix(t *testing.T) { }, } - r, _ := NewTXTRegistry(p, "txt.", "", "owner", time.Hour, "wc", []string{endpoint.RecordTypeCNAME, endpoint.RecordTypeA, endpoint.RecordTypeNS}, false, nil) + r, _ := NewTXTRegistry(p, "txt.", "", "owner", time.Hour, "wc", []string{endpoint.RecordTypeCNAME, endpoint.RecordTypeA, endpoint.RecordTypeNS}, []string{}, false, nil) records, _ := r.Records(ctx) assert.True(t, testutils.SameEndpoints(records, expectedRecords)) @@ -1389,7 +1389,7 @@ func TestNewTXTScheme(t *testing.T) { newEndpointWithOwner("cname-foobar.test-zone.example.org", "\"heritage=external-dns,external-dns/owner=owner\"", endpoint.RecordTypeTXT, ""), }, }) - r, _ := NewTXTRegistry(p, "", "", "owner", time.Hour, "", []string{}, false, nil) + r, _ := NewTXTRegistry(p, "", "", "owner", time.Hour, "", []string{}, []string{}, false, nil) changes := &plan.Changes{ Create: []*endpoint.Endpoint{ @@ -1465,7 +1465,7 @@ func TestGenerateTXT(t *testing.T) { } p := inmemory.NewInMemoryProvider() p.CreateZone(testZone) - r, _ := NewTXTRegistry(p, "", "", "owner", time.Hour, "", []string{}, false, nil) + r, _ := NewTXTRegistry(p, "", "", "owner", time.Hour, "", []string{}, []string{}, false, nil) gotTXT := r.generateTXTRecord(record) assert.Equal(t, expectedTXT, gotTXT) } @@ -1484,7 +1484,7 @@ func TestGenerateTXTForAAAA(t *testing.T) { } p := inmemory.NewInMemoryProvider() p.CreateZone(testZone) - r, _ := NewTXTRegistry(p, "", "", "owner", time.Hour, "", []string{}, false, nil) + r, _ := NewTXTRegistry(p, "", "", "owner", time.Hour, "", []string{}, []string{}, false, nil) gotTXT := r.generateTXTRecord(record) assert.Equal(t, expectedTXT, gotTXT) } @@ -1501,7 +1501,7 @@ func TestFailGenerateTXT(t *testing.T) { expectedTXT := []*endpoint.Endpoint{} p := inmemory.NewInMemoryProvider() p.CreateZone(testZone) - r, _ := NewTXTRegistry(p, "", "", "owner", time.Hour, "", []string{}, false, nil) + r, _ := NewTXTRegistry(p, "", "", "owner", time.Hour, "", []string{}, []string{}, false, nil) gotTXT := r.generateTXTRecord(cnameRecord) assert.Equal(t, expectedTXT, gotTXT) } @@ -1524,7 +1524,7 @@ func TestMultiClusterDifferentRecordTypeOwnership(t *testing.T) { }, }) - r, _ := NewTXTRegistry(p, "_owner.", "", "bar", time.Hour, "", []string{}, false, nil) + r, _ := NewTXTRegistry(p, "_owner.", "", "bar", time.Hour, "", []string{}, []string{}, false, nil) records, _ := r.Records(ctx) // new cluster has same ingress host as other cluster and uses CNAME ingress address