chore(filter-tags): pre-process tags

Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
This commit is contained in:
ivan katliarchuk 2025-02-05 08:52:17 +00:00
parent b9d033b1a0
commit aaa5bc3947
No known key found for this signature in database
GPG Key ID: 601CDBBBB76E47BE
2 changed files with 28 additions and 20 deletions

View File

@ -22,7 +22,7 @@ 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
@ -30,28 +30,35 @@ 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 {
for key, v := range f.tagsMap {
if value, hasTag := tagsMap[key]; !hasTag || (v != "" && value != v) {
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
return len(f.tagsMap) == 0
}

View File

@ -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,
},
}
@ -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)
})
}
}