From 831d4eb8b85be763614cd3d245975889fde02cd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charles-Edouard=20Br=C3=A9t=C3=A9ch=C3=A9?= Date: Tue, 7 Jan 2025 00:03:06 +0100 Subject: [PATCH] chore: add match conditions errors chainsaw test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Charles-Edouard Brétéché --- pkg/policy/compiler.go | 10 ++-- .../error-with-false/chainsaw-test.yaml | 30 ++++++++++++ .../error-with-false/istio-policy.yaml | 14 ++++++ .../error-with-false/policy.yaml | 18 +++++++ .../error-with-false/shell.yaml | 48 +++++++++++++++++++ .../error-with-true/chainsaw-test.yaml | 30 ++++++++++++ .../error-with-true/istio-policy.yaml | 14 ++++++ .../error-with-true/policy.yaml | 18 +++++++ .../error-with-true/shell.yaml | 48 +++++++++++++++++++ .../error-with-false/chainsaw-test.yaml | 30 ++++++++++++ .../error-with-false/istio-policy.yaml | 14 ++++++ .../error-with-false/policy.yaml | 18 +++++++ .../error-with-false/shell.yaml | 48 +++++++++++++++++++ .../error-with-true/chainsaw-test.yaml | 30 ++++++++++++ .../error-with-true/istio-policy.yaml | 14 ++++++ .../error-with-true/policy.yaml | 18 +++++++ .../error-with-true/shell.yaml | 48 +++++++++++++++++++ 17 files changed, 447 insertions(+), 3 deletions(-) create mode 100644 tests/e2e/authz-server/match-conditions/failure-policy-fail/error-with-false/chainsaw-test.yaml create mode 100644 tests/e2e/authz-server/match-conditions/failure-policy-fail/error-with-false/istio-policy.yaml create mode 100644 tests/e2e/authz-server/match-conditions/failure-policy-fail/error-with-false/policy.yaml create mode 100644 tests/e2e/authz-server/match-conditions/failure-policy-fail/error-with-false/shell.yaml create mode 100644 tests/e2e/authz-server/match-conditions/failure-policy-fail/error-with-true/chainsaw-test.yaml create mode 100644 tests/e2e/authz-server/match-conditions/failure-policy-fail/error-with-true/istio-policy.yaml create mode 100644 tests/e2e/authz-server/match-conditions/failure-policy-fail/error-with-true/policy.yaml create mode 100644 tests/e2e/authz-server/match-conditions/failure-policy-fail/error-with-true/shell.yaml create mode 100644 tests/e2e/authz-server/match-conditions/failure-policy-ignore/error-with-false/chainsaw-test.yaml create mode 100644 tests/e2e/authz-server/match-conditions/failure-policy-ignore/error-with-false/istio-policy.yaml create mode 100644 tests/e2e/authz-server/match-conditions/failure-policy-ignore/error-with-false/policy.yaml create mode 100644 tests/e2e/authz-server/match-conditions/failure-policy-ignore/error-with-false/shell.yaml create mode 100644 tests/e2e/authz-server/match-conditions/failure-policy-ignore/error-with-true/chainsaw-test.yaml create mode 100644 tests/e2e/authz-server/match-conditions/failure-policy-ignore/error-with-true/istio-policy.yaml create mode 100644 tests/e2e/authz-server/match-conditions/failure-policy-ignore/error-with-true/policy.yaml create mode 100644 tests/e2e/authz-server/match-conditions/failure-policy-ignore/error-with-true/shell.yaml diff --git a/pkg/policy/compiler.go b/pkg/policy/compiler.go index ede71d0..04baeb1 100644 --- a/pkg/policy/compiler.go +++ b/pkg/policy/compiler.go @@ -12,6 +12,7 @@ import ( engine "github.com/kyverno/kyverno-envoy-plugin/pkg/authz/cel" envoy "github.com/kyverno/kyverno-envoy-plugin/pkg/authz/cel/libs/envoy" "github.com/kyverno/kyverno-envoy-plugin/pkg/authz/cel/utils" + "go.uber.org/multierr" admissionregistrationv1 "k8s.io/api/admissionregistration/v1" "k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/apiserver/pkg/cel/lazy" @@ -49,25 +50,28 @@ func (p compiledPolicy) For(r *authv3.CheckRequest) (AllowFunc, DenyFunc) { data := map[string]any{ ObjectKey: r, } + var errs []error for _, matchCondition := range p.matchConditions { // evaluate the condition out, _, err := matchCondition.Eval(data) // check error if err != nil { - return false, err + errs = append(errs, err) + continue } // try to convert to a bool result, err := utils.ConvertToNative[bool](out) // check error if err != nil { - return false, err + errs = append(errs, err) + continue } // if condition is false, skip if !result { return false, nil } } - return true, nil + return true, multierr.Combine(errs...) }) variables := sync.OnceValue(func() map[string]any { vars := lazy.NewMapValue(engine.VariablesType) diff --git a/tests/e2e/authz-server/match-conditions/failure-policy-fail/error-with-false/chainsaw-test.yaml b/tests/e2e/authz-server/match-conditions/failure-policy-fail/error-with-false/chainsaw-test.yaml new file mode 100644 index 0000000..e388b76 --- /dev/null +++ b/tests/e2e/authz-server/match-conditions/failure-policy-fail/error-with-false/chainsaw-test.yaml @@ -0,0 +1,30 @@ +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + name: error-with-false +spec: + namespace: app + steps: + - try: + - create: + file: ./istio-policy.yaml + - create: + file: ./policy.yaml + - create: + file: ./shell.yaml + - wait: + apiVersion: v1 + kind: Pod + timeout: 1m + for: + condition: + name: Ready + value: 'true' + - script: + content: > + kubectl exec -n $NAMESPACE deploy/curl -- curl -s -w "\nhttp_code=%{http_code}" httpbin:8000/get + check: + (wildcard('*http_code=200', $stdout)): true + finally: + - sleep: + duration: 10s diff --git a/tests/e2e/authz-server/match-conditions/failure-policy-fail/error-with-false/istio-policy.yaml b/tests/e2e/authz-server/match-conditions/failure-policy-fail/error-with-false/istio-policy.yaml new file mode 100644 index 0000000..e8dadd0 --- /dev/null +++ b/tests/e2e/authz-server/match-conditions/failure-policy-fail/error-with-false/istio-policy.yaml @@ -0,0 +1,14 @@ +apiVersion: security.istio.io/v1 +kind: AuthorizationPolicy +metadata: + name: policy + namespace: istio-system +spec: + selector: + matchLabels: + ext-authz: enabled + action: CUSTOM + provider: + name: kyverno-authz-server + rules: + - {} diff --git a/tests/e2e/authz-server/match-conditions/failure-policy-fail/error-with-false/policy.yaml b/tests/e2e/authz-server/match-conditions/failure-policy-fail/error-with-false/policy.yaml new file mode 100644 index 0000000..d073cf2 --- /dev/null +++ b/tests/e2e/authz-server/match-conditions/failure-policy-fail/error-with-false/policy.yaml @@ -0,0 +1,18 @@ +# yaml-language-server: $schema=../../../../../../.schemas/json/authorizationpolicy-envoy-v1alpha1.json +apiVersion: envoy.kyverno.io/v1alpha1 +kind: AuthorizationPolicy +metadata: + name: policy +spec: + failurePolicy: Fail + matchConditions: + - name: error + expression: '(2 / 0) == 1' + - name: 'false' + expression: 'false' + deny: + - response: > + envoy + .Denied(403) + .WithBody("Unauthorized Request") + .Response() diff --git a/tests/e2e/authz-server/match-conditions/failure-policy-fail/error-with-false/shell.yaml b/tests/e2e/authz-server/match-conditions/failure-policy-fail/error-with-false/shell.yaml new file mode 100644 index 0000000..febda25 --- /dev/null +++ b/tests/e2e/authz-server/match-conditions/failure-policy-fail/error-with-false/shell.yaml @@ -0,0 +1,48 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: curl +--- +apiVersion: v1 +kind: Service +metadata: + name: curl + labels: + app: curl + service: curl +spec: + ports: + - port: 80 + name: http + selector: + app: curl +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: curl +spec: + replicas: 1 + selector: + matchLabels: + app: curl + template: + metadata: + labels: + app: curl + spec: + terminationGracePeriodSeconds: 0 + serviceAccountName: curl + containers: + - name: curl + image: curlimages/curl + command: ["/bin/sleep", "infinity"] + imagePullPolicy: IfNotPresent + volumeMounts: + - mountPath: /etc/curl/tls + name: secret-volume + volumes: + - name: secret-volume + secret: + secretName: curl-secret + optional: true diff --git a/tests/e2e/authz-server/match-conditions/failure-policy-fail/error-with-true/chainsaw-test.yaml b/tests/e2e/authz-server/match-conditions/failure-policy-fail/error-with-true/chainsaw-test.yaml new file mode 100644 index 0000000..25daa03 --- /dev/null +++ b/tests/e2e/authz-server/match-conditions/failure-policy-fail/error-with-true/chainsaw-test.yaml @@ -0,0 +1,30 @@ +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + name: error-with-true +spec: + namespace: app + steps: + - try: + - create: + file: ./istio-policy.yaml + - create: + file: ./policy.yaml + - create: + file: ./shell.yaml + - wait: + apiVersion: v1 + kind: Pod + timeout: 1m + for: + condition: + name: Ready + value: 'true' + - script: + content: > + kubectl exec -n $NAMESPACE deploy/curl -- curl -s -w "\nhttp_code=%{http_code}" httpbin:8000/get + check: + (wildcard('*http_code=403', $stdout)): true + finally: + - sleep: + duration: 10s diff --git a/tests/e2e/authz-server/match-conditions/failure-policy-fail/error-with-true/istio-policy.yaml b/tests/e2e/authz-server/match-conditions/failure-policy-fail/error-with-true/istio-policy.yaml new file mode 100644 index 0000000..e8dadd0 --- /dev/null +++ b/tests/e2e/authz-server/match-conditions/failure-policy-fail/error-with-true/istio-policy.yaml @@ -0,0 +1,14 @@ +apiVersion: security.istio.io/v1 +kind: AuthorizationPolicy +metadata: + name: policy + namespace: istio-system +spec: + selector: + matchLabels: + ext-authz: enabled + action: CUSTOM + provider: + name: kyverno-authz-server + rules: + - {} diff --git a/tests/e2e/authz-server/match-conditions/failure-policy-fail/error-with-true/policy.yaml b/tests/e2e/authz-server/match-conditions/failure-policy-fail/error-with-true/policy.yaml new file mode 100644 index 0000000..4d083b8 --- /dev/null +++ b/tests/e2e/authz-server/match-conditions/failure-policy-fail/error-with-true/policy.yaml @@ -0,0 +1,18 @@ +# yaml-language-server: $schema=../../../../../../.schemas/json/authorizationpolicy-envoy-v1alpha1.json +apiVersion: envoy.kyverno.io/v1alpha1 +kind: AuthorizationPolicy +metadata: + name: policy +spec: + failurePolicy: Fail + matchConditions: + - name: error + expression: '(2 / 0) == 1' + - name: 'true' + expression: 'true' + deny: + - response: > + envoy + .Denied(403) + .WithBody("Unauthorized Request") + .Response() diff --git a/tests/e2e/authz-server/match-conditions/failure-policy-fail/error-with-true/shell.yaml b/tests/e2e/authz-server/match-conditions/failure-policy-fail/error-with-true/shell.yaml new file mode 100644 index 0000000..febda25 --- /dev/null +++ b/tests/e2e/authz-server/match-conditions/failure-policy-fail/error-with-true/shell.yaml @@ -0,0 +1,48 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: curl +--- +apiVersion: v1 +kind: Service +metadata: + name: curl + labels: + app: curl + service: curl +spec: + ports: + - port: 80 + name: http + selector: + app: curl +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: curl +spec: + replicas: 1 + selector: + matchLabels: + app: curl + template: + metadata: + labels: + app: curl + spec: + terminationGracePeriodSeconds: 0 + serviceAccountName: curl + containers: + - name: curl + image: curlimages/curl + command: ["/bin/sleep", "infinity"] + imagePullPolicy: IfNotPresent + volumeMounts: + - mountPath: /etc/curl/tls + name: secret-volume + volumes: + - name: secret-volume + secret: + secretName: curl-secret + optional: true diff --git a/tests/e2e/authz-server/match-conditions/failure-policy-ignore/error-with-false/chainsaw-test.yaml b/tests/e2e/authz-server/match-conditions/failure-policy-ignore/error-with-false/chainsaw-test.yaml new file mode 100644 index 0000000..e388b76 --- /dev/null +++ b/tests/e2e/authz-server/match-conditions/failure-policy-ignore/error-with-false/chainsaw-test.yaml @@ -0,0 +1,30 @@ +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + name: error-with-false +spec: + namespace: app + steps: + - try: + - create: + file: ./istio-policy.yaml + - create: + file: ./policy.yaml + - create: + file: ./shell.yaml + - wait: + apiVersion: v1 + kind: Pod + timeout: 1m + for: + condition: + name: Ready + value: 'true' + - script: + content: > + kubectl exec -n $NAMESPACE deploy/curl -- curl -s -w "\nhttp_code=%{http_code}" httpbin:8000/get + check: + (wildcard('*http_code=200', $stdout)): true + finally: + - sleep: + duration: 10s diff --git a/tests/e2e/authz-server/match-conditions/failure-policy-ignore/error-with-false/istio-policy.yaml b/tests/e2e/authz-server/match-conditions/failure-policy-ignore/error-with-false/istio-policy.yaml new file mode 100644 index 0000000..e8dadd0 --- /dev/null +++ b/tests/e2e/authz-server/match-conditions/failure-policy-ignore/error-with-false/istio-policy.yaml @@ -0,0 +1,14 @@ +apiVersion: security.istio.io/v1 +kind: AuthorizationPolicy +metadata: + name: policy + namespace: istio-system +spec: + selector: + matchLabels: + ext-authz: enabled + action: CUSTOM + provider: + name: kyverno-authz-server + rules: + - {} diff --git a/tests/e2e/authz-server/match-conditions/failure-policy-ignore/error-with-false/policy.yaml b/tests/e2e/authz-server/match-conditions/failure-policy-ignore/error-with-false/policy.yaml new file mode 100644 index 0000000..3460bc5 --- /dev/null +++ b/tests/e2e/authz-server/match-conditions/failure-policy-ignore/error-with-false/policy.yaml @@ -0,0 +1,18 @@ +# yaml-language-server: $schema=../../../../../../.schemas/json/authorizationpolicy-envoy-v1alpha1.json +apiVersion: envoy.kyverno.io/v1alpha1 +kind: AuthorizationPolicy +metadata: + name: policy +spec: + failurePolicy: Ignore + matchConditions: + - name: error + expression: '(2 / 0) == 1' + - name: 'false' + expression: 'false' + deny: + - response: > + envoy + .Denied(403) + .WithBody("Unauthorized Request") + .Response() diff --git a/tests/e2e/authz-server/match-conditions/failure-policy-ignore/error-with-false/shell.yaml b/tests/e2e/authz-server/match-conditions/failure-policy-ignore/error-with-false/shell.yaml new file mode 100644 index 0000000..febda25 --- /dev/null +++ b/tests/e2e/authz-server/match-conditions/failure-policy-ignore/error-with-false/shell.yaml @@ -0,0 +1,48 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: curl +--- +apiVersion: v1 +kind: Service +metadata: + name: curl + labels: + app: curl + service: curl +spec: + ports: + - port: 80 + name: http + selector: + app: curl +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: curl +spec: + replicas: 1 + selector: + matchLabels: + app: curl + template: + metadata: + labels: + app: curl + spec: + terminationGracePeriodSeconds: 0 + serviceAccountName: curl + containers: + - name: curl + image: curlimages/curl + command: ["/bin/sleep", "infinity"] + imagePullPolicy: IfNotPresent + volumeMounts: + - mountPath: /etc/curl/tls + name: secret-volume + volumes: + - name: secret-volume + secret: + secretName: curl-secret + optional: true diff --git a/tests/e2e/authz-server/match-conditions/failure-policy-ignore/error-with-true/chainsaw-test.yaml b/tests/e2e/authz-server/match-conditions/failure-policy-ignore/error-with-true/chainsaw-test.yaml new file mode 100644 index 0000000..ad1c1e4 --- /dev/null +++ b/tests/e2e/authz-server/match-conditions/failure-policy-ignore/error-with-true/chainsaw-test.yaml @@ -0,0 +1,30 @@ +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + name: error-with-true +spec: + namespace: app + steps: + - try: + - create: + file: ./istio-policy.yaml + - create: + file: ./policy.yaml + - create: + file: ./shell.yaml + - wait: + apiVersion: v1 + kind: Pod + timeout: 1m + for: + condition: + name: Ready + value: 'true' + - script: + content: > + kubectl exec -n $NAMESPACE deploy/curl -- curl -s -w "\nhttp_code=%{http_code}" httpbin:8000/get + check: + (wildcard('*http_code=200', $stdout)): true + finally: + - sleep: + duration: 10s diff --git a/tests/e2e/authz-server/match-conditions/failure-policy-ignore/error-with-true/istio-policy.yaml b/tests/e2e/authz-server/match-conditions/failure-policy-ignore/error-with-true/istio-policy.yaml new file mode 100644 index 0000000..e8dadd0 --- /dev/null +++ b/tests/e2e/authz-server/match-conditions/failure-policy-ignore/error-with-true/istio-policy.yaml @@ -0,0 +1,14 @@ +apiVersion: security.istio.io/v1 +kind: AuthorizationPolicy +metadata: + name: policy + namespace: istio-system +spec: + selector: + matchLabels: + ext-authz: enabled + action: CUSTOM + provider: + name: kyverno-authz-server + rules: + - {} diff --git a/tests/e2e/authz-server/match-conditions/failure-policy-ignore/error-with-true/policy.yaml b/tests/e2e/authz-server/match-conditions/failure-policy-ignore/error-with-true/policy.yaml new file mode 100644 index 0000000..5ecd3d5 --- /dev/null +++ b/tests/e2e/authz-server/match-conditions/failure-policy-ignore/error-with-true/policy.yaml @@ -0,0 +1,18 @@ +# yaml-language-server: $schema=../../../../../../.schemas/json/authorizationpolicy-envoy-v1alpha1.json +apiVersion: envoy.kyverno.io/v1alpha1 +kind: AuthorizationPolicy +metadata: + name: policy +spec: + failurePolicy: Ignore + matchConditions: + - name: error + expression: '(2 / 0) == 1' + - name: 'true' + expression: 'true' + deny: + - response: > + envoy + .Denied(403) + .WithBody("Unauthorized Request") + .Response() diff --git a/tests/e2e/authz-server/match-conditions/failure-policy-ignore/error-with-true/shell.yaml b/tests/e2e/authz-server/match-conditions/failure-policy-ignore/error-with-true/shell.yaml new file mode 100644 index 0000000..febda25 --- /dev/null +++ b/tests/e2e/authz-server/match-conditions/failure-policy-ignore/error-with-true/shell.yaml @@ -0,0 +1,48 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: curl +--- +apiVersion: v1 +kind: Service +metadata: + name: curl + labels: + app: curl + service: curl +spec: + ports: + - port: 80 + name: http + selector: + app: curl +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: curl +spec: + replicas: 1 + selector: + matchLabels: + app: curl + template: + metadata: + labels: + app: curl + spec: + terminationGracePeriodSeconds: 0 + serviceAccountName: curl + containers: + - name: curl + image: curlimages/curl + command: ["/bin/sleep", "infinity"] + imagePullPolicy: IfNotPresent + volumeMounts: + - mountPath: /etc/curl/tls + name: secret-volume + volumes: + - name: secret-volume + secret: + secretName: curl-secret + optional: true