Skip to content

Commit

Permalink
fix
Browse files Browse the repository at this point in the history
Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
  • Loading branch information
eddycharly committed Sep 20, 2024
1 parent 20d691f commit b70bf41
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 70 deletions.
18 changes: 18 additions & 0 deletions pkg/core/templating/cel/cel.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package cel

import (
"github.com/google/cel-go/cel"
"github.com/jmespath-community/go-jmespath/pkg/binding"
)

func Execute(program cel.Program, value any, bindings binding.Bindings) (any, error) {
data := map[string]interface{}{
"object": value,
"bindings": NewVal(bindings, BindingsType),
}
out, _, err := program.Eval(data)
if err != nil {
return nil, err
}

Check warning on line 16 in pkg/core/templating/cel/cel.go

View check run for this annotation

Codecov / codecov/patch

pkg/core/templating/cel/cel.go#L15-L16

Added lines #L15 - L16 were not covered by tests
return out.Value(), nil
}
41 changes: 41 additions & 0 deletions pkg/core/templating/cel/env.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package cel

import (
"sync"

"github.com/google/cel-go/cel"
"github.com/google/cel-go/common/types"
"github.com/google/cel-go/common/types/ref"
"github.com/jmespath-community/go-jmespath/pkg/binding"
)

var (
BindingsType = cel.OpaqueType("bindings")
DefaultEnv = sync.OnceValues(func() (*cel.Env, error) {
return cel.NewEnv(
cel.Variable("object", cel.DynType),
cel.Variable("bindings", BindingsType),
cel.Function("resolve",
cel.MemberOverload("bindings_resolve_string",
[]*cel.Type{BindingsType, cel.StringType},
cel.AnyType,
cel.BinaryBinding(func(lhs, rhs ref.Val) ref.Val {
bindings, ok := lhs.(Val[binding.Bindings])
if !ok {
return types.ValOrErr(bindings, "invalid bindings type")
}

Check warning on line 26 in pkg/core/templating/cel/env.go

View check run for this annotation

Codecov / codecov/patch

pkg/core/templating/cel/env.go#L25-L26

Added lines #L25 - L26 were not covered by tests
name, ok := rhs.(types.String)
if !ok {
return types.ValOrErr(name, "invalid name type")
}

Check warning on line 30 in pkg/core/templating/cel/env.go

View check run for this annotation

Codecov / codecov/patch

pkg/core/templating/cel/env.go#L29-L30

Added lines #L29 - L30 were not covered by tests
value, err := binding.Resolve("$"+string(name), bindings.Unwrap())
if err != nil {
return types.WrapErr(err)
}

Check warning on line 34 in pkg/core/templating/cel/env.go

View check run for this annotation

Codecov / codecov/patch

pkg/core/templating/cel/env.go#L33-L34

Added lines #L33 - L34 were not covered by tests
return types.DefaultTypeAdapter.NativeToValue(value)
}),
),
),
)
})
)
48 changes: 48 additions & 0 deletions pkg/core/templating/cel/val.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package cel

import (
"reflect"

"github.com/google/cel-go/common/types"
"github.com/google/cel-go/common/types/ref"
)

type Val[T comparable] struct {
inner T
celType ref.Type
}

func NewVal[T comparable](value T, celType ref.Type) Val[T] {
return Val[T]{
inner: value,
celType: celType,
}
}

func (w Val[T]) Unwrap() T {
return w.inner
}

func (w Val[T]) Value() interface{} {
return w.Unwrap()

Check warning on line 27 in pkg/core/templating/cel/val.go

View check run for this annotation

Codecov / codecov/patch

pkg/core/templating/cel/val.go#L26-L27

Added lines #L26 - L27 were not covered by tests
}

func (w Val[T]) ConvertToNative(typeDesc reflect.Type) (interface{}, error) {
panic("not required")

Check warning on line 31 in pkg/core/templating/cel/val.go

View check run for this annotation

Codecov / codecov/patch

pkg/core/templating/cel/val.go#L30-L31

Added lines #L30 - L31 were not covered by tests
}

func (w Val[T]) ConvertToType(typeVal ref.Type) ref.Val {
panic("not required")

Check warning on line 35 in pkg/core/templating/cel/val.go

View check run for this annotation

Codecov / codecov/patch

pkg/core/templating/cel/val.go#L34-L35

Added lines #L34 - L35 were not covered by tests
}

func (w Val[T]) Equal(other ref.Val) ref.Val {
o, ok := other.Value().(Val[T])
if !ok {
return types.ValOrErr(other, "no such overload")
}
return types.Bool(o == w)

Check warning on line 43 in pkg/core/templating/cel/val.go

View check run for this annotation

Codecov / codecov/patch

pkg/core/templating/cel/val.go#L38-L43

Added lines #L38 - L43 were not covered by tests
}

