-
Notifications
You must be signed in to change notification settings - Fork 102
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
Introduce validating admission webhook (experimental) #1133
Conversation
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.
missing docs on setting up the cert manager
also... where is the link to the sequence diagram... super useful!
This is fantastic work!!! Really great. My request for change is really around some small nits and some addressing of the future of additional webhooks.
os.Exit(1) | ||
} | ||
} | ||
|
||
// Start the Cmd | ||
log.Info("Starting the Cmd.") |
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'm curious why you changed CRD installation messages to past tense and after the event... and left all the manager manages as logs prior to the event?
also seems like something that should have been on separate pr.
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.
hmm which messages? I don't see any change on this line
pkg/kudoctl/cmd/init.go
Outdated
@@ -98,6 +99,7 @@ func newInitCmd(fs afero.Fs, out io.Writer) *cobra.Command { | |||
f.BoolVar(&i.crdOnly, "crd-only", false, "Add only KUDO CRDs to your cluster") | |||
f.BoolVarP(&i.wait, "wait", "w", false, "Block until KUDO manager is running and ready to receive requests") | |||
f.Int64Var(&i.timeout, "wait-timeout", 300, "Wait timeout to be used") | |||
f.BoolVar(&i.enableValidation, "enable-validation", false, "When set to true, validation webhook will be deployed alongside KUDO controller") |
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.
as we discussed... I think this should be more clear and likely more granular... perhaps --web-hooks=InstanceValidator
with a comma separated list... and perhaps --web-hooks=All
for convince.
Not a blocker for me.. just think we will have to address this at some point.
@@ -149,6 +151,14 @@ func (initCmd *initCmd) run() error { | |||
} | |||
mans = append(mans, prereq...) | |||
|
|||
if opts.EnableValidation { | |||
prereq, err := cmdInit.WebhookManifests(opts.Namespace) |
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.
WebhookManifests
likely needs to passed a options with a slice... or another parameter of slice of options.
|
||
func installAdmissionWebhook(client clientv1beta1.ValidatingWebhookConfigurationsGetter, webhook v1beta1.ValidatingWebhookConfiguration) error { | ||
_, err := client.ValidatingWebhookConfigurations().Create(&webhook) | ||
if kerrors.IsAlreadyExists(err) { |
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.
In this case, should we Get the webhook configuration and deep-compare if it matches the expected configuration? Thinking about changes in the webhook, for example when we want to validate operatorVersions
in addition to instances
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 along the lines we handle all other resources right now. If we want to change it, I would do it for all and in another PR... but in general I agree :)
Co-Authored-By: Ken Sipe <[email protected]>
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 left a few nits around naming and what not. The only reason to request changes is explained here.
cmd/manager/main.go
Outdated
if err != nil { | ||
return err | ||
} | ||
validator, isValidator := obj.(kudo.Validator) |
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: these variable are called ok
by convention
validator, isValidator := obj.(kudo.Validator) | |
validator, ok := obj.(kudo.Validator) |
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 guess this method is adopted from the controller-runtime but since we're the one calling it, you could pass kudo.Validatior
directly and avoid the casting?
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 I need runtime.object here to be able to get GVK
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.
it's ok
then ;)
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.
Right right, it's ok now... 😝
log.Infof("skip registering a validating webhook, admission.Validator interface is not implemented", "GVK", gvk) | ||
return nil | ||
} | ||
vwh := kudo.ValidatingWebhookFor(validator) |
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 multiple hook kinds (mutating, conversion) and the fact that Go doesn't allow you to overload functions, you probably want to have that in name.
} | ||
vwh := kudo.ValidatingWebhookFor(validator) | ||
if vwh != nil { | ||
path := generateValidatePath(gvk) |
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.
All of that is adopted from the controller-runtime. It might not be ideal but I'd rather keep it this way: easier to bump once cr changes things.
@@ -277,6 +277,7 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw | |||
github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= | |||
github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= | |||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | |||
github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= |
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.
No reason to introduce another logger, I guess?
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 are a few minor changes I would still prefer to see... but I'm ok even without.
nice work!
pkg/kudoctl/cmd/init.go
Outdated
@@ -98,6 +99,7 @@ func newInitCmd(fs afero.Fs, out io.Writer) *cobra.Command { | |||
f.BoolVar(&i.crdOnly, "crd-only", false, "Add only KUDO CRDs to your cluster") | |||
f.BoolVarP(&i.wait, "wait", "w", false, "Block until KUDO manager is running and ready to receive requests") | |||
f.Int64Var(&i.timeout, "wait-timeout", 300, "Wait timeout to be used") | |||
f.StringVar(&i.webhooks, "webhook", "", "List of webhooks exposed, when empty, no webhook server will be started (the only webhook right now is InstanceValidation)") |
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.
f.StringVar(&i.webhooks, "webhook", "", "List of webhooks exposed, when empty, no webhook server will be started (the only webhook right now is InstanceValidation)") | |
f.StringVar(&i.webhooks, "webhook", "", "List of webhooks to install separated by commas") |
"list of webhooks exposed" isn't phrased corrected. "to be exposed" is closer. It is odd to add the "(...)" to a cli output or to specify limitations that will need to be edited and hopefully not forgotten.
The info I expect a user to be concerned with... is... is it the name of the class? does it include the package name? where can I find the mapping of strings -> webhooks.
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.
hmm I really wanted to help the user to know what to do here because if you know what are the supported options you have to go to the docs or code (?) and that's not very nice experience. I think the CLI should help you do this right. I rephrased it a bit.
Yes we will need to update it with every new webhook but this is the best documentation we have and the best documentation we can get to the user so I think we should be fine with it and just really take care of this docs and keep it up to date. We won't certainly add new webhook every week...
pkg/kudoctl/cmd/init.go
Outdated
@@ -118,13 +120,16 @@ func (initCmd *initCmd) validate(flags *flag.FlagSet) error { | |||
if flags.Changed("wait-timeout") && !initCmd.wait { | |||
return errors.New("wait-timeout is only useful when using the flag '--wait'") | |||
} | |||
if initCmd.webhooks != "" && initCmd.webhooks != "InstanceValidation" { | |||
return errors.New("webhooks can be only empty or contain a single string 'InstanceValidation'. No other webhooks supported right now") |
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.
again... I know we are looking to land this and it is limited to 1 WH... but we know we will add more. Couldn't we have a map of webhooks which contains 1 currently and have some infra code here that doesn't need to change as we add more in?
As far as the error message is concerned... certainly "no other webhooks are supported" should be the last sentence... "right now" is implied.
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 find that premature optimization - I don't see the advantage of writing it now rather then later :) it's the same job and later we'll have more information because we'll really be at the point when adding new webhook and having multiple. And we'll need to change this code anyway otherwise the validation would be failing. Whether it should be map or slice, I would prefer to leave that decision for later, when we really need to maintain multiple. I choose the easiest option for now
I removed the right now though, 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.
We should mention it somewhere that running plans are not interruptable anymore.
What this PR does / why we need it:
Please start reviewing by reading the user-facing documentation and reviewing also that kudobuilder/kudo.dev#110
Fixes #883
There are no integration tests (this is not possible to test via these) and no e2e tests right now. As this is experimental feature it's "OK" like that, but any suggestions in that space are appreciated, basically for that to be able to be test via current setup we would need pre-install cert-manager into kind cluster and start kudo with webhook (as harness takes care of starting kudo).
Also this is known as minimal implementation, all the following steps have been identified in these github issues component/webhook