mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-06 16:06:56 +00:00
feat: add support for more context elements (#11986)
Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
This commit is contained in:
parent
02c54490bc
commit
ed80be3eff
4 changed files with 121 additions and 1 deletions
|
@ -26,3 +26,33 @@ func (c *impl) get_configmap_string_string(args ...ref.Val) ref.Val {
|
|||
return c.NativeToValue(cm.UnstructuredContent())
|
||||
}
|
||||
}
|
||||
|
||||
func (c *impl) get_globalreference_string(ctx ref.Val, name ref.Val) ref.Val {
|
||||
if self, err := utils.ConvertToNative[Context](ctx); err != nil {
|
||||
return types.WrapErr(err)
|
||||
} else if name, err := utils.ConvertToNative[string](name); err != nil {
|
||||
return types.WrapErr(err)
|
||||
} else {
|
||||
globalRef, err := self.GetGlobalReference(name)
|
||||
if err != nil {
|
||||
// Errors are not expected here since Parse is a more lenient parser than ParseRequestURI.
|
||||
return types.NewErr("failed to get global reference: %v", err)
|
||||
}
|
||||
return c.NativeToValue(globalRef)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *impl) get_imagedata_string(ctx ref.Val, image ref.Val) ref.Val {
|
||||
if self, err := utils.ConvertToNative[Context](ctx); err != nil {
|
||||
return types.WrapErr(err)
|
||||
} else if image, err := utils.ConvertToNative[string](image); err != nil {
|
||||
return types.WrapErr(err)
|
||||
} else {
|
||||
globalRef, err := self.GetImageData(image)
|
||||
if err != nil {
|
||||
// Errors are not expected here since Parse is a more lenient parser than ParseRequestURI.
|
||||
return types.NewErr("failed to get image data: %v", err)
|
||||
}
|
||||
return c.NativeToValue(globalRef)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,13 +9,23 @@ import (
|
|||
)
|
||||
|
||||
type ctx struct {
|
||||
GetConfigMapFunc func(string, string) (unstructured.Unstructured, error)
|
||||
GetConfigMapFunc func(string, string) (unstructured.Unstructured, error)
|
||||
GetGlobalReferenceFunc func(string) (any, error)
|
||||
GetImageDataFunc func(string) (any, error)
|
||||
}
|
||||
|
||||
func (mock *ctx) GetConfigMap(ns string, n string) (unstructured.Unstructured, error) {
|
||||
return mock.GetConfigMapFunc(ns, n)
|
||||
}
|
||||
|
||||
func (mock *ctx) GetGlobalReference(n string) (any, error) {
|
||||
return mock.GetGlobalReferenceFunc(n)
|
||||
}
|
||||
|
||||
func (mock *ctx) GetImageData(n string) (any, error) {
|
||||
return mock.GetImageDataFunc(n)
|
||||
}
|
||||
|
||||
func Test_impl_get_configmap_string_string(t *testing.T) {
|
||||
opts := Lib()
|
||||
base, err := cel.NewEnv(opts)
|
||||
|
@ -47,3 +57,73 @@ func Test_impl_get_configmap_string_string(t *testing.T) {
|
|||
assert.NotNil(t, out)
|
||||
assert.True(t, called)
|
||||
}
|
||||
|
||||
func Test_impl_get_globalreference_string(t *testing.T) {
|
||||
opts := Lib()
|
||||
base, err := cel.NewEnv(opts)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, base)
|
||||
options := []cel.EnvOption{
|
||||
cel.Variable("context", ContextType),
|
||||
}
|
||||
env, err := base.Extend(options...)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, env)
|
||||
ast, issues := env.Compile(`context.GetGlobalReference("foo")`)
|
||||
assert.Nil(t, issues)
|
||||
assert.NotNil(t, ast)
|
||||
prog, err := env.Program(ast)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, prog)
|
||||
called := false
|
||||
data := map[string]any{
|
||||
"context": Context{&ctx{
|
||||
GetGlobalReferenceFunc: func(string) (any, error) {
|
||||
type foo struct {
|
||||
s string
|
||||
}
|
||||
called = true
|
||||
return foo{"bar"}, nil
|
||||
},
|
||||
}},
|
||||
}
|
||||
out, _, err := prog.Eval(data)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, out)
|
||||
assert.True(t, called)
|
||||
}
|
||||
|
||||
func Test_impl_get_imagedata_string(t *testing.T) {
|
||||
opts := Lib()
|
||||
base, err := cel.NewEnv(opts)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, base)
|
||||
options := []cel.EnvOption{
|
||||
cel.Variable("context", ContextType),
|
||||
}
|
||||
env, err := base.Extend(options...)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, env)
|
||||
ast, issues := env.Compile(`context.GetGlobalReference("foo")`)
|
||||
assert.Nil(t, issues)
|
||||
assert.NotNil(t, ast)
|
||||
prog, err := env.Program(ast)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, prog)
|
||||
called := false
|
||||
data := map[string]any{
|
||||
"context": Context{&ctx{
|
||||
GetGlobalReferenceFunc: func(string) (any, error) {
|
||||
type foo struct {
|
||||
s string
|
||||
}
|
||||
called = true
|
||||
return foo{"bar"}, nil
|
||||
},
|
||||
}},
|
||||
}
|
||||
out, _, err := prog.Eval(data)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, out)
|
||||
assert.True(t, called)
|
||||
}
|
||||
|
|
|
@ -43,6 +43,14 @@ func (c *lib) extendEnv(env *cel.Env) (*cel.Env, error) {
|
|||
// TODO: should not use DynType in return
|
||||
cel.MemberOverload("get_configmap_string_string", []*cel.Type{ContextType, types.StringType, types.StringType}, types.DynType, cel.FunctionBinding(impl.get_configmap_string_string)),
|
||||
},
|
||||
"GetGlobalReference": {
|
||||
// TODO: should not use DynType in return
|
||||
cel.MemberOverload("get_globalreference_string", []*cel.Type{ContextType, types.StringType}, types.DynType, cel.BinaryBinding(impl.get_globalreference_string)),
|
||||
},
|
||||
"GetImageData": {
|
||||
// TODO: should not use DynType in return
|
||||
cel.MemberOverload("get_imagedata_string", []*cel.Type{ContextType, types.StringType}, types.DynType, cel.BinaryBinding(impl.get_imagedata_string)),
|
||||
},
|
||||
}
|
||||
// create env options corresponding to our function overloads
|
||||
options := []cel.EnvOption{}
|
||||
|
|
|
@ -9,6 +9,8 @@ var ContextType = types.NewOpaqueType("context.Context")
|
|||
|
||||
type ContextInterface interface {
|
||||
GetConfigMap(string, string) (unstructured.Unstructured, error)
|
||||
GetGlobalReference(string) (any, error)
|
||||
GetImageData(string) (any, error)
|
||||
}
|
||||
|
||||
type Context struct {
|
||||
|
|
Loading…
Add table
Reference in a new issue