Skip to content

Commit b71bf10

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 55ee1fa commit b71bf10

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.Re
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
@@ -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)