From bbb1d6103cb5350d94925e289dcc10778006976d Mon Sep 17 00:00:00 2001 From: Khaled Emara Date: Mon, 12 Aug 2024 17:59:27 +0300 Subject: [PATCH 1/5] feat(mutate): don't eagerly process img-ver (#10703) * feat(mutate): don't eagerly process img-ver Signed-off-by: Khaled Emara * test(mutate): add mutate with img-ver test Signed-off-by: Khaled Emara --------- Signed-off-by: Khaled Emara Co-authored-by: Vishal Choudhary Co-authored-by: shuting --- pkg/webhooks/resource/handlers.go | 54 +++++++++---------- .../standard/with-mutation/README.md | 11 ++++ .../standard/with-mutation/chainsaw-test.yaml | 27 ++++++++++ .../with-mutation/img-cpol-assert.yaml | 9 ++++ .../standard/with-mutation/img-cpol.yaml | 30 +++++++++++ .../with-mutation/mut-cpol-assert.yaml | 9 ++++ .../standard/with-mutation/mut-cpol.yaml | 22 ++++++++ .../standard/with-mutation/ns.yaml | 4 ++ .../with-mutation/test-pod-assert.yaml | 5 ++ .../standard/with-mutation/test-pod.yaml | 9 ++++ 10 files changed, 153 insertions(+), 27 deletions(-) create mode 100644 test/conformance/chainsaw/verifyImages/clusterpolicy/standard/with-mutation/README.md create mode 100755 test/conformance/chainsaw/verifyImages/clusterpolicy/standard/with-mutation/chainsaw-test.yaml create mode 100755 test/conformance/chainsaw/verifyImages/clusterpolicy/standard/with-mutation/img-cpol-assert.yaml create mode 100755 test/conformance/chainsaw/verifyImages/clusterpolicy/standard/with-mutation/img-cpol.yaml create mode 100755 test/conformance/chainsaw/verifyImages/clusterpolicy/standard/with-mutation/mut-cpol-assert.yaml create mode 100755 test/conformance/chainsaw/verifyImages/clusterpolicy/standard/with-mutation/mut-cpol.yaml create mode 100755 test/conformance/chainsaw/verifyImages/clusterpolicy/standard/with-mutation/ns.yaml create mode 100755 test/conformance/chainsaw/verifyImages/clusterpolicy/standard/with-mutation/test-pod-assert.yaml create mode 100755 test/conformance/chainsaw/verifyImages/clusterpolicy/standard/with-mutation/test-pod.yaml diff --git a/pkg/webhooks/resource/handlers.go b/pkg/webhooks/resource/handlers.go index b41612f6f048..827be222fead 100644 --- a/pkg/webhooks/resource/handlers.go +++ b/pkg/webhooks/resource/handlers.go @@ -198,38 +198,38 @@ func (h *resourceHandlers) Mutate(ctx context.Context, logger logr.Logger, reque return admissionutils.Response(request.UID, err) } mh := mutation.NewMutationHandler(logger, h.engine, h.eventGen, h.nsLister, h.metricsConfig) - mutatePatches, mutateWarnings, err := mh.HandleMutation(ctx, request.AdmissionRequest, mutatePolicies, policyContext, startTime) + patches, warnings, err := mh.HandleMutation(ctx, request.AdmissionRequest, mutatePolicies, policyContext, startTime) if err != nil { logger.Error(err, "mutation failed") return admissionutils.Response(request.UID, err) } - newRequest := patchRequest(mutatePatches, request.AdmissionRequest, logger) - // rebuild context to process images updated via mutate policies - policyContext, err = h.pcBuilder.Build(newRequest, request.Roles, request.ClusterRoles, request.GroupVersionKind) - if err != nil { - logger.Error(err, "failed to build policy context") - return admissionutils.Response(request.UID, err) - } - ivh := imageverification.NewImageVerificationHandler( - logger, - h.kyvernoClient, - h.engine, - h.eventGen, - h.admissionReports, - h.configuration, - h.nsLister, - h.reportsBreaker, - ) - imagePatches, imageVerifyWarnings, err := ivh.Handle(ctx, newRequest, verifyImagesPolicies, policyContext) - if err != nil { - logger.Error(err, "image verification failed") - return admissionutils.Response(request.UID, err) + if len(verifyImagesPolicies) != 0 { + newRequest := patchRequest(patches, request.AdmissionRequest, logger) + // rebuild context to process images updated via mutate policies + policyContext, err = h.pcBuilder.Build(newRequest, request.Roles, request.ClusterRoles, request.GroupVersionKind) + if err != nil { + logger.Error(err, "failed to build policy context") + return admissionutils.Response(request.UID, err) + } + ivh := imageverification.NewImageVerificationHandler( + logger, + h.kyvernoClient, + h.engine, + h.eventGen, + h.admissionReports, + h.configuration, + h.nsLister, + h.reportsBreaker, + ) + imagePatches, imageVerifyWarnings, err := ivh.Handle(ctx, newRequest, verifyImagesPolicies, policyContext) + if err != nil { + logger.Error(err, "image verification failed") + return admissionutils.Response(request.UID, err) + } + patches = jsonutils.JoinPatches(patches, imagePatches) + warnings = append(warnings, imageVerifyWarnings...) } - patch := jsonutils.JoinPatches(mutatePatches, imagePatches) - var warnings []string - warnings = append(warnings, mutateWarnings...) - warnings = append(warnings, imageVerifyWarnings...) - return admissionutils.MutationResponse(request.UID, patch, warnings...) + return admissionutils.MutationResponse(request.UID, patches, warnings...) } func (h *resourceHandlers) retrieveAndCategorizePolicies( diff --git a/test/conformance/chainsaw/verifyImages/clusterpolicy/standard/with-mutation/README.md b/test/conformance/chainsaw/verifyImages/clusterpolicy/standard/with-mutation/README.md new file mode 100644 index 000000000000..e7e7aed1ee16 --- /dev/null +++ b/test/conformance/chainsaw/verifyImages/clusterpolicy/standard/with-mutation/README.md @@ -0,0 +1,11 @@ +## Description + +This test performs a simple verification of an image using a public key specified directly in the policy as well as mutate the image before the verification. + +## Expected Behavior + +Pod creation should pass as the mutated image has been signed by the public key specified in the policy. + +## Reference Issue(s) + +N/A \ No newline at end of file diff --git a/test/conformance/chainsaw/verifyImages/clusterpolicy/standard/with-mutation/chainsaw-test.yaml b/test/conformance/chainsaw/verifyImages/clusterpolicy/standard/with-mutation/chainsaw-test.yaml new file mode 100755 index 000000000000..3f9b2904e739 --- /dev/null +++ b/test/conformance/chainsaw/verifyImages/clusterpolicy/standard/with-mutation/chainsaw-test.yaml @@ -0,0 +1,27 @@ +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + creationTimestamp: null + name: with-mutation +spec: + timeouts: + delete: 2m + steps: + - name: step-01 + try: + - apply: + file: ns.yaml + - apply: + file: mut-cpol.yaml + - assert: + file: mut-cpol-assert.yaml + - apply: + file: img-cpol.yaml + - assert: + file: img-cpol-assert.yaml + - name: step-02 + try: + - apply: + file: test-pod.yaml + - assert: + file: test-pod-assert.yaml diff --git a/test/conformance/chainsaw/verifyImages/clusterpolicy/standard/with-mutation/img-cpol-assert.yaml b/test/conformance/chainsaw/verifyImages/clusterpolicy/standard/with-mutation/img-cpol-assert.yaml new file mode 100755 index 000000000000..a1e604427d78 --- /dev/null +++ b/test/conformance/chainsaw/verifyImages/clusterpolicy/standard/with-mutation/img-cpol-assert.yaml @@ -0,0 +1,9 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: with-mutation-img +status: + conditions: + - reason: Succeeded + status: "True" + type: Ready diff --git a/test/conformance/chainsaw/verifyImages/clusterpolicy/standard/with-mutation/img-cpol.yaml b/test/conformance/chainsaw/verifyImages/clusterpolicy/standard/with-mutation/img-cpol.yaml new file mode 100755 index 000000000000..f4822b3bbb37 --- /dev/null +++ b/test/conformance/chainsaw/verifyImages/clusterpolicy/standard/with-mutation/img-cpol.yaml @@ -0,0 +1,30 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: with-mutation-img +spec: + background: false + failurePolicy: Fail + rules: + - match: + any: + - resources: + kinds: + - Pod + name: with-mutation-rule + verifyImages: + - attestors: + - entries: + - keys: + publicKeys: |- + -----BEGIN PUBLIC KEY----- + MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8nXRh950IZbRj8Ra/N9sbqOPZrfM + 5/KAQN0/KjHcorm/J5yctVd7iEcnessRQjU917hmKO6JWVGHpDguIyakZA== + -----END PUBLIC KEY----- + rekor: + ignoreTlog: true + url: https://rekor.sigstore.dev + imageReferences: + - ghcr.io/kyverno/test-verify-image:* + validationFailureAction: Enforce + webhookTimeoutSeconds: 30 diff --git a/test/conformance/chainsaw/verifyImages/clusterpolicy/standard/with-mutation/mut-cpol-assert.yaml b/test/conformance/chainsaw/verifyImages/clusterpolicy/standard/with-mutation/mut-cpol-assert.yaml new file mode 100755 index 000000000000..8498e5fe2eda --- /dev/null +++ b/test/conformance/chainsaw/verifyImages/clusterpolicy/standard/with-mutation/mut-cpol-assert.yaml @@ -0,0 +1,9 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: with-mutation-mut +status: + conditions: + - reason: Succeeded + status: "True" + type: Ready diff --git a/test/conformance/chainsaw/verifyImages/clusterpolicy/standard/with-mutation/mut-cpol.yaml b/test/conformance/chainsaw/verifyImages/clusterpolicy/standard/with-mutation/mut-cpol.yaml new file mode 100755 index 000000000000..676f7a073157 --- /dev/null +++ b/test/conformance/chainsaw/verifyImages/clusterpolicy/standard/with-mutation/mut-cpol.yaml @@ -0,0 +1,22 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: with-mutation-mut +spec: + background: false + failurePolicy: Fail + rules: + - match: + any: + - resources: + kinds: + - Pod + name: with-mutation-rule + mutate: + patchStrategicMerge: + spec: + containers: + - (name): test-secret + image: "ghcr.io/kyverno/test-verify-image:signed" + validationFailureAction: Enforce + webhookTimeoutSeconds: 30 diff --git a/test/conformance/chainsaw/verifyImages/clusterpolicy/standard/with-mutation/ns.yaml b/test/conformance/chainsaw/verifyImages/clusterpolicy/standard/with-mutation/ns.yaml new file mode 100755 index 000000000000..54c1efb587b1 --- /dev/null +++ b/test/conformance/chainsaw/verifyImages/clusterpolicy/standard/with-mutation/ns.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: test-verify-images diff --git a/test/conformance/chainsaw/verifyImages/clusterpolicy/standard/with-mutation/test-pod-assert.yaml b/test/conformance/chainsaw/verifyImages/clusterpolicy/standard/with-mutation/test-pod-assert.yaml new file mode 100755 index 000000000000..1926808612a0 --- /dev/null +++ b/test/conformance/chainsaw/verifyImages/clusterpolicy/standard/with-mutation/test-pod-assert.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +kind: Pod +metadata: + name: test-with-mutation + namespace: test-verify-images diff --git a/test/conformance/chainsaw/verifyImages/clusterpolicy/standard/with-mutation/test-pod.yaml b/test/conformance/chainsaw/verifyImages/clusterpolicy/standard/with-mutation/test-pod.yaml new file mode 100755 index 000000000000..5922e5a0a3cf --- /dev/null +++ b/test/conformance/chainsaw/verifyImages/clusterpolicy/standard/with-mutation/test-pod.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Pod +metadata: + name: test-with-mutation + namespace: test-verify-images +spec: + containers: + - image: ghcr.io/kyverno/test-verify-image:unsigned + name: test-secret From b8a69a7eacc5da6ba5ce1c5f9e3538b3fa502a44 Mon Sep 17 00:00:00 2001 From: Khaled Emara Date: Mon, 12 Aug 2024 18:57:16 +0300 Subject: [PATCH 2/5] feat(audit): enable audit logs for kind (#10822) Signed-off-by: Khaled Emara --- scripts/config/kind/audit-config.yaml | 29 +++++++++++++++++++++++++++ scripts/config/kind/audit-policy.yaml | 7 +++++++ 2 files changed, 36 insertions(+) create mode 100644 scripts/config/kind/audit-config.yaml create mode 100644 scripts/config/kind/audit-policy.yaml diff --git a/scripts/config/kind/audit-config.yaml b/scripts/config/kind/audit-config.yaml new file mode 100644 index 000000000000..5b22c9b10412 --- /dev/null +++ b/scripts/config/kind/audit-config.yaml @@ -0,0 +1,29 @@ +kind: Cluster +apiVersion: kind.x-k8s.io/v1alpha4 +nodes: +- role: control-plane + kubeadmConfigPatches: + - | + kind: ClusterConfiguration + apiServer: + # enable auditing flags on the API server + extraArgs: + audit-log-path: /var/log/kubernetes/kube-apiserver-audit.log + audit-policy-file: /etc/kubernetes/policies/audit-policy.yaml + # mount new files / directories on the control plane + extraVolumes: + - name: audit-policies + hostPath: /etc/kubernetes/policies + mountPath: /etc/kubernetes/policies + readOnly: true + pathType: "DirectoryOrCreate" + - name: "audit-logs" + hostPath: "/var/log/kubernetes" + mountPath: "/var/log/kubernetes" + readOnly: false + pathType: DirectoryOrCreate + # mount the local file on the control plane + extraMounts: + - hostPath: ./scripts/config/kind/audit-policy.yaml + containerPath: /etc/kubernetes/policies/audit-policy.yaml + readOnly: true diff --git a/scripts/config/kind/audit-policy.yaml b/scripts/config/kind/audit-policy.yaml new file mode 100644 index 000000000000..0aa9818479d5 --- /dev/null +++ b/scripts/config/kind/audit-policy.yaml @@ -0,0 +1,7 @@ +apiVersion: audit.k8s.io/v1 +kind: Policy +rules: +- level: RequestResponse + resources: + - group: "kyverno.io" + resources: ["policies", "clusterpolicies"] From 3a69702b490cb7afe4cc026b34369932bf808ce7 Mon Sep 17 00:00:00 2001 From: Mariam Fahmy Date: Tue, 13 Aug 2024 12:25:29 +0300 Subject: [PATCH 3/5] fix: check permissions for validate.cel subrules only (#10829) Signed-off-by: Mariam Fahmy Co-authored-by: Jim Bugwadia --- pkg/validation/policy/actions.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/validation/policy/actions.go b/pkg/validation/policy/actions.go index acbf33f2952a..1cbbe3b2ae35 100644 --- a/pkg/validation/policy/actions.go +++ b/pkg/validation/policy/actions.go @@ -55,7 +55,7 @@ func validateActions(idx int, rule *kyvernov1.Rule, client dclient.Interface, mo } // In case generateValidatingAdmissionPolicy flag is set to true, check the required permissions. - if toggle.FromContext(context.TODO()).GenerateValidatingAdmissionPolicy() { + if rule.HasValidateCEL() && toggle.FromContext(context.TODO()).GenerateValidatingAdmissionPolicy() { authCheck := authChecker.NewSelfChecker(client.GetKubeClient().AuthorizationV1().SelfSubjectAccessReviews()) // check if the controller has the required permissions to generate validating admission policies. if !validatingadmissionpolicy.HasValidatingAdmissionPolicyPermission(authCheck) { From 25b7142ee0ae7a6656a02a3e756dc06e48396bad Mon Sep 17 00:00:00 2001 From: Mariam Fahmy Date: Tue, 13 Aug 2024 14:55:22 +0300 Subject: [PATCH 4/5] feat: generate VAPs from exceptions (#10771) Signed-off-by: Mariam Fahmy --- .../controller.go | 20 +- pkg/validatingadmissionpolicy/builder.go | 18 ++ .../kyvernopolicy_checker.go | 50 +++- .../kyvernopolicy_checker_test.go | 232 +++++++++++++++++- pkg/validation/policy/validate.go | 4 +- .../chainsaw-test.yaml | 23 ++ .../exception.yaml | 18 ++ .../policy-assert.yaml | 2 +- .../policy.yaml | 8 +- .../validatingadmissionpolicy.yaml | 41 ++++ .../validatingadmissionpolicybinding.yaml | 13 + .../cpol-with-an-exception/chainsaw-test.yaml | 23 ++ .../cpol-with-an-exception}/exception.yaml | 7 +- .../cpol-with-an-exception/policy-assert.yaml | 10 + .../cpol-with-an-exception/policy.yaml | 31 +++ .../validatingadmissionpolicy.yaml | 49 ++++ .../validatingadmissionpolicybinding.yaml | 13 + .../chainsaw-test.yaml | 23 ++ .../cpol-with-two-exceptions/exception.yaml | 39 +++ .../policy-assert.yaml | 10 + .../cpol-with-two-exceptions/policy.yaml | 31 +++ .../validatingadmissionpolicy.yaml | 50 ++++ .../validatingadmissionpolicybinding.yaml | 13 + .../chainsaw-test.yaml | 6 +- .../exception.yaml | 24 ++ .../policy-assert.yaml | 10 + .../policy.yaml | 31 +++ .../validatingadmissionpolicy.yaml | 4 +- .../validatingadmissionpolicybinding.yaml | 2 +- .../chainsaw-test.yaml | 23 ++ .../exception.yaml | 23 ++ .../policy-assert.yaml | 10 + .../policy.yaml | 22 ++ .../validatingadmissionpolicy.yaml | 7 + .../validatingadmissionpolicybinding.yaml | 7 + .../chainsaw-test.yaml | 23 ++ .../exception.yaml | 20 ++ .../policy-assert.yaml | 10 + .../policy.yaml | 22 ++ .../validatingadmissionpolicy.yaml | 7 + .../validatingadmissionpolicybinding.yaml | 7 + .../chainsaw-test.yaml | 23 ++ .../exception.yaml | 20 ++ .../policy-assert.yaml | 10 + .../policy.yaml | 22 ++ .../validatingadmissionpolicy.yaml | 7 + .../validatingadmissionpolicybinding.yaml | 7 + 47 files changed, 1044 insertions(+), 31 deletions(-) create mode 100755 test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-an-exception-excluding-namespaces/chainsaw-test.yaml create mode 100644 test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-an-exception-excluding-namespaces/exception.yaml rename test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/{skip-generate/cpol-with-exceptions => generate/cpol-with-an-exception-excluding-namespaces}/policy-assert.yaml (81%) rename test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/{skip-generate/cpol-with-exceptions => generate/cpol-with-an-exception-excluding-namespaces}/policy.yaml (80%) create mode 100644 test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-an-exception-excluding-namespaces/validatingadmissionpolicy.yaml create mode 100644 test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-an-exception-excluding-namespaces/validatingadmissionpolicybinding.yaml create mode 100755 test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-an-exception/chainsaw-test.yaml rename test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/{skip-generate/cpol-with-exceptions => generate/cpol-with-an-exception}/exception.yaml (65%) create mode 100644 test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-an-exception/policy-assert.yaml create mode 100644 test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-an-exception/policy.yaml create mode 100644 test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-an-exception/validatingadmissionpolicy.yaml create mode 100644 test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-an-exception/validatingadmissionpolicybinding.yaml create mode 100755 test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-two-exceptions/chainsaw-test.yaml create mode 100644 test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-two-exceptions/exception.yaml create mode 100644 test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-two-exceptions/policy-assert.yaml create mode 100644 test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-two-exceptions/policy.yaml create mode 100644 test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-two-exceptions/validatingadmissionpolicy.yaml create mode 100644 test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-two-exceptions/validatingadmissionpolicybinding.yaml rename test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/{cpol-with-exceptions => cpol-with-exception-and-conditions}/chainsaw-test.yaml (82%) create mode 100644 test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-conditions/exception.yaml create mode 100644 test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-conditions/policy-assert.yaml create mode 100644 test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-conditions/policy.yaml rename test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/{cpol-with-exceptions => cpol-with-exception-and-conditions}/validatingadmissionpolicy.yaml (78%) rename test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/{cpol-with-exceptions => cpol-with-exception-and-conditions}/validatingadmissionpolicybinding.yaml (80%) create mode 100755 test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-namespace-selector/chainsaw-test.yaml create mode 100644 test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-namespace-selector/exception.yaml create mode 100644 test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-namespace-selector/policy-assert.yaml create mode 100644 test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-namespace-selector/policy.yaml create mode 100644 test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-namespace-selector/validatingadmissionpolicy.yaml create mode 100644 test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-namespace-selector/validatingadmissionpolicybinding.yaml create mode 100755 test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-object-selector/chainsaw-test.yaml create mode 100644 test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-object-selector/exception.yaml create mode 100644 test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-object-selector/policy-assert.yaml create mode 100644 test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-object-selector/policy.yaml create mode 100644 test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-object-selector/validatingadmissionpolicy.yaml create mode 100644 test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-object-selector/validatingadmissionpolicybinding.yaml create mode 100755 test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-in-specific-namespace/chainsaw-test.yaml create mode 100644 test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-in-specific-namespace/exception.yaml create mode 100644 test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-in-specific-namespace/policy-assert.yaml create mode 100644 test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-in-specific-namespace/policy.yaml create mode 100644 test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-in-specific-namespace/validatingadmissionpolicy.yaml create mode 100644 test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-in-specific-namespace/validatingadmissionpolicybinding.yaml diff --git a/pkg/controllers/validatingadmissionpolicy-generate/controller.go b/pkg/controllers/validatingadmissionpolicy-generate/controller.go index d330c4a997f9..20f815d22356 100644 --- a/pkg/controllers/validatingadmissionpolicy-generate/controller.go +++ b/pkg/controllers/validatingadmissionpolicy-generate/controller.go @@ -266,18 +266,19 @@ func (c *controller) getValidatingAdmissionPolicyBinding(name string) (*admissio return vapbinding, nil } -// hasExceptions checks if there is an exception that match both the policy and the rule. -func (c *controller) hasExceptions(policyName, rule string) (bool, error) { +// getExceptions get exceptions that match both the policy and the rule if exists. +func (c *controller) getExceptions(policyName, rule string) ([]kyvernov2.PolicyException, error) { + var exceptions []kyvernov2.PolicyException polexs, err := c.polexLister.List(labels.Everything()) if err != nil { - return false, err + return nil, err } for _, polex := range polexs { if polex.Contains(policyName, rule) { - return true, nil + exceptions = append(exceptions, *polex) } } - return false, nil + return exceptions, nil } func constructVapBindingName(vapName string) string { @@ -319,11 +320,12 @@ func (c *controller) reconcile(ctx context.Context, logger logr.Logger, key, nam observedVAP, vapErr := c.getValidatingAdmissionPolicy(vapName) observedVAPbinding, vapBindingErr := c.getValidatingAdmissionPolicyBinding(vapBindingName) - hasExceptions, err := c.hasExceptions(name, spec.Rules[0].Name) + exceptions, err := c.getExceptions(name, spec.Rules[0].Name) if err != nil { return err } - if ok, msg := validatingadmissionpolicy.CanGenerateVAP(spec); !ok || hasExceptions { + + if ok, msg := validatingadmissionpolicy.CanGenerateVAP(spec, exceptions); !ok { // delete the ValidatingAdmissionPolicy if exist if vapErr == nil { err = c.client.AdmissionregistrationV1alpha1().ValidatingAdmissionPolicies().Delete(ctx, vapName, metav1.DeleteOptions{}) @@ -371,7 +373,7 @@ func (c *controller) reconcile(ctx context.Context, logger logr.Logger, key, nam } if observedVAP.ResourceVersion == "" { - err := validatingadmissionpolicy.BuildValidatingAdmissionPolicy(c.discoveryClient, observedVAP, policy) + err := validatingadmissionpolicy.BuildValidatingAdmissionPolicy(c.discoveryClient, observedVAP, policy, exceptions) if err != nil { c.updateClusterPolicyStatus(ctx, *policy, false, err.Error()) return err @@ -387,7 +389,7 @@ func (c *controller) reconcile(ctx context.Context, logger logr.Logger, key, nam observedVAP, c.client.AdmissionregistrationV1alpha1().ValidatingAdmissionPolicies(), func(observed *admissionregistrationv1alpha1.ValidatingAdmissionPolicy) error { - return validatingadmissionpolicy.BuildValidatingAdmissionPolicy(c.discoveryClient, observed, policy) + return validatingadmissionpolicy.BuildValidatingAdmissionPolicy(c.discoveryClient, observed, policy, exceptions) }) if err != nil { c.updateClusterPolicyStatus(ctx, *policy, false, err.Error()) diff --git a/pkg/validatingadmissionpolicy/builder.go b/pkg/validatingadmissionpolicy/builder.go index 649a54119720..be2e9d79df4a 100644 --- a/pkg/validatingadmissionpolicy/builder.go +++ b/pkg/validatingadmissionpolicy/builder.go @@ -5,6 +5,7 @@ import ( "slices" kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" + kyvernov2 "github.com/kyverno/kyverno/api/kyverno/v2" "github.com/kyverno/kyverno/pkg/clients/dclient" controllerutils "github.com/kyverno/kyverno/pkg/utils/controller" kubeutils "github.com/kyverno/kyverno/pkg/utils/kube" @@ -18,6 +19,7 @@ func BuildValidatingAdmissionPolicy( discoveryClient dclient.IDiscovery, vap *admissionregistrationv1alpha1.ValidatingAdmissionPolicy, cpol kyvernov1.PolicyInterface, + exceptions []kyvernov2.PolicyException, ) error { // set owner reference vap.OwnerReferences = []metav1.OwnerReference{ @@ -73,6 +75,22 @@ func BuildValidatingAdmissionPolicy( } } + // convert the exceptions if exist + for _, exception := range exceptions { + match := exception.Spec.Match + if match.Any != nil { + if err := translateResourceFilters(discoveryClient, &matchResources, &excludeRules, match.Any, false); err != nil { + return err + } + } + + if match.All != nil { + if err := translateResourceFilters(discoveryClient, &matchResources, &excludeRules, match.All, false); err != nil { + return err + } + } + } + // set policy spec vap.Spec = admissionregistrationv1alpha1.ValidatingAdmissionPolicySpec{ MatchConstraints: &matchResources, diff --git a/pkg/validatingadmissionpolicy/kyvernopolicy_checker.go b/pkg/validatingadmissionpolicy/kyvernopolicy_checker.go index 9a295175d58e..3646cf889502 100644 --- a/pkg/validatingadmissionpolicy/kyvernopolicy_checker.go +++ b/pkg/validatingadmissionpolicy/kyvernopolicy_checker.go @@ -2,11 +2,57 @@ package validatingadmissionpolicy import ( kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" + kyvernov2 "github.com/kyverno/kyverno/api/kyverno/v2" "github.com/kyverno/kyverno/ext/wildcard" ) -// CanGenerateVAP check if Kyverno policy can be translated to a Kubernetes ValidatingAdmissionPolicy -func CanGenerateVAP(spec *kyvernov1.Spec) (bool, string) { +// CanGenerateVAP check if Kyverno policy and a PolicyException can be translated to a Kubernetes ValidatingAdmissionPolicy +func CanGenerateVAP(spec *kyvernov1.Spec, exceptions []kyvernov2.PolicyException) (bool, string) { + var msg string + if ok, msg := checkPolicy(spec); !ok { + return false, msg + } + + if ok, msg := checkExceptions(exceptions); !ok { + return false, msg + } + + return true, msg +} + +func checkExceptions(exceptions []kyvernov2.PolicyException) (bool, string) { + var msg string + for _, exception := range exceptions { + spec := exception.Spec + for _, exception := range spec.Exceptions { + if len(exception.RuleNames) > 1 { + msg = "skip generating ValidatingAdmissionPolicy: multiple ruleNames in PolicyException is not applicable." + return false, msg + } + } + + if spec.Conditions != nil { + msg = "skip generating ValidatingAdmissionPolicy: Conditions in PolicyException is not applicable." + return false, msg + } + + exclude := spec.Match + if ok, msg := checkResourceFilter(exclude.Any, false); !ok { + return false, msg + } + + if len(exclude.All) > 1 { + msg = "skip generating ValidatingAdmissionPolicy: multiple 'all' in the PolicyException's match block is not applicable." + return false, msg + } + if ok, msg := checkResourceFilter(exclude.All, false); !ok { + return false, msg + } + } + return true, msg +} + +func checkPolicy(spec *kyvernov1.Spec) (bool, string) { var msg string if ok, msg := checkRuleCount(spec); !ok { return false, msg diff --git a/pkg/validatingadmissionpolicy/kyvernopolicy_checker_test.go b/pkg/validatingadmissionpolicy/kyvernopolicy_checker_test.go index b024fdae18a9..8a457d032820 100644 --- a/pkg/validatingadmissionpolicy/kyvernopolicy_checker_test.go +++ b/pkg/validatingadmissionpolicy/kyvernopolicy_checker_test.go @@ -4,9 +4,13 @@ import ( "encoding/json" "testing" + "github.com/kyverno/kyverno/api/kyverno" kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" + kyvernov2 "github.com/kyverno/kyverno/api/kyverno/v2" + kyvernov2beta1 "github.com/kyverno/kyverno/api/kyverno/v2beta1" yamlutils "github.com/kyverno/kyverno/pkg/utils/yaml" "gotest.tools/assert" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) func Test_Check_Resources(t *testing.T) { @@ -137,6 +141,232 @@ func Test_Check_Resources(t *testing.T) { } } +func Test_Check_Exception(t *testing.T) { + testCases := []struct { + name string + exceptions []kyvernov2.PolicyException + expected bool + }{ + { + name: "exception-with-multiple-policies", + exceptions: []kyvernov2.PolicyException{ + { + Spec: kyvernov2.PolicyExceptionSpec{ + Exceptions: []kyvernov2.Exception{ + { + PolicyName: "test-1", + RuleNames: []string{"rule-1"}, + }, + { + PolicyName: "test-2", + RuleNames: []string{"rule-2"}, + }, + }, + }, + }, + }, + expected: true, + }, + { + name: "exception-with-multiple-rules", + exceptions: []kyvernov2.PolicyException{ + { + Spec: kyvernov2.PolicyExceptionSpec{ + Exceptions: []kyvernov2.Exception{ + { + PolicyName: "test-1", + RuleNames: []string{"rule-1", "rule-2"}, + }, + }, + }, + }, + }, + expected: false, + }, + { + name: "exception-with-multiple-rules-in-different-exceptions", + exceptions: []kyvernov2.PolicyException{ + { + Spec: kyvernov2.PolicyExceptionSpec{ + Exceptions: []kyvernov2.Exception{ + { + PolicyName: "test-1", + RuleNames: []string{"rule-1", "rule-2"}, + }, + { + PolicyName: "test-2", + RuleNames: []string{"rule-1"}, + }, + }, + }, + }, + }, + expected: false, + }, + { + name: "exception-with-conditions", + exceptions: []kyvernov2.PolicyException{ + { + Spec: kyvernov2.PolicyExceptionSpec{ + Exceptions: []kyvernov2.Exception{ + { + PolicyName: "test-1", + RuleNames: []string{"rule-1"}, + }, + }, + Conditions: &kyvernov2.AnyAllConditions{ + AllConditions: []kyvernov2.Condition{ + { + RawKey: &kyverno.Any{ + Value: "{{ request.object.name }}", + }, + Operator: kyvernov2.ConditionOperators["Equals"], + RawValue: &kyverno.Any{ + Value: "dummy", + }, + }, + }, + }, + }, + }, + }, + expected: false, + }, + { + name: "exception-with-multiple-all", + exceptions: []kyvernov2.PolicyException{ + { + Spec: kyvernov2.PolicyExceptionSpec{ + Exceptions: []kyvernov2.Exception{ + { + PolicyName: "test-1", + RuleNames: []string{"rule-1"}, + }, + }, + Match: kyvernov2beta1.MatchResources{ + All: kyvernov1.ResourceFilters{ + kyvernov1.ResourceFilter{ + ResourceDescription: kyvernov1.ResourceDescription{ + Kinds: []string{"Pod"}, + Operations: []kyvernov1.AdmissionOperation{"CREATE"}, + }, + }, + kyvernov1.ResourceFilter{ + ResourceDescription: kyvernov1.ResourceDescription{ + Kinds: []string{"Pod"}, + Operations: []kyvernov1.AdmissionOperation{"CREATE"}, + }, + }, + }, + }, + }, + }, + }, + expected: false, + }, + { + name: "exception-with-namespace-selector", + exceptions: []kyvernov2.PolicyException{ + { + Spec: kyvernov2.PolicyExceptionSpec{ + Exceptions: []kyvernov2.Exception{ + { + PolicyName: "test-1", + RuleNames: []string{"rule-1"}, + }, + }, + Match: kyvernov2beta1.MatchResources{ + Any: kyvernov1.ResourceFilters{ + kyvernov1.ResourceFilter{ + ResourceDescription: kyvernov1.ResourceDescription{ + Kinds: []string{"Pod"}, + Operations: []kyvernov1.AdmissionOperation{"CREATE"}, + NamespaceSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app": "critical", + }, + }, + }, + }, + }, + }, + }, + }, + }, + expected: false, + }, + { + name: "exception-with-object-selector", + exceptions: []kyvernov2.PolicyException{ + { + Spec: kyvernov2.PolicyExceptionSpec{ + Exceptions: []kyvernov2.Exception{ + { + PolicyName: "test-1", + RuleNames: []string{"rule-1"}, + }, + }, + Match: kyvernov2beta1.MatchResources{ + Any: kyvernov1.ResourceFilters{ + kyvernov1.ResourceFilter{ + ResourceDescription: kyvernov1.ResourceDescription{ + Kinds: []string{"Pod"}, + Operations: []kyvernov1.AdmissionOperation{"CREATE"}, + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app": "critical", + }, + }, + }, + }, + }, + }, + }, + }, + }, + expected: false, + }, + { + name: "exception-with-multiple-any", + exceptions: []kyvernov2.PolicyException{ + { + Spec: kyvernov2.PolicyExceptionSpec{ + Exceptions: []kyvernov2.Exception{ + { + PolicyName: "test-1", + RuleNames: []string{"rule-1"}, + }, + }, + Match: kyvernov2beta1.MatchResources{ + Any: kyvernov1.ResourceFilters{ + kyvernov1.ResourceFilter{ + ResourceDescription: kyvernov1.ResourceDescription{ + Kinds: []string{"Pod"}, + Operations: []kyvernov1.AdmissionOperation{"CREATE"}, + }, + }, + kyvernov1.ResourceFilter{ + ResourceDescription: kyvernov1.ResourceDescription{ + Kinds: []string{"Pod"}, + Operations: []kyvernov1.AdmissionOperation{"CREATE"}, + }, + }, + }, + }, + }, + }, + }, + expected: true, + }, + } + for _, test := range testCases { + t.Run(test.name, func(t *testing.T) { + out, _ := checkExceptions(test.exceptions) + assert.Equal(t, out, test.expected) + }) + } +} + func Test_Can_Generate_ValidatingAdmissionPolicy(t *testing.T) { testCases := []struct { name string @@ -618,7 +848,7 @@ func Test_Can_Generate_ValidatingAdmissionPolicy(t *testing.T) { policies, _, _, err := yamlutils.GetPolicy([]byte(test.policy)) assert.NilError(t, err) assert.Equal(t, 1, len(policies)) - out, _ := CanGenerateVAP(policies[0].GetSpec()) + out, _ := CanGenerateVAP(policies[0].GetSpec(), nil) assert.Equal(t, out, test.expected) }) } diff --git a/pkg/validation/policy/validate.go b/pkg/validation/policy/validate.go index 44d8be7a3a01..f1ea3b423997 100644 --- a/pkg/validation/policy/validate.go +++ b/pkg/validation/policy/validate.go @@ -457,7 +457,7 @@ func Validate(policy, oldPolicy kyvernov1.PolicyInterface, client dclient.Interf } // check for CEL expression warnings in case of CEL subrules - if ok, _ := vaputils.CanGenerateVAP(spec); ok && client != nil { + if ok, _ := vaputils.CanGenerateVAP(spec, nil); ok && client != nil { resolver := &resolver.ClientDiscoveryResolver{ Discovery: client.GetKubeClient().Discovery(), } @@ -477,7 +477,7 @@ func Validate(policy, oldPolicy kyvernov1.PolicyInterface, client dclient.Interf Name: policy.GetName(), }, } - err = vaputils.BuildValidatingAdmissionPolicy(client.Discovery(), vap, policy) + err = vaputils.BuildValidatingAdmissionPolicy(client.Discovery(), vap, policy, nil) if err != nil { return nil, err } diff --git a/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-an-exception-excluding-namespaces/chainsaw-test.yaml b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-an-exception-excluding-namespaces/chainsaw-test.yaml new file mode 100755 index 000000000000..1e99d6ffbf89 --- /dev/null +++ b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-an-exception-excluding-namespaces/chainsaw-test.yaml @@ -0,0 +1,23 @@ +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + creationTimestamp: null + name: cpol-with-an-exception-excluding-namespaces +spec: + steps: + - name: step-01 + try: + - apply: + file: policy.yaml + - assert: + file: policy-assert.yaml + - name: step-02 + try: + - apply: + file: exception.yaml + - name: step-03 + try: + - assert: + file: validatingadmissionpolicy.yaml + - assert: + file: validatingadmissionpolicybinding.yaml diff --git a/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-an-exception-excluding-namespaces/exception.yaml b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-an-exception-excluding-namespaces/exception.yaml new file mode 100644 index 000000000000..2b3396c6c67a --- /dev/null +++ b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-an-exception-excluding-namespaces/exception.yaml @@ -0,0 +1,18 @@ +apiVersion: kyverno.io/v2 +kind: PolicyException +metadata: + name: policy-exception +spec: + exceptions: + - policyName: disallow-host-path + ruleNames: + - host-path + match: + any: + - resources: + namespaces: + - testing-ns + - staging-ns + operations: + - CREATE + - UPDATE diff --git a/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exceptions/policy-assert.yaml b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-an-exception-excluding-namespaces/policy-assert.yaml similarity index 81% rename from test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exceptions/policy-assert.yaml rename to test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-an-exception-excluding-namespaces/policy-assert.yaml index 20ad5ce9b6d1..a94129f63c0c 100644 --- a/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exceptions/policy-assert.yaml +++ b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-an-exception-excluding-namespaces/policy-assert.yaml @@ -1,7 +1,7 @@ apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: - name: disallow-host-path-t11 + name: disallow-host-path status: conditions: - reason: Succeeded diff --git a/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exceptions/policy.yaml b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-an-exception-excluding-namespaces/policy.yaml similarity index 80% rename from test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exceptions/policy.yaml rename to test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-an-exception-excluding-namespaces/policy.yaml index 9968b557e649..83f9851f879c 100644 --- a/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exceptions/policy.yaml +++ b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-an-exception-excluding-namespaces/policy.yaml @@ -1,23 +1,19 @@ apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: - name: disallow-host-path-t11 + name: disallow-host-path spec: background: false rules: - name: host-path match: - all: + any: - resources: kinds: - Deployment - - StatefulSet operations: - CREATE - UPDATE - selector: - matchLabels: - app: critical validate: validationFailureAction: Audit cel: diff --git a/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-an-exception-excluding-namespaces/validatingadmissionpolicy.yaml b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-an-exception-excluding-namespaces/validatingadmissionpolicy.yaml new file mode 100644 index 000000000000..74d7d903c5c1 --- /dev/null +++ b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-an-exception-excluding-namespaces/validatingadmissionpolicy.yaml @@ -0,0 +1,41 @@ +apiVersion: admissionregistration.k8s.io/v1alpha1 +kind: ValidatingAdmissionPolicy +metadata: + labels: + app.kubernetes.io/managed-by: kyverno + name: disallow-host-path + ownerReferences: + - apiVersion: kyverno.io/v1 + kind: ClusterPolicy + name: disallow-host-path +spec: + failurePolicy: Fail + matchConstraints: + excludeResourceRules: + - apiGroups: + - "" + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resourceNames: + - testing-ns + - staging-ns + resources: + - namespaces + resourceRules: + - apiGroups: + - apps + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - deployments + validations: + - expression: '!has(object.spec.template.spec.volumes) || object.spec.template.spec.volumes.all(volume, + !has(volume.hostPath))' + message: HostPath volumes are forbidden. The field spec.template.spec.volumes[*].hostPath + must be unset. diff --git a/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-an-exception-excluding-namespaces/validatingadmissionpolicybinding.yaml b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-an-exception-excluding-namespaces/validatingadmissionpolicybinding.yaml new file mode 100644 index 000000000000..5a26e33f2dfc --- /dev/null +++ b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-an-exception-excluding-namespaces/validatingadmissionpolicybinding.yaml @@ -0,0 +1,13 @@ +apiVersion: admissionregistration.k8s.io/v1alpha1 +kind: ValidatingAdmissionPolicyBinding +metadata: + labels: + app.kubernetes.io/managed-by: kyverno + name: disallow-host-path-binding + ownerReferences: + - apiVersion: kyverno.io/v1 + kind: ClusterPolicy + name: disallow-host-path +spec: + policyName: disallow-host-path + validationActions: [Audit, Warn] diff --git a/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-an-exception/chainsaw-test.yaml b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-an-exception/chainsaw-test.yaml new file mode 100755 index 000000000000..6045677f4212 --- /dev/null +++ b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-an-exception/chainsaw-test.yaml @@ -0,0 +1,23 @@ +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + creationTimestamp: null + name: cpol-with-an-exception +spec: + steps: + - name: step-01 + try: + - apply: + file: policy.yaml + - assert: + file: policy-assert.yaml + - name: step-02 + try: + - apply: + file: exception.yaml + - name: step-03 + try: + - assert: + file: validatingadmissionpolicy.yaml + - assert: + file: validatingadmissionpolicybinding.yaml diff --git a/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exceptions/exception.yaml b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-an-exception/exception.yaml similarity index 65% rename from test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exceptions/exception.yaml rename to test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-an-exception/exception.yaml index c4e61e5378ce..2d72c1e964e9 100644 --- a/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exceptions/exception.yaml +++ b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-an-exception/exception.yaml @@ -4,7 +4,7 @@ metadata: name: policy-exception spec: exceptions: - - policyName: disallow-host-path-t11 + - policyName: disallow-host-path ruleNames: - host-path match: @@ -13,4 +13,7 @@ spec: kinds: - Deployment names: - - important-tool* + - important-tool + operations: + - CREATE + - UPDATE diff --git a/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-an-exception/policy-assert.yaml b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-an-exception/policy-assert.yaml new file mode 100644 index 000000000000..a94129f63c0c --- /dev/null +++ b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-an-exception/policy-assert.yaml @@ -0,0 +1,10 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: disallow-host-path +status: + conditions: + - reason: Succeeded + status: "True" + type: Ready + \ No newline at end of file diff --git a/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-an-exception/policy.yaml b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-an-exception/policy.yaml new file mode 100644 index 000000000000..44bea23ca73d --- /dev/null +++ b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-an-exception/policy.yaml @@ -0,0 +1,31 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: disallow-host-path +spec: + validationFailureAction: Audit + background: false + rules: + - name: host-path + match: + any: + - resources: + kinds: + - Deployment + - StatefulSet + - ReplicaSet + - DaemonSet + operations: + - CREATE + - UPDATE + namespaceSelector: + matchExpressions: + - key: type + operator: In + values: + - connector + validate: + cel: + expressions: + - expression: "!has(object.spec.template.spec.volumes) || object.spec.template.spec.volumes.all(volume, !has(volume.hostPath))" + message: "HostPath volumes are forbidden. The field spec.template.spec.volumes[*].hostPath must be unset." diff --git a/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-an-exception/validatingadmissionpolicy.yaml b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-an-exception/validatingadmissionpolicy.yaml new file mode 100644 index 000000000000..b863879c797f --- /dev/null +++ b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-an-exception/validatingadmissionpolicy.yaml @@ -0,0 +1,49 @@ +apiVersion: admissionregistration.k8s.io/v1alpha1 +kind: ValidatingAdmissionPolicy +metadata: + labels: + app.kubernetes.io/managed-by: kyverno + name: disallow-host-path + ownerReferences: + - apiVersion: kyverno.io/v1 + kind: ClusterPolicy + name: disallow-host-path +spec: + failurePolicy: Fail + matchConstraints: + resourceRules: + - apiGroups: + - apps + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - deployments + - statefulsets + - replicasets + - daemonsets + namespaceSelector: + matchExpressions: + - key: type + operator: In + values: + - connector + excludeResourceRules: + - apiGroups: + - apps + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resourceNames: + - important-tool + resources: + - deployments + validations: + - expression: '!has(object.spec.template.spec.volumes) || object.spec.template.spec.volumes.all(volume, + !has(volume.hostPath))' + message: HostPath volumes are forbidden. The field spec.template.spec.volumes[*].hostPath + must be unset. diff --git a/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-an-exception/validatingadmissionpolicybinding.yaml b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-an-exception/validatingadmissionpolicybinding.yaml new file mode 100644 index 000000000000..5a26e33f2dfc --- /dev/null +++ b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-an-exception/validatingadmissionpolicybinding.yaml @@ -0,0 +1,13 @@ +apiVersion: admissionregistration.k8s.io/v1alpha1 +kind: ValidatingAdmissionPolicyBinding +metadata: + labels: + app.kubernetes.io/managed-by: kyverno + name: disallow-host-path-binding + ownerReferences: + - apiVersion: kyverno.io/v1 + kind: ClusterPolicy + name: disallow-host-path +spec: + policyName: disallow-host-path + validationActions: [Audit, Warn] diff --git a/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-two-exceptions/chainsaw-test.yaml b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-two-exceptions/chainsaw-test.yaml new file mode 100755 index 000000000000..bb73e75343f8 --- /dev/null +++ b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-two-exceptions/chainsaw-test.yaml @@ -0,0 +1,23 @@ +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + creationTimestamp: null + name: cpol-with-two-exceptions +spec: + steps: + - name: step-01 + try: + - apply: + file: policy.yaml + - assert: + file: policy-assert.yaml + - name: step-02 + try: + - apply: + file: exception.yaml + - name: step-03 + try: + - assert: + file: validatingadmissionpolicy.yaml + - assert: + file: validatingadmissionpolicybinding.yaml diff --git a/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-two-exceptions/exception.yaml b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-two-exceptions/exception.yaml new file mode 100644 index 000000000000..1cc0da1ecae7 --- /dev/null +++ b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-two-exceptions/exception.yaml @@ -0,0 +1,39 @@ +apiVersion: kyverno.io/v2 +kind: PolicyException +metadata: + name: policy-exception-1 +spec: + exceptions: + - policyName: disallow-host-path + ruleNames: + - host-path + match: + any: + - resources: + kinds: + - Deployment + names: + - important-tool + operations: + - CREATE + - UPDATE +--- +apiVersion: kyverno.io/v2 +kind: PolicyException +metadata: + name: policy-exception-2 +spec: + exceptions: + - policyName: disallow-host-path + ruleNames: + - host-path + match: + any: + - resources: + kinds: + - StatefulSet + names: + - important-tool + operations: + - CREATE + - UPDATE \ No newline at end of file diff --git a/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-two-exceptions/policy-assert.yaml b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-two-exceptions/policy-assert.yaml new file mode 100644 index 000000000000..a94129f63c0c --- /dev/null +++ b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-two-exceptions/policy-assert.yaml @@ -0,0 +1,10 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: disallow-host-path +status: + conditions: + - reason: Succeeded + status: "True" + type: Ready + \ No newline at end of file diff --git a/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-two-exceptions/policy.yaml b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-two-exceptions/policy.yaml new file mode 100644 index 000000000000..44bea23ca73d --- /dev/null +++ b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-two-exceptions/policy.yaml @@ -0,0 +1,31 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: disallow-host-path +spec: + validationFailureAction: Audit + background: false + rules: + - name: host-path + match: + any: + - resources: + kinds: + - Deployment + - StatefulSet + - ReplicaSet + - DaemonSet + operations: + - CREATE + - UPDATE + namespaceSelector: + matchExpressions: + - key: type + operator: In + values: + - connector + validate: + cel: + expressions: + - expression: "!has(object.spec.template.spec.volumes) || object.spec.template.spec.volumes.all(volume, !has(volume.hostPath))" + message: "HostPath volumes are forbidden. The field spec.template.spec.volumes[*].hostPath must be unset." diff --git a/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-two-exceptions/validatingadmissionpolicy.yaml b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-two-exceptions/validatingadmissionpolicy.yaml new file mode 100644 index 000000000000..551b99f54797 --- /dev/null +++ b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-two-exceptions/validatingadmissionpolicy.yaml @@ -0,0 +1,50 @@ +apiVersion: admissionregistration.k8s.io/v1alpha1 +kind: ValidatingAdmissionPolicy +metadata: + labels: + app.kubernetes.io/managed-by: kyverno + name: disallow-host-path + ownerReferences: + - apiVersion: kyverno.io/v1 + kind: ClusterPolicy + name: disallow-host-path +spec: + failurePolicy: Fail + matchConstraints: + resourceRules: + - apiGroups: + - apps + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - deployments + - statefulsets + - replicasets + - daemonsets + namespaceSelector: + matchExpressions: + - key: type + operator: In + values: + - connector + excludeResourceRules: + - apiGroups: + - apps + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resourceNames: + - important-tool + resources: + - deployments + - statefulsets + validations: + - expression: '!has(object.spec.template.spec.volumes) || object.spec.template.spec.volumes.all(volume, + !has(volume.hostPath))' + message: HostPath volumes are forbidden. The field spec.template.spec.volumes[*].hostPath + must be unset. diff --git a/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-two-exceptions/validatingadmissionpolicybinding.yaml b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-two-exceptions/validatingadmissionpolicybinding.yaml new file mode 100644 index 000000000000..5a26e33f2dfc --- /dev/null +++ b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/generate/cpol-with-two-exceptions/validatingadmissionpolicybinding.yaml @@ -0,0 +1,13 @@ +apiVersion: admissionregistration.k8s.io/v1alpha1 +kind: ValidatingAdmissionPolicyBinding +metadata: + labels: + app.kubernetes.io/managed-by: kyverno + name: disallow-host-path-binding + ownerReferences: + - apiVersion: kyverno.io/v1 + kind: ClusterPolicy + name: disallow-host-path +spec: + policyName: disallow-host-path + validationActions: [Audit, Warn] diff --git a/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exceptions/chainsaw-test.yaml b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-conditions/chainsaw-test.yaml similarity index 82% rename from test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exceptions/chainsaw-test.yaml rename to test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-conditions/chainsaw-test.yaml index 8e0346b37373..bc0861e6d846 100755 --- a/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exceptions/chainsaw-test.yaml +++ b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-conditions/chainsaw-test.yaml @@ -2,7 +2,7 @@ apiVersion: chainsaw.kyverno.io/v1alpha1 kind: Test metadata: creationTimestamp: null - name: cpol-with-exceptions + name: cpol-with-exceptions-and-conditions spec: steps: - name: step-01 @@ -16,10 +16,6 @@ spec: - apply: file: exception.yaml - name: step-03 - try: - - sleep: - duration: 15s - - name: step-04 try: - error: file: validatingadmissionpolicy.yaml diff --git a/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-conditions/exception.yaml b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-conditions/exception.yaml new file mode 100644 index 000000000000..5ebb34998c23 --- /dev/null +++ b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-conditions/exception.yaml @@ -0,0 +1,24 @@ +apiVersion: kyverno.io/v2 +kind: PolicyException +metadata: + name: policy-exception +spec: + exceptions: + - policyName: disallow-host-path + ruleNames: + - host-path + match: + any: + - resources: + kinds: + - Deployment + names: + - important-tool + operations: + - CREATE + - UPDATE + conditions: + any: + - key: "{{ request.object.metadata.labels.color || '' }}" + operator: Equals + value: red diff --git a/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-conditions/policy-assert.yaml b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-conditions/policy-assert.yaml new file mode 100644 index 000000000000..a94129f63c0c --- /dev/null +++ b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-conditions/policy-assert.yaml @@ -0,0 +1,10 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: disallow-host-path +status: + conditions: + - reason: Succeeded + status: "True" + type: Ready + \ No newline at end of file diff --git a/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-conditions/policy.yaml b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-conditions/policy.yaml new file mode 100644 index 000000000000..44bea23ca73d --- /dev/null +++ b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-conditions/policy.yaml @@ -0,0 +1,31 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: disallow-host-path +spec: + validationFailureAction: Audit + background: false + rules: + - name: host-path + match: + any: + - resources: + kinds: + - Deployment + - StatefulSet + - ReplicaSet + - DaemonSet + operations: + - CREATE + - UPDATE + namespaceSelector: + matchExpressions: + - key: type + operator: In + values: + - connector + validate: + cel: + expressions: + - expression: "!has(object.spec.template.spec.volumes) || object.spec.template.spec.volumes.all(volume, !has(volume.hostPath))" + message: "HostPath volumes are forbidden. The field spec.template.spec.volumes[*].hostPath must be unset." diff --git a/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exceptions/validatingadmissionpolicy.yaml b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-conditions/validatingadmissionpolicy.yaml similarity index 78% rename from test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exceptions/validatingadmissionpolicy.yaml rename to test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-conditions/validatingadmissionpolicy.yaml index 836c18653b61..bbd006a18120 100644 --- a/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exceptions/validatingadmissionpolicy.yaml +++ b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-conditions/validatingadmissionpolicy.yaml @@ -3,5 +3,5 @@ kind: ValidatingAdmissionPolicy metadata: labels: app.kubernetes.io/managed-by: kyverno - name: disallow-host-path-t11 -spec: {} + name: disallow-host-path +spec: {} \ No newline at end of file diff --git a/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exceptions/validatingadmissionpolicybinding.yaml b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-conditions/validatingadmissionpolicybinding.yaml similarity index 80% rename from test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exceptions/validatingadmissionpolicybinding.yaml rename to test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-conditions/validatingadmissionpolicybinding.yaml index 708e437aeed7..d55528cc08de 100644 --- a/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exceptions/validatingadmissionpolicybinding.yaml +++ b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-conditions/validatingadmissionpolicybinding.yaml @@ -3,5 +3,5 @@ kind: ValidatingAdmissionPolicyBinding metadata: labels: app.kubernetes.io/managed-by: kyverno - name: disallow-host-path-t11-binding + name: disallow-host-path-binding spec: {} diff --git a/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-namespace-selector/chainsaw-test.yaml b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-namespace-selector/chainsaw-test.yaml new file mode 100755 index 000000000000..60b7c186506d --- /dev/null +++ b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-namespace-selector/chainsaw-test.yaml @@ -0,0 +1,23 @@ +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + creationTimestamp: null + name: cpol-with-exception-and-namesapce-selector +spec: + steps: + - name: step-01 + try: + - apply: + file: policy.yaml + - assert: + file: policy-assert.yaml + - name: step-02 + try: + - apply: + file: exception.yaml + - name: step-03 + try: + - error: + file: validatingadmissionpolicy.yaml + - error: + file: validatingadmissionpolicybinding.yaml diff --git a/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-namespace-selector/exception.yaml b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-namespace-selector/exception.yaml new file mode 100644 index 000000000000..9b1afb15da69 --- /dev/null +++ b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-namespace-selector/exception.yaml @@ -0,0 +1,23 @@ +apiVersion: kyverno.io/v2 +kind: PolicyException +metadata: + name: policy-exception +spec: + exceptions: + - policyName: disallow-host-path + ruleNames: + - host-path + match: + any: + - resources: + kinds: + - Deployment + operations: + - CREATE + - UPDATE + namespaceSelector: + matchExpressions: + - key: type + operator: In + values: + - connector diff --git a/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-namespace-selector/policy-assert.yaml b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-namespace-selector/policy-assert.yaml new file mode 100644 index 000000000000..a94129f63c0c --- /dev/null +++ b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-namespace-selector/policy-assert.yaml @@ -0,0 +1,10 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: disallow-host-path +status: + conditions: + - reason: Succeeded + status: "True" + type: Ready + \ No newline at end of file diff --git a/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-namespace-selector/policy.yaml b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-namespace-selector/policy.yaml new file mode 100644 index 000000000000..a8f5aa4bf281 --- /dev/null +++ b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-namespace-selector/policy.yaml @@ -0,0 +1,22 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: disallow-host-path +spec: + validationFailureAction: Audit + background: false + rules: + - name: host-path + match: + any: + - resources: + kinds: + - Deployment + operations: + - CREATE + - UPDATE + validate: + cel: + expressions: + - expression: "!has(object.spec.template.spec.volumes) || object.spec.template.spec.volumes.all(volume, !has(volume.hostPath))" + message: "HostPath volumes are forbidden. The field spec.template.spec.volumes[*].hostPath must be unset." diff --git a/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-namespace-selector/validatingadmissionpolicy.yaml b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-namespace-selector/validatingadmissionpolicy.yaml new file mode 100644 index 000000000000..bbd006a18120 --- /dev/null +++ b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-namespace-selector/validatingadmissionpolicy.yaml @@ -0,0 +1,7 @@ +apiVersion: admissionregistration.k8s.io/v1alpha1 +kind: ValidatingAdmissionPolicy +metadata: + labels: + app.kubernetes.io/managed-by: kyverno + name: disallow-host-path +spec: {} \ No newline at end of file diff --git a/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-namespace-selector/validatingadmissionpolicybinding.yaml b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-namespace-selector/validatingadmissionpolicybinding.yaml new file mode 100644 index 000000000000..d55528cc08de --- /dev/null +++ b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-namespace-selector/validatingadmissionpolicybinding.yaml @@ -0,0 +1,7 @@ +apiVersion: admissionregistration.k8s.io/v1alpha1 +kind: ValidatingAdmissionPolicyBinding +metadata: + labels: + app.kubernetes.io/managed-by: kyverno + name: disallow-host-path-binding +spec: {} diff --git a/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-object-selector/chainsaw-test.yaml b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-object-selector/chainsaw-test.yaml new file mode 100755 index 000000000000..44cf57516822 --- /dev/null +++ b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-object-selector/chainsaw-test.yaml @@ -0,0 +1,23 @@ +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + creationTimestamp: null + name: cpol-with-exception-and-object-selector +spec: + steps: + - name: step-01 + try: + - apply: + file: policy.yaml + - assert: + file: policy-assert.yaml + - name: step-02 + try: + - apply: + file: exception.yaml + - name: step-03 + try: + - error: + file: validatingadmissionpolicy.yaml + - error: + file: validatingadmissionpolicybinding.yaml diff --git a/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-object-selector/exception.yaml b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-object-selector/exception.yaml new file mode 100644 index 000000000000..cd2f24732f39 --- /dev/null +++ b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-object-selector/exception.yaml @@ -0,0 +1,20 @@ +apiVersion: kyverno.io/v2 +kind: PolicyException +metadata: + name: policy-exception +spec: + exceptions: + - policyName: disallow-host-path + ruleNames: + - host-path + match: + any: + - resources: + kinds: + - Deployment + operations: + - CREATE + - UPDATE + selector: + matchLabels: + app: critical diff --git a/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-object-selector/policy-assert.yaml b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-object-selector/policy-assert.yaml new file mode 100644 index 000000000000..a94129f63c0c --- /dev/null +++ b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-object-selector/policy-assert.yaml @@ -0,0 +1,10 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: disallow-host-path +status: + conditions: + - reason: Succeeded + status: "True" + type: Ready + \ No newline at end of file diff --git a/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-object-selector/policy.yaml b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-object-selector/policy.yaml new file mode 100644 index 000000000000..a8f5aa4bf281 --- /dev/null +++ b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-object-selector/policy.yaml @@ -0,0 +1,22 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: disallow-host-path +spec: + validationFailureAction: Audit + background: false + rules: + - name: host-path + match: + any: + - resources: + kinds: + - Deployment + operations: + - CREATE + - UPDATE + validate: + cel: + expressions: + - expression: "!has(object.spec.template.spec.volumes) || object.spec.template.spec.volumes.all(volume, !has(volume.hostPath))" + message: "HostPath volumes are forbidden. The field spec.template.spec.volumes[*].hostPath must be unset." diff --git a/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-object-selector/validatingadmissionpolicy.yaml b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-object-selector/validatingadmissionpolicy.yaml new file mode 100644 index 000000000000..bbd006a18120 --- /dev/null +++ b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-object-selector/validatingadmissionpolicy.yaml @@ -0,0 +1,7 @@ +apiVersion: admissionregistration.k8s.io/v1alpha1 +kind: ValidatingAdmissionPolicy +metadata: + labels: + app.kubernetes.io/managed-by: kyverno + name: disallow-host-path +spec: {} \ No newline at end of file diff --git a/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-object-selector/validatingadmissionpolicybinding.yaml b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-object-selector/validatingadmissionpolicybinding.yaml new file mode 100644 index 000000000000..d55528cc08de --- /dev/null +++ b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-and-object-selector/validatingadmissionpolicybinding.yaml @@ -0,0 +1,7 @@ +apiVersion: admissionregistration.k8s.io/v1alpha1 +kind: ValidatingAdmissionPolicyBinding +metadata: + labels: + app.kubernetes.io/managed-by: kyverno + name: disallow-host-path-binding +spec: {} diff --git a/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-in-specific-namespace/chainsaw-test.yaml b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-in-specific-namespace/chainsaw-test.yaml new file mode 100755 index 000000000000..b8be34e76e27 --- /dev/null +++ b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-in-specific-namespace/chainsaw-test.yaml @@ -0,0 +1,23 @@ +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + creationTimestamp: null + name: cpol-with-exception-in-specific-namespace +spec: + steps: + - name: step-01 + try: + - apply: + file: policy.yaml + - assert: + file: policy-assert.yaml + - name: step-02 + try: + - apply: + file: exception.yaml + - name: step-03 + try: + - error: + file: validatingadmissionpolicy.yaml + - error: + file: validatingadmissionpolicybinding.yaml diff --git a/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-in-specific-namespace/exception.yaml b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-in-specific-namespace/exception.yaml new file mode 100644 index 000000000000..3ec4a8f88881 --- /dev/null +++ b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-in-specific-namespace/exception.yaml @@ -0,0 +1,20 @@ +apiVersion: kyverno.io/v2 +kind: PolicyException +metadata: + name: policy-exception +spec: + exceptions: + - policyName: disallow-host-path + ruleNames: + - host-path + match: + any: + - resources: + kinds: + - Deployment + operations: + - CREATE + - UPDATE + namespaces: + - testing-ns + - staging-ns diff --git a/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-in-specific-namespace/policy-assert.yaml b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-in-specific-namespace/policy-assert.yaml new file mode 100644 index 000000000000..a94129f63c0c --- /dev/null +++ b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-in-specific-namespace/policy-assert.yaml @@ -0,0 +1,10 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: disallow-host-path +status: + conditions: + - reason: Succeeded + status: "True" + type: Ready + \ No newline at end of file diff --git a/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-in-specific-namespace/policy.yaml b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-in-specific-namespace/policy.yaml new file mode 100644 index 000000000000..a8f5aa4bf281 --- /dev/null +++ b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-in-specific-namespace/policy.yaml @@ -0,0 +1,22 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: disallow-host-path +spec: + validationFailureAction: Audit + background: false + rules: + - name: host-path + match: + any: + - resources: + kinds: + - Deployment + operations: + - CREATE + - UPDATE + validate: + cel: + expressions: + - expression: "!has(object.spec.template.spec.volumes) || object.spec.template.spec.volumes.all(volume, !has(volume.hostPath))" + message: "HostPath volumes are forbidden. The field spec.template.spec.volumes[*].hostPath must be unset." diff --git a/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-in-specific-namespace/validatingadmissionpolicy.yaml b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-in-specific-namespace/validatingadmissionpolicy.yaml new file mode 100644 index 000000000000..bbd006a18120 --- /dev/null +++ b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-in-specific-namespace/validatingadmissionpolicy.yaml @@ -0,0 +1,7 @@ +apiVersion: admissionregistration.k8s.io/v1alpha1 +kind: ValidatingAdmissionPolicy +metadata: + labels: + app.kubernetes.io/managed-by: kyverno + name: disallow-host-path +spec: {} \ No newline at end of file diff --git a/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-in-specific-namespace/validatingadmissionpolicybinding.yaml b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-in-specific-namespace/validatingadmissionpolicybinding.yaml new file mode 100644 index 000000000000..d55528cc08de --- /dev/null +++ b/test/conformance/chainsaw/generate-validating-admission-policy/clusterpolicy/standard/skip-generate/cpol-with-exception-in-specific-namespace/validatingadmissionpolicybinding.yaml @@ -0,0 +1,7 @@ +apiVersion: admissionregistration.k8s.io/v1alpha1 +kind: ValidatingAdmissionPolicyBinding +metadata: + labels: + app.kubernetes.io/managed-by: kyverno + name: disallow-host-path-binding +spec: {} From e0ff371cccbbb5d213cb820ff22db19078262203 Mon Sep 17 00:00:00 2001 From: Khaled Emara Date: Tue, 13 Aug 2024 16:15:53 +0300 Subject: [PATCH 5/5] test(gctx): cli variable injection (#10809) Signed-off-by: Khaled Emara Co-authored-by: Mariam Fahmy --- test/cli/test/globalcontext/kyverno-test.yaml | 16 +++++++++ test/cli/test/globalcontext/policy.yaml | 33 +++++++++++++++++++ test/cli/test/globalcontext/resources.yaml | 22 +++++++++++++ test/cli/test/globalcontext/values.yaml | 12 +++++++ 4 files changed, 83 insertions(+) create mode 100644 test/cli/test/globalcontext/kyverno-test.yaml create mode 100644 test/cli/test/globalcontext/policy.yaml create mode 100644 test/cli/test/globalcontext/resources.yaml create mode 100644 test/cli/test/globalcontext/values.yaml diff --git a/test/cli/test/globalcontext/kyverno-test.yaml b/test/cli/test/globalcontext/kyverno-test.yaml new file mode 100644 index 000000000000..b9ebfbb476d3 --- /dev/null +++ b/test/cli/test/globalcontext/kyverno-test.yaml @@ -0,0 +1,16 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: gctx +policies: +- policy.yaml +resources: +- resources.yaml +results: +- kind: Deployment + policy: gctx + resources: + - test-gctx/new-deployment + result: pass + rule: main-deployment-exists +variables: values.yaml diff --git a/test/cli/test/globalcontext/policy.yaml b/test/cli/test/globalcontext/policy.yaml new file mode 100644 index 000000000000..586999320542 --- /dev/null +++ b/test/cli/test/globalcontext/policy.yaml @@ -0,0 +1,33 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: gctx +spec: + failurePolicy: Fail + rules: + - name: main-deployment-exists + context: + - name: deploymentCount + globalReference: + name: gctxentry-apicall-correct + jmesPath: "items | length(@)" + match: + all: + - resources: + kinds: + - Pod + preconditions: + all: + - key: "{{ request.operation }}" + operator: AnyIn + value: + - CREATE + - UPDATE + validate: + validationFailureAction: Enforce + deny: + conditions: + any: + - key: "{{ deploymentCount }}" + operator: Equal + value: 0 diff --git a/test/cli/test/globalcontext/resources.yaml b/test/cli/test/globalcontext/resources.yaml new file mode 100644 index 000000000000..2c1f25d74231 --- /dev/null +++ b/test/cli/test/globalcontext/resources.yaml @@ -0,0 +1,22 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: new-deployment + namespace: test-gctx + labels: + app: new-deployment +spec: + replicas: 1 + selector: + matchLabels: + app: new-deployment + template: + metadata: + labels: + app: new-deployment + spec: + containers: + - name: nginx + image: nginx:1.14.2 + ports: + - containerPort: 80 diff --git a/test/cli/test/globalcontext/values.yaml b/test/cli/test/globalcontext/values.yaml new file mode 100644 index 000000000000..2a906e39aa69 --- /dev/null +++ b/test/cli/test/globalcontext/values.yaml @@ -0,0 +1,12 @@ +apiVersion: cli.kyverno.io/v1alpha1 +kind: Value +metadata: + name: values +globalValues: + request.operation: CREATE +policies: + - name: gctx + rules: + - name: main-deployment-exists + values: + deploymentCount: 1