Skip to content

Commit 3b25aa6

Browse files
authoredMay 1, 2021
šŸ› fix nil Decoder in multiValidating and multiMutating handlers by implementing DecoderInjector (#1502)
* multiValidating and multiMutating handlers implement DecoderInjector * set fields before injecting in controllerManager
1 parent 2c238de commit 3b25aa6

File tree

3 files changed

+61
-5
lines changed

3 files changed

+61
-5
lines changed
 

ā€Žpkg/manager/internal.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,9 @@ func (cm *controllerManager) Add(r Runnable) error {
225225

226226
// Deprecated: use the equivalent Options field to set a field. This method will be removed in v0.10.
227227
func (cm *controllerManager) SetFields(i interface{}) error {
228+
if err := cm.cluster.SetFields(i); err != nil {
229+
return err
230+
}
228231
if _, err := inject.InjectorInto(cm.SetFields, i); err != nil {
229232
return err
230233
}
@@ -234,9 +237,6 @@ func (cm *controllerManager) SetFields(i interface{}) error {
234237
if _, err := inject.LoggerInto(cm.logger, i); err != nil {
235238
return err
236239
}
237-
if err := cm.cluster.SetFields(i); err != nil {
238-
return err
239-
}
240240

241241
return nil
242242
}

ā€Žpkg/webhook/admission/multi.go

+20
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,16 @@ func (hs multiMutating) InjectFunc(f inject.Func) error {
7777
return nil
7878
}
7979

80+
// InjectDecoder injects the decoder into the handlers.
81+
func (hs multiMutating) InjectDecoder(d *Decoder) error {
82+
for _, handler := range hs {
83+
if _, err := InjectDecoderInto(d, handler); err != nil {
84+
return err
85+
}
86+
}
87+
return nil
88+
}
89+
8090
// MultiMutatingHandler combines multiple mutating webhook handlers into a single
8191
// mutating webhook handler. Handlers are called in sequential order, and the first
8292
// `allowed: false` response may short-circuit the rest. Users must take care to
@@ -125,3 +135,13 @@ func (hs multiValidating) InjectFunc(f inject.Func) error {
125135

126136
return nil
127137
}
138+
139+
// InjectDecoder injects the decoder into the handlers.
140+
func (hs multiValidating) InjectDecoder(d *Decoder) error {
141+
for _, handler := range hs {
142+
if _, err := InjectDecoderInto(d, handler); err != nil {
143+
return err
144+
}
145+
}
146+
return nil
147+
}

ā€Žpkg/webhook/webhook_integration_test.go

+38-2
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,32 @@ var _ = Describe("Webhook", func() {
7676

7777
ctx, cancel := context.WithCancel(context.Background())
7878
go func() {
79-
_ = server.Start(ctx)
79+
err = server.Start(ctx)
80+
Expect(err).NotTo(HaveOccurred())
81+
}()
82+
83+
Eventually(func() bool {
84+
err = c.Create(context.TODO(), obj)
85+
return errors.ReasonForError(err) == metav1.StatusReason("Always denied")
86+
}, 1*time.Second).Should(BeTrue())
87+
88+
cancel()
89+
close(done)
90+
})
91+
It("should reject create request for multi-webhook that rejects all requests", func(done Done) {
92+
m, err := manager.New(cfg, manager.Options{
93+
Port: testenv.WebhookInstallOptions.LocalServingPort,
94+
Host: testenv.WebhookInstallOptions.LocalServingHost,
95+
CertDir: testenv.WebhookInstallOptions.LocalServingCertDir,
96+
}) // we need manager here just to leverage manager.SetFields
97+
Expect(err).NotTo(HaveOccurred())
98+
server := m.GetWebhookServer()
99+
server.Register("/failing", &webhook.Admission{Handler: admission.MultiValidatingHandler(&rejectingValidator{})})
100+
101+
ctx, cancel := context.WithCancel(context.Background())
102+
go func() {
103+
err = server.Start(ctx)
104+
Expect(err).NotTo(HaveOccurred())
80105
}()
81106

82107
Eventually(func() bool {
@@ -99,7 +124,8 @@ var _ = Describe("Webhook", func() {
99124

100125
ctx, cancel := context.WithCancel(context.Background())
101126
go func() {
102-
_ = server.StartStandalone(ctx, scheme.Scheme)
127+
err := server.StartStandalone(ctx, scheme.Scheme)
128+
Expect(err).NotTo(HaveOccurred())
103129
}()
104130

105131
Eventually(func() bool {
@@ -170,8 +196,18 @@ var _ = Describe("Webhook", func() {
170196
})
171197

172198
type rejectingValidator struct {
199+
d *admission.Decoder
200+
}
201+
202+
func (v *rejectingValidator) InjectDecoder(d *admission.Decoder) error {
203+
v.d = d
204+
return nil
173205
}
174206

175207
func (v *rejectingValidator) Handle(ctx context.Context, req admission.Request) admission.Response {
208+
var obj appsv1.Deployment
209+
if err := v.d.Decode(req, &obj); err != nil {
210+
return admission.Denied(err.Error())
211+
}
176212
return admission.Denied(fmt.Sprint("Always denied"))
177213
}

0 commit comments

Comments
 (0)
Please sign in to comment.