1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2024-12-14 11:57:48 +00:00

chore: use concurrent map v2 (generics) (#4803)

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
This commit is contained in:
Charles-Edouard Brétéché 2022-10-05 18:35:09 +02:00 committed by GitHub
parent 90a62e76ce
commit f7dde0ab96
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 25 additions and 50 deletions

2
go.mod
View file

@ -31,7 +31,7 @@ require (
github.com/mattbaird/jsonpatch v0.0.0-20200820163806-098863c1fc24 github.com/mattbaird/jsonpatch v0.0.0-20200820163806-098863c1fc24
github.com/onsi/ginkgo v1.16.5 github.com/onsi/ginkgo v1.16.5
github.com/onsi/gomega v1.20.2 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/pkg/errors v0.9.1
github.com/sigstore/cosign v1.12.1 github.com/sigstore/cosign v1.12.1
github.com/sigstore/k8s-manifest-sigstore v0.4.1 github.com/sigstore/k8s-manifest-sigstore v0.4.1

4
go.sum
View file

@ -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.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.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
github.com/openzipkin/zipkin-go v0.2.5/go.mod h1:KpXfKdgRDnnhsxw4pNIH9Md5lyFqKUa4YDFlwRYAMyE= 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/v2 v2.0.0 h1:iSMwuBQvQ1nX5i9gYuGMiSy0fjWHmazdjF+NdSO9JzI=
github.com/orcaman/concurrent-map v1.0.0/go.mod h1:Lu3tH6HLW3feq74c2GC+jIMS/K2CFcDWnWD9XkenwhI= 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/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 v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE=
github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs=

View file

@ -15,7 +15,7 @@ import (
"github.com/kyverno/kyverno/pkg/engine" "github.com/kyverno/kyverno/pkg/engine"
"github.com/kyverno/kyverno/pkg/logging" "github.com/kyverno/kyverno/pkg/logging"
"github.com/kyverno/kyverno/pkg/utils" "github.com/kyverno/kyverno/pkg/utils"
cmap "github.com/orcaman/concurrent-map" cmap "github.com/orcaman/concurrent-map/v2"
"github.com/pkg/errors" "github.com/pkg/errors"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@ -24,7 +24,7 @@ import (
"k8s.io/kube-openapi/pkg/util/proto/validation" "k8s.io/kube-openapi/pkg/util/proto/validation"
) )
type concurrentMap struct{ cmap.ConcurrentMap } // type concurrentMap struct{ cmap.ConcurrentMap }
type ValidateInterface interface { type ValidateInterface interface {
ValidateResource(resource unstructured.Unstructured, apiVersion, kind string) error ValidateResource(resource unstructured.Unstructured, apiVersion, kind string) error
@ -33,7 +33,7 @@ type ValidateInterface interface {
// Controller represents OpenAPIController // Controller represents OpenAPIController
type Controller struct { type Controller struct {
// definitions holds the map of {definitionName: *openapiv2.Schema} // definitions holds the map of {definitionName: *openapiv2.Schema}
definitions concurrentMap definitions cmap.ConcurrentMap[*openapiv2.Schema]
// kindToDefinitionName holds the map of {(group/version/)kind: definitionName} // kindToDefinitionName holds the map of {(group/version/)kind: definitionName}
// i.e. with k8s 1.20.2 // 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/v1/Ingress: io.k8s.api.networking.v1.Ingress
// - networking.k8s.io/v1beta1/Ingress: io.k8s.api.networking.v1beta1.Ingress // - networking.k8s.io/v1beta1/Ingress: io.k8s.api.networking.v1beta1.Ingress
// - extension/v1beta1/Ingress: io.k8s.api.extensions.v1beta1.Ingress // - extension/v1beta1/Ingress: io.k8s.api.extensions.v1beta1.Ingress
gvkToDefinitionName concurrentMap gvkToDefinitionName cmap.ConcurrentMap[string]
crdList []string crdList []string
models proto.Models models proto.Models
// kindToAPIVersions stores the Kind and all its available apiVersions, {kind: apiVersions} // 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 // apiVersions stores all available gvks for a kind, a gvk is "/" separated string
@ -56,34 +56,12 @@ type apiVersions struct {
gvks []string 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 // NewOpenAPIController initializes a new instance of OpenAPIController
func NewOpenAPIController() (*Controller, error) { func NewOpenAPIController() (*Controller, error) {
controller := &Controller{ controller := &Controller{
definitions: newConcurrentMap(), definitions: cmap.New[*openapiv2.Schema](),
gvkToDefinitionName: newConcurrentMap(), gvkToDefinitionName: cmap.New[string](),
kindToAPIVersions: newConcurrentMap(), kindToAPIVersions: cmap.New[apiVersions](),
} }
apiResourceLists, preferredAPIResourcesLists, err := getAPIResourceLists() apiResourceLists, preferredAPIResourcesLists, err := getAPIResourceLists()
@ -115,7 +93,7 @@ func (o *Controller) ValidateResource(patchedResource unstructured.Unstructured,
gvk = apiVersion + "/" + kind gvk = apiVersion + "/" + kind
} }
kind = o.gvkToDefinitionName.GetKind(gvk) kind, _ = o.gvkToDefinitionName.Get(gvk)
schema := o.models.LookupModel(kind) schema := o.models.LookupModel(kind)
if schema == nil { if schema == nil {
// Check if kind is a CRD // Check if kind is a CRD
@ -153,8 +131,9 @@ func (o *Controller) ValidatePolicyMutation(policy kyvernov1.PolicyInterface) er
newPolicy := policy.CreateDeepCopy() newPolicy := policy.CreateDeepCopy()
spec := newPolicy.GetSpec() spec := newPolicy.GetSpec()
spec.SetRules(rules) spec.SetRules(rules)
k := o.gvkToDefinitionName.GetKind(kind) k, _ := o.gvkToDefinitionName.Get(kind)
resource, _ := o.generateEmptyResource(o.definitions.GetSchema(k)).(map[string]interface{}) d, _ := o.definitions.Get(k)
resource, _ := o.generateEmptyResource(d).(map[string]interface{})
if len(resource) == 0 { if len(resource) == 0 {
logging.V(2).Info("unable to validate resource. OpenApi definition not found", "kind", kind) logging.V(2).Info("unable to validate resource. OpenApi definition not found", "kind", kind)
return nil return nil
@ -221,22 +200,17 @@ func (o *Controller) getGVKByDefinitionName(definitionName string) (gvk string,
return return
} }
versionsTyped, ok := versions.(apiVersions) if matchGVK(definitionName, versions.serverPreferredGVK) {
if !ok {
return "", preferredGVK, fmt.Errorf("type mismatched, expected apiVersions, got %T", versions)
}
if matchGVK(definitionName, versionsTyped.serverPreferredGVK) {
preferredGVK = true preferredGVK = true
} }
for _, gvk := range versionsTyped.gvks { for _, gvk := range versions.gvks {
if matchGVK(definitionName, gvk) { if matchGVK(definitionName, gvk) {
return gvk, preferredGVK, nil 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) { func parseGVK(str string) (group, apiVersion, kind string) {
@ -300,7 +274,7 @@ func (c *Controller) updateKindToAPIVersions(apiResourceLists, preferredAPIResou
tempKindToAPIVersions := getAllAPIVersions(apiResourceLists) tempKindToAPIVersions := getAllAPIVersions(apiResourceLists)
tempKindToAPIVersions = setPreferredVersions(tempKindToAPIVersions, preferredAPIResourcesLists) tempKindToAPIVersions = setPreferredVersions(tempKindToAPIVersions, preferredAPIResourcesLists)
c.kindToAPIVersions = newConcurrentMap() c.kindToAPIVersions = cmap.New[apiVersions]()
for key, value := range tempKindToAPIVersions { for key, value := range tempKindToAPIVersions {
c.kindToAPIVersions.Set(key, value) c.kindToAPIVersions.Set(key, value)
} }
@ -324,7 +298,7 @@ func (o *Controller) getCRDSchema(kind string) (proto.Schema, error) {
} }
path := proto.NewPath(kind) path := proto.NewPath(kind)
definition := o.definitions.GetSchema(kind) definition, _ := o.definitions.Get(kind)
if definition == nil { if definition == nil {
return nil, errors.New("could not find definition") return nil, errors.New("could not find definition")
} }
@ -342,7 +316,8 @@ func (o *Controller) generateEmptyResource(kindSchema *openapiv2.Schema) interfa
types := kindSchema.GetType().GetValue() types := kindSchema.GetType().GetValue()
if kindSchema.GetXRef() != "" { 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 { if len(types) != 1 {

View file

@ -170,9 +170,9 @@ func Test_Ingress(t *testing.T) {
versions, ok := o.kindToAPIVersions.Get("Ingress") versions, ok := o.kindToAPIVersions.Get("Ingress")
assert.Equal(t, true, ok) assert.Equal(t, true, ok)
versionsTyped := versions.(apiVersions)
assert.Equal(t, versionsTyped.serverPreferredGVK, "networking.k8s.io/v1/Ingress") assert.Equal(t, versions.serverPreferredGVK, "networking.k8s.io/v1/Ingress")
assert.Equal(t, len(versionsTyped.gvks), 3) assert.Equal(t, len(versions.gvks), 3)
definitionName, _ := o.gvkToDefinitionName.Get("Ingress") definitionName, _ := o.gvkToDefinitionName.Get("Ingress")
assert.Equal(t, definitionName, "io.k8s.api.networking.v1.Ingress") assert.Equal(t, definitionName, "io.k8s.api.networking.v1.Ingress")