mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-14 11:48:53 +00:00
feat: use pointer in rule (validate field) (#11095)
Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
This commit is contained in:
parent
a170b736d2
commit
b463ee40d2
16 changed files with 206 additions and 201 deletions
|
@ -93,7 +93,7 @@ type Rule struct {
|
||||||
|
|
||||||
// Validation is used to validate matching resources.
|
// Validation is used to validate matching resources.
|
||||||
// +optional
|
// +optional
|
||||||
Validation Validation `json:"validate,omitempty"`
|
Validation *Validation `json:"validate,omitempty"`
|
||||||
|
|
||||||
// Generation is used to create new resources.
|
// Generation is used to create new resources.
|
||||||
// +optional
|
// +optional
|
||||||
|
@ -164,35 +164,33 @@ func (r *Rule) HasVerifyImageChecks() bool {
|
||||||
|
|
||||||
// HasVerifyManifests checks for validate.manifests rule
|
// HasVerifyManifests checks for validate.manifests rule
|
||||||
func (r Rule) HasVerifyManifests() bool {
|
func (r Rule) HasVerifyManifests() bool {
|
||||||
return r.Validation.Manifests != nil && len(r.Validation.Manifests.Attestors) != 0
|
return r.Validation != nil && r.Validation.Manifests != nil && len(r.Validation.Manifests.Attestors) != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// HasValidatePodSecurity checks for validate.podSecurity rule
|
// HasValidatePodSecurity checks for validate.podSecurity rule
|
||||||
func (r Rule) HasValidatePodSecurity() bool {
|
func (r Rule) HasValidatePodSecurity() bool {
|
||||||
return r.Validation.PodSecurity != nil && !datautils.DeepEqual(r.Validation.PodSecurity, &PodSecurity{})
|
return r.Validation != nil && r.Validation.PodSecurity != nil && !datautils.DeepEqual(*r.Validation.PodSecurity, PodSecurity{})
|
||||||
}
|
}
|
||||||
|
|
||||||
// HasValidateCEL checks for validate.cel rule
|
// HasValidateCEL checks for validate.cel rule
|
||||||
func (r *Rule) HasValidateCEL() bool {
|
func (r *Rule) HasValidateCEL() bool {
|
||||||
return r.Validation.CEL != nil && !datautils.DeepEqual(r.Validation.CEL, &CEL{})
|
return r.Validation != nil && r.Validation.CEL != nil && !datautils.DeepEqual(*r.Validation.CEL, CEL{})
|
||||||
}
|
}
|
||||||
|
|
||||||
// HasValidateAssert checks for validate.assert rule
|
// HasValidateAssert checks for validate.assert rule
|
||||||
func (r *Rule) HasValidateAssert() bool {
|
func (r *Rule) HasValidateAssert() bool {
|
||||||
return !datautils.DeepEqual(r.Validation.Assert, AssertionTree{})
|
return r.Validation != nil && !datautils.DeepEqual(r.Validation.Assert, AssertionTree{})
|
||||||
}
|
}
|
||||||
|
|
||||||
// HasValidate checks for validate rule
|
// HasValidate checks for validate rule
|
||||||
func (r *Rule) HasValidate() bool {
|
func (r *Rule) HasValidate() bool {
|
||||||
return !datautils.DeepEqual(r.Validation, Validation{})
|
return r.Validation != nil && !datautils.DeepEqual(*r.Validation, Validation{})
|
||||||
}
|
}
|
||||||
|
|
||||||
// HasValidateAllowExistingViolations() checks for allowExisitingViolations under validate rule
|
// HasValidateAllowExistingViolations() checks for allowExisitingViolations under validate rule
|
||||||
func (r *Rule) HasValidateAllowExistingViolations() bool {
|
func (r *Rule) HasValidateAllowExistingViolations() bool {
|
||||||
var allowExisitingViolations bool
|
allowExisitingViolations := true
|
||||||
if r.Validation.AllowExistingViolations == nil {
|
if r.Validation != nil && r.Validation.AllowExistingViolations != nil {
|
||||||
allowExisitingViolations = true
|
|
||||||
} else {
|
|
||||||
allowExisitingViolations = *r.Validation.AllowExistingViolations
|
allowExisitingViolations = *r.Validation.AllowExistingViolations
|
||||||
}
|
}
|
||||||
return allowExisitingViolations
|
return allowExisitingViolations
|
||||||
|
@ -204,7 +202,7 @@ func (r *Rule) HasGenerate() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Rule) IsPodSecurity() bool {
|
func (r *Rule) IsPodSecurity() bool {
|
||||||
return r.Validation.PodSecurity != nil
|
return r.Validation != nil && r.Validation.PodSecurity != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Rule) GetSyncAndOrphanDownstream() (sync bool, orphanDownstream bool) {
|
func (r *Rule) GetSyncAndOrphanDownstream() (sync bool, orphanDownstream bool) {
|
||||||
|
@ -243,7 +241,6 @@ func (r *Rule) ValidateRuleType(path *field.Path) (errs field.ErrorList) {
|
||||||
} else if count != 1 {
|
} else if count != 1 {
|
||||||
errs = append(errs, field.Invalid(path, r, fmt.Sprintf("Multiple operations defined in the rule '%s', only one operation (mutate,validate,generate,verifyImages) is allowed per rule", r.Name)))
|
errs = append(errs, field.Invalid(path, r, fmt.Sprintf("Multiple operations defined in the rule '%s', only one operation (mutate,validate,generate,verifyImages) is allowed per rule", r.Name)))
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.ImageExtractors != nil && !r.HasVerifyImages() {
|
if r.ImageExtractors != nil && !r.HasVerifyImages() {
|
||||||
errs = append(errs, field.Invalid(path.Child("imageExtractors"), r, fmt.Sprintf("Invalid rule spec for rule '%s', imageExtractors can only be defined for verifyImages rule", r.Name)))
|
errs = append(errs, field.Invalid(path.Child("imageExtractors"), r, fmt.Sprintf("Invalid rule spec for rule '%s', imageExtractors can only be defined for verifyImages rule", r.Name)))
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ func Test_Validate_UniqueRuleName(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Validation: Validation{
|
Validation: &Validation{
|
||||||
Message: "message",
|
Message: "message",
|
||||||
RawAnyPattern: &apiextv1.JSON{
|
RawAnyPattern: &apiextv1.JSON{
|
||||||
Raw: []byte("{"),
|
Raw: []byte("{"),
|
||||||
|
@ -34,7 +34,7 @@ func Test_Validate_UniqueRuleName(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Validation: Validation{
|
Validation: &Validation{
|
||||||
Message: "message",
|
Message: "message",
|
||||||
RawAnyPattern: &apiextv1.JSON{
|
RawAnyPattern: &apiextv1.JSON{
|
||||||
Raw: []byte("{"),
|
Raw: []byte("{"),
|
||||||
|
|
|
@ -1430,7 +1430,11 @@ func (in *Rule) DeepCopyInto(out *Rule) {
|
||||||
*out = new(Mutation)
|
*out = new(Mutation)
|
||||||
(*in).DeepCopyInto(*out)
|
(*in).DeepCopyInto(*out)
|
||||||
}
|
}
|
||||||
in.Validation.DeepCopyInto(&out.Validation)
|
if in.Validation != nil {
|
||||||
|
in, out := &in.Validation, &out.Validation
|
||||||
|
*out = new(Validation)
|
||||||
|
(*in).DeepCopyInto(*out)
|
||||||
|
}
|
||||||
if in.Generation != nil {
|
if in.Generation != nil {
|
||||||
in, out := &in.Generation, &out.Generation
|
in, out := &in.Generation, &out.Generation
|
||||||
*out = new(Generation)
|
*out = new(Generation)
|
||||||
|
|
|
@ -56,7 +56,7 @@ type Rule struct {
|
||||||
|
|
||||||
// Validation is used to validate matching resources.
|
// Validation is used to validate matching resources.
|
||||||
// +optional
|
// +optional
|
||||||
Validation Validation `json:"validate,omitempty"`
|
Validation *Validation `json:"validate,omitempty"`
|
||||||
|
|
||||||
// Generation is used to create new resources.
|
// Generation is used to create new resources.
|
||||||
// +optional
|
// +optional
|
||||||
|
@ -114,22 +114,22 @@ func (r *Rule) HasVerifyImageChecks() bool {
|
||||||
|
|
||||||
// HasVerifyManifests checks for validate.manifests rule
|
// HasVerifyManifests checks for validate.manifests rule
|
||||||
func (r Rule) HasVerifyManifests() bool {
|
func (r Rule) HasVerifyManifests() bool {
|
||||||
return r.Validation.Manifests != nil && len(r.Validation.Manifests.Attestors) != 0
|
return r.Validation != nil && r.Validation.Manifests != nil && len(r.Validation.Manifests.Attestors) != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// HasValidatePodSecurity checks for validate.podSecurity rule
|
// HasValidatePodSecurity checks for validate.podSecurity rule
|
||||||
func (r Rule) HasValidatePodSecurity() bool {
|
func (r Rule) HasValidatePodSecurity() bool {
|
||||||
return r.Validation.PodSecurity != nil && !datautils.DeepEqual(r.Validation.PodSecurity, &kyvernov1.PodSecurity{})
|
return r.Validation != nil && r.Validation.PodSecurity != nil && !datautils.DeepEqual(*r.Validation.PodSecurity, kyvernov1.PodSecurity{})
|
||||||
}
|
}
|
||||||
|
|
||||||
// HasValidateCEL checks for validate.cel rule
|
// HasValidateCEL checks for validate.cel rule
|
||||||
func (r *Rule) HasValidateCEL() bool {
|
func (r *Rule) HasValidateCEL() bool {
|
||||||
return r.Validation.CEL != nil && !datautils.DeepEqual(r.Validation.CEL, &kyvernov1.CEL{})
|
return r.Validation != nil && r.Validation.CEL != nil && !datautils.DeepEqual(*r.Validation.CEL, kyvernov1.CEL{})
|
||||||
}
|
}
|
||||||
|
|
||||||
// HasValidate checks for validate rule
|
// HasValidate checks for validate rule
|
||||||
func (r *Rule) HasValidate() bool {
|
func (r *Rule) HasValidate() bool {
|
||||||
return !datautils.DeepEqual(r.Validation, Validation{})
|
return r.Validation != nil && !datautils.DeepEqual(*r.Validation, Validation{})
|
||||||
}
|
}
|
||||||
|
|
||||||
// HasGenerate checks for generate rule
|
// HasGenerate checks for generate rule
|
||||||
|
@ -151,7 +151,6 @@ func (r *Rule) ValidateRuleType(path *field.Path) (errs field.ErrorList) {
|
||||||
} else if count != 1 {
|
} else if count != 1 {
|
||||||
errs = append(errs, field.Invalid(path, r, fmt.Sprintf("Multiple operations defined in the rule '%s', only one operation (mutate,validate,generate,verifyImages) is allowed per rule", r.Name)))
|
errs = append(errs, field.Invalid(path, r, fmt.Sprintf("Multiple operations defined in the rule '%s', only one operation (mutate,validate,generate,verifyImages) is allowed per rule", r.Name)))
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.ImageExtractors != nil && !r.HasVerifyImages() {
|
if r.ImageExtractors != nil && !r.HasVerifyImages() {
|
||||||
errs = append(errs, field.Invalid(path.Child("imageExtractors"), r, fmt.Sprintf("Invalid rule spec for rule '%s', imageExtractors can only be defined for verifyImages rule", r.Name)))
|
errs = append(errs, field.Invalid(path.Child("imageExtractors"), r, fmt.Sprintf("Invalid rule spec for rule '%s', imageExtractors can only be defined for verifyImages rule", r.Name)))
|
||||||
}
|
}
|
||||||
|
@ -190,7 +189,6 @@ func (r *Rule) ValidateGenerate(path *field.Path, namespaced bool, policyNamespa
|
||||||
if !r.HasGenerate() {
|
if !r.HasGenerate() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return r.Generation.Validate(path, namespaced, policyNamespace, clusterResources)
|
return r.Generation.Validate(path, namespaced, policyNamespace, clusterResources)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ func Test_Validate_UniqueRuleName(t *testing.T) {
|
||||||
},
|
},
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
Validation: Validation{
|
Validation: &Validation{
|
||||||
Message: "message",
|
Message: "message",
|
||||||
RawAnyPattern: kyverno.ToAny("{"),
|
RawAnyPattern: kyverno.ToAny("{"),
|
||||||
},
|
},
|
||||||
|
@ -36,7 +36,7 @@ func Test_Validate_UniqueRuleName(t *testing.T) {
|
||||||
},
|
},
|
||||||
}},
|
}},
|
||||||
}},
|
}},
|
||||||
Validation: Validation{
|
Validation: &Validation{
|
||||||
Message: "message",
|
Message: "message",
|
||||||
RawAnyPattern: kyverno.ToAny("{"),
|
RawAnyPattern: kyverno.ToAny("{"),
|
||||||
},
|
},
|
||||||
|
|
|
@ -747,7 +747,11 @@ func (in *Rule) DeepCopyInto(out *Rule) {
|
||||||
*out = new(v1.Mutation)
|
*out = new(v1.Mutation)
|
||||||
(*in).DeepCopyInto(*out)
|
(*in).DeepCopyInto(*out)
|
||||||
}
|
}
|
||||||
in.Validation.DeepCopyInto(&out.Validation)
|
if in.Validation != nil {
|
||||||
|
in, out := &in.Validation, &out.Validation
|
||||||
|
*out = new(Validation)
|
||||||
|
(*in).DeepCopyInto(*out)
|
||||||
|
}
|
||||||
if in.Generation != nil {
|
if in.Generation != nil {
|
||||||
in, out := &in.Generation, &out.Generation
|
in, out := &in.Generation, &out.Generation
|
||||||
*out = new(v1.Generation)
|
*out = new(v1.Generation)
|
||||||
|
|
|
@ -233,7 +233,7 @@ func convertRule(rule kyvernoRule, kind string) (*kyvernov1.Rule, error) {
|
||||||
out.Mutation = rule.Mutation
|
out.Mutation = rule.Mutation
|
||||||
}
|
}
|
||||||
if rule.Validation != nil {
|
if rule.Validation != nil {
|
||||||
out.Validation = *rule.Validation
|
out.Validation = rule.Validation
|
||||||
}
|
}
|
||||||
return &out, nil
|
return &out, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ func createRule(rule *kyvernov1.Rule) *kyvernoRule {
|
||||||
if rule.Mutation != nil && !datautils.DeepEqual(*rule.Mutation, kyvernov1.Mutation{}) {
|
if rule.Mutation != nil && !datautils.DeepEqual(*rule.Mutation, kyvernov1.Mutation{}) {
|
||||||
jsonFriendlyStruct.Mutation = rule.Mutation.DeepCopy()
|
jsonFriendlyStruct.Mutation = rule.Mutation.DeepCopy()
|
||||||
}
|
}
|
||||||
if !datautils.DeepEqual(rule.Validation, kyvernov1.Validation{}) {
|
if rule.Validation != nil && !datautils.DeepEqual(*rule.Validation, kyvernov1.Validation{}) {
|
||||||
jsonFriendlyStruct.Validation = rule.Validation.DeepCopy()
|
jsonFriendlyStruct.Validation = rule.Validation.DeepCopy()
|
||||||
}
|
}
|
||||||
kyvernoAnyAllConditions := rule.GetAnyAllConditions()
|
kyvernoAnyAllConditions := rule.GetAnyAllConditions()
|
||||||
|
@ -131,84 +131,95 @@ func generateRule(name string, rule *kyvernov1.Rule, tplKey, shift string, kinds
|
||||||
return rule
|
return rule
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if target := rule.Validation.GetPattern(); target != nil {
|
if rule.Validation != nil {
|
||||||
newValidate := kyvernov1.Validation{
|
if target := rule.Validation.GetPattern(); target != nil {
|
||||||
Message: variables.FindAndShiftReferences(logger, rule.Validation.Message, shift, "pattern"),
|
newValidate := &kyvernov1.Validation{
|
||||||
FailureAction: rule.Validation.FailureAction,
|
Message: variables.FindAndShiftReferences(logger, rule.Validation.Message, shift, "pattern"),
|
||||||
FailureActionOverrides: rule.Validation.FailureActionOverrides,
|
FailureAction: rule.Validation.FailureAction,
|
||||||
}
|
FailureActionOverrides: rule.Validation.FailureActionOverrides,
|
||||||
newValidate.SetPattern(
|
|
||||||
map[string]interface{}{
|
|
||||||
"spec": map[string]interface{}{
|
|
||||||
tplKey: target,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
)
|
|
||||||
rule.Validation = newValidate
|
|
||||||
return rule
|
|
||||||
}
|
|
||||||
if rule.Validation.Deny != nil {
|
|
||||||
deny := kyvernov1.Validation{
|
|
||||||
Message: variables.FindAndShiftReferences(logger, rule.Validation.Message, shift, "deny"),
|
|
||||||
Deny: rule.Validation.Deny,
|
|
||||||
FailureAction: rule.Validation.FailureAction,
|
|
||||||
FailureActionOverrides: rule.Validation.FailureActionOverrides,
|
|
||||||
}
|
|
||||||
rule.Validation = deny
|
|
||||||
return rule
|
|
||||||
}
|
|
||||||
if rule.Validation.PodSecurity != nil {
|
|
||||||
newExclude := make([]kyvernov1.PodSecurityStandard, len(rule.Validation.PodSecurity.Exclude))
|
|
||||||
copy(newExclude, rule.Validation.PodSecurity.Exclude)
|
|
||||||
podSecurity := kyvernov1.Validation{
|
|
||||||
Message: variables.FindAndShiftReferences(logger, rule.Validation.Message, shift, "podSecurity"),
|
|
||||||
PodSecurity: &kyvernov1.PodSecurity{
|
|
||||||
Level: rule.Validation.PodSecurity.Level,
|
|
||||||
Version: rule.Validation.PodSecurity.Version,
|
|
||||||
Exclude: newExclude,
|
|
||||||
},
|
|
||||||
FailureAction: rule.Validation.FailureAction,
|
|
||||||
FailureActionOverrides: rule.Validation.FailureActionOverrides,
|
|
||||||
}
|
|
||||||
rule.Validation = podSecurity
|
|
||||||
return rule
|
|
||||||
}
|
|
||||||
if rule.Validation.GetAnyPattern() != nil {
|
|
||||||
anyPatterns, err := rule.Validation.DeserializeAnyPattern()
|
|
||||||
if err != nil {
|
|
||||||
logger.Error(err, "failed to deserialize anyPattern, expect type array")
|
|
||||||
}
|
|
||||||
var patterns []interface{}
|
|
||||||
for _, pattern := range anyPatterns {
|
|
||||||
newPattern := map[string]interface{}{
|
|
||||||
"spec": map[string]interface{}{
|
|
||||||
tplKey: pattern,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
patterns = append(patterns, newPattern)
|
newValidate.SetPattern(
|
||||||
|
map[string]interface{}{
|
||||||
|
"spec": map[string]interface{}{
|
||||||
|
tplKey: target,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
rule.Validation = newValidate
|
||||||
|
return rule
|
||||||
}
|
}
|
||||||
failureAction := rule.Validation.FailureAction
|
if rule.Validation.Deny != nil {
|
||||||
failureActionOverrides := rule.Validation.FailureActionOverrides
|
deny := &kyvernov1.Validation{
|
||||||
rule.Validation = kyvernov1.Validation{
|
Message: variables.FindAndShiftReferences(logger, rule.Validation.Message, shift, "deny"),
|
||||||
Message: variables.FindAndShiftReferences(logger, rule.Validation.Message, shift, "anyPattern"),
|
Deny: rule.Validation.Deny,
|
||||||
FailureAction: failureAction,
|
FailureAction: rule.Validation.FailureAction,
|
||||||
FailureActionOverrides: failureActionOverrides,
|
FailureActionOverrides: rule.Validation.FailureActionOverrides,
|
||||||
|
}
|
||||||
|
rule.Validation = deny
|
||||||
|
return rule
|
||||||
}
|
}
|
||||||
rule.Validation.SetAnyPattern(patterns)
|
if rule.Validation.PodSecurity != nil {
|
||||||
return rule
|
newExclude := make([]kyvernov1.PodSecurityStandard, len(rule.Validation.PodSecurity.Exclude))
|
||||||
}
|
copy(newExclude, rule.Validation.PodSecurity.Exclude)
|
||||||
if len(rule.Validation.ForEachValidation) > 0 && rule.Validation.ForEachValidation != nil {
|
podSecurity := &kyvernov1.Validation{
|
||||||
newForeachValidate := make([]kyvernov1.ForEachValidation, len(rule.Validation.ForEachValidation))
|
Message: variables.FindAndShiftReferences(logger, rule.Validation.Message, shift, "podSecurity"),
|
||||||
copy(newForeachValidate, rule.Validation.ForEachValidation)
|
PodSecurity: &kyvernov1.PodSecurity{
|
||||||
failureAction := rule.Validation.FailureAction
|
Level: rule.Validation.PodSecurity.Level,
|
||||||
failureActionOverrides := rule.Validation.FailureActionOverrides
|
Version: rule.Validation.PodSecurity.Version,
|
||||||
rule.Validation = kyvernov1.Validation{
|
Exclude: newExclude,
|
||||||
Message: variables.FindAndShiftReferences(logger, rule.Validation.Message, shift, "pattern"),
|
},
|
||||||
ForEachValidation: newForeachValidate,
|
FailureAction: rule.Validation.FailureAction,
|
||||||
FailureAction: failureAction,
|
FailureActionOverrides: rule.Validation.FailureActionOverrides,
|
||||||
FailureActionOverrides: failureActionOverrides,
|
}
|
||||||
|
rule.Validation = podSecurity
|
||||||
|
return rule
|
||||||
|
}
|
||||||
|
if rule.Validation.GetAnyPattern() != nil {
|
||||||
|
anyPatterns, err := rule.Validation.DeserializeAnyPattern()
|
||||||
|
if err != nil {
|
||||||
|
logger.Error(err, "failed to deserialize anyPattern, expect type array")
|
||||||
|
}
|
||||||
|
var patterns []interface{}
|
||||||
|
for _, pattern := range anyPatterns {
|
||||||
|
newPattern := map[string]interface{}{
|
||||||
|
"spec": map[string]interface{}{
|
||||||
|
tplKey: pattern,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
patterns = append(patterns, newPattern)
|
||||||
|
}
|
||||||
|
failureAction := rule.Validation.FailureAction
|
||||||
|
failureActionOverrides := rule.Validation.FailureActionOverrides
|
||||||
|
rule.Validation = &kyvernov1.Validation{
|
||||||
|
Message: variables.FindAndShiftReferences(logger, rule.Validation.Message, shift, "anyPattern"),
|
||||||
|
FailureAction: failureAction,
|
||||||
|
FailureActionOverrides: failureActionOverrides,
|
||||||
|
}
|
||||||
|
rule.Validation.SetAnyPattern(patterns)
|
||||||
|
return rule
|
||||||
|
}
|
||||||
|
if len(rule.Validation.ForEachValidation) > 0 && rule.Validation.ForEachValidation != nil {
|
||||||
|
newForeachValidate := make([]kyvernov1.ForEachValidation, len(rule.Validation.ForEachValidation))
|
||||||
|
copy(newForeachValidate, rule.Validation.ForEachValidation)
|
||||||
|
failureAction := rule.Validation.FailureAction
|
||||||
|
failureActionOverrides := rule.Validation.FailureActionOverrides
|
||||||
|
rule.Validation = &kyvernov1.Validation{
|
||||||
|
Message: variables.FindAndShiftReferences(logger, rule.Validation.Message, shift, "pattern"),
|
||||||
|
ForEachValidation: newForeachValidate,
|
||||||
|
FailureAction: failureAction,
|
||||||
|
FailureActionOverrides: failureActionOverrides,
|
||||||
|
}
|
||||||
|
return rule
|
||||||
|
}
|
||||||
|
if rule.HasValidateCEL() {
|
||||||
|
cel := rule.Validation.CEL.DeepCopy()
|
||||||
|
rule.Validation.CEL = cel
|
||||||
|
return rule
|
||||||
|
}
|
||||||
|
if rule.HasValidateAssert() {
|
||||||
|
rule.Validation.Assert = createAutogenAssertion(*rule.Validation.Assert.DeepCopy(), tplKey)
|
||||||
|
return rule
|
||||||
}
|
}
|
||||||
return rule
|
|
||||||
}
|
}
|
||||||
if rule.VerifyImages != nil {
|
if rule.VerifyImages != nil {
|
||||||
newVerifyImages := make([]kyvernov1.ImageVerification, len(rule.VerifyImages))
|
newVerifyImages := make([]kyvernov1.ImageVerification, len(rule.VerifyImages))
|
||||||
|
@ -218,16 +229,6 @@ func generateRule(name string, rule *kyvernov1.Rule, tplKey, shift string, kinds
|
||||||
rule.VerifyImages = newVerifyImages
|
rule.VerifyImages = newVerifyImages
|
||||||
return rule
|
return rule
|
||||||
}
|
}
|
||||||
if rule.HasValidateCEL() {
|
|
||||||
cel := rule.Validation.CEL.DeepCopy()
|
|
||||||
rule.Validation.CEL = cel
|
|
||||||
return rule
|
|
||||||
}
|
|
||||||
if rule.HasValidateAssert() {
|
|
||||||
rule.Validation.Assert = createAutogenAssertion(*rule.Validation.Assert.DeepCopy(), tplKey)
|
|
||||||
|
|
||||||
return rule
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -716,7 +716,7 @@ func TestEngineResponse_GetValidationFailureAction(t *testing.T) {
|
||||||
Spec: kyvernov1.Spec{
|
Spec: kyvernov1.Spec{
|
||||||
Rules: []kyvernov1.Rule{
|
Rules: []kyvernov1.Rule{
|
||||||
{
|
{
|
||||||
Validation: kyvernov1.Validation{
|
Validation: &kyvernov1.Validation{
|
||||||
FailureAction: &audit,
|
FailureAction: &audit,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -731,7 +731,7 @@ func TestEngineResponse_GetValidationFailureAction(t *testing.T) {
|
||||||
Spec: kyvernov1.Spec{
|
Spec: kyvernov1.Spec{
|
||||||
Rules: []kyvernov1.Rule{
|
Rules: []kyvernov1.Rule{
|
||||||
{
|
{
|
||||||
Validation: kyvernov1.Validation{
|
Validation: &kyvernov1.Validation{
|
||||||
FailureAction: &enforce,
|
FailureAction: &enforce,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -772,7 +772,7 @@ func TestEngineResponse_GetValidationFailureAction(t *testing.T) {
|
||||||
Spec: kyvernov1.Spec{
|
Spec: kyvernov1.Spec{
|
||||||
Rules: []kyvernov1.Rule{
|
Rules: []kyvernov1.Rule{
|
||||||
{
|
{
|
||||||
Validation: kyvernov1.Validation{
|
Validation: &kyvernov1.Validation{
|
||||||
FailureAction: &enforce,
|
FailureAction: &enforce,
|
||||||
FailureActionOverrides: []kyvernov1.ValidationFailureActionOverride{{
|
FailureActionOverrides: []kyvernov1.ValidationFailureActionOverride{{
|
||||||
Action: kyvernov1.Audit,
|
Action: kyvernov1.Audit,
|
||||||
|
@ -791,7 +791,7 @@ func TestEngineResponse_GetValidationFailureAction(t *testing.T) {
|
||||||
Spec: kyvernov1.Spec{
|
Spec: kyvernov1.Spec{
|
||||||
Rules: []kyvernov1.Rule{
|
Rules: []kyvernov1.Rule{
|
||||||
{
|
{
|
||||||
Validation: kyvernov1.Validation{
|
Validation: &kyvernov1.Validation{
|
||||||
FailureAction: &enforce,
|
FailureAction: &enforce,
|
||||||
FailureActionOverrides: []kyvernov1.ValidationFailureActionOverride{{
|
FailureActionOverrides: []kyvernov1.ValidationFailureActionOverride{{
|
||||||
Action: "invalid",
|
Action: "invalid",
|
||||||
|
@ -969,7 +969,7 @@ func TestEngineResponse_GetValidationFailureAction(t *testing.T) {
|
||||||
Spec: kyvernov1.Spec{
|
Spec: kyvernov1.Spec{
|
||||||
Rules: []kyvernov1.Rule{
|
Rules: []kyvernov1.Rule{
|
||||||
{
|
{
|
||||||
Validation: kyvernov1.Validation{
|
Validation: &kyvernov1.Validation{
|
||||||
FailureAction: &enforce,
|
FailureAction: &enforce,
|
||||||
FailureActionOverrides: []kyvernov1.ValidationFailureActionOverride{{
|
FailureActionOverrides: []kyvernov1.ValidationFailureActionOverride{{
|
||||||
Action: kyvernov1.Audit,
|
Action: kyvernov1.Audit,
|
||||||
|
@ -989,7 +989,7 @@ func TestEngineResponse_GetValidationFailureAction(t *testing.T) {
|
||||||
Spec: kyvernov1.Spec{
|
Spec: kyvernov1.Spec{
|
||||||
Rules: []kyvernov1.Rule{
|
Rules: []kyvernov1.Rule{
|
||||||
{
|
{
|
||||||
Validation: kyvernov1.Validation{
|
Validation: &kyvernov1.Validation{
|
||||||
FailureAction: &enforce,
|
FailureAction: &enforce,
|
||||||
FailureActionOverrides: []kyvernov1.ValidationFailureActionOverride{{
|
FailureActionOverrides: []kyvernov1.ValidationFailureActionOverride{{
|
||||||
Action: kyvernov1.Audit,
|
Action: kyvernov1.Audit,
|
||||||
|
@ -1012,7 +1012,7 @@ func TestEngineResponse_GetValidationFailureAction(t *testing.T) {
|
||||||
Spec: kyvernov1.Spec{
|
Spec: kyvernov1.Spec{
|
||||||
Rules: []kyvernov1.Rule{
|
Rules: []kyvernov1.Rule{
|
||||||
{
|
{
|
||||||
Validation: kyvernov1.Validation{
|
Validation: &kyvernov1.Validation{
|
||||||
FailureAction: &enforce,
|
FailureAction: &enforce,
|
||||||
FailureActionOverrides: []kyvernov1.ValidationFailureActionOverride{{
|
FailureActionOverrides: []kyvernov1.ValidationFailureActionOverride{{
|
||||||
Action: kyvernov1.Audit,
|
Action: kyvernov1.Audit,
|
||||||
|
@ -1039,7 +1039,7 @@ func TestEngineResponse_GetValidationFailureAction(t *testing.T) {
|
||||||
Spec: kyvernov1.Spec{
|
Spec: kyvernov1.Spec{
|
||||||
Rules: []kyvernov1.Rule{
|
Rules: []kyvernov1.Rule{
|
||||||
{
|
{
|
||||||
Validation: kyvernov1.Validation{
|
Validation: &kyvernov1.Validation{
|
||||||
FailureAction: &enforce,
|
FailureAction: &enforce,
|
||||||
FailureActionOverrides: []kyvernov1.ValidationFailureActionOverride{{
|
FailureActionOverrides: []kyvernov1.ValidationFailureActionOverride{{
|
||||||
Action: kyvernov1.Audit,
|
Action: kyvernov1.Audit,
|
||||||
|
@ -1066,7 +1066,7 @@ func TestEngineResponse_GetValidationFailureAction(t *testing.T) {
|
||||||
Spec: kyvernov1.Spec{
|
Spec: kyvernov1.Spec{
|
||||||
Rules: []kyvernov1.Rule{
|
Rules: []kyvernov1.Rule{
|
||||||
{
|
{
|
||||||
Validation: kyvernov1.Validation{
|
Validation: &kyvernov1.Validation{
|
||||||
FailureAction: &enforce,
|
FailureAction: &enforce,
|
||||||
FailureActionOverrides: []kyvernov1.ValidationFailureActionOverride{{
|
FailureActionOverrides: []kyvernov1.ValidationFailureActionOverride{{
|
||||||
Action: kyvernov1.Audit,
|
Action: kyvernov1.Audit,
|
||||||
|
@ -1094,7 +1094,7 @@ func TestEngineResponse_GetValidationFailureAction(t *testing.T) {
|
||||||
Spec: kyvernov1.Spec{
|
Spec: kyvernov1.Spec{
|
||||||
Rules: []kyvernov1.Rule{
|
Rules: []kyvernov1.Rule{
|
||||||
{
|
{
|
||||||
Validation: kyvernov1.Validation{
|
Validation: &kyvernov1.Validation{
|
||||||
FailureAction: &enforce,
|
FailureAction: &enforce,
|
||||||
FailureActionOverrides: []kyvernov1.ValidationFailureActionOverride{{
|
FailureActionOverrides: []kyvernov1.ValidationFailureActionOverride{{
|
||||||
Action: kyvernov1.Audit,
|
Action: kyvernov1.Audit,
|
||||||
|
@ -1122,7 +1122,7 @@ func TestEngineResponse_GetValidationFailureAction(t *testing.T) {
|
||||||
Spec: kyvernov1.Spec{
|
Spec: kyvernov1.Spec{
|
||||||
Rules: []kyvernov1.Rule{
|
Rules: []kyvernov1.Rule{
|
||||||
{
|
{
|
||||||
Validation: kyvernov1.Validation{
|
Validation: &kyvernov1.Validation{
|
||||||
FailureAction: &enforce,
|
FailureAction: &enforce,
|
||||||
FailureActionOverrides: []kyvernov1.ValidationFailureActionOverride{{
|
FailureActionOverrides: []kyvernov1.ValidationFailureActionOverride{{
|
||||||
Action: kyvernov1.Audit,
|
Action: kyvernov1.Audit,
|
||||||
|
@ -1150,7 +1150,7 @@ func TestEngineResponse_GetValidationFailureAction(t *testing.T) {
|
||||||
Spec: kyvernov1.Spec{
|
Spec: kyvernov1.Spec{
|
||||||
Rules: []kyvernov1.Rule{
|
Rules: []kyvernov1.Rule{
|
||||||
{
|
{
|
||||||
Validation: kyvernov1.Validation{
|
Validation: &kyvernov1.Validation{
|
||||||
FailureAction: &enforce,
|
FailureAction: &enforce,
|
||||||
FailureActionOverrides: []kyvernov1.ValidationFailureActionOverride{{
|
FailureActionOverrides: []kyvernov1.ValidationFailureActionOverride{{
|
||||||
Action: kyvernov1.Audit,
|
Action: kyvernov1.Audit,
|
||||||
|
|
|
@ -23,7 +23,7 @@ func ParsePolicyBackgroundMode(policy kyvernov1.PolicyInterface) PolicyBackgroun
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseRuleType(rule kyvernov1.Rule) RuleType {
|
func ParseRuleType(rule kyvernov1.Rule) RuleType {
|
||||||
if !datautils.DeepEqual(rule.Validation, kyvernov1.Validation{}) {
|
if rule.Validation != nil && !datautils.DeepEqual(*rule.Validation, kyvernov1.Validation{}) {
|
||||||
return Validate
|
return Validate
|
||||||
}
|
}
|
||||||
if rule.Mutation != nil && !datautils.DeepEqual(*rule.Mutation, kyvernov1.Mutation{}) {
|
if rule.Mutation != nil && !datautils.DeepEqual(*rule.Mutation, kyvernov1.Mutation{}) {
|
||||||
|
|
|
@ -32,7 +32,7 @@ func NewValidateFactory(rule *kyvernov1.Rule, client dclient.Interface, mock boo
|
||||||
|
|
||||||
return &Validate{
|
return &Validate{
|
||||||
rule: rule,
|
rule: rule,
|
||||||
validationRule: &rule.Validation,
|
validationRule: rule.Validation,
|
||||||
authChecker: authChecker,
|
authChecker: authChecker,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ func NewValidateFactory(rule *kyvernov1.Rule, client dclient.Interface, mock boo
|
||||||
func NewMockValidateFactory(rule *kyvernov1.Rule) *Validate {
|
func NewMockValidateFactory(rule *kyvernov1.Rule) *Validate {
|
||||||
return &Validate{
|
return &Validate{
|
||||||
rule: rule,
|
rule: rule,
|
||||||
validationRule: &rule.Validation,
|
validationRule: rule.Validation,
|
||||||
authChecker: fake.NewFakeAuth(),
|
authChecker: fake.NewFakeAuth(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ func Test_Validate_OverlayPattern_Nil_PatternAnypattern(t *testing.T) {
|
||||||
var validation kyverno.Validation
|
var validation kyverno.Validation
|
||||||
err := json.Unmarshal(rawValidation, &validation)
|
err := json.Unmarshal(rawValidation, &validation)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
checker := NewMockValidateFactory(&kyverno.Rule{Validation: validation})
|
checker := NewMockValidateFactory(&kyverno.Rule{Validation: &validation})
|
||||||
if _, _, err := checker.Validate(context.TODO(), nil); err != nil {
|
if _, _, err := checker.Validate(context.TODO(), nil); err != nil {
|
||||||
assert.Assert(t, err != nil)
|
assert.Assert(t, err != nil)
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,7 @@ func Test_Validate_OverlayPattern_Exist_PatternAnypattern(t *testing.T) {
|
||||||
var validation kyverno.Validation
|
var validation kyverno.Validation
|
||||||
err := json.Unmarshal(rawValidation, &validation)
|
err := json.Unmarshal(rawValidation, &validation)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
checker := NewMockValidateFactory(&kyverno.Rule{Validation: validation})
|
checker := NewMockValidateFactory(&kyverno.Rule{Validation: &validation})
|
||||||
if _, _, err := checker.Validate(context.TODO(), nil); err != nil {
|
if _, _, err := checker.Validate(context.TODO(), nil); err != nil {
|
||||||
assert.Assert(t, err != nil)
|
assert.Assert(t, err != nil)
|
||||||
}
|
}
|
||||||
|
@ -107,7 +107,7 @@ func Test_Validate_OverlayPattern_Valid(t *testing.T) {
|
||||||
var validation kyverno.Validation
|
var validation kyverno.Validation
|
||||||
err := json.Unmarshal(rawValidation, &validation)
|
err := json.Unmarshal(rawValidation, &validation)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
checker := NewMockValidateFactory(&kyverno.Rule{Validation: validation})
|
checker := NewMockValidateFactory(&kyverno.Rule{Validation: &validation})
|
||||||
if _, _, err := checker.Validate(context.TODO(), nil); err != nil {
|
if _, _, err := checker.Validate(context.TODO(), nil); err != nil {
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
}
|
}
|
||||||
|
@ -140,7 +140,7 @@ func Test_Validate_ExistingAnchor_AnchorOnMap(t *testing.T) {
|
||||||
var validation kyverno.Validation
|
var validation kyverno.Validation
|
||||||
err := json.Unmarshal(rawValidation, &validation)
|
err := json.Unmarshal(rawValidation, &validation)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
checker := NewMockValidateFactory(&kyverno.Rule{Validation: validation})
|
checker := NewMockValidateFactory(&kyverno.Rule{Validation: &validation})
|
||||||
if _, _, err := checker.Validate(context.TODO(), nil); err != nil {
|
if _, _, err := checker.Validate(context.TODO(), nil); err != nil {
|
||||||
assert.Assert(t, err != nil)
|
assert.Assert(t, err != nil)
|
||||||
}
|
}
|
||||||
|
@ -170,7 +170,7 @@ func Test_Validate_ExistingAnchor_AnchorOnString(t *testing.T) {
|
||||||
var validation kyverno.Validation
|
var validation kyverno.Validation
|
||||||
err := json.Unmarshal(rawValidation, &validation)
|
err := json.Unmarshal(rawValidation, &validation)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
checker := NewMockValidateFactory(&kyverno.Rule{Validation: validation})
|
checker := NewMockValidateFactory(&kyverno.Rule{Validation: &validation})
|
||||||
if _, _, err := checker.Validate(context.TODO(), nil); err != nil {
|
if _, _, err := checker.Validate(context.TODO(), nil); err != nil {
|
||||||
assert.Assert(t, err != nil)
|
assert.Assert(t, err != nil)
|
||||||
}
|
}
|
||||||
|
@ -203,7 +203,7 @@ func Test_Validate_ExistingAnchor_Valid(t *testing.T) {
|
||||||
|
|
||||||
err = json.Unmarshal(rawValidation, &validation)
|
err = json.Unmarshal(rawValidation, &validation)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
checker := NewMockValidateFactory(&kyverno.Rule{Validation: validation})
|
checker := NewMockValidateFactory(&kyverno.Rule{Validation: &validation})
|
||||||
if _, _, err := checker.Validate(context.TODO(), nil); err != nil {
|
if _, _, err := checker.Validate(context.TODO(), nil); err != nil {
|
||||||
assert.Assert(t, err != nil)
|
assert.Assert(t, err != nil)
|
||||||
}
|
}
|
||||||
|
@ -228,7 +228,7 @@ func Test_Validate_ExistingAnchor_Valid(t *testing.T) {
|
||||||
} `)
|
} `)
|
||||||
err = json.Unmarshal(rawValidation, &validation)
|
err = json.Unmarshal(rawValidation, &validation)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
checker = NewMockValidateFactory(&kyverno.Rule{Validation: validation})
|
checker = NewMockValidateFactory(&kyverno.Rule{Validation: &validation})
|
||||||
if _, _, err := checker.Validate(context.TODO(), nil); err != nil {
|
if _, _, err := checker.Validate(context.TODO(), nil); err != nil {
|
||||||
assert.Assert(t, err != nil)
|
assert.Assert(t, err != nil)
|
||||||
}
|
}
|
||||||
|
@ -269,7 +269,7 @@ func Test_Validate_Validate_ValidAnchor(t *testing.T) {
|
||||||
err = json.Unmarshal(rawValidate, &validate)
|
err = json.Unmarshal(rawValidate, &validate)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
|
||||||
checker := NewMockValidateFactory(&kyverno.Rule{Validation: validate})
|
checker := NewMockValidateFactory(&kyverno.Rule{Validation: &validate})
|
||||||
if _, _, err := checker.Validate(context.TODO(), nil); err != nil {
|
if _, _, err := checker.Validate(context.TODO(), nil); err != nil {
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
}
|
}
|
||||||
|
@ -291,7 +291,7 @@ func Test_Validate_Validate_ValidAnchor(t *testing.T) {
|
||||||
err = json.Unmarshal(rawValidate, &validate)
|
err = json.Unmarshal(rawValidate, &validate)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
|
||||||
checker = NewMockValidateFactory(&kyverno.Rule{Validation: validate})
|
checker = NewMockValidateFactory(&kyverno.Rule{Validation: &validate})
|
||||||
if _, _, err := checker.Validate(context.TODO(), nil); err != nil {
|
if _, _, err := checker.Validate(context.TODO(), nil); err != nil {
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
}
|
}
|
||||||
|
@ -318,7 +318,7 @@ func Test_Validate_Validate_Mismatched(t *testing.T) {
|
||||||
var validate kyverno.Validation
|
var validate kyverno.Validation
|
||||||
err := json.Unmarshal(rawValidate, &validate)
|
err := json.Unmarshal(rawValidate, &validate)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
checker := NewMockValidateFactory(&kyverno.Rule{Validation: validate})
|
checker := NewMockValidateFactory(&kyverno.Rule{Validation: &validate})
|
||||||
if _, _, err := checker.Validate(context.TODO(), nil); err != nil {
|
if _, _, err := checker.Validate(context.TODO(), nil); err != nil {
|
||||||
assert.Assert(t, err != nil)
|
assert.Assert(t, err != nil)
|
||||||
}
|
}
|
||||||
|
@ -348,7 +348,7 @@ func Test_Validate_Validate_Unsupported(t *testing.T) {
|
||||||
|
|
||||||
err = json.Unmarshal(rawValidate, &validate)
|
err = json.Unmarshal(rawValidate, &validate)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
checker := NewMockValidateFactory(&kyverno.Rule{Validation: validate})
|
checker := NewMockValidateFactory(&kyverno.Rule{Validation: &validate})
|
||||||
if _, _, err := checker.Validate(context.TODO(), nil); err != nil {
|
if _, _, err := checker.Validate(context.TODO(), nil); err != nil {
|
||||||
assert.Assert(t, err != nil)
|
assert.Assert(t, err != nil)
|
||||||
}
|
}
|
||||||
|
@ -374,7 +374,7 @@ func Test_Validate_Validate_Unsupported(t *testing.T) {
|
||||||
err = json.Unmarshal(rawValidate, &validate)
|
err = json.Unmarshal(rawValidate, &validate)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
|
||||||
checker = NewMockValidateFactory(&kyverno.Rule{Validation: validate})
|
checker = NewMockValidateFactory(&kyverno.Rule{Validation: &validate})
|
||||||
if _, _, err := checker.Validate(context.TODO(), nil); err != nil {
|
if _, _, err := checker.Validate(context.TODO(), nil); err != nil {
|
||||||
assert.Assert(t, err != nil)
|
assert.Assert(t, err != nil)
|
||||||
}
|
}
|
||||||
|
|
|
@ -233,7 +233,7 @@ func createRule(f *fuzz.ConsumeFuzzer) (*kyvernov1.Rule, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return rule, err
|
return rule, err
|
||||||
}
|
}
|
||||||
rule.Validation = *v
|
rule.Validation = v
|
||||||
}
|
}
|
||||||
|
|
||||||
setGeneration, err := f.GetBool()
|
setGeneration, err := f.GetBool()
|
||||||
|
|
|
@ -738,8 +738,10 @@ func buildContext(rule *kyvernov1.Rule, background bool, target bool) *enginecon
|
||||||
addContextVariables(rule.Context, ctx)
|
addContextVariables(rule.Context, ctx)
|
||||||
addImageVerifyVariables(rule, ctx)
|
addImageVerifyVariables(rule, ctx)
|
||||||
|
|
||||||
for _, fe := range rule.Validation.ForEachValidation {
|
if rule.Validation != nil {
|
||||||
addContextVariables(fe.Context, ctx)
|
for _, fe := range rule.Validation.ForEachValidation {
|
||||||
|
addContextVariables(fe.Context, ctx)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if rule.Mutation != nil {
|
if rule.Mutation != nil {
|
||||||
for _, fe := range rule.Mutation.ForEachMutation {
|
for _, fe := range rule.Mutation.ForEachMutation {
|
||||||
|
@ -943,29 +945,27 @@ func ruleOnlyDealsWithResourceMetaData(rule kyvernov1.Rule) bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if rule.Validation != nil {
|
||||||
patternMap, _ := rule.Validation.GetPattern().(map[string]interface{})
|
patternMap, _ := rule.Validation.GetPattern().(map[string]interface{})
|
||||||
for k := range patternMap {
|
|
||||||
if k != "metadata" {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
anyPatterns, err := rule.Validation.DeserializeAnyPattern()
|
|
||||||
if err != nil {
|
|
||||||
logging.Error(err, "failed to deserialize anyPattern, expect type array")
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, pattern := range anyPatterns {
|
|
||||||
patternMap, _ := pattern.(map[string]interface{})
|
|
||||||
for k := range patternMap {
|
for k := range patternMap {
|
||||||
if k != "metadata" {
|
if k != "metadata" {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
anyPatterns, err := rule.Validation.DeserializeAnyPattern()
|
||||||
|
if err != nil {
|
||||||
|
logging.Error(err, "failed to deserialize anyPattern, expect type array")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for _, pattern := range anyPatterns {
|
||||||
|
patternMap, _ := pattern.(map[string]interface{})
|
||||||
|
for k := range patternMap {
|
||||||
|
if k != "metadata" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1018,20 +1018,21 @@ func validateResources(path *field.Path, rule kyvernov1.Rule) (string, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// validating the values present under validate.conditions, if they exist
|
// validating the values present under validate.conditions, if they exist
|
||||||
if rule.Validation.Deny != nil {
|
if rule.Validation != nil {
|
||||||
if target := rule.Validation.Deny.GetAnyAllConditions(); target != nil {
|
if rule.Validation.Deny != nil {
|
||||||
if path, err := validateConditions(target, "conditions"); err != nil {
|
if target := rule.Validation.Deny.GetAnyAllConditions(); target != nil {
|
||||||
return fmt.Sprintf("validate.deny.%s", path), err
|
if path, err := validateConditions(target, "conditions"); err != nil {
|
||||||
}
|
return fmt.Sprintf("validate.deny.%s", path), err
|
||||||
if path, err := validateRawJSONConditionOperator(target, "conditions"); err != nil {
|
}
|
||||||
return fmt.Sprintf("validate.deny.%s", path), err
|
if path, err := validateRawJSONConditionOperator(target, "conditions"); err != nil {
|
||||||
|
return fmt.Sprintf("validate.deny.%s", path), err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if len(rule.Validation.ForEachValidation) != 0 {
|
||||||
|
if path, err := validateValidationForEach(rule.Validation.ForEachValidation, "validate.foreach"); err != nil {
|
||||||
if len(rule.Validation.ForEachValidation) != 0 {
|
return path, err
|
||||||
if path, err := validateValidationForEach(rule.Validation.ForEachValidation, "validate.foreach"); err != nil {
|
}
|
||||||
return path, err
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1292,7 +1293,7 @@ func validateRuleContext(rule kyvernov1.Rule) error {
|
||||||
}
|
}
|
||||||
// if it the rule uses kyverno-json we add some constraints on the name of context entries to make
|
// if it the rule uses kyverno-json we add some constraints on the name of context entries to make
|
||||||
// sure we can create the corresponding bindings
|
// sure we can create the corresponding bindings
|
||||||
if rule.Validation.Assert.Value != nil {
|
if rule.Validation != nil && rule.Validation.Assert.Value != nil {
|
||||||
if !bindingIdentifier.MatchString(entry.Name) {
|
if !bindingIdentifier.MatchString(entry.Name) {
|
||||||
return fmt.Errorf("context entry name %s is invalid, it must be a single word when the validation rule uses `assert`", entry.Name)
|
return fmt.Errorf("context entry name %s is invalid, it must be a single word when the validation rule uses `assert`", entry.Name)
|
||||||
}
|
}
|
||||||
|
@ -1534,7 +1535,7 @@ func validateWildcard(kinds []string, background bool, rule kyvernov1.Rule) erro
|
||||||
return fmt.Errorf("wildcard policy can not deal with more than one kind")
|
return fmt.Errorf("wildcard policy can not deal with more than one kind")
|
||||||
}
|
}
|
||||||
if slices.Contains(kinds, "*") {
|
if slices.Contains(kinds, "*") {
|
||||||
if rule.HasGenerate() || rule.HasVerifyImages() || rule.Validation.ForEachValidation != nil {
|
if rule.HasGenerate() || rule.HasVerifyImages() || (rule.Validation != nil && rule.Validation.ForEachValidation != nil) {
|
||||||
return fmt.Errorf("wildcard policy does not support rule type")
|
return fmt.Errorf("wildcard policy does not support rule type")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1737,25 +1738,25 @@ func checkDeprecatedRawJSONConditionOperator(c apiextensions.JSON, warnings *[]s
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkForDeprecatedOperatorsInRule(rule kyvernov1.Rule, warnings *[]string) {
|
func checkForDeprecatedOperatorsInRule(rule kyvernov1.Rule, warnings *[]string) {
|
||||||
if rule.Validation.Deny != nil {
|
if rule.Validation != nil {
|
||||||
if target := rule.Validation.Deny.GetAnyAllConditions(); target != nil {
|
if rule.Validation.Deny != nil {
|
||||||
checkDeprecatedRawJSONConditionOperator(target, warnings)
|
if target := rule.Validation.Deny.GetAnyAllConditions(); target != nil {
|
||||||
}
|
checkDeprecatedRawJSONConditionOperator(target, warnings)
|
||||||
}
|
|
||||||
|
|
||||||
if len(rule.Validation.ForEachValidation) != 0 {
|
|
||||||
for _, fe := range rule.Validation.ForEachValidation {
|
|
||||||
if fe.AnyAllConditions != nil {
|
|
||||||
checkDeprecatedAnyAllConditionOperator(*fe.AnyAllConditions, warnings)
|
|
||||||
}
|
}
|
||||||
if fe.Deny != nil {
|
}
|
||||||
if target := fe.Deny.GetAnyAllConditions(); target != nil {
|
if len(rule.Validation.ForEachValidation) != 0 {
|
||||||
checkDeprecatedRawJSONConditionOperator(target, warnings)
|
for _, fe := range rule.Validation.ForEachValidation {
|
||||||
|
if fe.AnyAllConditions != nil {
|
||||||
|
checkDeprecatedAnyAllConditionOperator(*fe.AnyAllConditions, warnings)
|
||||||
|
}
|
||||||
|
if fe.Deny != nil {
|
||||||
|
if target := fe.Deny.GetAnyAllConditions(); target != nil {
|
||||||
|
checkDeprecatedRawJSONConditionOperator(target, warnings)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(rule.VerifyImages) != 0 {
|
if len(rule.VerifyImages) != 0 {
|
||||||
for _, vi := range rule.VerifyImages {
|
for _, vi := range rule.VerifyImages {
|
||||||
for _, att := range vi.Attestations {
|
for _, att := range vi.Attestations {
|
||||||
|
|
|
@ -37,7 +37,7 @@ func Test_PolicyValidationWithInvalidVariable(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Validation: kyverno.Validation{
|
Validation: &kyverno.Validation{
|
||||||
Message: "{{ bar }} world!",
|
Message: "{{ bar }} world!",
|
||||||
Deny: &kyverno.Deny{},
|
Deny: &kyverno.Deny{},
|
||||||
},
|
},
|
||||||
|
@ -1661,7 +1661,7 @@ func Test_ValidateNamespace(t *testing.T) {
|
||||||
{
|
{
|
||||||
Name: "require-labels",
|
Name: "require-labels",
|
||||||
MatchResources: kyverno.MatchResources{ResourceDescription: kyverno.ResourceDescription{Kinds: []string{"Pod"}}},
|
MatchResources: kyverno.MatchResources{ResourceDescription: kyverno.ResourceDescription{Kinds: []string{"Pod"}}},
|
||||||
Validation: kyverno.Validation{
|
Validation: &kyverno.Validation{
|
||||||
Message: "label 'app.kubernetes.io/name' is required",
|
Message: "label 'app.kubernetes.io/name' is required",
|
||||||
RawPattern: &apiextv1.JSON{Raw: []byte(`"metadata": {"lables": {"app.kubernetes.io/name": "?*"}}`)},
|
RawPattern: &apiextv1.JSON{Raw: []byte(`"metadata": {"lables": {"app.kubernetes.io/name": "?*"}}`)},
|
||||||
},
|
},
|
||||||
|
@ -1724,7 +1724,7 @@ func Test_ValidateNamespace(t *testing.T) {
|
||||||
{
|
{
|
||||||
Name: "require-labels",
|
Name: "require-labels",
|
||||||
MatchResources: kyverno.MatchResources{ResourceDescription: kyverno.ResourceDescription{Kinds: []string{"Pod"}}},
|
MatchResources: kyverno.MatchResources{ResourceDescription: kyverno.ResourceDescription{Kinds: []string{"Pod"}}},
|
||||||
Validation: kyverno.Validation{
|
Validation: &kyverno.Validation{
|
||||||
Message: "label 'app.kubernetes.io/name' is required",
|
Message: "label 'app.kubernetes.io/name' is required",
|
||||||
RawPattern: &apiextv1.JSON{Raw: []byte(`"metadata": {"lables": {"app.kubernetes.io/name": "?*"}}`)},
|
RawPattern: &apiextv1.JSON{Raw: []byte(`"metadata": {"lables": {"app.kubernetes.io/name": "?*"}}`)},
|
||||||
},
|
},
|
||||||
|
@ -1756,7 +1756,7 @@ func Test_ValidateNamespace(t *testing.T) {
|
||||||
{
|
{
|
||||||
Name: "require-labels",
|
Name: "require-labels",
|
||||||
MatchResources: kyverno.MatchResources{ResourceDescription: kyverno.ResourceDescription{Kinds: []string{"Pod"}}},
|
MatchResources: kyverno.MatchResources{ResourceDescription: kyverno.ResourceDescription{Kinds: []string{"Pod"}}},
|
||||||
Validation: kyverno.Validation{
|
Validation: &kyverno.Validation{
|
||||||
Message: "label 'app.kubernetes.io/name' is required",
|
Message: "label 'app.kubernetes.io/name' is required",
|
||||||
RawPattern: &apiextv1.JSON{Raw: []byte(`"metadata": {"lables": {"app.kubernetes.io/name": "?*"}}`)},
|
RawPattern: &apiextv1.JSON{Raw: []byte(`"metadata": {"lables": {"app.kubernetes.io/name": "?*"}}`)},
|
||||||
},
|
},
|
||||||
|
@ -1788,7 +1788,7 @@ func Test_ValidateNamespace(t *testing.T) {
|
||||||
{
|
{
|
||||||
Name: "require-labels",
|
Name: "require-labels",
|
||||||
MatchResources: kyverno.MatchResources{ResourceDescription: kyverno.ResourceDescription{Kinds: []string{"Pod"}}},
|
MatchResources: kyverno.MatchResources{ResourceDescription: kyverno.ResourceDescription{Kinds: []string{"Pod"}}},
|
||||||
Validation: kyverno.Validation{
|
Validation: &kyverno.Validation{
|
||||||
Message: "label 'app.kubernetes.io/name' is required",
|
Message: "label 'app.kubernetes.io/name' is required",
|
||||||
RawPattern: &apiextv1.JSON{Raw: []byte(`"metadata": {"lables": {"app.kubernetes.io/name": "?*"}}`)},
|
RawPattern: &apiextv1.JSON{Raw: []byte(`"metadata": {"lables": {"app.kubernetes.io/name": "?*"}}`)},
|
||||||
},
|
},
|
||||||
|
@ -1820,7 +1820,7 @@ func Test_ValidateNamespace(t *testing.T) {
|
||||||
{
|
{
|
||||||
Name: "require-labels",
|
Name: "require-labels",
|
||||||
MatchResources: kyverno.MatchResources{ResourceDescription: kyverno.ResourceDescription{Kinds: []string{"Pod"}}},
|
MatchResources: kyverno.MatchResources{ResourceDescription: kyverno.ResourceDescription{Kinds: []string{"Pod"}}},
|
||||||
Validation: kyverno.Validation{
|
Validation: &kyverno.Validation{
|
||||||
Message: "label 'app.kubernetes.io/name' is required",
|
Message: "label 'app.kubernetes.io/name' is required",
|
||||||
RawPattern: &apiextv1.JSON{Raw: []byte(`"metadata": {"lables": {"app.kubernetes.io/name": "?*"}}`)},
|
RawPattern: &apiextv1.JSON{Raw: []byte(`"metadata": {"lables": {"app.kubernetes.io/name": "?*"}}`)},
|
||||||
},
|
},
|
||||||
|
@ -1852,7 +1852,7 @@ func Test_ValidateNamespace(t *testing.T) {
|
||||||
{
|
{
|
||||||
Name: "require-labels",
|
Name: "require-labels",
|
||||||
MatchResources: kyverno.MatchResources{ResourceDescription: kyverno.ResourceDescription{Kinds: []string{"Pod"}}},
|
MatchResources: kyverno.MatchResources{ResourceDescription: kyverno.ResourceDescription{Kinds: []string{"Pod"}}},
|
||||||
Validation: kyverno.Validation{
|
Validation: &kyverno.Validation{
|
||||||
Message: "label 'app.kubernetes.io/name' is required",
|
Message: "label 'app.kubernetes.io/name' is required",
|
||||||
RawPattern: &apiextv1.JSON{Raw: []byte(`"metadata": {"lables": {"app.kubernetes.io/name": "?*"}}`)},
|
RawPattern: &apiextv1.JSON{Raw: []byte(`"metadata": {"lables": {"app.kubernetes.io/name": "?*"}}`)},
|
||||||
},
|
},
|
||||||
|
@ -1883,7 +1883,7 @@ func Test_ValidateNamespace(t *testing.T) {
|
||||||
{
|
{
|
||||||
Name: "require-labels",
|
Name: "require-labels",
|
||||||
MatchResources: kyverno.MatchResources{ResourceDescription: kyverno.ResourceDescription{Kinds: []string{"Pod"}}},
|
MatchResources: kyverno.MatchResources{ResourceDescription: kyverno.ResourceDescription{Kinds: []string{"Pod"}}},
|
||||||
Validation: kyverno.Validation{
|
Validation: &kyverno.Validation{
|
||||||
Message: "label 'app.kubernetes.io/name' is required",
|
Message: "label 'app.kubernetes.io/name' is required",
|
||||||
RawPattern: &apiextv1.JSON{Raw: []byte(`"metadata": {"lables": {"app.kubernetes.io/name": "?*"}}`)},
|
RawPattern: &apiextv1.JSON{Raw: []byte(`"metadata": {"lables": {"app.kubernetes.io/name": "?*"}}`)},
|
||||||
},
|
},
|
||||||
|
@ -1916,7 +1916,7 @@ func Test_ValidateNamespace(t *testing.T) {
|
||||||
{
|
{
|
||||||
Name: "require-labels",
|
Name: "require-labels",
|
||||||
MatchResources: kyverno.MatchResources{ResourceDescription: kyverno.ResourceDescription{Kinds: []string{"Pod"}}},
|
MatchResources: kyverno.MatchResources{ResourceDescription: kyverno.ResourceDescription{Kinds: []string{"Pod"}}},
|
||||||
Validation: kyverno.Validation{
|
Validation: &kyverno.Validation{
|
||||||
Message: "label 'app.kubernetes.io/name' is required",
|
Message: "label 'app.kubernetes.io/name' is required",
|
||||||
RawPattern: &apiextv1.JSON{Raw: []byte(`"metadata": {"lables": {"app.kubernetes.io/name": "?*"}}`)},
|
RawPattern: &apiextv1.JSON{Raw: []byte(`"metadata": {"lables": {"app.kubernetes.io/name": "?*"}}`)},
|
||||||
},
|
},
|
||||||
|
@ -1948,7 +1948,7 @@ func Test_ValidateNamespace(t *testing.T) {
|
||||||
{
|
{
|
||||||
Name: "require-labels",
|
Name: "require-labels",
|
||||||
MatchResources: kyverno.MatchResources{ResourceDescription: kyverno.ResourceDescription{Kinds: []string{"Pod"}}},
|
MatchResources: kyverno.MatchResources{ResourceDescription: kyverno.ResourceDescription{Kinds: []string{"Pod"}}},
|
||||||
Validation: kyverno.Validation{
|
Validation: &kyverno.Validation{
|
||||||
Message: "label 'app.kubernetes.io/name' is required",
|
Message: "label 'app.kubernetes.io/name' is required",
|
||||||
RawPattern: &apiextv1.JSON{Raw: []byte(`"metadata": {"lables": {"app.kubernetes.io/name": "?*"}}`)},
|
RawPattern: &apiextv1.JSON{Raw: []byte(`"metadata": {"lables": {"app.kubernetes.io/name": "?*"}}`)},
|
||||||
},
|
},
|
||||||
|
@ -1980,7 +1980,7 @@ func Test_ValidateNamespace(t *testing.T) {
|
||||||
{
|
{
|
||||||
Name: "require-labels",
|
Name: "require-labels",
|
||||||
MatchResources: kyverno.MatchResources{ResourceDescription: kyverno.ResourceDescription{Kinds: []string{"Pod"}}},
|
MatchResources: kyverno.MatchResources{ResourceDescription: kyverno.ResourceDescription{Kinds: []string{"Pod"}}},
|
||||||
Validation: kyverno.Validation{
|
Validation: &kyverno.Validation{
|
||||||
Message: "label 'app.kubernetes.io/name' is required",
|
Message: "label 'app.kubernetes.io/name' is required",
|
||||||
RawPattern: &apiextv1.JSON{Raw: []byte(`"metadata": {"lables": {"app.kubernetes.io/name": "?*"}}`)},
|
RawPattern: &apiextv1.JSON{Raw: []byte(`"metadata": {"lables": {"app.kubernetes.io/name": "?*"}}`)},
|
||||||
},
|
},
|
||||||
|
@ -2011,7 +2011,7 @@ func Test_ValidateNamespace(t *testing.T) {
|
||||||
{
|
{
|
||||||
Name: "require-labels",
|
Name: "require-labels",
|
||||||
MatchResources: kyverno.MatchResources{ResourceDescription: kyverno.ResourceDescription{Kinds: []string{"Pod"}}},
|
MatchResources: kyverno.MatchResources{ResourceDescription: kyverno.ResourceDescription{Kinds: []string{"Pod"}}},
|
||||||
Validation: kyverno.Validation{
|
Validation: &kyverno.Validation{
|
||||||
Message: "label 'app.kubernetes.io/name' is required",
|
Message: "label 'app.kubernetes.io/name' is required",
|
||||||
RawPattern: &apiextv1.JSON{Raw: []byte(`"metadata": {"lables": {"app.kubernetes.io/name": "?*"}}`)},
|
RawPattern: &apiextv1.JSON{Raw: []byte(`"metadata": {"lables": {"app.kubernetes.io/name": "?*"}}`)},
|
||||||
},
|
},
|
||||||
|
@ -2041,7 +2041,7 @@ func Test_ValidateNamespace(t *testing.T) {
|
||||||
{
|
{
|
||||||
Name: "require-labels",
|
Name: "require-labels",
|
||||||
MatchResources: kyverno.MatchResources{ResourceDescription: kyverno.ResourceDescription{Kinds: []string{"Pod"}}},
|
MatchResources: kyverno.MatchResources{ResourceDescription: kyverno.ResourceDescription{Kinds: []string{"Pod"}}},
|
||||||
Validation: kyverno.Validation{
|
Validation: &kyverno.Validation{
|
||||||
Message: "label 'app.kubernetes.io/name' is required",
|
Message: "label 'app.kubernetes.io/name' is required",
|
||||||
RawPattern: &apiextv1.JSON{Raw: []byte(`"metadata": {"lables": {"app.kubernetes.io/name": "?*"}}`)},
|
RawPattern: &apiextv1.JSON{Raw: []byte(`"metadata": {"lables": {"app.kubernetes.io/name": "?*"}}`)},
|
||||||
},
|
},
|
||||||
|
|
|
@ -71,7 +71,7 @@ func TestBlockRequest(t *testing.T) {
|
||||||
Rules: []kyvernov1.Rule{
|
Rules: []kyvernov1.Rule{
|
||||||
{
|
{
|
||||||
Name: "rule-audit",
|
Name: "rule-audit",
|
||||||
Validation: kyvernov1.Validation{
|
Validation: &kyvernov1.Validation{
|
||||||
FailureAction: &audit,
|
FailureAction: &audit,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -87,7 +87,7 @@ func TestBlockRequest(t *testing.T) {
|
||||||
Rules: []kyvernov1.Rule{
|
Rules: []kyvernov1.Rule{
|
||||||
{
|
{
|
||||||
Name: "rule-enforce",
|
Name: "rule-enforce",
|
||||||
Validation: kyvernov1.Validation{
|
Validation: &kyvernov1.Validation{
|
||||||
FailureAction: &enforce,
|
FailureAction: &enforce,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
Loading…
Add table
Reference in a new issue