Skip to content

Commit 7161fa8

Browse files
Merge pull request #21 from klaases/gwh1
Refactor read and write functions for new handlers
2 parents b85ef96 + 6401372 commit 7161fa8

File tree

2 files changed

+83
-119
lines changed

2 files changed

+83
-119
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
out/
2+
.DS_Store

server.go

Lines changed: 82 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,13 @@ import (
2525
admissionv1 "k8s.io/api/admission/v1"
2626
corev1 "k8s.io/api/core/v1"
2727
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
28+
2829
"k8s.io/apimachinery/pkg/runtime"
2930
"k8s.io/apimachinery/pkg/runtime/serializer"
3031
)
3132

33+
const gcpAuth = "gcp-auth"
34+
3235
var (
3336
runtimeScheme = runtime.NewScheme()
3437
codecs = serializer.NewCodecFactory(runtimeScheme)
@@ -49,44 +52,20 @@ type patchOperation struct {
4952
Value interface{} `json:"value,omitempty"`
5053
}
5154

52-
// Mount in the volumes and add the appropriate env vars to new pods
55+
// mutateHandler mounts in the volumes and adds the appropriate env vars to new pods
5356
func mutateHandler(w http.ResponseWriter, r *http.Request) {
54-
log.Printf("%v\n", r)
55-
56-
var body []byte
57-
if r.Body != nil {
58-
if data, err := ioutil.ReadAll(r.Body); err == nil {
59-
body = data
60-
}
61-
}
62-
63-
if len(body) == 0 {
64-
log.Print("request body was empty, returning")
65-
http.Error(w, "empty body", http.StatusBadRequest)
66-
return
67-
}
68-
69-
var admissionResponse *admissionv1.AdmissionResponse
70-
71-
ar := admissionv1.AdmissionReview{}
72-
if _, _, err := deserializer.Decode(body, nil, &ar); err != nil {
73-
log.Printf("Can't decode body: %v", err)
74-
admissionResponse = &admissionv1.AdmissionResponse{
75-
Result: &metav1.Status{
76-
Message: err.Error(),
77-
},
78-
}
79-
}
57+
ar := getAdmissionReview(w, r)
8058

8159
req := ar.Request
8260
var pod corev1.Pod
8361
if err := json.Unmarshal(req.Object.Raw, &pod); err != nil {
8462
log.Printf("Could not unmarshal raw object: %v", err)
85-
admissionResponse = &admissionv1.AdmissionResponse{
63+
writeError(w, &admissionv1.AdmissionResponse{
8664
Result: &metav1.Status{
8765
Message: err.Error(),
8866
},
89-
}
67+
})
68+
return
9069
}
9170

9271
var patch []patchOperation
@@ -209,93 +188,29 @@ func mutateHandler(w http.ResponseWriter, r *http.Request) {
209188
}
210189
}
211190

212-
patchBytes, err := json.Marshal(patch)
213-
if err != nil {
214-
admissionResponse = &admissionv1.AdmissionResponse{
215-
Result: &metav1.Status{
216-
Message: err.Error(),
217-
},
218-
}
219-
}
220-
221-
if admissionResponse == nil {
222-
admissionResponse = &admissionv1.AdmissionResponse{
223-
Allowed: true,
224-
Patch: patchBytes,
225-
PatchType: func() *admissionv1.PatchType {
226-
pt := admissionv1.PatchTypeJSONPatch
227-
return &pt
228-
}(),
229-
}
230-
}
231-
232-
admissionReview := admissionv1.AdmissionReview{}
233-
if admissionResponse != nil {
234-
admissionReview.Response = admissionResponse
235-
if ar.Request != nil {
236-
admissionReview.Response.UID = ar.Request.UID
237-
}
238-
}
239-
admissionReview.Kind = "AdmissionReview"
240-
admissionReview.APIVersion = "admission.k8s.io/v1"
241-
242-
resp, err := json.Marshal(admissionReview)
243-
if err != nil {
244-
log.Printf("Can't encode response: %v", err)
245-
http.Error(w, fmt.Sprintf("could not encode response: %v", err), http.StatusInternalServerError)
246-
}
247-
log.Printf("Ready to write reponse ...")
248-
if _, err := w.Write(resp); err != nil {
249-
log.Printf("Can't write response: %v", err)
250-
http.Error(w, fmt.Sprintf("could not write response: %v", err), http.StatusInternalServerError)
251-
}
252-
191+
writePatch(w, ar, patch)
253192
}
254193

