From f7dde0ab96838220c0eea7323e4d49b9b2aad3fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charles-Edouard=20Br=C3=A9t=C3=A9ch=C3=A9?= Date: Wed, 5 Oct 2022 18:35:09 +0200 Subject: [PATCH] chore: use concurrent map v2 (generics) (#4803) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Charles-Edouard Brétéché Signed-off-by: Charles-Edouard Brétéché --- go.mod | 2 +- go.sum | 4 +-- pkg/openapi/validation.go | 63 ++++++++++------------------------ pkg/openapi/validation_test.go | 6 ++-- 4 files changed, 25 insertions(+), 50 deletions(-) diff --git a/go.mod b/go.mod index c6c52df355..d0f4ae3237 100644 --- a/go.mod +++ b/go.mod @@ -31,7 +31,7 @@ require ( github.com/mattbaird/jsonpatch v0.0.0-20200820163806-098863c1fc24 github.com/onsi/ginkgo v1.16.5 github.com/onsi/gomega v1.20.2 - github.com/orcaman/concurrent-map v1.0.0 + github.com/orcaman/concurrent-map/v2 v2.0.0 github.com/pkg/errors v0.9.1 github.com/sigstore/cosign v1.12.1 github.com/sigstore/k8s-manifest-sigstore v0.4.1 diff --git a/go.sum b/go.sum index 02e5e8552f..67f3bdcea1 100644 --- a/go.sum +++ b/go.sum @@ -1714,8 +1714,8 @@ github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJ github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= github.com/openzipkin/zipkin-go v0.2.5/go.mod h1:KpXfKdgRDnnhsxw4pNIH9Md5lyFqKUa4YDFlwRYAMyE= -github.com/orcaman/concurrent-map v1.0.0 h1:I/2A2XPCb4IuQWcQhBhSwGfiuybl/J0ev9HDbW65HOY= -github.com/orcaman/concurrent-map v1.0.0/go.mod h1:Lu3tH6HLW3feq74c2GC+jIMS/K2CFcDWnWD9XkenwhI= +github.com/orcaman/concurrent-map/v2 v2.0.0 h1:iSMwuBQvQ1nX5i9gYuGMiSy0fjWHmazdjF+NdSO9JzI= +github.com/orcaman/concurrent-map/v2 v2.0.0/go.mod h1:9Eq3TG2oBe5FirmYWQfYO5iH1q0Jv47PLaNK++uCdOM= github.com/otiai10/copy v1.2.0/go.mod h1:rrF5dJ5F0t/EWSYODDu4j9/vEeYHMkc8jt0zJChqQWw= github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= diff --git a/pkg/openapi/validation.go b/pkg/openapi/validation.go index 534ffc433b..f2f4292f0c 100644 --- a/pkg/openapi/validation.go +++ b/pkg/openapi/validation.go @@ -15,7 +15,7 @@ import ( "github.com/kyverno/kyverno/pkg/engine" "github.com/kyverno/kyverno/pkg/logging" "github.com/kyverno/kyverno/pkg/utils" - cmap "github.com/orcaman/concurrent-map" + cmap "github.com/orcaman/concurrent-map/v2" "github.com/pkg/errors" "gopkg.in/yaml.v3" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -24,7 +24,7 @@ import ( "k8s.io/kube-openapi/pkg/util/proto/validation" ) -type concurrentMap struct{ cmap.ConcurrentMap } +// type concurrentMap struct{ cmap.ConcurrentMap } type ValidateInterface interface { ValidateResource(resource unstructured.Unstructured, apiVersion, kind string) error @@ -33,7 +33,7 @@ type ValidateInterface interface { // Controller represents OpenAPIController type Controller struct { // definitions holds the map of {definitionName: *openapiv2.Schema} - definitions concurrentMap + definitions cmap.ConcurrentMap[*openapiv2.Schema] // kindToDefinitionName holds the map of {(group/version/)kind: definitionName} // i.e. with k8s 1.20.2 @@ -41,13 +41,13 @@ type Controller struct { // - networking.k8s.io/v1/Ingress: io.k8s.api.networking.v1.Ingress // - networking.k8s.io/v1beta1/Ingress: io.k8s.api.networking.v1beta1.Ingress // - extension/v1beta1/Ingress: io.k8s.api.extensions.v1beta1.Ingress - gvkToDefinitionName concurrentMap + gvkToDefinitionName cmap.ConcurrentMap[string] crdList []string models proto.Models // kindToAPIVersions stores the Kind and all its available apiVersions, {kind: apiVersions} - kindToAPIVersions concurrentMap + kindToAPIVersions cmap.ConcurrentMap[apiVersions] } // apiVersions stores all available gvks for a kind, a gvk is "/" separated string @@ -56,34 +56,12 @@ type apiVersions struct { gvks []string } -func newConcurrentMap() concurrentMap { - return concurrentMap{cmap.New()} -} - -func (m concurrentMap) GetKind(key string) string { - k, ok := m.Get(key) - if !ok { - return "" - } - - return k.(string) -} - -func (m concurrentMap) GetSchema(key string) *openapiv2.Schema { - k, ok := m.Get(key) - if !ok { - return nil - } - - return k.(*openapiv2.Schema) -} - // NewOpenAPIController initializes a new instance of OpenAPIController func NewOpenAPIController() (*Controller, error) { controller := &Controller{ - definitions: newConcurrentMap(), - gvkToDefinitionName: newConcurrentMap(), - kindToAPIVersions: newConcurrentMap(), + definitions: cmap.New[*openapiv2.Schema](), + gvkToDefinitionName: cmap.New[string](), + kindToAPIVersions: cmap.New[apiVersions](), } apiResourceLists, preferredAPIResourcesLists, err := getAPIResourceLists() @@ -115,7 +93,7 @@ func (o *Controller) ValidateResource(patchedResource unstructured.Unstructured, gvk = apiVersion + "/" + kind } - kind = o.gvkToDefinitionName.GetKind(gvk) + kind, _ = o.gvkToDefinitionName.Get(gvk) schema := o.models.LookupModel(kind) if schema == nil { // Check if kind is a CRD @@ -153,8 +131,9 @@ func (o *Controller) ValidatePolicyMutation(policy kyvernov1.PolicyInterface) er newPolicy := policy.CreateDeepCopy() spec := newPolicy.GetSpec() spec.SetRules(rules) - k := o.gvkToDefinitionName.GetKind(kind) - resource, _ := o.generateEmptyResource(o.definitions.GetSchema(k)).(map[string]interface{}) + k, _ := o.gvkToDefinitionName.Get(kind) + d, _ := o.definitions.Get(k) + resource, _ := o.generateEmptyResource(d).(map[string]interface{}) if len(resource) == 0 { logging.V(2).Info("unable to validate resource. OpenApi definition not found", "kind", kind) return nil @@ -221,22 +200,17 @@ func (o *Controller) getGVKByDefinitionName(definitionName string) (gvk string, return } - versionsTyped, ok := versions.(apiVersions) - if !ok { - return "", preferredGVK, fmt.Errorf("type mismatched, expected apiVersions, got %T", versions) - } - - if matchGVK(definitionName, versionsTyped.serverPreferredGVK) { + if matchGVK(definitionName, versions.serverPreferredGVK) { preferredGVK = true } - for _, gvk := range versionsTyped.gvks { + for _, gvk := range versions.gvks { if matchGVK(definitionName, gvk) { return gvk, preferredGVK, nil } } - return "", preferredGVK, fmt.Errorf("gvk not found by the given definition name %s, %v", definitionName, versionsTyped.gvks) + return "", preferredGVK, fmt.Errorf("gvk not found by the given definition name %s, %v", definitionName, versions.gvks) } func parseGVK(str string) (group, apiVersion, kind string) { @@ -300,7 +274,7 @@ func (c *Controller) updateKindToAPIVersions(apiResourceLists, preferredAPIResou tempKindToAPIVersions := getAllAPIVersions(apiResourceLists) tempKindToAPIVersions = setPreferredVersions(tempKindToAPIVersions, preferredAPIResourcesLists) - c.kindToAPIVersions = newConcurrentMap() + c.kindToAPIVersions = cmap.New[apiVersions]() for key, value := range tempKindToAPIVersions { c.kindToAPIVersions.Set(key, value) } @@ -324,7 +298,7 @@ func (o *Controller) getCRDSchema(kind string) (proto.Schema, error) { } path := proto.NewPath(kind) - definition := o.definitions.GetSchema(kind) + definition, _ := o.definitions.Get(kind) if definition == nil { return nil, errors.New("could not find definition") } @@ -342,7 +316,8 @@ func (o *Controller) generateEmptyResource(kindSchema *openapiv2.Schema) interfa types := kindSchema.GetType().GetValue() if kindSchema.GetXRef() != "" { - return o.generateEmptyResource(o.definitions.GetSchema(strings.TrimPrefix(kindSchema.GetXRef(), "#/definitions/"))) + d, _ := o.definitions.Get(strings.TrimPrefix(kindSchema.GetXRef(), "#/definitions/")) + return o.generateEmptyResource(d) } if len(types) != 1 { diff --git a/pkg/openapi/validation_test.go b/pkg/openapi/validation_test.go index 2157837123..853a59ca1c 100644 --- a/pkg/openapi/validation_test.go +++ b/pkg/openapi/validation_test.go @@ -170,9 +170,9 @@ func Test_Ingress(t *testing.T) { versions, ok := o.kindToAPIVersions.Get("Ingress") assert.Equal(t, true, ok) - versionsTyped := versions.(apiVersions) - assert.Equal(t, versionsTyped.serverPreferredGVK, "networking.k8s.io/v1/Ingress") - assert.Equal(t, len(versionsTyped.gvks), 3) + + assert.Equal(t, versions.serverPreferredGVK, "networking.k8s.io/v1/Ingress") + assert.Equal(t, len(versions.gvks), 3) definitionName, _ := o.gvkToDefinitionName.Get("Ingress") assert.Equal(t, definitionName, "io.k8s.api.networking.v1.Ingress")