- 
                Notifications
    You must be signed in to change notification settings 
- Fork 1.2k
⚠️ Generic Validator and Defaulter #3360
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
Conversation
| } | ||
| blder.apiType = apiType | ||
| return blder | ||
| func WebhookManagedBy[T runtime.Object](m manager.Manager, object T) *WebhookBuilder[T] { | 
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.
So I've spent a fair bit of time on pondering about how to best deal with this in the webhook builder:
- Initially, I didn't have the object Tfunc arg and used the existingWithValidatorandWithDefaultermethods. That works but requires everyone to explicitly typeWebhookManagedByas the typing must be know during initial construction and can not be inferred during subsequent method calls. This has two drawbacks IMHO:- I anticipate that to cause confusion, because my impression has been that many go engineers are not very used to explicitly typing generics as opposed to relying on type inference
- Anyone who has an existing CustomValidator/Defaulterwould have to type this toruntime.Objectwhich would likely cause further confusion
 
- So then I added a WebhookForthat has the same signature as the currentWebhookMangagedByand made theWebhookManagedBynon-generic and return a*WebhookBuilder[runtime.Object]. This is great for existing code as it will all keep working, but once we remove this, it will be confusing to have different names for the controller and webhook builder IMHO
- Then I finally ended up with this, make WebhookManagedBygeneric, add an explicit type argument so type inference works and add successors toWithValidator/Defaulterin the form ofWithAdmissionValidator/Defaulter. This means a breaking change for everyone that should be pretty easy to understand and fix and avoid requiring to type this toruntime.Objectfor existing validators/defaulters. The main drawback of that is that the new names aren't as nice (happy to hear suggestions for that).
All in all, the last option seemed the by far least bad one. What do you think?
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.
Agree with all your points.
The main drawback of that is that the new names aren't as nice (happy to hear suggestions for that).
I see the following options
- Go with your current names, keep them like that going forward eventually drop WithValidator/Defaulter
- 1 + but eventually do another round of deprecation to go from WithAdmissionValidator/Defaulter to WithValidator/Defaulter
- Directly go to WithValidator/Defaulter, temporarily introduce deprecated WithCustomValidator/Defaulter
No absolutely strong opinions from my side, but if possible I would like to get to WithValidator/Defaulter long-term. I have a slight tendency for option 3. We already have to do a breaking change in this PR, maybe it's better to just get it over with and do slightly more breaking changes now then dragging this out over a few years. It will also give a clear hint to folks that they should just migrate to the typed versions which is super straightforward then (just start using types in Validator/Defaulter, it's not even necessary to use different methods on the builder for Validator/Defaulter). So slightly less effort to do the right migration (use types), slightly more effort to delay the migration and keep using CustomValidator/Defaulter.
Somewhat related. Do you know why Defaulter is spelled with er and Validator with or? (probably don't want to change that though because it's not worth the additional confusion)
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.
Okay, if we say that we want to end up with WithValidator/Defaulter then option 3 makes most sense, otherwise its just a back and forth. I guess we can add a codesnippet before/after to the changelog to make that at least easy
Somewhat related. Do you know why Defaulter is spelled with er and Validator with or? (probably don't want to change that though because it's not worth the additional confusion)
That is just the English language, one has an er suffix and the other or
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.
Okay, if we say that we want to end up with WithValidator/Defaulter then option 3 makes most sense, otherwise its just a back and forth. I guess we can add a codesnippet before/after to the changelog to make that at least easy
Agree, sounds good
| /cc @sbueringer | 
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 a few minor findings
|  | ||
| var _ admission.CustomValidator = &TestCustomValidator{} | ||
|  | ||
| type testValidatorDefaulter struct{} | 
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.
Do we intentionally have two structs here that both are using TestCustomDefaultValidator internally?
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.
Yeah, because one of them is a Validator and the other a CustomValidator but I wanted to avoid implementing this twice, hence one is just a shim over the other.
The tests here also define their own runtime.Object which I guess is from back when these where methods on that. There isn't a good reason to do that at this point vs just using any built-in type, but the diff of this PR is already quite large so I will probably clean this up in a follow-up.
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.
Sorry I was a bit unclear.
I meant do we need testValidatorDefaulter and testDefaultValidatorValidator
(First one implements only Default, second one Validate*)
The name of the second one is also a bit strange
In any case, fine to clean up in a follow-up
| @alvaroaleman: The following test failed, say  
 Full PR test history. Your PR dashboard. Please help us cut down on flakes by linking to an open issue when you hit one in your PR. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here. | 
| Thank you very much!!! /lgtm | 
| LGTM label has been added. Git tree hash: a30fb81d8a79301f79c37ce8474d6d78ccede2ba | 
| [APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: alvaroaleman, sbueringer The full list of commands accepted by this bot can be found here. The pull request process is described here 
Needs approval from an approver in each of these files:
 
 Approvers can indicate their approval by writing  | 
This change adds the
ValidatorandDefaulterinterfaces which are generic versions ofCustomValidatorandCustomDefaulter. The existingCusotmDefaulterandCustomValidatorare being deprecated.Fixes #2675
/hold
This is missing tests, I will add them once we agree on the direction in #3360 (comment)