Skip to content

Commit e6dae8d

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 a37a573 commit e6dae8d

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"
@@ -271,7 +272,7 @@ func WithOverrideValues(overrides map[string]string) Option {
271272
}
272273
}
273274

274-
// WithDependentWatchesEnabled is an Option that configures whether the
275+
// SkipDependentWatches is an Option that configures whether the
275276
// Reconciler will register watches for dependent objects in releases and
276277
// trigger reconciliations when they change.
277278
//
@@ -602,7 +603,7 @@ func WithControllerSetupFunc(f ControllerSetupFunc) Option {
602603
}
603604

604605
// ControllerSetup allows restricted access to the Controller using the WithControllerSetupFunc option.
605-
// Currently the only supposed configuration is adding additional watchers do the controller.
606+
// Currently, the only supposed configuration is adding additional watchers do the controller.
606607
type ControllerSetup interface {
607608
// Watch takes events provided by a Source and uses the EventHandler to
608609
// enqueue reconcile.Requests in response to the events.
@@ -655,6 +656,11 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (_ ctrl.Re
655656
return ctrl.Result{}, err
656657
}
657658

659+
if r.selectorPredicate != nil && !r.selectorPredicate.Generic(event.GenericEvent{Object: obj}) {
660+
log.V(1).Info("Label selector does not match, skipping reconcile")
661+
return ctrl.Result{}, nil
662+
}
663+
658664
// The finalizer must be present on the CR before we can do anything. Otherwise, if the reconciliation fails,
659665
// there might be resources created by the chart that will not be garbage-collected
660666
// (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
@@ -503,6 +503,7 @@ var _ = Describe("Reconciler", func() {
503503
Expect(mgr.GetCache().WaitForCacheSync(ctx)).To(BeTrue())
504504

505505
obj = testutil.BuildTestCR(gvk)
506+
obj.SetLabels(map[string]string{"foo": "bar"})
506507
objKey = types.NamespacedName{Namespace: obj.GetNamespace(), Name: obj.GetName()}
507508
req = reconcile.Request{NamespacedName: objKey}
508509
})
@@ -535,6 +536,8 @@ var _ = Describe("Reconciler", func() {
535536
cancel()
536537
})
537538

539+
selector := metav1.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}}
540+
538541
// After migration to Ginkgo v2 this can be rewritten using e.g. DescribeTable.
539542
parameterizedReconcilerTests := func(opts reconcilerTestSuiteOpts) {
540543
BeforeEach(func() {
@@ -553,6 +556,7 @@ var _ = Describe("Reconciler", func() {
553556
WithUpgradeAnnotations(annotation.UpgradeDescription{}),
554557
WithUninstallAnnotations(annotation.UninstallDescription{}),
555558
WithPauseReconcileAnnotation("my.domain/pause-reconcile"),
559+
WithSelector(selector),
556560
WithOverrideValues(map[string]string{
557561
"image.repository": "custom-nginx",
558562
}),
@@ -568,6 +572,7 @@ var _ = Describe("Reconciler", func() {
568572
WithUpgradeAnnotations(annotation.UpgradeDescription{}),
569573
WithUninstallAnnotations(annotation.UninstallDescription{}),
570574
WithPauseReconcileAnnotation("my.domain/pause-reconcile"),
575+
WithSelector(selector),
571576
WithOverrideValues(map[string]string{
572577
"image.repository": "custom-nginx",
573578
}),
@@ -1502,6 +1507,40 @@ var _ = Describe("Reconciler", func() {
15021507
})
15031508
})
15041509
})
1510+
When("label selector succeeds", func() {
1511+
It("reconciles only matching label", func() {
1512+
By("setting an invalid action client getter to assert different reconcile results", func() {
1513+
r.actionClientGetter = helmclient.ActionClientGetterFunc(func(context.Context, client.Object) (helmclient.ActionInterface, error) {
1514+
fakeClient := helmfake.NewActionClient()
1515+
return &fakeClient, nil
1516+
})
1517+
})
1518+
1519+
By("setting not matching label to the CR", func() {
1520+
Expect(mgr.GetClient().Get(ctx, objKey, obj)).To(Succeed())
1521+
obj.SetLabels(map[string]string{"foo": "baz"})
1522+
Expect(mgr.GetClient().Update(ctx, obj)).To(Succeed())
1523+
})
1524+
1525+
By("reconciling is skipped, action client was not called and no error returned", func() {
1526+
res, err := r.Reconcile(ctx, req)
1527+
Expect(res).To(Equal(reconcile.Result{}))
1528+
Expect(err).To(BeNil())
1529+
})
1530+
1531+
By("setting matching label to the CR", func() {
1532+
Expect(mgr.GetClient().Get(ctx, objKey, obj)).To(Succeed())
1533+
obj.SetLabels(map[string]string{"foo": "bar"})
1534+
Expect(mgr.GetClient().Update(ctx, obj)).To(Succeed())
1535+
})
1536+
1537+
By("reconciling is not skipped and error returned because of broken action client", func() {
1538+
res, err := r.Reconcile(ctx, req)
1539+
Expect(res).To(Equal(reconcile.Result{}))
1540+
Expect(err).To(MatchError("get not implemented"))
1541+
})
1542+
})
1543+
})
15051544
})
15061545
})
15071546
})

0 commit comments

Comments
 (0)