From dac21e3aff65e5b5c9d0682fc55bf848e898fb9c Mon Sep 17 00:00:00 2001 From: Thibault Cohen Date: Fri, 7 Jun 2019 11:46:30 -0400 Subject: [PATCH] Add --zone-name-filter option for azure provider --- main.go | 3 ++- pkg/apis/externaldns/types.go | 2 ++ pkg/apis/externaldns/types_test.go | 5 +++++ provider/azure/azure.go | 20 +++++++++++++++++++- 4 files changed, 28 insertions(+), 2 deletions(-) diff --git a/main.go b/main.go index ecbda90d7..03a7f94e8 100644 --- a/main.go +++ b/main.go @@ -141,6 +141,7 @@ func main() { endpointsSource := source.NewDedupSource(source.NewMultiSource(sources)) domainFilter := endpoint.NewDomainFilterWithExclusions(cfg.DomainFilter, cfg.ExcludeDomains) + zoneNameFilter := endpoint.NewDomainFilter(cfg.ZoneNameFilter) zoneIDFilter := provider.NewZoneIDFilter(cfg.ZoneIDFilter) zoneTypeFilter := provider.NewZoneTypeFilter(cfg.AWSZoneType) zoneTagFilter := provider.NewZoneTagFilter(cfg.AWSZoneTagFilter) @@ -185,7 +186,7 @@ func main() { } p, err = awssd.NewAWSSDProvider(domainFilter, cfg.AWSZoneType, cfg.AWSAssumeRole, cfg.DryRun) case "azure-dns", "azure": - p, err = azure.NewAzureProvider(cfg.AzureConfigFile, domainFilter, zoneIDFilter, cfg.AzureResourceGroup, cfg.AzureUserAssignedIdentityClientID, cfg.DryRun) + p, err = azure.NewAzureProvider(cfg.AzureConfigFile, domainFilter, zoneNameFilter, zoneIDFilter, cfg.AzureResourceGroup, cfg.AzureUserAssignedIdentityClientID, cfg.DryRun) case "azure-private-dns": p, err = azure.NewAzurePrivateDNSProvider(domainFilter, zoneIDFilter, cfg.AzureResourceGroup, cfg.AzureSubscriptionID, cfg.DryRun) case "vinyldns": diff --git a/pkg/apis/externaldns/types.go b/pkg/apis/externaldns/types.go index 1476b4685..bb75044fe 100644 --- a/pkg/apis/externaldns/types.go +++ b/pkg/apis/externaldns/types.go @@ -61,6 +61,7 @@ type Config struct { GoogleBatchChangeInterval time.Duration DomainFilter []string ExcludeDomains []string + ZoneNameFilter []string ZoneIDFilter []string AlibabaCloudConfigFile string AlibabaCloudZoneType string @@ -321,6 +322,7 @@ func (cfg *Config) ParseFlags(args []string) error { app.Flag("provider", "The DNS provider where the DNS records will be created (required, options: aws, aws-sd, google, azure, azure-dns, azure-private-dns, cloudflare, rcodezero, digitalocean, hetzner, dnsimple, akamai, infoblox, dyn, designate, coredns, skydns, inmemory, ovh, pdns, oci, exoscale, linode, rfc2136, ns1, transip, vinyldns, rdns, scaleway, vultr, ultradns)").Required().PlaceHolder("provider").EnumVar(&cfg.Provider, "aws", "aws-sd", "google", "azure", "azure-dns", "hetzner", "azure-private-dns", "alibabacloud", "cloudflare", "rcodezero", "digitalocean", "dnsimple", "akamai", "infoblox", "dyn", "designate", "coredns", "skydns", "inmemory", "ovh", "pdns", "oci", "exoscale", "linode", "rfc2136", "ns1", "transip", "vinyldns", "rdns", "scaleway", "vultr", "ultradns") app.Flag("domain-filter", "Limit possible target zones by a domain suffix; specify multiple times for multiple domains (optional)").Default("").StringsVar(&cfg.DomainFilter) app.Flag("exclude-domains", "Exclude subdomains (optional)").Default("").StringsVar(&cfg.ExcludeDomains) + app.Flag("zone-name-filter", "Filter target zones by zone domain (For now, only AzureDNS provider is using this flag); specify multiple times for multiple zones (optional)").Default("").StringsVar(&cfg.ZoneNameFilter) app.Flag("zone-id-filter", "Filter target zones by hosted zone id; specify multiple times for multiple zones (optional)").Default("").StringsVar(&cfg.ZoneIDFilter) app.Flag("google-project", "When using the Google provider, current project is auto-detected, when running on GCP. Specify other project with this. Must be specified when running outside GCP.").Default(defaultConfig.GoogleProject).StringVar(&cfg.GoogleProject) app.Flag("google-batch-change-size", "When using the Google provider, set the maximum number of changes that will be applied in each batch.").Default(strconv.Itoa(defaultConfig.GoogleBatchChangeSize)).IntVar(&cfg.GoogleBatchChangeSize) diff --git a/pkg/apis/externaldns/types_test.go b/pkg/apis/externaldns/types_test.go index b6a55ae86..e472da906 100644 --- a/pkg/apis/externaldns/types_test.go +++ b/pkg/apis/externaldns/types_test.go @@ -44,6 +44,7 @@ var ( GoogleBatchChangeInterval: time.Second, DomainFilter: []string{""}, ExcludeDomains: []string{""}, + ZoneNameFilter: []string{""}, ZoneIDFilter: []string{""}, AlibabaCloudConfigFile: "/etc/kubernetes/alibaba-cloud.json", AWSZoneType: "", @@ -119,6 +120,7 @@ var ( GoogleBatchChangeInterval: time.Second * 2, DomainFilter: []string{"example.org", "company.com"}, ExcludeDomains: []string{"xapi.example.org", "xapi.company.com"}, + ZoneNameFilter: []string{"yapi.example.org", "yapi.company.com"}, ZoneIDFilter: []string{"/hostedzone/ZTST1", "/hostedzone/ZTST2"}, AlibabaCloudConfigFile: "/etc/kubernetes/alibaba-cloud.json", AWSZoneType: "private", @@ -252,6 +254,8 @@ func TestParseFlags(t *testing.T) { "--domain-filter=company.com", "--exclude-domains=xapi.example.org", "--exclude-domains=xapi.company.com", + "--zone-name-filter=yapi.example.org", + "--zone-name-filter=yapi.company.com", "--zone-id-filter=/hostedzone/ZTST1", "--zone-id-filter=/hostedzone/ZTST2", "--aws-zone-type=private", @@ -339,6 +343,7 @@ func TestParseFlags(t *testing.T) { "EXTERNAL_DNS_TLS_CA": "/path/to/ca.crt", "EXTERNAL_DNS_TLS_CLIENT_CERT": "/path/to/cert.pem", "EXTERNAL_DNS_TLS_CLIENT_CERT_KEY": "/path/to/key.pem", + "EXTERNAL_DNS_ZONE_NAME_FILTER": "yapi.example.org\nyapi.company.com", "EXTERNAL_DNS_ZONE_ID_FILTER": "/hostedzone/ZTST1\n/hostedzone/ZTST2", "EXTERNAL_DNS_AWS_ZONE_TYPE": "private", "EXTERNAL_DNS_AWS_ZONE_TAGS": "tag=foo", diff --git a/provider/azure/azure.go b/provider/azure/azure.go index d216f5dde..0584bd0c2 100644 --- a/provider/azure/azure.go +++ b/provider/azure/azure.go @@ -69,6 +69,7 @@ type RecordSetsClient interface { type AzureProvider struct { provider.BaseProvider domainFilter endpoint.DomainFilter + zoneNameFilter endpoint.DomainFilter zoneIDFilter provider.ZoneIDFilter dryRun bool resourceGroup string @@ -80,7 +81,7 @@ type AzureProvider struct { // NewAzureProvider creates a new Azure provider. // // Returns the provider or an error if a provider could not be created. -func NewAzureProvider(configFile string, domainFilter endpoint.DomainFilter, zoneIDFilter provider.ZoneIDFilter, resourceGroup string, userAssignedIdentityClientID string, dryRun bool) (*AzureProvider, error) { +func NewAzureProvider(configFile string, domainFilter endpoint.DomainFilter, zoneNameFilter endpoint.DomainFilter, zoneIDFilter provider.ZoneIDFilter, resourceGroup string, userAssignedIdentityClientID string, dryRun bool) (*AzureProvider, error) { contents, err := ioutil.ReadFile(configFile) if err != nil { return nil, fmt.Errorf("failed to read Azure config file '%s': %v", configFile, err) @@ -122,6 +123,7 @@ func NewAzureProvider(configFile string, domainFilter endpoint.DomainFilter, zon provider := &AzureProvider{ domainFilter: domainFilter, + zoneNameFilter: zoneNameFilter, zoneIDFilter: zoneIDFilter, dryRun: dryRun, resourceGroup: cfg.ResourceGroup, @@ -205,6 +207,11 @@ func (p *AzureProvider) Records(ctx context.Context) (endpoints []*endpoint.Endp return true } name := formatAzureDNSName(*recordSet.Name, *zone.Name) + + if len(p.zoneNameFilter.Filters) > 0 && !p.domainFilter.Match(name) { + log.Debugf("Skipping return of record %s because it was filtered out by the specified --domain-filter", name) + return false + } targets := extractAzureTargets(&recordSet) if len(targets) == 0 { log.Errorf("Failed to extract targets for '%s' with type '%s'.", name, recordType) @@ -262,6 +269,9 @@ func (p *AzureProvider) zones(ctx context.Context) ([]dns.Zone, error) { if zone.Name != nil && p.domainFilter.Match(*zone.Name) && p.zoneIDFilter.Match(*zone.ID) { zones = append(zones, zone) + } else if zone.Name != nil && len(p.zoneNameFilter.Filters) > 0 && p.zoneNameFilter.Match(*zone.Name) { + // Handle zoneNameFilter + zones = append(zones, zone) } err := zonesIterator.NextWithContext(ctx) @@ -344,6 +354,10 @@ func (p *AzureProvider) deleteRecords(ctx context.Context, deleted azureChangeMa for zone, endpoints := range deleted { for _, endpoint := range endpoints { name := p.recordSetNameForZone(zone, endpoint) + if !p.domainFilter.Match(endpoint.DNSName) { + log.Debugf("Skipping deletion of record %s because it was filtered out by the specified --domain-filter", endpoint.DNSName) + continue + } if p.dryRun { log.Infof("Would delete %s record named '%s' for Azure DNS zone '%s'.", endpoint.RecordType, name, zone) } else { @@ -366,6 +380,10 @@ func (p *AzureProvider) updateRecords(ctx context.Context, updated azureChangeMa for zone, endpoints := range updated { for _, endpoint := range endpoints { name := p.recordSetNameForZone(zone, endpoint) + if !p.domainFilter.Match(endpoint.DNSName) { + log.Debugf("Skipping update of record %s because it was filtered out by the specified --domain-filter", endpoint.DNSName) + continue + } if p.dryRun { log.Infof( "Would update %s record named '%s' to '%s' for Azure DNS zone '%s'.",