Skip to content

Commit 1361e2f

Browse files
authored
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 090c110 commit 1361e2f

File tree

2 files changed

+47
-2
lines changed

2 files changed

+47
-2
lines changed

pkg/reconciler/reconciler.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"errors"
2222
"fmt"
2323
errs "github.com/pkg/errors"
24+
"sigs.k8s.io/controller-runtime/pkg/event"
2425
"strings"
2526
"sync"
2627
"time"
@@ -276,7 +277,7 @@ func WithOverrideValues(overrides map[string]string) Option {
276277
}
277278
}
278279

279-
// WithDependentWatchesEnabled is an Option that configures whether the
280+
// SkipDependentWatches is an Option that configures whether the
280281
// Reconciler will register watches for dependent objects in releases and
281282
// trigger reconciliations when they change.
282283
//
@@ -597,7 +598,7 @@ func WithControllerSetupFunc(f ControllerSetupFunc) Option {
597598
}
598599

599600
// ControllerSetup allows restricted access to the Controller using the WithControllerSetupFunc option.
600-
// Currently the only supposed configuration is adding additional watchers do the controller.
601+
// Currently, the only supposed configuration is adding additional watchers do the controller.
601602
type ControllerSetup interface {
602603
// Watch takes events provided by a Source and uses the EventHandler to
603604
// enqueue reconcile.Requests in response to the events.
@@ -650,6 +651,11 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (res ctrl.
650651
return ctrl.Result{}, err
651652
}
652653

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

pkg/reconciler/reconciler_test.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,7 @@ var _ = Describe("Reconciler", func() {
484484
Expect(mgr.GetCache().WaitForCacheSync(ctx)).To(BeTrue())
485485

486486
obj = testutil.BuildTestCR(gvk)
487+
obj.SetLabels(map[string]string{"foo": "bar"})
487488
objKey = types.NamespacedName{Namespace: obj.GetNamespace(), Name: obj.GetName()}
488489
req = reconcile.Request{NamespacedName: objKey}
489490

@@ -517,6 +518,8 @@ var _ = Describe("Reconciler", func() {
517518
cancel()
518519
})
519520

521+
selector := metav1.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}}
522+
520523
// After migration to Ginkgo v2 this can be rewritten using e.g. DescribeTable.
521524
parameterizedReconcilerTests := func(opts reconcilerTestSuiteOpts) {
522525
BeforeEach(func() {
@@ -535,6 +538,7 @@ var _ = Describe("Reconciler", func() {
535538
WithUpgradeAnnotations(annotation.UpgradeDescription{}),
536539
WithUninstallAnnotations(annotation.UninstallDescription{}),
537540
WithPauseReconcileAnnotation("my.domain/pause-reconcile"),
541+
WithSelector(selector),
538542
WithOverrideValues(map[string]string{
539543
"image.repository": "custom-nginx",
540544
}),
@@ -550,6 +554,7 @@ var _ = Describe("Reconciler", func() {
550554
WithUpgradeAnnotations(annotation.UpgradeDescription{}),
551555
WithUninstallAnnotations(annotation.UninstallDescription{}),
552556
WithPauseReconcileAnnotation("my.domain/pause-reconcile"),
557+
WithSelector(selector),
553558
WithOverrideValues(map[string]string{
554559
"image.repository": "custom-nginx",
555560
}),
@@ -1392,6 +1397,40 @@ var _ = Describe("Reconciler", func() {
13921397
})
13931398
})
13941399
})
1400+
When("label selector succeeds", func() {
1401+
It("reconciles only matching label", func() {
1402+
By("setting an invalid action client getter to assert different reconcile results", func() {
1403+
r.actionClientGetter = helmclient.ActionClientGetterFunc(func(client.Object) (helmclient.ActionInterface, error) {
1404+
fakeClient := helmfake.NewActionClient()
1405+
return &fakeClient, nil
1406+
})
1407+
})
1408+
1409+
By("setting not matching label to the CR", func() {
1410+
Expect(mgr.GetClient().Get(ctx, objKey, obj)).To(Succeed())
1411+
obj.SetLabels(map[string]string{"foo": "baz"})
1412+
Expect(mgr.GetClient().Update(ctx, obj)).To(Succeed())
1413+
})
1414+
1415+
By("reconciling is skipped, action client was not called and no error returned", func() {
1416+
res, err := r.Reconcile(ctx, req)
1417+
Expect(res).To(Equal(reconcile.Result{}))
1418+
Expect(err).To(BeNil())
1419+
})
1420+
1421+
By("setting matching label to the CR", func() {
1422+
Expect(mgr.GetClient().Get(ctx, objKey, obj)).To(Succeed())
1423+
obj.SetLabels(map[string]string{"foo": "bar"})
1424+
Expect(mgr.GetClient().Update(ctx, obj)).To(Succeed())
1425+
})
1426+
1427+
By("reconciling is not skipped and error returned because of broken action client", func() {
1428+
res, err := r.Reconcile(ctx, req)
1429+
Expect(res).To(Equal(reconcile.Result{}))
1430+
Expect(err).To(MatchError("get not implemented"))
1431+
})
1432+
})
1433+
})
13951434
})
13961435
})
13971436
})

0 commit comments

Comments
 (0)