diff --git a/definitions/install.yaml b/definitions/install.yaml index d2b2e6cb36..e06d4f49f9 100644 --- a/definitions/install.yaml +++ b/definitions/install.yaml @@ -145,13 +145,13 @@ spec: AnyValue: {} validate: type: object - required: - - pattern properties: message: type: string pattern: AnyValue: {} + anyPattern: + AnyValue: {} generate: type: object required: diff --git a/definitions/install_debug.yaml b/definitions/install_debug.yaml index 7a7cb7c95d..918da0c354 100644 --- a/definitions/install_debug.yaml +++ b/definitions/install_debug.yaml @@ -145,13 +145,13 @@ spec: AnyValue: {} validate: type: object - required: - - pattern properties: message: type: string pattern: AnyValue: {} + anyPattern: + AnyValue: {} generate: type: object required: diff --git a/pkg/api/kyverno/v1alpha1/types.go b/pkg/api/kyverno/v1alpha1/types.go index 5597f97e23..bcf813d0d4 100644 --- a/pkg/api/kyverno/v1alpha1/types.go +++ b/pkg/api/kyverno/v1alpha1/types.go @@ -68,8 +68,9 @@ type Patch struct { // Validation describes the way how Validating Webhook will check the resource on creation type Validation struct { - Message string `json:"message"` - Pattern interface{} `json:"pattern"` + Message string `json:"message"` + Pattern interface{} `json:"pattern"` + AnyPattern []interface{} `json:"anyPattern"` } // Generation describes which resources will be created when other resource is created diff --git a/pkg/webhooks/policyvalidation.go b/pkg/webhooks/policyvalidation.go index abeca02c76..331210a6ac 100644 --- a/pkg/webhooks/policyvalidation.go +++ b/pkg/webhooks/policyvalidation.go @@ -3,6 +3,7 @@ package webhooks import ( "encoding/json" "fmt" + "reflect" "github.com/golang/glog" kyverno "github.com/nirmata/kyverno/pkg/api/kyverno/v1alpha1" @@ -28,7 +29,7 @@ func (ws *WebhookServer) HandlePolicyValidation(request *v1beta1.AdmissionReques } if request.Operation != v1beta1.Delete { - admissionResp = ws.validateUniqueRuleName(policy) + admissionResp = ws.validatePolicy(policy) } if admissionResp.Allowed { @@ -38,6 +39,32 @@ func (ws *WebhookServer) HandlePolicyValidation(request *v1beta1.AdmissionReques return admissionResp } +func (ws *WebhookServer) validatePolicy(policy *kyverno.Policy) *v1beta1.AdmissionResponse { + admissionResp := ws.validateUniqueRuleName(policy) + if !admissionResp.Allowed { + return admissionResp + } + + return ws.validateOverlayPattern(policy) +} + +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", + }, + } + } + } + } + + return &v1beta1.AdmissionResponse{Allowed: true} +} + // Verify if the Rule names are unique within a policy func (ws *WebhookServer) validateUniqueRuleName(policy *kyverno.Policy) *v1beta1.AdmissionResponse { // =======