mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-06 16:06:56 +00:00
feat: add context cel lib to get config map (#11898)
* feat: add context cel lib to get config map Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * function name Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * fix type 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
032d428b12
commit
bdc55fbc93
3 changed files with 26 additions and 40 deletions
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue