fix: apply tag:<key> filters to DescribeTags rows

This commit is contained in:
Julian Sommer
2026-09-30 11:05:44 +10:00
parent 5b2ca9373b
commit 45fdbc0444
2 changed files with 54 additions and 0 deletions
@@ -344,6 +344,9 @@ func (s *TagsServiceImpl) DescribeTags(ctx context.Context, input *ec2.DescribeT
if !filterutil.MatchesAny(filters["tag-key"], key) || !filterutil.MatchesAny(filters["tag-value"], value) {
continue
}
if !rowMatchesTagFilters(filters, key, value) {
continue
}
tags = append(tags, &ec2.TagDescription{
ResourceId: aws.String(resourceID),
@@ -361,6 +364,22 @@ func (s *TagsServiceImpl) DescribeTags(ctx context.Context, input *ec2.DescribeT
}, nil
}
// rowMatchesTagFilters applies each tag:<key> filter to one tag row, as
// tag-key and tag-value are applied here: the row must be that key, with a
// value the filter names.
func rowMatchesTagFilters(filters map[string][]string, key, value string) bool {
for name, values := range filters {
tagKey, ok := strings.CutPrefix(name, "tag:")
if !ok {
continue
}
if key != tagKey || !filterutil.MatchesAny(values, value) {
return false
}
}
return true
}
// DeleteTags removes tags from the specified resources.
func (s *TagsServiceImpl) DeleteTags(ctx context.Context, input *ec2.DeleteTagsInput, accountID string) (*ec2.DeleteTagsOutput, error) {
if input == nil {
@@ -322,6 +322,41 @@ func TestDescribeTags_FilterByTagKeyAndTagValue(t *testing.T) {
assert.Empty(t, describe("tag-value", "zz-awsdiff-none"))
}
// TestDescribeTags_FilterByTagKeyName checks that a tag:<key> filter selects
// the matching tag row, and only rows of resources that carry it.
func TestDescribeTags_FilterByTagKeyName(t *testing.T) {
svc, _ := setupTestTagsService(t)
for id, run := range map[string]string{"subnet-test1": "run-1", "subnet-test2": "run-2"} {
_, err := svc.CreateTags(context.Background(), &ec2.CreateTagsInput{
Resources: []*string{aws.String(id)},
Tags: []*ec2.Tag{
{Key: aws.String("env"), Value: aws.String("prod")},
{Key: aws.String("awsdiff"), Value: aws.String(run)},
},
}, testAccountID)
require.NoError(t, err)
}
result, err := svc.DescribeTags(context.Background(), &ec2.DescribeTagsInput{
Filters: []*ec2.Filter{
{Name: aws.String("resource-type"), Values: []*string{aws.String("subnet")}},
{Name: aws.String("tag:awsdiff"), Values: []*string{aws.String("run-1")}},
},
}, testAccountID)
require.NoError(t, err)
require.Len(t, result.Tags, 1)
assert.Equal(t, "subnet-test1", aws.StringValue(result.Tags[0].ResourceId))
assert.Equal(t, "awsdiff", aws.StringValue(result.Tags[0].Key))
assert.Equal(t, "run-1", aws.StringValue(result.Tags[0].Value))
result, err = svc.DescribeTags(context.Background(), &ec2.DescribeTagsInput{
Filters: []*ec2.Filter{{Name: aws.String("tag:awsdiff"), Values: []*string{aws.String("zz-awsdiff-none")}}},
}, testAccountID)
require.NoError(t, err)
assert.Empty(t, result.Tags)
}
// TestDescribeTags_Empty tests listing tags when none exist.
func TestDescribeTags_Empty(t *testing.T) {
svc, _ := setupTestTagsService(t)