From b2ff1619f5dfb50187fc75cb64733978d3a0d880 Mon Sep 17 00:00:00 2001 From: Thibault Jamet Date: Fri, 8 Sep 2023 16:21:54 +0300 Subject: [PATCH] Add Domain filter interface --- controller/controller.go | 4 ++-- controller/controller_test.go | 2 +- endpoint/domain_filter.go | 8 +++++++- pkg/apis/externaldns/types.go | 2 +- provider/aws/aws.go | 2 +- provider/aws/aws_test.go | 4 ++-- provider/cached_provider.go | 16 ++++++++-------- provider/inmemory/inmemory.go | 2 +- provider/provider.go | 4 ++-- registry/aws_sd_registry.go | 2 +- registry/dynamodb.go | 2 +- registry/noop.go | 2 +- registry/registry.go | 2 +- registry/txt.go | 2 +- 14 files changed, 30 insertions(+), 24 deletions(-) diff --git a/controller/controller.go b/controller/controller.go index c8bb6ff18..2521b4436 100644 --- a/controller/controller.go +++ b/controller/controller.go @@ -186,7 +186,7 @@ type Controller struct { // The interval between individual synchronizations Interval time.Duration // The DomainFilter defines which DNS records to keep or exclude - DomainFilter endpoint.DomainFilter + DomainFilter endpoint.DomainFilterInterface // The nextRunAt used for throttling and batching reconciliation nextRunAt time.Time // The runAtMutex is for atomic updating of nextRunAt and lastRunAt @@ -245,7 +245,7 @@ func (c *Controller) RunOnce(ctx context.Context) error { Policies: []plan.Policy{c.Policy}, Current: records, Desired: endpoints, - DomainFilter: endpoint.MatchAllDomainFilters{&c.DomainFilter, ®istryFilter}, + DomainFilter: endpoint.MatchAllDomainFilters{c.DomainFilter, registryFilter}, ManagedRecords: c.ManagedRecordTypes, ExcludeRecords: c.ExcludeRecordTypes, OwnerID: c.Registry.OwnerID(), diff --git a/controller/controller_test.go b/controller/controller_test.go index e95aa9802..c6074f833 100644 --- a/controller/controller_test.go +++ b/controller/controller_test.go @@ -57,7 +57,7 @@ type errorMockProvider struct { mockProvider } -func (p *filteredMockProvider) GetDomainFilter() endpoint.DomainFilter { +func (p *filteredMockProvider) GetDomainFilter() endpoint.DomainFilterInterface { return p.domainFilter } diff --git a/endpoint/domain_filter.go b/endpoint/domain_filter.go index 308599d80..3acfbcd93 100644 --- a/endpoint/domain_filter.go +++ b/endpoint/domain_filter.go @@ -25,7 +25,7 @@ import ( "strings" ) -type MatchAllDomainFilters []*DomainFilter +type MatchAllDomainFilters []DomainFilterInterface func (f MatchAllDomainFilters) Match(domain string) bool { for _, filter := range f { @@ -39,6 +39,10 @@ func (f MatchAllDomainFilters) Match(domain string) bool { return true } +type DomainFilterInterface interface { + Match(domain string) bool +} + // DomainFilter holds a lists of valid domain names type DomainFilter struct { // Filters define what domains to match @@ -51,6 +55,8 @@ type DomainFilter struct { regexExclusion *regexp.Regexp } +var _ DomainFilterInterface = &DomainFilter{} + // domainFilterSerde is a helper type for serializing and deserializing DomainFilter. type domainFilterSerde struct { Include []string `json:"include,omitempty"` diff --git a/pkg/apis/externaldns/types.go b/pkg/apis/externaldns/types.go index 05ba1f2e1..423229a8b 100644 --- a/pkg/apis/externaldns/types.go +++ b/pkg/apis/externaldns/types.go @@ -67,7 +67,7 @@ type Config struct { AlwaysPublishNotReadyAddresses bool ConnectorSourceServer string Provider string - ProviderCacheTime int + ProviderCacheTime time.Duration GoogleProject string GoogleBatchChangeSize int GoogleBatchChangeInterval time.Duration diff --git a/provider/aws/aws.go b/provider/aws/aws.go index 8e13d290f..1955efb16 100644 --- a/provider/aws/aws.go +++ b/provider/aws/aws.go @@ -567,7 +567,7 @@ func (p *AWSProvider) createUpdateChanges(newEndpoints, oldEndpoints []*endpoint } // GetDomainFilter generates a filter to exclude any domain that is not controlled by the provider -func (p *AWSProvider) GetDomainFilter() endpoint.DomainFilter { +func (p *AWSProvider) GetDomainFilter() endpoint.DomainFilterInterface { zones, err := p.Zones(context.Background()) if err != nil { log.Errorf("failed to list zones: %v", err) diff --git a/provider/aws/aws_test.go b/provider/aws/aws_test.go index 418e05d09..6968e7c76 100644 --- a/provider/aws/aws_test.go +++ b/provider/aws/aws_test.go @@ -319,10 +319,10 @@ func TestAWSZones(t *testing.T) { func TestAWSRecordsFilter(t *testing.T) { provider, _ := newAWSProvider(t, endpoint.DomainFilter{}, provider.ZoneIDFilter{}, provider.ZoneTypeFilter{}, false, false, nil) domainFilter := provider.GetDomainFilter() - assert.NotNil(t, domainFilter) + require.NotNil(t, domainFilter) require.IsType(t, endpoint.DomainFilter{}, domainFilter) count := 0 - filters := domainFilter.Filters + filters := domainFilter.(endpoint.DomainFilter).Filters for _, tld := range []string{ "zone-4.ext-dns-test-3.teapot.zalan.do", ".zone-4.ext-dns-test-3.teapot.zalan.do", diff --git a/provider/cached_provider.go b/provider/cached_provider.go index c8d2da9de..3ea1fd516 100644 --- a/provider/cached_provider.go +++ b/provider/cached_provider.go @@ -50,7 +50,6 @@ var ( type CachedProvider struct { Provider RefreshDelay time.Duration - err error lastRead time.Time cache []*endpoint.Endpoint } @@ -58,17 +57,19 @@ type CachedProvider struct { func (c *CachedProvider) Records(ctx context.Context) ([]*endpoint.Endpoint, error) { if c.needRefresh() { log.Info("Records cache provider: refreshing records list cache") - c.cache, c.err = c.Provider.Records(ctx) - if c.err != nil { - log.Errorf("Records cache provider: list records failed: %v", c.err) + records, err := c.Provider.Records(ctx) + if err != nil { + c.cache = nil + return nil, err } + c.cache = records c.lastRead = time.Now() cachedRecordsCallsTotal.WithLabelValues("false").Inc() } else { - log.Info("Records cache provider: using records list from cache") + log.Debug("Records cache provider: using records list from cache") cachedRecordsCallsTotal.WithLabelValues("true").Inc() } - return c.cache, c.err + return c.cache, nil } func (c *CachedProvider) ApplyChanges(ctx context.Context, changes *plan.Changes) error { if !changes.HasChanges() { @@ -81,13 +82,12 @@ func (c *CachedProvider) ApplyChanges(ctx context.Context, changes *plan.Changes } func (c *CachedProvider) Reset() { - c.err = nil c.cache = nil c.lastRead = time.Time{} } func (c *CachedProvider) needRefresh() bool { - if c.cache == nil || c.err != nil { + if c.cache == nil { log.Debug("Records cache provider is not initialized") return true } diff --git a/provider/inmemory/inmemory.go b/provider/inmemory/inmemory.go index eab515a67..1f636dfda 100644 --- a/provider/inmemory/inmemory.go +++ b/provider/inmemory/inmemory.go @@ -46,7 +46,7 @@ var ( // initialized as dns provider with no records type InMemoryProvider struct { provider.BaseProvider - domain endpoint.DomainFilter + domain endpoint.DomainFilterInterface client *inMemoryClient filter *filter OnApplyChanges func(ctx context.Context, changes *plan.Changes) diff --git a/provider/provider.go b/provider/provider.go index 6a9c591e1..2bbfac161 100644 --- a/provider/provider.go +++ b/provider/provider.go @@ -48,7 +48,7 @@ type Provider interface { // unnecessary (potentially failing) changes. It may also modify other fields, add, or remove // Endpoints. It is permitted to modify the supplied endpoints. AdjustEndpoints(endpoints []*endpoint.Endpoint) ([]*endpoint.Endpoint, error) - GetDomainFilter() endpoint.DomainFilter + GetDomainFilter() endpoint.DomainFilterInterface } type BaseProvider struct{} @@ -57,7 +57,7 @@ func (b BaseProvider) AdjustEndpoints(endpoints []*endpoint.Endpoint) ([]*endpoi return endpoints, nil } -func (b BaseProvider) GetDomainFilter() endpoint.DomainFilter { +func (b BaseProvider) GetDomainFilter() endpoint.DomainFilterInterface { return endpoint.DomainFilter{} } diff --git a/registry/aws_sd_registry.go b/registry/aws_sd_registry.go index 8a2b023c4..a1e2103f5 100644 --- a/registry/aws_sd_registry.go +++ b/registry/aws_sd_registry.go @@ -42,7 +42,7 @@ func NewAWSSDRegistry(provider provider.Provider, ownerID string) (*AWSSDRegistr }, nil } -func (sdr *AWSSDRegistry) GetDomainFilter() endpoint.DomainFilter { +func (sdr *AWSSDRegistry) GetDomainFilter() endpoint.DomainFilterInterface { return sdr.provider.GetDomainFilter() } diff --git a/registry/dynamodb.go b/registry/dynamodb.go index aeb38d9a9..b13d55ce9 100644 --- a/registry/dynamodb.go +++ b/registry/dynamodb.go @@ -105,7 +105,7 @@ func NewDynamoDBRegistry(provider provider.Provider, ownerID string, dynamodbAPI }, nil } -func (im *DynamoDBRegistry) GetDomainFilter() endpoint.DomainFilter { +func (im *DynamoDBRegistry) GetDomainFilter() endpoint.DomainFilterInterface { return im.provider.GetDomainFilter() } diff --git a/registry/noop.go b/registry/noop.go index 9e06bbb92..daf29cb01 100644 --- a/registry/noop.go +++ b/registry/noop.go @@ -36,7 +36,7 @@ func NewNoopRegistry(provider provider.Provider) (*NoopRegistry, error) { }, nil } -func (im *NoopRegistry) GetDomainFilter() endpoint.DomainFilter { +func (im *NoopRegistry) GetDomainFilter() endpoint.DomainFilterInterface { return im.provider.GetDomainFilter() } diff --git a/registry/registry.go b/registry/registry.go index d2955365d..3117c4205 100644 --- a/registry/registry.go +++ b/registry/registry.go @@ -31,6 +31,6 @@ type Registry interface { Records(ctx context.Context) ([]*endpoint.Endpoint, error) ApplyChanges(ctx context.Context, changes *plan.Changes) error AdjustEndpoints(endpoints []*endpoint.Endpoint) ([]*endpoint.Endpoint, error) - GetDomainFilter() endpoint.DomainFilter + GetDomainFilter() endpoint.DomainFilterInterface OwnerID() string } diff --git a/registry/txt.go b/registry/txt.go index 8e7b6f096..12445bcb1 100644 --- a/registry/txt.go +++ b/registry/txt.go @@ -95,7 +95,7 @@ func getSupportedTypes() []string { return []string{endpoint.RecordTypeA, endpoint.RecordTypeAAAA, endpoint.RecordTypeCNAME, endpoint.RecordTypeNS} } -func (im *TXTRegistry) GetDomainFilter() endpoint.DomainFilter { +func (im *TXTRegistry) GetDomainFilter() endpoint.DomainFilterInterface { return im.provider.GetDomainFilter() }