From 0986e6370e542831296c19a1418f555e632a0e60 Mon Sep 17 00:00:00 2001 From: Elie Date: Fri, 13 May 2022 14:12:31 +0200 Subject: [PATCH] fix: driftignore that ignore type In some case driftignore filtering engine was ignoring some types event if some inclusion rules are defined. This is because we do not handle the case where we use an inclusion rule on a resource with an ID, the git matching logic is not exactly what we want here. --- pkg/filter/driftignore.go | 13 +++++++++- pkg/filter/driftignore_test.go | 44 ++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/pkg/filter/driftignore.go b/pkg/filter/driftignore.go index d7885f40..ac9033f2 100644 --- a/pkg/filter/driftignore.go +++ b/pkg/filter/driftignore.go @@ -90,7 +90,7 @@ func (r *DriftIgnore) parseIgnorePattern(line string, patterns *[]gitignore.Patt func (r *DriftIgnore) isAnyOfChildrenTypesNotIgnored(ty resource.ResourceType) bool { childrenTypes := resource.GetMeta(ty).GetChildrenTypes() for _, childrenType := range childrenTypes { - if !r.match(fmt.Sprintf("%s.*", childrenType)) { + if !r.shouldIgnoreType(childrenType) { return true } if r.isAnyOfChildrenTypesNotIgnored(childrenType) { @@ -107,6 +107,17 @@ func (r *DriftIgnore) IsTypeIgnored(ty resource.ResourceType) bool { return false } + return r.shouldIgnoreType(ty) +} + +func (r *DriftIgnore) shouldIgnoreType(ty resource.ResourceType) bool { + for _, pattern := range r.ignorePatterns { + // If a line start with a `!` and if the type match, we should not ignore it + if strings.HasPrefix(pattern, fmt.Sprintf("!%s.", ty)) { + return false + } + } + return r.match(fmt.Sprintf("%s.*", ty)) } diff --git a/pkg/filter/driftignore_test.go b/pkg/filter/driftignore_test.go index 61002cfb..575ea7b2 100644 --- a/pkg/filter/driftignore_test.go +++ b/pkg/filter/driftignore_test.go @@ -712,6 +712,50 @@ func TestDriftIgnore_IsTypeIgnored(t *testing.T) { path: "testdata/drift_ignore_all/.driftignore", ignores: []string{"*", "!aws_s3*", "!aws_route53*"}, }, + { + name: "do not ignore type when one inclusion rule with resource ID exist", + resources: []*resource.Resource{ + // This type should not be ignored because of `!aws_iam_policy_attachment.foo*` expression + { + Type: "aws_iam_policy_attachment", + Id: "foobar", + }, + // This type should not be ignored because `azurerm_route` type is not ignored and is a child of `azurerm_route_table` + { + Type: "azurerm_route_table", + Id: "uselessId", + }, + // This type should not be ignored because of `!azurerm_route.barfoo` expression + { + Type: "azurerm_route", + Id: "barfoo", + }, + }, + want: []bool{ + false, + false, + false, + }, + path: "", + ignores: []string{"*", "!aws_iam_policy_attachment.foobar", "!azurerm_route.barfoo"}, + }, + { + name: "ignore type wildcard while excluding one", + resources: []*resource.Resource{ + { + Type: "type_ignored", + }, + { + Type: "type_not_ignored", + }, + }, + want: []bool{ + true, + false, + }, + path: "", + ignores: []string{"type_*", "!type_not_ignored"}, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) {