mirror of
https://github.com/kyverno/kyverno.git
synced 2024-12-14 11:57:48 +00:00
fix: deepcopy patched resource in foreach mutate (#10252)
* fix: deepcopy patched resource to avoid indirect reversal of its elements Signed-off-by: Vishal Choudhary <vishal.choudhary@nirmata.com> * fix: copy elements while reversing Signed-off-by: Vishal Choudhary <vishal.choudhary@nirmata.com> * fix: copy resources inside foreach Signed-off-by: Vishal Choudhary <vishal.choudhary@nirmata.com> * add test Signed-off-by: Jim Bugwadia <jim@nirmata.com> * add test Signed-off-by: Jim Bugwadia <jim@nirmata.com> --------- Signed-off-by: Vishal Choudhary <vishal.choudhary@nirmata.com> Signed-off-by: Jim Bugwadia <jim@nirmata.com> Co-authored-by: Jim Bugwadia <jim@nirmata.com>
This commit is contained in:
parent
1302004bc2
commit
3af0e461f0
12 changed files with 154 additions and 5 deletions
|
@ -66,6 +66,7 @@ func (f *forEachMutator) mutateElements(ctx context.Context, foreach kyvernov1.F
|
|||
defer f.policyContext.JSONContext().Restore()
|
||||
|
||||
patchedResource := f.resource
|
||||
patchedResource.unstructured = *f.resource.unstructured.DeepCopy()
|
||||
|
||||
reverse := false
|
||||
// if it's a patch strategic merge, reverse by default
|
||||
|
@ -76,7 +77,7 @@ func (f *forEachMutator) mutateElements(ctx context.Context, foreach kyvernov1.F
|
|||
reverse = *foreach.Order == kyvernov1.Descending
|
||||
}
|
||||
if reverse {
|
||||
engineutils.InvertedElement(elements)
|
||||
elements = engineutils.InvertElements(elements)
|
||||
}
|
||||
|
||||
for index, element := range elements {
|
||||
|
|
|
@ -23,11 +23,14 @@ func EvaluateList(jmesPath string, ctx enginecontext.EvalInterface) ([]interface
|
|||
return l, nil
|
||||
}
|
||||
|
||||
// InvertedElement inverted the order of element for patchStrategicMerge policies as kustomize patch revering the order of patch resources.
|
||||
func InvertedElement(elements []interface{}) {
|
||||
for i, j := 0, len(elements)-1; i < j; i, j = i+1, j-1 {
|
||||
elements[i], elements[j] = elements[j], elements[i]
|
||||
// InvertElements inverts the order of elements for patchStrategicMerge policies
|
||||
// as kustomize patch reverses the order of patch resources.
|
||||
func InvertElements(elements []interface{}) []interface{} {
|
||||
elementsCopy := make([]interface{}, len(elements))
|
||||
for i := range elements {
|
||||
elementsCopy[i] = elements[len(elements)-i-1]
|
||||
}
|
||||
return elementsCopy
|
||||
}
|
||||
|
||||
func AddElementToContext(ctx engineapi.PolicyContext, element interface{}, index, nesting int, elementScope *bool) error {
|
||||
|
|
16
pkg/engine/utils/foreach_test.go
Normal file
16
pkg/engine/utils/foreach_test.go
Normal file
|
@ -0,0 +1,16 @@
|
|||
package utils
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func Test_InvertElements(t *testing.T) {
|
||||
elems := []interface{}{"a", "b", "c"}
|
||||
elemsInverted := InvertElements(elems)
|
||||
|
||||
assert.Equal(t, "a", elemsInverted[2])
|
||||
assert.Equal(t, "b", elemsInverted[1])
|
||||
assert.Equal(t, "c", elemsInverted[0])
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
## Description
|
||||
|
||||
This test creates two `Pod`s: trigger and target. The policy updates the image of the third container in the target pod whemn the trigger pod is created.
|
||||
## Expected Behavior
|
||||
|
||||
When the trigger pod is applied the, image in container3 of target pod changes
|
|
@ -0,0 +1,35 @@
|
|||
apiVersion: chainsaw.kyverno.io/v1alpha1
|
||||
kind: Test
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: descending-patchjson
|
||||
spec:
|
||||
steps:
|
||||
- name: step-01
|
||||
try:
|
||||
- apply:
|
||||
file: policy.yaml
|
||||
- name: step-01-assert
|
||||
try:
|
||||
- assert:
|
||||
file: policy-assert.yaml
|
||||
- name: step-02
|
||||
try:
|
||||
- apply:
|
||||
file: target-pod.yaml
|
||||
- name: step-02-assert
|
||||
try:
|
||||
- assert:
|
||||
file: target-pod-assert.yaml
|
||||
- name: step-03
|
||||
try:
|
||||
- apply:
|
||||
file: trigger-pod.yaml
|
||||
- name: step-03-assert
|
||||
try:
|
||||
- assert:
|
||||
file: trigger-pod-assert.yaml
|
||||
- name: step-04
|
||||
try:
|
||||
- assert:
|
||||
file: target-pod-updated.yaml
|
|
@ -0,0 +1,5 @@
|
|||
apiVersion: kyverno.io/v1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: descending-jsonpatch
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
apiVersion: kyverno.io/v1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: descending-jsonpatch
|
||||
spec:
|
||||
background: false
|
||||
schemaValidation: false
|
||||
rules:
|
||||
- name: remove-elements
|
||||
match:
|
||||
all:
|
||||
- resources:
|
||||
kinds:
|
||||
- Pod
|
||||
names:
|
||||
- trigger-pod
|
||||
mutate:
|
||||
targets:
|
||||
- apiVersion: v1
|
||||
kind: Pod
|
||||
name: target-pod
|
||||
namespace: default
|
||||
foreach:
|
||||
- list: "target.spec.containers"
|
||||
order: Descending
|
||||
preconditions:
|
||||
all:
|
||||
- key: "{{ element.name }}"
|
||||
operator: Equals
|
||||
value: container3
|
||||
patchesJson6902: |-
|
||||
- op: replace
|
||||
path: /spec/containers/{{elementIndex}}/image
|
||||
value: ghcr.io/kyverno/test-verify-images:signed
|
|
@ -0,0 +1,6 @@
|
|||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: target-pod
|
||||
namespace: default
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: target-pod
|
||||
namespace: default
|
||||
spec:
|
||||
containers:
|
||||
- name: container1
|
||||
image: busybox:latest
|
||||
- name: container2
|
||||
image: busybox:latest
|
||||
- name: container3
|
||||
image: ghcr.io/kyverno/test-verify-images:signed
|
|
@ -0,0 +1,14 @@
|
|||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: target-pod
|
||||
namespace: default
|
||||
spec:
|
||||
containers:
|
||||
- name: container1
|
||||
image: busybox:latest
|
||||
- name: container2
|
||||
image: busybox:latest
|
||||
- name: container3
|
||||
image: busybox:latest
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: trigger-pod
|
||||
namespace: default
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: trigger-pod
|
||||
namespace: default
|
||||
spec:
|
||||
containers:
|
||||
- name: container1
|
||||
image: busybox:latest
|
||||
|
Loading…
Reference in a new issue