@@ -31,6 +31,7 @@ import (
31
31
"k8s.io/apimachinery/pkg/runtime/schema"
32
32
"k8s.io/apimachinery/pkg/util/sets"
33
33
34
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
34
35
"sigs.k8s.io/controller-tools/pkg/genall"
35
36
"sigs.k8s.io/controller-tools/pkg/markers"
36
37
)
@@ -42,16 +43,31 @@ const (
42
43
)
43
44
44
45
var (
45
- // ConfigDefinition s a marker for defining Webhook manifests.
46
+ // ConfigDefinition is a marker for defining Webhook manifests.
46
47
// Call ToWebhook on the value to get a Kubernetes Webhook.
47
48
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 {}))
48
51
)
49
52
50
53
// supportedWebhookVersions returns currently supported API version of {Mutating,Validating}WebhookConfiguration.
51
54
func supportedWebhookVersions () []string {
52
55
return []string {defaultWebhookVersion }
53
56
}
54
57
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
+
55
71
// +controllertools:marker:generateHelp:category=Webhook
56
72
57
73
// Config specifies how a webhook should be served.
@@ -154,6 +170,32 @@ func verbToAPIVariant(verbRaw string) admissionregv1.OperationType {
154
170
}
155
171
}
156
172
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
+
157
199
// ToMutatingWebhook converts this rule to its Kubernetes API form.
158
200
func (c Config ) ToMutatingWebhook () (admissionregv1.MutatingWebhook , error ) {
159
201
if ! c .Mutating {
@@ -362,20 +404,54 @@ func (Generator) RegisterMarkers(into *markers.Registry) error {
362
404
if err := into .Register (ConfigDefinition ); err != nil {
363
405
return err
364
406
}
407
+ if err := into .Register (WebhookConfigDefinition ); err != nil {
408
+ return err
409
+ }
365
410
into .AddHelp (ConfigDefinition , Config {}.Help ())
411
+ into .AddHelp (WebhookConfigDefinition , Config {}.Help ())
366
412
return nil
367
413
}
368
414
369
415
func (g Generator ) Generate (ctx * genall.GenerationContext ) error {
370
416
supportedWebhookVersions := supportedWebhookVersions ()
371
417
mutatingCfgs := make (map [string ][]admissionregv1.MutatingWebhook , len (supportedWebhookVersions ))
372
418
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
+
373
422
for _ , root := range ctx .Roots {
374
423
markerSet , err := markers .PackageMarkers (ctx .Collector , root )
375
424
if err != nil {
376
425
root .AddError (err )
377
426
}
378
427
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
+
379
455
cfgs := markerSet [ConfigDefinition .Name ]
380
456
sort .SliceStable (cfgs , func (i , j int ) bool {
381
457
return cfgs [i ].(Config ).Name < cfgs [j ].(Config ).Name
@@ -410,16 +486,22 @@ func (g Generator) Generate(ctx *genall.GenerationContext) error {
410
486
versionedWebhooks := make (map [string ][]interface {}, len (supportedWebhookVersions ))
411
487
for _ , version := range supportedWebhookVersions {
412
488
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
+ }
416
498
objRaw .SetGroupVersionKind (schema.GroupVersionKind {
417
499
Group : admissionregv1 .SchemeGroupVersion .Group ,
418
500
Version : version ,
419
501
Kind : "MutatingWebhookConfiguration" ,
420
502
})
421
- objRaw .SetName ("mutating-webhook-configuration" )
422
503
objRaw .Webhooks = cfgs
504
+
423
505
for i := range objRaw .Webhooks {
424
506
// SideEffects is required in admissionregistration/v1, if this is not set or set to `Some` or `Known`,
425
507
// return an error
@@ -441,16 +523,22 @@ func (g Generator) Generate(ctx *genall.GenerationContext) error {
441
523
}
442
524
443
525
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
+ }
447
535
objRaw .SetGroupVersionKind (schema.GroupVersionKind {
448
536
Group : admissionregv1 .SchemeGroupVersion .Group ,
449
537
Version : version ,
450
538
Kind : "ValidatingWebhookConfiguration" ,
451
539
})
452
- objRaw .SetName ("validating-webhook-configuration" )
453
540
objRaw .Webhooks = cfgs
541
+
454
542
for i := range objRaw .Webhooks {
455
543
// SideEffects is required in admissionregistration/v1, if this is not set or set to `Some` or `Known`,
456
544
// return an error
0 commit comments