Skip to content

Commit f4409bf

Browse files
committed
Make hasMatchingLabels generic
1 parent 2ccd5c2 commit f4409bf

4 files changed

+92
-127
lines changed

controllers/machine_helpers.go

+19
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import (
2020
"context"
2121

2222
"github.com/pkg/errors"
23+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
24+
"k8s.io/apimachinery/pkg/labels"
2325
clusterv1 "sigs.k8s.io/cluster-api/api/v1alpha3"
2426
"sigs.k8s.io/controller-runtime/pkg/client"
2527
)
@@ -47,3 +49,20 @@ func getActiveMachinesInCluster(ctx context.Context, c client.Client, namespace,
4749
}
4850
return machines, nil
4951
}
52+
53+
// hasMatchingLabels verifies that the Label Selector matches the given Labels
54+
func hasMatchingLabels(matchSelector metav1.LabelSelector, matchLabels map[string]string) bool {
55+
// This should never fail, validating webhook should catch this first
56+
selector, err := metav1.LabelSelectorAsSelector(&matchSelector)
57+
if err != nil {
58+
return false
59+
}
60+
// If a nil or empty selector creeps in, it should match nothing, not everything.
61+
if selector.Empty() {
62+
return false
63+
}
64+
if !selector.Matches(labels.Set(matchLabels)) {
65+
return false
66+
}
67+
return true
68+
}

controllers/machine_helpers_test.go

+71
Original file line numberDiff line numberDiff line change
@@ -127,3 +127,74 @@ func Test_getActiveMachinesInCluster(t *testing.T) {
127127
})
128128
}
129129
}
130+
131+
func TestMachineHealthCheckHasMatchingLabels(t *testing.T) {
132+
testCases := []struct {
133+
name string
134+
selector metav1.LabelSelector
135+
labels map[string]string
136+
expected bool
137+
}{
138+
{
139+
name: "selector matches labels",
140+
141+
selector: metav1.LabelSelector{
142+
MatchLabels: map[string]string{
143+
"foo": "bar",
144+
},
145+
},
146+
147+
labels: map[string]string{
148+
"foo": "bar",
149+
},
150+
151+
expected: true,
152+
},
153+
{
154+
name: "selector does not match labels",
155+
156+
selector: metav1.LabelSelector{
157+
MatchLabels: map[string]string{
158+
"foo": "bar",
159+
},
160+
},
161+
162+
labels: map[string]string{
163+
"no": "match",
164+
},
165+
expected: false,
166+
},
167+
{
168+
name: "selector is empty",
169+
selector: metav1.LabelSelector{},
170+
labels: map[string]string{},
171+
expected: false,
172+
},
173+
{
174+
name: "seelctor is invalid",
175+
selector: metav1.LabelSelector{
176+
MatchLabels: map[string]string{
177+
"foo": "bar",
178+
},
179+
MatchExpressions: []metav1.LabelSelectorRequirement{
180+
{
181+
Operator: "bad-operator",
182+
},
183+
},
184+
},
185+
labels: map[string]string{
186+
"foo": "bar",
187+
},
188+
expected: false,
189+
},
190+
}
191+
192+
for _, tc := range testCases {
193+
t.Run(tc.name, func(t *testing.T) {
194+
g := NewWithT(t)
195+
196+
got := hasMatchingLabels(tc.selector, tc.labels)
197+
g.Expect(got).To(Equal(tc.expected))
198+
})
199+
}
200+
}

controllers/machinehealthcheck_controller.go

