mirror of
https://github.com/kyverno/kyverno.git
synced 2024-12-15 17:51:20 +00:00
fix: return skip when celPreconditions/matchConditions aren't met (#9940)
* fix: return skip when cel preconditions aren't met Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com> * fix test Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com> * fix: return skip when matchConditions in VAPs aren't met Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com> --------- Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com>
This commit is contained in:
parent
dbc12ac2be
commit
798950f72c
8 changed files with 224 additions and 13 deletions
|
@ -12,6 +12,7 @@ import (
|
|||
"github.com/kyverno/kyverno/pkg/engine/internal"
|
||||
engineutils "github.com/kyverno/kyverno/pkg/engine/utils"
|
||||
celutils "github.com/kyverno/kyverno/pkg/utils/cel"
|
||||
datautils "github.com/kyverno/kyverno/pkg/utils/data"
|
||||
vaputils "github.com/kyverno/kyverno/pkg/validatingadmissionpolicy"
|
||||
admissionregistrationv1alpha1 "k8s.io/api/admissionregistration/v1alpha1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
|
@ -173,6 +174,13 @@ func (h validateCELHandler) Process(
|
|||
}
|
||||
|
||||
for _, validationResult := range validationResults {
|
||||
// no validations are returned if preconditions aren't met
|
||||
if datautils.DeepEqual(validationResult, validatingadmissionpolicy.ValidateResult{}) {
|
||||
return resource, handlers.WithResponses(
|
||||
engineapi.RuleSkip(rule.Name, engineapi.Validation, "cel preconditions not met"),
|
||||
)
|
||||
}
|
||||
|
||||
for _, decision := range validationResult.Decisions {
|
||||
switch decision.Action {
|
||||
case validatingadmissionpolicy.ActionAdmit:
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"github.com/kyverno/kyverno/pkg/clients/dclient"
|
||||
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
||||
celutils "github.com/kyverno/kyverno/pkg/utils/cel"
|
||||
datautils "github.com/kyverno/kyverno/pkg/utils/data"
|
||||
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
|
||||
"golang.org/x/text/cases"
|
||||
"golang.org/x/text/language"
|
||||
|
@ -224,6 +225,10 @@ func validateResource(
|
|||
versionedAttr, _ := admission.NewVersionedAttributes(a, a.GetKind(), nil)
|
||||
validateResult := validator.Validate(context.TODO(), a.GetResource(), versionedAttr, nil, &namespace, celconfig.RuntimeCELCostBudget, nil)
|
||||
|
||||
// no validations are returned if match conditions aren't met
|
||||
if datautils.DeepEqual(validateResult, validatingadmissionpolicy.ValidateResult{}) {
|
||||
ruleResp = engineapi.RuleSkip(policy.GetName(), engineapi.Validation, "match conditions aren't met")
|
||||
} else {
|
||||
isPass := true
|
||||
for _, policyDecision := range validateResult.Decisions {
|
||||
if policyDecision.Evaluation == validatingadmissionpolicy.EvalError {
|
||||
|
@ -240,6 +245,7 @@ func validateResource(
|
|||
if isPass {
|
||||
ruleResp = engineapi.RulePass(policy.GetName(), engineapi.Validation, "")
|
||||
}
|
||||
}
|
||||
|
||||
if binding != nil {
|
||||
ruleResp = ruleResp.WithBinding(binding)
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
apiVersion: admissionregistration.k8s.io/v1alpha1
|
||||
kind: ValidatingAdmissionPolicy
|
||||
metadata:
|
||||
name: "disallow-host-path"
|
||||
spec:
|
||||
matchConstraints:
|
||||
resourceRules:
|
||||
- apiGroups: [""]
|
||||
apiVersions: ["v1"]
|
||||
operations: ["CREATE", "UPDATE"]
|
||||
resources: ["pods"]
|
||||
matchConditions:
|
||||
- expression: "object.metadata.labels['color'] == 'red'"
|
||||
name: "red-label"
|
||||
validations:
|
||||
- expression: "!has(object.spec.volumes) || object.spec.volumes.all(volume, !has(volume.hostPath))"
|
||||
message: "HostPath volumes are forbidden. The field spec.volumes[*].hostPath must be unset."
|
|
@ -0,0 +1,27 @@
|
|||
apiVersion: cli.kyverno.io/v1alpha1
|
||||
kind: Test
|
||||
metadata:
|
||||
name: kyverno-test.yaml
|
||||
policies:
|
||||
- disallow-host-path.yaml
|
||||
resources:
|
||||
- resources.yaml
|
||||
results:
|
||||
- isValidatingAdmissionPolicy: true
|
||||
kind: Pod
|
||||
policy: disallow-host-path
|
||||
resources:
|
||||
- bad-pod
|
||||
result: fail
|
||||
- isValidatingAdmissionPolicy: true
|
||||
kind: Pod
|
||||
policy: disallow-host-path
|
||||
resources:
|
||||
- good-pod
|
||||
result: pass
|
||||
- isValidatingAdmissionPolicy: true
|
||||
kind: Pod
|
||||
policy: disallow-host-path
|
||||
resources:
|
||||
- skipped-pod
|
||||
result: skip
|
|
@ -0,0 +1,52 @@
|
|||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: skipped-pod
|
||||
labels:
|
||||
color: blue
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx-container
|
||||
image: nginx:latest
|
||||
volumeMounts:
|
||||
- name: hostpath-volume
|
||||
mountPath: /var/www/html
|
||||
volumes:
|
||||
- name: hostpath-volume
|
||||
hostPath:
|
||||
path: /var/log
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: bad-pod
|
||||
labels:
|
||||
color: red
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx-container
|
||||
image: nginx:latest
|
||||
volumeMounts:
|
||||
- name: hostpath-volume
|
||||
mountPath: /var/www/html
|
||||
volumes:
|
||||
- name: hostpath-volume
|
||||
hostPath:
|
||||
path: /var/log
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: good-pod
|
||||
labels:
|
||||
color: red
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx-container
|
||||
image: nginx:latest
|
||||
volumeMounts:
|
||||
- name: hostpath-volume
|
||||
mountPath: /var/www/html
|
||||
volumes:
|
||||
- name: hostpath-volume
|
||||
emptyDir: {}
|
22
test/cli/test/cel-preconditions/disallow-host-path.yaml
Normal file
22
test/cli/test/cel-preconditions/disallow-host-path.yaml
Normal file
|
@ -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:
|
||||
- Pod
|
||||
celPreconditions:
|
||||
- expression: "object.metadata.labels['color'] == 'red'"
|
||||
name: "Label should be red"
|
||||
validate:
|
||||
cel:
|
||||
expressions:
|
||||
- expression: "!has(object.spec.volumes) || object.spec.volumes.all(volume, !has(volume.hostPath))"
|
||||
message: "HostPath volumes are forbidden. The field spec.volumes[*].hostPath must be unset."
|
27
test/cli/test/cel-preconditions/kyverno-test.yaml
Normal file
27
test/cli/test/cel-preconditions/kyverno-test.yaml
Normal file
|
@ -0,0 +1,27 @@
|
|||
apiVersion: cli.kyverno.io/v1alpha1
|
||||
kind: Test
|
||||
metadata:
|
||||
name: kyverno-test.yaml
|
||||
policies:
|
||||
- disallow-host-path.yaml
|
||||
resources:
|
||||
- resources.yaml
|
||||
results:
|
||||
- kind: Pod
|
||||
policy: disallow-host-path
|
||||
resources:
|
||||
- bad-pod
|
||||
result: fail
|
||||
rule: host-path
|
||||
- kind: Pod
|
||||
policy: disallow-host-path
|
||||
resources:
|
||||
- good-pod
|
||||
result: pass
|
||||
rule: host-path
|
||||
- kind: Pod
|
||||
policy: disallow-host-path
|
||||
resources:
|
||||
- skipped-pod
|
||||
result: skip
|
||||
rule: host-path
|
52
test/cli/test/cel-preconditions/resources.yaml
Normal file
52
test/cli/test/cel-preconditions/resources.yaml
Normal file
|
@ -0,0 +1,52 @@
|
|||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: skipped-pod
|
||||
labels:
|
||||
color: blue
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx-container
|
||||
image: nginx:latest
|
||||
volumeMounts:
|
||||
- name: hostpath-volume
|
||||
mountPath: /var/www/html
|
||||
volumes:
|
||||
- name: hostpath-volume
|
||||
hostPath:
|
||||
path: /var/log
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: bad-pod
|
||||
labels:
|
||||
color: red
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx-container
|
||||
image: nginx:latest
|
||||
volumeMounts:
|
||||
- name: hostpath-volume
|
||||
mountPath: /var/www/html
|
||||
volumes:
|
||||
- name: hostpath-volume
|
||||
hostPath:
|
||||
path: /var/log
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: good-pod
|
||||
labels:
|
||||
color: red
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx-container
|
||||
image: nginx:latest
|
||||
volumeMounts:
|
||||
- name: hostpath-volume
|
||||
mountPath: /var/www/html
|
||||
volumes:
|
||||
- name: hostpath-volume
|
||||
emptyDir: {}
|
Loading…
Reference in a new issue