Skip to content

Commit 247b0c5

Browse files
authored
feat(policy): remove support for deprecated violations rule (#2380)
Signed-off-by: Sylwester Piskozub <[email protected]>
1 parent 14b6391 commit 247b0c5

13 files changed

+346
-98
lines changed

pkg/policies/engine/rego/rego.go

Lines changed: 2 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,6 @@ const (
114114
expectedArgs = "expected_args"
115115
evalResult = "evaluation_result"
116116
inputElements = "elements"
117-
deprecatedRule = "violations"
118117
mainRule = "result"
119118
matchesParametersRule = "matches_parameters"
120119
matchesEvaluationRule = "matches_evaluation"
@@ -219,63 +218,18 @@ func (r *Engine) Verify(ctx context.Context, policy *engine.Policy, input []byte
219218
}
220219
}
221220

222-
// Try the main rule first
221+
// Try the main rule
223222
if err := executeQuery(getRuleName(parsedModule.Package.Path, mainRule), r.operatingMode == EnvironmentModeRestrictive); err != nil {
224223
return nil, err
225224
}
226225

227-
// If res is nil, it means that the rule hasn't been found
228-
// TODO: Remove when this deprecated rule is not used anymore
229226
if res == nil {
230-
// Try with the deprecated main rule
231-
if err := executeQuery(getRuleName(parsedModule.Package.Path, deprecatedRule), r.operatingMode == EnvironmentModeRestrictive); err != nil {
232-
return nil, err
233-
}
234-
235-
if res == nil {
236-
return nil, fmt.Errorf("failed to evaluate policy: neither '%s' nor '%s' rule found", mainRule, deprecatedRule)
237-
}
238-
239-
return parseViolationsRule(res, policy, rawData)
227+
return nil, fmt.Errorf("failed to evaluate policy: '%s' rule not found", mainRule)
240228
}
241229

242230
return parseResultRule(res, policy, rawData)
243231
}
244232

