ilm: Select an object when all AND tags are satisfied (#19134)

Currently, if one object tag matches with one lifecycle tag filter, ILM
will select it, however, this is wrong. All the Tag filters in the
lifecycle document should be satisfied.
This commit is contained in:
Anis Eleuch 2024-02-27 01:01:20 +01:00 committed by GitHub
parent b1351e2dee
commit 95032e4710
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 107 additions and 8 deletions

View File

@ -232,21 +232,20 @@ func (f Filter) TestTags(userTags string) bool {
} }
tagsMap := parsedTags.ToMap() tagsMap := parsedTags.ToMap()
// This filter has tags configured but this object // Not enough tags on object to satisfy the rule filter's tags
// does not have any tag, skip this object if len(tagsMap) < len(f.cachedTags) {
if len(tagsMap) == 0 {
return false return false
} }
// Both filter and object have tags, find a match, var mismatch bool
// skip this object otherwise
for k, cv := range f.cachedTags { for k, cv := range f.cachedTags {
v, ok := tagsMap[k] v, ok := tagsMap[k]
if ok && v == cv { if !ok || v != cv {
return true mismatch = true
break
} }
} }
return false return !mismatch
} }
// BySize returns true if sz satisfies one of ObjectSizeGreaterThan, // BySize returns true if sz satisfies one of ObjectSizeGreaterThan,

View File

@ -241,3 +241,103 @@ func TestObjectSizeFilters(t *testing.T) {
}) })
} }
} }
func TestTestTags(t *testing.T) {
noTags := Filter{
set: true,
And: And{
Tags: []Tag{},
},
andSet: true,
}
oneTag := Filter{
set: true,
And: And{
Tags: []Tag{{Key: "FOO", Value: "1"}},
},
andSet: true,
}
twoTags := Filter{
set: true,
And: And{
Tags: []Tag{{Key: "FOO", Value: "1"}, {Key: "BAR", Value: "2"}},
},
andSet: true,
}
tests := []struct {
filter Filter
userTags string
want bool
}{
{
filter: noTags,
userTags: "",
want: true,
},
{
filter: noTags,
userTags: "A=3",
want: true,
},
{
filter: oneTag,
userTags: "A=3",
want: false,
},
{
filter: oneTag,
userTags: "FOO=1",
want: true,
},
{
filter: oneTag,
userTags: "A=B&FOO=1",
want: true,
},
{
filter: twoTags,
userTags: "",
want: false,
},
{
filter: twoTags,
userTags: "FOO=1",
want: false,
},
{
filter: twoTags,
userTags: "BAR=2",
want: false,
},
{
filter: twoTags,
userTags: "FOO=2&BAR=2",
want: false,
},
{
filter: twoTags,
userTags: "F=1&B=2",
want: false,
},
{
filter: twoTags,
userTags: "FOO=1&BAR=2",
want: true,
},
{
filter: twoTags,
userTags: "BAR=2&FOO=1",
want: true,
},
}
for i, test := range tests {
t.Run(fmt.Sprintf("Test %d", i+1), func(t *testing.T) {
if got := test.filter.TestTags(test.userTags); got != test.want {
t.Errorf("Expected %v but got %v", test.want, got)
}
})
}
}