From 88256cdfed637f633a33626aeac7f956a71f75fa Mon Sep 17 00:00:00 2001 From: Norwin Schnyder Date: Tue, 19 Dec 2023 10:12:03 +0000 Subject: [PATCH] fix: nil pointer exception due to failed injection Signed-off-by: Norwin Schnyder --- pkg/webhook/injection.go | 20 ++++++++++++++++++-- pkg/webhook/webhook.go | 4 ++-- pkg/webhook/webhook_test.go | 10 ++++++++++ 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/pkg/webhook/injection.go b/pkg/webhook/injection.go index 052f5d9..219acfd 100644 --- a/pkg/webhook/injection.go +++ b/pkg/webhook/injection.go @@ -5,23 +5,39 @@ import ( "sigs.k8s.io/controller-runtime/pkg/webhook/admission" ) +// ClientInjector is used to inject a client.Client into webhook handlers. +type ClientInjector interface { + InjectClient(client.Client) error +} + +// ensure InjectedClient implements ClientInjector +var _ ClientInjector = &InjectedClient{} + // InjectedClient holds an injected client.Client type InjectedClient struct { Client client.Client } -// InjectClient implements the inject.Client interface. +// InjectClient implements the ClientInjector interface. func (i *InjectedClient) InjectClient(client client.Client) error { i.Client = client return nil } +// DecoderInjector is used to inject an admission.Decoder into webhook handlers. +type DecoderInjector interface { + InjectDecoder(*admission.Decoder) error +} + +// ensure InjectedDecoder implements DecoderInjector +var _ DecoderInjector = &InjectedDecoder{} + // InjectedDecoder holds an injected admission.Decoder type InjectedDecoder struct { Decoder *admission.Decoder } -// InjectDecoder implements the admission.DecoderInjector interface. +// InjectDecoder implements the DecoderInjector interface. func (i *InjectedDecoder) InjectDecoder(decoder *admission.Decoder) error { i.Decoder = decoder return nil diff --git a/pkg/webhook/webhook.go b/pkg/webhook/webhook.go index 3e9296a..2dd9ad9 100644 --- a/pkg/webhook/webhook.go +++ b/pkg/webhook/webhook.go @@ -108,13 +108,13 @@ func (blder *Builder) Complete(i interface{}) error { return fmt.Errorf("webhook instance %v does implement neither Mutator nor Validator interface", i) } - if injector, ok := i.(InjectedClient); ok { + if injector, ok := i.(ClientInjector); ok { if err := injector.InjectClient(blder.mgr.GetClient()); err != nil { return err } } - if injector, ok := i.(InjectedDecoder); ok { + if injector, ok := i.(DecoderInjector); ok { if err := injector.InjectDecoder(decoder); err != nil { return err } diff --git a/pkg/webhook/webhook_test.go b/pkg/webhook/webhook_test.go index 1447818..a974d61 100644 --- a/pkg/webhook/webhook_test.go +++ b/pkg/webhook/webhook_test.go @@ -70,6 +70,16 @@ var _ = Describe("Webhook", func() { Complete(&webhook.ValidatingWebhook{}) Ω(err).ShouldNot(HaveOccurred()) }) + It("should inject client and decoder", func() { + wh := &webhook.ValidatingWebhook{} + err := webhook.NewGenericWebhookManagedBy(mgr). + For(&corev1.Pod{}). + Complete(wh) + Ω(err).ShouldNot(HaveOccurred()) + + Ω(wh.Client).ShouldNot(BeNil()) + Ω(wh.Decoder).ShouldNot(BeNil()) + }) It("should not fail if mutating webhook is already registered", func() { err := webhook.NewGenericWebhookManagedBy(mgr). For(&corev1.Pod{}).