From deab83d62f2f6cb7ccf59a376325b0094a427da2 Mon Sep 17 00:00:00 2001 From: Frank Jogeleit Date: Tue, 6 Aug 2024 14:43:47 +0200 Subject: [PATCH] reconcile only PolicyReports managed by kyverno (#10794) Signed-off-by: Frank Jogeleit Co-authored-by: shuting --- .../report/aggregate/controller.go | 9 +- .../report/aggregate/controller_test.go | 102 ++++++++++++++++++ 2 files changed, 109 insertions(+), 2 deletions(-) create mode 100644 pkg/controllers/report/aggregate/controller_test.go diff --git a/pkg/controllers/report/aggregate/controller.go b/pkg/controllers/report/aggregate/controller.go index 99c7f72ac3..28622ac97a 100644 --- a/pkg/controllers/report/aggregate/controller.go +++ b/pkg/controllers/report/aggregate/controller.go @@ -5,6 +5,7 @@ import ( "time" "github.com/go-logr/logr" + "github.com/kyverno/kyverno/api/kyverno" kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" policyreportv1alpha2 "github.com/kyverno/kyverno/api/policyreport/v1alpha2" reportsv1 "github.com/kyverno/kyverno/api/reports/v1" @@ -92,12 +93,16 @@ func NewController( logger.Error(err, "failed to register event handlers") } enqueueAll := func() { - if list, err := polrInformer.Lister().List(labels.Everything()); err == nil { + selector := labels.SelectorFromSet(labels.Set{ + kyverno.LabelAppManagedBy: kyverno.ValueKyvernoApp, + }) + + if list, err := polrInformer.Lister().List(selector); err == nil { for _, item := range list { c.backQueue.AddAfter(controllerutils.MetaObjectToName(item.(*metav1.PartialObjectMetadata)), enqueueDelay) } } - if list, err := cpolrInformer.Lister().List(labels.Everything()); err == nil { + if list, err := cpolrInformer.Lister().List(selector); err == nil { for _, item := range list { c.backQueue.AddAfter(controllerutils.MetaObjectToName(item.(*metav1.PartialObjectMetadata)), enqueueDelay) } diff --git a/pkg/controllers/report/aggregate/controller_test.go b/pkg/controllers/report/aggregate/controller_test.go new file mode 100644 index 0000000000..a9a1881ee3 --- /dev/null +++ b/pkg/controllers/report/aggregate/controller_test.go @@ -0,0 +1,102 @@ +package aggregate_test + +import ( + "context" + "testing" + "time" + + "github.com/kyverno/kyverno/api/kyverno" + v1 "github.com/kyverno/kyverno/api/kyverno/v1" + "github.com/kyverno/kyverno/api/policyreport/v1alpha2" + versionedfake "github.com/kyverno/kyverno/pkg/client/clientset/versioned/fake" + kyvernoinformer "github.com/kyverno/kyverno/pkg/client/informers/externalversions" + "github.com/kyverno/kyverno/pkg/controllers/report/aggregate" + "github.com/stretchr/testify/assert" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + metafake "k8s.io/client-go/metadata/fake" + metadatainformers "k8s.io/client-go/metadata/metadatainformer" + k8stesting "k8s.io/client-go/testing" +) + +func newFakeMetaClient() (metadatainformers.SharedInformerFactory, metafake.MetadataClient) { + s := metafake.NewTestScheme() + metav1.AddMetaToScheme(s) + + client := metafake.NewSimpleMetadataClient(s) + + return metadatainformers.NewSharedInformerFactory(client, 1*time.Minute), client.Resource(v1alpha2.SchemeGroupVersion.WithResource("policyreports")).Namespace("default").(metafake.MetadataClient) +} + +var ( + kyvernoPolr = &v1alpha2.PolicyReport{ + ObjectMeta: metav1.ObjectMeta{ + Name: "kyverno-polr", + Namespace: "default", + Labels: map[string]string{ + kyverno.LabelAppManagedBy: kyverno.ValueKyvernoApp, + }, + }, + } + notKyvernoPolr = &v1alpha2.PolicyReport{ + ObjectMeta: metav1.ObjectMeta{ + Name: "not-kyverno-polr", + Namespace: "default", + }, + } +) + +func TestController(t *testing.T) { + metaFactory, metaClient := newFakeMetaClient() + client := versionedfake.NewSimpleClientset() + kyvernoFactory := kyvernoinformer.NewSharedInformerFactory(client, 1*time.Second) + + polInformer := kyvernoFactory.Kyverno().V1().Policies() + cpolInformer := kyvernoFactory.Kyverno().V1().ClusterPolicies() + + client.Wgpolicyk8sV1alpha2().PolicyReports("default").Create(context.TODO(), kyvernoPolr, metav1.CreateOptions{}) + client.Wgpolicyk8sV1alpha2().PolicyReports("default").Create(context.TODO(), notKyvernoPolr, metav1.CreateOptions{}) + + metaClient.CreateFake(&metav1.PartialObjectMetadata{ObjectMeta: kyvernoPolr.ObjectMeta}, metav1.CreateOptions{}) + metaClient.CreateFake(&metav1.PartialObjectMetadata{ObjectMeta: notKyvernoPolr.ObjectMeta}, metav1.CreateOptions{}) + + controller := aggregate.NewController(client, nil, metaFactory, polInformer, cpolInformer, nil) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + go func() { + controller.Run(ctx, 1) + }() + + stop := make(chan struct{}) + defer close(stop) + + metaFactory.Start(stop) + kyvernoFactory.Start(stop) + + metaFactory.WaitForCacheSync(stop) + kyvernoFactory.WaitForCacheSync(stop) + + _, err := client.KyvernoV1().ClusterPolicies().Create(context.TODO(), &v1.ClusterPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "kyverno-pol", + }, + }, metav1.CreateOptions{}) + + assert.Nil(t, err) + + // This delay is necessary because the controller processes the queue if a delay of 10 seconds + // because the controller runs in a goroutine it needs to wait a bit longer to give the controller time to process the queue + time.Sleep(13 * time.Second) + + list, _ := client.Wgpolicyk8sV1alpha2().PolicyReports("default").List(context.TODO(), metav1.ListOptions{}) + + assert.Len(t, list.Items, 1) + assert.Equal(t, notKyvernoPolr.Name, list.Items[0].Name) + + for _, a := range client.Fake.Actions() { + if action, ok := a.(k8stesting.GetAction); ok { + assert.False(t, action.GetName() == notKyvernoPolr.Name, "PolicyReports not managed by kyverno should not be requested") + } + } +}