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:
parent
90a62e76ce
commit
f7dde0ab96
4 changed files with 25 additions and 50 deletions
2
go.mod
2
go.mod
|
@ -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
4
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.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=
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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")
|
||||||
|
|
Loading…
Reference in a new issue