mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-13 19:28:55 +00:00
properly deserialize anyPattern
This commit is contained in:
parent
365dd6e408
commit
943935ee1b
10 changed files with 115 additions and 31 deletions
2
Makefile
2
Makefile
|
@ -185,12 +185,10 @@ release:
|
|||
|
||||
kyverno-crd: controller-gen
|
||||
$(CONTROLLER_GEN) crd paths=./pkg/api/kyverno/v1alpha1 output:dir=./definitions/crds
|
||||
$(CONTROLLER_GEN) object paths=./pkg/api/kyverno/v1alpha1
|
||||
$(CONTROLLER_GEN) crd paths=./pkg/api/kyverno/v1 output:dir=./definitions/crds
|
||||
|
||||
report-crd: controller-gen
|
||||
$(CONTROLLER_GEN) crd paths=./pkg/api/policyreport/v1alpha1 output:dir=./definitions/crds
|
||||
$(CONTROLLER_GEN) object paths=./pkg/api/policyreport/v1alpha1
|
||||
|
||||
# find or download controller-gen
|
||||
# download controller-gen if necessary
|
||||
|
|
|
@ -1,12 +1,28 @@
|
|||
// +build !ignore_autogenerated
|
||||
|
||||
// Code generated by controller-gen. DO NOT EDIT.
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by deepcopy-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
policyreportv1alpha1 "github.com/kyverno/kyverno/pkg/api/policyreport/v1alpha1"
|
||||
"k8s.io/api/core/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
@ -38,6 +54,7 @@ func (in *ClusterReportChangeRequest) DeepCopyInto(out *ClusterReportChangeReque
|
|||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterReportChangeRequest.
|
||||
|
@ -70,6 +87,7 @@ func (in *ClusterReportChangeRequestList) DeepCopyInto(out *ClusterReportChangeR
|
|||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterReportChangeRequestList.
|
||||
|
@ -117,6 +135,7 @@ func (in *ReportChangeRequest) DeepCopyInto(out *ReportChangeRequest) {
|
|||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReportChangeRequest.
|
||||
|
@ -149,6 +168,7 @@ func (in *ReportChangeRequestList) DeepCopyInto(out *ReportChangeRequestList) {
|
|||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReportChangeRequestList.
|
||||
|
|
|
@ -1,11 +1,27 @@
|
|||
// +build !ignore_autogenerated
|
||||
|
||||
// Code generated by controller-gen. DO NOT EDIT.
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by deepcopy-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"k8s.io/api/core/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
@ -37,6 +53,7 @@ func (in *ClusterPolicyReport) DeepCopyInto(out *ClusterPolicyReport) {
|
|||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterPolicyReport.
|
||||
|
@ -69,6 +86,7 @@ func (in *ClusterPolicyReportList) DeepCopyInto(out *ClusterPolicyReportList) {
|
|||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterPolicyReportList.
|
||||
|
@ -116,6 +134,7 @@ func (in *PolicyReport) DeepCopyInto(out *PolicyReport) {
|
|||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PolicyReport.
|
||||
|
@ -148,6 +167,7 @@ func (in *PolicyReportList) DeepCopyInto(out *PolicyReportList) {
|
|||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PolicyReportList.
|
||||
|
@ -194,6 +214,7 @@ func (in *PolicyReportResult) DeepCopyInto(out *PolicyReportResult) {
|
|||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PolicyReportResult.
|
||||
|
@ -209,6 +230,7 @@ func (in *PolicyReportResult) DeepCopy() *PolicyReportResult {
|
|||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PolicyReportSummary) DeepCopyInto(out *PolicyReportSummary) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PolicyReportSummary.
|
||||
|
|
|
@ -291,7 +291,15 @@ func validatePatterns(log logr.Logger, ctx context.EvalInterface, resource unstr
|
|||
var failedSubstitutionsErrors []error
|
||||
var failedAnyPatternsErrors []error
|
||||
var err error
|
||||
for idx, pattern := range validationRule.AnyPattern {
|
||||
|
||||
anyPatterns, err := rule.Validation.DeserializeAnyPattern()
|
||||
if err != nil {
|
||||
resp.Success = false
|
||||
resp.Message = fmt.Sprintf("Failed to deserialze anyPattern, expect type array: %v", err)
|
||||
return resp
|
||||
}
|
||||
|
||||
for idx, pattern := range anyPatterns {
|
||||
if pattern, err = variables.SubstituteVars(logger, ctx, pattern); err != nil {
|
||||
// variable subsitution failed
|
||||
failedSubstitutionsErrors = append(failedSubstitutionsErrors, err)
|
||||
|
|
|
@ -48,14 +48,22 @@ func ContainsVariablesOtherThanObject(policy kyverno.ClusterPolicy) error {
|
|||
return fmt.Errorf("invalid variable used at spec/rules[%d]/validate/pattern", idx)
|
||||
}
|
||||
}
|
||||
for idx2, pattern := range rule.Validation.AnyPattern {
|
||||
if rule.Validation.AnyPattern[idx2], err = variables.SubstituteVars(log.Log, ctx, pattern); !checkNotFoundErr(err) {
|
||||
|
||||
anyPattern, err := rule.Validation.DeserializeAnyPattern()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to deserialze anyPattern, expect array: %v", err)
|
||||
}
|
||||
|
||||
for idx2, pattern := range anyPattern {
|
||||
if anyPattern[idx2], err = variables.SubstituteVars(log.Log, ctx, pattern); !checkNotFoundErr(err) {
|
||||
return fmt.Errorf("invalid variable used at spec/rules[%d]/validate/anyPattern[%d]", idx, idx2)
|
||||
}
|
||||
}
|
||||
|
||||
if _, err = variables.SubstituteVars(log.Log, ctx, rule.Validation.Message); !checkNotFoundErr(err) {
|
||||
return fmt.Errorf("invalid variable used at spec/rules[%d]/validate/message", idx)
|
||||
}
|
||||
|
||||
if rule.Validation.Deny != nil {
|
||||
for i := range rule.Validation.Deny.Conditions {
|
||||
if _, err = variables.SubstituteVars(log.Log, ctx, rule.Validation.Deny.Conditions[i].Key); !checkNotFoundErr(err) {
|
||||
|
@ -67,6 +75,7 @@ func ContainsVariablesOtherThanObject(policy kyverno.ClusterPolicy) error {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -7,16 +7,14 @@ import (
|
|||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/kyverno/kyverno/pkg/kyverno/common"
|
||||
|
||||
"github.com/minio/minio/pkg/wildcard"
|
||||
|
||||
"github.com/kyverno/kyverno/pkg/openapi"
|
||||
|
||||
kyverno "github.com/kyverno/kyverno/pkg/api/kyverno/v1"
|
||||
dclient "github.com/kyverno/kyverno/pkg/dclient"
|
||||
"github.com/kyverno/kyverno/pkg/kyverno/common"
|
||||
"github.com/kyverno/kyverno/pkg/openapi"
|
||||
"github.com/minio/minio/pkg/wildcard"
|
||||
rbacv1 "k8s.io/api/rbac/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
log "sigs.k8s.io/controller-runtime/pkg/log"
|
||||
)
|
||||
|
||||
// Validate does some initial check to verify some conditions
|
||||
|
@ -66,8 +64,8 @@ func Validate(policyRaw []byte, client *dclient.Client, mock bool, openAPIContro
|
|||
return fmt.Errorf("path: spec.rules[%d]: %v", i, err)
|
||||
}
|
||||
|
||||
// validate Cluster Resources in namespaced cluster policy
|
||||
// For namespaced cluster policy, ClusterResource type field and values are not allowed in match and exclude
|
||||
// validate Cluster Resources in namespaced policy
|
||||
// For namespaced policy, ClusterResource type field and values are not allowed in match and exclude
|
||||
if !mock && p.ObjectMeta.Namespace != "" {
|
||||
var Empty struct{}
|
||||
clusterResourcesMap := make(map[string]*struct{})
|
||||
|
@ -147,7 +145,7 @@ func checkInvalidFields(policyRaw []byte) error {
|
|||
}
|
||||
mapData := data.(map[string]interface{})
|
||||
// validate any new fields in the admission request against the supported fields and block the request with any new fields
|
||||
for requestField, _ := range mapData {
|
||||
for requestField := range mapData {
|
||||
ok := false
|
||||
for _, allowedField := range allowedKeys {
|
||||
if requestField == allowedField {
|
||||
|
@ -348,8 +346,13 @@ func isLabelAndAnnotationsString(rule kyverno.Rule) bool {
|
|||
patternMap, ok := rule.Validation.Pattern.(map[string]interface{})
|
||||
if ok {
|
||||
return checkMetadata(patternMap)
|
||||
} else if len(rule.Validation.AnyPattern) > 0 {
|
||||
anyPatterns := rule.Validation.AnyPattern
|
||||
} else if rule.Validation.AnyPattern != nil {
|
||||
anyPatterns, err := rule.Validation.DeserializeAnyPattern()
|
||||
if err != nil {
|
||||
log.Log.Error(err, "failed to deserialze anyPattern, expect type array")
|
||||
return false
|
||||
}
|
||||
|
||||
for _, pattern := range anyPatterns {
|
||||
patternMap, ok := pattern.(map[string]interface{})
|
||||
if ok {
|
||||
|
@ -384,7 +387,13 @@ func ruleOnlyDealsWithResourceMetaData(rule kyverno.Rule) bool {
|
|||
}
|
||||
}
|
||||
|
||||
for _, pattern := range rule.Validation.AnyPattern {
|
||||
anyPatterns, err := rule.Validation.DeserializeAnyPattern()
|
||||
if err != nil {
|
||||
log.Log.Error(err, "failed to deserialze anyPattern, expect type array")
|
||||
return false
|
||||
}
|
||||
|
||||
for _, pattern := range anyPatterns {
|
||||
patternMap, _ := pattern.(map[string]interface{})
|
||||
for k := range patternMap {
|
||||
if k != "metadata" {
|
||||
|
|
|
@ -36,8 +36,14 @@ func (v *Validate) Validate() (string, error) {
|
|||
}
|
||||
}
|
||||
|
||||
if len(rule.AnyPattern) != 0 {
|
||||
for i, pattern := range rule.AnyPattern {
|
||||
if rule.AnyPattern != nil {
|
||||
// validation := &kyverno.Validation{}
|
||||
// rule.DeepCopyInto(validation)
|
||||
anyPattern, err := rule.DeserializeAnyPattern()
|
||||
if err != nil {
|
||||
return "anyPattern", fmt.Errorf("failed to deserialze anyPattern, expect array: %v", err)
|
||||
}
|
||||
for i, pattern := range anyPattern {
|
||||
if path, err := common.ValidatePattern(pattern, "/", []commonAnchors.IsAnchor{commonAnchors.IsConditionAnchor, commonAnchors.IsExistenceAnchor, commonAnchors.IsEqualityAnchor, commonAnchors.IsNegationAnchor}); err != nil {
|
||||
return fmt.Sprintf("anyPattern[%d].%s", i, path), err
|
||||
}
|
||||
|
@ -49,11 +55,11 @@ func (v *Validate) Validate() (string, error) {
|
|||
// validateOverlayPattern checks one of pattern/anyPattern must exist
|
||||
func (v *Validate) validateOverlayPattern() error {
|
||||
rule := v.rule
|
||||
if rule.Pattern == nil && len(rule.AnyPattern) == 0 && rule.Deny == nil {
|
||||
if rule.Pattern == nil && rule.AnyPattern == nil && rule.Deny == nil {
|
||||
return fmt.Errorf("pattern, anyPattern or deny must be specified")
|
||||
}
|
||||
|
||||
if rule.Pattern != nil && len(rule.AnyPattern) != 0 {
|
||||
if rule.Pattern != nil && rule.AnyPattern != nil {
|
||||
return fmt.Errorf("only one operation allowed per validation rule(pattern or anyPattern)")
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ func generateCronJobRule(rule kyverno.Rule, controllers string, log logr.Logger)
|
|||
return kyvernoRule{}
|
||||
}
|
||||
|
||||
logger.V(3).Info("")
|
||||
logger.V(3).Info("generating rule for cronJob")
|
||||
jobRule := generateRuleForControllers(rule, "Job", logger)
|
||||
|
||||
if reflect.DeepEqual(jobRule, kyvernoRule{}) {
|
||||
|
@ -70,9 +70,14 @@ func generateCronJobRule(rule kyverno.Rule, controllers string, log logr.Logger)
|
|||
return *cronJobRule
|
||||
}
|
||||
|
||||
if (jobRule.Validation != nil) && (len(jobRule.Validation.AnyPattern) != 0) {
|
||||
if (jobRule.Validation != nil) && (jobRule.Validation.AnyPattern != nil) {
|
||||
var patterns []interface{}
|
||||
for _, pattern := range jobRule.Validation.AnyPattern {
|
||||
anyPatterns, err := rule.Validation.DeserializeAnyPattern()
|
||||
if err != nil {
|
||||
logger.Error(err, "failed to deserialze anyPattern, expect tyepe array")
|
||||
}
|
||||
|
||||
for _, pattern := range anyPatterns {
|
||||
newPattern := map[string]interface{}{
|
||||
"spec": map[string]interface{}{
|
||||
"jobTemplate": pattern,
|
||||
|
|
|
@ -467,9 +467,14 @@ func generateRuleForControllers(rule kyverno.Rule, controllers string, log logr.
|
|||
return *controllerRule
|
||||
}
|
||||
|
||||
if len(rule.Validation.AnyPattern) != 0 {
|
||||
if rule.Validation.AnyPattern != nil {
|
||||
var patterns []interface{}
|
||||
for _, pattern := range rule.Validation.AnyPattern {
|
||||
anyPatterns, err := rule.Validation.DeserializeAnyPattern()
|
||||
if err != nil {
|
||||
logger.Error(err, "failed to deserialze anyPattern, expect type array")
|
||||
}
|
||||
|
||||
for _, pattern := range anyPatterns {
|
||||
newPattern := map[string]interface{}{
|
||||
"spec": map[string]interface{}{
|
||||
"template": pattern,
|
||||
|
|
|
@ -297,7 +297,9 @@ func (gen *Generator) sync(reportReq *unstructured.Unstructured, info Info) erro
|
|||
if err != nil {
|
||||
if apierrors.IsNotFound(err) {
|
||||
if _, err = gen.dclient.CreateResource(reportReq.GetAPIVersion(), reportReq.GetKind(), config.KubePolicyNamespace, reportReq, false); err != nil {
|
||||
return fmt.Errorf("failed to create ReportChangeRequest: %v", err)
|
||||
if !apierrors.IsNotFound(err) {
|
||||
return fmt.Errorf("failed to create ReportChangeRequest: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
logger.V(3).Info("successfully created reportChangeRequest", "name", reportReq.GetName())
|
||||
|
|
Loading…
Add table
Reference in a new issue