mirror of
https://github.com/kubernetes-sigs/external-dns.git
synced 2025-08-05 17:16:59 +02:00
Add zone tag filter for AWS
This commit is contained in:
parent
f25f90db0e
commit
65e13af9b7
2
main.go
2
main.go
@ -99,6 +99,7 @@ func main() {
|
||||
domainFilter := provider.NewDomainFilter(cfg.DomainFilter)
|
||||
zoneIDFilter := provider.NewZoneIDFilter(cfg.ZoneIDFilter)
|
||||
zoneTypeFilter := provider.NewZoneTypeFilter(cfg.AWSZoneType)
|
||||
zoneTagFilter := provider.NewZoneTagFilter(cfg.AWSZoneTagFilter)
|
||||
|
||||
var p provider.Provider
|
||||
switch cfg.Provider {
|
||||
@ -110,6 +111,7 @@ func main() {
|
||||
DomainFilter: domainFilter,
|
||||
ZoneIDFilter: zoneIDFilter,
|
||||
ZoneTypeFilter: zoneTypeFilter,
|
||||
ZoneTagFilter: zoneTagFilter,
|
||||
BatchChangeSize: cfg.AWSBatchChangeSize,
|
||||
BatchChangeInterval: cfg.AWSBatchChangeInterval,
|
||||
EvaluateTargetHealth: cfg.AWSEvaluateTargetHealth,
|
||||
|
@ -56,6 +56,7 @@ type Config struct {
|
||||
AlibabaCloudConfigFile string
|
||||
AlibabaCloudZoneType string
|
||||
AWSZoneType string
|
||||
AWSZoneTagFilter []string
|
||||
AWSAssumeRole string
|
||||
AWSBatchChangeSize int
|
||||
AWSBatchChangeInterval time.Duration
|
||||
@ -127,6 +128,7 @@ var defaultConfig = &Config{
|
||||
DomainFilter: []string{},
|
||||
AlibabaCloudConfigFile: "/etc/kubernetes/alibaba-cloud.json",
|
||||
AWSZoneType: "",
|
||||
AWSZoneTagFilter: []string{},
|
||||
AWSAssumeRole: "",
|
||||
AWSBatchChangeSize: 4000,
|
||||
AWSBatchChangeInterval: time.Second,
|
||||
@ -241,6 +243,7 @@ func (cfg *Config) ParseFlags(args []string) error {
|
||||
app.Flag("alibaba-cloud-config-file", "When using the Alibaba Cloud provider, specify the Alibaba Cloud configuration file (required when --provider=alibabacloud").Default(defaultConfig.AlibabaCloudConfigFile).StringVar(&cfg.AlibabaCloudConfigFile)
|
||||
app.Flag("alibaba-cloud-zone-type", "When using the Alibaba Cloud provider, filter for zones of this type (optional, options: public, private)").Default(defaultConfig.AlibabaCloudZoneType).EnumVar(&cfg.AlibabaCloudZoneType, "", "public", "private")
|
||||
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("aws-zone-tags", "When using the AWS provider, filter for zones with these tags").Default("").StringsVar(&cfg.AWSZoneTagFilter)
|
||||
app.Flag("aws-assume-role", "When using the AWS provider, assume this IAM role. Useful for hosted zones in another AWS account. Specify the full ARN, e.g. `arn:aws:iam::123455567:role/external-dns` (optional)").Default(defaultConfig.AWSAssumeRole).StringVar(&cfg.AWSAssumeRole)
|
||||
app.Flag("aws-batch-change-size", "When using the AWS provider, set the maximum number of changes that will be applied in each batch.").Default(strconv.Itoa(defaultConfig.AWSBatchChangeSize)).IntVar(&cfg.AWSBatchChangeSize)
|
||||
app.Flag("aws-batch-change-interval", "When using the AWS provider, set the interval between batch changes.").Default(defaultConfig.AWSBatchChangeInterval.String()).DurationVar(&cfg.AWSBatchChangeInterval)
|
||||
|
@ -43,6 +43,7 @@ var (
|
||||
ZoneIDFilter: []string{""},
|
||||
AlibabaCloudConfigFile: "/etc/kubernetes/alibaba-cloud.json",
|
||||
AWSZoneType: "",
|
||||
AWSZoneTagFilter: []string{""},
|
||||
AWSAssumeRole: "",
|
||||
AWSBatchChangeSize: 4000,
|
||||
AWSBatchChangeInterval: time.Second,
|
||||
@ -94,6 +95,7 @@ var (
|
||||
ZoneIDFilter: []string{"/hostedzone/ZTST1", "/hostedzone/ZTST2"},
|
||||
AlibabaCloudConfigFile: "/etc/kubernetes/alibaba-cloud.json",
|
||||
AWSZoneType: "private",
|
||||
AWSZoneTagFilter: []string{"tag=foo"},
|
||||
AWSAssumeRole: "some-other-role",
|
||||
AWSBatchChangeSize: 100,
|
||||
AWSBatchChangeInterval: time.Second * 2,
|
||||
@ -189,6 +191,7 @@ func TestParseFlags(t *testing.T) {
|
||||
"--zone-id-filter=/hostedzone/ZTST1",
|
||||
"--zone-id-filter=/hostedzone/ZTST2",
|
||||
"--aws-zone-type=private",
|
||||
"--aws-zone-tags=tag=foo",
|
||||
"--aws-assume-role=some-other-role",
|
||||
"--aws-batch-change-size=100",
|
||||
"--aws-batch-change-interval=2s",
|
||||
@ -248,6 +251,7 @@ func TestParseFlags(t *testing.T) {
|
||||
"EXTERNAL_DNS_TLS_CLIENT_CERT_KEY": "/path/to/key.pem",
|
||||
"EXTERNAL_DNS_ZONE_ID_FILTER": "/hostedzone/ZTST1\n/hostedzone/ZTST2",
|
||||
"EXTERNAL_DNS_AWS_ZONE_TYPE": "private",
|
||||
"EXTERNAL_DNS_AWS_ZONE_TAGS": "tag=foo",
|
||||
"EXTERNAL_DNS_AWS_ASSUME_ROLE": "some-other-role",
|
||||
"EXTERNAL_DNS_AWS_BATCH_CHANGE_SIZE": "100",
|
||||
"EXTERNAL_DNS_AWS_BATCH_CHANGE_INTERVAL": "2s",
|
||||
|
@ -85,6 +85,7 @@ type Route53API interface {
|
||||
ChangeResourceRecordSets(*route53.ChangeResourceRecordSetsInput) (*route53.ChangeResourceRecordSetsOutput, error)
|
||||
CreateHostedZone(*route53.CreateHostedZoneInput) (*route53.CreateHostedZoneOutput, error)
|
||||
ListHostedZonesPages(input *route53.ListHostedZonesInput, fn func(resp *route53.ListHostedZonesOutput, lastPage bool) (shouldContinue bool)) error
|
||||
ListTagsForResource(input *route53.ListTagsForResourceInput) (*route53.ListTagsForResourceOutput, error)
|
||||
}
|
||||
|
||||
// AWSProvider is an implementation of Provider for AWS Route53.
|
||||
@ -100,6 +101,8 @@ type AWSProvider struct {
|
||||
zoneIDFilter ZoneIDFilter
|
||||
// filter hosted zones by type (e.g. private or public)
|
||||
zoneTypeFilter ZoneTypeFilter
|
||||
// filter hosted zones by tags
|
||||
zoneTagFilter ZoneTagFilter
|
||||
}
|
||||
|
||||
// AWSConfig contains configuration to create a new AWS provider.
|
||||
@ -107,6 +110,7 @@ type AWSConfig struct {
|
||||
DomainFilter DomainFilter
|
||||
ZoneIDFilter ZoneIDFilter
|
||||
ZoneTypeFilter ZoneTypeFilter
|
||||
ZoneTagFilter ZoneTagFilter
|
||||
BatchChangeSize int
|
||||
BatchChangeInterval time.Duration
|
||||
EvaluateTargetHealth bool
|
||||
@ -145,6 +149,7 @@ func NewAWSProvider(awsConfig AWSConfig) (*AWSProvider, error) {
|
||||
domainFilter: awsConfig.DomainFilter,
|
||||
zoneIDFilter: awsConfig.ZoneIDFilter,
|
||||
zoneTypeFilter: awsConfig.ZoneTypeFilter,
|
||||
zoneTagFilter: awsConfig.ZoneTagFilter,
|
||||
batchChangeSize: awsConfig.BatchChangeSize,
|
||||
batchChangeInterval: awsConfig.BatchChangeInterval,
|
||||
evaluateTargetHealth: awsConfig.EvaluateTargetHealth,
|
||||
@ -158,6 +163,7 @@ func NewAWSProvider(awsConfig AWSConfig) (*AWSProvider, error) {
|
||||
func (p *AWSProvider) Zones() (map[string]*route53.HostedZone, error) {
|
||||
zones := make(map[string]*route53.HostedZone)
|
||||
|
||||
var tagErr error
|
||||
f := func(resp *route53.ListHostedZonesOutput, lastPage bool) (shouldContinue bool) {
|
||||
for _, zone := range resp.HostedZones {
|
||||
if !p.zoneIDFilter.Match(aws.StringValue(zone.Id)) {
|
||||
@ -172,6 +178,18 @@ func (p *AWSProvider) Zones() (map[string]*route53.HostedZone, error) {
|
||||
continue
|
||||
}
|
||||
|
||||
// Only fetch tags if a tag filter was specified
|
||||
if !p.zoneTagFilter.IsEmpty() {
|
||||
tags, err := p.tagsForZone(*zone.Id)
|
||||
if err != nil {
|
||||
tagErr = err
|
||||
return false
|
||||
}
|
||||
if !p.zoneTagFilter.Match(tags) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
zones[aws.StringValue(zone.Id)] = zone
|
||||
}
|
||||
|
||||
@ -182,6 +200,9 @@ func (p *AWSProvider) Zones() (map[string]*route53.HostedZone, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if tagErr != nil {
|
||||
return nil, tagErr
|
||||
}
|
||||
|
||||
for _, zone := range zones {
|
||||
log.Debugf("Considering zone: %s (domain: %s)", aws.StringValue(zone.Id), aws.StringValue(zone.Name))
|
||||
@ -412,6 +433,21 @@ func (p *AWSProvider) newChange(action string, endpoint *endpoint.Endpoint) *rou
|
||||
return change
|
||||
}
|
||||
|
||||
func (p *AWSProvider) tagsForZone(zoneID string) (map[string]string, error) {
|
||||
response, err := p.client.ListTagsForResource(&route53.ListTagsForResourceInput{
|
||||
ResourceType: aws.String("hostedzone"),
|
||||
ResourceId: aws.String(zoneID),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tagMap := map[string]string{}
|
||||
for _, tag := range response.ResourceTagSet.Tags {
|
||||
tagMap[*tag.Key] = *tag.Value
|
||||
}
|
||||
return tagMap, nil
|
||||
}
|
||||
|
||||
func batchChangeSet(cs []*route53.Change, batchSize int) [][]*route53.Change {
|
||||
if len(cs) <= batchSize {
|
||||
return [][]*route53.Change{cs}
|
||||
|
@ -50,6 +50,7 @@ var _ Route53API = &Route53APIStub{}
|
||||
type Route53APIStub struct {
|
||||
zones map[string]*route53.HostedZone
|
||||
recordSets map[string]map[string][]*route53.ResourceRecordSet
|
||||
zoneTags map[string][]*route53.Tag
|
||||
m dynamicMock
|
||||
}
|
||||
|
||||
@ -66,6 +67,7 @@ func NewRoute53APIStub() *Route53APIStub {
|
||||
return &Route53APIStub{
|
||||
zones: make(map[string]*route53.HostedZone),
|
||||
recordSets: make(map[string]map[string][]*route53.ResourceRecordSet),
|
||||
zoneTags: make(map[string][]*route53.Tag),
|
||||
}
|
||||
}
|
||||
|
||||
@ -95,6 +97,20 @@ func wildcardEscape(s string) string {
|
||||
return s
|
||||
}
|
||||
|
||||
func (r *Route53APIStub) ListTagsForResource(input *route53.ListTagsForResourceInput) (*route53.ListTagsForResourceOutput, error) {
|
||||
if aws.StringValue(input.ResourceType) == "hostedzone" {
|
||||
tags := r.zoneTags[aws.StringValue(input.ResourceId)]
|
||||
return &route53.ListTagsForResourceOutput{
|
||||
ResourceTagSet: &route53.ResourceTagSet{
|
||||
ResourceId: input.ResourceId,
|
||||
ResourceType: input.ResourceType,
|
||||
Tags: tags,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
return &route53.ListTagsForResourceOutput{}, nil
|
||||
}
|
||||
|
||||
func (r *Route53APIStub) ChangeResourceRecordSets(input *route53.ChangeResourceRecordSetsInput) (*route53.ChangeResourceRecordSetsOutput, error) {
|
||||
if r.m.isMocked("ChangeResourceRecordSets", input) {
|
||||
return r.m.ChangeResourceRecordSets(input)
|
||||
@ -231,15 +247,17 @@ func TestAWSZones(t *testing.T) {
|
||||
msg string
|
||||
zoneIDFilter ZoneIDFilter
|
||||
zoneTypeFilter ZoneTypeFilter
|
||||
zoneTagFilter ZoneTagFilter
|
||||
expectedZones map[string]*route53.HostedZone
|
||||
}{
|
||||
{"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},
|
||||
{"no filter", NewZoneIDFilter([]string{}), NewZoneTypeFilter(""), NewZoneTagFilter([]string{}), allZones},
|
||||
{"public filter", NewZoneIDFilter([]string{}), NewZoneTypeFilter("public"), NewZoneTagFilter([]string{}), publicZones},
|
||||
{"private filter", NewZoneIDFilter([]string{}), NewZoneTypeFilter("private"), NewZoneTagFilter([]string{}), privateZones},
|
||||
{"unknown filter", NewZoneIDFilter([]string{}), NewZoneTypeFilter("unknown"), NewZoneTagFilter([]string{}), noZones},
|
||||
{"zone id filter", NewZoneIDFilter([]string{"/hostedzone/zone-3.ext-dns-test-2.teapot.zalan.do."}), NewZoneTypeFilter(""), NewZoneTagFilter([]string{}), privateZones},
|
||||
{"tag filter", NewZoneIDFilter([]string{}), NewZoneTypeFilter(""), NewZoneTagFilter([]string{"zone=3"}), privateZones},
|
||||
} {
|
||||
provider, _ := newAWSProvider(t, NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), ti.zoneIDFilter, ti.zoneTypeFilter, defaultEvaluateTargetHealth, false, []*endpoint.Endpoint{})
|
||||
provider, _ := newAWSProviderWithTagFilter(t, NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), ti.zoneIDFilter, ti.zoneTypeFilter, ti.zoneTagFilter, defaultEvaluateTargetHealth, false, []*endpoint.Endpoint{})
|
||||
|
||||
zones, err := provider.Zones()
|
||||
require.NoError(t, err)
|
||||
@ -1027,8 +1045,11 @@ func escapeAWSRecords(t *testing.T, provider *AWSProvider, zone string) {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
}
|
||||
|
||||
func newAWSProvider(t *testing.T, domainFilter DomainFilter, zoneIDFilter ZoneIDFilter, zoneTypeFilter ZoneTypeFilter, evaluateTargetHealth, dryRun bool, records []*endpoint.Endpoint) (*AWSProvider, *Route53APIStub) {
|
||||
return newAWSProviderWithTagFilter(t, domainFilter, zoneIDFilter, zoneTypeFilter, NewZoneTagFilter([]string{}), evaluateTargetHealth, dryRun, records)
|
||||
}
|
||||
|
||||
func newAWSProviderWithTagFilter(t *testing.T, domainFilter DomainFilter, zoneIDFilter ZoneIDFilter, zoneTypeFilter ZoneTypeFilter, zoneTagFilter ZoneTagFilter, evaluateTargetHealth, dryRun bool, records []*endpoint.Endpoint) (*AWSProvider, *Route53APIStub) {
|
||||
client := NewRoute53APIStub()
|
||||
|
||||
provider := &AWSProvider{
|
||||
@ -1039,6 +1060,7 @@ func newAWSProvider(t *testing.T, domainFilter DomainFilter, zoneIDFilter ZoneID
|
||||
domainFilter: domainFilter,
|
||||
zoneIDFilter: zoneIDFilter,
|
||||
zoneTypeFilter: zoneTypeFilter,
|
||||
zoneTagFilter: zoneTagFilter,
|
||||
dryRun: false,
|
||||
}
|
||||
|
||||
@ -1067,6 +1089,8 @@ func newAWSProvider(t *testing.T, domainFilter DomainFilter, zoneIDFilter ZoneID
|
||||
Config: &route53.HostedZoneConfig{PrivateZone: aws.Bool(false)},
|
||||
})
|
||||
|
||||
setupZoneTags(provider.client.(*Route53APIStub))
|
||||
|
||||
setupAWSRecords(t, provider, records)
|
||||
|
||||
provider.dryRun = dryRun
|
||||
@ -1074,6 +1098,40 @@ func newAWSProvider(t *testing.T, domainFilter DomainFilter, zoneIDFilter ZoneID
|
||||
return provider, client
|
||||
}
|
||||
|
||||
func setupZoneTags(client *Route53APIStub) {
|
||||
addZoneTags(client.zoneTags, "/hostedzone/zone-1.ext-dns-test-2.teapot.zalan.do.", map[string]string{
|
||||
"zone-1-tag-1": "tag-1-value",
|
||||
"domain": "test-2",
|
||||
"zone": "1",
|
||||
})
|
||||
addZoneTags(client.zoneTags, "/hostedzone/zone-2.ext-dns-test-2.teapot.zalan.do.", map[string]string{
|
||||
"zone-2-tag-1": "tag-1-value",
|
||||
"domain": "test-2",
|
||||
"zone": "2",
|
||||
})
|
||||
addZoneTags(client.zoneTags, "/hostedzone/zone-3.ext-dns-test-2.teapot.zalan.do.", map[string]string{
|
||||
"zone-3-tag-1": "tag-1-value",
|
||||
"domain": "test-2",
|
||||
"zone": "3",
|
||||
})
|
||||
addZoneTags(client.zoneTags, "/hostedzone/zone-4.ext-dns-test-2.teapot.zalan.do.", map[string]string{
|
||||
"zone-4-tag-1": "tag-1-value",
|
||||
"domain": "test-3",
|
||||
"zone": "4",
|
||||
})
|
||||
}
|
||||
|
||||
func addZoneTags(tagMap map[string][]*route53.Tag, zoneID string, tags map[string]string) {
|
||||
tagList := make([]*route53.Tag, 0, len(tags))
|
||||
for k, v := range tags {
|
||||
tagList = append(tagList, &route53.Tag{
|
||||
Key: aws.String(k),
|
||||
Value: aws.String(v),
|
||||
})
|
||||
}
|
||||
tagMap[zoneID] = tagList
|
||||
}
|
||||
|
||||
func validateRecords(t *testing.T, records []*route53.ResourceRecordSet, expected []*route53.ResourceRecordSet) {
|
||||
assert.Equal(t, expected, records)
|
||||
}
|
||||
|
57
provider/zone_tag_filter.go
Normal file
57
provider/zone_tag_filter.go
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
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"
|
||||
)
|
||||
|
||||
// ZoneTagFilter holds a list of zone tags to filter by
|
||||
type ZoneTagFilter struct {
|
||||
zoneTags []string
|
||||
}
|
||||
|
||||
// NewZoneTagFilter returns a new ZoneTagFilter given a list of zone tags
|
||||
func NewZoneTagFilter(tags []string) ZoneTagFilter {
|
||||
if len(tags) == 1 && len(tags[0]) == 0 {
|
||||
tags = []string{}
|
||||
}
|
||||
return ZoneTagFilter{zoneTags: tags}
|
||||
}
|
||||
|
||||
// Match checks whether a zone's set of tags matches the provided tag values
|
||||
func (f ZoneTagFilter) Match(tagsMap map[string]string) bool {
|
||||
for _, tagFilter := range f.zoneTags {
|
||||
filterParts := strings.SplitN(tagFilter, "=", 2)
|
||||
switch len(filterParts) {
|
||||
case 1:
|
||||
if _, hasTag := tagsMap[filterParts[0]]; !hasTag {
|
||||
return false
|
||||
}
|
||||
case 2:
|
||||
if value, hasTag := tagsMap[filterParts[0]]; !hasTag || value != filterParts[1] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// IsEmpty returns true if there are no tags for the filter
|
||||
func (f ZoneTagFilter) IsEmpty() bool {
|
||||
return len(f.zoneTags) == 0
|
||||
}
|
62
provider/zone_tag_filter_test.go
Normal file
62
provider/zone_tag_filter_test.go
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
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"
|
||||
)
|
||||
|
||||
func TestZoneTagFilterMatch(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
zoneTagFilter []string
|
||||
zoneTags map[string]string
|
||||
matches bool
|
||||
}{
|
||||
{
|
||||
"single tag no match", []string{"tag1=value1"}, map[string]string{"tag0": "value0"}, false,
|
||||
},
|
||||
{
|
||||
"single tag matches", []string{"tag1=value1"}, map[string]string{"tag1": "value1"}, true,
|
||||
},
|
||||
{
|
||||
"multiple tags no value match", []string{"tag1=value1"}, map[string]string{"tag0": "value0", "tag1": "value2"}, false,
|
||||
},
|
||||
{
|
||||
"multiple tags matches", []string{"tag1=value1"}, map[string]string{"tag0": "value0", "tag1": "value1"}, true,
|
||||
},
|
||||
{
|
||||
"tag name no match", []string{"tag1"}, map[string]string{"tag0": "value0"}, false,
|
||||
},
|
||||
{
|
||||
"tag name matches", []string{"tag1"}, map[string]string{"tag1": "value1"}, true,
|
||||
},
|
||||
{
|
||||
"multiple filter no match", []string{"tag1=value1", "tag2=value2"}, map[string]string{"tag1": "value1"}, false,
|
||||
},
|
||||
{
|
||||
"multiple filter matches", []string{"tag1=value1", "tag2=value2"}, map[string]string{"tag2": "value2", "tag1": "value1", "tag3": "value3"}, true,
|
||||
},
|
||||
} {
|
||||
zoneTagFilter := NewZoneTagFilter(tc.zoneTagFilter)
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
assert.Equal(t, tc.matches, zoneTagFilter.Match(tc.zoneTags))
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user