255-
// Add image pull secret to new service accounts
194+
// serviceaccountHandler adds image pull secret to new service accounts
256195
func serviceaccountHandler(w http.ResponseWriter, r *http.Request) {
257-
log.Printf("%v\n", r)
258-
259-
var body []byte
260-
if r.Body != nil {
261-
if data, err := ioutil.ReadAll(r.Body); err == nil {
262-
body = data
263-
}
264-
}
265-
266-
if len(body) == 0 {
267-
log.Print("request body was empty, returning")
268-
http.Error(w, "empty body", http.StatusBadRequest)
269-
return
270-
}
271-
272-
var admissionResponse *admissionv1.AdmissionResponse
273-
274-
ar := admissionv1.AdmissionReview{}
275-
if _, _, err := deserializer.Decode(body, nil, &ar); err != nil {
276-
log.Printf("Can't decode body: %v", err)
277-
admissionResponse = &admissionv1.AdmissionResponse{
278-
Result: &metav1.Status{
279-
Message: err.Error(),
280-
},
281-
}
282-
}
196+
ar := getAdmissionReview(w, r)
283197

284198
req := ar.Request
285199
var sa corev1.ServiceAccount
286200
if err := json.Unmarshal(req.Object.Raw, &sa); err != nil {
287201
log.Printf("Could not unmarshal raw object: %v", err)
288-
admissionResponse = &admissionv1.AdmissionResponse{
202+
writeError(w, &admissionv1.AdmissionResponse{
289203
Result: &metav1.Status{
290204
Message: err.Error(),
291205
},
292-
}
206+
})
207+
return
293208
}
294209

295210
// Make sure the gcp-auth secret exists before adding it as a pull secret
296211
hasSecret := false
297212
for _, s := range sa.Secrets {
298-
if s.Name == "gcp-auth" {
213+
if s.Name == gcpAuth {
299214
hasSecret = true
300215
break
301216
}
@@ -304,7 +219,7 @@ func serviceaccountHandler(w http.ResponseWriter, r *http.Request) {
304219
var patch []patchOperation
305220

306221
if hasSecret {
307-
ips := corev1.LocalObjectReference{Name: "gcp-auth"}
222+
ips := corev1.LocalObjectReference{Name: gcpAuth}
308223
if len(sa.ImagePullSecrets) == 0 {
309224
patch = []patchOperation{{
310225
Op: "add",
@@ -320,42 +235,90 @@ func serviceaccountHandler(w http.ResponseWriter, r *http.Request) {
320235
}
321236
}
322237

238+
writePatch(w, ar, patch)
239+
}
240+
241+
// getAdmissionReview reads and validates an inbound request and returns an admissionReview
242+
func getAdmissionReview(w http.ResponseWriter, r *http.Request) *admissionv1.AdmissionReview {
243+
log.Printf("%v\n", r)
244+
245+
var body []byte
246+
if r.Body != nil {
247+
if data, err := ioutil.ReadAll(r.Body); err == nil {
248+
body = data
249+
}
250+
}
251+
252+
if len(body) == 0 {
253+
log.Print("request body was empty, returning")
254+
http.Error(w, "empty body", http.StatusBadRequest)
255+
return nil
256+
}
257+
258+
ar := admissionv1.AdmissionReview{}
259+
if _, _, err := deserializer.Decode(body, nil, &ar); err != nil {
260+
log.Printf("Can't decode body: %v", err)
261+
writeError(w, &admissionv1.AdmissionResponse{
262+
Result: &metav1.Status{
263+
Message: err.Error(),
264+
},
265+
})
266+
return nil
267+
}
268+
return &ar
269+
}
270+
271+
// writeError writes an error response
272+
func writeError(w http.ResponseWriter, admissionResp *admissionv1.AdmissionResponse) {
273+
admissionReview := admissionv1.AdmissionReview{
274+
Response: admissionResp,
275+
}
276+
writeResp(w, admissionReview)
277+
}
278+
279+
// writePatch writes a patch response
280+
func writePatch(w http.ResponseWriter, ar *admissionv1.AdmissionReview, patch []patchOperation) {
323281
patchBytes, err := json.Marshal(patch)
324282
if err != nil {
325-
admissionResponse = &admissionv1.AdmissionResponse{
283+
writeError(w, &admissionv1.AdmissionResponse{
326284
Result: &metav1.Status{
327285
Message: err.Error(),
328286
},
329-
}
287+
})
288+
return
330289
}
331290

332-
if admissionResponse == nil {
333-
admissionResponse = &admissionv1.AdmissionResponse{
334-
Allowed: true,
335-
Patch: patchBytes,
336-
PatchType: func() *admissionv1.PatchType {
337-
pt := admissionv1.PatchTypeJSONPatch
338-
return &pt
339-
}(),
340-
}
291+
admissionResp := &admissionv1.AdmissionResponse{
292+
Allowed: true,
293+
Patch: patchBytes,
294+
PatchType: func() *admissionv1.PatchType {
295+
pt := admissionv1.PatchTypeJSONPatch
296+
return &pt
297+
}(),
341298
}
342299

343-
admissionReview := admissionv1.AdmissionReview{}
344-
if admissionResponse != nil {
345-
admissionReview.Response = admissionResponse
346-
if ar.Request != nil {
347-
admissionReview.Response.UID = ar.Request.UID
348-
}
300+
admissionReview := admissionv1.AdmissionReview{
301+
Response: admissionResp,
302+
}
303+
if ar.Request != nil {
304+
admissionReview.Response.UID = ar.Request.UID
349305
}
306+
307+
writeResp(w, admissionReview)
308+
}
309+
310+
// writeResp writes an admissionReview response
311+
func writeResp(w http.ResponseWriter, admissionReview admissionv1.AdmissionReview) {
350312
admissionReview.Kind = "AdmissionReview"
351313
admissionReview.APIVersion = "admission.k8s.io/v1"
352314

315+
log.Printf("Ready to marshal response ...")
353316
resp, err := json.Marshal(admissionReview)
354317
if err != nil {
355318
log.Printf("Can't encode response: %v", err)
356319
http.Error(w, fmt.Sprintf("could not encode response: %v", err), http.StatusInternalServerError)
357320
}
358-
log.Printf("Ready to write reponse ...")
321+
log.Printf("Ready to write response ...")
359322
if _, err := w.Write(resp); err != nil {
360323
log.Printf("Can't write response: %v", err)
361324
http.Error(w, fmt.Sprintf("could not write response: %v", err), http.StatusInternalServerError)

0 commit comments

Comments
 (0)