diff --git a/api/kyverno/v1/rule_types.go b/api/kyverno/v1/rule_types.go index 0311d9ad4f..3b8a516009 100644 --- a/api/kyverno/v1/rule_types.go +++ b/api/kyverno/v1/rule_types.go @@ -3,9 +3,9 @@ package v1 import ( "encoding/json" "fmt" - "reflect" "github.com/kyverno/kyverno/pkg/pss/utils" + datautils "github.com/kyverno/kyverno/pkg/utils/data" wildcard "github.com/kyverno/kyverno/pkg/utils/wildcard" "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions" apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" @@ -96,12 +96,17 @@ type Rule struct { // HasMutate checks for mutate rule func (r *Rule) HasMutate() bool { - return !reflect.DeepEqual(r.Mutation, Mutation{}) + return !datautils.DeepEqual(r.Mutation, Mutation{}) } // HasVerifyImages checks for verifyImages rule func (r *Rule) HasVerifyImages() bool { - return r.VerifyImages != nil && !reflect.DeepEqual(r.VerifyImages, ImageVerification{}) + for _, verifyImage := range r.VerifyImages { + if !datautils.DeepEqual(verifyImage, ImageVerification{}) { + return true + } + } + return false } // HasYAMLSignatureVerify checks for validate.manifests rule @@ -133,12 +138,12 @@ func (p *ClusterPolicy) HasYAMLSignatureVerify() bool { // HasValidate checks for validate rule func (r *Rule) HasValidate() bool { - return !reflect.DeepEqual(r.Validation, Validation{}) + return !datautils.DeepEqual(r.Validation, Validation{}) } // HasGenerate checks for generate rule func (r *Rule) HasGenerate() bool { - return !reflect.DeepEqual(r.Generation, Generation{}) + return !datautils.DeepEqual(r.Generation, Generation{}) } // IsMutateExisting checks if the mutate rule applies to existing resources @@ -195,14 +200,14 @@ func (r *Rule) ValidateMatchExcludeConflict(path *field.Path) (errs field.ErrorL if len(r.MatchResources.Any) > 0 && len(r.ExcludeResources.Any) > 0 { for _, rmr := range r.MatchResources.Any { for _, rer := range r.ExcludeResources.Any { - if reflect.DeepEqual(rmr, rer) { + if datautils.DeepEqual(rmr, rer) { return append(errs, field.Invalid(path, r, "Rule is matching an empty set")) } } } return errs } - if reflect.DeepEqual(r.ExcludeResources, MatchResources{}) { + if datautils.DeepEqual(r.ExcludeResources, MatchResources{}) { return errs } excludeRoles := sets.New(r.ExcludeResources.Roles...) @@ -340,7 +345,7 @@ func (r *Rule) ValidateMatchExcludeConflict(path *field.Path) (errs field.ErrorL return errs } if r.MatchResources.Annotations != nil && r.ExcludeResources.Annotations != nil { - if !(reflect.DeepEqual(r.MatchResources.Annotations, r.ExcludeResources.Annotations)) { + if !datautils.DeepEqual(r.MatchResources.Annotations, r.ExcludeResources.Annotations) { return errs } } diff --git a/api/kyverno/v2alpha1/cleanup_policy_types.go b/api/kyverno/v2alpha1/cleanup_policy_types.go index 47c11f9231..479249d0c8 100644 --- a/api/kyverno/v2alpha1/cleanup_policy_types.go +++ b/api/kyverno/v2alpha1/cleanup_policy_types.go @@ -17,10 +17,9 @@ limitations under the License. package v2alpha1 import ( - "reflect" - kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" kyvernov2beta1 "github.com/kyverno/kyverno/api/kyverno/v2beta1" + datautils "github.com/kyverno/kyverno/pkg/utils/data" "github.com/robfig/cron" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/sets" @@ -210,14 +209,14 @@ func (spec *CleanupPolicySpec) ValidateMatchExcludeConflict(path *field.Path) (e if len(spec.MatchResources.Any) > 0 && len(spec.ExcludeResources.Any) > 0 { for _, rmr := range spec.MatchResources.Any { for _, rer := range spec.ExcludeResources.Any { - if reflect.DeepEqual(rmr, rer) { + if datautils.DeepEqual(rmr, rer) { return append(errs, field.Invalid(path, spec, "CleanupPolicy is matching an empty set")) } } } return errs } - if reflect.DeepEqual(spec.ExcludeResources, kyvernov2beta1.MatchResources{}) { + if datautils.DeepEqual(spec.ExcludeResources, &kyvernov2beta1.MatchResources{}) { return errs } return append(errs, field.Invalid(path, spec, "CleanupPolicy is matching an empty set")) diff --git a/api/kyverno/v2beta1/rule_types.go b/api/kyverno/v2beta1/rule_types.go index a8afee7e54..0861af36aa 100644 --- a/api/kyverno/v2beta1/rule_types.go +++ b/api/kyverno/v2beta1/rule_types.go @@ -2,9 +2,9 @@ package v2beta1 import ( "fmt" - "reflect" kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" + datautils "github.com/kyverno/kyverno/pkg/utils/data" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/validation/field" ) @@ -64,12 +64,17 @@ type Rule struct { // HasMutate checks for mutate rule func (r *Rule) HasMutate() bool { - return !reflect.DeepEqual(r.Mutation, kyvernov1.Mutation{}) + return !datautils.DeepEqual(r.Mutation, kyvernov1.Mutation{}) } // HasVerifyImages checks for verifyImages rule func (r *Rule) HasVerifyImages() bool { - return r.VerifyImages != nil && !reflect.DeepEqual(r.VerifyImages, ImageVerification{}) + for _, verifyImage := range r.VerifyImages { + if !datautils.DeepEqual(verifyImage, ImageVerification{}) { + return true + } + } + return false } // HasYAMLSignatureVerify checks for validate.manifests rule @@ -101,12 +106,12 @@ func (p *ClusterPolicy) HasYAMLSignatureVerify() bool { // HasValidate checks for validate rule func (r *Rule) HasValidate() bool { - return !reflect.DeepEqual(r.Validation, Validation{}) + return !datautils.DeepEqual(r.Validation, Validation{}) } // HasGenerate checks for generate rule func (r *Rule) HasGenerate() bool { - return !reflect.DeepEqual(r.Generation, kyvernov1.Generation{}) + return !datautils.DeepEqual(r.Generation, kyvernov1.Generation{}) } // IsMutateExisting checks if the mutate rule applies to existing resources @@ -158,17 +163,17 @@ func (r *Rule) ValidateMatchExcludeConflict(path *field.Path) (errs field.ErrorL if len(r.MatchResources.Any) > 0 && len(r.ExcludeResources.Any) > 0 { for _, rmr := range r.MatchResources.Any { for _, rer := range r.ExcludeResources.Any { - if reflect.DeepEqual(rmr, rer) { + if datautils.DeepEqual(rmr, rer) { return append(errs, field.Invalid(path, r, "Rule is matching an empty set")) } } } return errs } - if reflect.DeepEqual(r.ExcludeResources.Any, r.MatchResources.Any) { + if datautils.DeepEqual(r.ExcludeResources.Any, r.MatchResources.Any) { return errs } - if reflect.DeepEqual(r.ExcludeResources.All, r.MatchResources.All) { + if datautils.DeepEqual(r.ExcludeResources.All, r.MatchResources.All) { return errs } return append(errs, field.Invalid(path, r, "Rule is matching an empty set")) diff --git a/pkg/utils/data/equal.go b/pkg/utils/data/equal.go new file mode 100644 index 0000000000..acbce59add --- /dev/null +++ b/pkg/utils/data/equal.go @@ -0,0 +1,7 @@ +package data + +import "reflect" + +func DeepEqual[T any](a T, b T) bool { + return reflect.DeepEqual(a, b) +}