diff --git a/pkg/cel/libs/context/impl.go b/pkg/cel/libs/context/impl.go index 4a8be7990a..2ceab25d82 100644 --- a/pkg/cel/libs/context/impl.go +++ b/pkg/cel/libs/context/impl.go @@ -1,34 +1,28 @@ package context import ( - "context" - "github.com/google/cel-go/common/types" "github.com/google/cel-go/common/types/ref" "github.com/kyverno/kyverno/pkg/cel/utils" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/kubernetes" ) type impl struct { types.Adapter - client kubernetes.Interface } -func (c *impl) context_get_cm(arg ref.Val) ref.Val { - if ref, err := utils.ConvertToNative[ConfigMapReference](arg); err != nil { +func (c *impl) get_configmap_string_string(args ...ref.Val) ref.Val { + if self, err := utils.ConvertToNative[Context](args[0]); err != nil { + return types.WrapErr(err) + } else if namespace, err := utils.ConvertToNative[string](args[1]); err != nil { + return types.WrapErr(err) + } else if name, err := utils.ConvertToNative[string](args[2]); err != nil { return types.WrapErr(err) } else { - cm, err := c.client.CoreV1().ConfigMaps(ref.Namespace).Get(context.TODO(), ref.Name, metav1.GetOptions{}) + cm, err := self.GetConfigMap(namespace, name) if err != nil { // Errors are not expected here since Parse is a more lenient parser than ParseRequestURI. return types.NewErr("failed to get resource: %v", err) } - out, err := utils.ConvertObjectToUnstructured(cm) - if err != nil { - // Errors are not expected here since Parse is a more lenient parser than ParseRequestURI. - return types.NewErr("failed to convert to unstructured: %v", err) - } - return c.NativeToValue(out.UnstructuredContent()) + return c.NativeToValue(cm.UnstructuredContent()) } } diff --git a/pkg/cel/libs/context/lib.go b/pkg/cel/libs/context/lib.go index 51f386f372..30a1ae511b 100644 --- a/pkg/cel/libs/context/lib.go +++ b/pkg/cel/libs/context/lib.go @@ -1,36 +1,23 @@ package context import ( - "reflect" - "github.com/google/cel-go/cel" "github.com/google/cel-go/common/types" - "github.com/google/cel-go/ext" - "k8s.io/client-go/kubernetes" ) -// lib types -var ConfigMapReferenceType = types.NewObjectType("context.ConfigMapReference") +type lib struct{} -type lib struct { - client kubernetes.Interface +func Lib() cel.EnvOption { + // create the cel lib env option + return cel.Lib(&lib{}) } -func Lib(client kubernetes.Interface) cel.EnvOption { - // create the cel lib env option - return cel.Lib(&lib{ - client: client, - }) +func (*lib) LibraryName() string { + return "kyverno.context" } func (c *lib) CompileOptions() []cel.EnvOption { return []cel.EnvOption{ - ext.NativeTypes( - // TODO: needs cel lib bump - // ext.ParseStructTags(true), - reflect.TypeFor[ConfigMapReference](), - ), - // extend environment with function overloads c.extendEnv, } } @@ -43,13 +30,12 @@ func (c *lib) extendEnv(env *cel.Env) (*cel.Env, error) { // create implementation, recording the envoy types aware adapter impl := impl{ Adapter: env.CELTypeAdapter(), - client: c.client, } // build our function overloads libraryDecls := map[string][]cel.FunctionOpt{ - "context.configMap": { - // TODO: add more overloads... - cel.Overload("context_get_cm", []*cel.Type{ConfigMapReferenceType}, types.DynType, cel.UnaryBinding(impl.context_get_cm)), + "GetConfigMap": { + // 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)), }, } // create env options corresponding to our function overloads diff --git a/pkg/cel/libs/context/types.go b/pkg/cel/libs/context/types.go index c2ff41ff23..cdce14af9b 100644 --- a/pkg/cel/libs/context/types.go +++ b/pkg/cel/libs/context/types.go @@ -1,6 +1,12 @@ package context -type ConfigMapReference struct { - Name string `cel:"name"` - Namespace string `cel:"namespace"` +import ( + "github.com/google/cel-go/common/types" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" +) + +var ContextType = types.NewObjectType("context.Context") + +type Context interface { + GetConfigMap(string, string) (unstructured.Unstructured, error) }