mirror of
https://github.com/kubernetes-sigs/external-dns.git
synced 2025-08-05 09:06:58 +02:00
New filter: --zone-id-filter
(#422)
* Add aws-zone-id flag * Add Zone ID filter * Update AWS provider and main * Make ZoneIDFilter generic * Implement ZoneIDFilter for all providers * Update CHANGELOG
This commit is contained in:
parent
ec07f45c8e
commit
4dacf81238
@ -3,6 +3,7 @@
|
||||
- Target of DNS record is changed only if corresponding kubernetes resource target changes
|
||||
- If kubernetes resource is deleted, then another resource may acquire DNS name
|
||||
- "Flapping" target issue is resolved by providing a consistent and defined mechanism for choosing a target
|
||||
- New `--zone-id-filter` parameter allows filtering by zone id
|
||||
|
||||
## v0.4.8 - 2017-11-22
|
||||
|
||||
|
12
main.go
12
main.go
@ -88,26 +88,28 @@ func main() {
|
||||
endpointsSource := source.NewDedupSource(source.NewMultiSource(sources))
|
||||
|
||||
domainFilter := provider.NewDomainFilter(cfg.DomainFilter)
|
||||
zoneIDFilter := provider.NewZoneIDFilter(cfg.ZoneIDFilter)
|
||||
zoneTypeFilter := provider.NewZoneTypeFilter(cfg.AWSZoneType)
|
||||
|
||||
var p provider.Provider
|
||||
switch cfg.Provider {
|
||||
case "aws":
|
||||
p, err = provider.NewAWSProvider(domainFilter, zoneTypeFilter, cfg.DryRun)
|
||||
p, err = provider.NewAWSProvider(domainFilter, zoneIDFilter, zoneTypeFilter, cfg.DryRun)
|
||||
case "azure":
|
||||
p, err = provider.NewAzureProvider(cfg.AzureConfigFile, domainFilter, cfg.AzureResourceGroup, cfg.DryRun)
|
||||
p, err = provider.NewAzureProvider(cfg.AzureConfigFile, domainFilter, zoneIDFilter, cfg.AzureResourceGroup, cfg.DryRun)
|
||||
case "cloudflare":
|
||||
p, err = provider.NewCloudFlareProvider(domainFilter, cfg.CloudflareProxied, cfg.DryRun)
|
||||
p, err = provider.NewCloudFlareProvider(domainFilter, zoneIDFilter, cfg.CloudflareProxied, cfg.DryRun)
|
||||
case "google":
|
||||
p, err = provider.NewGoogleProvider(cfg.GoogleProject, domainFilter, cfg.DryRun)
|
||||
p, err = provider.NewGoogleProvider(cfg.GoogleProject, domainFilter, zoneIDFilter, cfg.DryRun)
|
||||
case "digitalocean":
|
||||
p, err = provider.NewDigitalOceanProvider(domainFilter, cfg.DryRun)
|
||||
case "dnsimple":
|
||||
p, err = provider.NewDnsimpleProvider(domainFilter, cfg.DryRun)
|
||||
p, err = provider.NewDnsimpleProvider(domainFilter, zoneIDFilter, cfg.DryRun)
|
||||
case "infoblox":
|
||||
p, err = provider.NewInfobloxProvider(
|
||||
provider.InfobloxConfig{
|
||||
DomainFilter: domainFilter,
|
||||
ZoneIDFilter: zoneIDFilter,
|
||||
Host: cfg.InfobloxGridHost,
|
||||
Port: cfg.InfobloxWapiPort,
|
||||
Username: cfg.InfobloxWapiUsername,
|
||||
|
@ -41,6 +41,7 @@ type Config struct {
|
||||
Provider string
|
||||
GoogleProject string
|
||||
DomainFilter []string
|
||||
ZoneIDFilter []string
|
||||
AWSZoneType string
|
||||
AzureConfigFile string
|
||||
AzureResourceGroup string
|
||||
@ -134,6 +135,7 @@ func (cfg *Config) ParseFlags(args []string) error {
|
||||
// Flags related to providers
|
||||
app.Flag("provider", "The DNS provider where the DNS records will be created (required, options: aws, google, azure, cloudflare, digitalocean, dnsimple, infoblox, inmemory)").Required().PlaceHolder("provider").EnumVar(&cfg.Provider, "aws", "google", "azure", "cloudflare", "digitalocean", "dnsimple", "infoblox", "inmemory")
|
||||
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("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, specify the Google project (required when --provider=google)").Default(defaultConfig.GoogleProject).StringVar(&cfg.GoogleProject)
|
||||
app.Flag("aws-zone-type", "When using the AWS provider, filter for zones of this type (optional, options: public, private)").Default(defaultConfig.AWSZoneType).EnumVar(&cfg.AWSZoneType, "", "public", "private")
|
||||
app.Flag("azure-config-file", "When using the Azure provider, specify the Azure configuration file (required when --provider=azure").Default(defaultConfig.AzureConfigFile).StringVar(&cfg.AzureConfigFile)
|
||||
|
@ -37,6 +37,7 @@ var (
|
||||
Provider: "google",
|
||||
GoogleProject: "",
|
||||
DomainFilter: []string{""},
|
||||
ZoneIDFilter: []string{""},
|
||||
AWSZoneType: "",
|
||||
AzureConfigFile: "/etc/kubernetes/azure.json",
|
||||
AzureResourceGroup: "",
|
||||
@ -70,6 +71,7 @@ var (
|
||||
Provider: "google",
|
||||
GoogleProject: "project",
|
||||
DomainFilter: []string{"example.org", "company.com"},
|
||||
ZoneIDFilter: []string{"/hostedzone/ZTST1", "/hostedzone/ZTST2"},
|
||||
AWSZoneType: "private",
|
||||
AzureConfigFile: "azure.json",
|
||||
AzureResourceGroup: "arg",
|
||||
@ -135,6 +137,8 @@ func TestParseFlags(t *testing.T) {
|
||||
"--no-infoblox-ssl-verify",
|
||||
"--domain-filter=example.org",
|
||||
"--domain-filter=company.com",
|
||||
"--zone-id-filter=/hostedzone/ZTST1",
|
||||
"--zone-id-filter=/hostedzone/ZTST2",
|
||||
"--aws-zone-type=private",
|
||||
"--policy=upsert-only",
|
||||
"--registry=noop",
|
||||
@ -173,6 +177,7 @@ func TestParseFlags(t *testing.T) {
|
||||
"EXTERNAL_DNS_INFOBLOX_SSL_VERIFY": "0",
|
||||
"EXTERNAL_DNS_INMEMORY_ZONE": "example.org\ncompany.com",
|
||||
"EXTERNAL_DNS_DOMAIN_FILTER": "example.org\ncompany.com",
|
||||
"EXTERNAL_DNS_ZONE_ID_FILTER": "/hostedzone/ZTST1\n/hostedzone/ZTST2",
|
||||
"EXTERNAL_DNS_AWS_ZONE_TYPE": "private",
|
||||
"EXTERNAL_DNS_POLICY": "upsert-only",
|
||||
"EXTERNAL_DNS_REGISTRY": "noop",
|
||||
|
@ -71,12 +71,14 @@ type AWSProvider struct {
|
||||
dryRun bool
|
||||
// only consider hosted zones managing domains ending in this suffix
|
||||
domainFilter DomainFilter
|
||||
// filter hosted zones by id
|
||||
zoneIDFilter ZoneIDFilter
|
||||
// filter hosted zones by type (e.g. private or public)
|
||||
zoneTypeFilter ZoneTypeFilter
|
||||
}
|
||||
|
||||
// NewAWSProvider initializes a new AWS Route53 based Provider.
|
||||
func NewAWSProvider(domainFilter DomainFilter, zoneTypeFilter ZoneTypeFilter, dryRun bool) (*AWSProvider, error) {
|
||||
func NewAWSProvider(domainFilter DomainFilter, zoneIDFilter ZoneIDFilter, zoneTypeFilter ZoneTypeFilter, dryRun bool) (*AWSProvider, error) {
|
||||
config := aws.NewConfig()
|
||||
|
||||
config = config.WithHTTPClient(
|
||||
@ -99,6 +101,7 @@ func NewAWSProvider(domainFilter DomainFilter, zoneTypeFilter ZoneTypeFilter, dr
|
||||
provider := &AWSProvider{
|
||||
client: route53.New(session),
|
||||
domainFilter: domainFilter,
|
||||
zoneIDFilter: zoneIDFilter,
|
||||
zoneTypeFilter: zoneTypeFilter,
|
||||
dryRun: dryRun,
|
||||
}
|
||||
@ -112,6 +115,10 @@ func (p *AWSProvider) Zones() (map[string]*route53.HostedZone, error) {
|
||||
|
||||
f := func(resp *route53.ListHostedZonesOutput, lastPage bool) (shouldContinue bool) {
|
||||
for _, zone := range resp.HostedZones {
|
||||
if !p.zoneIDFilter.Match(aws.StringValue(zone.Id)) {
|
||||
continue
|
||||
}
|
||||
|
||||
if !p.zoneTypeFilter.Match(zone) {
|
||||
continue
|
||||
}
|
||||
|
@ -183,15 +183,17 @@ func TestAWSZones(t *testing.T) {
|
||||
|
||||
for _, ti := range []struct {
|
||||
msg string
|
||||
zoneIDFilter ZoneIDFilter
|
||||
zoneTypeFilter ZoneTypeFilter
|
||||
expectedZones map[string]*route53.HostedZone
|
||||
}{
|
||||
{"no filter", NewZoneTypeFilter(""), allZones},
|
||||
{"public filter", NewZoneTypeFilter("public"), publicZones},
|
||||
{"private filter", NewZoneTypeFilter("private"), privateZones},
|
||||
{"unknown filter", NewZoneTypeFilter("unknown"), noZones},
|
||||
{"no filter", NewZoneIDFilter([]string{}), NewZoneTypeFilter(""), allZones},
|
||||
{"public filter", NewZoneIDFilter([]string{}), NewZoneTypeFilter("public"), publicZones},
|
||||
{"private filter", NewZoneIDFilter([]string{}), NewZoneTypeFilter("private"), privateZones},
|
||||
{"unknown filter", NewZoneIDFilter([]string{}), NewZoneTypeFilter("unknown"), noZones},
|
||||
{"zone id filter", NewZoneIDFilter([]string{"/hostedzone/zone-3.ext-dns-test-2.teapot.zalan.do."}), NewZoneTypeFilter(""), privateZones},
|
||||
} {
|
||||
provider := newAWSProvider(t, NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), ti.zoneTypeFilter, false, []*endpoint.Endpoint{})
|
||||
provider := newAWSProvider(t, NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), ti.zoneIDFilter, ti.zoneTypeFilter, false, []*endpoint.Endpoint{})
|
||||
|
||||
zones, err := provider.Zones()
|
||||
require.NoError(t, err)
|
||||
@ -201,7 +203,7 @@ func TestAWSZones(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestAWSRecords(t *testing.T) {
|
||||
provider := newAWSProvider(t, NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), NewZoneTypeFilter(""), false, []*endpoint.Endpoint{
|
||||
provider := newAWSProvider(t, NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), NewZoneIDFilter([]string{}), NewZoneTypeFilter(""), false, []*endpoint.Endpoint{
|
||||
endpoint.NewEndpointWithTTL("list-test.zone-1.ext-dns-test-2.teapot.zalan.do", "1.2.3.4", endpoint.RecordTypeA, endpoint.TTL(recordTTL)),
|
||||
endpoint.NewEndpointWithTTL("list-test.zone-2.ext-dns-test-2.teapot.zalan.do", "8.8.8.8", endpoint.RecordTypeA, endpoint.TTL(recordTTL)),
|
||||
endpoint.NewEndpointWithTTL("*.wildcard-test.zone-2.ext-dns-test-2.teapot.zalan.do", "8.8.8.8", endpoint.RecordTypeA, endpoint.TTL(recordTTL)),
|
||||
@ -223,7 +225,7 @@ func TestAWSRecords(t *testing.T) {
|
||||
|
||||
func TestAWSCreateRecords(t *testing.T) {
|
||||
customTTL := endpoint.TTL(60)
|
||||
provider := newAWSProvider(t, NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), NewZoneTypeFilter(""), false, []*endpoint.Endpoint{})
|
||||
provider := newAWSProvider(t, NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), NewZoneIDFilter([]string{}), NewZoneTypeFilter(""), false, []*endpoint.Endpoint{})
|
||||
|
||||
records := []*endpoint.Endpoint{
|
||||
endpoint.NewEndpoint("create-test.zone-1.ext-dns-test-2.teapot.zalan.do", "1.2.3.4", endpoint.RecordTypeA),
|
||||
@ -246,7 +248,7 @@ func TestAWSCreateRecords(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestAWSUpdateRecords(t *testing.T) {
|
||||
provider := newAWSProvider(t, NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), NewZoneTypeFilter(""), false, []*endpoint.Endpoint{
|
||||
provider := newAWSProvider(t, NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), NewZoneIDFilter([]string{}), NewZoneTypeFilter(""), false, []*endpoint.Endpoint{
|
||||
endpoint.NewEndpointWithTTL("update-test.zone-1.ext-dns-test-2.teapot.zalan.do", "8.8.8.8", endpoint.RecordTypeA, endpoint.TTL(recordTTL)),
|
||||
endpoint.NewEndpointWithTTL("update-test.zone-2.ext-dns-test-2.teapot.zalan.do", "8.8.4.4", endpoint.RecordTypeA, endpoint.TTL(recordTTL)),
|
||||
endpoint.NewEndpointWithTTL("update-test-cname.zone-1.ext-dns-test-2.teapot.zalan.do", "foo.elb.amazonaws.com", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL)),
|
||||
@ -284,7 +286,7 @@ func TestAWSDeleteRecords(t *testing.T) {
|
||||
endpoint.NewEndpoint("delete-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do", "foo.eu-central-1.elb.amazonaws.com", endpoint.RecordTypeCNAME),
|
||||
}
|
||||
|
||||
provider := newAWSProvider(t, NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), NewZoneTypeFilter(""), false, originalEndpoints)
|
||||
provider := newAWSProvider(t, NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), NewZoneIDFilter([]string{}), NewZoneTypeFilter(""), false, originalEndpoints)
|
||||
|
||||
require.NoError(t, provider.DeleteRecords(originalEndpoints))
|
||||
|
||||
@ -296,7 +298,7 @@ func TestAWSDeleteRecords(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestAWSApplyChanges(t *testing.T) {
|
||||
provider := newAWSProvider(t, NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), NewZoneTypeFilter(""), false, []*endpoint.Endpoint{
|
||||
provider := newAWSProvider(t, NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), NewZoneIDFilter([]string{}), NewZoneTypeFilter(""), false, []*endpoint.Endpoint{
|
||||
endpoint.NewEndpointWithTTL("update-test.zone-1.ext-dns-test-2.teapot.zalan.do", "8.8.8.8", endpoint.RecordTypeA, endpoint.TTL(recordTTL)),
|
||||
endpoint.NewEndpointWithTTL("delete-test.zone-1.ext-dns-test-2.teapot.zalan.do", "8.8.8.8", endpoint.RecordTypeA, endpoint.TTL(recordTTL)),
|
||||
endpoint.NewEndpointWithTTL("update-test.zone-2.ext-dns-test-2.teapot.zalan.do", "8.8.4.4", endpoint.RecordTypeA, endpoint.TTL(recordTTL)),
|
||||
@ -370,7 +372,7 @@ func TestAWSApplyChangesDryRun(t *testing.T) {
|
||||
endpoint.NewEndpointWithTTL("delete-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do", "qux.elb.amazonaws.com", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL)),
|
||||
}
|
||||
|
||||
provider := newAWSProvider(t, NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), NewZoneTypeFilter(""), true, originalEndpoints)
|
||||
provider := newAWSProvider(t, NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), NewZoneIDFilter([]string{}), NewZoneTypeFilter(""), true, originalEndpoints)
|
||||
|
||||
createRecords := []*endpoint.Endpoint{
|
||||
endpoint.NewEndpoint("create-test.zone-1.ext-dns-test-2.teapot.zalan.do", "8.8.8.8", endpoint.RecordTypeA),
|
||||
@ -492,7 +494,7 @@ func TestAWSChangesByZones(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestAWSsubmitChanges(t *testing.T) {
|
||||
provider := newAWSProvider(t, NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), NewZoneTypeFilter(""), false, []*endpoint.Endpoint{})
|
||||
provider := newAWSProvider(t, NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), NewZoneIDFilter([]string{}), NewZoneTypeFilter(""), false, []*endpoint.Endpoint{})
|
||||
const subnets = 16
|
||||
const hosts = maxChangeCount / subnets
|
||||
|
||||
@ -604,7 +606,7 @@ func validateAWSChangeRecord(t *testing.T, record *route53.Change, expected *rou
|
||||
}
|
||||
|
||||
func TestAWSCreateRecordsWithCNAME(t *testing.T) {
|
||||
provider := newAWSProvider(t, NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), NewZoneTypeFilter(""), false, []*endpoint.Endpoint{})
|
||||
provider := newAWSProvider(t, NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), NewZoneIDFilter([]string{}), NewZoneTypeFilter(""), false, []*endpoint.Endpoint{})
|
||||
|
||||
records := []*endpoint.Endpoint{
|
||||
{DNSName: "create-test.zone-1.ext-dns-test-2.teapot.zalan.do", Target: "foo.example.org", RecordType: endpoint.RecordTypeCNAME},
|
||||
@ -629,7 +631,7 @@ func TestAWSCreateRecordsWithCNAME(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestAWSCreateRecordsWithALIAS(t *testing.T) {
|
||||
provider := newAWSProvider(t, NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), NewZoneTypeFilter(""), false, []*endpoint.Endpoint{})
|
||||
provider := newAWSProvider(t, NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), NewZoneIDFilter([]string{}), NewZoneTypeFilter(""), false, []*endpoint.Endpoint{})
|
||||
|
||||
records := []*endpoint.Endpoint{
|
||||
{DNSName: "create-test.zone-1.ext-dns-test-2.teapot.zalan.do", Target: "foo.eu-central-1.elb.amazonaws.com", RecordType: endpoint.RecordTypeCNAME},
|
||||
@ -764,12 +766,13 @@ func clearAWSRecords(t *testing.T, provider *AWSProvider, zone string) {
|
||||
}
|
||||
}
|
||||
|
||||
func newAWSProvider(t *testing.T, domainFilter DomainFilter, zoneTypeFilter ZoneTypeFilter, dryRun bool, records []*endpoint.Endpoint) *AWSProvider {
|
||||
func newAWSProvider(t *testing.T, domainFilter DomainFilter, zoneIDFilter ZoneIDFilter, zoneTypeFilter ZoneTypeFilter, dryRun bool, records []*endpoint.Endpoint) *AWSProvider {
|
||||
client := NewRoute53APIStub()
|
||||
|
||||
provider := &AWSProvider{
|
||||
client: client,
|
||||
domainFilter: domainFilter,
|
||||
zoneIDFilter: zoneIDFilter,
|
||||
zoneTypeFilter: zoneTypeFilter,
|
||||
dryRun: false,
|
||||
}
|
||||
|
@ -66,6 +66,7 @@ type RecordsClient interface {
|
||||
// AzureProvider implements the DNS provider for Microsoft's Azure cloud platform.
|
||||
type AzureProvider struct {
|
||||
domainFilter DomainFilter
|
||||
zoneIDFilter ZoneIDFilter
|
||||
dryRun bool
|
||||
resourceGroup string
|
||||
zonesClient ZonesClient
|
||||
@ -75,7 +76,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 DomainFilter, resourceGroup string, dryRun bool) (*AzureProvider, error) {
|
||||
func NewAzureProvider(configFile string, domainFilter DomainFilter, zoneIDFilter ZoneIDFilter, resourceGroup 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)
|
||||
@ -118,6 +119,7 @@ func NewAzureProvider(configFile string, domainFilter DomainFilter, resourceGrou
|
||||
|
||||
provider := &AzureProvider{
|
||||
domainFilter: domainFilter,
|
||||
zoneIDFilter: zoneIDFilter,
|
||||
dryRun: dryRun,
|
||||
resourceGroup: cfg.ResourceGroup,
|
||||
zonesClient: zonesClient,
|
||||
@ -194,9 +196,19 @@ func (p *AzureProvider) zones() ([]dns.Zone, error) {
|
||||
|
||||
for list.Value != nil && len(*list.Value) > 0 {
|
||||
for _, zone := range *list.Value {
|
||||
if zone.Name != nil && p.domainFilter.Match(*zone.Name) {
|
||||
zones = append(zones, zone)
|
||||
if zone.Name == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if !p.domainFilter.Match(*zone.Name) {
|
||||
continue
|
||||
}
|
||||
|
||||
if !p.zoneIDFilter.Match(*zone.ID) {
|
||||
continue
|
||||
}
|
||||
|
||||
zones = append(zones, zone)
|
||||
}
|
||||
|
||||
list, err = p.zonesClient.ListByResourceGroupNextResults(list)
|
||||
|
@ -37,8 +37,9 @@ type mockRecordsClient struct {
|
||||
updatedEndpoints []*endpoint.Endpoint
|
||||
}
|
||||
|
||||
func createMockZone(zone string) dns.Zone {
|
||||
func createMockZone(zone string, id string) dns.Zone {
|
||||
return dns.Zone{
|
||||
ID: to.StringPtr(id),
|
||||
Name: to.StringPtr(zone),
|
||||
}
|
||||
}
|
||||
@ -138,9 +139,10 @@ func (client *mockRecordsClient) CreateOrUpdate(resourceGroupName string, zoneNa
|
||||
return parameters, nil
|
||||
}
|
||||
|
||||
func newAzureProvider(domainFilter DomainFilter, dryRun bool, resourceGroup string, zonesClient ZonesClient, recordsClient RecordsClient) *AzureProvider {
|
||||
func newAzureProvider(domainFilter DomainFilter, zoneIDFilter ZoneIDFilter, dryRun bool, resourceGroup string, zonesClient ZonesClient, recordsClient RecordsClient) *AzureProvider {
|
||||
return &AzureProvider{
|
||||
domainFilter: domainFilter,
|
||||
zoneIDFilter: zoneIDFilter,
|
||||
dryRun: dryRun,
|
||||
resourceGroup: resourceGroup,
|
||||
zonesClient: zonesClient,
|
||||
@ -152,7 +154,7 @@ func TestAzureRecord(t *testing.T) {
|
||||
zonesClient := mockZonesClient{
|
||||
mockZoneListResult: &dns.ZoneListResult{
|
||||
Value: &[]dns.Zone{
|
||||
createMockZone("example.com"),
|
||||
createMockZone("example.com", "/dnszones/example.com"),
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -169,7 +171,7 @@ func TestAzureRecord(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
provider := newAzureProvider(NewDomainFilter([]string{"example.com"}), true, "k8s", &zonesClient, &recordsClient)
|
||||
provider := newAzureProvider(NewDomainFilter([]string{"example.com"}), NewZoneIDFilter([]string{""}), true, "k8s", &zonesClient, &recordsClient)
|
||||
actual, err := provider.Records()
|
||||
|
||||
if err != nil {
|
||||
@ -225,13 +227,14 @@ func TestAzureApplyChangesDryRun(t *testing.T) {
|
||||
func testAzureApplyChangesInternal(t *testing.T, dryRun bool, client RecordsClient) {
|
||||
provider := newAzureProvider(
|
||||
NewDomainFilter([]string{""}),
|
||||
NewZoneIDFilter([]string{""}),
|
||||
dryRun,
|
||||
"group",
|
||||
&mockZonesClient{
|
||||
mockZoneListResult: &dns.ZoneListResult{
|
||||
Value: &[]dns.Zone{
|
||||
createMockZone("example.com"),
|
||||
createMockZone("other.com"),
|
||||
createMockZone("example.com", "/dnszones/example.com"),
|
||||
createMockZone("other.com", "/dnszones/other.com"),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -92,6 +92,7 @@ type CloudFlareProvider struct {
|
||||
Client cloudFlareDNS
|
||||
// only consider hosted zones managing domains ending in this suffix
|
||||
domainFilter DomainFilter
|
||||
zoneIDFilter ZoneIDFilter
|
||||
proxied bool
|
||||
DryRun bool
|
||||
}
|
||||
@ -103,7 +104,7 @@ type cloudFlareChange struct {
|
||||
}
|
||||
|
||||
// NewCloudFlareProvider initializes a new CloudFlare DNS based Provider.
|
||||
func NewCloudFlareProvider(domainFilter DomainFilter, proxied bool, dryRun bool) (*CloudFlareProvider, error) {
|
||||
func NewCloudFlareProvider(domainFilter DomainFilter, zoneIDFilter ZoneIDFilter, proxied bool, dryRun bool) (*CloudFlareProvider, error) {
|
||||
// initialize via API email and API key and returns new API object
|
||||
config, err := cloudflare.New(os.Getenv("CF_API_KEY"), os.Getenv("CF_API_EMAIL"))
|
||||
if err != nil {
|
||||
@ -113,6 +114,7 @@ func NewCloudFlareProvider(domainFilter DomainFilter, proxied bool, dryRun bool)
|
||||
//Client: config,
|
||||
Client: zoneService{config},
|
||||
domainFilter: domainFilter,
|
||||
zoneIDFilter: zoneIDFilter,
|
||||
proxied: proxied,
|
||||
DryRun: dryRun,
|
||||
}
|
||||
@ -129,9 +131,15 @@ func (p *CloudFlareProvider) Zones() ([]cloudflare.Zone, error) {
|
||||
}
|
||||
|
||||
for _, zone := range zones {
|
||||
if p.domainFilter.Match(zone.Name) {
|
||||
result = append(result, zone)
|
||||
if !p.domainFilter.Match(zone.Name) {
|
||||
continue
|
||||
}
|
||||
|
||||
if !p.zoneIDFilter.Match(zone.ID) {
|
||||
continue
|
||||
}
|
||||
|
||||
result = append(result, zone)
|
||||
}
|
||||
|
||||
return result, nil
|
||||
|
@ -378,6 +378,7 @@ func TestCloudFlareZones(t *testing.T) {
|
||||
provider := &CloudFlareProvider{
|
||||
Client: &mockCloudFlareClient{},
|
||||
domainFilter: NewDomainFilter([]string{"zalando.to."}),
|
||||
zoneIDFilter: NewZoneIDFilter([]string{""}),
|
||||
}
|
||||
|
||||
zones, err := provider.Zones()
|
||||
@ -415,13 +416,13 @@ func TestRecords(t *testing.T) {
|
||||
func TestNewCloudFlareProvider(t *testing.T) {
|
||||
_ = os.Setenv("CF_API_KEY", "xxxxxxxxxxxxxxxxx")
|
||||
_ = os.Setenv("CF_API_EMAIL", "test@test.com")
|
||||
_, err := NewCloudFlareProvider(NewDomainFilter([]string{"ext-dns-test.zalando.to."}), false, true)
|
||||
_, err := NewCloudFlareProvider(NewDomainFilter([]string{"ext-dns-test.zalando.to."}), NewZoneIDFilter([]string{""}), false, true)
|
||||
if err != nil {
|
||||
t.Errorf("should not fail, %s", err)
|
||||
}
|
||||
_ = os.Unsetenv("CF_API_KEY")
|
||||
_ = os.Unsetenv("CF_API_EMAIL")
|
||||
_, err = NewCloudFlareProvider(NewDomainFilter([]string{"ext-dns-test.zalando.to."}), false, true)
|
||||
_, err = NewCloudFlareProvider(NewDomainFilter([]string{"ext-dns-test.zalando.to."}), NewZoneIDFilter([]string{""}), false, true)
|
||||
if err == nil {
|
||||
t.Errorf("expected to fail")
|
||||
}
|
||||
|
@ -84,6 +84,7 @@ type dnsimpleProvider struct {
|
||||
identity identityService
|
||||
accountID string
|
||||
domainFilter DomainFilter
|
||||
zoneIDFilter ZoneIDFilter
|
||||
dryRun bool
|
||||
}
|
||||
|
||||
@ -99,7 +100,7 @@ const (
|
||||
)
|
||||
|
||||
// NewDnsimpleProvider initializes a new Dnsimple based provider
|
||||
func NewDnsimpleProvider(domainFilter DomainFilter, dryRun bool) (Provider, error) {
|
||||
func NewDnsimpleProvider(domainFilter DomainFilter, zoneIDFilter ZoneIDFilter, dryRun bool) (Provider, error) {
|
||||
oauthToken := os.Getenv("DNSIMPLE_OAUTH")
|
||||
if len(oauthToken) == 0 {
|
||||
return nil, fmt.Errorf("No dnsimple oauth token provided")
|
||||
@ -109,6 +110,7 @@ func NewDnsimpleProvider(domainFilter DomainFilter, dryRun bool) (Provider, erro
|
||||
client: dnsimpleZoneService{service: client.Zones},
|
||||
identity: identityService{service: client.Identity},
|
||||
domainFilter: domainFilter,
|
||||
zoneIDFilter: zoneIDFilter,
|
||||
dryRun: dryRun,
|
||||
}
|
||||
whoamiResponse, err := provider.identity.service.Whoami()
|
||||
@ -119,7 +121,7 @@ func NewDnsimpleProvider(domainFilter DomainFilter, dryRun bool) (Provider, erro
|
||||
return provider, nil
|
||||
}
|
||||
|
||||
// Returns a list of Zones that end with the provider's domainFilter
|
||||
// Returns a list of filtered Zones
|
||||
func (p *dnsimpleProvider) Zones() (map[string]dnsimple.Zone, error) {
|
||||
zones := make(map[string]dnsimple.Zone)
|
||||
zonesResponse, err := p.client.ListZones(p.accountID, &dnsimple.ZoneListOptions{})
|
||||
@ -127,9 +129,15 @@ func (p *dnsimpleProvider) Zones() (map[string]dnsimple.Zone, error) {
|
||||
return nil, err
|
||||
}
|
||||
for _, zone := range zonesResponse.Data {
|
||||
if p.domainFilter.Match(zone.Name) {
|
||||
zones[strconv.Itoa(zone.ID)] = zone
|
||||
if !p.domainFilter.Match(zone.Name) {
|
||||
continue
|
||||
}
|
||||
|
||||
if !p.zoneIDFilter.Match(strconv.Itoa(zone.ID)) {
|
||||
continue
|
||||
}
|
||||
|
||||
zones[strconv.Itoa(zone.ID)] = zone
|
||||
}
|
||||
return zones, nil
|
||||
}
|
||||
|
@ -153,7 +153,7 @@ func testDnsimpleSuitableZone(t *testing.T) {
|
||||
|
||||
func TestNewDnsimpleProvider(t *testing.T) {
|
||||
os.Setenv("DNSIMPLE_OAUTH", "xxxxxxxxxxxxxxxxxxxxxxxxxx")
|
||||
_, err := NewDnsimpleProvider(DomainFilter{filters: []string{"example.com"}}, true)
|
||||
_, err := NewDnsimpleProvider(NewDomainFilter([]string{"example.com"}), NewZoneIDFilter([]string{""}), true)
|
||||
if err == nil {
|
||||
t.Errorf("Expected to fail new provider on bad token")
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ limitations under the License.
|
||||
package provider
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/linki/instrumented_http"
|
||||
@ -102,6 +103,8 @@ type GoogleProvider struct {
|
||||
dryRun bool
|
||||
// only consider hosted zones managing domains ending in this suffix
|
||||
domainFilter DomainFilter
|
||||
// only consider hosted zones ending with this zone id
|
||||
zoneIDFilter ZoneIDFilter
|
||||
// A client for managing resource record sets
|
||||
resourceRecordSetsClient resourceRecordSetsClientInterface
|
||||
// A client for managing hosted zones
|
||||
@ -111,7 +114,7 @@ type GoogleProvider struct {
|
||||
}
|
||||
|
||||
// NewGoogleProvider initializes a new Google CloudDNS based Provider.
|
||||
func NewGoogleProvider(project string, domainFilter DomainFilter, dryRun bool) (*GoogleProvider, error) {
|
||||
func NewGoogleProvider(project string, domainFilter DomainFilter, zoneIDFilter ZoneIDFilter, dryRun bool) (*GoogleProvider, error) {
|
||||
gcloud, err := google.DefaultClient(context.TODO(), dns.NdevClouddnsReadwriteScope)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -132,6 +135,7 @@ func NewGoogleProvider(project string, domainFilter DomainFilter, dryRun bool) (
|
||||
provider := &GoogleProvider{
|
||||
project: project,
|
||||
domainFilter: domainFilter,
|
||||
zoneIDFilter: zoneIDFilter,
|
||||
dryRun: dryRun,
|
||||
resourceRecordSetsClient: resourceRecordSetsService{dnsClient.ResourceRecordSets},
|
||||
managedZonesClient: managedZonesService{dnsClient.ManagedZones},
|
||||
@ -147,9 +151,15 @@ func (p *GoogleProvider) Zones() (map[string]*dns.ManagedZone, error) {
|
||||
|
||||
f := func(resp *dns.ManagedZonesListResponse) error {
|
||||
for _, zone := range resp.ManagedZones {
|
||||
if p.domainFilter.Match(zone.DnsName) {
|
||||
zones[zone.Name] = zone
|
||||
if !p.domainFilter.Match(zone.DnsName) {
|
||||
continue
|
||||
}
|
||||
|
||||
if !p.zoneIDFilter.Match(fmt.Sprintf("%v", zone.Id)) {
|
||||
continue
|
||||
}
|
||||
|
||||
zones[zone.Name] = zone
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -193,7 +193,7 @@ func hasTrailingDot(target string) bool {
|
||||
}
|
||||
|
||||
func TestGoogleZones(t *testing.T) {
|
||||
provider := newGoogleProvider(t, NewDomainFilter([]string{"ext-dns-test-2.gcp.zalan.do."}), false, []*endpoint.Endpoint{})
|
||||
provider := newGoogleProvider(t, NewDomainFilter([]string{"ext-dns-test-2.gcp.zalan.do."}), NewZoneIDFilter([]string{""}), false, []*endpoint.Endpoint{})
|
||||
|
||||
zones, err := provider.Zones()
|
||||
require.NoError(t, err)
|
||||
@ -212,7 +212,7 @@ func TestGoogleRecords(t *testing.T) {
|
||||
endpoint.NewEndpoint("list-test-alias.zone-1.ext-dns-test-2.gcp.zalan.do", "foo.elb.amazonaws.com", endpoint.RecordTypeCNAME),
|
||||
}
|
||||
|
||||
provider := newGoogleProvider(t, NewDomainFilter([]string{"ext-dns-test-2.gcp.zalan.do."}), false, originalEndpoints)
|
||||
provider := newGoogleProvider(t, NewDomainFilter([]string{"ext-dns-test-2.gcp.zalan.do."}), NewZoneIDFilter([]string{""}), false, originalEndpoints)
|
||||
|
||||
records, err := provider.Records()
|
||||
require.NoError(t, err)
|
||||
@ -221,7 +221,7 @@ func TestGoogleRecords(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGoogleCreateRecords(t *testing.T) {
|
||||
provider := newGoogleProvider(t, NewDomainFilter([]string{"ext-dns-test-2.gcp.zalan.do."}), false, []*endpoint.Endpoint{})
|
||||
provider := newGoogleProvider(t, NewDomainFilter([]string{"ext-dns-test-2.gcp.zalan.do."}), NewZoneIDFilter([]string{""}), false, []*endpoint.Endpoint{})
|
||||
|
||||
records := []*endpoint.Endpoint{
|
||||
endpoint.NewEndpoint("create-test.zone-1.ext-dns-test-2.gcp.zalan.do", "1.2.3.4", endpoint.RecordTypeA),
|
||||
@ -242,7 +242,7 @@ func TestGoogleCreateRecords(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGoogleUpdateRecords(t *testing.T) {
|
||||
provider := newGoogleProvider(t, NewDomainFilter([]string{"ext-dns-test-2.gcp.zalan.do."}), false, []*endpoint.Endpoint{
|
||||
provider := newGoogleProvider(t, NewDomainFilter([]string{"ext-dns-test-2.gcp.zalan.do."}), NewZoneIDFilter([]string{""}), false, []*endpoint.Endpoint{
|
||||
endpoint.NewEndpoint("update-test.zone-1.ext-dns-test-2.gcp.zalan.do", "8.8.8.8", endpoint.RecordTypeA),
|
||||
endpoint.NewEndpoint("update-test.zone-2.ext-dns-test-2.gcp.zalan.do", "8.8.4.4", endpoint.RecordTypeA),
|
||||
endpoint.NewEndpoint("update-test-cname.zone-1.ext-dns-test-2.gcp.zalan.do", "foo.elb.amazonaws.com", endpoint.RecordTypeCNAME),
|
||||
@ -278,7 +278,7 @@ func TestGoogleDeleteRecords(t *testing.T) {
|
||||
endpoint.NewEndpoint("delete-test-cname.zone-1.ext-dns-test-2.gcp.zalan.do", "baz.elb.amazonaws.com", endpoint.RecordTypeCNAME),
|
||||
}
|
||||
|
||||
provider := newGoogleProvider(t, NewDomainFilter([]string{"ext-dns-test-2.gcp.zalan.do."}), false, originalEndpoints)
|
||||
provider := newGoogleProvider(t, NewDomainFilter([]string{"ext-dns-test-2.gcp.zalan.do."}), NewZoneIDFilter([]string{""}), false, originalEndpoints)
|
||||
|
||||
require.NoError(t, provider.DeleteRecords(originalEndpoints))
|
||||
|
||||
@ -289,7 +289,7 @@ func TestGoogleDeleteRecords(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGoogleApplyChanges(t *testing.T) {
|
||||
provider := newGoogleProvider(t, NewDomainFilter([]string{"ext-dns-test-2.gcp.zalan.do."}), false, []*endpoint.Endpoint{
|
||||
provider := newGoogleProvider(t, NewDomainFilter([]string{"ext-dns-test-2.gcp.zalan.do."}), NewZoneIDFilter([]string{""}), false, []*endpoint.Endpoint{
|
||||
endpoint.NewEndpoint("update-test.zone-1.ext-dns-test-2.gcp.zalan.do", "8.8.8.8", endpoint.RecordTypeA),
|
||||
endpoint.NewEndpoint("delete-test.zone-1.ext-dns-test-2.gcp.zalan.do", "8.8.8.8", endpoint.RecordTypeA),
|
||||
endpoint.NewEndpoint("update-test.zone-2.ext-dns-test-2.gcp.zalan.do", "8.8.4.4", endpoint.RecordTypeA),
|
||||
@ -353,7 +353,7 @@ func TestGoogleApplyChangesDryRun(t *testing.T) {
|
||||
endpoint.NewEndpoint("delete-test-cname.zone-1.ext-dns-test-2.gcp.zalan.do", "qux.elb.amazonaws.com", endpoint.RecordTypeCNAME),
|
||||
}
|
||||
|
||||
provider := newGoogleProvider(t, NewDomainFilter([]string{"ext-dns-test-2.gcp.zalan.do."}), true, originalEndpoints)
|
||||
provider := newGoogleProvider(t, NewDomainFilter([]string{"ext-dns-test-2.gcp.zalan.do."}), NewZoneIDFilter([]string{""}), true, originalEndpoints)
|
||||
|
||||
createRecords := []*endpoint.Endpoint{
|
||||
endpoint.NewEndpoint("create-test.zone-1.ext-dns-test-2.gcp.zalan.do", "8.8.8.8", endpoint.RecordTypeA),
|
||||
@ -394,7 +394,7 @@ func TestGoogleApplyChangesDryRun(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGoogleApplyChangesEmpty(t *testing.T) {
|
||||
provider := newGoogleProvider(t, NewDomainFilter([]string{"ext-dns-test-2.gcp.zalan.do."}), false, []*endpoint.Endpoint{})
|
||||
provider := newGoogleProvider(t, NewDomainFilter([]string{"ext-dns-test-2.gcp.zalan.do."}), NewZoneIDFilter([]string{""}), false, []*endpoint.Endpoint{})
|
||||
assert.NoError(t, provider.ApplyChanges(&plan.Changes{}))
|
||||
}
|
||||
|
||||
@ -501,10 +501,11 @@ func validateChangeRecord(t *testing.T, record *dns.ResourceRecordSet, expected
|
||||
assert.Equal(t, expected.Type, record.Type)
|
||||
}
|
||||
|
||||
func newGoogleProvider(t *testing.T, domainFilter DomainFilter, dryRun bool, records []*endpoint.Endpoint) *GoogleProvider {
|
||||
func newGoogleProvider(t *testing.T, domainFilter DomainFilter, zoneIDFilter ZoneIDFilter, dryRun bool, records []*endpoint.Endpoint) *GoogleProvider {
|
||||
provider := &GoogleProvider{
|
||||
project: "zalando-external-dns-test",
|
||||
domainFilter: domainFilter,
|
||||
zoneIDFilter: zoneIDFilter,
|
||||
dryRun: false,
|
||||
resourceRecordSetsClient: &mockResourceRecordSetsClient{},
|
||||
managedZonesClient: &mockManagedZonesClient{},
|
||||
|
@ -30,6 +30,7 @@ import (
|
||||
// InfobloxConfig clarifies the method signature
|
||||
type InfobloxConfig struct {
|
||||
DomainFilter DomainFilter
|
||||
ZoneIDFilter ZoneIDFilter
|
||||
Host string
|
||||
Port int
|
||||
Username string
|
||||
@ -43,6 +44,7 @@ type InfobloxConfig struct {
|
||||
type InfobloxProvider struct {
|
||||
client ibclient.IBConnector
|
||||
domainFilter DomainFilter
|
||||
zoneIDFilter ZoneIDFilter
|
||||
dryRun bool
|
||||
}
|
||||
|
||||
@ -82,6 +84,7 @@ func NewInfobloxProvider(infobloxConfig InfobloxConfig) (*InfobloxProvider, erro
|
||||
provider := &InfobloxProvider{
|
||||
client: client,
|
||||
domainFilter: infobloxConfig.DomainFilter,
|
||||
zoneIDFilter: infobloxConfig.ZoneIDFilter,
|
||||
dryRun: infobloxConfig.DryRun,
|
||||
}
|
||||
|
||||
@ -186,9 +189,15 @@ func (p *InfobloxProvider) zones() ([]ibclient.ZoneAuth, error) {
|
||||
}
|
||||
|
||||
for _, zone := range res {
|
||||
if p.domainFilter.Match(zone.Fqdn) {
|
||||
result = append(result, zone)
|
||||
if !p.domainFilter.Match(zone.Fqdn) {
|
||||
continue
|
||||
}
|
||||
|
||||
if !p.zoneIDFilter.Match(zone.Ref) {
|
||||
continue
|
||||
}
|
||||
|
||||
result = append(result, zone)
|
||||
}
|
||||
|
||||
return result, nil
|
||||
|
@ -327,10 +327,11 @@ func createMockInfobloxObject(name, recordType, value string) ibclient.IBObject
|
||||
return nil
|
||||
}
|
||||
|
||||
func newInfobloxProvider(domainFilter DomainFilter, dryRun bool, client ibclient.IBConnector) *InfobloxProvider {
|
||||
func newInfobloxProvider(domainFilter DomainFilter, zoneIDFilter ZoneIDFilter, dryRun bool, client ibclient.IBConnector) *InfobloxProvider {
|
||||
return &InfobloxProvider{
|
||||
client: client,
|
||||
domainFilter: domainFilter,
|
||||
zoneIDFilter: zoneIDFilter,
|
||||
dryRun: dryRun,
|
||||
}
|
||||
}
|
||||
@ -351,7 +352,7 @@ func TestInfobloxRecords(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
provider := newInfobloxProvider(NewDomainFilter([]string{"example.com"}), true, &client)
|
||||
provider := newInfobloxProvider(NewDomainFilter([]string{"example.com"}), NewZoneIDFilter([]string{""}), true, &client)
|
||||
actual, err := provider.Records()
|
||||
|
||||
if err != nil {
|
||||
@ -425,6 +426,7 @@ func testInfobloxApplyChangesInternal(t *testing.T, dryRun bool, client ibclient
|
||||
|
||||
provider := newInfobloxProvider(
|
||||
NewDomainFilter([]string{""}),
|
||||
NewZoneIDFilter([]string{""}),
|
||||
dryRun,
|
||||
client,
|
||||
)
|
||||
@ -482,7 +484,7 @@ func TestInfobloxZones(t *testing.T) {
|
||||
mockInfobloxObjects: &[]ibclient.IBObject{},
|
||||
}
|
||||
|
||||
provider := newInfobloxProvider(NewDomainFilter([]string{"example.com"}), true, &client)
|
||||
provider := newInfobloxProvider(NewDomainFilter([]string{"example.com"}), NewZoneIDFilter([]string{""}), true, &client)
|
||||
zones, _ := provider.zones()
|
||||
|
||||
assert.Equal(t, provider.findZone(zones, "example.com").Fqdn, "example.com")
|
||||
|
45
provider/zone_id_filter.go
Normal file
45
provider/zone_id_filter.go
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package provider
|
||||
|
||||
import "strings"
|
||||
|
||||
// ZoneIDFilter holds a list of zone ids to filter by
|
||||
type ZoneIDFilter struct {
|
||||
zoneIDs []string
|
||||
}
|
||||
|
||||
// NewZoneIDFilter returns a new ZoneIDFilter given a list of zone ids
|
||||
func NewZoneIDFilter(zoneIDs []string) ZoneIDFilter {
|
||||
return ZoneIDFilter{zoneIDs}
|
||||
}
|
||||
|
||||
// Match checks whether a zone matches one of the provided zone ids
|
||||
func (f ZoneIDFilter) Match(zoneID string) bool {
|
||||
// An empty filter includes all zones.
|
||||
if len(f.zoneIDs) == 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
for _, id := range f.zoneIDs {
|
||||
if strings.HasSuffix(zoneID, id) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
79
provider/zone_id_filter_test.go
Normal file
79
provider/zone_id_filter_test.go
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package provider
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
type zoneIDFilterTest struct {
|
||||
zoneIDFilter []string
|
||||
zone string
|
||||
expected bool
|
||||
}
|
||||
|
||||
func TestZoneIDFilterMatch(t *testing.T) {
|
||||
zone := "/hostedzone/ZTST1"
|
||||
|
||||
for _, tt := range []zoneIDFilterTest{
|
||||
{
|
||||
[]string{},
|
||||
zone,
|
||||
true,
|
||||
},
|
||||
{
|
||||
[]string{"/hostedzone/ZTST1"},
|
||||
zone,
|
||||
true,
|
||||
},
|
||||
{
|
||||
[]string{"/hostedzone/ZTST2"},
|
||||
zone,
|
||||
false,
|
||||
},
|
||||
{
|
||||
[]string{"ZTST1"},
|
||||
zone,
|
||||
true,
|
||||
},
|
||||
{
|
||||
[]string{"ZTST2"},
|
||||
zone,
|
||||
false,
|
||||
},
|
||||
{
|
||||
[]string{"/hostedzone/ZTST1", "/hostedzone/ZTST2"},
|
||||
zone,
|
||||
true,
|
||||
},
|
||||
{
|
||||
[]string{"/hostedzone/ZTST2", "/hostedzone/ZTST3"},
|
||||
zone,
|
||||
false,
|
||||
},
|
||||
{
|
||||
[]string{"/hostedzone/ZTST2", "/hostedzone/ZTST1"},
|
||||
zone,
|
||||
true,
|
||||
},
|
||||
} {
|
||||
zoneIDFilter := NewZoneIDFilter(tt.zoneIDFilter)
|
||||
assert.Equal(t, tt.expected, zoneIDFilter.Match(tt.zone))
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user