mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-28 10:28:36 +00:00
add anyPattern in validate rule
This commit is contained in:
parent
124b105736
commit
97335270cd
4 changed files with 81 additions and 63 deletions
|
@ -1,22 +1,27 @@
|
|||
apiVersion : kyverno.io/v1alpha1
|
||||
apiVersion: kyverno.io/v1alpha1
|
||||
kind: Policy
|
||||
metadata:
|
||||
name: policy-security-context
|
||||
name: check-container-security-context
|
||||
spec:
|
||||
# validationFailureAction: "audit"
|
||||
rules:
|
||||
- name: validate-runAsNonRoot
|
||||
- name: check-root-user
|
||||
exclude:
|
||||
resources:
|
||||
namespaces:
|
||||
- kube-system
|
||||
match:
|
||||
resources:
|
||||
kinds:
|
||||
- Deployment
|
||||
selector :
|
||||
matchLabels:
|
||||
test: psp
|
||||
- Pod
|
||||
validate:
|
||||
message: "security context 'runAsNonRoot' shoud be set to true"
|
||||
pattern:
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
message: "Root user is not allowed. Set runAsNonRoot to true."
|
||||
anyPattern:
|
||||
- spec:
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
- spec:
|
||||
containers:
|
||||
- name: "*"
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
|
@ -1,21 +1,10 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: psp-demo-unprivileged
|
||||
labels:
|
||||
test: psp
|
||||
name: sec-ctx-unprivileged
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
test: psp
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
test: psp
|
||||
spec:
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
containers:
|
||||
- name: sec-ctx-unprivileged
|
||||
image: nginxinc/nginx-unprivileged
|
||||
# securityContext:
|
||||
# runAsNonRoot: true
|
||||
containers:
|
||||
- name: imagen-with-hostpath
|
||||
image: nginxinc/nginx-unprivileged
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package engine
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
|
@ -18,18 +17,6 @@ import (
|
|||
// Validate handles validating admission request
|
||||
// Checks the target resources for rules defined in the policy
|
||||
func Validate(policy kyverno.Policy, resource unstructured.Unstructured) EngineResponse {
|
||||
resourceRaw, err := resource.MarshalJSON()
|
||||
if err != nil {
|
||||
glog.V(4).Infof("Skip processing validating rule, unable to marshal resource : %v\n", err)
|
||||
return EngineResponse{PatchedResource: resource}
|
||||
}
|
||||
|
||||
var resourceInt interface{}
|
||||
if err := json.Unmarshal(resourceRaw, &resourceInt); err != nil {
|
||||
glog.V(4).Infof("unable to unmarshal resource : %v\n", err)
|
||||
return EngineResponse{PatchedResource: resource}
|
||||
}
|
||||
|
||||
var ruleInfos []info.RuleInfo
|
||||
|
||||
for _, rule := range policy.Spec.Rules {
|
||||
|
@ -46,22 +33,54 @@ func Validate(policy kyverno.Policy, resource unstructured.Unstructured) EngineR
|
|||
continue
|
||||
}
|
||||
|
||||
ruleInfo := info.NewRuleInfo(rule.Name, info.Validation)
|
||||
|
||||
err := validateResourceWithPattern(resourceInt, rule.Validation.Pattern)
|
||||
if err != nil {
|
||||
ruleInfo.Fail()
|
||||
ruleInfo.Addf("Failed to apply pattern: %v.", err)
|
||||
} else {
|
||||
ruleInfo.Add("Pattern succesfully validated")
|
||||
glog.V(4).Infof("pattern validated succesfully on resource %s/%s", resource.GetNamespace(), resource.GetName())
|
||||
}
|
||||
ruleInfo := validatePatterns(resource, rule.Validation, rule.Name)
|
||||
ruleInfos = append(ruleInfos, ruleInfo)
|
||||
}
|
||||
|
||||
return EngineResponse{RuleInfos: ruleInfos}
|
||||
}
|
||||
|
||||
// validatePatterns validate pattern and anyPattern
|
||||
func validatePatterns(resource unstructured.Unstructured, validation kyverno.Validation, ruleName string) info.RuleInfo {
|
||||
var errs []error
|
||||
ruleInfo := info.NewRuleInfo(ruleName, info.Validation)
|
||||
|
||||
if validation.Pattern != nil {
|
||||
err := validateResourceWithPattern(resource.Object, validation.Pattern)
|
||||
if err != nil {
|
||||
ruleInfo.Fail()
|
||||
ruleInfo.Addf("Failed to apply pattern: %v", err)
|
||||
} else {
|
||||
ruleInfo.Add("Pattern succesfully validated")
|
||||
glog.V(4).Infof("pattern validated succesfully on resource %s/%s", resource.GetNamespace(), resource.GetName())
|
||||
}
|
||||
return ruleInfo
|
||||
}
|
||||
|
||||
if validation.AnyPattern != nil {
|
||||
for _, pattern := range validation.AnyPattern {
|
||||
if err := validateResourceWithPattern(resource.Object, pattern); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
}
|
||||
|
||||
failedPattern := len(errs)
|
||||
patterns := len(validation.AnyPattern)
|
||||
|
||||
// all pattern fail
|
||||
if failedPattern == patterns {
|
||||
ruleInfo.Fail()
|
||||
ruleInfo.Addf("None of anyPattern succeed: %v", errs)
|
||||
} else {
|
||||
ruleInfo.Addf("%d/%d patterns succesfully validated", patterns-failedPattern, patterns)
|
||||
glog.V(4).Infof("%d/%d patterns validated succesfully on resource %s/%s", patterns-failedPattern, patterns, resource.GetNamespace(), resource.GetName())
|
||||
}
|
||||
return ruleInfo
|
||||
}
|
||||
|
||||
return info.RuleInfo{}
|
||||
}
|
||||
|
||||
// validateResourceWithPattern is a start of element-by-element validation process
|
||||
// It assumes that validation is started from root, so "/" is passed
|
||||
func validateResourceWithPattern(resource, pattern interface{}) error {
|
||||
|
|
|
@ -25,7 +25,10 @@ func (ws *WebhookServer) HandlePolicyValidation(request *v1beta1.AdmissionReques
|
|||
}
|
||||
if err := json.Unmarshal(raw, &policy); err != nil {
|
||||
glog.Errorf("Failed to unmarshal policy admission request, err %v\n", err)
|
||||
return &v1beta1.AdmissionResponse{Allowed: false}
|
||||
return &v1beta1.AdmissionResponse{Allowed: false,
|
||||
Result: &metav1.Status{
|
||||
Message: fmt.Sprintf("Failed to unmarshal policy admission request err %v", err),
|
||||
}}
|
||||
}
|
||||
|
||||
if request.Operation != v1beta1.Delete {
|
||||
|
@ -50,14 +53,16 @@ func (ws *WebhookServer) validatePolicy(policy *kyverno.Policy) *v1beta1.Admissi
|
|||
|
||||
func (ws *WebhookServer) validateOverlayPattern(policy *kyverno.Policy) *v1beta1.AdmissionResponse {
|
||||
for _, rule := range policy.Spec.Rules {
|
||||
if !reflect.DeepEqual(rule.Validation, kyverno.Validation{}) {
|
||||
if rule.Validation.Pattern == nil && rule.Validation.AnyPattern == nil {
|
||||
return &v1beta1.AdmissionResponse{
|
||||
Allowed: false,
|
||||
Result: &metav1.Status{
|
||||
Message: "Invalid policy, either pattern or anyPattern found in policy spec",
|
||||
},
|
||||
}
|
||||
if reflect.DeepEqual(rule.Validation, kyverno.Validation{}) {
|
||||
continue
|
||||
}
|
||||
|
||||
if rule.Validation.Pattern == nil && len(rule.Validation.AnyPattern) == 0 {
|
||||
return &v1beta1.AdmissionResponse{
|
||||
Allowed: false,
|
||||
Result: &metav1.Status{
|
||||
Message: fmt.Sprintf("Invalid policy, neither pattern nor anyPattern found in validate rule %s", rule.Name),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue