Skip to content

Commit 922ee77

Browse files
Allow to wire an object mutation handler
1 parent e6c3d13 commit 922ee77

File tree

2 files changed

+51
-25
lines changed

2 files changed

+51
-25
lines changed

pkg/builder/webhook.go

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import (
3737
// WebhookBuilder builds a Webhook.
3838
type WebhookBuilder struct {
3939
apiType runtime.Object
40+
mutationHandler admission.ObjectHandler
4041
customDefaulter admission.CustomDefaulter
4142
customValidator admission.CustomValidator
4243
gvk schema.GroupVersionKind
@@ -65,6 +66,12 @@ func (blder *WebhookBuilder) For(apiType runtime.Object) *WebhookBuilder {
6566
return blder
6667
}
6768

69+
// WithMutationHandler takes an admission.ObjectHandler interface, a MutatingWebhook will be wired for this type.
70+
func (blder *WebhookBuilder) WithMutationHandler(handler admission.ObjectHandler) *WebhookBuilder {
71+
blder.mutationHandler = handler
72+
return blder
73+
}
74+
6875
// WithDefaulter takes an admission.CustomDefaulter interface, a MutatingWebhook will be wired for this type.
6976
func (blder *WebhookBuilder) WithDefaulter(defaulter admission.CustomDefaulter) *WebhookBuilder {
7077
blder.customDefaulter = defaulter
@@ -169,24 +176,24 @@ func (blder *WebhookBuilder) registerDefaultingWebhook() {
169176
}
170177

171178
func (blder *WebhookBuilder) getDefaultingWebhook() *admission.Webhook {
172-
if defaulter := blder.customDefaulter; defaulter != nil {
173-
w := admission.WithCustomDefaulter(blder.mgr.GetScheme(), blder.apiType, defaulter)
174-
if blder.recoverPanic != nil {
175-
w = w.WithRecoverPanic(*blder.recoverPanic)
176-
}
177-
return w
179+
var w *admission.Webhook
180+
if handler := blder.mutationHandler; handler != nil {
181+
w = admission.WithObjectHandler(blder.mgr.GetScheme(), blder.apiType, handler)
182+
} else if defaulter := blder.customDefaulter; defaulter != nil {
183+
w = admission.WithCustomDefaulter(blder.mgr.GetScheme(), blder.apiType, defaulter)
184+
} else if defaulter, ok := blder.apiType.(admission.Defaulter); ok {
185+
w = admission.DefaultingWebhookFor(blder.mgr.GetScheme(), defaulter)
178186
}
179-
if defaulter, ok := blder.apiType.(admission.Defaulter); ok {
180-
w := admission.DefaultingWebhookFor(blder.mgr.GetScheme(), defaulter)
181-
if blder.recoverPanic != nil {
182-
w = w.WithRecoverPanic(*blder.recoverPanic)
183-
}
184-
return w
187+
if w == nil {
188+
log.Info(
189+
"Skip registering a mutating webhook, object does not implement admission.Defaulter or WithDefaulter wasn't called",
190+
"GVK", blder.gvk)
191+
return nil
185192
}
186-
log.Info(
187-
"skip registering a mutating webhook, object does not implement admission.Defaulter or WithDefaulter wasn't called",
188-
"GVK", blder.gvk)
189-
return nil
193+
if blder.recoverPanic != nil {
194+
w = w.WithRecoverPanic(*blder.recoverPanic)
195+
}
196+
return w
190197
}
191198

192199
// registerValidatingWebhook registers a validating webhook if necessary.

pkg/webhook/admission/defaulter_custom.go

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,18 @@ import (
2828
"k8s.io/apimachinery/pkg/runtime"
2929
)
3030

31+
// ObjectHandler defines functions for handling objects on webhooks.
32+
type ObjectHandler interface {
33+
Handle(ctx context.Context, raw []byte, obj runtime.Object) Response
34+
}
35+
36+
// WithObjectHandler creates a new Webhook for an ObjectHandler interface.
37+
func WithObjectHandler(scheme *runtime.Scheme, obj runtime.Object, handler ObjectHandler) *Webhook {
38+
return &Webhook{
39+
Handler: &handlerForType{object: obj, handler: handler, decoder: NewDecoder(scheme)},
40+
}
41+
}
42+
3143
// CustomDefaulter defines functions for setting defaults on resources.
3244
type CustomDefaulter interface {
3345
Default(ctx context.Context, obj runtime.Object) error
@@ -36,22 +48,22 @@ type CustomDefaulter interface {
3648
// WithCustomDefaulter creates a new Webhook for a CustomDefaulter interface.
3749
func WithCustomDefaulter(scheme *runtime.Scheme, obj runtime.Object, defaulter CustomDefaulter) *Webhook {
3850
return &Webhook{
39-
Handler: &defaulterForType{object: obj, defaulter: defaulter, decoder: NewDecoder(scheme)},
51+
Handler: &handlerForType{object: obj, handler: &handlerForDefaulter{defaulter: defaulter}, decoder: NewDecoder(scheme)},
4052
}
4153
}
4254

43-
type defaulterForType struct {
44-
defaulter CustomDefaulter
45-
object runtime.Object
46-
decoder Decoder
55+
type handlerForType struct {
56+
handler ObjectHandler
57+
object runtime.Object
58+
decoder Decoder
4759
}
4860

4961
// Handle handles admission requests.
50-
func (h *defaulterForType) Handle(ctx context.Context, req Request) Response {
62+
func (h *handlerForType) Handle(ctx context.Context, req Request) Response {
5163
if h.decoder == nil {
5264
panic("decoder should never be nil")
5365
}
54-
if h.defaulter == nil {
66+
if h.handler == nil {
5567
panic("defaulter should never be nil")
5668
}
5769
if h.object == nil {
@@ -76,7 +88,14 @@ func (h *defaulterForType) Handle(ctx context.Context, req Request) Response {
7688
return Errored(http.StatusBadRequest, err)
7789
}
7890

79-
// Default the object
91+
return h.handler.Handle(ctx, req.Object.Raw, obj)
92+
}
93+
94+
type handlerForDefaulter struct {
95+
defaulter CustomDefaulter
96+
}
97+
98+
func (h *handlerForDefaulter) Handle(ctx context.Context, raw []byte, obj runtime.Object) Response {
8099
if err := h.defaulter.Default(ctx, obj); err != nil {
81100
var apiStatus apierrors.APIStatus
82101
if errors.As(err, &apiStatus) {
@@ -90,5 +109,5 @@ func (h *defaulterForType) Handle(ctx context.Context, req Request) Response {
90109
if err != nil {
91110
return Errored(http.StatusInternalServerError, err)
92111
}
93-
return PatchResponseFromRaw(req.Object.Raw, marshalled)
112+
return PatchResponseFromRaw(raw, marshalled)
94113
}

0 commit comments

Comments
 (0)