diff --git a/pkg/engine/mutate/strategicPreprocessing.go b/pkg/engine/mutate/strategicPreprocessing.go index a3f85f41f3..e2ae6a9b45 100644 --- a/pkg/engine/mutate/strategicPreprocessing.go +++ b/pkg/engine/mutate/strategicPreprocessing.go @@ -103,11 +103,23 @@ func walkMap(pattern, resource *yaml.RNode) error { if ind == -1 { continue } - + // remove anchor tags from value // A MappingNode contains keyNode and Value node // keyNode contains it's key value in it's Value field, So remove anchor tags from Value field pattern.YNode().Content[ind].Value = removeAnchor(key) + // If the field exists in resource, then remove the field from pattern + _, resFields, err := getAnchorSortedFields(resource) + if err != nil { + return err + } + rInd := getIndex(removeAnchor(key), resFields) + if rInd != -1 { + // remove anchor field from the map and update fields + removeAnchorNode(pattern, ind) + sfields = removeKeyFromFields(key, sfields) + fields = removeKeyFromFields(key, fields) + } } noAnchorKey := removeAnchor(key) patternMapNode := pattern.Field(noAnchorKey) diff --git a/pkg/engine/mutate/strategicPreprocessing_test.go b/pkg/engine/mutate/strategicPreprocessing_test.go index b5c1d8ef9e..93ea79100f 100644 --- a/pkg/engine/mutate/strategicPreprocessing_test.go +++ b/pkg/engine/mutate/strategicPreprocessing_test.go @@ -9,11 +9,99 @@ import ( ) func Test_preProcessStrategicMergePatch(t *testing.T) { - rawPolicy := []byte(`{"metadata":{"+(annotations)":{"+(annotation1)":"atest1"},"labels":{"+(label1)":"test1"}},"spec":{"(volumes)":[{"(hostPath)":{"path":"/var/run/docker.sock"}}],"containers":[{"(image)":"*:latest","command":["ls"],"imagePullPolicy":"Always"}]}}`) + rawPolicy := []byte(`{"metadata":{"annotations":{"+(annotation1)":"atest1", "+(annotation2)":"atest2"},"labels":{"+(label1)":"test1"}},"spec":{"(volumes)":[{"(hostPath)":{"path":"/var/run/docker.sock"}}],"containers":[{"(image)":"*:latest","command":["ls"],"imagePullPolicy":"Always"}]}}`) rawResource := []byte(`{"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{"annotation1":"atest2"},"labels":{"label1":"test2","label2":"test2"},"name":"check-root-user"},"spec":{"containers":[{"command":["ll"],"image":"nginx:latest","imagePullPolicy":"Never","name":"nginx"},{"image":"busybox:latest","imagePullPolicy":"Never","name":"busybox"}],"volumes":[{"hostPath":{"path":"/var/run/docker.sock"},"name":"test-volume"}]}}`) - expected := `{"metadata": {"annotations": {"annotation1": "atest1"}, "labels": {"label1": "test1"}},"spec": {"containers": [{"command": ["ls", "ll"], "imagePullPolicy": "Always", "name": "nginx"},{"command": ["ls"], "imagePullPolicy": "Always", "name": "busybox"}]}}` + expected := `{"metadata": {"annotations": {"annotation2":"atest2"}, "labels": {}},"spec": {"containers": [{"command": ["ls", "ll"], "imagePullPolicy": "Always", "name": "nginx"},{"command": ["ls"], "imagePullPolicy": "Always", "name": "busybox"}]}}` + + preProcessedPolicy, err := preProcessStrategicMergePatch(string(rawPolicy), string(rawResource)) + assert.NilError(t, err) + output, err := preProcessedPolicy.String() + assert.NilError(t, err) + re := regexp.MustCompile("\\n") + if !assertnew.Equal(t, strings.ReplaceAll(expected, " ", ""), strings.ReplaceAll(re.ReplaceAllString(output, ""), " ", "")) { + t.FailNow() + } +} + +func Test_preProcessStrategicMergePatch_Deployment(t *testing.T) { + rawPolicy := []byte(`"spec": { + "template": { + "spec": { + "containers": [ + { + "(name)": "*", + "resources": { + "limits": { + "+(memory)": "300Mi", + "+(cpu)": "100" + } + } + } + ] + } + } + }`) + + rawResource := []byte(`{ + "apiVersion": "apps/v1", + "kind": "Deployment", + "metadata": { + "name": "qos-demo", + "labels": { + "test": "qos" + } + }, + "spec": { + "replicas": 1, + "selector": { + "matchLabels": { + "app": "nginx" + } + }, + "template": { + "metadata": { + "labels": { + "app": "nginx" + } + }, + "spec": { + "containers": [ + { + "name": "nginx", + "image": "nginx:latest", + "resources": { + "limits": { + "cpu": "50m" + } + } + } + ] + } + } + } + }`) + + expected := `"spec":{"template":{"spec":{"containers":[{"resources":{"limits":{"memory":"300Mi"}},"name":"nginx"}]}}}` + + preProcessedPolicy, err := preProcessStrategicMergePatch(string(rawPolicy), string(rawResource)) + assert.NilError(t, err) + output, err := preProcessedPolicy.String() + assert.NilError(t, err) + re := regexp.MustCompile("\\n") + if !assertnew.Equal(t, strings.ReplaceAll(expected, " ", ""), strings.ReplaceAll(re.ReplaceAllString(output, ""), " ", "")) { + t.FailNow() + } +} + + +func Test_preProcessStrategicMergePatch_Annotation(t *testing.T) { + rawPolicy := []byte(`{"metadata":{"annotations":{"+(cluster-autoscaler.kubernetes.io/safe-to-evict)":true}},"spec":{"volumes":[{"(hostPath)":{"path":"*"}}]}}`) + + rawResource := []byte(`{"kind":"Pod","apiVersion":"v1","metadata":{"name":"nginx","annotations":{"cluster-autoscaler.kubernetes.io/safe-to-evict":"false"}},"spec":{"containers":[{"name":"nginx","image":"nginx:latest","imagePullPolicy":"Never","volumeMounts":[{"mountPath":"/cache","name":"cache-volume"}]}],"volumes":[{"name":"cache-volume","hostPath":{"path":"/data","type":"Directory"}}]}}`) + + expected := `{"metadata":{"annotations":{}},"spec":{"volumes":[{"name":"cache-volume"}]}}` preProcessedPolicy, err := preProcessStrategicMergePatch(string(rawPolicy), string(rawResource)) assert.NilError(t, err)