Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: make evaluation path live in payload world #522

Merged
merged 3 commits into from
Sep 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 20 additions & 5 deletions pkg/commands/scan/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,15 +105,30 @@
for _, response := range responses {
for _, policy := range response.Policies {
for _, rule := range policy.Rules {
status := "PASSED"
if rule.Error != nil {
out.println("-", policy.Policy.Name, "/", rule.Rule.Name, "/", rule.Identifier, "ERROR:", rule.Error.Error())
status = fmt.Sprintf("ERROR: %s", rule.Error.Error())

Check warning on line 110 in pkg/commands/scan/options.go

View check run for this annotation

Codecov / codecov/patch

pkg/commands/scan/options.go#L110

Added line #L110 was not covered by tests
} else if len(rule.Violations) != 0 {
out.println("-", policy.Policy.Name, "/", rule.Rule.Name, "/", rule.Identifier, "FAILED")
out.println(rule.Violations.Error())
status = "FAILED"
}
if rule.Identifier != "" {
out.println(fmt.Sprintf("- %s (POLICY=%s, RULE=%s, ID=%s)", status, policy.Policy.Name, rule.Rule.Name, rule.Identifier))
} else {
// TODO: handle skip, warn
out.println("-", policy.Policy.Name, "/", rule.Rule.Name, "/", rule.Identifier, "PASSED")
out.println(fmt.Sprintf("- %s (POLICY=%s, RULE=%s)", status, policy.Policy.Name, rule.Rule.Name))
}
if len(rule.Violations) != 0 {
out.println(rule.Violations.Error(" "))
}

// if rule.Error != nil {
// out.println("-", policy.Policy.Name, "/", rule.Rule.Name, "/", rule.Identifier, "ERROR:", rule.Error.Error())
// } else if len(rule.Violations) != 0 {
// out.println("-", policy.Policy.Name, "/", rule.Rule.Name, "/", rule.Identifier, "FAILED")
// out.println(rule.Violations.Error())
// } else {
// // TODO: handle skip, warn
// out.println("-", policy.Policy.Name, "/", rule.Rule.Name, "/", rule.Identifier, "PASSED")
// }
}
}
}
Expand Down
6 changes: 4 additions & 2 deletions pkg/json-engine/compiler.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,9 +194,11 @@ func (c *compiler) compileAssertion(
errs, err := check(resource, bindings)
if len(errs) != 0 {
result.ErrorList = errs
message := fmt.Sprintf("(CHECK=%s)", path.String())
if in.Message != nil {
result.Message = in.Message.Format(resource, bindings, compilers.Jp.Options()...)
message = fmt.Sprintf("%s %s", in.Message.Format(resource, bindings, compilers.Jp.Options()...), message)
}
result.Message = message
}
return result, err
}, nil
Expand Down Expand Up @@ -228,7 +230,7 @@ func (c *compiler) compileAssertionTree(
return nil, err
}
return func(resource any, bindings binding.Bindings) (field.ErrorList, error) {
return check.Assert(path, resource, bindings)
return check.Assert(nil, resource, bindings)
}, nil
}

Expand Down
11 changes: 6 additions & 5 deletions pkg/json-engine/model.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package jsonengine

