From aaa5bc394775a1c6ef72c50ab00e914a89ebe0c8 Mon Sep 17 00:00:00 2001 From: ivan katliarchuk Date: Wed, 5 Feb 2025 08:52:17 +0000 Subject: [PATCH] chore(filter-tags): pre-process tags Signed-off-by: ivan katliarchuk --- provider/zone_tag_filter.go | 35 +++++++++++++++++++------------- provider/zone_tag_filter_test.go | 13 ++++++------ 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/provider/zone_tag_filter.go b/provider/zone_tag_filter.go index c40ab06e9..f659420d5 100644 --- a/provider/zone_tag_filter.go +++ b/provider/zone_tag_filter.go @@ -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,22 +30,29 @@ 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 @@ -53,5 +60,5 @@ func (f ZoneTagFilter) Match(tagsMap map[string]string) bool { // 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 } diff --git a/provider/zone_tag_filter_test.go b/provider/zone_tag_filter_test.go index 05d435cea..a2a0b688b 100644 --- a/provider/zone_tag_filter_test.go +++ b/provider/zone_tag_filter_test.go @@ -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) }) } }