func (w Val[T]) Type() ref.Type {
return w.celType
}
72 changes: 4 additions & 68 deletions pkg/core/templating/compiler.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@
package templating

import (
"reflect"
"sync"

"github.com/google/cel-go/cel"
"github.com/google/cel-go/common/types"
"github.com/google/cel-go/common/types/ref"
"github.com/jmespath-community/go-jmespath/pkg/binding"
"github.com/jmespath-community/go-jmespath/pkg/interpreter"
"github.com/jmespath-community/go-jmespath/pkg/parsing"
"github.com/kyverno/kyverno-json/pkg/core/expression"
"github.com/kyverno/kyverno-json/pkg/core/templating/cel"
"github.com/kyverno/kyverno-json/pkg/core/templating/jp"
"k8s.io/apimachinery/pkg/util/validation/field"
)
Expand Down Expand Up @@ -40,80 +35,21 @@ func (c Compiler) Options() CompilerOptions {
return c.options
}

var bindingsType = cel.OpaqueType("bindings")

type b struct {
binding.Bindings
}

func (b b) Value() interface{} {
return b
}
func (b b) ConvertToNative(typeDesc reflect.Type) (interface{}, error) {
panic("not required")
}

func (b b) ConvertToType(typeVal ref.Type) ref.Val {
panic("not required")
}
func (x b) Equal(other ref.Val) ref.Val {
o, ok := other.Value().(b)
if !ok {
return types.ValOrErr(other, "no such overload xxx")
}
return types.Bool(o == x)
}

func (b b) Type() ref.Type {
return bindingsType
}

var newEnv = sync.OnceValues(func() (*cel.Env, error) {
return cel.NewEnv(
cel.Variable("object", cel.DynType),
cel.Variable("bindings", bindingsType),
cel.Function("resolve",
cel.MemberOverload("bindings_resolve_string",
[]*cel.Type{bindingsType, cel.StringType},
cel.AnyType,
cel.BinaryBinding(func(lhs, rhs ref.Val) ref.Val {
bindings := lhs.(b)
name := rhs.(types.String)
value, err := binding.Resolve("$"+string(name), bindings)
if err != nil {
return types.WrapErr(err)
}
return types.DefaultTypeAdapter.NativeToValue(value)
}),
),
),
)
})

func (c Compiler) CompileCEL(statement string) (Program, error) {
env, err := newEnv()
env, err := cel.DefaultEnv()
if err != nil {
return nil, err
}

Check warning on line 42 in pkg/core/templating/compiler.go

View check run for this annotation

Codecov / codecov/patch

pkg/core/templating/compiler.go#L41-L42

Added lines #L41 - L42 were not covered by tests
ast, iss := env.Compile(statement)
if iss.Err() != nil {
return nil, iss.Err()
}

Check warning on line 46 in pkg/core/templating/compiler.go

View check run for this annotation

Codecov / codecov/patch

pkg/core/templating/compiler.go#L45-L46

Added lines #L45 - L46 were not covered by tests
prg, err := env.Program(ast)
program, err := env.Program(ast)
if err != nil {
return nil, err
}

Check warning on line 50 in pkg/core/templating/compiler.go

View check run for this annotation

Codecov / codecov/patch

pkg/core/templating/compiler.go#L49-L50

Added lines #L49 - L50 were not covered by tests
return func(value any, bindings binding.Bindings) (any, error) {
out, _, err := prg.Eval(
map[string]interface{}{
"object": value,
"bindings": b{bindings},
},
)
if err != nil {
return nil, err
}
return out.Value(), nil
return cel.Execute(program, value, bindings)
}, nil
}

Expand Down
3 changes: 1 addition & 2 deletions pkg/policy/load_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"testing"

"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"github.com/kyverno/kyverno-json/pkg/apis/policy/v1alpha1"
"github.com/stretchr/testify/assert"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -124,7 +123,7 @@ func TestLoad(t *testing.T) {
} else {
assert.NoError(t, err)
}
assert.True(t, cmp.Equal(tt.want, got, cmp.AllowUnexported(v1alpha1.AssertionTree{}), cmpopts.IgnoreFields(v1alpha1.AssertionTree{}, "_assertion")))
assert.True(t, cmp.Equal(tt.want, got, cmp.AllowUnexported(v1alpha1.AssertionTree{})))
})
}
}

0 comments on commit b70bf41

Please sign in to comment.