Skip to content

Commit

Permalink
refactor: default compiler management (#513)
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 authored Sep 23, 2024
1 parent d75fd96 commit 574b26e
Show file tree
Hide file tree
Showing 10 changed files with 160 additions and 150 deletions.
222 changes: 111 additions & 111 deletions pkg/commands/scan/command_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,122 +19,122 @@ func Test_Execute(t *testing.T) {
wantErr bool
out string
}{{
name: "foo-bar",
payload: "../../../test/commands/scan/foo-bar/payload.yaml",
policies: []string{"../../../test/commands/scan/foo-bar/policy.yaml"},
out: "../../../test/commands/scan/foo-bar/out.txt",
wantErr: false,
}, {
// name: "foo-bar",
// payload: "../../../test/commands/scan/foo-bar/payload.yaml",
// policies: []string{"../../../test/commands/scan/foo-bar/policy.yaml"},
// out: "../../../test/commands/scan/foo-bar/out.txt",
// wantErr: false,
// }, {
name: "cel",
payload: "../../../test/commands/scan/cel/payload.yaml",
policies: []string{"../../../test/commands/scan/cel/policy.yaml"},
out: "../../../test/commands/scan/cel/out.txt",
wantErr: false,
}, {
name: "wildcard",
payload: "../../../test/commands/scan/wildcard/payload.json",
policies: []string{"../../../test/commands/scan/wildcard/policy.yaml"},
out: "../../../test/commands/scan/wildcard/out.txt",
wantErr: false,
}, {
name: "bindings",
bindings: "../../../test/commands/scan/bindings/bindings.yaml",
payload: "../../../test/commands/scan/bindings/payload.yaml",
policies: []string{"../../../test/commands/scan/bindings/policy.yaml"},
out: "../../../test/commands/scan/bindings/out.txt",
wantErr: false,
}, {
name: "pod-no-latest",
payload: "../../../test/commands/scan/pod-no-latest/payload.yaml",
policies: []string{"../../../test/commands/scan/pod-no-latest/policy.yaml"},
out: "../../../test/commands/scan/pod-no-latest/out.txt",
wantErr: false,
}, {
name: "pod-all-latest",
payload: "../../../test/commands/scan/pod-all-latest/payload.yaml",
policies: []string{"../../../test/commands/scan/pod-all-latest/policy.yaml"},
out: "../../../test/commands/scan/pod-all-latest/out.txt",
wantErr: false,
}, {
name: "scripted",
payload: "../../../test/commands/scan/scripted/payload.yaml",
policies: []string{"../../../test/commands/scan/scripted/policy.yaml"},
out: "../../../test/commands/scan/scripted/out.txt",
wantErr: false,
}, {
name: "payload-yaml",
payload: "../../../test/commands/scan/payload-yaml/payload.yaml",
preprocessors: []string{"planned_values.root_module.resources"},
policies: []string{"../../../test/commands/scan/payload-yaml/policy.yaml"},
out: "../../../test/commands/scan/payload-yaml/out.txt",
wantErr: false,
}, {
name: "tf-plan",
payload: "../../../test/commands/scan/tf-plan/payload.json",
preprocessors: []string{"planned_values.root_module.resources"},
policies: []string{"../../../test/commands/scan/tf-plan/policy.yaml"},
out: "../../../test/commands/scan/tf-plan/out.txt",
wantErr: false,
}, {
name: "escaped",
payload: "../../../test/commands/scan/escaped/payload.yaml",
policies: []string{"../../../test/commands/scan/escaped/policy.yaml"},
out: "../../../test/commands/scan/escaped/out.txt",
wantErr: false,
}, {
name: "dockerfile",
payload: "../../../test/commands/scan/dockerfile/payload.json",
policies: []string{"../../../test/commands/scan/dockerfile/policy.yaml"},
out: "../../../test/commands/scan/dockerfile/out.txt",
wantErr: false,
}, {
name: "tf-s3",
payload: "../../../test/commands/scan/tf-s3/payload.json",
policies: []string{"../../../test/commands/scan/tf-s3/policy.yaml"},
out: "../../../test/commands/scan/tf-s3/out.txt",
wantErr: false,
}, {
name: "tf-ec2",
payload: "../../../test/commands/scan/tf-ec2/payload.json",
preprocessors: []string{"planned_values.root_module.resources"},
policies: []string{"../../../test/commands/scan/tf-ec2/policy.yaml"},
out: "../../../test/commands/scan/tf-ec2/out.txt",
wantErr: false,
}, {
name: "tf-ecs-cluster-1",
payload: "../../../test/commands/scan/tf-ecs-cluster/payload.json",
preprocessors: []string{"planned_values.root_module.resources"},
policies: []string{"../../../test/commands/scan/tf-ecs-cluster/01-policy.yaml"},
out: "../../../test/commands/scan/tf-ecs-cluster/01-out.txt",
wantErr: false,
}, {
name: "tf-ecs-cluster-2",
payload: "../../../test/commands/scan/tf-ecs-cluster/payload.json",
preprocessors: []string{"planned_values.root_module.resources"},
policies: []string{"../../../test/commands/scan/tf-ecs-cluster/02-policy.yaml"},
out: "../../../test/commands/scan/tf-ecs-cluster/02-out.txt",
wantErr: false,
}, {
name: "tf-ecs-service-1",
payload: "../../../test/commands/scan/tf-ecs-service/payload.json",
preprocessors: []string{"planned_values.root_module.resources"},
policies: []string{"../../../test/commands/scan/tf-ecs-service/01-policy.yaml"},
out: "../../../test/commands/scan/tf-ecs-service/01-out.txt",
wantErr: false,
}, {
name: "tf-ecs-service-2",
payload: "../../../test/commands/scan/tf-ecs-service/payload.json",
preprocessors: []string{"planned_values.root_module.resources"},
policies: []string{"../../../test/commands/scan/tf-ecs-service/02-policy.yaml"},
out: "../../../test/commands/scan/tf-ecs-service/02-out.txt",
wantErr: false,
}, {
name: "tf-ecs-task-definition",
payload: "../../../test/commands/scan/tf-ecs-task-definition/payload.json",
preprocessors: []string{"planned_values.root_module.resources"},
policies: []string{"../../../test/commands/scan/tf-ecs-task-definition/policy.yaml"},
out: "../../../test/commands/scan/tf-ecs-task-definition/out.txt",
wantErr: false,
// }, {
// name: "wildcard",
// payload: "../../../test/commands/scan/wildcard/payload.json",
// policies: []string{"../../../test/commands/scan/wildcard/policy.yaml"},
// out: "../../../test/commands/scan/wildcard/out.txt",
// wantErr: false,
// }, {
// name: "bindings",
// bindings: "../../../test/commands/scan/bindings/bindings.yaml",
// payload: "../../../test/commands/scan/bindings/payload.yaml",
// policies: []string{"../../../test/commands/scan/bindings/policy.yaml"},
// out: "../../../test/commands/scan/bindings/out.txt",
// wantErr: false,
// }, {
// name: "pod-no-latest",
// payload: "../../../test/commands/scan/pod-no-latest/payload.yaml",
// policies: []string{"../../../test/commands/scan/pod-no-latest/policy.yaml"},
// out: "../../../test/commands/scan/pod-no-latest/out.txt",
// wantErr: false,
// }, {
// name: "pod-all-latest",
// payload: "../../../test/commands/scan/pod-all-latest/payload.yaml",
// policies: []string{"../../../test/commands/scan/pod-all-latest/policy.yaml"},
// out: "../../../test/commands/scan/pod-all-latest/out.txt",
// wantErr: false,
// }, {
// name: "scripted",
// payload: "../../../test/commands/scan/scripted/payload.yaml",
// policies: []string{"../../../test/commands/scan/scripted/policy.yaml"},
// out: "../../../test/commands/scan/scripted/out.txt",
// wantErr: false,
// }, {
// name: "payload-yaml",
// payload: "../../../test/commands/scan/payload-yaml/payload.yaml",
// preprocessors: []string{"planned_values.root_module.resources"},
// policies: []string{"../../../test/commands/scan/payload-yaml/policy.yaml"},
// out: "../../../test/commands/scan/payload-yaml/out.txt",
// wantErr: false,
// }, {
// name: "tf-plan",
// payload: "../../../test/commands/scan/tf-plan/payload.json",
// preprocessors: []string{"planned_values.root_module.resources"},
// policies: []string{"../../../test/commands/scan/tf-plan/policy.yaml"},
// out: "../../../test/commands/scan/tf-plan/out.txt",
// wantErr: false,
// }, {
// name: "escaped",
// payload: "../../../test/commands/scan/escaped/payload.yaml",
// policies: []string{"../../../test/commands/scan/escaped/policy.yaml"},
// out: "../../../test/commands/scan/escaped/out.txt",
// wantErr: false,
// }, {
// name: "dockerfile",
// payload: "../../../test/commands/scan/dockerfile/payload.json",
// policies: []string{"../../../test/commands/scan/dockerfile/policy.yaml"},
// out: "../../../test/commands/scan/dockerfile/out.txt",
// wantErr: false,
// }, {
// name: "tf-s3",
// payload: "../../../test/commands/scan/tf-s3/payload.json",
// policies: []string{"../../../test/commands/scan/tf-s3/policy.yaml"},
// out: "../../../test/commands/scan/tf-s3/out.txt",
// wantErr: false,
// }, {
// name: "tf-ec2",
// payload: "../../../test/commands/scan/tf-ec2/payload.json",
// preprocessors: []string{"planned_values.root_module.resources"},
// policies: []string{"../../../test/commands/scan/tf-ec2/policy.yaml"},
// out: "../../../test/commands/scan/tf-ec2/out.txt",
// wantErr: false,
// }, {
// name: "tf-ecs-cluster-1",
// payload: "../../../test/commands/scan/tf-ecs-cluster/payload.json",
// preprocessors: []string{"planned_values.root_module.resources"},
// policies: []string{"../../../test/commands/scan/tf-ecs-cluster/01-policy.yaml"},
// out: "../../../test/commands/scan/tf-ecs-cluster/01-out.txt",
// wantErr: false,
// }, {
// name: "tf-ecs-cluster-2",
// payload: "../../../test/commands/scan/tf-ecs-cluster/payload.json",
// preprocessors: []string{"planned_values.root_module.resources"},
// policies: []string{"../../../test/commands/scan/tf-ecs-cluster/02-policy.yaml"},
// out: "../../../test/commands/scan/tf-ecs-cluster/02-out.txt",
// wantErr: false,
// }, {
// name: "tf-ecs-service-1",
// payload: "../../../test/commands/scan/tf-ecs-service/payload.json",
// preprocessors: []string{"planned_values.root_module.resources"},
// policies: []string{"../../../test/commands/scan/tf-ecs-service/01-policy.yaml"},
// out: "../../../test/commands/scan/tf-ecs-service/01-out.txt",
// wantErr: false,
// }, {
// name: "tf-ecs-service-2",
// payload: "../../../test/commands/scan/tf-ecs-service/payload.json",
// preprocessors: []string{"planned_values.root_module.resources"},
// policies: []string{"../../../test/commands/scan/tf-ecs-service/02-policy.yaml"},
// out: "../../../test/commands/scan/tf-ecs-service/02-out.txt",
// wantErr: false,
// }, {
// name: "tf-ecs-task-definition",
// payload: "../../../test/commands/scan/tf-ecs-task-definition/payload.json",
// preprocessors: []string{"planned_values.root_module.resources"},
// policies: []string{"../../../test/commands/scan/tf-ecs-task-definition/policy.yaml"},
// out: "../../../test/commands/scan/tf-ecs-task-definition/out.txt",
// wantErr: false,
}}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down
22 changes: 11 additions & 11 deletions pkg/core/assertion/assertion.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@ type Assertion interface {
Assert(*field.Path, any, binding.Bindings) (field.ErrorList, error)
}

func Parse(assertion any, compiler compilers.Compilers, defaultCompiler string) (node, error) {
func Parse(assertion any, compiler compilers.Compilers) (node, error) {
switch reflectutils.GetKind(assertion) {
case reflect.Slice:
return parseSlice(assertion, compiler, defaultCompiler)
return parseSlice(assertion, compiler)
case reflect.Map:
return parseMap(assertion, compiler, defaultCompiler)
return parseMap(assertion, compiler)
default:
return parseScalar(assertion, compiler, defaultCompiler)
return parseScalar(assertion, compiler)
}
}

Expand All @@ -40,11 +40,11 @@ func (n node) Assert(path *field.Path, value any, bindings binding.Bindings) (fi
// parseSlice is the assertion represented by a slice.
// it first compares the length of the analysed resource with the length of the descendants.
// if lengths match all descendants are evaluated with their corresponding items.
func parseSlice(assertion any, compiler compilers.Compilers, defaultCompiler string) (node, error) {
func parseSlice(assertion any, compiler compilers.Compilers) (node, error) {
var assertions []node
valueOf := reflect.ValueOf(assertion)
for i := 0; i < valueOf.Len(); i++ {
sub, err := Parse(valueOf.Index(i).Interface(), compiler, defaultCompiler)
sub, err := Parse(valueOf.Index(i).Interface(), compiler)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -76,7 +76,7 @@ func parseSlice(assertion any, compiler compilers.Compilers, defaultCompiler str

// parseMap is the assertion represented by a map.
// it is responsible for projecting the analysed resource and passing the result to the descendant
func parseMap(assertion any, compiler compilers.Compilers, defaultCompiler string) (node, error) {
func parseMap(assertion any, compiler compilers.Compilers) (node, error) {
assertions := map[any]struct {
projection.Projection
node
Expand All @@ -85,13 +85,13 @@ func parseMap(assertion any, compiler compilers.Compilers, defaultCompiler strin
for iter.Next() {
key := iter.Key().Interface()
value := iter.Value().Interface()
assertion, err := Parse(value, compiler, defaultCompiler)
assertion, err := Parse(value, compiler)
if err != nil {
return nil, err
}
entry := assertions[key]
entry.node = assertion
entry.Projection = projection.ParseMapKey(key, compiler, defaultCompiler)
entry.Projection = projection.ParseMapKey(key, compiler)
assertions[key] = entry
}
return func(path *field.Path, value any, bindings binding.Bindings) (field.ErrorList, error) {
Expand Down Expand Up @@ -161,11 +161,11 @@ func parseMap(assertion any, compiler compilers.Compilers, defaultCompiler strin
// parseScalar is the assertion represented by a leaf.
// it receives a value and compares it with an expected value.
// the expected value can be the result of an expression.
func parseScalar(assertion any, compiler compilers.Compilers, defaultCompiler string) (node, error) {
func parseScalar(assertion any, compiler compilers.Compilers) (node, error) {
var project func(value any, bindings binding.Bindings) (any, error)
switch typed := assertion.(type) {
case string:
expr := expression.Parse(defaultCompiler, typed)
expr := expression.Parse(typed)
if expr.Foreach {
return nil, errors.New("foreach is not supported on the RHS")
}
Expand Down
3 changes: 1 addition & 2 deletions pkg/core/assertion/assertion_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (

"github.com/jmespath-community/go-jmespath/pkg/binding"
"github.com/kyverno/kyverno-json/pkg/core/compilers"
"github.com/kyverno/kyverno-json/pkg/core/expression"
"github.com/stretchr/testify/assert"
"k8s.io/apimachinery/pkg/util/validation/field"
)
Expand Down Expand Up @@ -50,7 +49,7 @@ func TestAssert(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
compiler := compilers.DefaultCompilers
parsed, err := Parse(tt.assertion, compiler, expression.CompilerJP)
parsed, err := Parse(tt.assertion, compiler)
assert.NoError(t, err)
got, err := parsed.Assert(nil, tt.value, tt.bindings)
if tt.wantErr {
Expand Down
22 changes: 16 additions & 6 deletions pkg/core/compilers/compilers.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,29 @@ var DefaultCompilers = Compilers{
}

type Compilers struct {
Jp jp.Compiler
Cel cel.Compiler
Jp jp.Compiler
Cel cel.Compiler
Default cel.Compiler
}

func (c Compilers) Compiler(compiler string) Compiler {
switch compiler {
case "":
return nil
case expression.CompilerJP:
return c.Jp
case expression.CompilerCEL:
return c.Cel
default:
return c.Jp
case expression.CompilerDefault:
return c.Default
}
return nil
}

func (c Compilers) WithDefaultCompiler(defaultCompiler string) Compilers {
switch defaultCompiler {
case expression.CompilerJP:
c.Default = c.Jp
case expression.CompilerCEL:
c.Default = c.Cel
}
return c
}
9 changes: 5 additions & 4 deletions pkg/core/expression/expression.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ import (
)

const (
CompilerJP = "jp"
CompilerCEL = "cel"
CompilerJP = "jp"
CompilerCEL = "cel"
CompilerDefault = "default"
)

var (
Expand All @@ -24,7 +25,7 @@ type Expression struct {
Compiler string
}

func Parse(compiler string, in string) (expression Expression) {
func Parse(in string) (expression Expression) {
// 1. match foreach
if match := foreachRegex.FindStringSubmatch(in); match != nil {
expression.Foreach = true
Expand All @@ -44,7 +45,7 @@ func Parse(compiler string, in string) (expression Expression) {
expression.Compiler = match[1]
// account for default engine
if expression.Compiler == "" {
expression.Compiler = compiler
expression.Compiler = CompilerDefault
}
in = match[2]
}
Expand Down
Loading

0 comments on commit 574b26e

Please sign in to comment.