From c9d821ee7258963d1afd1c303710443f94545f87 Mon Sep 17 00:00:00 2001
From: Khaled Emara <khaled.emara@nirmata.com>
Date: Tue, 30 Apr 2024 17:05:33 +0300
Subject: [PATCH] fix: shared policy context needs to be copied (#10139)

* fix: shared policy context needs to be copied

Signed-off-by: Khaled Emara <khaled.emara@nirmata.com>

* test(e2e): concurrent PSS execution

Signed-off-by: Khaled Emara <khaled.emara@nirmata.com>

* test(e2e): wait for pss policies to be ready

Signed-off-by: Khaled Emara <khaled.emara@nirmata.com>

---------

Signed-off-by: Khaled Emara <khaled.emara@nirmata.com>
Co-authored-by: shuting <shuting@nirmata.com>
---
 pkg/engine/policycontext/policy_context.go    |  32 ++--
 .../concurrent-policy-execution/bad-pod.yaml  |  19 ++
 .../chainsaw-test.yaml                        |  36 ++++
 .../concurrent-policy-execution/good-pod.yaml |  19 ++
 .../policy-asserts.yaml                       | 171 ++++++++++++++++++
 5 files changed, 261 insertions(+), 16 deletions(-)
 create mode 100644 test/conformance/chainsaw/validate/clusterpolicy/standard/psa/concurrent-policy-execution/bad-pod.yaml
 create mode 100755 test/conformance/chainsaw/validate/clusterpolicy/standard/psa/concurrent-policy-execution/chainsaw-test.yaml
 create mode 100644 test/conformance/chainsaw/validate/clusterpolicy/standard/psa/concurrent-policy-execution/good-pod.yaml
 create mode 100644 test/conformance/chainsaw/validate/clusterpolicy/standard/psa/concurrent-policy-execution/policy-asserts.yaml

diff --git a/pkg/engine/policycontext/policy_context.go b/pkg/engine/policycontext/policy_context.go
index 20773b42f0..cd2f8b9ec0 100644
--- a/pkg/engine/policycontext/policy_context.go
+++ b/pkg/engine/policycontext/policy_context.go
@@ -127,49 +127,49 @@ func (c *PolicyContext) JSONContext() enginectx.Interface {
 
 // Mutators
 
-func (c *PolicyContext) WithPolicy(policy kyvernov1.PolicyInterface) *PolicyContext {
+func (c PolicyContext) WithPolicy(policy kyvernov1.PolicyInterface) *PolicyContext {
 	c.policy = policy
-	return c
+	return &c
 }
 
-func (c *PolicyContext) WithNamespaceLabels(namespaceLabels map[string]string) *PolicyContext {
+func (c PolicyContext) WithNamespaceLabels(namespaceLabels map[string]string) *PolicyContext {
 	c.namespaceLabels = namespaceLabels
-	return c
+	return &c
 }
 
-func (c *PolicyContext) WithAdmissionInfo(admissionInfo kyvernov1beta1.RequestInfo) *PolicyContext {
+func (c PolicyContext) WithAdmissionInfo(admissionInfo kyvernov1beta1.RequestInfo) *PolicyContext {
 	c.admissionInfo = admissionInfo
-	return c
+	return &c
 }
 
-func (c *PolicyContext) WithNewResource(resource unstructured.Unstructured) *PolicyContext {
+func (c PolicyContext) WithNewResource(resource unstructured.Unstructured) *PolicyContext {
 	c.newResource = resource
-	return c
+	return &c
 }
 
-func (c *PolicyContext) WithOldResource(resource unstructured.Unstructured) *PolicyContext {
+func (c PolicyContext) WithOldResource(resource unstructured.Unstructured) *PolicyContext {
 	c.oldResource = resource
-	return c
+	return &c
 }
 
-func (c *PolicyContext) WithResourceKind(gvk schema.GroupVersionKind, subresource string) *PolicyContext {
+func (c PolicyContext) WithResourceKind(gvk schema.GroupVersionKind, subresource string) *PolicyContext {
 	c.gvk = gvk
 	c.subresource = subresource
-	return c
+	return &c
 }
 
-func (c *PolicyContext) WithRequestResource(gvr metav1.GroupVersionResource) *PolicyContext {
+func (c PolicyContext) WithRequestResource(gvr metav1.GroupVersionResource) *PolicyContext {
 	c.requestResource = gvr
-	return c
+	return &c
 }
 
 func (c *PolicyContext) WithResources(newResource unstructured.Unstructured, oldResource unstructured.Unstructured) *PolicyContext {
 	return c.WithNewResource(newResource).WithOldResource(oldResource)
 }
 
-func (c *PolicyContext) WithAdmissionOperation(admissionOperation bool) *PolicyContext {
+func (c PolicyContext) WithAdmissionOperation(admissionOperation bool) *PolicyContext {
 	c.admissionOperation = admissionOperation
-	return c
+	return &c
 }
 
 // Constructors
diff --git a/test/conformance/chainsaw/validate/clusterpolicy/standard/psa/concurrent-policy-execution/bad-pod.yaml b/test/conformance/chainsaw/validate/clusterpolicy/standard/psa/concurrent-policy-execution/bad-pod.yaml
new file mode 100644
index 0000000000..fc106a3c79
--- /dev/null
+++ b/test/conformance/chainsaw/validate/clusterpolicy/standard/psa/concurrent-policy-execution/bad-pod.yaml
@@ -0,0 +1,19 @@
+apiVersion: v1
+kind: Pod
+metadata:
+  name: bad-pod
+spec:
+  containers:
+    - name: nginx
+      image: nginx
+      args:
+        - sleep
+        - 1d
+      securityContext:
+        seccompProfile:
+          type: RuntimeDefault
+        runAsNonRoot: true
+        allowPrivilegeEscalation: true
+        capabilities:
+          drop:
+            - ALL
diff --git a/test/conformance/chainsaw/validate/clusterpolicy/standard/psa/concurrent-policy-execution/chainsaw-test.yaml b/test/conformance/chainsaw/validate/clusterpolicy/standard/psa/concurrent-policy-execution/chainsaw-test.yaml
new file mode 100755
index 0000000000..80af7056f4
--- /dev/null
+++ b/test/conformance/chainsaw/validate/clusterpolicy/standard/psa/concurrent-policy-execution/chainsaw-test.yaml
@@ -0,0 +1,36 @@
+apiVersion: chainsaw.kyverno.io/v1alpha1
+kind: Test
+metadata:
+  name: concurrent-policy-execution
+spec:
+  steps:
+    - name: install-pss-policies
+      try:
+        - script:
+            content: |
+              #!/bin/bash
+              set -eu
+
+              helm --repo https://kyverno.github.io/kyverno/ install kyverno-policies kyverno-policies --set=podSecurityStandard=restricted --set=background=true --set=validationFailureAction=Enforce
+        - assert:
+            file: policy-asserts.yaml
+    - name: apply-test-pods
+      try:
+        - apply:
+            expect:
+              - check:
+                  ($error != null): false
+            file: good-pod.yaml
+        - apply:
+            expect:
+              - check:
+                  ($error != null): true
+            file: bad-pod.yaml
+    - name: uninstall-pss-policies
+      try:
+        - script:
+            content: |
+              #!/bin/bash
+              set -eu
+
+              helm uninstall kyverno-policies
diff --git a/test/conformance/chainsaw/validate/clusterpolicy/standard/psa/concurrent-policy-execution/good-pod.yaml b/test/conformance/chainsaw/validate/clusterpolicy/standard/psa/concurrent-policy-execution/good-pod.yaml
new file mode 100644
index 0000000000..dae5557f17
--- /dev/null
+++ b/test/conformance/chainsaw/validate/clusterpolicy/standard/psa/concurrent-policy-execution/good-pod.yaml
@@ -0,0 +1,19 @@
+apiVersion: v1
+kind: Pod
+metadata:
+  name: good-pod
+spec:
+  containers:
+    - name: nginx
+      image: nginx
+      args:
+        - sleep
+        - 1d
+      securityContext:
+        seccompProfile:
+          type: RuntimeDefault
+        runAsNonRoot: true
+        allowPrivilegeEscalation: false
+        capabilities:
+          drop:
+            - ALL
diff --git a/test/conformance/chainsaw/validate/clusterpolicy/standard/psa/concurrent-policy-execution/policy-asserts.yaml b/test/conformance/chainsaw/validate/clusterpolicy/standard/psa/concurrent-policy-execution/policy-asserts.yaml
new file mode 100644
index 0000000000..9ffe1b633b
--- /dev/null
+++ b/test/conformance/chainsaw/validate/clusterpolicy/standard/psa/concurrent-policy-execution/policy-asserts.yaml
@@ -0,0 +1,171 @@
+---
+apiVersion: kyverno.io/v1
+kind: ClusterPolicy
+metadata:
+  name: disallow-capabilities
+status:
+  conditions:
+  - reason: Succeeded
+    status: "True"
+    type: Ready
+---
+apiVersion: kyverno.io/v1
+kind: ClusterPolicy
+metadata:
+  name: disallow-capabilities-strict
+status:
+  conditions:
+  - reason: Succeeded
+    status: "True"
+    type: Ready
+---
+apiVersion: kyverno.io/v1
+kind: ClusterPolicy
+metadata:
+  name: disallow-host-namespaces
+status:
+  conditions:
+  - reason: Succeeded
+    status: "True"
+    type: Ready
+---
+apiVersion: kyverno.io/v1
+kind: ClusterPolicy
+metadata:
+  name: disallow-host-path
+status:
+  conditions:
+  - reason: Succeeded
+    status: "True"
+    type: Ready
+---
+apiVersion: kyverno.io/v1
+kind: ClusterPolicy
+metadata:
+  name: disallow-host-ports
+status:
+  conditions:
+  - reason: Succeeded
+    status: "True"
+    type: Ready
+---
+apiVersion: kyverno.io/v1
+kind: ClusterPolicy
+metadata:
+  name: disallow-host-process
+status:
+  conditions:
+  - reason: Succeeded
+    status: "True"
+    type: Ready
+---
+apiVersion: kyverno.io/v1
+kind: ClusterPolicy
+metadata:
+  name: disallow-privilege-escalation
+status:
+  conditions:
+  - reason: Succeeded
+    status: "True"
+    type: Ready
+---
+apiVersion: kyverno.io/v1
+kind: ClusterPolicy
+metadata:
+  name: disallow-privileged-containers
+status:
+  conditions:
+  - reason: Succeeded
+    status: "True"
+    type: Ready
+---
+apiVersion: kyverno.io/v1
+kind: ClusterPolicy
+metadata:
+  name: disallow-proc-mount
+status:
+  conditions:
+  - reason: Succeeded
+    status: "True"
+    type: Ready
+---
+apiVersion: kyverno.io/v1
+kind: ClusterPolicy
+metadata:
+  name: disallow-selinux
+status:
+  conditions:
+  - reason: Succeeded
+    status: "True"
+    type: Ready
+---
+apiVersion: kyverno.io/v1
+kind: ClusterPolicy
+metadata:
+  name: require-run-as-non-root-user
+status:
+  conditions:
+  - reason: Succeeded
+    status: "True"
+    type: Ready
+---
+apiVersion: kyverno.io/v1
+kind: ClusterPolicy
+metadata:
+  name: require-run-as-nonroot
+status:
+  conditions:
+  - reason: Succeeded
+    status: "True"
+    type: Ready
+---
+apiVersion: kyverno.io/v1
+kind: ClusterPolicy
+metadata:
+  name: restrict-apparmor-profiles
+status:
+  conditions:
+  - reason: Succeeded
+    status: "True"
+    type: Ready
+---
+apiVersion: kyverno.io/v1
+kind: ClusterPolicy
+metadata:
+  name: restrict-seccomp
+status:
+  conditions:
+  - reason: Succeeded
+    status: "True"
+    type: Ready
+---
+apiVersion: kyverno.io/v1
+kind: ClusterPolicy
+metadata:
+  name: restrict-seccomp-strict
+status:
+  conditions:
+  - reason: Succeeded
+    status: "True"
+    type: Ready
+---
+apiVersion: kyverno.io/v1
+kind: ClusterPolicy
+metadata:
+  name: restrict-sysctls
+status:
+  conditions:
+  - reason: Succeeded
+    status: "True"
+    type: Ready
+---
+apiVersion: kyverno.io/v1
+kind: ClusterPolicy
+metadata:
+  name: restrict-volume-types
+status:
+  conditions:
+  - reason: Succeeded
+    status: "True"
+    type: Ready
+