From 594a04db01186197e1df88b1d8bd329f84385b83 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Charles-Edouard=20Br=C3=A9t=C3=A9ch=C3=A9?=
 <charled.breteche@gmail.com>
Date: Tue, 5 Apr 2022 17:12:22 +0200
Subject: [PATCH] refactor: simplify autogen package (#3532)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Charles-Edouard Brétéché <charled.breteche@gmail.com>

Co-authored-by: Vyankatesh Kudtarkar <vyankateshkd@gmail.com>
Co-authored-by: shuting <shuting@nirmata.com>
---
 api/kyverno/v1/match_resources_types.go |  12 +
 api/kyverno/v1/rule_types.go            |  25 --
 pkg/autogen/autogen.go                  | 150 +++----
 pkg/autogen/autogen_test.go             |  46 +-
 pkg/autogen/rule.go                     | 552 +++++++++---------------
 pkg/autogen/utils.go                    |  73 ----
 pkg/policy/existing.go                  |   3 +-
 pkg/webhookconfig/configmanager.go      |   6 +-
 8 files changed, 331 insertions(+), 536 deletions(-)
 delete mode 100644 pkg/autogen/utils.go

diff --git a/api/kyverno/v1/match_resources_types.go b/api/kyverno/v1/match_resources_types.go
index 915dbc2146..de93c4a886 100644
--- a/api/kyverno/v1/match_resources_types.go
+++ b/api/kyverno/v1/match_resources_types.go
@@ -30,6 +30,18 @@ type MatchResources struct {
 	ResourceDescription `json:"resources,omitempty" yaml:"resources,omitempty"`
 }
 
+// GetKinds returns all kinds
+func (m *MatchResources) GetKinds() []string {
+	kinds := m.ResourceDescription.Kinds
+	for _, value := range m.All {
+		kinds = append(kinds, value.ResourceDescription.Kinds...)
+	}
+	for _, value := range m.Any {
+		kinds = append(kinds, value.ResourceDescription.Kinds...)
+	}
+	return kinds
+}
+
 // Validate implements programmatic validation
 func (m *MatchResources) Validate(path *field.Path, namespaced bool, clusterResources sets.String) (errs field.ErrorList) {
 	if len(m.Any) > 0 && len(m.All) > 0 {
diff --git a/api/kyverno/v1/rule_types.go b/api/kyverno/v1/rule_types.go
index 7225a1f83a..1199f0c432 100644
--- a/api/kyverno/v1/rule_types.go
+++ b/api/kyverno/v1/rule_types.go
@@ -81,31 +81,6 @@ func (r *Rule) HasGenerate() bool {
 	return !reflect.DeepEqual(r.Generation, Generation{})
 }
 
-// MatchKinds returns a slice of all kinds to match
-func (r *Rule) MatchKinds() []string {
-	matchKinds := r.MatchResources.ResourceDescription.Kinds
-	for _, value := range r.MatchResources.All {
-		matchKinds = append(matchKinds, value.ResourceDescription.Kinds...)
-	}
-	for _, value := range r.MatchResources.Any {
-		matchKinds = append(matchKinds, value.ResourceDescription.Kinds...)
-	}
-
-	return matchKinds
-}
-
-// ExcludeKinds returns a slice of all kinds to exclude
-func (r *Rule) ExcludeKinds() []string {
-	excludeKinds := r.ExcludeResources.ResourceDescription.Kinds
-	for _, value := range r.ExcludeResources.All {
-		excludeKinds = append(excludeKinds, value.ResourceDescription.Kinds...)
-	}
-	for _, value := range r.ExcludeResources.Any {
-		excludeKinds = append(excludeKinds, value.ResourceDescription.Kinds...)
-	}
-	return excludeKinds
-}
-
 func (r *Rule) GetAnyAllConditions() apiextensions.JSON {
 	return FromJSON(r.RawAnyAllConditions)
 }
diff --git a/pkg/autogen/autogen.go b/pkg/autogen/autogen.go
index c0b4cc1598..0f0f96b82c 100644
--- a/pkg/autogen/autogen.go
+++ b/pkg/autogen/autogen.go
@@ -11,7 +11,9 @@ import (
 	"github.com/kyverno/kyverno/pkg/toggle"
 	"github.com/kyverno/kyverno/pkg/utils"
 	jsonutils "github.com/kyverno/kyverno/pkg/utils/json"
+	kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/util/sets"
 	log "sigs.k8s.io/controller-runtime/pkg/log"
 )
 
@@ -22,6 +24,46 @@ const (
 	PodControllers = "DaemonSet,Deployment,Job,StatefulSet,CronJob"
 )
 
+var (
+	podControllersKindsSet = sets.NewString(append(strings.Split(PodControllers, ","), "Pod")...)
+	podSet                 = sets.NewString("Pod")
+)
+
+func isKindOtherthanPod(kinds []string) bool {
+	if len(kinds) > 1 && kubeutils.ContainsKind(kinds, "Pod") {
+		return true
+	}
+	return false
+}
+
+func checkAutogenSupport(needed *bool, subjects ...kyverno.ResourceDescription) bool {
+	for _, subject := range subjects {
+		if subject.Name != "" || subject.Selector != nil || subject.Annotations != nil || isKindOtherthanPod(subject.Kinds) {
+			return false
+		}
+		if needed != nil {
+			*needed = *needed || podControllersKindsSet.HasAny(subject.Kinds...)
+		}
+	}
+	return true
+}
+
+// stripCronJob removes CronJob from controllers
+func stripCronJob(controllers string) string {
+	var newControllers []string
+	controllerArr := strings.Split(controllers, ",")
+	for _, c := range controllerArr {
+		if c == PodControllerCronJob {
+			continue
+		}
+		newControllers = append(newControllers, c)
+	}
+	if len(newControllers) == 0 {
+		return ""
+	}
+	return strings.Join(newControllers, ",")
+}
+
 // CanAutoGen checks whether the rule(s) (in policy) can be applied to Pod controllers
 // returns controllers as:
 // - "" if:
@@ -31,82 +73,44 @@ const (
 //          - mutate.Patches/mutate.PatchesJSON6902/validate.deny/generate rule is defined
 // - otherwise it returns all pod controllers
 func CanAutoGen(spec *kyverno.Spec, log logr.Logger) (applyAutoGen bool, controllers string) {
-	var needAutogen bool
-	rules := spec.Rules
-	for _, rule := range rules {
-		match := rule.MatchResources
-		exclude := rule.ExcludeResources
-
-		if match.ResourceDescription.Name != "" || match.ResourceDescription.Selector != nil || match.ResourceDescription.Annotations != nil ||
-			exclude.ResourceDescription.Name != "" || exclude.ResourceDescription.Selector != nil || exclude.ResourceDescription.Annotations != nil {
+	needed := false
+	for _, rule := range spec.Rules {
+		if rule.Mutation.PatchesJSON6902 != "" || rule.HasGenerate() {
+			return false, "none"
+		}
+		match, exclude := rule.MatchResources, rule.ExcludeResources
+		if !checkAutogenSupport(&needed, match.ResourceDescription, exclude.ResourceDescription) {
 			log.V(3).Info("skip generating rule on pod controllers: Name / Selector in resource description may not be applicable.", "rule", rule.Name)
 			return false, ""
 		}
-
-		if isKindOtherthanPod(match.Kinds) || isKindOtherthanPod(exclude.Kinds) {
-			return false, ""
-		}
-
-		needAutogen = hasAutogenKinds(match.Kinds) || hasAutogenKinds(exclude.Kinds)
-
 		for _, value := range match.Any {
-			if isKindOtherthanPod(value.Kinds) {
-				return false, ""
-			}
-			if !needAutogen {
-				needAutogen = hasAutogenKinds(value.Kinds)
-			}
-			if value.Name != "" || value.Selector != nil || value.Annotations != nil {
+			if !checkAutogenSupport(&needed, value.ResourceDescription) {
 				log.V(3).Info("skip generating rule on pod controllers: Name / Selector in match any block is not be applicable.", "rule", rule.Name)
 				return false, ""
 			}
 		}
 		for _, value := range match.All {
-			if isKindOtherthanPod(value.Kinds) {
-				return false, ""
-			}
-			if !needAutogen {
-				needAutogen = hasAutogenKinds(value.Kinds)
-			}
-			if value.Name != "" || value.Selector != nil || value.Annotations != nil {
+			if !checkAutogenSupport(&needed, value.ResourceDescription) {
 				log.V(3).Info("skip generating rule on pod controllers: Name / Selector in match all block is not be applicable.", "rule", rule.Name)
 				return false, ""
 			}
 		}
 		for _, value := range exclude.Any {
-			if isKindOtherthanPod(value.Kinds) {
-				return false, ""
-			}
-			if !needAutogen {
-				needAutogen = hasAutogenKinds(value.Kinds)
-			}
-			if value.Name != "" || value.Selector != nil || value.Annotations != nil {
+			if !checkAutogenSupport(&needed, value.ResourceDescription) {
 				log.V(3).Info("skip generating rule on pod controllers: Name / Selector in exclude any block is not be applicable.", "rule", rule.Name)
 				return false, ""
 			}
 		}
 		for _, value := range exclude.All {
-			if isKindOtherthanPod(value.Kinds) {
-				return false, ""
-			}
-			if !needAutogen {
-				needAutogen = hasAutogenKinds(value.Kinds)
-			}
-			if value.Name != "" || value.Selector != nil || value.Annotations != nil {
+			if !checkAutogenSupport(&needed, value.ResourceDescription) {
 				log.V(3).Info("skip generating rule on pod controllers: Name / Selector in exclud all block is not be applicable.", "rule", rule.Name)
 				return false, ""
 			}
 		}
-
-		if rule.Mutation.PatchesJSON6902 != "" || rule.HasGenerate() {
-			return false, "none"
-		}
 	}
-
-	if !needAutogen {
+	if !needed {
 		return false, ""
 	}
-
 	return true, PodControllers
 }
 
@@ -139,14 +143,11 @@ func GetRequestedControllers(meta *metav1.ObjectMeta) []string {
 // It returns the requested, supported and effective controllers (intersection of requested and supported ones).
 func GetControllers(meta *metav1.ObjectMeta, spec *kyverno.Spec, log logr.Logger) ([]string, []string, []string) {
 	// compute supported and requested controllers
-	supported := GetSupportedControllers(spec, log)
-	requested := GetRequestedControllers(meta)
-
+	supported, requested := GetSupportedControllers(spec, log), GetRequestedControllers(meta)
 	// no specific request, we can return supported controllers without further filtering
 	if requested == nil {
 		return requested, supported, supported
 	}
-
 	// filter supported controllers, keeping only those that have been requested
 	var activated []string
 	for _, controller := range supported {
@@ -168,24 +169,19 @@ func GetControllers(meta *metav1.ObjectMeta, spec *kyverno.Spec, log logr.Logger
 
 // GenerateRulePatches generates rule for podControllers based on scenario A and C
 func GenerateRulePatches(spec *kyverno.Spec, controllers string, log logr.Logger) (rulePatches [][]byte, errs []error) {
-	ruleMap := createRuleMap(spec.Rules)
 	var ruleIndex = make(map[string]int)
 	for index, rule := range spec.Rules {
 		ruleIndex[rule.Name] = index
 	}
 	insertIdx := len(spec.Rules)
-	for _, rule := range spec.Rules {
+	genRules := generateRules(spec, controllers, log)
+	for i := range genRules {
 		patchPostion := insertIdx
 		convertToPatches := func(genRule kyvernoRule, patchPostion int) []byte {
 			operation := "add"
-			if existingAutoGenRule, alreadyExists := ruleMap[genRule.Name]; alreadyExists {
-				existingAutoGenRuleRaw, _ := json.Marshal(existingAutoGenRule)
-				genRuleRaw, _ := json.Marshal(genRule)
-				if string(existingAutoGenRuleRaw) == string(genRuleRaw) {
-					return nil
-				}
+			if existingIndex, alreadyExists := ruleIndex[genRule.Name]; alreadyExists {
 				operation = "replace"
-				patchPostion = ruleIndex[genRule.Name]
+				patchPostion = existingIndex
 			}
 			patch := jsonutils.NewPatch(fmt.Sprintf("/spec/rules/%s", strconv.Itoa(patchPostion)), operation, genRule)
 			pbytes, err := patch.Marshal()
@@ -199,27 +195,15 @@ func GenerateRulePatches(spec *kyverno.Spec, controllers string, log logr.Logger
 			}
 			return pbytes
 		}
-		// handle all other controllers other than CronJob
-		genRule := generateRuleForControllers(rule, stripCronJob(controllers), log)
+		genRule := createRule(&genRules[i])
 		if genRule != nil {
 			pbytes := convertToPatches(*genRule, patchPostion)
-			pbytes = updateGenRuleByte(pbytes, "Pod", *genRule)
 			if pbytes != nil {
 				rulePatches = append(rulePatches, pbytes)
 			}
 			insertIdx++
 			patchPostion = insertIdx
 		}
-		// handle CronJob, it appends an additional rule
-		genRule = generateCronJobRule(rule, controllers, log)
-		if genRule != nil {
-			pbytes := convertToPatches(*genRule, patchPostion)
-			pbytes = updateGenRuleByte(pbytes, "Cronjob", *genRule)
-			if pbytes != nil {
-				rulePatches = append(rulePatches, pbytes)
-			}
-			insertIdx++
-		}
 	}
 	return
 }
@@ -233,18 +217,18 @@ func GenerateRulePatches(spec *kyverno.Spec, controllers string, log logr.Logger
 //             copy entire match / exclude block, it's users' responsibility to
 //             make sure all fields are applicable to pod controllers
 
-// GenerateRules generates rule for podControllers based on scenario A and C
-func GenerateRules(spec *kyverno.Spec, controllers string, log logr.Logger) []kyverno.Rule {
+// generateRules generates rule for podControllers based on scenario A and C
+func generateRules(spec *kyverno.Spec, controllers string, log logr.Logger) []kyverno.Rule {
 	var rules []kyverno.Rule
-	for _, rule := range spec.Rules {
+	for i := range spec.Rules {
 		// handle all other controllers other than CronJob
-		if genRule := generateRuleForControllers(*rule.DeepCopy(), stripCronJob(controllers), log); genRule != nil {
+		if genRule := createRule(generateRuleForControllers(&spec.Rules[i], stripCronJob(controllers), log)); genRule != nil {
 			if convRule, err := convertRule(*genRule, "Pod"); err == nil {
 				rules = append(rules, *convRule)
 			}
 		}
 		// handle CronJob, it appends an additional rule
-		if genRule := generateCronJobRule(*rule.DeepCopy(), controllers, log); genRule != nil {
+		if genRule := createRule(generateCronJobRule(&spec.Rules[i], controllers, log)); genRule != nil {
 			if convRule, err := convertRule(*genRule, "Cronjob"); err == nil {
 				rules = append(rules, *convRule)
 			}
@@ -257,7 +241,7 @@ func convertRule(rule kyvernoRule, kind string) (*kyverno.Rule, error) {
 	if bytes, err := json.Marshal(rule); err != nil {
 		return nil, err
 	} else {
-		bytes = updateGenRuleByte(bytes, kind, rule)
+		bytes = updateGenRuleByte(bytes, kind)
 		if err := json.Unmarshal(bytes, &rule); err != nil {
 			return nil, err
 		}
@@ -308,7 +292,7 @@ func ComputeRules(p kyverno.PolicyInterface) []kyverno.Rule {
 	if actualControllers == "none" {
 		return spec.Rules
 	}
-	genRules := GenerateRules(spec.DeepCopy(), actualControllers, log.Log)
+	genRules := generateRules(spec.DeepCopy(), actualControllers, log.Log)
 	if len(genRules) == 0 {
 		return spec.Rules
 	}
diff --git a/pkg/autogen/autogen_test.go b/pkg/autogen/autogen_test.go
index 879d4800bb..7e6d2378c5 100644
--- a/pkg/autogen/autogen_test.go
+++ b/pkg/autogen/autogen_test.go
@@ -11,12 +11,47 @@ import (
 
 	kyverno "github.com/kyverno/kyverno/api/kyverno/v1"
 	"github.com/kyverno/kyverno/pkg/utils"
-	jsonutils "github.com/kyverno/kyverno/pkg/utils/json"
 	"gotest.tools/assert"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"sigs.k8s.io/controller-runtime/pkg/log"
 )
 
+func Test_getAutogenRuleName(t *testing.T) {
+	testCases := []struct {
+		name     string
+		ruleName string
+		prefix   string
+		expected string
+	}{
+		{"valid", "valid-rule-name", "autogen", "autogen-valid-rule-name"},
+		{"truncated", "too-long-this-rule-name-will-be-truncated-to-63-characters", "autogen", "autogen-too-long-this-rule-name-will-be-truncated-to-63-charact"},
+		{"valid-cronjob", "valid-rule-name", "autogen-cronjob", "autogen-cronjob-valid-rule-name"},
+		{"truncated-cronjob", "too-long-this-rule-name-will-be-truncated-to-63-characters", "autogen-cronjob", "autogen-cronjob-too-long-this-rule-name-will-be-truncated-to-63"},
+	}
+	for _, test := range testCases {
+		res := getAutogenRuleName(test.prefix, test.ruleName)
+		assert.Equal(t, test.expected, res)
+	}
+}
+
+func Test_isAutogenRule(t *testing.T) {
+	testCases := []struct {
+		name     string
+		ruleName string
+		expected bool
+	}{
+		{"normal", "valid-rule-name", false},
+		{"simple", "autogen-simple", true},
+		{"simple-cronjob", "autogen-cronjob-simple", true},
+		{"truncated", "autogen-too-long-this-rule-name-will-be-truncated-to-63-charact", true},
+		{"truncated-cronjob", "autogen-cronjob-too-long-this-rule-name-will-be-truncated-to-63", true},
+	}
+	for _, test := range testCases {
+		res := isAutogenRuleName(test.ruleName)
+		assert.Equal(t, test.expected, res)
+	}
+}
+
 func Test_CanAutoGen(t *testing.T) {
 	testCases := []struct {
 		name                string
@@ -271,7 +306,6 @@ func Test_Any(t *testing.T) {
 	}
 
 	rulePatches, errs := GenerateRulePatches(spec, PodControllers, log.Log)
-	fmt.Println("utils.JoinPatches(patches)erterter", string(jsonutils.JoinPatches(rulePatches...)))
 	if len(errs) != 0 {
 		t.Log(errs)
 	}
@@ -359,7 +393,6 @@ func Test_Exclude(t *testing.T) {
 }
 
 func Test_CronJobOnly(t *testing.T) {
-
 	controllers := PodControllerCronJob
 	dir, err := os.Getwd()
 	baseDir := filepath.Dir(filepath.Dir(dir))
@@ -424,7 +457,6 @@ func Test_ForEachPod(t *testing.T) {
 }
 
 func Test_CronJob_hasExclude(t *testing.T) {
-
 	controllers := PodControllerCronJob
 	dir, err := os.Getwd()
 	baseDir := filepath.Dir(filepath.Dir(dir))
@@ -518,7 +550,10 @@ func Test_UpdateVariablePath(t *testing.T) {
 		[]byte(`{"path":"/spec/rules/2","op":"add","value":{"name":"autogen-cronjob-select-secrets-from-volumes","match":{"resources":{"kinds":["CronJob"]}},"context":[{"name":"volsecret","apiCall":{"urlPath":"/api/v1/namespaces/{{request.object.spec.template.metadata.namespace}}/secrets/{{request.object.spec.jobTemplate.spec.template.spec.volumes[0].secret.secretName}}","jmesPath":"metadata.labels.foo"}}],"preconditions":[{"key":"{{ request.operation }}","operator":"Equals","value":"CREATE"}],"validate":{"message":"The Secret named {{request.object.spec.jobTemplate.spec.template.spec.volumes[0].secret.secretName}} is restricted and may not be used.","pattern":{"spec":{"jobTemplate":{"spec":{"template":{"spec":{"containers":[{"image":"registry.domain.com/*"}]}}}}}}}}}`),
 	}
 
-	assert.DeepEqual(t, rulePatches, expectedPatches)
+	for i, ep := range expectedPatches {
+		assert.Equal(t, string(rulePatches[i]), string(ep),
+			fmt.Sprintf("unexpected patch: %s\nexpected: %s", rulePatches[i], ep))
+	}
 }
 
 func Test_Deny(t *testing.T) {
@@ -545,7 +580,6 @@ func Test_Deny(t *testing.T) {
 	}
 
 	rulePatches, errs := GenerateRulePatches(spec, PodControllers, log.Log)
-	fmt.Println("utils.JoinPatches(patches)erterter", string(jsonutils.JoinPatches(rulePatches...)))
 	if len(errs) != 0 {
 		t.Log(errs)
 	}
diff --git a/pkg/autogen/rule.go b/pkg/autogen/rule.go
index a9f852f09b..5294ea6d94 100644
--- a/pkg/autogen/rule.go
+++ b/pkg/autogen/rule.go
@@ -1,8 +1,6 @@
 package autogen
 
 import (
-	"encoding/json"
-	"fmt"
 	"reflect"
 	"strings"
 
@@ -34,55 +32,199 @@ type kyvernoRule struct {
 	VerifyImages     []*kyverno.ImageVerification `json:"verifyImages,omitempty" yaml:"verifyImages,omitempty"`
 }
 
-func createRuleMap(rules []kyverno.Rule) map[string]kyvernoRule {
-	var ruleMap = make(map[string]kyvernoRule)
-	for _, rule := range rules {
-		var jsonFriendlyStruct kyvernoRule
-
-		jsonFriendlyStruct.Name = rule.Name
-
-		if !reflect.DeepEqual(rule.MatchResources, kyverno.MatchResources{}) {
-			jsonFriendlyStruct.MatchResources = rule.MatchResources.DeepCopy()
-		}
-
-		if !reflect.DeepEqual(rule.ExcludeResources, kyverno.MatchResources{}) {
-			jsonFriendlyStruct.ExcludeResources = rule.ExcludeResources.DeepCopy()
-		}
-
-		if !reflect.DeepEqual(rule.Mutation, kyverno.Mutation{}) {
-			jsonFriendlyStruct.Mutation = rule.Mutation.DeepCopy()
-		}
-
-		if !reflect.DeepEqual(rule.Validation, kyverno.Validation{}) {
-			jsonFriendlyStruct.Validation = rule.Validation.DeepCopy()
-		}
-
-		ruleMap[rule.Name] = jsonFriendlyStruct
+func createRule(rule *kyverno.Rule) *kyvernoRule {
+	if rule == nil {
+		return nil
 	}
-	return ruleMap
+	jsonFriendlyStruct := kyvernoRule{
+		Name: rule.Name,
+	}
+	if !reflect.DeepEqual(rule.MatchResources, kyverno.MatchResources{}) {
+		jsonFriendlyStruct.MatchResources = rule.MatchResources.DeepCopy()
+	}
+	if !reflect.DeepEqual(rule.ExcludeResources, kyverno.MatchResources{}) {
+		jsonFriendlyStruct.ExcludeResources = rule.ExcludeResources.DeepCopy()
+	}
+	if !reflect.DeepEqual(rule.Mutation, kyverno.Mutation{}) {
+		jsonFriendlyStruct.Mutation = rule.Mutation.DeepCopy()
+	}
+	if !reflect.DeepEqual(rule.Validation, kyverno.Validation{}) {
+		jsonFriendlyStruct.Validation = rule.Validation.DeepCopy()
+	}
+	kyvernoAnyAllConditions, _ := utils.ApiextensionsJsonToKyvernoConditions(rule.GetAnyAllConditions())
+	switch typedAnyAllConditions := kyvernoAnyAllConditions.(type) {
+	case kyverno.AnyAllConditions:
+		if !reflect.DeepEqual(typedAnyAllConditions, kyverno.AnyAllConditions{}) {
+			jsonFriendlyStruct.AnyAllConditions = rule.DeepCopy().RawAnyAllConditions
+		}
+	case []kyverno.Condition:
+		if len(typedAnyAllConditions) > 0 {
+			jsonFriendlyStruct.AnyAllConditions = rule.DeepCopy().RawAnyAllConditions
+		}
+	}
+	if len(rule.Context) > 0 {
+		jsonFriendlyStruct.Context = &rule.DeepCopy().Context
+	}
+	return &jsonFriendlyStruct
 }
 
-func generateRuleForControllers(rule kyverno.Rule, controllers string, log logr.Logger) *kyvernoRule {
-	logger := log.WithName("generateRuleForControllers")
+type generateResourceFilters func(kyverno.ResourceFilters, []string) kyverno.ResourceFilters
 
-	if strings.HasPrefix(rule.Name, "autogen-") || controllers == "" {
+func generateRule(logger logr.Logger, name string, rule *kyverno.Rule, tplKey, shift string, kinds []string, grf generateResourceFilters) *kyverno.Rule {
+	if rule == nil {
+		return nil
+	}
+	rule = rule.DeepCopy()
+	rule.Name = name
+	// overwrite Kinds by pod controllers defined in the annotation
+	if len(rule.MatchResources.Any) > 0 {
+		rule.MatchResources.Any = grf(rule.MatchResources.Any, kinds)
+	} else if len(rule.MatchResources.All) > 0 {
+		rule.MatchResources.All = grf(rule.MatchResources.All, kinds)
+	} else {
+		rule.MatchResources.Kinds = kinds
+	}
+	if len(rule.ExcludeResources.Any) > 0 {
+		rule.ExcludeResources.Any = grf(rule.ExcludeResources.Any, kinds)
+	} else if len(rule.ExcludeResources.All) > 0 {
+		rule.ExcludeResources.All = grf(rule.ExcludeResources.All, kinds)
+	} else {
+		if len(rule.ExcludeResources.Kinds) != 0 {
+			rule.ExcludeResources.Kinds = kinds
+		}
+	}
+	if target := rule.Mutation.GetPatchStrategicMerge(); target != nil {
+		newMutation := kyverno.Mutation{}
+		newMutation.SetPatchStrategicMerge(
+			map[string]interface{}{
+				"spec": map[string]interface{}{
+					tplKey: target,
+				},
+			},
+		)
+		rule.Mutation = newMutation
+		return rule
+	}
+	if len(rule.Mutation.ForEachMutation) > 0 && rule.Mutation.ForEachMutation != nil {
+		var newForeachMutation []*kyverno.ForEachMutation
+		for _, foreach := range rule.Mutation.ForEachMutation {
+			temp := kyverno.ForEachMutation{
+				List:             foreach.List,
+				Context:          foreach.Context,
+				AnyAllConditions: foreach.AnyAllConditions,
+			}
+			temp.SetPatchStrategicMerge(
+				map[string]interface{}{
+					"spec": map[string]interface{}{
+						tplKey: foreach.GetPatchStrategicMerge(),
+					},
+				},
+			)
+			newForeachMutation = append(newForeachMutation, &temp)
+		}
+		rule.Mutation = kyverno.Mutation{
+			ForEachMutation: newForeachMutation,
+		}
+		return rule
+	}
+	if target := rule.Validation.GetPattern(); target != nil {
+		newValidate := kyverno.Validation{
+			Message: variables.FindAndShiftReferences(logger, rule.Validation.Message, shift, "pattern"),
+		}
+		newValidate.SetPattern(
+			map[string]interface{}{
+				"spec": map[string]interface{}{
+					tplKey: target,
+				},
+			},
+		)
+		rule.Validation = newValidate
+		return rule
+	}
+	if rule.Validation.Deny != nil {
+		deny := kyverno.Validation{
+			Message: variables.FindAndShiftReferences(logger, rule.Validation.Message, shift, "deny"),
+			Deny:    rule.Validation.Deny,
+		}
+		rule.Validation = deny
+		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)
+		}
+		rule.Validation = kyverno.Validation{
+			Message: variables.FindAndShiftReferences(logger, rule.Validation.Message, shift, "anyPattern"),
+		}
+		rule.Validation.SetAnyPattern(patterns)
+		return rule
+	}
+	if len(rule.Validation.ForEachValidation) > 0 && rule.Validation.ForEachValidation != nil {
+		newForeachValidate := make([]*kyverno.ForEachValidation, len(rule.Validation.ForEachValidation))
+		for i, foreach := range rule.Validation.ForEachValidation {
+			newForeachValidate[i] = foreach
+		}
+		rule.Validation = kyverno.Validation{
+			Message:           variables.FindAndShiftReferences(logger, rule.Validation.Message, shift, "pattern"),
+			ForEachValidation: newForeachValidate,
+		}
+		return rule
+	}
+	if rule.VerifyImages != nil {
+		newVerifyImages := make([]*kyverno.ImageVerification, len(rule.VerifyImages))
+		for i, vi := range rule.VerifyImages {
+			newVerifyImages[i] = vi.DeepCopy()
+		}
+		rule.VerifyImages = newVerifyImages
+		return rule
+	}
+	return nil
+}
+
+func getAutogenRuleName(prefix string, name string) string {
+	name = prefix + "-" + name
+	if len(name) > 63 {
+		name = name[:63]
+	}
+	return name
+}
+
+func isAutogenRuleName(name string) bool {
+	return strings.HasPrefix(name, "autogen-")
+}
+
+func getAnyAllAutogenRule(v kyverno.ResourceFilters, match string, kinds []string) kyverno.ResourceFilters {
+	anyKind := v.DeepCopy()
+	for i, value := range v {
+		if kubeutils.ContainsKind(value.Kinds, match) {
+			anyKind[i].Kinds = kinds
+		}
+	}
+	return anyKind
+}
+
+func generateRuleForControllers(rule *kyverno.Rule, controllers string, log logr.Logger) *kyverno.Rule {
+	logger := log.WithName("generateRuleForControllers")
+	if isAutogenRuleName(rule.Name) || controllers == "" {
 		logger.V(5).Info("skip generateRuleForControllers")
 		return nil
 	}
-
 	logger.V(3).Info("processing rule", "rulename", rule.Name)
-
-	match := rule.MatchResources
-	exclude := rule.ExcludeResources
-
-	matchResourceDescriptionsKinds := rule.MatchKinds()
-	excludeResourceDescriptionsKinds := rule.ExcludeKinds()
-
-	if !kubeutils.ContainsKind(matchResourceDescriptionsKinds, "Pod") ||
-		(len(excludeResourceDescriptionsKinds) != 0 && !kubeutils.ContainsKind(excludeResourceDescriptionsKinds, "Pod")) {
+	match, exclude := rule.MatchResources, rule.ExcludeResources
+	matchKinds, excludeKinds := match.GetKinds(), exclude.GetKinds()
+	if !kubeutils.ContainsKind(matchKinds, "Pod") || (len(excludeKinds) != 0 && !kubeutils.ContainsKind(excludeKinds, "Pod")) {
 		return nil
 	}
-
 	// Support backwards compatibility
 	skipAutoGeneration := false
 	var controllersValidated []string
@@ -99,7 +241,6 @@ func generateRuleForControllers(rule kyverno.Rule, controllers string, log logr.
 			skipAutoGeneration = true
 		}
 	}
-
 	if skipAutoGeneration {
 		if controllers == "all" {
 			controllers = "DaemonSet,Deployment,Job,StatefulSet"
@@ -107,317 +248,40 @@ func generateRuleForControllers(rule kyverno.Rule, controllers string, log logr.
 			controllers = strings.Join(controllersValidated, ",")
 		}
 	}
-
-	name := fmt.Sprintf("autogen-%s", rule.Name)
-	if len(name) > 63 {
-		name = name[:63]
-	}
-
-	controllerRule := &kyvernoRule{
-		Name:           name,
-		MatchResources: match.DeepCopy(),
-	}
-
-	if len(rule.Context) > 0 {
-		controllerRule.Context = &rule.DeepCopy().Context
-	}
-
-	kyvernoAnyAllConditions, _ := utils.ApiextensionsJsonToKyvernoConditions(rule.GetAnyAllConditions())
-	switch typedAnyAllConditions := kyvernoAnyAllConditions.(type) {
-	case kyverno.AnyAllConditions:
-		if !reflect.DeepEqual(typedAnyAllConditions, kyverno.AnyAllConditions{}) {
-			controllerRule.AnyAllConditions = rule.DeepCopy().RawAnyAllConditions
-		}
-	case []kyverno.Condition:
-		if len(typedAnyAllConditions) > 0 {
-			controllerRule.AnyAllConditions = rule.DeepCopy().RawAnyAllConditions
-		}
-	}
-
-	if !reflect.DeepEqual(exclude, kyverno.MatchResources{}) {
-		controllerRule.ExcludeResources = exclude.DeepCopy()
-	}
-
-	// overwrite Kinds by pod controllers defined in the annotation
-	if len(rule.MatchResources.Any) > 0 {
-		rule := getAnyAllAutogenRule(controllerRule.MatchResources.Any, controllers)
-		controllerRule.MatchResources.Any = rule
-	} else if len(rule.MatchResources.All) > 0 {
-		rule := getAnyAllAutogenRule(controllerRule.MatchResources.All, controllers)
-		controllerRule.MatchResources.All = rule
-	} else {
-		controllerRule.MatchResources.Kinds = strings.Split(controllers, ",")
-	}
-
-	if len(rule.ExcludeResources.Any) > 0 {
-		rule := getAnyAllAutogenRule(controllerRule.ExcludeResources.Any, controllers)
-		controllerRule.ExcludeResources.Any = rule
-	} else if len(rule.ExcludeResources.All) > 0 {
-		rule := getAnyAllAutogenRule(controllerRule.ExcludeResources.All, controllers)
-		controllerRule.ExcludeResources.All = rule
-	} else {
-		if len(exclude.Kinds) != 0 {
-			controllerRule.ExcludeResources.Kinds = strings.Split(controllers, ",")
-		}
-	}
-
-	if target := rule.Mutation.GetPatchStrategicMerge(); target != nil {
-		newMutation := &kyverno.Mutation{}
-		newMutation.SetPatchStrategicMerge(
-			map[string]interface{}{
-				"spec": map[string]interface{}{
-					"template": target,
-				},
-			},
-		)
-		controllerRule.Mutation = newMutation.DeepCopy()
-		return controllerRule
-	}
-
-	if len(rule.Mutation.ForEachMutation) > 0 && rule.Mutation.ForEachMutation != nil {
-		var newForeachMutation []*kyverno.ForEachMutation
-		for _, foreach := range rule.Mutation.ForEachMutation {
-			temp := &kyverno.ForEachMutation{
-				List:             foreach.List,
-				Context:          foreach.Context,
-				AnyAllConditions: foreach.AnyAllConditions,
-			}
-			temp.SetPatchStrategicMerge(
-				map[string]interface{}{
-					"spec": map[string]interface{}{
-						"template": foreach.GetPatchStrategicMerge(),
-					},
-				},
-			)
-			newForeachMutation = append(newForeachMutation, temp)
-		}
-		controllerRule.Mutation = &kyverno.Mutation{
-			ForEachMutation: newForeachMutation,
-		}
-		return controllerRule
-	}
-
-	if target := rule.Validation.GetPattern(); target != nil {
-		newValidate := &kyverno.Validation{
-			Message: variables.FindAndShiftReferences(log, rule.Validation.Message, "spec/template", "pattern"),
-		}
-		newValidate.SetPattern(
-			map[string]interface{}{
-				"spec": map[string]interface{}{
-					"template": target,
-				},
-			},
-		)
-		controllerRule.Validation = newValidate.DeepCopy()
-		return controllerRule
-	}
-
-	if rule.Validation.Deny != nil {
-		deny := &kyverno.Validation{
-			Message: variables.FindAndShiftReferences(log, rule.Validation.Message, "spec/template", "deny"),
-			Deny:    rule.Validation.Deny,
-		}
-		controllerRule.Validation = deny.DeepCopy()
-		return controllerRule
-	}
-
-	if rule.Validation.GetAnyPattern() != nil {
-		anyPatterns, err := rule.Validation.DeserializeAnyPattern()
-		if err != nil {
-			logger.Error(err, "failed to deserialize anyPattern, expect type array")
-		}
-		patterns := validateAnyPattern(anyPatterns)
-		controllerRule.Validation = &kyverno.Validation{
-			Message: variables.FindAndShiftReferences(log, rule.Validation.Message, "spec/template", "anyPattern"),
-		}
-		controllerRule.Validation.SetAnyPattern(patterns)
-		return controllerRule
-	}
-
-	if len(rule.Validation.ForEachValidation) > 0 && rule.Validation.ForEachValidation != nil {
-		newForeachValidate := make([]*kyverno.ForEachValidation, len(rule.Validation.ForEachValidation))
-		for i, foreach := range rule.Validation.ForEachValidation {
-			newForeachValidate[i] = foreach
-		}
-		controllerRule.Validation = &kyverno.Validation{
-			Message:           variables.FindAndShiftReferences(log, rule.Validation.Message, "spec/template", "pattern"),
-			ForEachValidation: newForeachValidate,
-		}
-		return controllerRule
-	}
-
-	if rule.VerifyImages != nil {
-		newVerifyImages := make([]*kyverno.ImageVerification, len(rule.VerifyImages))
-		for i, vi := range rule.VerifyImages {
-			newVerifyImages[i] = vi.DeepCopy()
-		}
-
-		controllerRule.VerifyImages = newVerifyImages
-		return controllerRule
-	}
-
-	return nil
+	return generateRule(
+		logger,
+		getAutogenRuleName("autogen", rule.Name),
+		rule,
+		"template",
+		"spec/template",
+		strings.Split(controllers, ","),
+		func(r kyverno.ResourceFilters, kinds []string) kyverno.ResourceFilters {
+			return getAnyAllAutogenRule(r, "Pod", kinds)
+		},
+	)
 }
 
-func generateCronJobRule(rule kyverno.Rule, controllers string, log logr.Logger) *kyvernoRule {
-	logger := log.WithName("handleCronJob")
-
+func generateCronJobRule(rule *kyverno.Rule, controllers string, log logr.Logger) *kyverno.Rule {
+	logger := log.WithName("generateCronJobRule")
 	hasCronJob := strings.Contains(controllers, PodControllerCronJob) || strings.Contains(controllers, "all")
 	if !hasCronJob {
 		return nil
 	}
-
 	logger.V(3).Info("generating rule for cronJob")
-	jobRule := generateRuleForControllers(rule, "Job", logger)
-
-	if jobRule == nil {
-		return nil
-	}
-
-	cronJobRule := jobRule
-
-	name := fmt.Sprintf("autogen-cronjob-%s", rule.Name)
-	if len(name) > 63 {
-		name = name[:63]
-	}
-	cronJobRule.Name = name
-
-	if len(jobRule.MatchResources.Any) > 0 {
-		rule := cronJobAnyAllAutogenRule(cronJobRule.MatchResources.Any)
-		cronJobRule.MatchResources.Any = rule
-	} else if len(jobRule.MatchResources.All) > 0 {
-		rule := cronJobAnyAllAutogenRule(cronJobRule.MatchResources.All)
-		cronJobRule.MatchResources.All = rule
-	} else {
-		cronJobRule.MatchResources.Kinds = []string{PodControllerCronJob}
-	}
-
-	if (jobRule.ExcludeResources) != nil && len(jobRule.ExcludeResources.Any) > 0 {
-		rule := cronJobAnyAllAutogenRule(cronJobRule.ExcludeResources.Any)
-		cronJobRule.ExcludeResources.Any = rule
-	} else if (jobRule.ExcludeResources) != nil && len(jobRule.ExcludeResources.All) > 0 {
-		rule := cronJobAnyAllAutogenRule(cronJobRule.ExcludeResources.All)
-		cronJobRule.ExcludeResources.All = rule
-	} else {
-		if (jobRule.ExcludeResources) != nil && (len(jobRule.ExcludeResources.Kinds) > 0) {
-			cronJobRule.ExcludeResources.Kinds = []string{PodControllerCronJob}
-		}
-	}
-
-	if jobRule.Mutation != nil {
-		if target := jobRule.Mutation.GetPatchStrategicMerge(); target != nil {
-			newMutation := &kyverno.Mutation{}
-			newMutation.SetPatchStrategicMerge(
-				map[string]interface{}{
-					"spec": map[string]interface{}{
-						"jobTemplate": target,
-					},
-				},
-			)
-			cronJobRule.Mutation = newMutation.DeepCopy()
-			return cronJobRule
-		}
-	}
-
-	if jobRule.Validation != nil {
-		if target := jobRule.Validation.GetPattern(); target != nil {
-			newValidate := &kyverno.Validation{
-				Message: variables.FindAndShiftReferences(log, rule.Validation.Message, "spec/jobTemplate/spec/template", "pattern"),
-			}
-			newValidate.SetPattern(
-				map[string]interface{}{
-					"spec": map[string]interface{}{
-						"jobTemplate": target,
-					},
-				},
-			)
-			cronJobRule.Validation = newValidate.DeepCopy()
-			return cronJobRule
-		}
-
-		if jobRule.Validation.Deny != nil {
-			newValidate := &kyverno.Validation{
-				Message: variables.FindAndShiftReferences(log, rule.Validation.Message, "spec/jobTemplate/spec/template", "pattern"),
-				Deny:    jobRule.Validation.Deny,
-			}
-			cronJobRule.Validation = newValidate.DeepCopy()
-			return cronJobRule
-		}
-
-		if target := jobRule.Validation.GetAnyPattern(); target != nil {
-			var patterns []interface{}
-			anyPatterns, err := jobRule.Validation.DeserializeAnyPattern()
-			if err != nil {
-				logger.Error(err, "failed to deserialize anyPattern, expect type array")
-			}
-			for _, pattern := range anyPatterns {
-				newPattern := map[string]interface{}{
-					"spec": map[string]interface{}{
-						"jobTemplate": pattern,
-					},
-				}
-				patterns = append(patterns, newPattern)
-			}
-			cronJobRule.Validation = &kyverno.Validation{
-				Message: variables.FindAndShiftReferences(log, rule.Validation.Message, "spec/jobTemplate/spec/template", "anyPattern"),
-			}
-			cronJobRule.Validation.SetAnyPattern(patterns)
-			return cronJobRule
-		}
-
-		if len(jobRule.Validation.ForEachValidation) > 0 && jobRule.Validation.ForEachValidation != nil {
-			newForeachValidate := make([]*kyverno.ForEachValidation, len(jobRule.Validation.ForEachValidation))
-			for i, foreach := range rule.Validation.ForEachValidation {
-				newForeachValidate[i] = foreach
-			}
-			cronJobRule.Validation = &kyverno.Validation{
-				Message:           variables.FindAndShiftReferences(log, rule.Validation.Message, "spec/template", "pattern"),
-				ForEachValidation: newForeachValidate,
-			}
-			return cronJobRule
-		}
-	}
-
-	if jobRule.Mutation != nil && len(jobRule.Mutation.ForEachMutation) > 0 && jobRule.Mutation.ForEachMutation != nil {
-		var newForeachMutation []*kyverno.ForEachMutation
-		for _, foreach := range jobRule.Mutation.ForEachMutation {
-			temp := &kyverno.ForEachMutation{
-				List:             foreach.List,
-				Context:          foreach.Context,
-				AnyAllConditions: foreach.AnyAllConditions,
-			}
-			temp.SetPatchStrategicMerge(
-				map[string]interface{}{
-					"spec": map[string]interface{}{
-						"jobTemplate": foreach.GetPatchStrategicMerge(),
-					},
-				},
-			)
-			newForeachMutation = append(newForeachMutation, temp)
-		}
-		cronJobRule.Mutation = &kyverno.Mutation{
-			ForEachMutation: newForeachMutation,
-		}
-		return cronJobRule
-	}
-
-	if jobRule.VerifyImages != nil {
-		newVerifyImages := make([]*kyverno.ImageVerification, len(jobRule.VerifyImages))
-		for i, vi := range rule.VerifyImages {
-			newVerifyImages[i] = vi.DeepCopy()
-		}
-		cronJobRule.VerifyImages = newVerifyImages
-		return cronJobRule
-	}
-
-	return nil
+	return generateRule(
+		logger,
+		getAutogenRuleName("autogen-cronjob", rule.Name),
+		generateRuleForControllers(rule, controllers, log),
+		"jobTemplate",
+		"spec/jobTemplate/spec/template",
+		[]string{PodControllerCronJob},
+		func(r kyverno.ResourceFilters, kinds []string) kyverno.ResourceFilters {
+			return getAnyAllAutogenRule(r, "Job", kinds)
+		},
+	)
 }
 
-func updateGenRuleByte(pbyte []byte, kind string, genRule kyvernoRule) (obj []byte) {
-	// TODO: do we need to unmarshall here ?
-	if err := json.Unmarshal(pbyte, &genRule); err != nil {
-		return obj
-	}
+func updateGenRuleByte(pbyte []byte, kind string) (obj []byte) {
 	if kind == "Pod" {
 		obj = []byte(strings.ReplaceAll(string(pbyte), "request.object.spec", "request.object.spec.template.spec"))
 	}
diff --git a/pkg/autogen/utils.go b/pkg/autogen/utils.go
deleted file mode 100644
index 5b4981cc9a..0000000000
--- a/pkg/autogen/utils.go
+++ /dev/null
@@ -1,73 +0,0 @@
-package autogen
-
-import (
-	"strings"
-
-	kyverno "github.com/kyverno/kyverno/api/kyverno/v1"
-	kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
-)
-
-func isKindOtherthanPod(kinds []string) bool {
-	if len(kinds) > 1 && kubeutils.ContainsKind(kinds, "Pod") {
-		return true
-	}
-	return false
-}
-
-func hasAutogenKinds(kind []string) bool {
-	for _, v := range kind {
-		if v == "Pod" || strings.Contains(PodControllers, v) {
-			return true
-		}
-	}
-	return false
-}
-
-func validateAnyPattern(anyPatterns []interface{}) []interface{} {
-	var patterns []interface{}
-	for _, pattern := range anyPatterns {
-		newPattern := map[string]interface{}{
-			"spec": map[string]interface{}{
-				"template": pattern,
-			},
-		}
-		patterns = append(patterns, newPattern)
-	}
-	return patterns
-}
-
-func getAnyAllAutogenRule(v kyverno.ResourceFilters, controllers string) kyverno.ResourceFilters {
-	anyKind := v.DeepCopy()
-	for i, value := range v {
-		if kubeutils.ContainsKind(value.Kinds, "Pod") {
-			anyKind[i].Kinds = strings.Split(controllers, ",")
-		}
-	}
-	return anyKind
-}
-
-// stripCronJob removes CronJob from controllers
-func stripCronJob(controllers string) string {
-	var newControllers []string
-	controllerArr := strings.Split(controllers, ",")
-	for _, c := range controllerArr {
-		if c == PodControllerCronJob {
-			continue
-		}
-		newControllers = append(newControllers, c)
-	}
-	if len(newControllers) == 0 {
-		return ""
-	}
-	return strings.Join(newControllers, ",")
-}
-
-func cronJobAnyAllAutogenRule(v kyverno.ResourceFilters) kyverno.ResourceFilters {
-	anyKind := v.DeepCopy()
-	for i, value := range v {
-		if kubeutils.ContainsKind(value.Kinds, "Job") {
-			anyKind[i].Kinds = []string{PodControllerCronJob}
-		}
-	}
-	return anyKind
-}
diff --git a/pkg/policy/existing.go b/pkg/policy/existing.go
index b00af3e221..12f8a4ec62 100644
--- a/pkg/policy/existing.go
+++ b/pkg/policy/existing.go
@@ -30,8 +30,7 @@ func (pc *PolicyController) processExistingResources(policy kyverno.PolicyInterf
 		if !rule.HasValidate() && !rule.HasVerifyImages() {
 			continue
 		}
-
-		matchKinds := rule.MatchKinds()
+		matchKinds := rule.MatchResources.GetKinds()
 		pc.processExistingKinds(matchKinds, policy, rule, logger)
 	}
 }
diff --git a/pkg/webhookconfig/configmanager.go b/pkg/webhookconfig/configmanager.go
index 505fd9f7b7..91f3043326 100644
--- a/pkg/webhookconfig/configmanager.go
+++ b/pkg/webhookconfig/configmanager.go
@@ -734,7 +734,7 @@ func (m *webhookConfigManager) mergeWebhook(dst *webhook, policy kyverno.PolicyI
 	for _, rule := range autogen.ComputeRules(policy) {
 		// matching kinds in generate policies need to be added to both webhook
 		if rule.HasGenerate() {
-			matchedGVK = append(matchedGVK, rule.MatchKinds()...)
+			matchedGVK = append(matchedGVK, rule.MatchResources.GetKinds()...)
 			matchedGVK = append(matchedGVK, rule.Generation.ResourceSpec.Kind)
 			continue
 		}
@@ -742,7 +742,7 @@ func (m *webhookConfigManager) mergeWebhook(dst *webhook, policy kyverno.PolicyI
 		if (updateValidate && rule.HasValidate()) ||
 			(!updateValidate && rule.HasMutate()) ||
 			(!updateValidate && rule.HasVerifyImages()) {
-			matchedGVK = append(matchedGVK, rule.MatchKinds()...)
+			matchedGVK = append(matchedGVK, rule.MatchResources.GetKinds()...)
 		}
 	}
 
@@ -847,7 +847,7 @@ func webhookKey(webhookKind, failurePolicy string) string {
 
 func hasWildcard(spec *kyverno.Spec) bool {
 	for _, rule := range spec.Rules {
-		if kinds := rule.MatchKinds(); utils.ContainsString(kinds, "*") {
+		if kinds := rule.MatchResources.GetKinds(); utils.ContainsString(kinds, "*") {
 			return true
 		}
 	}