diff --git a/pkg/autogen/rule.go b/pkg/autogen/rule.go index 45db01b377..a9f852f09b 100644 --- a/pkg/autogen/rule.go +++ b/pkg/autogen/rule.go @@ -10,6 +10,7 @@ import ( kyverno "github.com/kyverno/kyverno/api/kyverno/v1" "github.com/kyverno/kyverno/pkg/engine/variables" "github.com/kyverno/kyverno/pkg/utils" + kubeutils "github.com/kyverno/kyverno/pkg/utils/kube" apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" ) @@ -77,8 +78,8 @@ func generateRuleForControllers(rule kyverno.Rule, controllers string, log logr. matchResourceDescriptionsKinds := rule.MatchKinds() excludeResourceDescriptionsKinds := rule.ExcludeKinds() - if !utils.ContainsKind(matchResourceDescriptionsKinds, "Pod") || - (len(excludeResourceDescriptionsKinds) != 0 && !utils.ContainsKind(excludeResourceDescriptionsKinds, "Pod")) { + if !kubeutils.ContainsKind(matchResourceDescriptionsKinds, "Pod") || + (len(excludeResourceDescriptionsKinds) != 0 && !kubeutils.ContainsKind(excludeResourceDescriptionsKinds, "Pod")) { return nil } diff --git a/pkg/autogen/utils.go b/pkg/autogen/utils.go index 4dc08a4599..5b4981cc9a 100644 --- a/pkg/autogen/utils.go +++ b/pkg/autogen/utils.go @@ -4,11 +4,11 @@ import ( "strings" kyverno "github.com/kyverno/kyverno/api/kyverno/v1" - "github.com/kyverno/kyverno/pkg/utils" + kubeutils "github.com/kyverno/kyverno/pkg/utils/kube" ) func isKindOtherthanPod(kinds []string) bool { - if len(kinds) > 1 && utils.ContainsKind(kinds, "Pod") { + if len(kinds) > 1 && kubeutils.ContainsKind(kinds, "Pod") { return true } return false @@ -39,7 +39,7 @@ func validateAnyPattern(anyPatterns []interface{}) []interface{} { func getAnyAllAutogenRule(v kyverno.ResourceFilters, controllers string) kyverno.ResourceFilters { anyKind := v.DeepCopy() for i, value := range v { - if utils.ContainsKind(value.Kinds, "Pod") { + if kubeutils.ContainsKind(value.Kinds, "Pod") { anyKind[i].Kinds = strings.Split(controllers, ",") } } @@ -65,7 +65,7 @@ func stripCronJob(controllers string) string { func cronJobAnyAllAutogenRule(v kyverno.ResourceFilters) kyverno.ResourceFilters { anyKind := v.DeepCopy() for i, value := range v { - if utils.ContainsKind(value.Kinds, "Job") { + if kubeutils.ContainsKind(value.Kinds, "Job") { anyKind[i].Kinds = []string{PodControllerCronJob} } } diff --git a/pkg/common/common.go b/pkg/common/common.go index 81e5655226..28f25459c5 100644 --- a/pkg/common/common.go +++ b/pkg/common/common.go @@ -70,21 +70,6 @@ func GetNamespaceLabels(namespaceObj *v1.Namespace, logger logr.Logger) map[stri return namespaceUnstructured.GetLabels() } -// GetKindFromGVK - get kind and APIVersion from GVK -func GetKindFromGVK(str string) (apiVersion string, kind string) { - if strings.Count(str, "/") == 0 { - return "", str - } - splitString := strings.Split(str, "/") - if strings.Count(str, "/") == 1 { - return splitString[0], splitString[1] - } - if splitString[1] == "*" { - return "", splitString[2] - } - return splitString[0] + "/" + splitString[1], splitString[2] -} - func VariableToJSON(key, value string) []byte { var subString string splitBySlash := strings.Split(key, "\"") @@ -203,14 +188,3 @@ func removePolicyFromLabels(pName string, labels map[string]string) (bool, map[s return false, labels } - -func GetFormatedKind(str string) (kind string) { - if strings.Count(str, "/") == 0 { - return strings.Title(str) - } - splitString := strings.Split(str, "/") - if strings.Count(str, "/") == 1 { - return splitString[0] + "/" + strings.Title(splitString[1]) - } - return splitString[0] + "/" + splitString[1] + "/" + strings.Title(splitString[2]) -} diff --git a/pkg/openapi/validation.go b/pkg/openapi/validation.go index 74713f32e1..4cd9b1f158 100644 --- a/pkg/openapi/validation.go +++ b/pkg/openapi/validation.go @@ -7,17 +7,16 @@ import ( "strings" "sync" - "github.com/pkg/errors" - "github.com/googleapis/gnostic/compiler" openapiv2 "github.com/googleapis/gnostic/openapiv2" v1 "github.com/kyverno/kyverno/api/kyverno/v1" "github.com/kyverno/kyverno/data" "github.com/kyverno/kyverno/pkg/autogen" - "github.com/kyverno/kyverno/pkg/common" "github.com/kyverno/kyverno/pkg/engine" "github.com/kyverno/kyverno/pkg/utils" + kubeutils "github.com/kyverno/kyverno/pkg/utils/kube" cmap "github.com/orcaman/concurrent-map" + "github.com/pkg/errors" "gopkg.in/yaml.v3" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -142,7 +141,7 @@ func (o *Controller) ValidatePolicyMutation(policy v1.PolicyInterface) error { for _, rule := range autogen.ComputeRules(policy) { if rule.HasMutate() { for _, kind := range rule.MatchResources.Kinds { - kindToRules[kind] = append(kindToRules[common.GetFormatedKind(kind)], rule) + kindToRules[kind] = append(kindToRules[kubeutils.GetFormatedKind(kind)], rule) } } } diff --git a/pkg/policy/existing.go b/pkg/policy/existing.go index b5cacdba6c..b00af3e221 100644 --- a/pkg/policy/existing.go +++ b/pkg/policy/existing.go @@ -15,6 +15,7 @@ import ( "github.com/kyverno/kyverno/pkg/metrics" policyExecutionDuration "github.com/kyverno/kyverno/pkg/metrics/policyexecutionduration" policyResults "github.com/kyverno/kyverno/pkg/metrics/policyresults" + kubeutils "github.com/kyverno/kyverno/pkg/utils/kube" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" ) @@ -207,7 +208,7 @@ func (pc *PolicyController) processExistingKinds(kinds []string, policy kyverno. logger = logger.WithValues("rule", rule.Name, "kind", kind) _, err := pc.rm.GetScope(kind) if err != nil { - gv, k := common.GetKindFromGVK(kind) + gv, k := kubeutils.GetKindFromGVK(kind) if !strings.Contains(k, "*") { resourceSchema, _, err := pc.client.DiscoveryClient.FindResource(gv, k) if err != nil { diff --git a/pkg/policy/validate.go b/pkg/policy/validate.go index 5439849bbf..2a62de7b6a 100644 --- a/pkg/policy/validate.go +++ b/pkg/policy/validate.go @@ -9,19 +9,18 @@ import ( "strings" "github.com/distribution/distribution/reference" - "github.com/kyverno/kyverno/pkg/autogen" - "github.com/kyverno/kyverno/pkg/engine/context" - jsonpatch "github.com/evanphx/json-patch/v5" "github.com/jmespath/go-jmespath" kyverno "github.com/kyverno/kyverno/api/kyverno/v1" - comn "github.com/kyverno/kyverno/pkg/common" + "github.com/kyverno/kyverno/pkg/autogen" dclient "github.com/kyverno/kyverno/pkg/dclient" "github.com/kyverno/kyverno/pkg/engine" + "github.com/kyverno/kyverno/pkg/engine/context" "github.com/kyverno/kyverno/pkg/engine/variables" "github.com/kyverno/kyverno/pkg/kyverno/common" "github.com/kyverno/kyverno/pkg/openapi" "github.com/kyverno/kyverno/pkg/utils" + kubeutils "github.com/kyverno/kyverno/pkg/utils/kube" "github.com/pkg/errors" v1beta1 "k8s.io/api/admission/v1beta1" "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions" @@ -1021,12 +1020,12 @@ func podControllerAutoGenExclusion(policy kyverno.PolicyInterface) bool { // and found in the cache, returns error if not found func validateKinds(kinds []string, mock bool, client *dclient.Client, p kyverno.PolicyInterface) error { for _, kind := range kinds { - gv, k := comn.GetKindFromGVK(kind) + gv, k := kubeutils.GetKindFromGVK(kind) if k == p.GetKind() { return fmt.Errorf("kind and match resource kind should not be the same") } - if !mock && !utils.SkipSubResources(k) && !strings.Contains(kind, "*") { + if !mock && !kubeutils.SkipSubResources(k) && !strings.Contains(kind, "*") { _, _, err := client.DiscoveryClient.FindResource(gv, k) if err != nil { return fmt.Errorf("unable to convert GVK to GVR, %s, err: %s", kinds, err) diff --git a/pkg/policycache/policy_cache.go b/pkg/policycache/policy_cache.go index 80186684ac..536887340a 100644 --- a/pkg/policycache/policy_cache.go +++ b/pkg/policycache/policy_cache.go @@ -4,8 +4,8 @@ import ( "github.com/go-logr/logr" kyverno "github.com/kyverno/kyverno/api/kyverno/v1" kyvernolister "github.com/kyverno/kyverno/pkg/client/listers/kyverno/v1" - "github.com/kyverno/kyverno/pkg/common" "github.com/kyverno/kyverno/pkg/policy" + kubeutils "github.com/kyverno/kyverno/pkg/utils/kube" ) // Interface ... @@ -84,7 +84,7 @@ func (pc *policyCache) remove(p kyverno.PolicyInterface) { } func (pc *policyCache) getPolicyObject(key PolicyType, gvk string, nspace string) (policyObject []kyverno.PolicyInterface) { - _, kind := common.GetKindFromGVK(gvk) + _, kind := kubeutils.GetKindFromGVK(gvk) policyNames := pc.pMap.get(key, kind, nspace) wildcardPolicies := pc.pMap.get(key, "*", nspace) policyNames = append(policyNames, wildcardPolicies...) diff --git a/pkg/policycache/policy_map.go b/pkg/policycache/policy_map.go index e4622b6611..910c9b92bc 100644 --- a/pkg/policycache/policy_map.go +++ b/pkg/policycache/policy_map.go @@ -6,8 +6,8 @@ import ( kyverno "github.com/kyverno/kyverno/api/kyverno/v1" "github.com/kyverno/kyverno/pkg/autogen" - "github.com/kyverno/kyverno/pkg/common" "github.com/kyverno/kyverno/pkg/policy" + kubeutils "github.com/kyverno/kyverno/pkg/utils/kube" ) type pMap struct { @@ -74,7 +74,7 @@ func (m *pMap) add(policy kyverno.PolicyInterface) { func (m *pMap) get(key PolicyType, gvk, namespace string) (names []string) { m.lock.RLock() defer m.lock.RUnlock() - _, kind := common.GetKindFromGVK(gvk) + _, kind := kubeutils.GetKindFromGVK(gvk) for _, policyName := range m.kindDataMap[kind][key] { ns, key, isNamespacedPolicy := policy.ParseNamespacedPolicy(policyName) if !isNamespacedPolicy && namespace == "" { @@ -115,7 +115,7 @@ func (m *pMap) remove(policy kyverno.PolicyInterface) { func addCacheHelper(rmr kyverno.ResourceFilter, m *pMap, rule kyverno.Rule, mutateMap map[string]bool, pName string, enforcePolicy bool, validateEnforceMap map[string]bool, validateAuditMap map[string]bool, generateMap map[string]bool, imageVerifyMap map[string]bool) { for _, gvk := range rmr.Kinds { - _, k := common.GetKindFromGVK(gvk) + _, k := kubeutils.GetKindFromGVK(gvk) kind := strings.Title(k) _, ok := m.kindDataMap[kind] if !ok { @@ -172,7 +172,7 @@ func addCacheHelper(rmr kyverno.ResourceFilter, m *pMap, rule kyverno.Rule, muta func removeCacheHelper(rmr kyverno.ResourceFilter, m *pMap, pName string) { for _, gvk := range rmr.Kinds { - _, kind := common.GetKindFromGVK(gvk) + _, kind := kubeutils.GetKindFromGVK(gvk) dataMap := m.kindDataMap[kind] for policyType, policies := range dataMap { var newPolicies []string diff --git a/pkg/policymutation/policymutation.go b/pkg/policymutation/policymutation.go index 1bd4d6c153..a6140afd67 100644 --- a/pkg/policymutation/policymutation.go +++ b/pkg/policymutation/policymutation.go @@ -8,9 +8,9 @@ import ( "github.com/go-logr/logr" kyverno "github.com/kyverno/kyverno/api/kyverno/v1" "github.com/kyverno/kyverno/pkg/autogen" - "github.com/kyverno/kyverno/pkg/common" "github.com/kyverno/kyverno/pkg/toggle" jsonutils "github.com/kyverno/kyverno/pkg/utils/json" + kubeutils "github.com/kyverno/kyverno/pkg/utils/kube" ) // GenerateJSONPatchesForDefaults generates default JSON patches for @@ -121,7 +121,7 @@ func checkForGVKFormatPatch(policy kyverno.PolicyInterface, log logr.Logger) (pa func convertGVKForKinds(path string, kinds []string, log logr.Logger) ([]byte, error) { kindList := []string{} for _, k := range kinds { - gvk := common.GetFormatedKind(k) + gvk := kubeutils.GetFormatedKind(k) if gvk == k { continue } diff --git a/pkg/resourcecache/resourcecache.go b/pkg/resourcecache/resourcecache.go index 8cd3af4a17..0627776780 100644 --- a/pkg/resourcecache/resourcecache.go +++ b/pkg/resourcecache/resourcecache.go @@ -3,7 +3,7 @@ package resourcecache import ( "fmt" - "github.com/kyverno/kyverno/pkg/common" + kubeutils "github.com/kyverno/kyverno/pkg/utils/kube" ) // CreateInformers ... @@ -44,7 +44,7 @@ func (resc *resourceCache) CreateGVKInformer(gvk string) (GenericCache, error) { if ok { return gc, nil } - gv, k := common.GetKindFromGVK(gvk) + gv, k := kubeutils.GetKindFromGVK(gvk) apiResource, gvr, err := resc.dclient.DiscoveryClient.FindResource(gv, k) if err != nil { return nil, fmt.Errorf("cannot find API resource %s", gvk) diff --git a/pkg/utils/kube/kind.go b/pkg/utils/kube/kind.go new file mode 100644 index 0000000000..ac8e9c7eeb --- /dev/null +++ b/pkg/utils/kube/kind.go @@ -0,0 +1,44 @@ +package kube + +import "strings" + +// GetKindFromGVK - get kind and APIVersion from GVK +func GetKindFromGVK(str string) (apiVersion string, kind string) { + if strings.Count(str, "/") == 0 { + return "", str + } + splitString := strings.Split(str, "/") + if strings.Count(str, "/") == 1 { + return splitString[0], splitString[1] + } + if splitString[1] == "*" { + return "", splitString[2] + } + return splitString[0] + "/" + splitString[1], splitString[2] +} + +func ContainsKind(list []string, kind string) bool { + for _, e := range list { + if _, k := GetKindFromGVK(e); k == kind { + return true + } + } + return false +} + +// SkipSubResources check to skip list of resources which don't have group. +func SkipSubResources(kind string) bool { + s := []string{"PodExecOptions", "PodAttachOptions", "PodProxyOptions", "ServiceProxyOptions", "NodeProxyOptions"} + return ContainsKind(s, kind) +} + +func GetFormatedKind(str string) (kind string) { + if strings.Count(str, "/") == 0 { + return strings.Title(str) + } + splitString := strings.Split(str, "/") + if strings.Count(str, "/") == 1 { + return splitString[0] + "/" + strings.Title(splitString[1]) + } + return splitString[0] + "/" + splitString[1] + "/" + strings.Title(splitString[2]) +} diff --git a/pkg/utils/util.go b/pkg/utils/util.go index b67f659b47..396f1ba3a1 100644 --- a/pkg/utils/util.go +++ b/pkg/utils/util.go @@ -12,7 +12,6 @@ import ( "github.com/go-logr/logr" wildcard "github.com/kyverno/go-wildcard" - common "github.com/kyverno/kyverno/pkg/common" client "github.com/kyverno/kyverno/pkg/dclient" engineutils "github.com/kyverno/kyverno/pkg/engine/utils" "k8s.io/api/admission/v1beta1" @@ -36,22 +35,6 @@ func contains(list []string, element string, fn func(string, string) bool) bool return false } -func ContainsKind(list []string, element string) bool { - for _, e := range list { - _, k := common.GetKindFromGVK(e) - if k == element { - return true - } - } - return false -} - -// SkipSubResources check to skip list of resources which don't have group. -func SkipSubResources(kind string) bool { - s := []string{"PodExecOptions", "PodAttachOptions", "PodProxyOptions", "ServiceProxyOptions", "NodeProxyOptions"} - return ContainsKind(s, kind) -} - // ContainsNamepace check if namespace satisfies any list of pattern(regex) func ContainsNamepace(patterns []string, ns string) bool { return contains(patterns, ns, compareNamespaces) diff --git a/pkg/webhookconfig/configmanager.go b/pkg/webhookconfig/configmanager.go index 775f26fb20..705038fb62 100644 --- a/pkg/webhookconfig/configmanager.go +++ b/pkg/webhookconfig/configmanager.go @@ -20,6 +20,7 @@ import ( client "github.com/kyverno/kyverno/pkg/dclient" "github.com/kyverno/kyverno/pkg/resourcecache" "github.com/kyverno/kyverno/pkg/utils" + kubeutils "github.com/kyverno/kyverno/pkg/utils/kube" "github.com/pkg/errors" admregapi "k8s.io/api/admissionregistration/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" @@ -752,7 +753,7 @@ func (m *webhookConfigManager) mergeWebhook(dst *webhook, policy kyverno.PolicyI gvkMap[gvk] = 1 // note: webhook stores GVR in its rules while policy stores GVK in its rules definition - gv, k := common.GetKindFromGVK(gvk) + gv, k := kubeutils.GetKindFromGVK(gvk) switch k { case "Binding": gvrList = append(gvrList, schema.GroupVersionResource{Group: "", Version: "v1", Resource: "pods/binding"})