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()
// This filter has tags configured but this object
// does not have any tag, skip this object
if len(tagsMap) == 0 {
// Not enough tags on object to satisfy the rule filter's tags
if len(tagsMap) < len(f.cachedTags) {
return false
}
// Both filter and object have tags, find a match,
// skip this object otherwise
var mismatch bool
for k, cv := range f.cachedTags {
v, ok := tagsMap[k]
if ok && v == cv {
return true
if !ok || v != cv {
mismatch = true
break
}
}
return false
return !mismatch
}
// 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)
}
})
}
}