diff --git a/internal/controllers/topology/cluster/structuredmerge/filterintent.go b/internal/controllers/topology/cluster/structuredmerge/filterintent.go index 2b743db040d2..a8d741d1e6a1 100644 --- a/internal/controllers/topology/cluster/structuredmerge/filterintent.go +++ b/internal/controllers/topology/cluster/structuredmerge/filterintent.go @@ -79,6 +79,7 @@ func filterIntent(ctx *filterIntentInput) bool { // Ensure we are not leaving empty maps around. if v, ok := fieldCtx.value.(map[string]interface{}); ok && len(v) == 0 { delete(value, field) + gotDeletions = true } } } diff --git a/internal/controllers/topology/cluster/structuredmerge/filterintent_test.go b/internal/controllers/topology/cluster/structuredmerge/filterintent_test.go index 30be02e21277..e68f5bc6335d 100644 --- a/internal/controllers/topology/cluster/structuredmerge/filterintent_test.go +++ b/internal/controllers/topology/cluster/structuredmerge/filterintent_test.go @@ -167,6 +167,27 @@ func Test_filterIgnoredPaths(t *testing.T) { // we are filtering out spec.foo and then spec given that it is an empty map }, }, + { + name: "Cleanup empty nested maps", + ctx: &filterIntentInput{ + path: contract.Path{}, + value: map[string]interface{}{ + "spec": map[string]interface{}{ + "bar": map[string]interface{}{ + "foo": "123", + }, + }, + }, + shouldFilter: isIgnorePath( + []contract.Path{ + {"spec", "bar", "foo"}, + }, + ), + }, + wantValue: map[string]interface{}{ + // we are filtering out spec.bar.foo and then spec given that it is an empty map + }, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) {