From 9e6f30b640724f657ff17605493bb81dfdcabe37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charles-Edouard=20Br=C3=A9t=C3=A9ch=C3=A9?= Date: Tue, 9 Jan 2024 15:07:12 +0100 Subject: [PATCH] fix: remove deps from engine to api (#272) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: remove deps from engine to api Signed-off-by: Charles-Edouard Brétéché * binding Signed-off-by: Charles-Edouard Brétéché --------- Signed-off-by: Charles-Edouard Brétéché --- pkg/binding/binding.go | 17 +++++++++++++++++ pkg/engine/assert/assert.go | 6 +----- pkg/engine/assert/binding.go | 20 +++++--------------- pkg/json-engine/engine.go | 11 ++++++----- pkg/{engine/assert => matching}/match.go | 15 ++++++--------- 5 files changed, 35 insertions(+), 34 deletions(-) create mode 100644 pkg/binding/binding.go rename pkg/{engine/assert => matching}/match.go (82%) diff --git a/pkg/binding/binding.go b/pkg/binding/binding.go new file mode 100644 index 00000000..5d638f7e --- /dev/null +++ b/pkg/binding/binding.go @@ -0,0 +1,17 @@ +package binding + +import ( + "github.com/jmespath-community/go-jmespath/pkg/binding" + "github.com/kyverno/kyverno-json/pkg/apis/v1alpha1" + "github.com/kyverno/kyverno-json/pkg/engine/assert" + "k8s.io/apimachinery/pkg/util/validation/field" +) + +func NewContextBindings(bindings binding.Bindings, value any, entries ...v1alpha1.ContextEntry) binding.Bindings { + var path *field.Path + path = path.Child("context") + for i, entry := range entries { + bindings = bindings.Register("$"+entry.Name, assert.NewContextBinding(path.Index(i), bindings, value, entry.Variable.Value)) + } + return bindings +} diff --git a/pkg/engine/assert/assert.go b/pkg/engine/assert/assert.go index fa066ea0..db930b19 100644 --- a/pkg/engine/assert/assert.go +++ b/pkg/engine/assert/assert.go @@ -8,10 +8,6 @@ import ( "k8s.io/apimachinery/pkg/util/validation/field" ) -func Assert(ctx context.Context, assertion Assertion, value any, bindings binding.Bindings, opts ...template.Option) (field.ErrorList, error) { - return assert(ctx, nil, assertion, value, bindings, opts...) -} - -func assert(ctx context.Context, path *field.Path, assertion Assertion, value any, bindings binding.Bindings, opts ...template.Option) (field.ErrorList, error) { +func Assert(ctx context.Context, path *field.Path, assertion Assertion, value any, bindings binding.Bindings, opts ...template.Option) (field.ErrorList, error) { return assertion.assert(ctx, path, value, bindings, opts...) } diff --git a/pkg/engine/assert/binding.go b/pkg/engine/assert/binding.go index 35bfd50f..fef9570c 100644 --- a/pkg/engine/assert/binding.go +++ b/pkg/engine/assert/binding.go @@ -4,30 +4,20 @@ import ( "context" "github.com/jmespath-community/go-jmespath/pkg/binding" - "github.com/kyverno/kyverno-json/pkg/apis/v1alpha1" "github.com/kyverno/kyverno-json/pkg/engine/template" "k8s.io/apimachinery/pkg/util/validation/field" ) -func NewContextBindings(bindings binding.Bindings, value any, entries ...v1alpha1.ContextEntry) binding.Bindings { - var path *field.Path - path = path.Child("context") - for i, entry := range entries { - bindings = bindings.Register("$"+entry.Name, NewContextBinding(path.Index(i), bindings, value, entry)) - } - return bindings -} - -func NewContextBinding(path *field.Path, bindings binding.Bindings, value any, entry v1alpha1.ContextEntry) binding.Binding { +func NewContextBinding(path *field.Path, bindings binding.Bindings, value any, entry any) binding.Binding { return template.NewLazyBinding( func() (any, error) { - expression := parseExpression(context.TODO(), entry.Variable.Value) + expression := parseExpression(context.TODO(), entry) if expression != nil && expression.engine != "" { if expression.foreach { - return nil, field.Invalid(path.Child("variable"), entry.Variable.Value, "foreach is not supported in context") + return nil, field.Invalid(path.Child("variable"), entry, "foreach is not supported in context") } if expression.binding != "" { - return nil, field.Invalid(path.Child("variable"), entry.Variable.Value, "binding is not supported in context") + return nil, field.Invalid(path.Child("variable"), entry, "binding is not supported in context") } projected, err := template.Execute(context.Background(), expression.statement, value, bindings) if err != nil { @@ -35,7 +25,7 @@ func NewContextBinding(path *field.Path, bindings binding.Bindings, value any, e } return projected, nil } - return entry.Variable.Value, nil + return entry, nil }, ) } diff --git a/pkg/json-engine/engine.go b/pkg/json-engine/engine.go index 9600f67a..f0bd0419 100644 --- a/pkg/json-engine/engine.go +++ b/pkg/json-engine/engine.go @@ -6,11 +6,12 @@ import ( jpbinding "github.com/jmespath-community/go-jmespath/pkg/binding" "github.com/kyverno/kyverno-json/pkg/apis/v1alpha1" + "github.com/kyverno/kyverno-json/pkg/binding" "github.com/kyverno/kyverno-json/pkg/engine" - "github.com/kyverno/kyverno-json/pkg/engine/assert" "github.com/kyverno/kyverno-json/pkg/engine/blocks/loop" "github.com/kyverno/kyverno-json/pkg/engine/builder" "github.com/kyverno/kyverno-json/pkg/engine/template" + "github.com/kyverno/kyverno-json/pkg/matching" "go.uber.org/multierr" ) @@ -59,7 +60,7 @@ func New() engine.Engine[Request, RuleResponse] { bindings = bindings.Register("$policy", jpbinding.NewBinding(policy)) for _, rule := range policy.Spec.Rules { bindings = bindings.Register("$rule", jpbinding.NewBinding(rule)) - bindings = assert.NewContextBindings(bindings, resource, rule.Context...) + bindings = binding.NewContextBindings(bindings, resource, rule.Context...) requests = append(requests, request{ policy: policy, rule: rule, @@ -73,7 +74,7 @@ func New() engine.Engine[Request, RuleResponse] { } inner := builder. Function(func(ctx context.Context, r request) RuleResponse { - errs, err := assert.MatchAssert(ctx, nil, r.rule.Assert, r.value, r.bindings) + errs, err := matching.MatchAssert(ctx, nil, r.rule.Assert, r.value, r.bindings) response := buildResponse(r, errs, err) return response }). @@ -81,7 +82,7 @@ func New() engine.Engine[Request, RuleResponse] { if r.rule.Exclude == nil { return true } - errs, err := assert.Match(ctx, nil, r.rule.Exclude, r.value, r.bindings) + errs, err := matching.Match(ctx, nil, r.rule.Exclude, r.value, r.bindings) // TODO: handle error and skip return err == nil && len(errs) != 0 }). @@ -89,7 +90,7 @@ func New() engine.Engine[Request, RuleResponse] { if r.rule.Match == nil { return true } - errs, err := assert.Match(ctx, nil, r.rule.Match, r.value, r.bindings) + errs, err := matching.Match(ctx, nil, r.rule.Match, r.value, r.bindings) // TODO: handle error and skip return err == nil && len(errs) == 0 }) diff --git a/pkg/engine/assert/match.go b/pkg/matching/match.go similarity index 82% rename from pkg/engine/assert/match.go rename to pkg/matching/match.go index c018f342..19eb1306 100644 --- a/pkg/engine/assert/match.go +++ b/pkg/matching/match.go @@ -1,4 +1,4 @@ -package assert +package matching import ( "context" @@ -6,14 +6,11 @@ import ( "github.com/jmespath-community/go-jmespath/pkg/binding" "github.com/kyverno/kyverno-json/pkg/apis/v1alpha1" + "github.com/kyverno/kyverno-json/pkg/engine/assert" "github.com/kyverno/kyverno-json/pkg/engine/template" "k8s.io/apimachinery/pkg/util/validation/field" ) -// TODO: this is the only file we reference the apis package. -// We should remove this dependency. -// Either move the Match struct in this package or move this file in a more specific package. - func MatchAssert(ctx context.Context, path *field.Path, match *v1alpha1.Assert, actual any, bindings binding.Bindings, opts ...template.Option) ([]error, error) { if match == nil || (len(match.Any) == 0 && len(match.All) == 0) { return nil, field.Invalid(path, match, "an empty assert is not valid") @@ -22,7 +19,7 @@ func MatchAssert(ctx context.Context, path *field.Path, match *v1alpha1.Assert, var fails []error path := path.Child("any") for i, assertion := range match.Any { - checkFails, err := assert(ctx, path.Index(i).Child("check"), Parse(ctx, assertion.Check.Value), actual, bindings, opts...) + checkFails, err := assert.Assert(ctx, path.Index(i).Child("check"), assert.Parse(ctx, assertion.Check.Value), actual, bindings, opts...) if err != nil { return fails, err } @@ -46,7 +43,7 @@ func MatchAssert(ctx context.Context, path *field.Path, match *v1alpha1.Assert, var fails []error path := path.Child("all") for i, assertion := range match.All { - checkFails, err := assert(ctx, path.Index(i).Child("check"), Parse(ctx, assertion.Check.Value), actual, bindings, opts...) + checkFails, err := assert.Assert(ctx, path.Index(i).Child("check"), assert.Parse(ctx, assertion.Check.Value), actual, bindings, opts...) if err != nil { return fails, err } @@ -92,7 +89,7 @@ func Match(ctx context.Context, path *field.Path, match *v1alpha1.Match, actual func MatchAny(ctx context.Context, path *field.Path, assertions []v1alpha1.Any, actual any, bindings binding.Bindings, opts ...template.Option) (field.ErrorList, error) { var errs field.ErrorList for i, assertion := range assertions { - _errs, err := assert(ctx, path.Index(i), Parse(ctx, assertion.Value), actual, bindings, opts...) + _errs, err := assert.Assert(ctx, path.Index(i), assert.Parse(ctx, assertion.Value), actual, bindings, opts...) if err != nil { return errs, err } @@ -107,7 +104,7 @@ func MatchAny(ctx context.Context, path *field.Path, assertions []v1alpha1.Any, func MatchAll(ctx context.Context, path *field.Path, assertions []v1alpha1.Any, actual any, bindings binding.Bindings, opts ...template.Option) (field.ErrorList, error) { var errs field.ErrorList for i, assertion := range assertions { - _errs, err := assert(ctx, path.Index(i), Parse(ctx, assertion.Value), actual, bindings, opts...) + _errs, err := assert.Assert(ctx, path.Index(i), assert.Parse(ctx, assertion.Value), actual, bindings, opts...) if err != nil { return errs, err }