245-
// Parse deprecated list of violations.
246-
// TODO: Remove this path once `result` rule is consolidated
247-
func parseViolationsRule(res rego.ResultSet, policy *engine.Policy, rawData *engine.RawData) (*engine.EvaluationResult, error) {
248-
violations := make([]*engine.PolicyViolation, 0)
249-
for _, exp := range res {
250-
for _, val := range exp.Expressions {
251-
ruleResults, ok := val.Value.([]interface{})
252-
if !ok {
253-
return nil, engine.ResultFormatError{Field: deprecatedRule}
254-
}
255-
256-
for _, result := range ruleResults {
257-
reasonStr, ok := result.(string)
258-
if !ok {
259-
return nil, engine.ResultFormatError{Field: deprecatedRule}
260-
}
261-
262-
violations = append(violations, &engine.PolicyViolation{
263-
Subject: policy.Name,
264-
Violation: reasonStr,
265-
})
266-
}
267-
}
268-
}
269-
270-
return &engine.EvaluationResult{
271-
Violations: violations,
272-
Skipped: false, // best effort
273-
SkipReason: "",
274-
Ignore: false, // Assume old rules should not be ignored
275-
RawData: rawData,
276-
}, nil
277-
}
278-
279233
// parse `result` rule
280234
func parseResultRule(res rego.ResultSet, policy *engine.Policy, rawData *engine.RawData) (*engine.EvaluationResult, error) {
281235
result := &engine.EvaluationResult{Violations: make([]*engine.PolicyViolation, 0)}

pkg/policies/engine/rego/rego_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ func TestRego_VerifyInvalidPolicy(t *testing.T) {
169169
t.Run("doesn't eval a main rule", func(t *testing.T) {
170170
_, err := r.Verify(context.TODO(), policy, []byte("{\"foo\": \"bar\"}"), nil)
171171
assert.Error(t, err)
172-
assert.Contains(t, err.Error(), "neither 'result' nor 'violations' rule found")
172+
assert.Contains(t, err.Error(), "'result' rule not found")
173173
})
174174
}
175175

pkg/policies/engine/rego/testfiles/arguments.rego

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,37 @@ package main
22

33
import rego.v1
44

5+
################################
6+
# Common section do NOT change #
7+
################################
8+
9+
result := {
10+
"skipped": skipped,
11+
"violations": violations,
12+
"skip_reason": skip_reason,
13+
}
14+
15+
default skip_reason := ""
16+
17+
skip_reason := m if {
18+
not valid_input
19+
m := "invalid input"
20+
}
21+
22+
default skipped := true
23+
24+
skipped := false if valid_input
25+
26+
########################################
27+
# EO Common section, custom code below #
28+
########################################
29+
30+
# Validates if the input is valid and can be understood by this policy
31+
valid_input := true
32+
33+
# If the input is valid, check for any policy violation here
534
violations contains msg if {
35+
valid_input
636
input.args.foo == "bar"
7-
837
msg := "foo is bar"
938
}

pkg/policies/engine/rego/testfiles/arguments_array.rego

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,37 @@ package main
22

33
import rego.v1
44

5+
################################
6+
# Common section do NOT change #
7+
################################
8+
9+
result := {
10+
"skipped": skipped,
11+
"violations": violations,
12+
"skip_reason": skip_reason,
13+
}
14+
15+
default skip_reason := ""
16+
17+
skip_reason := m if {
18+
not valid_input
19+
m := "invalid input"
20+
}
21+
22+
default skipped := true
23+
24+
skipped := false if valid_input
25+
26+
########################################
27+
# EO Common section, custom code below #
28+
########################################
29+
30+
# Validates if the input is valid and can be understood by this policy
31+
valid_input := true
32+
33+
# If the input is valid, check for any policy violation here
534
violations contains msg if {
35+
valid_input
636
"bar" in input.args.foo
7-
837
msg := "foo has bar"
938
}

pkg/policies/engine/rego/testfiles/check_qa.rego

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,55 @@
11
package main
22

3-
violations[msg] {
4-
not is_released
3+
import rego.v1
4+
5+
################################
6+
# Common section do NOT change #
7+
################################
58

6-
msg:= "Container image is not released"
9+
result := {
10+
"skipped": skipped,
11+
"violations": violations,
12+
"skip_reason": skip_reason,
713
}
814

9-
violations[msg] {
10-
not is_approved
15+
default skip_reason := ""
16+
17+
skip_reason := m if {
18+
not valid_input
19+
m := "invalid input"
20+
}
21+
22+
default skipped := true
23+
24+
skipped := false if valid_input
1125

12-
msg:= "Container image is not approved"
26+
########################################
27+
# EO Common section, custom code below #
28+
########################################
29+
30+
# Validates if the input is valid and can be understood by this policy
31+
valid_input := true
32+
33+
# If the input is valid, check for any policy violation here
34+
violations contains msg if {
35+
not is_released
36+
msg := "Container image is not released"
37+
}
38+
39+
violations contains msg if {
40+
valid_input
41+
not is_approved
42+
msg := "Container image is not approved"
1343
}
1444

15-
is_approved {
45+
is_approved if {
1646
input.kind == "CONTAINER_IMAGE"
1747

1848
input.references[i].metadata.name == "chainloop-platform-qa-approval"
1949
input.references[i].annotations.approval == "true"
2050
}
2151

22-
is_released {
52+
is_released if {
2353
input.kind == "CONTAINER_IMAGE"
2454

2555
input.references[i].metadata.name == "chainloop-platform-release-production"
Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
package main
22

3-
is_approved {
4-
input.kind == "CONTAINER_IMAGE"
3+
import rego.v1
4+
5+
# This policy intentionally has no violations or result rule to test error handling
56

7+
is_approved if {
8+
input.kind == "CONTAINER_IMAGE"
69
input.references[i].metadata.name == "chainloop-platform-qa-approval"
710
input.references[i].annotations.approval == "true"
811
}
912

10-
is_released {
13+
is_released if {
1114
input.kind == "CONTAINER_IMAGE"
12-
1315
input.references[i].metadata.name == "chainloop-platform-release-production"
1416
}

pkg/policies/engine/rego/testfiles/restricted_mode_networking_allowed_host.rego

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,35 @@ package main
22

33
import rego.v1
44

5+
################################
6+
# Common section do NOT change #
7+
################################
8+
9+
result := {
10+
"skipped": skipped,
11+
"violations": violations,
12+
"skip_reason": skip_reason,
13+
}
14+
15+
default skip_reason := ""
16+
17+
skip_reason := m if {
18+
not valid_input
19+
m := "invalid input"
20+
}
21+
22+
default skipped := true
23+
24+
skipped := false if valid_input
25+
26+
########################################
27+
# EO Common section, custom code below #
28+
########################################
29+
30+
# Validates if the input is valid and can be understood by this policy
31+
valid_input := true
32+
533
violations contains msg if {
634
kev := http.send({"method": "GET", "url": "https://www.chainloop.dev", "cache": true}).body
7-
835
msg := ""
936
}

pkg/policies/engine/rego/testfiles/restrictive_mode_networking.rego

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,35 @@ package main
22

33
import rego.v1
44

5+
################################
6+
# Common section do NOT change #
7+
################################
8+
9+
result := {
10+
"skipped": skipped,
11+
"violations": violations,
12+
"skip_reason": skip_reason,
13+
}
14+
15+
default skip_reason := ""
16+
17+
skip_reason := m if {
18+
not valid_input
19+
m := "invalid input"
20+
}
21+
22+
default skipped := true
23+
24+
skipped := false if valid_input
25+
26+
########################################
27+
# EO Common section, custom code below #
28+
########################################
29+
30+
# Validates if the input is valid and can be understood by this policy
31+
valid_input := true
32+
533
violations contains msg if {
634
http.send({"method": "GET", "url": "https://github.com"})
7-
835
msg := ""
936
}
Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,54 @@
11
package main
22

3-
import future.keywords.in
4-
import future.keywords.contains
3+
import rego.v1
54

65
# Verifies there is a VEX material, even if not enforced by contract
76

8-
violations[msg] {
9-
not has_vex
7+
################################
8+
# Common section do NOT change #
9+
################################
10+
11+
result := {
12+
"skipped": skipped,
13+
"violations": violations,
14+
"skip_reason": skip_reason,
15+
}
16+
17+
default skip_reason := ""
18+
19+
skip_reason := m if {
20+
not valid_input
21+
m := "invalid input"
22+
}
1023

24+
default skipped := true
25+
26+
skipped := false if valid_input
27+
28+
########################################
29+
# EO Common section, custom code below #
30+
########################################
31+
32+
# Validates if the input is valid and can be understood by this policy
33+
valid_input := true
34+
35+
# If the input is valid, check for any policy violation here
36+
violations contains msg if {
37+
valid_input
38+
not has_vex
1139
msg := "missing VEX material"
1240
}
1341

1442
# Collect all material types
15-
kinds contains kind {
43+
kinds contains kind if {
1644
some material in input.predicate.materials
1745
kind := material.annotations["chainloop.material.type"]
1846
}
1947

20-
has_vex {
48+
has_vex if {
2149
"CSAF_VEX" in kinds
2250
}
2351

24-
has_vex {
52+
has_vex if {
2553
"OPENVEX" in kinds
2654
}

0 commit comments

Comments
 (0)