-
Notifications
You must be signed in to change notification settings - Fork 743
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
Implement the match logic #932
Conversation
Thanks! I'll take a look at this once we merge some of the other PRs, it's getting a bit hard to track which diff belongs to which PR. |
Actually (not asking to), but you could do by reviewing only the last commit d6cff6b |
oh, nice! I'll take a look |
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.
@maxsmythe @ritazh @shomron rebased, ready for 👀 |
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.
Thanks! Some comments around the label selector logic
corev1 "k8s.io/api/core/v1" | ||
apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" | ||
"k8s.io/apimachinery/pkg/api/meta" | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" |
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.
nit: merge import blocks
return false, nil | ||
} | ||
} | ||
if match.LabelSelector != 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.
Should we also match the label selector against old object?
It seems weird, but that's how MutatingWebhookConfiguration's logic works:
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 assumed it was only against the old object, as it's the criteria for applying a given mutation.
Given all the stability premises and the fact that we are only adding (and not changing) labels, I think it's safe to assume that if the old object matches the selector, the new one will. If only the new one will, it will be a matter of another round of mutation before the stability.
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.
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.
This is the last bit, I think apart from this discussion this is good to go.
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.
Adding the above people to the review, hopefully that kick-starts the discussion.
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.
+1 on not deviating from K8s mutatingwebhookconfig logic to avoid surprises to users
we are only adding (and not changing) labels
what if users want to match label on the old object then mutate the object to delete that label? is that a supported scenario for MVP?
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.
Just to make sure I understood.
Here defining "the old" vs "the new" is a bit tricky, as we apply a bunch of mutations at the same time, and we can't just refer to the old as "before all mutations" and new as "after all mutations" because the decision of whether applying a mutation or not is based on the match logic. I think what we do here is to test only against "the old" object, with respect to the single mutation.
See
gatekeeper/pkg/mutation/system.go
Line 85 in 624bfcc
if m.Matches(obj, ns) { |
In that case, what is referred as old vs new? And what should happen if we find out that after a mutation the object does not match anymore?
Is it fine to assume that we match against the old, we mutate and then we "rollback" the mutation (i.e restoring a backup of the object) if match of the single mutation fails afterwards?
Re: deleting labels, this is not possible with the current design as we are only adding non-existing labels / annotations. This is needed for making sure the mutation converges.
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.
Given all the reasons above, +1 on not testing OldObject for now
Re: deleting labels, this is not possible with the current design as we are only adding non-existing labels / annotations. This is needed for making sure the mutation converges.
Thanks!
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.
Lemme make sure I'm getting this straight:
If we also match against newObject, then, if a mutation were to add a label to a resource, then all instances of that resource type would match. The other angle on that would be that you couldn't add a label to a subset of objects of one GVK by selecting by label.
I think I don't grok the purpose of applying to both old and new objects unless you allow the mutation webhook to create or delete objects. It seems unexpected at best.
I'm in favor of shirking the k8s standard here and doing what makes more common sense, but I suspect I am missing something, too.
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.
One point of confusion is OldObject
has a specific meaning, defined here:
I don't think that changes much, if any, of the above analysis, but has been the source of a bit of confusion.
} | ||
} | ||
|
||
if match.NamespaceSelector != 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.
For MutatingWebhookConfigurations:
- Cluster scoped resources always match an NS selector
- If the object itself is an NS, the namespace selector is evaluated against the object's labels
- Unclear whether the old object + new object matching logic also applies here
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.
The namespace remains the same, so there won't be difference in new vs old.
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.
Implemented the first two points and added tests.
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.
The namespace would remain the same unless the object itself is a namespace.
f24dfd1
to
a22459c
Compare
Adding a Match function that accepts a Match instance, an object to be matched against and its related namespace. Adding a AppliesTo function that accepts a ApplyTo slice and an object to be matched against. Signed-off-by: Federico Paolinelli <fpaoline@redhat.com>
Rebased and integrated the two mutators' Matches method with the Matches function. |
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.
return false, nil | ||
} | ||
} | ||
if match.LabelSelector != 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.
See the notes in the discussion on the meeting minutes:
TL;DR my opinion is we not test OldObject for mutation for now, and re-visit the question before graduating from alpha, so we can make this decision based off real usage data.
Each mutator matches uses the Matches function to check if the given object matches the mutator. This also includes a change in the mutator interface as metav1.Object do not have accessors for kind / group. Signed-off-by: Federico Paolinelli <fpaoline@redhat.com>
Codecov Report
@@ Coverage Diff @@
## master #932 +/- ##
==========================================
+ Coverage 46.99% 47.86% +0.86%
==========================================
Files 58 59 +1
Lines 3541 3623 +82
==========================================
+ Hits 1664 1734 +70
- Misses 1668 1678 +10
- Partials 209 211 +2
Flags with carried forward coverage won't be shown. Click here to find out more.
Continue to review full report at Codecov.
|
Added this last change https://github.com/open-policy-agent/gatekeeper/compare/379dc934fa7a12f7a4a99f080aa3c211a5a5197f..55aaaffc6c91e4ce33787d62e55d26be8a416251 Apart from this, based on the previous discussions I think this one is ready to go. |
} | ||
for _, g := range apply.Versions { | ||
if g == gvk.Version { | ||
matchesVersion = true |
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.
how do we handle when there are multiple versions of the same group kind in the cluster? this here would resolve to mismatch but the apiserver would consider it a match.
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.
applyTo
should be a strict check, because mutations create implicit schema.
Note that this check is for the mutation.spec.applyTo
field, not spec.match.kinds
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.
Not sure I got the point.
ApplyTo allows to specify multiple versions, which would then match (or, apply) to different versions of the same group.
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.
Gotcha! Let's make sure we document this. To support multiple versions of the same schema, user needs to add another gvk to the applyTo
list in the mutation object.
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
What this PR does / why we need it:
Implement both a Matches function and an AppliesTo function that checks if the given object matches a Match / ApplyTo.
This tells if a given mutation will need to be applied to a given object.
Which issue(s) this PR fixes (optional, using
fixes #<issue number>(, fixes #<issue_number>, ...)
format, will close the issue(s) when the PR gets merged):Fixes #929
Special notes for your reviewer:
Built on top of
#926
#916
The last commit is the relevant one, namely with match.go / match_test.go files.
This assumes that the Match structure will need to be changed according to https://github.com/open-policy-agent/gatekeeper/pull/916/files#r516071473