From c8edf1ab324a96cec8e719f76120b721a6651199 Mon Sep 17 00:00:00 2001 From: shuting <shuting@nirmata.com> Date: Thu, 2 Feb 2023 22:46:53 +0800 Subject: [PATCH] fix: admission review variables for DELETE operations (#6197) * build trigger from the stored admission request payload Signed-off-by: ShutingZhao <shuting@nirmata.com> * add a kuttl test Signed-off-by: ShutingZhao <shuting@nirmata.com> --------- Signed-off-by: ShutingZhao <shuting@nirmata.com> --- pkg/background/common/resource.go | 13 ++++- pkg/webhooks/resource/utils.go | 4 +- .../existing/basic-delete/01-assert.yaml | 9 +++ .../existing/basic-delete/01-manifests.yaml | 58 +++++++++++++++++++ .../existing/basic-delete/02-delete-cm.yaml | 7 +++ .../existing/basic-delete/03-assert.yaml | 7 +++ .../standard/existing/basic-delete/README.md | 11 ++++ .../existing/basic-delete/cleanup.yaml | 4 ++ 8 files changed, 110 insertions(+), 3 deletions(-) create mode 100644 test/conformance/kuttl/mutate/clusterpolicy/standard/existing/basic-delete/01-assert.yaml create mode 100644 test/conformance/kuttl/mutate/clusterpolicy/standard/existing/basic-delete/01-manifests.yaml create mode 100644 test/conformance/kuttl/mutate/clusterpolicy/standard/existing/basic-delete/02-delete-cm.yaml create mode 100644 test/conformance/kuttl/mutate/clusterpolicy/standard/existing/basic-delete/03-assert.yaml create mode 100644 test/conformance/kuttl/mutate/clusterpolicy/standard/existing/basic-delete/README.md create mode 100644 test/conformance/kuttl/mutate/clusterpolicy/standard/existing/basic-delete/cleanup.yaml diff --git a/pkg/background/common/resource.go b/pkg/background/common/resource.go index 0ead37cb48..1220fa24f1 100644 --- a/pkg/background/common/resource.go +++ b/pkg/background/common/resource.go @@ -8,6 +8,7 @@ import ( "github.com/go-logr/logr" kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1" "github.com/kyverno/kyverno/pkg/clients/dclient" + kubeutils "github.com/kyverno/kyverno/pkg/utils/kube" retryutils "github.com/kyverno/kyverno/pkg/utils/retry" admissionv1 "k8s.io/api/admission/v1" "k8s.io/apimachinery/pkg/api/errors" @@ -51,6 +52,16 @@ func GetResource(client dclient.Interface, urSpec kyvernov1beta1.UpdateRequestSp return nil, err } - log.V(2).Info("fetched trigger resource", "resourceSpec", resourceSpec) + if resource == nil && urSpec.Context.AdmissionRequestInfo.AdmissionRequest != nil { + request := urSpec.Context.AdmissionRequestInfo.AdmissionRequest + raw := request.Object.Raw + if request.Operation == admissionv1.Delete { + raw = request.OldObject.Raw + } + + resource, err = kubeutils.BytesToUnstructured(raw) + } + + log.V(3).Info("fetched trigger resource", "resourceSpec", resourceSpec) return resource, err } diff --git a/pkg/webhooks/resource/utils.go b/pkg/webhooks/resource/utils.go index 5e156d60de..f7ddc15dc6 100644 --- a/pkg/webhooks/resource/utils.go +++ b/pkg/webhooks/resource/utils.go @@ -49,7 +49,7 @@ func applyUpdateRequest( ctx context.Context, request *admissionv1.AdmissionRequest, ruleType kyvernov1beta1.RequestType, - grGenerator updaterequest.Generator, + urGenerator updaterequest.Generator, userRequestInfo kyvernov1beta1.RequestInfo, action admissionv1.Operation, engineResponses ...*engineapi.EngineResponse, @@ -61,7 +61,7 @@ func applyUpdateRequest( for _, er := range engineResponses { ur := transform(admissionRequestInfo, userRequestInfo, er, ruleType) - if err := grGenerator.Apply(ctx, ur, action); err != nil { + if err := urGenerator.Apply(ctx, ur, action); err != nil { failedUpdateRequest = append(failedUpdateRequest, updateRequestResponse{ur: ur, err: err}) } } diff --git a/test/conformance/kuttl/mutate/clusterpolicy/standard/existing/basic-delete/01-assert.yaml b/test/conformance/kuttl/mutate/clusterpolicy/standard/existing/basic-delete/01-assert.yaml new file mode 100644 index 0000000000..0ac1ea7dcc --- /dev/null +++ b/test/conformance/kuttl/mutate/clusterpolicy/standard/existing/basic-delete/01-assert.yaml @@ -0,0 +1,9 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: test-post-mutation-delete-trigger +status: + conditions: + - reason: Succeeded + status: "True" + type: Ready diff --git a/test/conformance/kuttl/mutate/clusterpolicy/standard/existing/basic-delete/01-manifests.yaml b/test/conformance/kuttl/mutate/clusterpolicy/standard/existing/basic-delete/01-manifests.yaml new file mode 100644 index 0000000000..706fb39f53 --- /dev/null +++ b/test/conformance/kuttl/mutate/clusterpolicy/standard/existing/basic-delete/01-manifests.yaml @@ -0,0 +1,58 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: staging-2 + labels: + app-type: corp + annotations: + cloud.platformzero.com/serviceClass: "xl2" +--- +apiVersion: v1 +data: + foo: bar +kind: ConfigMap +metadata: + name: dictionary-2 + namespace: staging-2 +--- +apiVersion: v1 +data: + foo: YmFy +kind: Secret +metadata: + name: test-secret-2 + namespace: staging-2 +type: Opaque +--- +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: test-post-mutation-delete-trigger +spec: + mutateExistingOnPolicyUpdate: false + rules: + - name: mutate-secret-on-configmap-delete + match: + any: + - resources: + kinds: + - ConfigMap + names: + - dictionary-2 + namespaces: + - staging-2 + preconditions: + any: + - key: "{{ request.operation }}" + operator: Equals + value: DELETE + mutate: + targets: + - apiVersion: v1 + kind: Secret + name: test-secret-2 + namespace: "{{ request.object.metadata.namespace }}" + patchStrategicMerge: + metadata: + labels: + foo: "{{ request.object.metadata.name }}" \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/clusterpolicy/standard/existing/basic-delete/02-delete-cm.yaml b/test/conformance/kuttl/mutate/clusterpolicy/standard/existing/basic-delete/02-delete-cm.yaml new file mode 100644 index 0000000000..82f33a28bc --- /dev/null +++ b/test/conformance/kuttl/mutate/clusterpolicy/standard/existing/basic-delete/02-delete-cm.yaml @@ -0,0 +1,7 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +delete: +- apiVersion: v1 + kind: ConfigMap + name: dictionary-2 + namespace: staging-2 \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/clusterpolicy/standard/existing/basic-delete/03-assert.yaml b/test/conformance/kuttl/mutate/clusterpolicy/standard/existing/basic-delete/03-assert.yaml new file mode 100644 index 0000000000..fc44140bd6 --- /dev/null +++ b/test/conformance/kuttl/mutate/clusterpolicy/standard/existing/basic-delete/03-assert.yaml @@ -0,0 +1,7 @@ +apiVersion: v1 +kind: Secret +metadata: + name: test-secret-2 + namespace: staging-2 + labels: + foo: dictionary-2 \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/clusterpolicy/standard/existing/basic-delete/README.md b/test/conformance/kuttl/mutate/clusterpolicy/standard/existing/basic-delete/README.md new file mode 100644 index 0000000000..9abd9c3007 --- /dev/null +++ b/test/conformance/kuttl/mutate/clusterpolicy/standard/existing/basic-delete/README.md @@ -0,0 +1,11 @@ +## Description + +This is a basic test for the mutate existing capability which ensures that specifically deleting a triggering resource, via a precondition, results in the correct mutation of a different resource. + +## Expected Behavior + +When the `dictionary-2` ConfigMap is deleted, this should result in the mutation of the Secret named `test-secret-2` within the same Namespace to add the label `foo` with value set to the name or `dictionary-2` in this case. If the Secret is mutated so that the label `foo: dictionary-2` is present, the test passes. If not, the test fails. + +## Reference Issue(s) + +N/A \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/clusterpolicy/standard/existing/basic-delete/cleanup.yaml b/test/conformance/kuttl/mutate/clusterpolicy/standard/existing/basic-delete/cleanup.yaml new file mode 100644 index 0000000000..15c3c49051 --- /dev/null +++ b/test/conformance/kuttl/mutate/clusterpolicy/standard/existing/basic-delete/cleanup.yaml @@ -0,0 +1,4 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: kubectl delete -f 01-manifests.yaml --force --wait=true --ignore-not-found=true \ No newline at end of file