import (
"fmt"
"strings"
"time"

Expand Down Expand Up @@ -39,24 +40,24 @@ type Result struct {
Message string
}

func (r Result) Error() string {
func (r Result) Error(prefix string) string {
var lines []string
if r.Message != "" {
lines = append(lines, "-> "+r.Message)
lines = append(lines, prefix+"-> "+r.Message)
}
for _, err := range r.ErrorList {
lines = append(lines, " -> "+err.Error())
lines = append(lines, prefix+fmt.Sprintf(" -> %s (PATH=%s)", err.ErrorBody(), err.Field))
}
return strings.Join(lines, "\n")
}

//nolint:errname
type Results []Result

func (r Results) Error() string {
func (r Results) Error(prefix string) string {
var lines []string
for _, err := range r {
lines = append(lines, err.Error())
lines = append(lines, err.Error(prefix))
}
return strings.Join(lines, "\n")
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/server/model/response.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
return rule.Error.Error()
}
if len(rule.Violations) != 0 {
return rule.Violations.Error()
return rule.Violations.Error("")

Check warning on line 53 in pkg/server/model/response.go

View check run for this annotation

Codecov / codecov/patch

pkg/server/model/response.go#L53

Added line #L53 was not covered by tests
}
return ""
}
2 changes: 1 addition & 1 deletion test/api/go/main/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
if rule.Error != nil {
logger.Printf("error: %s/%s -> %s: %s", policy.Policy.Name, rule.Rule.Name, rule.Identifier, rule.Error)
} else if len(rule.Violations) != 0 {
logger.Printf("fail: %s/%s -> %s\n%s", policy.Policy.Name, rule.Rule.Name, rule.Identifier, rule.Violations.Error())
logger.Printf("fail: %s/%s -> %s\n%s", policy.Policy.Name, rule.Rule.Name, rule.Identifier, rule.Violations.Error(""))

Check warning on line 72 in test/api/go/main/main.go

View check run for this annotation

Codecov / codecov/patch

test/api/go/main/main.go#L72

Added line #L72 was not covered by tests
} else {
logger.Printf("pass: %s/%s -> %s", policy.Policy.Name, rule.Rule.Name, rule.Identifier)
}
Expand Down
2 changes: 1 addition & 1 deletion test/commands/scan/bindings/out.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ Loading bindings ...
Loading payload ...
Pre processing ...
Running ( evaluating 1 resource against 1 policy ) ...
- test / foo-bar-4 / PASSED
- PASSED (POLICY=test, RULE=foo-bar-4)
Done
2 changes: 1 addition & 1 deletion test/commands/scan/cel/out.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ Loading policies ...
Loading payload ...
Pre processing ...
Running ( evaluating 1 resource against 1 policy ) ...
- test / foo-bar-4 / PASSED
- PASSED (POLICY=test, RULE=foo-bar-4)
Done
10 changes: 5 additions & 5 deletions test/commands/scan/dockerfile/out.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ Loading policies ...
Loading payload ...
Pre processing ...
Running ( evaluating 1 resource against 1 policy ) ...
- check-dockerfile / deny-external-calls / FAILED
-> HTTP calls are not allowed
-> spec.rules[0].assert.all[0].check.~.(Stages[].Commands[].Args[].Value)[0].(contains(@, 'https://') || contains(@, 'http://')): Invalid value: true: Expected value: false
-> wget is not allowed
-> spec.rules[0].assert.all[3].check.~.(Stages[].Commands[].CmdLine[])[0].(contains(@, 'wget')): Invalid value: true: Expected value: false
- FAILED (POLICY=check-dockerfile, RULE=deny-external-calls)
-> HTTP calls are not allowed (CHECK=spec.rules[0].assert.all[0])
-> Invalid value: true: Expected value: false (PATH=~.(Stages[].Commands[].Args[].Value)[0].(contains(@, 'https://') || contains(@, 'http://')))
-> wget is not allowed (CHECK=spec.rules[0].assert.all[3])
-> Invalid value: true: Expected value: false (PATH=~.(Stages[].Commands[].CmdLine[])[0].(contains(@, 'wget')))
Done
2 changes: 1 addition & 1 deletion test/commands/scan/escaped/out.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ Loading policies ...
Loading payload ...
Pre processing ...
Running ( evaluating 1 resource against 1 policy ) ...
- test / foo-bar-4 / PASSED
- PASSED (POLICY=test, RULE=foo-bar-4)
Done
2 changes: 1 addition & 1 deletion test/commands/scan/foo-bar/out.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ Loading policies ...
Loading payload ...
Pre processing ...
Running ( evaluating 1 resource against 1 policy ) ...
- test / foo-bar-4 / PASSED
- PASSED (POLICY=test, RULE=foo-bar-4)
Done
6 changes: 3 additions & 3 deletions test/commands/scan/payload-yaml/out.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Loading policies ...
Loading payload ...
Pre processing ...
Running ( evaluating 1 resource against 1 policy ) ...
- required-s3-tags / require-team-tag / aws_s3_bucket.example FAILED
-> Bucket `example` (aws_s3_bucket.example) does not have the required tags {"Team":"Kyverno"}
-> spec.rules[0].assert.all[0].check.values.tags: Invalid value: map[string]interface {}{"Environment":"Dev", "Name":"My bucket"}: Expected value: map[string]interface {}{"Team":"Kyverno"}
- FAILED (POLICY=required-s3-tags, RULE=require-team-tag, ID=aws_s3_bucket.example)
-> Bucket `example` (aws_s3_bucket.example) does not have the required tags {"Team":"Kyverno"} (CHECK=spec.rules[0].assert.all[0])
-> Invalid value: map[string]interface {}{"Environment":"Dev", "Name":"My bucket"}: Expected value: map[string]interface {}{"Team":"Kyverno"} (PATH=values.tags)
Done
2 changes: 1 addition & 1 deletion test/commands/scan/pod-all-latest/out.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ Loading policies ...
Loading payload ...
Pre processing ...
Running ( evaluating 1 resource against 1 policy ) ...
- test / pod-no-latest / webserver PASSED
- PASSED (POLICY=test, RULE=pod-no-latest, ID=webserver)
Done
23 changes: 13 additions & 10 deletions test/commands/scan/pod-no-latest/out.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@ Loading policies ...
Loading payload ...
Pre processing ...
Running ( evaluating 1 resource against 1 policy ) ...
- test / pod-no-latest / webserver FAILED
-> spec.rules[0].assert.all[0].check.spec.~foo.containers->foos[0].(at($foos, $foo).image)->foo.(ends_with($foo, $tag)): Invalid value: true: Expected value: false
-> spec.rules[0].assert.all[0].check.spec.~foo.containers->foos[1].(at($foos, $foo).image)->foo.(ends_with($foo, $tag)): Invalid value: true: Expected value: false
-> spec.rules[0].assert.all[0].check.spec.~foo.containers->foos[2].(at($foos, $foo).image)->foo.(ends_with($foo, $tag)): Invalid value: true: Expected value: false
-> spec.rules[0].assert.all[1].check.spec.~.containers->foo[0].image.(ends_with(@, ':latest')): Invalid value: true: Expected value: false
-> spec.rules[0].assert.all[1].check.spec.~.containers->foo[1].image.(ends_with(@, ':latest')): Invalid value: true: Expected value: false
-> spec.rules[0].assert.all[1].check.spec.~.containers->foo[2].image.(ends_with(@, ':latest')): Invalid value: true: Expected value: false
-> spec.rules[0].assert.all[2].check.~index.(spec.containers[*].image)->images[0].(ends_with(@, ':latest')): Invalid value: true: Expected value: false
-> spec.rules[0].assert.all[2].check.~index.(spec.containers[*].image)->images[1].(ends_with(@, ':latest')): Invalid value: true: Expected value: false
-> spec.rules[0].assert.all[2].check.~index.(spec.containers[*].image)->images[2].(ends_with(@, ':latest')): Invalid value: true: Expected value: false
- FAILED (POLICY=test, RULE=pod-no-latest, ID=webserver)
-> (CHECK=spec.rules[0].assert.all[0])
-> Invalid value: true: Expected value: false (PATH=spec.~foo.containers->foos[0].(at($foos, $foo).image)->foo.(ends_with($foo, $tag)))
-> Invalid value: true: Expected value: false (PATH=spec.~foo.containers->foos[1].(at($foos, $foo).image)->foo.(ends_with($foo, $tag)))
-> Invalid value: true: Expected value: false (PATH=spec.~foo.containers->foos[2].(at($foos, $foo).image)->foo.(ends_with($foo, $tag)))
-> (CHECK=spec.rules[0].assert.all[1])
-> Invalid value: true: Expected value: false (PATH=spec.~.containers->foo[0].image.(ends_with(@, ':latest')))
-> Invalid value: true: Expected value: false (PATH=spec.~.containers->foo[1].image.(ends_with(@, ':latest')))
-> Invalid value: true: Expected value: false (PATH=spec.~.containers->foo[2].image.(ends_with(@, ':latest')))
-> (CHECK=spec.rules[0].assert.all[2])
-> Invalid value: true: Expected value: false (PATH=~index.(spec.containers[*].image)->images[0].(ends_with(@, ':latest')))
-> Invalid value: true: Expected value: false (PATH=~index.(spec.containers[*].image)->images[1].(ends_with(@, ':latest')))
-> Invalid value: true: Expected value: false (PATH=~index.(spec.containers[*].image)->images[2].(ends_with(@, ':latest')))
Done
2 changes: 1 addition & 1 deletion test/commands/scan/scripted/out.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ Loading policies ...
Loading payload ...
Pre processing ...
Running ( evaluating 1 resource against 1 policy ) ...
- test / foo-bar-4 / PASSED
- PASSED (POLICY=test, RULE=foo-bar-4)
Done
2 changes: 1 addition & 1 deletion test/commands/scan/tf-ec2/out.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ Loading policies ...
Loading payload ...
Pre processing ...
Running ( evaluating 1 resource against 1 policy ) ...
- required-ec2-tags / require-team-tag / PASSED
- PASSED (POLICY=required-ec2-tags, RULE=require-team-tag)
Done
2 changes: 1 addition & 1 deletion test/commands/scan/tf-ecs-cluster/01-out.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ Loading policies ...
Loading payload ...
Pre processing ...
Running ( evaluating 3 resources against 1 policy ) ...
- required-container-insights / required-container-insights / PASSED
- PASSED (POLICY=required-container-insights, RULE=required-container-insights)
Done
2 changes: 1 addition & 1 deletion test/commands/scan/tf-ecs-cluster/02-out.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ Loading policies ...
Loading payload ...
Pre processing ...
Running ( evaluating 3 resources against 1 policy ) ...
- ecs-cluster-enable-logging / ecs-cluster-enable-logging / PASSED
- PASSED (POLICY=ecs-cluster-enable-logging, RULE=ecs-cluster-enable-logging)
Done
2 changes: 1 addition & 1 deletion test/commands/scan/tf-ecs-service/01-out.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ Loading policies ...
Loading payload ...
Pre processing ...
Running ( evaluating 1 resource against 1 policy ) ...
- required-latest-platform-fargate / required-latest-platform / PASSED
- PASSED (POLICY=required-latest-platform-fargate, RULE=required-latest-platform)
Done
2 changes: 1 addition & 1 deletion test/commands/scan/tf-ecs-service/02-out.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ Loading policies ...
Loading payload ...
Pre processing ...
Running ( evaluating 1 resource against 1 policy ) ...
- ecs-public-ip / ecs-public-ip / PASSED
- PASSED (POLICY=ecs-public-ip, RULE=ecs-public-ip)
Done
2 changes: 1 addition & 1 deletion test/commands/scan/tf-ecs-task-definition/out.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ Loading policies ...
Loading payload ...
Pre processing ...
Running ( evaluating 1 resource against 1 policy ) ...
- fs-read-only / require-fs-read-only / PASSED
- PASSED (POLICY=fs-read-only, RULE=require-fs-read-only)
Done
6 changes: 3 additions & 3 deletions test/commands/scan/tf-plan/out.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Loading policies ...
Loading payload ...
Pre processing ...
Running ( evaluating 1 resource against 1 policy ) ...
- required-s3-tags / require-team-tag / aws_s3_bucket.example FAILED
-> Bucket `example` (aws_s3_bucket.example) does not have the required tags {"Team":"Kyverno"}
-> spec.rules[0].assert.all[0].check.values.tags: Invalid value: map[string]interface {}{"Environment":"Dev", "Name":"My bucket"}: Expected value: map[string]interface {}{"Team":"Kyverno"}
- FAILED (POLICY=required-s3-tags, RULE=require-team-tag, ID=aws_s3_bucket.example)
-> Bucket `example` (aws_s3_bucket.example) does not have the required tags {"Team":"Kyverno"} (CHECK=spec.rules[0].assert.all[0])
-> Invalid value: map[string]interface {}{"Environment":"Dev", "Name":"My bucket"}: Expected value: map[string]interface {}{"Team":"Kyverno"} (PATH=values.tags)
Done
5 changes: 3 additions & 2 deletions test/commands/scan/tf-s3/out.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ Loading policies ...
Loading payload ...
Pre processing ...
Running ( evaluating 1 resource against 1 policy ) ...
- s3 / check-tags / FAILED
-> spec.rules[0].assert.all[0].check.planned_values.root_module.~.resources[0].values.(keys(tags_all)).(contains(@, 'Team')): Invalid value: false: Expected value: true
- FAILED (POLICY=s3, RULE=check-tags)
-> (CHECK=spec.rules[0].assert.all[0])
-> Invalid value: false: Expected value: true (PATH=planned_values.root_module.~.resources[0].values.(keys(tags_all)).(contains(@, 'Team')))
Done
5 changes: 3 additions & 2 deletions test/commands/scan/wildcard/out.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ Loading policies ...
Loading payload ...
Pre processing ...
Running ( evaluating 1 resource against 1 policy ) ...
- required-s3-tags / require-team-tag / bucket1 FAILED
-> spec.rules[0].assert.all[0].check.tags.(wildcard('?*', Team)): Invalid value: true: Expected value: false
- FAILED (POLICY=required-s3-tags, RULE=require-team-tag, ID=bucket1)
-> (CHECK=spec.rules[0].assert.all[0])
-> Invalid value: true: Expected value: false (PATH=tags.(wildcard('?*', Team)))
Done