1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2024-12-15 17:51:20 +00:00

refactor: migrate context loaders (part 1) from #7597 (#7676)

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
This commit is contained in:
Charles-Edouard Brétéché 2023-06-26 19:18:32 +02:00 committed by GitHub
parent f9209de3ff
commit a7cfeaa3ce
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 61 additions and 41 deletions

View file

@ -76,7 +76,7 @@ type Interface interface {
AddImageInfos(resource *unstructured.Unstructured, cfg config.Configuration) error
// AddDeferredLoader adds a loader that is executed on first use (query)
AddDeferredLoader(name string, loader DeferredLoader)
AddDeferredLoader(name string, loader Loader) error
// ImageInfo returns image infos present in the context
ImageInfo() map[string]map[string]apiutils.ImageInfo
@ -100,9 +100,6 @@ type Interface interface {
addJSON(dataRaw []byte) error
}
// DeferredLoader loads the context data on first use (query)
type DeferredLoader func() error
// Context stores the data resources as JSON
type context struct {
jp jmespath.Interface
@ -115,7 +112,7 @@ type context struct {
type deferredLoaders struct {
mutex sync.Mutex
loaders map[string]DeferredLoader
loaders map[string]Loader
}
// NewContext returns a new context
@ -130,7 +127,7 @@ func NewContextFromRaw(jp jmespath.Interface, raw []byte) Interface {
jsonRaw: raw,
jsonRawCheckpoints: make([][]byte, 0),
deferred: deferredLoaders{
loaders: make(map[string]DeferredLoader),
loaders: make(map[string]Loader),
},
}
}
@ -353,8 +350,9 @@ func (ctx *context) reset(remove bool) {
}
}
func (ctx *context) AddDeferredLoader(name string, loader DeferredLoader) {
func (ctx *context) AddDeferredLoader(name string, loader Loader) error {
ctx.deferred.mutex.Lock()
defer ctx.deferred.mutex.Unlock()
ctx.deferred.loaders[name] = loader
return nil
}

View file

@ -67,7 +67,7 @@ func (ctx *context) evaluateLoader(name string) error {
return nil
}
delete(ctx.deferred.loaders, name)
return loader()
return loader.LoadData()
}
func (ctx *context) HasChanged(jmespath string) (bool, error) {

View file

@ -8,22 +8,36 @@ import (
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
enginecontext "github.com/kyverno/kyverno/pkg/engine/context"
"github.com/kyverno/kyverno/pkg/engine/context/loaders"
"github.com/kyverno/kyverno/pkg/engine/jmespath"
"github.com/kyverno/kyverno/pkg/logging"
)
func DefaultContextLoaderFactory(cmResolver engineapi.ConfigmapResolver) engineapi.ContextLoaderFactory {
return func(policy kyvernov1.PolicyInterface, rule kyvernov1.Rule) engineapi.ContextLoader {
return &contextLoader{
type ContextLoaderFactoryOptions func(*contextLoader)
func DefaultContextLoaderFactory(cmResolver engineapi.ConfigmapResolver, opts ...ContextLoaderFactoryOptions) engineapi.ContextLoaderFactory {
return func(_ kyvernov1.PolicyInterface, _ kyvernov1.Rule) engineapi.ContextLoader {
cl := &contextLoader{
logger: logging.WithName("DefaultContextLoaderFactory"),
cmResolver: cmResolver,
}
for _, o := range opts {
o(cl)
}
return cl
}
}
func WithInitializer(initializer engineapi.Initializer) ContextLoaderFactoryOptions {
return func(cl *contextLoader) {
cl.initializers = append(cl.initializers, initializer)
}
}
type contextLoader struct {
logger logr.Logger
cmResolver engineapi.ConfigmapResolver
logger logr.Logger
cmResolver engineapi.ConfigmapResolver
initializers []engineapi.Initializer
}
func (l *contextLoader) Load(
@ -34,12 +48,21 @@ func (l *contextLoader) Load(
contextEntries []kyvernov1.ContextEntry,
jsonContext enginecontext.Interface,
) error {
for _, entry := range contextEntries {
deferredLoader := l.newDeferredLoader(ctx, jp, client, rclientFactory, entry, jsonContext)
if deferredLoader == nil {
return fmt.Errorf("invalid context entry %s", entry.Name)
for _, init := range l.initializers {
if err := init(jsonContext); err != nil {
return err
}
}
for _, entry := range contextEntries {
deferredLoader, err := l.newDeferredLoader(ctx, jp, client, rclientFactory, entry, jsonContext)
if err != nil {
return fmt.Errorf("failed to create deferred loader for context entry %s", entry.Name)
}
if deferredLoader != nil {
if err := jsonContext.AddDeferredLoader(entry.Name, deferredLoader); err != nil {
return err
}
}
jsonContext.AddDeferredLoader(entry.Name, deferredLoader)
}
return nil
}
@ -51,36 +74,35 @@ func (l *contextLoader) newDeferredLoader(
rclientFactory engineapi.RegistryClientFactory,
entry kyvernov1.ContextEntry,
jsonContext enginecontext.Interface,
) enginecontext.DeferredLoader {
) (enginecontext.Loader, error) {
if entry.ConfigMap != nil {
return func() error {
if err := engineapi.LoadConfigMap(ctx, l.logger, entry, jsonContext, l.cmResolver); err != nil {
return err
}
return nil
if l.cmResolver != nil {
l := loaders.NewConfigMapLoader(ctx, l.logger, entry, l.cmResolver, jsonContext)
return l, nil
} else {
l.logger.Info("disabled loading of ConfigMap context entry %s", entry.Name)
return nil, nil
}
} else if entry.APICall != nil {
return func() error {
if err := engineapi.LoadAPIData(ctx, jp, l.logger, entry, jsonContext, client); err != nil {
return err
}
return nil
if client != nil {
l := loaders.NewAPILoader(ctx, l.logger, entry, jsonContext, jp, client)
return l, nil
} else {
l.logger.Info("disabled loading of APICall context entry %s", entry.Name)
return nil, nil
}
} else if entry.ImageRegistry != nil {
return func() error {
if err := engineapi.LoadImageData(ctx, jp, rclientFactory, l.logger, entry, jsonContext); err != nil {
return err
}
return nil
if rclientFactory != nil {
l := loaders.NewImageDataLoader(ctx, l.logger, entry, jsonContext, jp, rclientFactory)
return l, nil
} else {
l.logger.Info("disabled loading of ImageRegistry context entry %s", entry.Name)
return nil, nil
}
} else if entry.Variable != nil {
return func() error {
if err := engineapi.LoadVariable(l.logger, jp, entry, jsonContext); err != nil {
return err
}
return nil
}
l := loaders.NewVariableLoader(l.logger, entry, jsonContext, jp)
return l, nil
}
return nil
return nil, fmt.Errorf("missing ConfigMap|APICall|ImageRegistry|Variable in context entry %s", entry.Name)
}