diff --git a/cmd/cli/kubectl-kyverno/commands/apply/command.go b/cmd/cli/kubectl-kyverno/commands/apply/command.go index ee6a22f3a7..ec878ca039 100644 --- a/cmd/cli/kubectl-kyverno/commands/apply/command.go +++ b/cmd/cli/kubectl-kyverno/commands/apply/command.go @@ -170,7 +170,7 @@ func (c *ApplyCommandConfig) applyCommandHelper(out io.Writer) (*processor.Resul if !c.Stdin && !c.PolicyReport { var policyRulesCount int for _, policy := range policies { - policyRulesCount += len(autogen.ComputeRules(policy)) + policyRulesCount += len(autogen.ComputeRules(policy, "")) } policyRulesCount += len(vaps) if len(exceptions) > 0 { diff --git a/cmd/cli/kubectl-kyverno/commands/test/test.go b/cmd/cli/kubectl-kyverno/commands/test/test.go index 270de3c293..920d3d6c3a 100644 --- a/cmd/cli/kubectl-kyverno/commands/test/test.go +++ b/cmd/cli/kubectl-kyverno/commands/test/test.go @@ -101,7 +101,7 @@ func runTest(out io.Writer, testCase test.TestCase, registryAccess bool, auditWa // TODO document the code below ruleToCloneSourceResource := map[string]string{} for _, policy := range policies { - for _, rule := range autogen.ComputeRules(policy) { + for _, rule := range autogen.ComputeRules(policy, "") { for _, res := range testCase.Test.Results { if res.IsValidatingAdmissionPolicy { continue diff --git a/cmd/cli/kubectl-kyverno/processor/generate.go b/cmd/cli/kubectl-kyverno/processor/generate.go index b5df84db26..5533aef6d1 100644 --- a/cmd/cli/kubectl-kyverno/processor/generate.go +++ b/cmd/cli/kubectl-kyverno/processor/generate.go @@ -48,7 +48,7 @@ func handleGeneratePolicy(out io.Writer, store *store.Store, generateResponse *e listKinds := map[schema.GroupVersionResource]string{} // Collect items in a potential cloneList to provide list kinds to the fake dynamic client. - for _, rule := range autogen.ComputeRules(policyContext.Policy()) { + for _, rule := range autogen.ComputeRules(policyContext.Policy(), "") { if !rule.HasGenerate() || len(rule.Generation.CloneList.Kinds) == 0 { continue } diff --git a/cmd/cli/kubectl-kyverno/processor/result.go b/cmd/cli/kubectl-kyverno/processor/result.go index 173ed08b16..8cc72564d8 100644 --- a/cmd/cli/kubectl-kyverno/processor/result.go +++ b/cmd/cli/kubectl-kyverno/processor/result.go @@ -39,7 +39,7 @@ func (rc *ResultCounts) addEngineResponse(auditWarn bool, response engineapi.Eng } policy := genericPolicy.AsKyvernoPolicy() scored := annotations.Scored(policy.GetAnnotations()) - for _, rule := range autogen.ComputeRules(policy) { + for _, rule := range autogen.ComputeRules(policy, "") { if rule.HasValidate() || rule.HasVerifyImageChecks() || rule.HasVerifyImages() { for _, valResponseRule := range response.PolicyResponse.Rules { if rule.Name == valResponseRule.Name() { @@ -76,7 +76,7 @@ func (rc *ResultCounts) addGenerateResponse(auditWarn bool, resPath string, resp return } policy := genericPolicy.AsKyvernoPolicy() - for _, policyRule := range autogen.ComputeRules(policy) { + for _, policyRule := range autogen.ComputeRules(policy, "") { for _, ruleResponse := range response.PolicyResponse.Rules { if policyRule.Name == ruleResponse.Name() { if ruleResponse.Status() == engineapi.RuleStatusPass { @@ -101,7 +101,7 @@ func (rc *ResultCounts) addMutateResponse(resourcePath string, response engineap } policy := genericPolicy.AsKyvernoPolicy() var policyHasMutate bool - for _, rule := range autogen.ComputeRules(policy) { + for _, rule := range autogen.ComputeRules(policy, "") { if rule.HasMutate() { policyHasMutate = true } @@ -110,7 +110,7 @@ func (rc *ResultCounts) addMutateResponse(resourcePath string, response engineap return false } printMutatedRes := false - for _, policyRule := range autogen.ComputeRules(policy) { + for _, policyRule := range autogen.ComputeRules(policy, "") { for _, mutateResponseRule := range response.PolicyResponse.Rules { if policyRule.Name == mutateResponseRule.Name() { if mutateResponseRule.Status() == engineapi.RuleStatusPass { diff --git a/cmd/cli/kubectl-kyverno/utils/common/common.go b/cmd/cli/kubectl-kyverno/utils/common/common.go index ba05ec6e66..b7432a8457 100644 --- a/cmd/cli/kubectl-kyverno/utils/common/common.go +++ b/cmd/cli/kubectl-kyverno/utils/common/common.go @@ -89,7 +89,7 @@ func GetResourceAccordingToResourcePath( func GetKindsFromPolicy(out io.Writer, policy kyvernov1.PolicyInterface, subresources []v1alpha1.Subresource, dClient dclient.Interface) sets.Set[string] { knownkinds := sets.New[string]() - for _, rule := range autogen.ComputeRules(policy) { + for _, rule := range autogen.ComputeRules(policy, "") { for _, kind := range rule.MatchResources.ResourceDescription.Kinds { k, err := getKind(kind, subresources, dClient) if err != nil { diff --git a/cmd/cli/kubectl-kyverno/utils/common/fetch.go b/cmd/cli/kubectl-kyverno/utils/common/fetch.go index 227aed32e7..ed0a1890ff 100644 --- a/cmd/cli/kubectl-kyverno/utils/common/fetch.go +++ b/cmd/cli/kubectl-kyverno/utils/common/fetch.go @@ -130,7 +130,7 @@ func GetResourcesWithTest(out io.Writer, fs billy.Filesystem, policies []kyverno resources := make([]*unstructured.Unstructured, 0) resourceTypesMap := make(map[string]bool) for _, policy := range policies { - for _, rule := range autogen.ComputeRules(policy) { + for _, rule := range autogen.ComputeRules(policy, "") { for _, kind := range rule.MatchResources.Kinds { resourceTypesMap[kind] = true } diff --git a/cmd/cli/kubectl-kyverno/utils/common/kyverno_resources_types.go b/cmd/cli/kubectl-kyverno/utils/common/kyverno_resources_types.go index 60a05a89e6..45aae6fa4e 100644 --- a/cmd/cli/kubectl-kyverno/utils/common/kyverno_resources_types.go +++ b/cmd/cli/kubectl-kyverno/utils/common/kyverno_resources_types.go @@ -24,7 +24,7 @@ func (r *KyvernoResources) FetchResourcesFromPolicy(out io.Writer, resourcePaths var subresourceMap map[schema.GroupVersionKind]v1alpha1.Subresource for _, policy := range r.policies { - for _, rule := range autogen.ComputeRules(policy) { + for _, rule := range autogen.ComputeRules(policy, "") { var resourceTypesInRule map[schema.GroupVersionKind]bool resourceTypesInRule, subresourceMap = GetKindsFromRule(rule, dClient) for resourceKind := range resourceTypesInRule { diff --git a/pkg/autogen/autogen.go b/pkg/autogen/autogen.go index 3fc0199ef3..ba005998dc 100644 --- a/pkg/autogen/autogen.go +++ b/pkg/autogen/autogen.go @@ -1,10 +1,9 @@ package autogen import ( - "encoding/json" - "slices" "strings" + jsoniter "github.com/json-iterator/go" "github.com/kyverno/kyverno/api/kyverno" kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" kubeutils "github.com/kyverno/kyverno/pkg/utils/kube" @@ -15,11 +14,12 @@ import ( const ( // PodControllerCronJob represent CronJob string PodControllerCronJob = "CronJob" - // PodControllers stores the list of Pod-controllers in csv string - PodControllers = "DaemonSet,Deployment,Job,StatefulSet,ReplicaSet,ReplicationController,CronJob" ) -var podControllersKindsSet = sets.New(append(strings.Split(PodControllers, ","), "Pod")...) +var ( + PodControllers = sets.New("DaemonSet", "Deployment", "Job", "StatefulSet", "ReplicaSet", "ReplicationController", "CronJob") + podControllersKindsSet = PodControllers.Union(sets.New("Pod")) +) func isKindOtherthanPod(kinds []string) bool { if len(kinds) > 1 && kubeutils.ContainsKind(kinds, "Pod") { @@ -65,64 +65,64 @@ func stripCronJob(controllers string) string { // - mutate.Patches/mutate.PatchesJSON6902/validate.deny/generate rule is defined // // - otherwise it returns all pod controllers -func CanAutoGen(spec *kyvernov1.Spec) (applyAutoGen bool, controllers string) { +func CanAutoGen(spec *kyvernov1.Spec) (applyAutoGen bool, controllers sets.Set[string]) { needed := false for _, rule := range spec.Rules { if rule.Mutation.PatchesJSON6902 != "" || rule.HasGenerate() { - return false, "none" + return false, sets.New("none") } for _, foreach := range rule.Mutation.ForEachMutation { if foreach.PatchesJSON6902 != "" { - return false, "none" + return false, sets.New("none") } } match, exclude := rule.MatchResources, rule.ExcludeResources if !checkAutogenSupport(&needed, match.ResourceDescription, exclude.ResourceDescription) { debug.Info("skip generating rule on pod controllers: Name / Selector in resource description may not be applicable.", "rule", rule.Name) - return false, "" + return false, sets.New[string]() } for _, value := range match.Any { if !checkAutogenSupport(&needed, value.ResourceDescription) { debug.Info("skip generating rule on pod controllers: Name / Selector in match any block is not applicable.", "rule", rule.Name) - return false, "" + return false, sets.New[string]() } } for _, value := range match.All { if !checkAutogenSupport(&needed, value.ResourceDescription) { debug.Info("skip generating rule on pod controllers: Name / Selector in match all block is not applicable.", "rule", rule.Name) - return false, "" + return false, sets.New[string]() } } for _, value := range exclude.Any { if !checkAutogenSupport(&needed, value.ResourceDescription) { debug.Info("skip generating rule on pod controllers: Name / Selector in exclude any block is not applicable.", "rule", rule.Name) - return false, "" + return false, sets.New[string]() } } for _, value := range exclude.All { if !checkAutogenSupport(&needed, value.ResourceDescription) { debug.Info("skip generating rule on pod controllers: Name / Selector in exclud all block is not applicable.", "rule", rule.Name) - return false, "" + return false, sets.New[string]() } } } if !needed { - return false, "" + return false, sets.New[string]() } return true, PodControllers } // GetSupportedControllers returns the supported autogen controllers for a given spec. -func GetSupportedControllers(spec *kyvernov1.Spec) []string { +func GetSupportedControllers(spec *kyvernov1.Spec) sets.Set[string] { apply, controllers := CanAutoGen(spec) - if !apply || controllers == "none" { + if !apply || (controllers.Len() == 1 && controllers.Has("none")) { return nil } - return strings.Split(controllers, ",") + return controllers } // GetRequestedControllers returns the requested autogen controllers based on object annotations. -func GetRequestedControllers(meta *metav1.ObjectMeta) []string { +func GetRequestedControllers(meta *metav1.ObjectMeta) sets.Set[string] { annotations := meta.GetAnnotations() if annotations == nil { return nil @@ -132,9 +132,9 @@ func GetRequestedControllers(meta *metav1.ObjectMeta) []string { return nil } if controllers == "none" { - return []string{} + return sets.New[string]() } - return strings.Split(controllers, ",") + return sets.New(strings.Split(controllers, ",")...) } // GetControllers computes the autogen controllers that should be applied to a policy. @@ -144,16 +144,16 @@ func GetControllers(meta *metav1.ObjectMeta, spec *kyvernov1.Spec) ([]string, [] supported, requested := GetSupportedControllers(spec), GetRequestedControllers(meta) // no specific request, we can return supported controllers without further filtering if requested == nil { - return requested, supported, supported + return requested.UnsortedList(), supported.UnsortedList(), supported.UnsortedList() } // filter supported controllers, keeping only those that have been requested var activated []string - for _, controller := range supported { - if slices.Contains(requested, controller) { + for _, controller := range supported.UnsortedList() { + if requested.Has(controller) { activated = append(activated, controller) } } - return requested, supported, activated + return requested.UnsortedList(), supported.UnsortedList(), activated } // podControllersKey annotation could be: @@ -190,6 +190,8 @@ func generateRules(spec *kyvernov1.Spec, controllers string) []kyvernov1.Rule { } func convertRule(rule kyvernoRule, kind string) (*kyvernov1.Rule, error) { + json := jsoniter.ConfigCompatibleWithStandardLibrary + if bytes, err := json.Marshal(rule); err != nil { return nil, err } else { @@ -233,29 +235,43 @@ func convertRule(rule kyvernoRule, kind string) (*kyvernov1.Rule, error) { return &out, nil } -func ComputeRules(p kyvernov1.PolicyInterface) []kyvernov1.Rule { - return computeRules(p) +func ComputeRules(p kyvernov1.PolicyInterface, kind string) []kyvernov1.Rule { + return computeRules(p, kind) } -func computeRules(p kyvernov1.PolicyInterface) []kyvernov1.Rule { +func computeRules(p kyvernov1.PolicyInterface, kind string) []kyvernov1.Rule { spec := p.GetSpec() applyAutoGen, desiredControllers := CanAutoGen(spec) if !applyAutoGen { - desiredControllers = "none" + desiredControllers = sets.New("none") } + + var actualControllers sets.Set[string] ann := p.GetAnnotations() - actualControllers, ok := ann[kyverno.AnnotationAutogenControllers] + actualControllersString, ok := ann[kyverno.AnnotationAutogenControllers] if !ok || !applyAutoGen { actualControllers = desiredControllers } else { if !applyAutoGen { actualControllers = desiredControllers + } else { + actualControllers = sets.New(strings.Split(actualControllersString, ",")...) } } - if actualControllers == "none" { + + if kind != "" { + if !actualControllers.Has(kind) { + return spec.Rules + } + } else { + kind = strings.Join(actualControllers.UnsortedList(), ",") + } + + if kind == "none" { return spec.Rules } - genRules := generateRules(spec.DeepCopy(), actualControllers) + + genRules := generateRules(spec.DeepCopy(), kind) if len(genRules) == 0 { return spec.Rules } diff --git a/pkg/autogen/autogen_test.go b/pkg/autogen/autogen_test.go index 00e7e3c09d..6c5523aec4 100644 --- a/pkg/autogen/autogen_test.go +++ b/pkg/autogen/autogen_test.go @@ -4,7 +4,6 @@ import ( "encoding/json" "fmt" "reflect" - "strings" "testing" "github.com/kyverno/kyverno/api/kyverno" @@ -12,6 +11,7 @@ import ( yamlutils "github.com/kyverno/kyverno/pkg/utils/yaml" "gotest.tools/assert" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/sets" ) func Test_getAutogenRuleName(t *testing.T) { @@ -58,32 +58,32 @@ func Test_CanAutoGen(t *testing.T) { testCases := []struct { name string policy []byte - expectedControllers string + expectedControllers sets.Set[string] }{ { name: "rule-with-match-name", policy: []byte(`{"apiVersion":"kyverno.io/v1","kind":"ClusterPolicy","metadata":{"name":"test"},"spec":{"rules":[{"name":"test","match":{"resources":{"kinds":["Namespace"],"name":"*"}}}]}}`), - expectedControllers: "none", + expectedControllers: sets.New("none"), }, { name: "rule-with-match-selector", policy: []byte(`{"apiVersion":"kyverno.io/v1","kind":"ClusterPolicy","metadata":{"name":"test-getcontrollers"},"spec":{"background":false,"rules":[{"name":"test-getcontrollers","match":{"resources":{"kinds":["Pod"],"selector":{"matchLabels":{"foo":"bar"}}}}}]}}`), - expectedControllers: "none", + expectedControllers: sets.New("none"), }, { name: "rule-with-exclude-name", policy: []byte(`{"apiVersion":"kyverno.io/v1","kind":"ClusterPolicy","metadata":{"name":"test-getcontrollers"},"spec":{"background":false,"rules":[{"name":"test-getcontrollers","match":{"resources":{"kinds":["Pod"]}},"exclude":{"resources":{"name":"test"}}}]}}`), - expectedControllers: "none", + expectedControllers: sets.New("none"), }, { name: "rule-with-exclude-names", policy: []byte(`{"apiVersion":"kyverno.io/v1","kind":"ClusterPolicy","metadata":{"name":"test-getcontrollers"},"spec":{"background":false,"rules":[{"name":"test-getcontrollers","match":{"resources":{"kinds":["Pod"]}},"exclude":{"resources":{"names":["test"]}}}]}}`), - expectedControllers: "none", + expectedControllers: sets.New("none"), }, { name: "rule-with-exclude-selector", policy: []byte(`{"apiVersion":"kyverno.io/v1","kind":"ClusterPolicy","metadata":{"name":"test-getcontrollers"},"spec":{"background":false,"rules":[{"name":"test-getcontrollers","match":{"resources":{"kinds":["Pod"]}},"exclude":{"resources":{"selector":{"matchLabels":{"foo":"bar"}}}}}]}}`), - expectedControllers: "none", + expectedControllers: sets.New("none"), }, { name: "rule-with-deny", @@ -93,12 +93,12 @@ func Test_CanAutoGen(t *testing.T) { { name: "rule-with-match-mixed-kinds-pod-podcontrollers", policy: []byte(`{"apiVersion":"kyverno.io/v1","kind":"ClusterPolicy","metadata":{"name":"set-service-labels-env"},"spec":{"background":false,"rules":[{"name":"set-service-label","match":{"resources":{"kinds":["Pod","Deployment"]}},"preconditions":{"any":[{"key":"{{request.operation}}","operator":"Equals","value":"CREATE"}]},"mutate":{"patchStrategicMerge":{"metadata":{"labels":{"+(service)":"{{request.object.spec.template.metadata.labels.app}}"}}}}}]}}`), - expectedControllers: "none", + expectedControllers: sets.New("none"), }, { name: "rule-with-exclude-mixed-kinds-pod-podcontrollers", policy: []byte(`{"apiVersion":"kyverno.io/v1","kind":"ClusterPolicy","metadata":{"name":"set-service-labels-env"},"spec":{"background":false,"rules":[{"name":"set-service-label","match":{"resources":{"kinds":["Pod"]}},"exclude":{"resources":{"kinds":["Pod","Deployment"]}},"mutate":{"patchStrategicMerge":{"metadata":{"labels":{"+(service)":"{{request.object.spec.template.metadata.labels.app}}"}}}}}]}}`), - expectedControllers: "none", + expectedControllers: sets.New("none"), }, { name: "rule-with-match-kinds-pod-only", @@ -113,27 +113,27 @@ func Test_CanAutoGen(t *testing.T) { { name: "rule-with-mutate-patches", policy: []byte(`{"apiVersion":"kyverno.io/v1","kind":"ClusterPolicy","metadata":{"name":"test"},"spec":{"rules":[{"name":"test","match":{"resources":{"kinds":["Pod"]}},"mutate":{"patchesJson6902":"-op:add\npath:/spec/containers/0/env/-1\nvalue:{\"name\":\"SERVICE\",\"value\":{{request.object.spec.template.metadata.labels.app}}}"}}]}}`), - expectedControllers: "none", + expectedControllers: sets.New("none"), }, { name: "rule-with-generate", policy: []byte(`{"apiVersion":"kyverno.io/v1","kind":"ClusterPolicy","metadata":{"name":"add-networkpolicy"},"spec":{"rules":[{"name":"default-deny-ingress","match":{"resources":{"kinds":["Namespace"],"name":"*"}},"exclude":{"resources":{"namespaces":["kube-system","default","kube-public","kyverno"]}},"generate":{"kind":"NetworkPolicy","name":"default-deny-ingress","namespace":"{{request.object.metadata.name}}","synchronize":true,"data":{"spec":{"podSelector":{},"policyTypes":["Ingress"]}}}}]}}`), - expectedControllers: "none", + expectedControllers: sets.New("none"), }, { name: "rule-with-predefined-invalid-controllers", policy: []byte(`{"apiVersion":"kyverno.io/v1","kind":"ClusterPolicy","metadata":{"name":"set-service-labels-env"},"annotations":null,"pod-policies.kyverno.io/autogen-controllers":"DaemonSet,Deployment,StatefulSet","spec":{"background":false,"rules":[{"name":"set-service-label","match":{"resources":{"kinds":["Pod","Deployment"]}},"mutate":{"patchStrategicMerge":{"metadata":{"labels":{"+(service)":"{{request.object.spec.template.metadata.labels.app}}"}}}}}]}}`), - expectedControllers: "none", + expectedControllers: sets.New("none"), }, { name: "rule-with-predefined-valid-controllers", policy: []byte(`{"apiVersion":"kyverno.io/v1","kind":"ClusterPolicy","metadata":{"name":"set-service-labels-env"},"annotations":null,"pod-policies.kyverno.io/autogen-controllers":"none","spec":{"background":false,"rules":[{"name":"set-service-label","match":{"resources":{"kinds":["Pod","Deployment"]}},"mutate":{"patchStrategicMerge":{"metadata":{"labels":{"+(service)":"{{request.object.spec.template.metadata.labels.app}}"}}}}}]}}`), - expectedControllers: "none", + expectedControllers: sets.New("none"), }, { name: "rule-with-only-predefined-valid-controllers", policy: []byte(`{"apiVersion":"kyverno.io/v1","kind":"ClusterPolicy","metadata":{"name":"set-service-labels-env"},"annotations":null,"pod-policies.kyverno.io/autogen-controllers":"none","spec":{"background":false,"rules":[{"name":"set-service-label","match":{"resources":{"kinds":["Namespace"]}},"mutate":{"patchStrategicMerge":{"metadata":{"labels":{"+(service)":"{{request.object.spec.template.metadata.labels.app}}"}}}}}]}}`), - expectedControllers: "none", + expectedControllers: sets.New("none"), }, { name: "rule-with-match-kinds-pod-only-validate-exclude", @@ -150,9 +150,11 @@ func Test_CanAutoGen(t *testing.T) { applyAutoGen, controllers := CanAutoGen(&policy.Spec) if !applyAutoGen { - controllers = "none" + controllers = sets.New("none") } - assert.Equal(t, test.expectedControllers, controllers, fmt.Sprintf("test %s failed", test.name)) + + equalityTest := test.expectedControllers.Equal(controllers) + assert.Assert(t, equalityTest, fmt.Sprintf("expected: %v, got: %v", test.expectedControllers, controllers)) }) } } @@ -161,27 +163,27 @@ func Test_GetSupportedControllers(t *testing.T) { testCases := []struct { name string policy []byte - expectedControllers string + expectedControllers sets.Set[string] }{ { name: "rule-with-match-name", policy: []byte(`{"apiVersion":"kyverno.io/v1","kind":"ClusterPolicy","metadata":{"name":"test"},"spec":{"rules":[{"name":"test","match":{"resources":{"kinds":["Namespace"],"name":"*"}}}]}}`), - expectedControllers: "none", + expectedControllers: sets.New[string](), }, { name: "rule-with-match-selector", policy: []byte(`{"apiVersion":"kyverno.io/v1","kind":"ClusterPolicy","metadata":{"name":"test-getcontrollers"},"spec":{"background":false,"rules":[{"name":"test-getcontrollers","match":{"resources":{"kinds":["Pod"],"selector":{"matchLabels":{"foo":"bar"}}}}}]}}`), - expectedControllers: "none", + expectedControllers: sets.New[string](), }, { name: "rule-with-exclude-name", policy: []byte(`{"apiVersion":"kyverno.io/v1","kind":"ClusterPolicy","metadata":{"name":"test-getcontrollers"},"spec":{"background":false,"rules":[{"name":"test-getcontrollers","match":{"resources":{"kinds":["Pod"]}},"exclude":{"resources":{"name":"test"}}}]}}`), - expectedControllers: "none", + expectedControllers: sets.New[string](), }, { name: "rule-with-exclude-selector", policy: []byte(`{"apiVersion":"kyverno.io/v1","kind":"ClusterPolicy","metadata":{"name":"test-getcontrollers"},"spec":{"background":false,"rules":[{"name":"test-getcontrollers","match":{"resources":{"kinds":["Pod"]}},"exclude":{"resources":{"selector":{"matchLabels":{"foo":"bar"}}}}}]}}`), - expectedControllers: "none", + expectedControllers: sets.New[string](), }, { name: "rule-with-deny", @@ -191,12 +193,12 @@ func Test_GetSupportedControllers(t *testing.T) { { name: "rule-with-match-mixed-kinds-pod-podcontrollers", policy: []byte(`{"apiVersion":"kyverno.io/v1","kind":"ClusterPolicy","metadata":{"name":"set-service-labels-env"},"spec":{"background":false,"rules":[{"name":"set-service-label","match":{"resources":{"kinds":["Pod","Deployment"]}},"preconditions":{"any":[{"key":"{{request.operation}}","operator":"Equals","value":"CREATE"}]},"mutate":{"patchStrategicMerge":{"metadata":{"labels":{"+(service)":"{{request.object.spec.template.metadata.labels.app}}"}}}}}]}}`), - expectedControllers: "none", + expectedControllers: sets.New[string](), }, { name: "rule-with-exclude-mixed-kinds-pod-podcontrollers", policy: []byte(`{"apiVersion":"kyverno.io/v1","kind":"ClusterPolicy","metadata":{"name":"set-service-labels-env"},"spec":{"background":false,"rules":[{"name":"set-service-label","match":{"resources":{"kinds":["Pod"]}},"exclude":{"resources":{"kinds":["Pod","Deployment"]}},"mutate":{"patchStrategicMerge":{"metadata":{"labels":{"+(service)":"{{request.object.spec.template.metadata.labels.app}}"}}}}}]}}`), - expectedControllers: "none", + expectedControllers: sets.New[string](), }, { name: "rule-with-match-kinds-pod-only", @@ -211,27 +213,27 @@ func Test_GetSupportedControllers(t *testing.T) { { name: "rule-with-mutate-patches", policy: []byte(`{"apiVersion":"kyverno.io/v1","kind":"ClusterPolicy","metadata":{"name":"test"},"spec":{"rules":[{"name":"test","match":{"resources":{"kinds":["Pod"]}},"mutate":{"patchesJson6902":"-op:add\npath:/spec/containers/0/env/-1\nvalue:{\"name\":\"SERVICE\",\"value\":{{request.object.spec.template.metadata.labels.app}}}"}}]}}`), - expectedControllers: "none", + expectedControllers: sets.New[string](), }, { name: "rule-with-generate", policy: []byte(`{"apiVersion":"kyverno.io/v1","kind":"ClusterPolicy","metadata":{"name":"add-networkpolicy"},"spec":{"rules":[{"name":"default-deny-ingress","match":{"resources":{"kinds":["Namespace"],"name":"*"}},"exclude":{"resources":{"namespaces":["kube-system","default","kube-public","kyverno"]}},"generate":{"kind":"NetworkPolicy","name":"default-deny-ingress","namespace":"{{request.object.metadata.name}}","synchronize":true,"data":{"spec":{"podSelector":{},"policyTypes":["Ingress"]}}}}]}}`), - expectedControllers: "none", + expectedControllers: sets.New[string](), }, { name: "rule-with-predefined-invalid-controllers", policy: []byte(`{"apiVersion":"kyverno.io/v1","kind":"ClusterPolicy","metadata":{"name":"set-service-labels-env"},"annotations":null,"pod-policies.kyverno.io/autogen-controllers":"DaemonSet,Deployment,StatefulSet","spec":{"background":false,"rules":[{"name":"set-service-label","match":{"resources":{"kinds":["Pod","Deployment"]}},"mutate":{"patchStrategicMerge":{"metadata":{"labels":{"+(service)":"{{request.object.spec.template.metadata.labels.app}}"}}}}}]}}`), - expectedControllers: "none", + expectedControllers: sets.New[string](), }, { name: "rule-with-predefined-valid-controllers", policy: []byte(`{"apiVersion":"kyverno.io/v1","kind":"ClusterPolicy","metadata":{"name":"set-service-labels-env"},"annotations":null,"pod-policies.kyverno.io/autogen-controllers":"none","spec":{"background":false,"rules":[{"name":"set-service-label","match":{"resources":{"kinds":["Pod","Deployment"]}},"mutate":{"patchStrategicMerge":{"metadata":{"labels":{"+(service)":"{{request.object.spec.template.metadata.labels.app}}"}}}}}]}}`), - expectedControllers: "none", + expectedControllers: sets.New[string](), }, { name: "rule-with-only-predefined-valid-controllers", policy: []byte(`{"apiVersion":"kyverno.io/v1","kind":"ClusterPolicy","metadata":{"name":"set-service-labels-env"},"annotations":null,"pod-policies.kyverno.io/autogen-controllers":"none","spec":{"background":false,"rules":[{"name":"set-service-label","match":{"resources":{"kinds":["Namespace"]}},"mutate":{"patchStrategicMerge":{"metadata":{"labels":{"+(service)":"{{request.object.spec.template.metadata.labels.app}}"}}}}}]}}`), - expectedControllers: "none", + expectedControllers: sets.New[string](), }, { name: "rule-with-match-kinds-pod-only-validate-exclude", @@ -253,12 +255,8 @@ func Test_GetSupportedControllers(t *testing.T) { controllers := GetSupportedControllers(&policy.Spec) - var expectedControllers []string - if test.expectedControllers != "none" { - expectedControllers = strings.Split(test.expectedControllers, ",") - } - - assert.DeepEqual(t, expectedControllers, controllers) + equalityTest := test.expectedControllers.Equal(controllers) + assert.Assert(t, equalityTest, fmt.Sprintf("expected: %v, got: %v", test.expectedControllers, controllers)) }) } } @@ -267,7 +265,7 @@ func Test_GetRequestedControllers(t *testing.T) { testCases := []struct { name string meta metav1.ObjectMeta - expectedControllers []string + expectedControllers sets.Set[string] }{ { name: "annotations-nil", @@ -287,24 +285,26 @@ func Test_GetRequestedControllers(t *testing.T) { { name: "annotation-none", meta: metav1.ObjectMeta{Annotations: map[string]string{kyverno.AnnotationAutogenControllers: "none"}}, - expectedControllers: []string{}, + expectedControllers: sets.New[string](), }, { name: "annotation-job", meta: metav1.ObjectMeta{Annotations: map[string]string{kyverno.AnnotationAutogenControllers: "Job"}}, - expectedControllers: []string{"Job"}, + expectedControllers: sets.New[string]("Job"), }, { name: "annotation-job-deployment", meta: metav1.ObjectMeta{Annotations: map[string]string{kyverno.AnnotationAutogenControllers: "Job,Deployment"}}, - expectedControllers: []string{"Job", "Deployment"}, + expectedControllers: sets.New[string]("Job", "Deployment"), }, } for _, test := range testCases { t.Run(test.name, func(t *testing.T) { controllers := GetRequestedControllers(&test.meta) - assert.DeepEqual(t, test.expectedControllers, controllers) + + equalityTest := test.expectedControllers.Equal(controllers) + assert.Assert(t, equalityTest, fmt.Sprintf("expected: %v, got: %v", test.expectedControllers, controllers)) }) } } @@ -480,45 +480,6 @@ GdxLXeocztZ220idf6uDYeNLnGLBfkodEgFV0RmrlnHQYQdRqj3hjClLAkNqKVrz rxNyyQvgaswK+4kHAPQhv+ipx4Q0eeROpp3prJ+dD0hhk8niQSKWQWZHyElhzIKv FlDw3fzPhtberBblY4Y9u525ev999SogMBTXoSkfajRR2ol10xUxY60kVbqoEUln kA== ------END CERTIFICATE-----`, - }, - }}, - }}, - }}, - }, { - Name: "autogen-check-image", - MatchResources: kyvernov1.MatchResources{ - ResourceDescription: kyvernov1.ResourceDescription{ - Kinds: []string{"DaemonSet", "Deployment", "Job", "StatefulSet", "ReplicaSet", "ReplicationController"}, - }, - }, - VerifyImages: []kyvernov1.ImageVerification{{ - ImageReferences: []string{"*"}, - Attestors: []kyvernov1.AttestorSet{{ - Count: intPtr(1), - Entries: []kyvernov1.Attestor{{ - Keyless: &kyvernov1.KeylessAttestor{ - Roots: `-----BEGIN CERTIFICATE----- -MIIDjTCCAnWgAwIBAgIQb8yUrbw3aYZAubIjOJkFBjANBgkqhkiG9w0BAQsFADBZ -MRMwEQYKCZImiZPyLGQBGRYDY29tMRowGAYKCZImiZPyLGQBGRYKdmVuYWZpZGVt -bzEmMCQGA1UEAxMddmVuYWZpZGVtby1FQzJBTUFaLVFOSVI4OUktQ0EwHhcNMjAx -MjE0MjEzNzAzWhcNMjUxMjE0MjE0NzAzWjBZMRMwEQYKCZImiZPyLGQBGRYDY29t -MRowGAYKCZImiZPyLGQBGRYKdmVuYWZpZGVtbzEmMCQGA1UEAxMddmVuYWZpZGVt -by1FQzJBTUFaLVFOSVI4OUktQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK -AoIBAQC5CTVQczGnh77yNxq+BGh5ff0qNcRTkFll+y8lJbMPHevebF7JLWBQTGS7 -9aHIqUQLjy9sPOkdMrDh/vOZNVhVrHon9uwepF81dUMJ9lMbfQSI/tytp78f0z6b -DVRHYZr/taYSkqNPT2FuHOijc7Y+oB3Q1DzPSoBc3a6I5DM6ET6O2GZWo3mqpImG -J8+dNllYgjVKEuxuPqQjT7VD4fB2GqJbwwL0E8bSyfsgMV9Y+qHdznkm8v+TbYoc -9uS83f1fjjp98D7VtWpSC4O/27JWgEED/BB58sOipUQHiECr6dD5VWGJ9fnVOV2i -vHqj9cKS6BGMkAh99ss0Bu/3DEBxAgMBAAGjUTBPMAsGA1UdDwQEAwIBhjAPBgNV -HRMBAf8EBTADAQH/MB0GA1UdDgQWBBTuZecNgrj3Gdv9XpekFZuIkYtu9jAQBgkr -BgEEAYI3FQEEAwIBADANBgkqhkiG9w0BAQsFAAOCAQEADPNrGypaKliXJ+H7gt6b -NJSBdWB9EV63CdvxjLOuqvp3IUu8KIV2mMsulEjxjAb5kya0SURJVFvr9rrLVxvR -e6B2SJUGUKJkX1Cq4nIthwGfJTEnypYhqMKkfUYjqfszU+1CerRD2ZTJHeKZsc7M -GdxLXeocztZ220idf6uDYeNLnGLBfkodEgFV0RmrlnHQYQdRqj3hjClLAkNqKVrz -rxNyyQvgaswK+4kHAPQhv+ipx4Q0eeROpp3prJ+dD0hhk8niQSKWQWZHyElhzIKv -FlDw3fzPhtberBblY4Y9u525ev999SogMBTXoSkfajRR2ol10xUxY60kVbqoEUln -kA== -----END CERTIFICATE-----`, }, }}, @@ -572,7 +533,7 @@ kA== policies, _, _, err := yamlutils.GetPolicy([]byte(test.policy)) assert.NilError(t, err) assert.Equal(t, 1, len(policies)) - rules := computeRules(policies[0]) + rules := computeRules(policies[0], "CronJob") assert.DeepEqual(t, test.expectedRules, rules) }) } @@ -584,8 +545,8 @@ func Test_PodSecurityWithNoExceptions(t *testing.T) { assert.NilError(t, err) assert.Equal(t, 1, len(policies)) - rules := computeRules(policies[0]) - assert.Equal(t, 3, len(rules)) + rules := computeRules(policies[0], "Deployment") + assert.Equal(t, 2, len(rules)) } func Test_ValidateWithCELExpressions(t *testing.T) { @@ -632,6 +593,6 @@ func Test_ValidateWithCELExpressions(t *testing.T) { assert.NilError(t, err) assert.Equal(t, 1, len(policies)) - rules := computeRules(policies[0]) - assert.Equal(t, 3, len(rules)) + rules := computeRules(policies[0], "DaemonSet") + assert.Equal(t, 2, len(rules)) } diff --git a/pkg/background/generate/generate.go b/pkg/background/generate/generate.go index b5e079b3e3..9fbc44c6a4 100644 --- a/pkg/background/generate/generate.go +++ b/pkg/background/generate/generate.go @@ -342,7 +342,7 @@ func (c *GenerateController) ApplyGeneratePolicy(log logr.Logger, policyContext applyRules := policy.GetSpec().GetApplyRules() applyCount := 0 - for _, rule := range autogen.ComputeRules(policy) { + for _, rule := range autogen.ComputeRules(policy, "") { var err error if !rule.HasGenerate() { continue diff --git a/pkg/controllers/exceptions/controller.go b/pkg/controllers/exceptions/controller.go index 1d664c5f97..5ac7141150 100644 --- a/pkg/controllers/exceptions/controller.go +++ b/pkg/controllers/exceptions/controller.go @@ -155,7 +155,7 @@ func (c *controller) buildRuleIndex(key string, policy kyvernov1.PolicyInterface return 0 }) index := ruleIndex{} - for _, rule := range autogen.ComputeRules(policy) { + for _, rule := range autogen.ComputeRules(policy, "") { for _, polex := range polexList { if polex.Contains(key, rule.Name) { index[rule.Name] = append(index[rule.Name], polex) diff --git a/pkg/controllers/metrics/policy/controller.go b/pkg/controllers/metrics/policy/controller.go index 7e6d32d27e..04dae80e74 100644 --- a/pkg/controllers/metrics/policy/controller.go +++ b/pkg/controllers/metrics/policy/controller.go @@ -111,7 +111,7 @@ func (c *controller) reportPolicy(ctx context.Context, policy kyvernov1.PolicyIn attribute.String("policy_type", string(policyType)), attribute.String("policy_background_mode", string(backgroundMode)), } - for _, rule := range autogen.ComputeRules(policy) { + for _, rule := range autogen.ComputeRules(policy, "") { ruleType := metrics.ParseRuleType(rule) ruleAttributes := []attribute.KeyValue{ attribute.String("rule_name", rule.Name), diff --git a/pkg/controllers/report/aggregate/controller.go b/pkg/controllers/report/aggregate/controller.go index 43cfccb1a3..2defb1a03d 100644 --- a/pkg/controllers/report/aggregate/controller.go +++ b/pkg/controllers/report/aggregate/controller.go @@ -160,7 +160,7 @@ func (c *controller) createPolicyMap() (map[string]policyMapEntry, error) { policy: cpol, rules: sets.New[string](), } - for _, rule := range autogen.ComputeRules(cpol) { + for _, rule := range autogen.ComputeRules(cpol, "") { results[key].rules.Insert(rule.Name) } } @@ -177,7 +177,7 @@ func (c *controller) createPolicyMap() (map[string]policyMapEntry, error) { policy: pol, rules: sets.New[string](), } - for _, rule := range autogen.ComputeRules(pol) { + for _, rule := range autogen.ComputeRules(pol, "") { results[key].rules.Insert(rule.Name) } } diff --git a/pkg/controllers/report/utils/utils.go b/pkg/controllers/report/utils/utils.go index 109649d1ae..6b40818f9c 100644 --- a/pkg/controllers/report/utils/utils.go +++ b/pkg/controllers/report/utils/utils.go @@ -33,7 +33,7 @@ func CanBackgroundProcess(p kyvernov1.PolicyInterface) bool { func BuildKindSet(logger logr.Logger, policies ...kyvernov1.PolicyInterface) sets.Set[string] { kinds := sets.New[string]() for _, policy := range policies { - for _, rule := range autogen.ComputeRules(policy) { + for _, rule := range autogen.ComputeRules(policy, "") { if rule.HasValidate() || rule.HasVerifyImages() { kinds.Insert(rule.MatchResources.GetKinds()...) } diff --git a/pkg/controllers/webhook/controller.go b/pkg/controllers/webhook/controller.go index 5959a0604a..aee0d7d5fb 100644 --- a/pkg/controllers/webhook/controller.go +++ b/pkg/controllers/webhook/controller.go @@ -476,7 +476,7 @@ func (c *controller) updatePolicyStatuses(ctx context.Context) error { status := policy.GetStatus() status.SetReady(ready, message) status.Autogen.Rules = nil - rules := autogen.ComputeRules(policy) + rules := autogen.ComputeRules(policy, "") setRuleCount(rules, status) for _, rule := range rules { if strings.HasPrefix(rule.Name, "autogen-") { @@ -965,7 +965,7 @@ func (gvs GroupVersionResourceScope) String() string { // mergeWebhook merges the matching kinds of the policy to webhook.rule func (c *controller) mergeWebhook(dst *webhook, policy kyvernov1.PolicyInterface, updateValidate bool) { var matchedGVK []string - for _, rule := range autogen.ComputeRules(policy) { + 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.MatchResources.GetKinds()...) diff --git a/pkg/controllers/webhook/utils_test.go b/pkg/controllers/webhook/utils_test.go index f425c80dbf..f5c3953cdf 100644 --- a/pkg/controllers/webhook/utils_test.go +++ b/pkg/controllers/webhook/utils_test.go @@ -156,7 +156,7 @@ func Test_RuleCount(t *testing.T) { err := json.Unmarshal([]byte(policy), &cpol) assert.NilError(t, err) status := cpol.GetStatus() - rules := autogen.ComputeRules(&cpol) + rules := autogen.ComputeRules(&cpol, "") setRuleCount(rules, status) assert.Equal(t, status.RuleCount.Validate, 0) assert.Equal(t, status.RuleCount.Generate, 0) diff --git a/pkg/engine/background.go b/pkg/engine/background.go index 4c30de16d5..ce5ec52580 100644 --- a/pkg/engine/background.go +++ b/pkg/engine/background.go @@ -35,7 +35,7 @@ func (e *engine) filterRules( policy := policyContext.Policy() resp := engineapi.NewPolicyResponse() applyRules := policy.GetSpec().GetApplyRules() - for _, rule := range autogen.ComputeRules(policy) { + for _, rule := range autogen.ComputeRules(policy, "") { logger := internal.LoggerWithRule(logger, rule) if ruleResp := e.filterRule(rule, logger, policyContext); ruleResp != nil { resp.Rules = append(resp.Rules, *ruleResp) diff --git a/pkg/engine/fuzz_test.go b/pkg/engine/fuzz_test.go index 63888f3a12..1860c4b469 100644 --- a/pkg/engine/fuzz_test.go +++ b/pkg/engine/fuzz_test.go @@ -55,7 +55,7 @@ func buildFuzzContext(ff *fuzz.ConsumeFuzzer) (*PolicyContext, error) { cpol := &kyverno.ClusterPolicy{} cpol.Spec = cpSpec - if len(autogen.ComputeRules(cpol)) == 0 { + if len(autogen.ComputeRules(cpol, "")) == 0 { return nil, fmt.Errorf("No rules created") } @@ -145,7 +145,7 @@ func FuzzEngineValidateTest(f *testing.F) { policy := &kyverno.ClusterPolicy{} policy.Spec = cpSpec - if len(autogen.ComputeRules(policy)) == 0 { + if len(autogen.ComputeRules(policy, "")) == 0 { return } @@ -242,7 +242,7 @@ func FuzzMutateTest(f *testing.F) { policy := &kyverno.ClusterPolicy{} policy.Spec = cpSpec - if len(autogen.ComputeRules(policy)) == 0 { + if len(autogen.ComputeRules(policy, "")) == 0 { return } diff --git a/pkg/engine/generation.go b/pkg/engine/generation.go index b3109905e2..826bffbc7e 100644 --- a/pkg/engine/generation.go +++ b/pkg/engine/generation.go @@ -16,7 +16,7 @@ func (e *engine) generateResponse( policyContext engineapi.PolicyContext, ) engineapi.PolicyResponse { resp := engineapi.NewPolicyResponse() - for _, rule := range autogen.ComputeRules(policyContext.Policy()) { + for _, rule := range autogen.ComputeRules(policyContext.Policy(), "") { logger := internal.LoggerWithRule(logger, rule) if ruleResp := e.filterRule(rule, logger, policyContext); ruleResp != nil { resp.Rules = append(resp.Rules, *ruleResp) diff --git a/pkg/engine/image_verify.go b/pkg/engine/image_verify.go index c525f39e52..74f28d855c 100644 --- a/pkg/engine/image_verify.go +++ b/pkg/engine/image_verify.go @@ -28,7 +28,7 @@ func (e *engine) verifyAndPatchImages( policyContext.JSONContext().Checkpoint() defer policyContext.JSONContext().Restore() - for _, rule := range autogen.ComputeRules(policy) { + for _, rule := range autogen.ComputeRules(policy, "") { startTime := time.Now() logger := internal.LoggerWithRule(logger, rule) handlerFactory := func() (handlers.Handler, error) { diff --git a/pkg/engine/mutate/patch/strategicMergePatch_test.go b/pkg/engine/mutate/patch/strategicMergePatch_test.go index de13a84203..c37080e1e1 100644 --- a/pkg/engine/mutate/patch/strategicMergePatch_test.go +++ b/pkg/engine/mutate/patch/strategicMergePatch_test.go @@ -245,7 +245,7 @@ func Test_PolicyDeserilize(t *testing.T) { err := json.Unmarshal(rawPolicy, &policy) assert.NilError(t, err) - overlayPatches := autogen.ComputeRules(&policy)[0].Mutation.GetPatchStrategicMerge() + overlayPatches := autogen.ComputeRules(&policy, "")[0].Mutation.GetPatchStrategicMerge() patchString, err := json.Marshal(overlayPatches) assert.NilError(t, err) diff --git a/pkg/engine/mutation.go b/pkg/engine/mutation.go index a5e10977c2..d84e2a50ed 100644 --- a/pkg/engine/mutation.go +++ b/pkg/engine/mutation.go @@ -28,7 +28,7 @@ func (e *engine) mutate( policyContext.JSONContext().Checkpoint() defer policyContext.JSONContext().Restore() - for _, rule := range autogen.ComputeRules(policy) { + for _, rule := range autogen.ComputeRules(policy, "") { startTime := time.Now() logger := internal.LoggerWithRule(logger, rule) handlerFactory := func() (handlers.Handler, error) { diff --git a/pkg/engine/utils/utils_test.go b/pkg/engine/utils/utils_test.go index 2522bc7999..51f72bc343 100644 --- a/pkg/engine/utils/utils_test.go +++ b/pkg/engine/utils/utils_test.go @@ -904,7 +904,7 @@ func TestMatchesResourceDescription(t *testing.T) { } resource, _ := kubeutils.BytesToUnstructured(tc.Resource) - for _, rule := range autogen.ComputeRules(&policy) { + for _, rule := range autogen.ComputeRules(&policy, "") { err := MatchesResourceDescription(*resource, rule, tc.AdmissionInfo, nil, "", resource.GroupVersionKind(), "", "CREATE") if err != nil { if !tc.areErrorsExpected { @@ -1809,7 +1809,7 @@ func TestMatchesResourceDescription_GenerateName(t *testing.T) { } resource, _ := kubeutils.BytesToUnstructured(tc.Resource) - for _, rule := range autogen.ComputeRules(&policy) { + for _, rule := range autogen.ComputeRules(&policy, "") { err := MatchesResourceDescription(*resource, rule, tc.AdmissionInfo, nil, "", resource.GroupVersionKind(), "", "CREATE") if err != nil { if !tc.areErrorsExpected { diff --git a/pkg/engine/validation.go b/pkg/engine/validation.go index bd6ab4579b..64e4e95b97 100644 --- a/pkg/engine/validation.go +++ b/pkg/engine/validation.go @@ -26,7 +26,8 @@ func (e *engine) validate( policyContext.JSONContext().Checkpoint() defer policyContext.JSONContext().Restore() - for _, rule := range autogen.ComputeRules(policy) { + gvk, _ := policyContext.ResourceKind() + for _, rule := range autogen.ComputeRules(policy, gvk.Kind) { startTime := time.Now() logger := internal.LoggerWithRule(logger, rule) handlerFactory := func() (handlers.Handler, error) { diff --git a/pkg/policy/generate.go b/pkg/policy/generate.go index 7bd7ca2fda..90984c9974 100644 --- a/pkg/policy/generate.go +++ b/pkg/policy/generate.go @@ -64,7 +64,7 @@ func (pc *policyController) handleGenerateForExisting(policy kyvernov1.PolicyInt func (pc *policyController) createURForDownstreamDeletion(policy kyvernov1.PolicyInterface) error { var errs []error - rules := autogen.ComputeRules(policy) + rules := autogen.ComputeRules(policy, "") for _, r := range rules { generateType, sync, orphanDownstreamOnPolicyDelete := r.GetTypeAndSyncAndOrphanDownstream() if sync && (generateType == kyvernov1.Data) && !orphanDownstreamOnPolicyDelete { diff --git a/pkg/policycache/cache_test.go b/pkg/policycache/cache_test.go index 0e16fce2f8..bc4da40495 100644 --- a/pkg/policycache/cache_test.go +++ b/pkg/policycache/cache_test.go @@ -28,7 +28,7 @@ func Test_All(t *testing.T) { finder := TestResourceFinder{} //add setPolicy(t, pCache, policy, finder) - for _, rule := range autogen.ComputeRules(policy) { + for _, rule := range autogen.ComputeRules(policy, "") { for _, kind := range rule.MatchResources.Kinds { group, version, kind, subresource := kubeutils.ParseKindSelector(kind) gvrs, err := finder.FindResources(group, version, kind, subresource) @@ -64,7 +64,7 @@ func Test_Add_Duplicate_Policy(t *testing.T) { setPolicy(t, pCache, policy, finder) setPolicy(t, pCache, policy, finder) setPolicy(t, pCache, policy, finder) - for _, rule := range autogen.ComputeRules(policy) { + for _, rule := range autogen.ComputeRules(policy, "") { for _, kind := range rule.MatchResources.Kinds { group, version, kind, subresource := kubeutils.ParseKindSelector(kind) gvrs, err := finder.FindResources(group, version, kind, subresource) @@ -97,7 +97,7 @@ func Test_Add_Validate_Audit(t *testing.T) { policy.Spec.ValidationFailureAction = "audit" setPolicy(t, pCache, policy, finder) setPolicy(t, pCache, policy, finder) - for _, rule := range autogen.ComputeRules(policy) { + for _, rule := range autogen.ComputeRules(policy, "") { for _, kind := range rule.MatchResources.Kinds { group, version, kind, subresource := kubeutils.ParseKindSelector(kind) gvrs, err := finder.FindResources(group, version, kind, subresource) @@ -894,7 +894,7 @@ func Test_Ns_All(t *testing.T) { //add setPolicy(t, pCache, policy, finder) nspace := policy.GetNamespace() - for _, rule := range autogen.ComputeRules(policy) { + for _, rule := range autogen.ComputeRules(policy, "") { for _, kind := range rule.MatchResources.Kinds { group, version, kind, subresource := kubeutils.ParseKindSelector(kind) gvrs, err := finder.FindResources(group, version, kind, subresource) @@ -930,7 +930,7 @@ func Test_Ns_Add_Duplicate_Policy(t *testing.T) { setPolicy(t, pCache, policy, finder) setPolicy(t, pCache, policy, finder) nspace := policy.GetNamespace() - for _, rule := range autogen.ComputeRules(policy) { + for _, rule := range autogen.ComputeRules(policy, "") { for _, kind := range rule.MatchResources.Kinds { group, version, kind, subresource := kubeutils.ParseKindSelector(kind) gvrs, err := finder.FindResources(group, version, kind, subresource) @@ -963,7 +963,7 @@ func Test_Ns_Add_Validate_Audit(t *testing.T) { policy.GetSpec().ValidationFailureAction = "audit" setPolicy(t, pCache, policy, finder) setPolicy(t, pCache, policy, finder) - for _, rule := range autogen.ComputeRules(policy) { + for _, rule := range autogen.ComputeRules(policy, "") { for _, kind := range rule.MatchResources.Kinds { group, version, kind, subresource := kubeutils.ParseKindSelector(kind) gvrs, err := finder.FindResources(group, version, kind, subresource) @@ -1006,7 +1006,7 @@ func Test_GVk_Cache(t *testing.T) { finder := TestResourceFinder{} //add setPolicy(t, pCache, policy, finder) - for _, rule := range autogen.ComputeRules(policy) { + for _, rule := range autogen.ComputeRules(policy, "") { for _, kind := range rule.MatchResources.Kinds { group, version, kind, subresource := kubeutils.ParseKindSelector(kind) gvrs, err := finder.FindResources(group, version, kind, subresource) @@ -1044,7 +1044,7 @@ func Test_Add_Validate_Enforce(t *testing.T) { finder := TestResourceFinder{} //add setPolicy(t, pCache, policy, finder) - for _, rule := range autogen.ComputeRules(policy) { + for _, rule := range autogen.ComputeRules(policy, "") { for _, kind := range rule.MatchResources.Kinds { group, version, kind, subresource := kubeutils.ParseKindSelector(kind) gvrs, err := finder.FindResources(group, version, kind, subresource) @@ -1085,7 +1085,7 @@ func Test_Mutate_Policy(t *testing.T) { setPolicy(t, pCache, policy, finder) setPolicy(t, pCache, policy, finder) setPolicy(t, pCache, policy, finder) - for _, rule := range autogen.ComputeRules(policy) { + for _, rule := range autogen.ComputeRules(policy, "") { for _, kind := range rule.MatchResources.Kinds { group, version, kind, subresource := kubeutils.ParseKindSelector(kind) gvrs, err := finder.FindResources(group, version, kind, subresource) @@ -1107,7 +1107,7 @@ func Test_Generate_Policy(t *testing.T) { finder := TestResourceFinder{} //add setPolicy(t, pCache, policy, finder) - for _, rule := range autogen.ComputeRules(policy) { + for _, rule := range autogen.ComputeRules(policy, "") { for _, kind := range rule.MatchResources.Kinds { group, version, kind, subresource := kubeutils.ParseKindSelector(kind) gvrs, err := finder.FindResources(group, version, kind, subresource) diff --git a/pkg/policycache/store.go b/pkg/policycache/store.go index 547149342a..94afba7f1e 100644 --- a/pkg/policycache/store.go +++ b/pkg/policycache/store.go @@ -107,7 +107,7 @@ func (m *policyMap) set(key string, policy kyvernov1.PolicyInterface, client Res hasMutate, hasValidate, hasGenerate, hasVerifyImages, hasImagesValidationChecks bool } kindStates := map[policyKey]state{} - for _, rule := range autogen.ComputeRules(policy) { + for _, rule := range autogen.ComputeRules(policy, "") { entries := sets.New[policyKey]() for _, gvk := range rule.MatchResources.GetKinds() { group, version, kind, subresource := kubeutils.ParseKindSelector(gvk) diff --git a/pkg/validation/policy/background.go b/pkg/validation/policy/background.go index 184c1e88eb..773e85ee8b 100644 --- a/pkg/validation/policy/background.go +++ b/pkg/validation/policy/background.go @@ -18,7 +18,7 @@ var ForbiddenUserVariables = []*regexp.Regexp{ // containsUserVariables returns error if variable that does not start from request.object func containsUserVariables(policy kyvernov1.PolicyInterface, vars [][]string) error { - rules := autogen.ComputeRules(policy) + rules := autogen.ComputeRules(policy, "") for idx := range rules { if err := hasUserMatchExclude(idx, &rules[idx]); err != nil { return err diff --git a/pkg/validation/policy/validate.go b/pkg/validation/policy/validate.go index c4c0f73f88..bc28a4c8c4 100644 --- a/pkg/validation/policy/validate.go +++ b/pkg/validation/policy/validate.go @@ -224,7 +224,7 @@ func Validate(policy, oldPolicy kyvernov1.PolicyInterface, client dclient.Interf return warnings, err } - rules := autogen.ComputeRules(policy) + rules := autogen.ComputeRules(policy, "") rulesPath := specPath.Child("rules") for i, rule := range rules { @@ -505,7 +505,7 @@ func ValidateVariables(p kyvernov1.PolicyInterface, backgroundMode bool) error { // hasInvalidVariables - checks for unexpected variables in the policy func hasInvalidVariables(policy kyvernov1.PolicyInterface, background bool) error { - for _, r := range autogen.ComputeRules(policy) { + for _, r := range autogen.ComputeRules(policy, "") { ruleCopy := r.DeepCopy() if err := ruleForbiddenSectionsHaveVariables(ruleCopy); err != nil { diff --git a/pkg/webhooks/resource/updaterequest.go b/pkg/webhooks/resource/updaterequest.go index eeb6cb162a..97d5d35295 100644 --- a/pkg/webhooks/resource/updaterequest.go +++ b/pkg/webhooks/resource/updaterequest.go @@ -51,7 +51,7 @@ func (h *resourceHandlers) handleMutateExisting(ctx context.Context, logger logr // skip rules that don't specify the DELETE operation in case the admission request is of type DELETE var skipped []string - for _, rule := range autogen.ComputeRules(policy) { + for _, rule := range autogen.ComputeRules(policy, "") { if request.AdmissionRequest.Operation == admissionv1.Delete && !webhookutils.MatchDeleteOperation(rule) { skipped = append(skipped, rule.Name) }