From 19b816ba703f80465ab986b188a26324248d5a95 Mon Sep 17 00:00:00 2001 From: Mohd Kamaal <102820439+Mohdcode@users.noreply.github.com> Date: Thu, 13 Mar 2025 19:52:51 +0530 Subject: [PATCH] solves the cronjob autogen nested path issue (#12383) * solves the cronjob autogen nested path issue Signed-off-by: Mohd Kamaal * format the file using linter Signed-off-by: Mohd Kamaal * autogen path change in validating-polcies Signed-off-by: Mohd Kamaal --------- Signed-off-by: Mohd Kamaal Signed-off-by: Mohd Kamaal Co-authored-by: Mohd Kamaal --- pkg/cel/autogen/rule.go | 41 ++++---- .../bad-deployment.yaml | 26 +++++ .../check-autogen.yaml | 95 ++++++++++--------- .../good-deployment.yaml | 24 +++++ .../autogen/should-autogen/check-autogen.yaml | 2 +- 5 files changed, 121 insertions(+), 67 deletions(-) diff --git a/pkg/cel/autogen/rule.go b/pkg/cel/autogen/rule.go index 8d725f90e7..a62f153789 100644 --- a/pkg/cel/autogen/rule.go +++ b/pkg/cel/autogen/rule.go @@ -152,19 +152,6 @@ func convertMatchconditions(conditions []admissionregistrationv1.MatchCondition, } var ( - podReplacementRules [][2][]byte = [][2][]byte{ - {[]byte("object.spec"), []byte("object.spec.template.spec")}, - {[]byte("oldObject.spec"), []byte("oldObject.spec.template.spec")}, - {[]byte("object.metadata"), []byte("object.spec.template.metadata")}, - {[]byte("oldObject.metadata"), []byte("oldObject.spec.template.metadata")}, - } - cronJobReplacementRules [][2][]byte = [][2][]byte{ - {[]byte("object.spec"), []byte("object.spec.jobTemplate.spec.template.spec")}, - {[]byte("oldObject.spec"), []byte("oldObject.spec.jobTemplate.spec.template.spec")}, - {[]byte("object.metadata"), []byte("object.spec.jobTemplate.spec.template.metadata")}, - {[]byte("oldObject.metadata"), []byte("oldObject.spec.jobTemplate.spec.template.metadata")}, - } - podControllerMatchConditionName = "autogen-" podControllersMatchConditionExpression = "!(object.kind =='Deployment' || object.kind =='ReplicaSet' || object.kind =='StatefulSet' || object.kind =='DaemonSet') || " cronjobMatchConditionName = "autogen-cronjobs-" @@ -172,15 +159,31 @@ var ( ) func updateFields(data []byte, resource autogencontroller) []byte { + // Define the target prefixes based on resource type + var specPrefix, metadataPrefix []byte switch resource { case PODS: - for _, replacement := range podReplacementRules { - data = bytes.ReplaceAll(data, replacement[0], replacement[1]) - } + specPrefix = []byte("object.spec.template.spec") + metadataPrefix = []byte("object.spec.template.metadata") case CRONJOBS: - for _, replacement := range cronJobReplacementRules { - data = bytes.ReplaceAll(data, replacement[0], replacement[1]) - } + specPrefix = []byte("object.spec.jobTemplate.spec.template.spec") + metadataPrefix = []byte("object.spec.jobTemplate.spec.template.metadata") } + + // Replace object.spec and oldObject.spec with the correct prefix + data = bytes.ReplaceAll(data, []byte("object.spec"), specPrefix) + data = bytes.ReplaceAll(data, []byte("oldObject.spec"), append([]byte("oldObject"), specPrefix[6:]...)) // Adjust for oldObject + data = bytes.ReplaceAll(data, []byte("object.metadata"), metadataPrefix) + data = bytes.ReplaceAll(data, []byte("oldObject.metadata"), append([]byte("oldObject"), metadataPrefix[6:]...)) + + // Normalize any over-nested paths remove extra .template.spec + if resource == CRONJOBS { + data = bytes.ReplaceAll(data, []byte("object.spec.jobTemplate.spec.template.spec.template.spec"), specPrefix) + data = bytes.ReplaceAll(data, []byte("oldObject.spec.jobTemplate.spec.template.spec.template.spec"), append([]byte("oldObject"), specPrefix[6:]...)) + } else if resource == PODS { + data = bytes.ReplaceAll(data, []byte("object.spec.template.spec.template.spec"), specPrefix) + data = bytes.ReplaceAll(data, []byte("oldObject.spec.template.spec.template.spec"), append([]byte("oldObject"), specPrefix[6:]...)) + } + return data } diff --git a/test/conformance/chainsaw/validating-policies/autogen/autogen-deployments-cronjobs/bad-deployment.yaml b/test/conformance/chainsaw/validating-policies/autogen/autogen-deployments-cronjobs/bad-deployment.yaml index 3b0f87113d..1d87b43b17 100644 --- a/test/conformance/chainsaw/validating-policies/autogen/autogen-deployments-cronjobs/bad-deployment.yaml +++ b/test/conformance/chainsaw/validating-policies/autogen/autogen-deployments-cronjobs/bad-deployment.yaml @@ -22,3 +22,29 @@ spec: image: nginx:latest securityContext: allowPrivilegeEscalation: true +--- +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: bad-cronjob +spec: + schedule: "*/5 * * * *" + concurrencyPolicy: Forbid + jobTemplate: + metadata: + labels: + prod: "true" + spec: + template: + metadata: + labels: + prod: "true" + spec: + containers: + - name: secure-container + image: busybox + command: ["echo", "Hello, world"] + securityContext: + allowPrivilegeEscalation: true + restartPolicy: OnFailure \ No newline at end of file diff --git a/test/conformance/chainsaw/validating-policies/autogen/autogen-deployments-cronjobs/check-autogen.yaml b/test/conformance/chainsaw/validating-policies/autogen/autogen-deployments-cronjobs/check-autogen.yaml index ce899a4443..24c602e49c 100644 --- a/test/conformance/chainsaw/validating-policies/autogen/autogen-deployments-cronjobs/check-autogen.yaml +++ b/test/conformance/chainsaw/validating-policies/autogen/autogen-deployments-cronjobs/check-autogen.yaml @@ -1,51 +1,52 @@ apiVersion: policies.kyverno.io/v1alpha1 kind: ValidatingPolicy metadata: - name: disallow-privilege-escalation + name: disallow-privilege-escalation status: - autogen: - rules: - - matchConditions: - - expression: "!(object.kind =='Deployment' || object.kind =='ReplicaSet' || object.kind =='StatefulSet' || object.kind =='DaemonSet') || has(object.spec.template.metadata.labels) && has(object.spec.template.metadata.labels.prod) - && object.spec.template.metadata.labels.prod == 'true'" - name: autogen-check-prod-label - matchConstraints: - resourceRules: - - apiGroups: - - apps - apiVersions: - - v1 - operations: - - CREATE - - UPDATE - resources: - - deployments - validations: - - expression: object.spec.template.spec.containers.all(container, has(container.securityContext) - && has(container.securityContext.allowPrivilegeEscalation) && container.securityContext.allowPrivilegeEscalation - == false) - message: Privilege escalation is disallowed. The field spec.containers[*].securityContext.allowPrivilegeEscalation - must be set to `false`. - - matchConditions: - - expression: "!(object.kind =='CronJob') || has(object.spec.jobTemplate.spec.template.metadata.labels) - && has(object.spec.jobTemplate.spec.template.metadata.labels.prod) - && object.spec.jobTemplate.spec.template.metadata.labels.prod - == 'true'" - name: autogen-cronjobs-check-prod-label - matchConstraints: - resourceRules: - - apiGroups: - - batch - apiVersions: - - v1 - operations: - - CREATE - - UPDATE - resources: - - cronjobs - validations: - - expression: object.spec.jobTemplate.spec.template.spec.template.spec.containers.all(container, - has(container.securityContext) && has(container.securityContext.allowPrivilegeEscalation) - && container.securityContext.allowPrivilegeEscalation == false) - message: Privilege escalation is disallowed. The field spec.containers[*].securityContext.allowPrivilegeEscalation - must be set to `false`. + autogen: + rules: + - matchConditions: + - expression: '!(object.kind ==''Deployment'' || object.kind ==''ReplicaSet'' + || object.kind ==''StatefulSet'' || object.kind ==''DaemonSet'') || has(object.spec.template.metadata.labels) + && has(object.spec.template.metadata.labels.prod) && object.spec.template.metadata.labels.prod + == ''true''' + name: autogen-check-prod-label + matchConstraints: + resourceRules: + - apiGroups: + - apps + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - deployments + validations: + - expression: object.spec.template.spec.containers.all(container, has(container.securityContext) + && has(container.securityContext.allowPrivilegeEscalation) && container.securityContext.allowPrivilegeEscalation + == false) + message: Privilege escalation is disallowed. The field spec.containers[*].securityContext.allowPrivilegeEscalation + must be set to `false`. + - matchConditions: + - expression: '!(object.kind ==''CronJob'') || has(object.spec.jobTemplate.spec.template.metadata.labels) + && has(object.spec.jobTemplate.spec.template.metadata.labels.prod) && + object.spec.jobTemplate.spec.template.metadata.labels.prod == ''true''' + name: autogen-cronjobs-check-prod-label + matchConstraints: + resourceRules: + - apiGroups: + - batch + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - cronjobs + validations: + - expression: object.spec.jobTemplate.spec.template.spec.containers.all(container, + has(container.securityContext) && has(container.securityContext.allowPrivilegeEscalation) + && container.securityContext.allowPrivilegeEscalation == false) + message: Privilege escalation is disallowed. The field spec.containers[*].securityContext.allowPrivilegeEscalation + must be set to `false`. diff --git a/test/conformance/chainsaw/validating-policies/autogen/autogen-deployments-cronjobs/good-deployment.yaml b/test/conformance/chainsaw/validating-policies/autogen/autogen-deployments-cronjobs/good-deployment.yaml index 0e274974d1..4fe7ff79f0 100644 --- a/test/conformance/chainsaw/validating-policies/autogen/autogen-deployments-cronjobs/good-deployment.yaml +++ b/test/conformance/chainsaw/validating-policies/autogen/autogen-deployments-cronjobs/good-deployment.yaml @@ -22,3 +22,27 @@ spec: image: nginx:latest securityContext: allowPrivilegeEscalation: false +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: good-cronjob +spec: + schedule: "*/5 * * * *" + jobTemplate: + metadata: + labels: + prod: "true" + spec: + template: + metadata: + labels: + prod: "true" + spec: + containers: + - name: secure-container + image: busybox + command: ["echo", "Hello, world"] + securityContext: + allowPrivilegeEscalation: false + restartPolicy: OnFailure diff --git a/test/conformance/chainsaw/validating-policies/autogen/should-autogen/check-autogen.yaml b/test/conformance/chainsaw/validating-policies/autogen/should-autogen/check-autogen.yaml index b998041b65..ae382e6d9a 100644 --- a/test/conformance/chainsaw/validating-policies/autogen/should-autogen/check-autogen.yaml +++ b/test/conformance/chainsaw/validating-policies/autogen/should-autogen/check-autogen.yaml @@ -56,7 +56,7 @@ status: resources: - cronjobs validations: - - expression: object.spec.jobTemplate.spec.template.spec.template.spec.containers.all(container, + - expression: object.spec.jobTemplate.spec.template.spec.containers.all(container, has(container.securityContext) && has(container.securityContext.allowPrivilegeEscalation) && container.securityContext.allowPrivilegeEscalation == false) message: Privilege escalation is disallowed. The field spec.containers[*].securityContext.allowPrivilegeEscalation