Skip to content

Commit

Permalink
Make sure that the Rego hook is well-behaved with no data cache
Browse files Browse the repository at this point in the history
Fixes open-policy-agent/gatekeeper#2026

Signed-off-by: Max Smythe <[email protected]>
  • Loading branch information
maxsmythe committed May 4, 2022
1 parent 496a6ae commit cd8c819
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 4 deletions.
2 changes: 1 addition & 1 deletion constraint/pkg/client/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -821,7 +821,7 @@ func TestClient_RemoveTemplate_CascadingDelete(t *testing.T) {

sLower := strings.ToLower(s)
if strings.Contains(sLower, "cascadingdelete") {
t.Errorf("Template not removed from cache: %s", s)
t.Errorf("Constraint not removed from cache: %s", s)
}

finalPreserved := strings.Count(sLower, "stillpersists")
Expand Down
4 changes: 2 additions & 2 deletions constraint/pkg/client/drivers/local/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ func (d *Driver) AddTemplate(ctx context.Context, templ *templates.ConstraintTem
func (d *Driver) RemoveTemplate(ctx context.Context, templ *templates.ConstraintTemplate) error {
kind := templ.Spec.CRD.Spec.Names.Kind

constraintParent := storage.Path{"constraint", kind}
constraintParent := storage.Path{"constraints", kind}

d.mtx.Lock()
defer d.mtx.Unlock()
Expand Down Expand Up @@ -289,7 +289,7 @@ func (d *Driver) Dump(ctx context.Context) (string, error) {
targetData := make(map[string]rego.ResultSet)

for kind, compiler := range targetCompilers {
rs, _, err := d.eval(ctx, compiler, targetName, []string{"data"}, nil)
rs, _, err := d.eval(ctx, compiler, targetName, []string{}, nil)
if err != nil {
return "", err
}
Expand Down
58 changes: 58 additions & 0 deletions constraint/pkg/client/drivers/local/driver_unit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,67 @@ fooisbar[msg] {
input.foo == "bar"
msg := "input.foo is bar"
}
`

AlwaysViolate string = `
package foobar
violation[{"msg": "always violate"}] {
true
}
`
)

func TestDriver_Query(t *testing.T) {
d, err := New()
if err != nil {
t.Fatal(err)
}

tmpl := cts.New(cts.OptTargets(cts.Target(cts.MockTargetHandler, AlwaysViolate)))
ctx := context.Background()

if err := d.AddTemplate(ctx, tmpl); err != nil {
t.Fatalf("got AddTemplate() error = %v, want %v", err, nil)
}

if err := d.AddConstraint(ctx, cts.MakeConstraint(t, "Fakes", "foo-1")); err != nil {
t.Fatalf("got AddConstraint() error = %v, want %v", err, nil)
}

res, _, err := d.Query(
ctx,
cts.MockTargetHandler,
[]*unstructured.Unstructured{cts.MakeConstraint(t, "Fakes", "foo-1")},
map[string]interface{}{"hi": "there"},
)
if err != nil {
t.Fatalf("got Query() error = %v, want %v", err, nil)
}
if len(res) == 0 {
t.Fatalf("got 0 errors on normal query; want 1")
}

// Remove data to make sure our rego hook is well-behaved when
// there is no external data root
if err := d.RemoveData(ctx, cts.MockTargetHandler, nil); err != nil {
t.Fatalf("got RemoveData() error = %v, want %v", err, nil)
}

res, _, err = d.Query(
ctx,
cts.MockTargetHandler,
[]*unstructured.Unstructured{cts.MakeConstraint(t, "Fakes", "foo-1")},
map[string]interface{}{"hi": "there"},
)
if err != nil {
t.Fatalf("got Query() (#2) error = %v, want %v", err, nil)
}
if len(res) == 0 {
t.Fatalf("got 0 errors on data-less query; want 1")
}
}

func TestDriver_AddTemplate(t *testing.T) {
testCases := []struct {
name string
Expand Down
9 changes: 8 additions & 1 deletion constraint/pkg/client/drivers/local/rego.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ violation[response] {
}
# Run the Template with Constraint.
data.template.violation[r] with input as inp with data.inventory as data.external
inventory[inv]
data.template.violation[r] with input as inp with data.inventory as inv
# Construct the response, defaulting "details" to empty object if it is not
# specified.
Expand All @@ -45,6 +46,12 @@ violation[response] {
}
}
inventory[inv] {
inv = data.external
}
inventory[{}] {
not data.external
}
`
)

Expand Down

0 comments on commit cd8c819

Please sign in to comment.