Skip to content

Commit 1006456

Browse files
committed
feat: allow customizing generated webhook's name
closes #865
1 parent b07ad66 commit 1006456

File tree

2 files changed

+117
-9
lines changed

2 files changed

+117
-9
lines changed

pkg/webhook/parser.go

+97-9
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import (
3131
"k8s.io/apimachinery/pkg/runtime/schema"
3232
"k8s.io/apimachinery/pkg/util/sets"
3333

34+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3435
"sigs.k8s.io/controller-tools/pkg/genall"
3536
"sigs.k8s.io/controller-tools/pkg/markers"
3637
)
@@ -42,16 +43,31 @@ const (
4243
)
4344

4445
var (
45-
// ConfigDefinition s a marker for defining Webhook manifests.
46+
// ConfigDefinition is a marker for defining Webhook manifests.
4647
// Call ToWebhook on the value to get a Kubernetes Webhook.
4748
ConfigDefinition = markers.Must(markers.MakeDefinition("kubebuilder:webhook", markers.DescribesPackage, Config{}))
49+
// WebhookConfigDefinition is a marker for defining MutatingWebhookConfiguration or ValidatingWebhookConfiguration manifests.
50+
WebhookConfigDefinition = markers.Must(markers.MakeDefinition("kubebuilder:webhookconfiguration", markers.DescribesPackage, WebhookConfig{}))
4851
)
4952

5053
// supportedWebhookVersions returns currently supported API version of {Mutating,Validating}WebhookConfiguration.
5154
func supportedWebhookVersions() []string {
5255
return []string{defaultWebhookVersion}
5356
}
5457

58+
// +controllertools:marker:generateHelp
59+
60+
type WebhookConfig struct {
61+
// Mutating marks this as a mutating webhook (it's validating only if false)
62+
//
63+
// Mutating webhooks are allowed to change the object in their response,
64+
// and are called *before* all validating webhooks. Mutating webhooks may
65+
// choose to reject an object, similarly to a validating webhook.
66+
Mutating bool
67+
// Name indicates the name of the K8s MutatingWebhookConfiguration or ValidatingWebhookConfiguration object.
68+
Name string `marker:"name,optional"`
69+
}
70+
5571
// +controllertools:marker:generateHelp:category=Webhook
5672

5773
// Config specifies how a webhook should be served.
@@ -154,6 +170,32 @@ func verbToAPIVariant(verbRaw string) admissionregv1.OperationType {
154170
}
155171
}
156172

