Skip to content

Commit f47bc9d

Browse files
authored
refactor: parse selector in WithSelector option (#154)
* refactor: use pointer for reconciler selector Signed-off-by: Joe Lanford <[email protected]> * refactor: convert selector to predicate in WithSelector to catch error earlier Signed-off-by: Joe Lanford <[email protected]>
1 parent 0d534ef commit f47bc9d

File tree

4 files changed

+43
-56
lines changed

4 files changed

+43
-56
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,4 +76,4 @@ jobs:
7676
with:
7777
fetch-depth: 0
7878
- name: Run go-apidiff
79-
uses: joelanford/go-apidiff@master
79+
uses: joelanford/go-apidiff@main

internal/cmd/helm-operator/run/cmd.go

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,6 @@ import (
2222
"runtime"
2323
"strings"
2424

25-
"github.com/operator-framework/helm-operator-plugins/internal/flags"
26-
"github.com/operator-framework/helm-operator-plugins/internal/metrics"
27-
"github.com/operator-framework/helm-operator-plugins/internal/version"
28-
"github.com/operator-framework/helm-operator-plugins/pkg/annotation"
29-
helmmgr "github.com/operator-framework/helm-operator-plugins/pkg/manager"
30-
"github.com/operator-framework/helm-operator-plugins/pkg/reconciler"
31-
"github.com/operator-framework/helm-operator-plugins/pkg/watches"
32-
3325
"github.com/spf13/cobra"
3426
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3527
ctrl "sigs.k8s.io/controller-runtime"
@@ -41,6 +33,14 @@ import (
4133
"sigs.k8s.io/controller-runtime/pkg/manager"
4234
"sigs.k8s.io/controller-runtime/pkg/manager/signals"
4335
crmetrics "sigs.k8s.io/controller-runtime/pkg/metrics"
36+
37+
"github.com/operator-framework/helm-operator-plugins/internal/flags"
38+
"github.com/operator-framework/helm-operator-plugins/internal/metrics"
39+
"github.com/operator-framework/helm-operator-plugins/internal/version"
40+
"github.com/operator-framework/helm-operator-plugins/pkg/annotation"
41+
helmmgr "github.com/operator-framework/helm-operator-plugins/pkg/manager"
42+
"github.com/operator-framework/helm-operator-plugins/pkg/reconciler"
43+
"github.com/operator-framework/helm-operator-plugins/pkg/watches"
4444
)
4545

4646
var log = logf.Log.WithName("cmd")
@@ -176,7 +176,6 @@ func run(cmd *cobra.Command, f *flags.Flags) {
176176
}
177177

178178
for _, w := range ws {
179-
180179
r, err := reconciler.New(
181180
reconciler.WithChart(*w.Chart),
182181
reconciler.WithGroupVersionKind(w.GroupVersionKind),
@@ -190,7 +189,7 @@ func run(cmd *cobra.Command, f *flags.Flags) {
190189
reconciler.WithUninstallAnnotations(annotation.DefaultUninstallAnnotations...),
191190
)
192191
if err != nil {
193-
log.Error(err, "unable to creste helm reconciler", "controller", "Helm")
192+
log.Error(err, "unable to create helm reconciler", "controller", "Helm")
194193
os.Exit(1)
195194
}
196195

pkg/reconciler/reconciler.go

Lines changed: 9 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import (
2020
"context"
2121
"errors"
2222
"fmt"
23-
"reflect"
2423
"strings"
2524
"sync"
2625
"time"
@@ -43,6 +42,7 @@ import (
4342
"sigs.k8s.io/controller-runtime/pkg/client"
4443
"sigs.k8s.io/controller-runtime/pkg/controller"
4544
"sigs.k8s.io/controller-runtime/pkg/handler"
45+
"sigs.k8s.io/controller-runtime/pkg/predicate"
4646
ctrlpredicate "sigs.k8s.io/controller-runtime/pkg/predicate"
4747
"sigs.k8s.io/controller-runtime/pkg/source"
4848

@@ -72,7 +72,7 @@ type Reconciler struct {
7272
log logr.Logger
7373
gvk *schema.GroupVersionKind
7474
chrt *chart.Chart
75-
selector metav1.LabelSelector
75+
selectorPredicate predicate.Predicate
7676
overrideValues map[string]string
7777
skipDependentWatches bool
7878
maxConcurrentReconciles int
@@ -420,7 +420,11 @@ func WithValueMapper(m values.Mapper) Option {
420420
// predicate that is used to filter resources based on the specified selector
421421
func WithSelector(s metav1.LabelSelector) Option {
422422
return func(r *Reconciler) error {
423-
r.selector = s
423+
p, err := ctrlpredicate.LabelSelectorPredicate(s)
424+
if err != nil {
425+
return err
426+
}
427+
r.selectorPredicate = p
424428
return nil
425429
}
426430
}
@@ -820,13 +824,8 @@ func (r *Reconciler) setupWatches(mgr ctrl.Manager, c controller.Controller) err
820824
obj.SetGroupVersionKind(*r.gvk)
821825

822826
var preds []ctrlpredicate.Predicate
823-
p, err := parsePredicateSelector(r.selector)
824-
if err != nil {
825-
return err
826-
}
827-
828-
if p != nil {
829-
preds = append(preds, p)
827+
if r.selectorPredicate != nil {
828+
preds = append(preds, r.selectorPredicate)
830829
}
831830

832831
if err := c.Watch(
@@ -860,20 +859,6 @@ func (r *Reconciler) setupWatches(mgr ctrl.Manager, c controller.Controller) err
860859
return nil
861860
}
862861

863-
// parsePredicateSelector parses the selector in the WatchOptions and creates a predicate
864-
// that is used to filter resources based on the specified selector
865-
func parsePredicateSelector(selector metav1.LabelSelector) (ctrlpredicate.Predicate, error) {
866-
// If a selector has been specified in watches.yaml, add it to the watch's predicates.
867-
if !reflect.ValueOf(selector).IsZero() {
868-
p, err := ctrlpredicate.LabelSelectorPredicate(selector)
869-
if err != nil {
870-
return nil, fmt.Errorf("error constructing predicate from watches selector: %v", err)
871-
}
872-
return p, nil
873-
}
874-
return nil, nil
875-
}
876-
877862
func ensureDeployedRelease(u *updater.Updater, rel *release.Release) {
878863
reason := conditions.ReasonInstallSuccessful
879864
message := "release was successfully installed"

pkg/reconciler/reconciler_test.go

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ import (
4343
"k8s.io/client-go/tools/record"
4444
"sigs.k8s.io/controller-runtime/pkg/client"
4545
"sigs.k8s.io/controller-runtime/pkg/client/fake"
46+
"sigs.k8s.io/controller-runtime/pkg/event"
4647
"sigs.k8s.io/controller-runtime/pkg/log/zap"
4748
"sigs.k8s.io/controller-runtime/pkg/manager"
4849
"sigs.k8s.io/controller-runtime/pkg/reconcile"
@@ -381,6 +382,29 @@ var _ = Describe("Reconciler", func() {
381382
Expect(r.valueTranslator.Translate(context.Background(), &unstructured.Unstructured{})).To(Equal(chartutil.Values{"translated": true}))
382383
})
383384
})
385+
var _ = Describe("WithSelector", func() {
386+
It("should set the reconciler selector", func() {
387+
objUnlabeled := &unstructured.Unstructured{}
388+
389+
objLabeled := &unstructured.Unstructured{}
390+
objLabeled.SetLabels(map[string]string{"foo": "bar"})
391+
392+
selector := metav1.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}}
393+
Expect(WithSelector(selector)(r)).To(Succeed())
394+
Expect(r.selectorPredicate).NotTo(BeNil())
395+
396+
Expect(r.selectorPredicate.Create(event.CreateEvent{Object: objLabeled})).To(BeTrue())
397+
Expect(r.selectorPredicate.Update(event.UpdateEvent{ObjectOld: objUnlabeled, ObjectNew: objLabeled})).To(BeTrue())
398+
Expect(r.selectorPredicate.Delete(event.DeleteEvent{Object: objLabeled})).To(BeTrue())
399+
Expect(r.selectorPredicate.Generic(event.GenericEvent{Object: objLabeled})).To(BeTrue())
400+
401+
Expect(r.selectorPredicate.Create(event.CreateEvent{Object: objUnlabeled})).To(BeFalse())
402+
Expect(r.selectorPredicate.Update(event.UpdateEvent{ObjectOld: objLabeled, ObjectNew: objUnlabeled})).To(BeFalse())
403+
Expect(r.selectorPredicate.Update(event.UpdateEvent{ObjectOld: objUnlabeled, ObjectNew: objUnlabeled})).To(BeFalse())
404+
Expect(r.selectorPredicate.Delete(event.DeleteEvent{Object: objUnlabeled})).To(BeFalse())
405+
Expect(r.selectorPredicate.Generic(event.GenericEvent{Object: objUnlabeled})).To(BeFalse())
406+
})
407+
})
384408
})
385409

386410
var _ = Describe("Reconcile", func() {
@@ -1221,27 +1245,6 @@ var _ = Describe("Reconciler", func() {
12211245
})
12221246
})
12231247
})
1224-
1225-
var _ = Describe("Test predicate selector", func() {
1226-
It("verifying when a valid selector is passed", func() {
1227-
selectorPass := metav1.LabelSelector{
1228-
MatchLabels: map[string]string{
1229-
"testKey": "testValue",
1230-
},
1231-
}
1232-
1233-
passPredicate, err := parsePredicateSelector(selectorPass)
1234-
Expect(err).NotTo(HaveOccurred())
1235-
Expect(passPredicate).NotTo(BeNil())
1236-
})
1237-
1238-
It("verifying there is no error when no predicate is passed", func() {
1239-
noSelector := metav1.LabelSelector{}
1240-
nilPredicate, err := parsePredicateSelector(noSelector)
1241-
Expect(err).NotTo(HaveOccurred())
1242-
Expect(nilPredicate).To(BeNil())
1243-
})
1244-
})
12451248
})
12461249

12471250
func getManagerOrFail() manager.Manager {

0 commit comments

Comments
 (0)