Skip to content

Commit 5cf2324

Browse files
committed
✨ Able to set WithContextFunc in WebhookBuilder
1 parent 961fc2c commit 5cf2324

File tree

2 files changed

+63
-0
lines changed

2 files changed

+63
-0
lines changed

pkg/builder/webhook.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ limitations under the License.
1717
package builder
1818

1919
import (
20+
"context"
2021
"errors"
2122
"net/http"
2223
"net/url"
@@ -49,6 +50,7 @@ type WebhookBuilder struct {
4950
config *rest.Config
5051
recoverPanic *bool
5152
logConstructor func(base logr.Logger, req *admission.Request) logr.Logger
53+
contextFunc func(context.Context, *http.Request) context.Context
5254
err error
5355
}
5456

@@ -90,6 +92,12 @@ func (blder *WebhookBuilder) WithLogConstructor(logConstructor func(base logr.Lo
9092
return blder
9193
}
9294

95+
// WithContextFunc overrides the webhook's WithContextFunc.
96+
func (blder *WebhookBuilder) WithContextFunc(contextFunc func(context.Context, *http.Request) context.Context) *WebhookBuilder {
97+
blder.contextFunc = contextFunc
98+
return blder
99+
}
100+
93101
// RecoverPanic indicates whether panics caused by the webhook should be recovered.
94102
// Defaults to true.
95103
func (blder *WebhookBuilder) RecoverPanic(recoverPanic bool) *WebhookBuilder {
@@ -205,6 +213,7 @@ func (blder *WebhookBuilder) registerDefaultingWebhook() error {
205213
mwh := blder.getDefaultingWebhook()
206214
if mwh != nil {
207215
mwh.LogConstructor = blder.logConstructor
216+
mwh.WithContextFunc = blder.contextFunc
208217
path := generateMutatePath(blder.gvk)
209218
if blder.customDefaulterCustomPath != "" {
210219
generatedCustomPath, err := generateCustomPath(blder.customDefaulterCustomPath)
@@ -243,6 +252,7 @@ func (blder *WebhookBuilder) registerValidatingWebhook() error {
243252
vwh := blder.getValidatingWebhook()
244253
if vwh != nil {
245254
vwh.LogConstructor = blder.logConstructor
255+
vwh.WithContextFunc = blder.contextFunc
246256
path := generateValidatePath(blder.gvk)
247257
if blder.customValidatorCustomPath != "" {
248258
generatedCustomPath, err := generateCustomPath(blder.customValidatorCustomPath)

pkg/builder/webhook_test.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ const (
4949
svcBaseAddr = "http://svc-name.svc-ns.svc"
5050

5151
customPath = "/custom-path"
52+
53+
userAgentHeader = "User-Agent"
54+
userAgentCtxKey = "UserAgent"
55+
userAgentValue = "test"
5256
)
5357

5458
var _ = Describe("webhook", func() {
@@ -315,6 +319,9 @@ func runTests(admissionReviewVersion string) {
315319
WithLogConstructor(func(base logr.Logger, req *admission.Request) logr.Logger {
316320
return admission.DefaultLogConstructor(testingLogger, req)
317321
}).
322+
WithContextFunc(func(ctx context.Context, request *http.Request) context.Context {
323+
return context.WithValue(ctx, userAgentCtxKey, request.Header.Get(userAgentHeader))
324+
}).
318325
Complete()
319326
ExpectWithOffset(1, err).NotTo(HaveOccurred())
320327
svr := m.GetWebhookServer()
@@ -344,6 +351,30 @@ func runTests(admissionReviewVersion string) {
344351
}
345352
}
346353
}`)
354+
readerWithCxt := strings.NewReader(admissionReviewGV + admissionReviewVersion + `",
355+
"request":{
356+
"uid":"07e52e8d-4513-11e9-a716-42010a800270",
357+
"kind":{
358+
"group":"foo.test.org",
359+
"version":"v1",
360+
"kind":"TestValidator"
361+
},
362+
"resource":{
363+
"group":"foo.test.org",
364+
"version":"v1",
365+
"resource":"testvalidator"
366+
},
367+
"namespace":"default",
368+
"name":"foo",
369+
"operation":"UPDATE",
370+
"object":{
371+
"replica":1
372+
},
373+
"oldObject":{
374+
"replica":1
375+
}
376+
}
377+
}`)
347378

348379
ctx, cancel := context.WithCancel(specCtx)
349380
cancel()
@@ -373,6 +404,20 @@ func runTests(admissionReviewVersion string) {
373404
ExpectWithOffset(1, w.Body).To(ContainSubstring(`"allowed":false`))
374405
ExpectWithOffset(1, w.Body).To(ContainSubstring(`"code":403`))
375406
EventuallyWithOffset(1, logBuffer).Should(gbytes.Say(`"msg":"Validating object","object":{"name":"foo","namespace":"default"},"namespace":"default","name":"foo","resource":{"group":"foo.test.org","version":"v1","resource":"testvalidator"},"user":"","requestID":"07e52e8d-4513-11e9-a716-42010a800270"`))
407+
408+
By("sending a request to a validating webhook with context header validation")
409+
path = generateValidatePath(testValidatorGVK)
410+
_, err = readerWithCxt.Seek(0, 0)
411+
ExpectWithOffset(1, err).NotTo(HaveOccurred())
412+
req = httptest.NewRequest("POST", svcBaseAddr+path, readerWithCxt)
413+
req.Header.Add("Content-Type", "application/json")
414+
req.Header.Add(userAgentHeader, userAgentValue)
415+
w = httptest.NewRecorder()
416+
svr.WebhookMux().ServeHTTP(w, req)
417+
ExpectWithOffset(1, w.Code).To(Equal(http.StatusOK))
418+
By("sanity checking the response contains reasonable field")
419+
ExpectWithOffset(1, w.Body).To(ContainSubstring(`"allowed":true`))
420+
ExpectWithOffset(1, w.Body).To(ContainSubstring(`"code":200`))
376421
})
377422

378423
It("should scaffold a custom validating webhook with a custom path", func(specCtx SpecContext) {
@@ -1009,6 +1054,7 @@ func (*TestCustomDefaulter) Default(ctx context.Context, obj runtime.Object) err
10091054
if d.Replica < 2 {
10101055
d.Replica = 2
10111056
}
1057+
10121058
return nil
10131059
}
10141060

@@ -1035,6 +1081,7 @@ func (*TestCustomValidator) ValidateCreate(ctx context.Context, obj runtime.Obje
10351081
if v.Replica < 0 {
10361082
return nil, errors.New("number of replica should be greater than or equal to 0")
10371083
}
1084+
10381085
return nil, nil
10391086
}
10401087

@@ -1056,6 +1103,12 @@ func (*TestCustomValidator) ValidateUpdate(ctx context.Context, oldObj, newObj r
10561103
if v.Replica < old.Replica {
10571104
return nil, fmt.Errorf("new replica %v should not be fewer than old replica %v", v.Replica, old.Replica)
10581105
}
1106+
1107+
userAgent, ok := ctx.Value(userAgentCtxKey).(string)
1108+
if ok && userAgent != userAgentValue {
1109+
return nil, fmt.Errorf("expected %s value is %q in TestCustomValidator got %q", userAgentCtxKey, userAgentValue, userAgent)
1110+
}
1111+
10591112
return nil, nil
10601113
}
10611114

0 commit comments

Comments
 (0)