173+
// ToMutatingWebhookConfiguration converts this WebhookConfig to its Kubernetes API form.
174+
func (c WebhookConfig) ToMutatingWebhookConfiguration() (admissionregv1.MutatingWebhookConfiguration, error) {
175+
if !c.Mutating {
176+
return admissionregv1.MutatingWebhookConfiguration{}, fmt.Errorf("%s is a validating webhook", c.Name)
177+
}
178+
179+
return admissionregv1.MutatingWebhookConfiguration{
180+
ObjectMeta: metav1.ObjectMeta{
181+
Name: c.Name,
182+
},
183+
}, nil
184+
}
185+
186+
// ToValidatingWebhookConfiguration converts this WebhookConfig to its Kubernetes API form.
187+
func (c WebhookConfig) ToValidatingWebhookConfiguration() (admissionregv1.ValidatingWebhookConfiguration, error) {
188+
if c.Mutating {
189+
return admissionregv1.ValidatingWebhookConfiguration{}, fmt.Errorf("%s is a mutating webhook", c.Name)
190+
}
191+
192+
return admissionregv1.ValidatingWebhookConfiguration{
193+
ObjectMeta: metav1.ObjectMeta{
194+
Name: c.Name,
195+
},
196+
}, nil
197+
}
198+
157199
// ToMutatingWebhook converts this rule to its Kubernetes API form.
158200
func (c Config) ToMutatingWebhook() (admissionregv1.MutatingWebhook, error) {
159201
if !c.Mutating {
@@ -362,20 +404,54 @@ func (Generator) RegisterMarkers(into *markers.Registry) error {
362404
if err := into.Register(ConfigDefinition); err != nil {
363405
return err
364406
}
407+
if err := into.Register(WebhookConfigDefinition); err != nil {
408+
return err
409+
}
365410
into.AddHelp(ConfigDefinition, Config{}.Help())
411+
into.AddHelp(WebhookConfigDefinition, Config{}.Help())
366412
return nil
367413
}
368414

369415
func (g Generator) Generate(ctx *genall.GenerationContext) error {
370416
supportedWebhookVersions := supportedWebhookVersions()
371417
mutatingCfgs := make(map[string][]admissionregv1.MutatingWebhook, len(supportedWebhookVersions))
372418
validatingCfgs := make(map[string][]admissionregv1.ValidatingWebhook, len(supportedWebhookVersions))
419+
mutatingWebhookCfgs := make(map[string]admissionregv1.MutatingWebhookConfiguration, len(supportedWebhookVersions))
420+
validatingWebhookCfgs := make(map[string]admissionregv1.ValidatingWebhookConfiguration, len(supportedWebhookVersions))
421+
373422
for _, root := range ctx.Roots {
374423
markerSet, err := markers.PackageMarkers(ctx.Collector, root)
375424
if err != nil {
376425
root.AddError(err)
377426
}
378427

428+
webhookCfgs := markerSet[WebhookConfigDefinition.Name]
429+
sort.SliceStable(webhookCfgs, func(i, j int) bool {
430+
return webhookCfgs[i].(WebhookConfig).Name < webhookCfgs[j].(WebhookConfig).Name
431+
})
432+
433+
for _, webhookCfg := range webhookCfgs {
434+
webhookCfg := webhookCfg.(WebhookConfig)
435+
436+
if webhookCfg.Mutating {
437+
w, err := webhookCfg.ToMutatingWebhookConfiguration()
438+
if err != nil {
439+
return err
440+
}
441+
for _, webhookVersion := range supportedWebhookVersions {
442+
mutatingWebhookCfgs[webhookVersion] = w
443+
}
444+
} else {
445+
w, err := webhookCfg.ToValidatingWebhookConfiguration()
446+
if err != nil {
447+
return err
448+
}
449+
for _, webhookVersion := range supportedWebhookVersions {
450+
validatingWebhookCfgs[webhookVersion] = w
451+
}
452+
}
453+
}
454+
379455
cfgs := markerSet[ConfigDefinition.Name]
380456
sort.SliceStable(cfgs, func(i, j int) bool {
381457
return cfgs[i].(Config).Name < cfgs[j].(Config).Name
@@ -410,16 +486,22 @@ func (g Generator) Generate(ctx *genall.GenerationContext) error {
410486
versionedWebhooks := make(map[string][]interface{}, len(supportedWebhookVersions))
411487
for _, version := range supportedWebhookVersions {
412488
if cfgs, ok := mutatingCfgs[version]; ok {
413-
// The only possible version in supportedWebhookVersions is v1,
414-
// so use it for all versioned types in this context.
415-
objRaw := &admissionregv1.MutatingWebhookConfiguration{}
489+
var objRaw *admissionregv1.MutatingWebhookConfiguration
490+
if mutatingWebhookCfg, ok := mutatingWebhookCfgs[version]; ok {
491+
objRaw = &mutatingWebhookCfg
492+
} else {
493+
// The only possible version in supportedWebhookVersions is v1,
494+
// so use it for all versioned types in this context.
495+
objRaw = &admissionregv1.MutatingWebhookConfiguration{}
496+
objRaw.SetName("mutating-webhook-configuration")
497+
}
416498
objRaw.SetGroupVersionKind(schema.GroupVersionKind{
417499
Group: admissionregv1.SchemeGroupVersion.Group,
418500
Version: version,
419501
Kind: "MutatingWebhookConfiguration",
420502
})
421-
objRaw.SetName("mutating-webhook-configuration")
422503
objRaw.Webhooks = cfgs
504+
423505
for i := range objRaw.Webhooks {
424506
// SideEffects is required in admissionregistration/v1, if this is not set or set to `Some` or `Known`,
425507
// return an error
@@ -441,16 +523,22 @@ func (g Generator) Generate(ctx *genall.GenerationContext) error {
441523
}
442524

443525
if cfgs, ok := validatingCfgs[version]; ok {
444-
// The only possible version in supportedWebhookVersions is v1,
445-
// so use it for all versioned types in this context.
446-
objRaw := &admissionregv1.ValidatingWebhookConfiguration{}
526+
var objRaw *admissionregv1.ValidatingWebhookConfiguration
527+
if validatingWebhookCfg, ok := validatingWebhookCfgs[version]; ok {
528+
objRaw = &validatingWebhookCfg
529+
} else {
530+
// The only possible version in supportedWebhookVersions is v1,
531+
// so use it for all versioned types in this context.
532+
objRaw = &admissionregv1.ValidatingWebhookConfiguration{}
533+
objRaw.SetName("validating-webhook-configuration")
534+
}
447535
objRaw.SetGroupVersionKind(schema.GroupVersionKind{
448536
Group: admissionregv1.SchemeGroupVersion.Group,
449537
Version: version,
450538
Kind: "ValidatingWebhookConfiguration",
451539
})
452-
objRaw.SetName("validating-webhook-configuration")
453540
objRaw.Webhooks = cfgs
541+
454542
for i := range objRaw.Webhooks {
455543
// SideEffects is required in admissionregistration/v1, if this is not set or set to `Some` or `Known`,
456544
// return an error

pkg/webhook/zz_generated.markerhelp.go

+20
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)