mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-22 07:41:10 +00:00
solves the cronjob autogen nested path issue (#12383)
* solves the cronjob autogen nested path issue Signed-off-by: Mohd Kamaal <mohdkamaal2019@gmail.com> * format the file using linter Signed-off-by: Mohd Kamaal <mohdkamaal2019@gmail.com> * autogen path change in validating-polcies Signed-off-by: Mohd Kamaal <mohdcode@MBA.local> --------- Signed-off-by: Mohd Kamaal <mohdkamaal2019@gmail.com> Signed-off-by: Mohd Kamaal <mohdcode@MBA.local> Co-authored-by: Mohd Kamaal <mohdcode@MBA.local>
This commit is contained in:
parent
7e3dfd934e
commit
19b816ba70
5 changed files with 121 additions and 67 deletions
|
@ -152,19 +152,6 @@ func convertMatchconditions(conditions []admissionregistrationv1.MatchCondition,
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
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-"
|
podControllerMatchConditionName = "autogen-"
|
||||||
podControllersMatchConditionExpression = "!(object.kind =='Deployment' || object.kind =='ReplicaSet' || object.kind =='StatefulSet' || object.kind =='DaemonSet') || "
|
podControllersMatchConditionExpression = "!(object.kind =='Deployment' || object.kind =='ReplicaSet' || object.kind =='StatefulSet' || object.kind =='DaemonSet') || "
|
||||||
cronjobMatchConditionName = "autogen-cronjobs-"
|
cronjobMatchConditionName = "autogen-cronjobs-"
|
||||||
|
@ -172,15 +159,31 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
func updateFields(data []byte, resource autogencontroller) []byte {
|
func updateFields(data []byte, resource autogencontroller) []byte {
|
||||||
|
// Define the target prefixes based on resource type
|
||||||
|
var specPrefix, metadataPrefix []byte
|
||||||
switch resource {
|
switch resource {
|
||||||
case PODS:
|
case PODS:
|
||||||
for _, replacement := range podReplacementRules {
|
specPrefix = []byte("object.spec.template.spec")
|
||||||
data = bytes.ReplaceAll(data, replacement[0], replacement[1])
|
metadataPrefix = []byte("object.spec.template.metadata")
|
||||||
}
|
|
||||||
case CRONJOBS:
|
case CRONJOBS:
|
||||||
for _, replacement := range cronJobReplacementRules {
|
specPrefix = []byte("object.spec.jobTemplate.spec.template.spec")
|
||||||
data = bytes.ReplaceAll(data, replacement[0], replacement[1])
|
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
|
return data
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,3 +22,29 @@ spec:
|
||||||
image: nginx:latest
|
image: nginx:latest
|
||||||
securityContext:
|
securityContext:
|
||||||
allowPrivilegeEscalation: true
|
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
|
|
@ -1,51 +1,52 @@
|
||||||
apiVersion: policies.kyverno.io/v1alpha1
|
apiVersion: policies.kyverno.io/v1alpha1
|
||||||
kind: ValidatingPolicy
|
kind: ValidatingPolicy
|
||||||
metadata:
|
metadata:
|
||||||
name: disallow-privilege-escalation
|
name: disallow-privilege-escalation
|
||||||
status:
|
status:
|
||||||
autogen:
|
autogen:
|
||||||
rules:
|
rules:
|
||||||
- matchConditions:
|
- 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)
|
- expression: '!(object.kind ==''Deployment'' || object.kind ==''ReplicaSet''
|
||||||
&& object.spec.template.metadata.labels.prod == 'true'"
|
|| object.kind ==''StatefulSet'' || object.kind ==''DaemonSet'') || has(object.spec.template.metadata.labels)
|
||||||
name: autogen-check-prod-label
|
&& has(object.spec.template.metadata.labels.prod) && object.spec.template.metadata.labels.prod
|
||||||
matchConstraints:
|
== ''true'''
|
||||||
resourceRules:
|
name: autogen-check-prod-label
|
||||||
- apiGroups:
|
matchConstraints:
|
||||||
- apps
|
resourceRules:
|
||||||
apiVersions:
|
- apiGroups:
|
||||||
- v1
|
- apps
|
||||||
operations:
|
apiVersions:
|
||||||
- CREATE
|
- v1
|
||||||
- UPDATE
|
operations:
|
||||||
resources:
|
- CREATE
|
||||||
- deployments
|
- UPDATE
|
||||||
validations:
|
resources:
|
||||||
- expression: object.spec.template.spec.containers.all(container, has(container.securityContext)
|
- deployments
|
||||||
&& has(container.securityContext.allowPrivilegeEscalation) && container.securityContext.allowPrivilegeEscalation
|
validations:
|
||||||
== false)
|
- expression: object.spec.template.spec.containers.all(container, has(container.securityContext)
|
||||||
message: Privilege escalation is disallowed. The field spec.containers[*].securityContext.allowPrivilegeEscalation
|
&& has(container.securityContext.allowPrivilegeEscalation) && container.securityContext.allowPrivilegeEscalation
|
||||||
must be set to `false`.
|
== false)
|
||||||
- matchConditions:
|
message: Privilege escalation is disallowed. The field spec.containers[*].securityContext.allowPrivilegeEscalation
|
||||||
- expression: "!(object.kind =='CronJob') || has(object.spec.jobTemplate.spec.template.metadata.labels)
|
must be set to `false`.
|
||||||
&& has(object.spec.jobTemplate.spec.template.metadata.labels.prod)
|
- matchConditions:
|
||||||
&& object.spec.jobTemplate.spec.template.metadata.labels.prod
|
- expression: '!(object.kind ==''CronJob'') || has(object.spec.jobTemplate.spec.template.metadata.labels)
|
||||||
== 'true'"
|
&& has(object.spec.jobTemplate.spec.template.metadata.labels.prod) &&
|
||||||
name: autogen-cronjobs-check-prod-label
|
object.spec.jobTemplate.spec.template.metadata.labels.prod == ''true'''
|
||||||
matchConstraints:
|
name: autogen-cronjobs-check-prod-label
|
||||||
resourceRules:
|
matchConstraints:
|
||||||
- apiGroups:
|
resourceRules:
|
||||||
- batch
|
- apiGroups:
|
||||||
apiVersions:
|
- batch
|
||||||
- v1
|
apiVersions:
|
||||||
operations:
|
- v1
|
||||||
- CREATE
|
operations:
|
||||||
- UPDATE
|
- CREATE
|
||||||
resources:
|
- UPDATE
|
||||||
- cronjobs
|
resources:
|
||||||
validations:
|
- cronjobs
|
||||||
- expression: object.spec.jobTemplate.spec.template.spec.template.spec.containers.all(container,
|
validations:
|
||||||
has(container.securityContext) && has(container.securityContext.allowPrivilegeEscalation)
|
- expression: object.spec.jobTemplate.spec.template.spec.containers.all(container,
|
||||||
&& container.securityContext.allowPrivilegeEscalation == false)
|
has(container.securityContext) && has(container.securityContext.allowPrivilegeEscalation)
|
||||||
message: Privilege escalation is disallowed. The field spec.containers[*].securityContext.allowPrivilegeEscalation
|
&& container.securityContext.allowPrivilegeEscalation == false)
|
||||||
must be set to `false`.
|
message: Privilege escalation is disallowed. The field spec.containers[*].securityContext.allowPrivilegeEscalation
|
||||||
|
must be set to `false`.
|
||||||
|
|
|
@ -22,3 +22,27 @@ spec:
|
||||||
image: nginx:latest
|
image: nginx:latest
|
||||||
securityContext:
|
securityContext:
|
||||||
allowPrivilegeEscalation: false
|
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
|
||||||
|
|
|
@ -56,7 +56,7 @@ status:
|
||||||
resources:
|
resources:
|
||||||
- cronjobs
|
- cronjobs
|
||||||
validations:
|
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)
|
has(container.securityContext) && has(container.securityContext.allowPrivilegeEscalation)
|
||||||
&& container.securityContext.allowPrivilegeEscalation == false)
|
&& container.securityContext.allowPrivilegeEscalation == false)
|
||||||
message: Privilege escalation is disallowed. The field spec.containers[*].securityContext.allowPrivilegeEscalation
|
message: Privilege escalation is disallowed. The field spec.containers[*].securityContext.allowPrivilegeEscalation
|
||||||
|
|
Loading…
Add table
Reference in a new issue