Skip to content

Commit d8562a8

Browse files
author
Mengqi Yu
committed
address comments
1 parent 7ba8e54 commit d8562a8

File tree

5 files changed

+72
-137
lines changed

5 files changed

+72
-137
lines changed

pkg/webhook/admission/admission_suite_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import (
2626
logf "sigs.k8s.io/controller-runtime/pkg/runtime/log"
2727
)
2828

29-
func TestSource(t *testing.T) {
29+
func TestAdmissionWebhook(t *testing.T) {
3030
RegisterFailHandler(Fail)
3131
RunSpecsWithDefaultAndCustomReporters(t, "application Suite", []Reporter{envtest.NewlineReporter{}})
3232
}

pkg/webhook/admission/decode_test.go

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,15 @@ import (
2727
)
2828

2929
var _ = Describe("admission webhook decoder", func() {
30+
var decoder Decoder
31+
BeforeEach(func(done Done) {
32+
var err error
33+
decoder, err = NewDecoder(scheme.Scheme)
34+
Expect(err).NotTo(HaveOccurred())
35+
Expect(decoder).NotTo(BeNil())
36+
close(done)
37+
})
38+
3039
Describe("NewDecoder", func() {
3140
It("should return a decoder without an error", func() {
3241
decoder, err := NewDecoder(scheme.Scheme)
@@ -36,7 +45,6 @@ var _ = Describe("admission webhook decoder", func() {
3645
})
3746

3847
Describe("Decode", func() {
39-
var decoder Decoder
4048
req := Request{
4149
AdmissionRequest: &admissionv1beta1.AdmissionRequest{
4250
Object: runtime.RawExtension{
@@ -59,13 +67,6 @@ var _ = Describe("admission webhook decoder", func() {
5967
},
6068
},
6169
}
62-
BeforeEach(func(done Done) {
63-
var err error
64-
decoder, err = NewDecoder(scheme.Scheme)
65-
Expect(err).NotTo(HaveOccurred())
66-
Expect(decoder).NotTo(BeNil())
67-
close(done)
68-
})
6970

7071
It("should be able to decode", func() {
7172
err := decoder.Decode(req, &corev1.Pod{})

pkg/webhook/admission/http_test.go

Lines changed: 25 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"context"
2222
"io"
2323
"net/http"
24+
"net/http/httptest"
2425

2526
. "github.com/onsi/ginkgo"
2627
. "github.com/onsi/gomega"
@@ -30,18 +31,25 @@ import (
3031
)
3132

3233
var _ = Describe("admission webhook http handler", func() {
34+
var w *httptest.ResponseRecorder
35+
BeforeEach(func(done Done) {
36+
w = &httptest.ResponseRecorder{
37+
Body: bytes.NewBuffer(nil),
38+
}
39+
close(done)
40+
})
41+
3342
Describe("empty request body", func() {
3443
req := &http.Request{Body: nil}
3544
wh := &Webhook{
3645
Handlers: []Handler{},
3746
}
38-
w := &fakeResponseWriter{}
47+
3948
expected := []byte(`{"response":{"uid":"","allowed":false,"status":{"metadata":{},"message":"request body is empty","code":400}}}
4049
`)
41-
It("should return a response with an error", func() {
50+
It("should return an error with bad-request status code", func() {
4251
wh.ServeHTTP(w, req)
43-
Expect(w.response).NotTo(BeNil())
44-
Expect(w.response).To(Equal(expected))
52+
Expect(w.Body.Bytes()).To(Equal(expected))
4553
})
4654
})
4755

@@ -53,13 +61,12 @@ var _ = Describe("admission webhook http handler", func() {
5361
wh := &Webhook{
5462
Handlers: []Handler{},
5563
}
56-
w := &fakeResponseWriter{}
5764
expected := []byte(`{"response":{"uid":"","allowed":false,"status":{"metadata":{},"message":"contentType=application/foo, expect application/json","code":400}}}
5865
`)
59-
It("should return a response with an error", func() {
66+
It("should return an error with bad-request status code", func() {
6067
wh.ServeHTTP(w, req)
61-
Expect(w.response).NotTo(BeNil())
62-
Expect(w.response).To(Equal(expected))
68+
Expect(w.Body.Bytes()).To(Equal(expected))
69+
6370
})
6471
})
6572

@@ -72,14 +79,13 @@ var _ = Describe("admission webhook http handler", func() {
7279
Type: types.WebhookTypeMutating,
7380
Handlers: []Handler{},
7481
}
75-
w := &fakeResponseWriter{}
7682
expected := []byte(
7783
`{"response":{"uid":"","allowed":false,"status":{"metadata":{},"message":"couldn't get version/kind; json parse error: unexpected end of JSON input","code":400}}}
7884
`)
79-
It("should return a response with an error", func() {
85+
It("should return an error with bad-request status code", func() {
8086
wh.ServeHTTP(w, req)
81-
Expect(w.response).NotTo(BeNil())
82-
Expect(w.response).To(Equal(expected))
87+
Expect(w.Body.Bytes()).To(Equal(expected))
88+
8389
})
8490
})
8591

@@ -92,13 +98,11 @@ var _ = Describe("admission webhook http handler", func() {
9298
Type: types.WebhookTypeMutating,
9399
Handlers: []Handler{},
94100
}
95-
w := &fakeResponseWriter{}
96101
expected := []byte(`{"response":{"uid":"","allowed":false,"status":{"metadata":{},"message":"got an empty AdmissionRequest","code":400}}}
97102
`)
98-
It("should return a response with an error", func() {
103+
It("should return an error with bad-request status code", func() {
99104
wh.ServeHTTP(w, req)
100-
Expect(w.response).NotTo(BeNil())
101-
Expect(w.response).To(Equal(expected))
105+
Expect(w.Body.Bytes()).To(Equal(expected))
102106
})
103107
})
104108

@@ -110,13 +114,12 @@ var _ = Describe("admission webhook http handler", func() {
110114
wh := &Webhook{
111115
Handlers: []Handler{},
112116
}
113-
w := &fakeResponseWriter{}
114-
expected := []byte(`{"response":{"uid":"","allowed":false,"status":{"metadata":{},"message":"you must specify your webhook type","code":400}}}
117+
expected := []byte(`{"response":{"uid":"","allowed":false,"status":{"metadata":{},"message":"you must specify your webhook type","code":500}}}
115118
`)
116-
It("should return a response with an error", func() {
119+
It("should return an error with internal-error status code", func() {
117120
wh.ServeHTTP(w, req)
118-
Expect(w.response).NotTo(BeNil())
119-
Expect(w.response).To(Equal(expected))
121+
Expect(w.Body.Bytes()).To(Equal(expected))
122+
120123
})
121124
})
122125

@@ -131,36 +134,17 @@ var _ = Describe("admission webhook http handler", func() {
131134
Handlers: []Handler{h},
132135
KVMap: map[string]interface{}{"foo": "bar"},
133136
}
134-
w := &fakeResponseWriter{}
135137
expected := []byte(`{"response":{"uid":"","allowed":true}}
136138
`)
137139
It("should return a response successfully", func() {
138140
wh.ServeHTTP(w, req)
139-
Expect(w.response).NotTo(BeNil())
140-
Expect(w.response).To(Equal(expected))
141+
Expect(w.Body.Bytes()).To(Equal(expected))
141142
Expect(h.invoked).To(BeTrue())
142143
Expect(h.valueFromContext).To(Equal("bar"))
143144
})
144145
})
145146
})
146147

147-
type fakeResponseWriter struct {
148-
response []byte
149-
}
150-
151-
var _ http.ResponseWriter = &fakeResponseWriter{}
152-
153-
func (w *fakeResponseWriter) Header() http.Header {
154-
return nil
155-
}
156-
157-
func (w *fakeResponseWriter) Write(resp []byte) (int, error) {
158-
w.response = append(w.response, resp...)
159-
return len(resp), nil
160-
}
161-
162-
func (w *fakeResponseWriter) WriteHeader(statusCode int) {}
163-
164148
type nopCloser struct {
165149
io.Reader
166150
}

pkg/webhook/admission/webhook.go

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ type Webhook struct {
7272
KVMap map[string]interface{}
7373
// Handlers contains a list of handlers. Each handler may only contains the business logic for its own feature.
7474
// For example, feature foo and bar can be in the same webhook if all the other configurations are the same.
75+
// The handler will be invoked sequentially as the order in the list.
7576
Handlers []Handler
7677

7778
once sync.Once
@@ -117,7 +118,7 @@ func (w *Webhook) Handle(ctx context.Context, req Request) Response {
117118
case types.WebhookTypeValidating:
118119
resp = w.handleValidating(ctx, req)
119120
default:
120-
return ErrorResponse(http.StatusBadRequest, errors.New("you must specify your webhook type"))
121+
return ErrorResponse(http.StatusInternalServerError, errors.New("you must specify your webhook type"))
121122
}
122123
resp.Response.UID = req.AdmissionRequest.UID
123124
return resp
@@ -135,44 +136,45 @@ func (w *Webhook) kvMapToContext(ctx context.Context) (context.Context, error) {
135136
}
136137

137138
func (w *Webhook) handleMutating(ctx context.Context, req Request) Response {
138-
r := Response{
139-
Response: &admissionv1beta1.AdmissionResponse{},
140-
}
141139
patches := []jsonpatch.JsonPatchOperation{}
142140
for _, handler := range w.Handlers {
143141
resp := handler.Handle(ctx, req)
144142
if !resp.Response.Allowed {
145143
return resp
146144
}
147-
if resp.Response.PatchType == nil || *resp.Response.PatchType != admissionv1beta1.PatchTypeJSONPatch {
145+
if resp.Response.PatchType != nil && *resp.Response.PatchType != admissionv1beta1.PatchTypeJSONPatch {
148146
return ErrorResponse(http.StatusInternalServerError,
149147
fmt.Errorf("unexpected patch type returned by the handler: %v, only allow: %v",
150148
resp.Response.PatchType, admissionv1beta1.PatchTypeJSONPatch))
151149
}
152150
patches = append(patches, resp.Patches...)
153151
}
154152
var err error
155-
r.Response.Patch, err = json.Marshal(patches)
153+
marshaledPatch, err := json.Marshal(patches)
156154
if err != nil {
157155
return ErrorResponse(http.StatusBadRequest, fmt.Errorf("error when marshaling the patch: %v", err))
158156
}
159-
return r
160-
}
161-
162-
func (w *Webhook) handleValidating(ctx context.Context, req Request) Response {
163-
r := Response{
157+
return Response{
164158
Response: &admissionv1beta1.AdmissionResponse{
165-
Allowed: true,
159+
Allowed: true,
160+
Patch: marshaledPatch,
161+
PatchType: func() *admissionv1beta1.PatchType { pt := admissionv1beta1.PatchTypeJSONPatch; return &pt }(),
166162
},
167163
}
164+
}
165+
166+
func (w *Webhook) handleValidating(ctx context.Context, req Request) Response {
168167
for _, handler := range w.Handlers {
169168
resp := handler.Handle(ctx, req)
170169
if !resp.Response.Allowed {
171-
r.Response.Allowed = false
172-
break
170+
return resp
173171
}
174172
}
175-
return r
173+
return Response{
174+
Response: &admissionv1beta1.AdmissionResponse{
175+
Allowed: true,
176+
},
177+
}
176178
}
177179

178180
// GetName returns the name of the webhook.

0 commit comments

Comments
 (0)