-
Notifications
You must be signed in to change notification settings - Fork 52
Pass label selector predicate to the Secret Watch and handler #443
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Pass label selector predicate to the Secret Watch and handler #443
Conversation
pkg/reconciler/reconciler.go
Outdated
@@ -1028,8 +1025,18 @@ func (r *Reconciler) setupWatches(mgr ctrl.Manager, c controller.Controller) err | |||
obj.SetGroupVersionKind(*r.gvk) | |||
|
|||
var preds []predicate.Predicate | |||
if r.selectorPredicate != nil { | |||
preds = append(preds, r.selectorPredicate) | |||
var secretPreds []predicate.TypedPredicate[*corev1.Secret] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I get that you are harmonizing with the existing code, but do we need to use a slice at all here (for either preds or secretPreds)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, got it. It's to handle the nil case...
pkg/reconciler/reconciler.go
Outdated
@@ -1060,6 +1067,7 @@ func (r *Reconciler) setupWatches(mgr ctrl.Manager, c controller.Controller) err | |||
obj, | |||
handler.OnlyControllerOwner(), | |||
), | |||
secretPreds..., |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could we get away with fewer changes if we used client.Object in the watch, like e.g.:
if err := c.Watch(
source.Kind(
mgr.GetCache(),
client.Object(secret),
handler.TypedEnqueueRequestForOwner[client.Object](
mgr.GetScheme(),
mgr.GetRESTMapper(),
obj,
handler.OnlyControllerOwner(),
),
preds...,
),
); err != nil {
return err
}
then we don't need to duplicate the predicate slice
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right, this is better
@@ -1488,6 +1492,45 @@ var _ = Describe("Reconciler", func() { | |||
}) | |||
}) | |||
}) | |||
When("label selector set", func() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
<3
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm - just added a small suggestion that could obviate the need to refactor the option because of the requirement for a TypedPredicate. I don't know if there could be side-effects though.
Head branch was pushed to by a user without write access
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #443 +/- ##
==========================================
- Coverage 85.06% 78.49% -6.58%
==========================================
Files 19 31 +12
Lines 1346 2520 +1174
==========================================
+ Hits 1145 1978 +833
- Misses 125 452 +327
- Partials 76 90 +14 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
if r.selectorPredicate != nil { | ||
preds = append(preds, r.selectorPredicate) | ||
|
||
if r.labelSelector.MatchLabels != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, so AFAICT WithSelector
accepts a selector with match expressions (and no match labels), but then this check causes these expressions to be ignored? 🤔
This would be an unwelcome surprise for the user, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a good catch!
I think it depends on how operator handles selectors. If operator uses built-in ParseToLabelSelector
from k8s like in stackrox then this line will not be ignored and behaviour should be correct. But if some operator which uses this plugin creates selector manually with providing MatchExpressions
only then there will be still a bug for multiple version for the same operator.
I also tested fir PR locally and my setup had such selector generation and it worked as expected:
...
selector := "app=" + appLabelValue
labelSelector, err := metav1.ParseToLabelSelector(selector)
...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, it depends on what you pass to ParseToLabelSelector
. If you use any other operator than =
or ==
then AFAICT MatchLabels
will be empty and MatchExpressions
will not.
I think the best way would be to change the if
to do the emptiness check differently...
What
Updated the
setupWatches
method to passpredicate
iflabelSelector
is set to the reconciler.Why
If run two reconcilers with the same GVK but different labelSelectors then both reconcilers reconcile each other RCs ignoring configured LabelSelectors. This could be considered as not expected behavior if running two or more reconcilers with the same GVK but different labelSelectors is covered scenario. This PR fixes this issue.
Example logs of two reconcilers with the same GVK but different label selector.
There is only one CR with label
app=nginx
.Reconciler1 has
app=nginx
label selectorReconciler2 has
app=foo
label selectorReconciler1:
Reconciler2:
Manual testing
This small setup was used for running locally two reconcilers:
Running locally with the fix shows that only one reconciler reconcile the CR and another
Reconciler1:
Reconciler2: