Skip to content

Commit 4f1b67d

Browse files
kurlovporridge
authored andcommitted
ROX-19221: Fix reconciling with label selector for multiple reconcilers (#42)
* Add filter predicate to secret kind watch * Change fix to filter resource in the reconcile function * Fix doc string typo * Update description for setting broken action client
1 parent 9b91dd7 commit 4f1b67d

File tree

2 files changed

+47
-2
lines changed

2 files changed

+47
-2
lines changed

pkg/reconciler/reconciler.go

+8-2
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import (
4141
ctrl "sigs.k8s.io/controller-runtime"
4242
"sigs.k8s.io/controller-runtime/pkg/client"
4343
"sigs.k8s.io/controller-runtime/pkg/controller"
44+
"sigs.k8s.io/controller-runtime/pkg/event"
4445
"sigs.k8s.io/controller-runtime/pkg/handler"
4546
"sigs.k8s.io/controller-runtime/pkg/predicate"
4647
"sigs.k8s.io/controller-runtime/pkg/source"
@@ -277,7 +278,7 @@ func WithOverrideValues(overrides map[string]string) Option {
277278
}
278279
}
279280

280-
// WithDependentWatchesEnabled is an Option that configures whether the
281+
// SkipDependentWatches is an Option that configures whether the
281282
// Reconciler will register watches for dependent objects in releases and
282283
// trigger reconciliations when they change.
283284
//
@@ -608,7 +609,7 @@ func WithControllerSetupFunc(f ControllerSetupFunc) Option {
608609
}
609610

610611
// ControllerSetup allows restricted access to the Controller using the WithControllerSetupFunc option.
611-
// Currently the only supposed configuration is adding additional watchers do the controller.
612+
// Currently, the only supposed configuration is adding additional watchers do the controller.
612613
type ControllerSetup interface {
613614
// Watch takes events provided by a Source and uses the EventHandler to
614615
// enqueue reconcile.Requests in response to the events.
@@ -661,6 +662,11 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
661662
return ctrl.Result{}, err
662663
}
663664

665+
if r.selectorPredicate != nil && !r.selectorPredicate.Generic(event.GenericEvent{Object: obj}) {
666+
log.V(1).Info("Label selector does not match, skipping reconcile")
667+
return ctrl.Result{}, nil
668+
}
669+
664670
// The finalizer must be present on the CR before we can do anything. Otherwise, if the reconciliation fails,
665671
// there might be resources created by the chart that will not be garbage-collected
666672
// (cluster-scoped resources or resources in other namespaces, which are not bound by an owner reference).

pkg/reconciler/reconciler_test.go

+39
Original file line numberDiff line numberDiff line change
@@ -501,6 +501,7 @@ var _ = Describe("Reconciler", func() {
501501
Expect(mgr.GetCache().WaitForCacheSync(ctx)).To(BeTrue())
502502

503503
obj = testutil.BuildTestCR(gvk)
504+
obj.SetLabels(map[string]string{"foo": "bar"})
504505
objKey = types.NamespacedName{Namespace: obj.GetNamespace(), Name: obj.GetName()}
505506
req = reconcile.Request{NamespacedName: objKey}
506507
})
@@ -533,6 +534,8 @@ var _ = Describe("Reconciler", func() {
533534
cancel()
534535
})
535536

537+
selector := metav1.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}}
538+
536539
// After migration to Ginkgo v2 this can be rewritten using e.g. DescribeTable.
537540
parameterizedReconcilerTests := func(opts reconcilerTestSuiteOpts) {
538541
BeforeEach(func() {
@@ -551,6 +554,7 @@ var _ = Describe("Reconciler", func() {
551554
WithUpgradeAnnotations(annotation.UpgradeDescription{}),
552555
WithUninstallAnnotations(annotation.UninstallDescription{}),
553556
WithPauseReconcileAnnotation("my.domain/pause-reconcile"),
557+
WithSelector(selector),
554558
WithOverrideValues(map[string]string{
555559
"image.repository": "custom-nginx",
556560
}),
@@ -566,6 +570,7 @@ var _ = Describe("Reconciler", func() {
566570
WithUpgradeAnnotations(annotation.UpgradeDescription{}),
567571
WithUninstallAnnotations(annotation.UninstallDescription{}),
568572
WithPauseReconcileAnnotation("my.domain/pause-reconcile"),
573+
WithSelector(selector),
569574
WithOverrideValues(map[string]string{
570575
"image.repository": "custom-nginx",
571576
}),
@@ -1455,6 +1460,40 @@ var _ = Describe("Reconciler", func() {
14551460
})
14561461
})
14571462
})
1463+
When("label selector succeeds", func() {
1464+
It("reconciles only matching label", func() {
1465+
By("setting an invalid action client getter to assert different reconcile results", func() {
1466+
r.actionClientGetter = helmclient.ActionClientGetterFunc(func(context.Context, client.Object) (helmclient.ActionInterface, error) {
1467+
fakeClient := helmfake.NewActionClient()
1468+
return &fakeClient, nil
1469+
})
1470+
})
1471+
1472+
By("setting not matching label to the CR", func() {
1473+
Expect(mgr.GetClient().Get(ctx, objKey, obj)).To(Succeed())
1474+
obj.SetLabels(map[string]string{"foo": "baz"})
1475+
Expect(mgr.GetClient().Update(ctx, obj)).To(Succeed())
1476+
})
1477+
1478+
By("reconciling is skipped, action client was not called and no error returned", func() {
1479+
res, err := r.Reconcile(ctx, req)
1480+
Expect(res).To(Equal(reconcile.Result{}))
1481+
Expect(err).To(BeNil())
1482+
})
1483+
1484+
By("setting matching label to the CR", func() {
1485+
Expect(mgr.GetClient().Get(ctx, objKey, obj)).To(Succeed())
1486+
obj.SetLabels(map[string]string{"foo": "bar"})
1487+
Expect(mgr.GetClient().Update(ctx, obj)).To(Succeed())
1488+
})
1489+
1490+
By("reconciling is not skipped and error returned because of broken action client", func() {
1491+
res, err := r.Reconcile(ctx, req)
1492+
Expect(res).To(Equal(reconcile.Result{}))
1493+
Expect(err).To(MatchError("get not implemented"))
1494+
})
1495+
})
1496+
})
14581497
})
14591498
})
14601499
})

0 commit comments

Comments
 (0)