+2-21
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ import (
2727
corev1 "k8s.io/api/core/v1"
2828
apierrors "k8s.io/apimachinery/pkg/api/errors"
2929
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
30-
"k8s.io/apimachinery/pkg/labels"
3130
"k8s.io/apimachinery/pkg/runtime"
3231
"k8s.io/apimachinery/pkg/types"
3332
kerrors "k8s.io/apimachinery/pkg/util/errors"
@@ -283,7 +282,7 @@ func (r *MachineHealthCheckReconciler) machineToMachineHealthCheck(o handler.Map
283282
var requests []reconcile.Request
284283
for k := range mhcList.Items {
285284
mhc := &mhcList.Items[k]
286-
if r.hasMatchingLabels(mhc, m) {
285+
if hasMatchingLabels(mhc.Spec.Selector, m.Labels) {
287286
key := util.ObjectKey(mhc)
288287
requests = append(requests, reconcile.Request{NamespacedName: key})
289288
}
@@ -318,7 +317,7 @@ func (r *MachineHealthCheckReconciler) nodeToMachineHealthCheck(o handler.MapObj
318317
var requests []reconcile.Request
319318
for k := range mhcList.Items {
320319
mhc := &mhcList.Items[k]
321-
if r.hasMatchingLabels(mhc, machine) {
320+
if hasMatchingLabels(mhc.Spec.Selector, machine.Labels) {
322321
key := util.ObjectKey(mhc)
323322
requests = append(requests, reconcile.Request{NamespacedName: key})
324323
}
@@ -406,21 +405,3 @@ func (r *MachineHealthCheckReconciler) indexMachineByNodeName(object runtime.Obj
406405

407406
return nil
408407
}
409-
410-
// hasMatchingLabels verifies that the MachineHealthCheck's label selector
411-
// matches the given Machine
412-
func (r *MachineHealthCheckReconciler) hasMatchingLabels(machineHealthCheck *clusterv1.MachineHealthCheck, machine *clusterv1.Machine) bool {
413-
// This should never fail, validating webhook should catch this first
414-
selector, err := metav1.LabelSelectorAsSelector(&machineHealthCheck.Spec.Selector)
415-
if err != nil {
416-
return false
417-
}
418-
// If a MachineHealthCheck with a nil or empty selector creeps in, it should match nothing, not everything.
419-
if selector.Empty() {
420-
return false
421-
}
422-
if !selector.Matches(labels.Set(machine.Labels)) {
423-
return false
424-
}
425-
return true
426-
}

controllers/machinehealthcheck_controller_test.go

-106
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ import (
3131
"k8s.io/apimachinery/pkg/runtime"
3232
"k8s.io/apimachinery/pkg/types"
3333
"k8s.io/client-go/kubernetes/scheme"
34-
"k8s.io/klog/klogr"
3534
clusterv1 "sigs.k8s.io/cluster-api/api/v1alpha3"
3635
"sigs.k8s.io/cluster-api/controllers/external"
3736
"sigs.k8s.io/controller-runtime/pkg/client"
@@ -420,111 +419,6 @@ func newTestMachineHealthCheck(name, namespace, cluster string, labels map[strin
420419
}
421420
}
422421

423-
func TestMachineHealthCheckHasMatchingLabels(t *testing.T) {
424-
r := &MachineHealthCheckReconciler{
425-
Log: klogr.New(),
426-
}
427-
428-
testCases := []struct {
429-
name string
430-
machineHealthCheck clusterv1.MachineHealthCheck
431-
machine clusterv1.Machine
432-
expected bool
433-
}{
434-
{
435-
name: "machine set and machine have matching labels",
436-
machineHealthCheck: clusterv1.MachineHealthCheck{
437-
Spec: clusterv1.MachineHealthCheckSpec{
438-
Selector: metav1.LabelSelector{
439-
MatchLabels: map[string]string{
440-
"foo": "bar",
441-
},
442-
},
443-
},
444-
},
445-
machine: clusterv1.Machine{
446-
ObjectMeta: metav1.ObjectMeta{
447-
Name: "matchSelector",
448-
Labels: map[string]string{
449-
"foo": "bar",
450-
},
451-
},
452-
},
453-
expected: true,
454-
},
455-
{
456-
name: "machine set and machine do not have matching labels",
457-
machineHealthCheck: clusterv1.MachineHealthCheck{
458-
Spec: clusterv1.MachineHealthCheckSpec{
459-
Selector: metav1.LabelSelector{
460-
MatchLabels: map[string]string{
461-
"foo": "bar",
462-
},
463-
},
464-
},
465-
},
466-
machine: clusterv1.Machine{
467-
ObjectMeta: metav1.ObjectMeta{
468-
Name: "doesNotMatchSelector",
469-
Labels: map[string]string{
470-
"no": "match",
471-
},
472-
},
473-
},
474-
expected: false,
475-
},
476-
{
477-
name: "machine set has empty selector",
478-
machineHealthCheck: clusterv1.MachineHealthCheck{
479-
Spec: clusterv1.MachineHealthCheckSpec{
480-
Selector: metav1.LabelSelector{},
481-
},
482-
},
483-
machine: clusterv1.Machine{
484-
ObjectMeta: metav1.ObjectMeta{
485-
Name: "doesNotMatter",
486-
},
487-
},
488-
expected: false,
489-
},
490-
{
491-
name: "machine set has bad selector",
492-
machineHealthCheck: clusterv1.MachineHealthCheck{
493-
Spec: clusterv1.MachineHealthCheckSpec{
494-
Selector: metav1.LabelSelector{
495-
MatchLabels: map[string]string{
496-
"foo": "bar",
497-
},
498-
MatchExpressions: []metav1.LabelSelectorRequirement{
499-
{
500-
Operator: "bad-operator",
501-
},
502-
},
503-
},
504-
},
505-
},
506-
machine: clusterv1.Machine{
507-
ObjectMeta: metav1.ObjectMeta{
508-
Name: "match",
509-
Labels: map[string]string{
510-
"foo": "bar",
511-
},
512-
},
513-
},
514-
expected: false,
515-
},
516-
}
517-
518-
for _, tc := range testCases {
519-
t.Run(tc.name, func(t *testing.T) {
520-
g := NewWithT(t)
521-
522-
got := r.hasMatchingLabels(&tc.machineHealthCheck, &tc.machine)
523-
g.Expect(got).To(Equal(tc.expected))
524-
})
525-
}
526-
}
527-
528422
func TestMachineToMachineHealthCheck(t *testing.T) {
529423
// This test sets up a proper test env to allow testing of the cache index
530424
// that is used as part of the clusterToMachineHealthCheck map function

0 commit comments

Comments
 (0)