From 767d0db885833c457f933b5b39206d9cf32f160d Mon Sep 17 00:00:00 2001 From: Camila Macedo <7708031+camilamacedo86@users.noreply.github.com> Date: Sun, 2 Nov 2025 13:56:48 +0000 Subject: [PATCH] Add support for custom webhook paths Users can now set custom paths for webhooks using --defaulting-path and --validation-path flags. Requires controller-runtime v0.20+. Assisted-by: Cursor --- .../internal/webhook/v1/cronjob_webhook.go | 2 + .../webhook-implementation.md | 27 +- .../src/multiversion-tutorial/conversion.md | 10 + .../internal/webhook/v1/cronjob_webhook.go | 2 + .../internal/webhook/v2/cronjob_webhook.go | 3 +- docs/book/src/reference/admission-webhook.md | 31 +++ .../cronjob-tutorial/generate_cronjob.go | 7 +- .../webhook_implementation.go | 4 +- pkg/cli/alpha/internal/generate.go | 7 + pkg/model/resource/webhooks.go | 21 +- pkg/plugins/golang/options.go | 12 + .../internal/templates/webhooks/webhook.go | 19 +- pkg/plugins/golang/v4/webhook.go | 29 ++ test/e2e/v4/generate_test.go | 64 +++++ test/e2e/v4/plugin_cluster_test.go | 4 + test/testdata/generate.sh | 7 +- .../webhook/apps/v1/deployment_webhook.go | 3 +- .../internal/webhook/core/v1/pod_webhook.go | 3 +- .../webhook/crew/v1/captain_webhook.go | 3 +- .../example.com/v1alpha1/memcached_webhook.go | 3 +- .../webhook/ship/v2alpha1/cruiser_webhook.go | 3 +- .../webhook/v1alpha1/memcached_webhook.go | 3 +- testdata/project-v4/PROJECT | 17 ++ testdata/project-v4/api/v1/sailor_types.go | 92 +++++++ .../api/v1/zz_generated.deepcopy.go | 101 +++++++ testdata/project-v4/cmd/main.go | 14 + .../bases/crew.testproject.org_sailors.yaml | 126 +++++++++ .../project-v4/config/crd/kustomization.yaml | 1 + .../project-v4/config/rbac/kustomization.yaml | 3 + testdata/project-v4/config/rbac/role.yaml | 3 + .../config/rbac/sailor_admin_role.yaml | 27 ++ .../config/rbac/sailor_editor_role.yaml | 33 +++ .../config/rbac/sailor_viewer_role.yaml | 29 ++ .../config/samples/crew_v1_sailor.yaml | 9 + .../config/samples/kustomization.yaml | 1 + .../project-v4/config/webhook/manifests.yaml | 60 ++++ testdata/project-v4/dist/install.yaml | 260 ++++++++++++++++++ .../internal/controller/sailor_controller.go | 63 +++++ .../controller/sailor_controller_test.go | 84 ++++++ .../internal/webhook/v1/admiral_webhook.go | 57 ++++ .../webhook/v1/admiral_webhook_test.go | 26 ++ .../internal/webhook/v1/captain_webhook.go | 3 +- .../internal/webhook/v1/deployment_webhook.go | 3 +- .../internal/webhook/v1/sailor_webhook.go | 127 +++++++++ .../webhook/v1/sailor_webhook_test.go | 87 ++++++ .../internal/webhook/v1/webhook_suite_test.go | 3 + 46 files changed, 1466 insertions(+), 30 deletions(-) create mode 100644 testdata/project-v4/api/v1/sailor_types.go create mode 100644 testdata/project-v4/config/crd/bases/crew.testproject.org_sailors.yaml create mode 100644 testdata/project-v4/config/rbac/sailor_admin_role.yaml create mode 100644 testdata/project-v4/config/rbac/sailor_editor_role.yaml create mode 100644 testdata/project-v4/config/rbac/sailor_viewer_role.yaml create mode 100644 testdata/project-v4/config/samples/crew_v1_sailor.yaml create mode 100644 testdata/project-v4/internal/controller/sailor_controller.go create mode 100644 testdata/project-v4/internal/controller/sailor_controller_test.go create mode 100644 testdata/project-v4/internal/webhook/v1/sailor_webhook.go create mode 100644 testdata/project-v4/internal/webhook/v1/sailor_webhook_test.go diff --git a/docs/book/src/cronjob-tutorial/testdata/project/internal/webhook/v1/cronjob_webhook.go b/docs/book/src/cronjob-tutorial/testdata/project/internal/webhook/v1/cronjob_webhook.go index 1f58ce66db3..f923176b2e3 100644 --- a/docs/book/src/cronjob-tutorial/testdata/project/internal/webhook/v1/cronjob_webhook.go +++ b/docs/book/src/cronjob-tutorial/testdata/project/internal/webhook/v1/cronjob_webhook.go @@ -155,6 +155,8 @@ validate anything on deletion. /* This marker is responsible for generating a validation webhook manifest. */ + +// NOTE: If you want to customise the 'path', use the flags '--defaulting-path' or '--validation-path'. // +kubebuilder:webhook:path=/validate-batch-tutorial-kubebuilder-io-v1-cronjob,mutating=false,failurePolicy=fail,sideEffects=None,groups=batch.tutorial.kubebuilder.io,resources=cronjobs,verbs=create;update,versions=v1,name=vcronjob-v1.kb.io,admissionReviewVersions=v1 // CronJobCustomValidator struct is responsible for validating the CronJob resource diff --git a/docs/book/src/cronjob-tutorial/webhook-implementation.md b/docs/book/src/cronjob-tutorial/webhook-implementation.md index 423f27f73b1..ea4b4375a42 100644 --- a/docs/book/src/cronjob-tutorial/webhook-implementation.md +++ b/docs/book/src/cronjob-tutorial/webhook-implementation.md @@ -11,7 +11,7 @@ Kubebuilder takes care of the rest for you, such as 1. Creating handlers for your webhooks. 1. Registering each handler with a path in your server. -First, let's scaffold the webhooks for our CRD (CronJob). We’ll need to run the following command with the `--defaulting` and `--programmatic-validation` flags (since our test project will use defaulting and validating webhooks): +First, let's scaffold the webhooks for our CRD (CronJob). We'll need to run the following command with the `--defaulting` and `--programmatic-validation` flags (since our test project will use defaulting and validating webhooks): ```bash kubebuilder create webhook --group batch --version v1 --kind CronJob --defaulting --programmatic-validation @@ -19,4 +19,29 @@ kubebuilder create webhook --group batch --version v1 --kind CronJob --defaultin This will scaffold the webhook functions and register your webhook with the manager in your `main.go` for you. +## Custom Webhook Paths + +You can specify custom HTTP paths for your webhooks using the `--defaulting-path` and `--validation-path` flags: + +```bash +# Custom path for defaulting webhook +kubebuilder create webhook --group batch --version v1 --kind CronJob --defaulting --defaulting-path=/my-custom-mutate-path + +# Custom path for validation webhook +kubebuilder create webhook --group batch --version v1 --kind CronJob --programmatic-validation --validation-path=/my-custom-validate-path + +# Both webhooks with different custom paths +kubebuilder create webhook --group batch --version v1 --kind CronJob --defaulting --programmatic-validation \ + --defaulting-path=/custom-mutate --validation-path=/custom-validate +``` + +This changes the path in the webhook marker annotation but does not change where the webhook files are scaffolded. The webhook files will still be created in `internal/webhook/v1/`. + + + {{#literatego ./testdata/project/internal/webhook/v1/cronjob_webhook.go}} diff --git a/docs/book/src/multiversion-tutorial/conversion.md b/docs/book/src/multiversion-tutorial/conversion.md index 39b37a907b2..4166992e419 100644 --- a/docs/book/src/multiversion-tutorial/conversion.md +++ b/docs/book/src/multiversion-tutorial/conversion.md @@ -13,6 +13,16 @@ The above command will generate the `cronjob_conversion.go` next to our `cronjob_types.go` file, to avoid cluttering up our main types file with extra functions. + + ## Hub... First, we'll implement the hub. We'll choose the v1 version as the hub: diff --git a/docs/book/src/multiversion-tutorial/testdata/project/internal/webhook/v1/cronjob_webhook.go b/docs/book/src/multiversion-tutorial/testdata/project/internal/webhook/v1/cronjob_webhook.go index 2a076ab4f23..7f5224e5581 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/internal/webhook/v1/cronjob_webhook.go +++ b/docs/book/src/multiversion-tutorial/testdata/project/internal/webhook/v1/cronjob_webhook.go @@ -160,6 +160,8 @@ validate anything on deletion. /* This marker is responsible for generating a validation webhook manifest. */ + +// NOTE: If you want to customise the 'path', use the flags '--defaulting-path' or '--validation-path'. // +kubebuilder:webhook:path=/validate-batch-tutorial-kubebuilder-io-v1-cronjob,mutating=false,failurePolicy=fail,sideEffects=None,groups=batch.tutorial.kubebuilder.io,resources=cronjobs,verbs=create;update,versions=v1,name=vcronjob-v1.kb.io,admissionReviewVersions=v1 // CronJobCustomValidator struct is responsible for validating the CronJob resource diff --git a/docs/book/src/multiversion-tutorial/testdata/project/internal/webhook/v2/cronjob_webhook.go b/docs/book/src/multiversion-tutorial/testdata/project/internal/webhook/v2/cronjob_webhook.go index ab1d46b2f79..9d6e3d48d71 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/internal/webhook/v2/cronjob_webhook.go +++ b/docs/book/src/multiversion-tutorial/testdata/project/internal/webhook/v2/cronjob_webhook.go @@ -88,8 +88,7 @@ func (d *CronJobCustomDefaulter) Default(_ context.Context, obj runtime.Object) } // TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation. -// NOTE: The 'path' attribute must follow a specific pattern and should not be modified directly here. -// Modifying the path for an invalid path can cause API server errors; failing to locate the webhook. +// NOTE: If you want to customise the 'path', use the flags '--defaulting-path' or '--validation-path'. // +kubebuilder:webhook:path=/validate-batch-tutorial-kubebuilder-io-v2-cronjob,mutating=false,failurePolicy=fail,sideEffects=None,groups=batch.tutorial.kubebuilder.io,resources=cronjobs,verbs=create;update,versions=v2,name=vcronjob-v2.kb.io,admissionReviewVersions=v1 // CronJobCustomValidator struct is responsible for validating the CronJob resource diff --git a/docs/book/src/reference/admission-webhook.md b/docs/book/src/reference/admission-webhook.md index f37e4d47bc3..222d49f7437 100644 --- a/docs/book/src/reference/admission-webhook.md +++ b/docs/book/src/reference/admission-webhook.md @@ -30,6 +30,37 @@ object after your validation has accepted it. +## Custom Webhook Paths + +By default, Kubebuilder generates webhook paths based on the resource's group, version, and kind. For example: +- Mutating webhook for `batch/v1/CronJob`: `/mutate-batch-v1-cronjob` +- Validating webhook for `batch/v1/CronJob`: `/validate-batch-v1-cronjob` + +You can specify custom paths for webhooks using dedicated flags: + +```bash +# Custom path for defaulting webhook +kubebuilder create webhook --group batch --version v1 --kind CronJob \ + --defaulting --defaulting-path=/my-custom-mutate-path + +# Custom path for validation webhook +kubebuilder create webhook --group batch --version v1 --kind CronJob \ + --programmatic-validation --validation-path=/my-custom-validate-path + +# Both webhooks with different custom paths +kubebuilder create webhook --group batch --version v1 --kind CronJob \ + --defaulting --programmatic-validation \ + --defaulting-path=/custom-mutate --validation-path=/custom-validate +``` + + + + ## Handling Resource Status in Admission Webhooks