1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2024-12-14 11:57:48 +00:00

fix: preconditions in mutate existing rules (#7183)

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
This commit is contained in:
Charles-Edouard Brétéché 2023-05-12 17:43:36 +02:00 committed by GitHub
parent b3a56176e5
commit 073309a8ae
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 135 additions and 6 deletions

View file

@ -201,7 +201,7 @@ func (h *handlers) executePolicy(ctx context.Context, logger logr.Logger, policy
// check conditions
if spec.Conditions != nil {
enginectx.Reset()
if err := enginectx.AddTargetResource(resource.Object); err != nil {
if err := enginectx.SetTargetResource(resource.Object); err != nil {
debug.Error(err, "failed to add resource in context")
errs = append(errs, err)
continue

View file

@ -51,8 +51,8 @@ type Interface interface {
// AddOldResource merges resource json under request.oldObject
AddOldResource(data map[string]interface{}) error
// AddTargetResource merges resource json under target
AddTargetResource(data map[string]interface{}) error
// SetTargetResource merges resource json under target
SetTargetResource(data map[string]interface{}) error
// AddOperation merges operation under request.operation
AddOperation(data string) error
@ -190,7 +190,11 @@ func (ctx *context) AddOldResource(data map[string]interface{}) error {
}
// AddTargetResource adds data at path: target
func (ctx *context) AddTargetResource(data map[string]interface{}) error {
func (ctx *context) SetTargetResource(data map[string]interface{}) error {
if err := addToContext(ctx, nil, "target"); err != nil {
logger.Error(err, "unable to replace target resource")
return err
}
return addToContext(ctx, data, "target")
}

View file

@ -47,7 +47,7 @@ func (h mutateExistingHandler) Process(
continue
}
policyContext := policyContext.Copy()
if err := policyContext.JSONContext().AddTargetResource(target.unstructured.Object); err != nil {
if err := policyContext.JSONContext().SetTargetResource(target.unstructured.Object); err != nil {
logger.Error(err, "failed to add target resource to the context")
continue
}

View file

@ -64,7 +64,7 @@ func Mutate(rule *kyvernov1.Rule, ctx context.Interface, resource unstructured.U
return NewErrorResponse("failed to unmarshal patched resource", err)
}
if rule.IsMutateExisting() {
if err := ctx.AddTargetResource(resource.Object); err != nil {
if err := ctx.SetTargetResource(resource.Object); err != nil {
return NewErrorResponse("failed to update patched resource in the JSON context", err)
}
} else {

View file

@ -0,0 +1,4 @@
apiVersion: kuttl.dev/v1beta1
kind: TestStep
apply:
- resources.yaml

View file

@ -0,0 +1,6 @@
apiVersion: kuttl.dev/v1beta1
kind: TestStep
apply:
- policy.yaml
assert:
- policy-ready.yaml

View file

@ -0,0 +1,4 @@
apiVersion: kuttl.dev/v1beta1
kind: TestStep
assert:
- resources-assert.yaml

View file

@ -0,0 +1,4 @@
apiVersion: kuttl.dev/v1beta1
kind: TestStep
error:
- resources-error.yaml

View file

@ -0,0 +1,11 @@
## Description
This test creates pods and a policy to add a label to existing pods with per target preconditions based on the target annotations.
## Expected Behavior
Only the pod with `policy.lan/value: foo` annotation has the label `policy-applied: 'true'` added.
## Reference Issue(s)
https://github.com/kyverno/kyverno/issues/7174

View file

@ -0,0 +1,9 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: test
status:
conditions:
- reason: Succeeded
status: "True"
type: Ready

View file

@ -0,0 +1,30 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: test
spec:
mutateExistingOnPolicyUpdate: true
rules:
- name: test
match:
any:
- resources:
kinds:
- Namespace
names:
- default
mutate:
targets:
- kind: Pod
apiVersion: '*'
name: '*'
namespace: "{{ request.object.metadata.name }}"
preconditions:
all:
- key: "{{ target.metadata.annotations.\"policy.lan/value\" }}"
operator: Equals
value: foo
patchStrategicMerge:
metadata:
labels:
policy-applied: 'true'

View file

@ -0,0 +1,9 @@
apiVersion: v1
kind: Pod
metadata:
name: nginx-a
namespace: default
labels:
policy-applied: 'true'
annotations:
policy.lan/value: foo

View file

@ -0,0 +1,15 @@
apiVersion: v1
kind: Pod
metadata:
name: nginx-b
namespace: default
labels:
policy-applied: 'true'
---
apiVersion: v1
kind: Pod
metadata:
name: nginx-c
namespace: default
labels:
policy-applied: 'true'

View file

@ -0,0 +1,33 @@
apiVersion: v1
kind: Pod
metadata:
name: nginx-a
namespace: default
annotations:
policy.lan/value: foo
spec:
containers:
- name: nginx
image: nginx
---
apiVersion: v1
kind: Pod
metadata:
name: nginx-b
namespace: default
spec:
containers:
- name: nginx
image: nginx
---
apiVersion: v1
kind: Pod
metadata:
name: nginx-c
namespace: default
annotations:
policy.lan/value: bar
spec:
containers:
- name: nginx
image: nginx