From 7d351ba25eecff1ad38e85f38b948e6109e48637 Mon Sep 17 00:00:00 2001 From: Mikko Ylinen Date: Tue, 26 Jul 2022 13:17:25 +0300 Subject: [PATCH] pkg/webhook: add support for reinvocationPolicy marker Mutating webhooks using controller-gen markers for generating MutatingWebhookConfigration cannot control reinvocationPolicy. This field must always be added manually afterwards should the webhook need to set its value. Add support for reinvocationPolicy marker for Mutating Webhooks. Signed-off-by: Mikko Ylinen --- pkg/webhook/parser.go | 27 ++++++++++++++++++++++- pkg/webhook/testdata/manifests.yaml | 1 + pkg/webhook/testdata/valid/manifests.yaml | 1 + pkg/webhook/testdata/valid/webhook.go | 2 +- pkg/webhook/testdata/webhook.go | 2 +- pkg/webhook/zz_generated.markerhelp.go | 4 ++++ 6 files changed, 34 insertions(+), 3 deletions(-) diff --git a/pkg/webhook/parser.go b/pkg/webhook/parser.go index 392acfc77..0b4af49af 100644 --- a/pkg/webhook/parser.go +++ b/pkg/webhook/parser.go @@ -19,7 +19,7 @@ limitations under the License. // // The markers take the form: // -// +kubebuilder:webhook:webhookVersions=<[]string>,failurePolicy=,matchPolicy=,groups=<[]string>,resources=<[]string>,verbs=<[]string>,versions=<[]string>,name=,path=,mutating=,sideEffects=,admissionReviewVersions=<[]string> +// +kubebuilder:webhook:webhookVersions=<[]string>,failurePolicy=,matchPolicy=,groups=<[]string>,resources=<[]string>,verbs=<[]string>,versions=<[]string>,name=,path=,mutating=,sideEffects=,admissionReviewVersions=<[]string>,reinvocationPolicy= package webhook import ( @@ -111,6 +111,14 @@ type Config struct { // AdmissionReviewVersions is an ordered list of preferred `AdmissionReview` // versions the Webhook expects. AdmissionReviewVersions []string `marker:"admissionReviewVersions"` + + // ReinvocationPolicy allows mutating webhooks to request reinvocation after other mutations + // + // To allow mutating admission plugins to observe changes made by other plugins, + // built-in mutating admission plugins are re-run if a mutating webhook modifies + // an object, and mutating webhooks can specify a reinvocationPolicy to control + // whether they are reinvoked as well. + ReinvocationPolicy string `marker:"reinvocationPolicy,optional"` } // verbToAPIVariant converts a marker's verb to the proper value for the API. @@ -151,6 +159,7 @@ func (c Config) ToMutatingWebhook() (admissionregv1.MutatingWebhook, error) { ClientConfig: c.clientConfig(), SideEffects: c.sideEffects(), AdmissionReviewVersions: c.AdmissionReviewVersions, + ReinvocationPolicy: c.reinvocationPolicy(), }, nil } @@ -263,6 +272,22 @@ func (c Config) sideEffects() *admissionregv1.SideEffectClass { return &sideEffects } +// reinvocationPolicy returns the reinvocationPolicy config for a webhook. +func (c Config) reinvocationPolicy() *admissionregv1.ReinvocationPolicyType { + var reinvocationPolicy admissionregv1.ReinvocationPolicyType + switch strings.ToLower(c.ReinvocationPolicy) { + case strings.ToLower(string(admissionregv1.NeverReinvocationPolicy)): + reinvocationPolicy = admissionregv1.NeverReinvocationPolicy + case strings.ToLower(string(admissionregv1.IfNeededReinvocationPolicy)): + reinvocationPolicy = admissionregv1.IfNeededReinvocationPolicy + case "": + return nil + default: + return nil + } + return &reinvocationPolicy +} + // webhookVersions returns the target API versions of the {Mutating,Validating}WebhookConfiguration objects for a webhook. func (c Config) webhookVersions() ([]string, error) { // If WebhookVersions is not specified, we default it to `v1`. diff --git a/pkg/webhook/testdata/manifests.yaml b/pkg/webhook/testdata/manifests.yaml index 059794d6d..ab4fdc85f 100644 --- a/pkg/webhook/testdata/manifests.yaml +++ b/pkg/webhook/testdata/manifests.yaml @@ -16,6 +16,7 @@ webhooks: failurePolicy: Fail matchPolicy: Equivalent name: default.cronjob.testdata.kubebuilder.io + reinvocationPolicy: Never rules: - apiGroups: - testdata.kubebuiler.io diff --git a/pkg/webhook/testdata/valid/manifests.yaml b/pkg/webhook/testdata/valid/manifests.yaml index 059794d6d..ce3836ddd 100644 --- a/pkg/webhook/testdata/valid/manifests.yaml +++ b/pkg/webhook/testdata/valid/manifests.yaml @@ -27,6 +27,7 @@ webhooks: resources: - cronjobs sideEffects: None + reinvocationPolicy: IfNeeded --- apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingWebhookConfiguration diff --git a/pkg/webhook/testdata/valid/webhook.go b/pkg/webhook/testdata/valid/webhook.go index d964c493a..2ea3c31d2 100644 --- a/pkg/webhook/testdata/valid/webhook.go +++ b/pkg/webhook/testdata/valid/webhook.go @@ -29,7 +29,7 @@ func (c *CronJob) SetupWebhookWithManager(mgr ctrl.Manager) error { // +kubebuilder:webhook:webhookVersions=v1,verbs=create;update,path=/validate-testdata-kubebuilder-io-v1-cronjob,mutating=false,failurePolicy=fail,matchPolicy=Equivalent,groups=testdata.kubebuiler.io,resources=cronjobs,versions=v1,name=validation.cronjob.testdata.kubebuilder.io,sideEffects=None,admissionReviewVersions=v1;v1beta1 // +kubebuilder:webhook:verbs=create;update,path=/validate-testdata-kubebuilder-io-v1-cronjob,mutating=false,failurePolicy=fail,matchPolicy=Equivalent,groups=testdata.kubebuiler.io,resources=cronjobs,versions=v1,name=validation.cronjob.testdata.kubebuilder.io,sideEffects=NoneOnDryRun,admissionReviewVersions=v1;v1beta1 -// +kubebuilder:webhook:webhookVersions=v1,verbs=create;update,path=/mutate-testdata-kubebuilder-io-v1-cronjob,mutating=true,failurePolicy=fail,matchPolicy=Equivalent,groups=testdata.kubebuiler.io,resources=cronjobs,versions=v1,name=default.cronjob.testdata.kubebuilder.io,sideEffects=None,admissionReviewVersions=v1;v1beta1 +// +kubebuilder:webhook:webhookVersions=v1,verbs=create;update,path=/mutate-testdata-kubebuilder-io-v1-cronjob,mutating=true,failurePolicy=fail,matchPolicy=Equivalent,groups=testdata.kubebuiler.io,resources=cronjobs,versions=v1,name=default.cronjob.testdata.kubebuilder.io,sideEffects=None,admissionReviewVersions=v1;v1beta1,reinvocationPolicy=IfNeeded var _ webhook.Defaulter = &CronJob{} var _ webhook.Validator = &CronJob{} diff --git a/pkg/webhook/testdata/webhook.go b/pkg/webhook/testdata/webhook.go index d964c493a..41a69d706 100644 --- a/pkg/webhook/testdata/webhook.go +++ b/pkg/webhook/testdata/webhook.go @@ -29,7 +29,7 @@ func (c *CronJob) SetupWebhookWithManager(mgr ctrl.Manager) error { // +kubebuilder:webhook:webhookVersions=v1,verbs=create;update,path=/validate-testdata-kubebuilder-io-v1-cronjob,mutating=false,failurePolicy=fail,matchPolicy=Equivalent,groups=testdata.kubebuiler.io,resources=cronjobs,versions=v1,name=validation.cronjob.testdata.kubebuilder.io,sideEffects=None,admissionReviewVersions=v1;v1beta1 // +kubebuilder:webhook:verbs=create;update,path=/validate-testdata-kubebuilder-io-v1-cronjob,mutating=false,failurePolicy=fail,matchPolicy=Equivalent,groups=testdata.kubebuiler.io,resources=cronjobs,versions=v1,name=validation.cronjob.testdata.kubebuilder.io,sideEffects=NoneOnDryRun,admissionReviewVersions=v1;v1beta1 -// +kubebuilder:webhook:webhookVersions=v1,verbs=create;update,path=/mutate-testdata-kubebuilder-io-v1-cronjob,mutating=true,failurePolicy=fail,matchPolicy=Equivalent,groups=testdata.kubebuiler.io,resources=cronjobs,versions=v1,name=default.cronjob.testdata.kubebuilder.io,sideEffects=None,admissionReviewVersions=v1;v1beta1 +// +kubebuilder:webhook:webhookVersions=v1,verbs=create;update,path=/mutate-testdata-kubebuilder-io-v1-cronjob,mutating=true,failurePolicy=fail,matchPolicy=Equivalent,groups=testdata.kubebuiler.io,resources=cronjobs,versions=v1,name=default.cronjob.testdata.kubebuilder.io,sideEffects=None,admissionReviewVersions=v1;v1beta1,reinvocationPolicy=Never var _ webhook.Defaulter = &CronJob{} var _ webhook.Validator = &CronJob{} diff --git a/pkg/webhook/zz_generated.markerhelp.go b/pkg/webhook/zz_generated.markerhelp.go index 2a34608e8..411c58e17 100644 --- a/pkg/webhook/zz_generated.markerhelp.go +++ b/pkg/webhook/zz_generated.markerhelp.go @@ -81,6 +81,10 @@ func (Config) Help() *markers.DefinitionHelp { Summary: "is an ordered list of preferred `AdmissionReview` versions the Webhook expects.", Details: "", }, + "ReinvocationPolicy": { + Summary: "allows mutating webhooks to request reinvocation after other mutations ", + Details: "To allow mutating admission plugins to observe changes made by other plugins, built-in mutating admission plugins are re-run if a mutating webhook modifies an object, and mutating webhooks can specify a reinvocationPolicy to control whether they are reinvoked as well.", + }, }, } }