Skip to content
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

Merged
merged 19 commits into from
Dec 6, 2019
Merged

Conversation

alenkacz
Copy link
Contributor

@alenkacz alenkacz commented Dec 3, 2019

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

Copy link
Member

@kensipe kensipe left a 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.

Makefile Show resolved Hide resolved
cmd/manager/main.go Outdated Show resolved Hide resolved
cmd/manager/main.go Outdated Show resolved Hide resolved
cmd/manager/main.go Outdated Show resolved Hide resolved
os.Exit(1)
}
}

// Start the Cmd
log.Info("Starting the Cmd.")
Copy link
Member

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.

Copy link
Contributor Author

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/apis/kudo/v1beta1/instance_validator.go Show resolved Hide resolved
@@ -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")
Copy link
Member

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)
Copy link
Member

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.

pkg/kudoctl/cmd/init/webhook.go Outdated Show resolved Hide resolved
pkg/kudoctl/cmd/init/webhook.go Show resolved Hide resolved

func installAdmissionWebhook(client clientv1beta1.ValidatingWebhookConfigurationsGetter, webhook v1beta1.ValidatingWebhookConfiguration) error {
_, err := client.ValidatingWebhookConfigurations().Create(&webhook)
if kerrors.IsAlreadyExists(err) {
Copy link
Member

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

Copy link
Contributor Author

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 :)

alenkacz and others added 2 commits December 4, 2019 16:02
Co-Authored-By: Ken Sipe <kensipe@gmail.com>
Copy link
Contributor

@zen-dog zen-dog left a 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.

if err != nil {
return err
}
validator, isValidator := obj.(kudo.Validator)
Copy link
Contributor

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

Suggested change
validator, isValidator := obj.(kudo.Validator)
validator, ok := obj.(kudo.Validator)

Copy link
Contributor

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?

Copy link
Contributor Author

@alenkacz alenkacz Dec 4, 2019

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

Copy link
Contributor

@zen-dog zen-dog Dec 4, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's ok then ;)

Copy link
Contributor Author

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)
Copy link
Contributor

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.

cmd/manager/main.go Show resolved Hide resolved
}
vwh := kudo.ValidatingWebhookFor(validator)
if vwh != nil {
path := generateValidatePath(gvk)
Copy link
Contributor

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=
Copy link
Contributor

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?

pkg/apis/kudo/v1beta1/instance_validator.go Show resolved Hide resolved
pkg/kudoctl/cmd/init/webhook.go Outdated Show resolved Hide resolved
pkg/kudoctl/cmd/init/webhook.go Outdated Show resolved Hide resolved
pkg/kudoctl/cmd/init/webhook.go Outdated Show resolved Hide resolved
pkg/kudoctl/cmd/init/webhook.go Outdated Show resolved Hide resolved
cmd/manager/main.go Outdated Show resolved Hide resolved
Copy link
Member

@kensipe kensipe left a 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!

@@ -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)")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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.

Copy link
Contributor Author

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...

@@ -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")
Copy link
Member

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.

Copy link
Contributor Author

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

go.mod Show resolved Hide resolved
Copy link
Contributor

@zen-dog zen-dog left a 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.

@alenkacz alenkacz merged commit da27754 into master Dec 6, 2019
@alenkacz alenkacz deleted the av/webhook branch December 6, 2019 17:29
@porridge porridge added release/highlight This PR is a highlight for the next release and removed release-highlight labels Mar 4, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
release/highlight This PR is a highlight for the next release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Admission webhook for instance CRD
6 participants