Skip to content

Commit

Permalink
fix: ns exclusion audit from cache (#3129) cherry-pick for 3.14 (#3141)
Browse files Browse the repository at this point in the history
Signed-off-by: Alex Pana <8968914+acpana@users.noreply.github.com>
Signed-off-by: alex <8968914+acpana@users.noreply.github.com>
Signed-off-by: Sertaç Özercan <852750+sozercan@users.noreply.github.com>
Co-authored-by: Sertaç Özercan <852750+sozercan@users.noreply.github.com>
  • Loading branch information
acpana and sozercan committed Nov 1, 2023
1 parent 3f3b697 commit 3b9f645
Show file tree
Hide file tree
Showing 3 changed files with 172 additions and 0 deletions.
11 changes: 11 additions & 0 deletions pkg/audit/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,17 @@ func (am *Manager) auditFromCache(ctx context.Context) ([]Result, []error) {
ns = nil
}

excluded, err := am.skipExcludedNamespace(&obj)
if err != nil {
am.log.Error(err, "Unable to exclude object namespace for audit from cache %v %s/%s", obj.GroupVersionKind().String(), obj.GetNamespace(), obj.GetName())
continue
}

if excluded {
am.log.V(logging.DebugLevel).Info("excluding object from audit from cache %v %s/%s", obj.GroupVersionKind().String(), obj.GetNamespace(), obj.GetName())
continue
}

au := &target.AugmentedUnstructured{
Object: obj,
Namespace: ns,
Expand Down
98 changes: 98 additions & 0 deletions pkg/audit/manager_test.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,115 @@
package audit

import (
"context"
"os"
"reflect"
"testing"

constraintclient "github.com/open-policy-agent/frameworks/constraint/pkg/client"
"github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/rego"
configv1alpha1 "github.com/open-policy-agent/gatekeeper/v3/apis/config/v1alpha1"
"github.com/open-policy-agent/gatekeeper/v3/pkg/controller/config/process"
"github.com/open-policy-agent/gatekeeper/v3/pkg/fakes"
"github.com/open-policy-agent/gatekeeper/v3/pkg/target"
"github.com/open-policy-agent/gatekeeper/v3/pkg/wildcard"
"github.com/pkg/errors"
"github.com/stretchr/testify/require"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
)

func Test_auditFromCache(t *testing.T) {
podToReview := fakes.Pod(fakes.WithNamespace("test-namespace-1"))
podGVK := podToReview.GroupVersionKind()
testAuditCache := fakeCacheListerFor([]schema.GroupVersionKind{podGVK}, []client.Object{podToReview})

driver, err := rego.New()
require.NoError(t, err)
client, err := constraintclient.NewClient(constraintclient.Targets(&target.K8sValidationTarget{}), constraintclient.Driver(driver))
require.NoError(t, err)

_, err = client.AddTemplate(context.Background(), fakes.DenyAllRegoTemplate())
require.NoError(t, err, "adding denyall constraint template")
_, err = client.AddConstraint(context.Background(), fakes.DenyAllConstraint())
require.NoError(t, err, "adding denyall constraint")

tests := []struct {
name string
processExcluder *process.Excluder
wantViolation bool
}{
{
name: "obj excluded from audit",
processExcluder: processExcluderFor([]string{"test-namespace-1"}),
},
{
name: "obj not excluded from audit",
processExcluder: processExcluderFor([]string{}),
wantViolation: true,
},
}

for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
am := &Manager{
processExcluder: tc.processExcluder,
auditCache: testAuditCache,
opa: client,
}

results, errs := am.auditFromCache(context.Background())
require.Len(t, errs, 0)

if tc.wantViolation {
require.Len(t, results, 1)
} else {
require.Len(t, results, 0)
}
})
}
}

func fakeCacheListerFor(gvks []schema.GroupVersionKind, objsToList []client.Object) *CacheLister {
k8sclient := fake.NewClientBuilder().WithObjects(objsToList...).Build()
fakeLister := fakeWatchIterator{gvksToList: gvks}

return NewAuditCacheLister(k8sclient, &fakeLister)
}

type fakeWatchIterator struct {
gvksToList []schema.GroupVersionKind
}

func (f *fakeWatchIterator) DoForEach(listFunc func(gvk schema.GroupVersionKind) error) error {
for _, gvk := range f.gvksToList {
if err := listFunc(gvk); err != nil {
return err
}
}

return nil
}

func processExcluderFor(ns []string) *process.Excluder {
processExcluder := process.New()
for _, n := range ns {
processExcluder.Add([]configv1alpha1.MatchEntry{
{
ExcludedNamespaces: []wildcard.Wildcard{wildcard.Wildcard(n)},
Processes: []string{"audit"},
},
})
}

return processExcluder
}

func Test_newNSCache(t *testing.T) {
tests := []struct {
name string
Expand Down
63 changes: 63 additions & 0 deletions pkg/fakes/fixtures.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package fakes

import (
"github.com/open-policy-agent/frameworks/constraint/pkg/apis/constraints"
templatesv1beta1 "github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1beta1"
"github.com/open-policy-agent/frameworks/constraint/pkg/core/templates"
"github.com/open-policy-agent/gatekeeper/v3/pkg/target"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
)

func DenyAllRegoTemplate() *templates.ConstraintTemplate {
return &templates.ConstraintTemplate{
TypeMeta: metav1.TypeMeta{
APIVersion: templatesv1beta1.SchemeGroupVersion.String(),
Kind: "ConstraintTemplate",
},
ObjectMeta: metav1.ObjectMeta{
Name: "denyall",
},
Spec: templates.ConstraintTemplateSpec{
CRD: templates.CRD{
Spec: templates.CRDSpec{
Names: templates.Names{
Kind: "denyall",
},
},
},
Targets: []templates.Target{{
Target: target.Name,
Code: []templates.Code{{
Engine: "Rego",
Source: &templates.Anything{
Value: map[string]interface{}{"rego": `
package goodrego
violation[{"msg": msg}] {
msg := "denyall"
}`},
},
}},
}},
},
}
}

func DenyAllConstraint() *unstructured.Unstructured {
return ConstraintFor("denyall")
}

func ConstraintFor(kind string) *unstructured.Unstructured {
u := &unstructured.Unstructured{}

u.SetGroupVersionKind(schema.GroupVersionKind{
Group: constraints.Group,
Version: "v1beta1",
Kind: kind,
})
u.SetName("constraint")

return u
}

0 comments on commit 3b9f645

Please sign in to comment.