Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(filter-tags): pre-process filter tags #5063

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 21 additions & 14 deletions provider/zone_tag_filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,36 +22,43 @@ import (

// ZoneTagFilter holds a list of zone tags to filter by
type ZoneTagFilter struct {
zoneTags []string
tagsMap map[string]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}
tagsMap := make(map[string]string)
// tags pre-processing, to make sure the pre-processing is not happening at the time of filtering
for _, tag := range tags {
parts := strings.SplitN(tag, "=", 2)
key := strings.TrimSpace(parts[0])
if key == "" {
continue
}
if len(parts) == 2 {
value := strings.TrimSpace(parts[1])
tagsMap[key] = value
} else {
tagsMap[key] = ""
}
}
return ZoneTagFilter{tagsMap: tagsMap}
}

// 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
}
for key, v := range f.tagsMap {
if value, hasTag := tagsMap[key]; !hasTag || (v != "" && value != v) {
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
return len(f.tagsMap) == 0
}
13 changes: 7 additions & 6 deletions provider/zone_tag_filter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ var basicZoneTags = []struct {
"empty tag filter matches all", []string{""}, map[string]string{"tag0": "value0"}, true,
},
{
"tag filter without key and equal sign", []string{"tag1=value1", "=haha"}, map[string]string{"tag1": "value1"}, false,
"tag filter without key and equal sign", []string{"tag1=value1", "=haha"}, map[string]string{"tag1": "value1"}, true,
},
}

Expand All @@ -74,16 +74,17 @@ func TestZoneTagFilterNotSupportedFormat(t *testing.T) {
tests := []struct {
desc string
tags []string
want []string
want map[string]string
}{
{desc: "multiple or separate values with commas", tags: []string{"key1=val1,key2=val2"}, want: []string{"key1=val1,key2=val2"}},
{desc: "exclude tag", tags: []string{"!key1"}, want: []string{"!key1"}},
{desc: "exclude tags", tags: []string{"!key1=val"}, want: []string{"!key1=val"}},
{desc: "multiple or separate values with commas", tags: []string{"key1=val1,key2=val2"}, want: map[string]string{"key1": "val1,key2=val2"}},
{desc: "exclude tag", tags: []string{"!key1"}, want: map[string]string{"!key1": ""}},
{desc: "exclude tags", tags: []string{"!key1=val"}, want: map[string]string{"!key1": "val"}},
{desc: "key is empty", tags: []string{"=val"}, want: map[string]string{}},
}
for _, tc := range tests {
t.Run(fmt.Sprintf("%s", tc.desc), func(t *testing.T) {
got := NewZoneTagFilter(tc.tags)
assert.Equal(t, tc.want, got.zoneTags)
assert.Equal(t, tc.want, got.tagsMap)
})
}
}
Expand Down
Loading