@@ -25,10 +25,13 @@ import (
25
25
admissionv1 "k8s.io/api/admission/v1"
26
26
corev1 "k8s.io/api/core/v1"
27
27
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
28
+
28
29
"k8s.io/apimachinery/pkg/runtime"
29
30
"k8s.io/apimachinery/pkg/runtime/serializer"
30
31
)
31
32
33
+ const gcpAuth = "gcp-auth"
34
+
32
35
var (
33
36
runtimeScheme = runtime .NewScheme ()
34
37
codecs = serializer .NewCodecFactory (runtimeScheme )
@@ -49,44 +52,20 @@ type patchOperation struct {
49
52
Value interface {} `json:"value,omitempty"`
50
53
}
51
54
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
53
56
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 )
80
58
81
59
req := ar .Request
82
60
var pod corev1.Pod
83
61
if err := json .Unmarshal (req .Object .Raw , & pod ); err != nil {
84
62
log .Printf ("Could not unmarshal raw object: %v" , err )
85
- admissionResponse = & admissionv1.AdmissionResponse {
63
+ writeError ( w , & admissionv1.AdmissionResponse {
86
64
Result : & metav1.Status {
87
65
Message : err .Error (),
88
66
},
89
- }
67
+ })
68
+ return
90
69
}
91
70
92
71
var patch []patchOperation
@@ -209,93 +188,29 @@ func mutateHandler(w http.ResponseWriter, r *http.Request) {
209
188
}
210
189
}
211
190
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 )
253
192
}
254
193
255
- // Add image pull secret to new service accounts
194
+ // serviceaccountHandler adds image pull secret to new service accounts
256
195
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 )
283
197
284
198
req := ar .Request
285
199
var sa corev1.ServiceAccount
286
200
if err := json .Unmarshal (req .Object .Raw , & sa ); err != nil {
287
201
log .Printf ("Could not unmarshal raw object: %v" , err )
288
- admissionResponse = & admissionv1.AdmissionResponse {
202
+ writeError ( w , & admissionv1.AdmissionResponse {
289
203
Result : & metav1.Status {
290
204
Message : err .Error (),
291
205
},
292
- }
206
+ })
207
+ return
293
208
}
294
209
295
210
// Make sure the gcp-auth secret exists before adding it as a pull secret
296
211
hasSecret := false
297
212
for _ , s := range sa .Secrets {
298
- if s .Name == "gcp-auth" {
213
+ if s .Name == gcpAuth {
299
214
hasSecret = true
300
215
break
301
216
}
@@ -304,7 +219,7 @@ func serviceaccountHandler(w http.ResponseWriter, r *http.Request) {
304
219
var patch []patchOperation
305
220
306
221
if hasSecret {
307
- ips := corev1.LocalObjectReference {Name : "gcp-auth" }
222
+ ips := corev1.LocalObjectReference {Name : gcpAuth }
308
223
if len (sa .ImagePullSecrets ) == 0 {
309
224
patch = []patchOperation {{
310
225
Op : "add" ,
@@ -320,42 +235,90 @@ func serviceaccountHandler(w http.ResponseWriter, r *http.Request) {
320
235
}
321
236
}
322
237
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 ) {
323
281
patchBytes , err := json .Marshal (patch )
324
282
if err != nil {
325
- admissionResponse = & admissionv1.AdmissionResponse {
283
+ writeError ( w , & admissionv1.AdmissionResponse {
326
284
Result : & metav1.Status {
327
285
Message : err .Error (),
328
286
},
329
- }
287
+ })
288
+ return
330
289
}
331
290
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
+ }(),
341
298
}
342
299
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
349
305
}
306
+
307
+ writeResp (w , admissionReview )
308
+ }
309
+
310
+ // writeResp writes an admissionReview response
311
+ func writeResp (w http.ResponseWriter , admissionReview admissionv1.AdmissionReview ) {
350
312
admissionReview .Kind = "AdmissionReview"
351
313
admissionReview .APIVersion = "admission.k8s.io/v1"
352
314
315
+ log .Printf ("Ready to marshal response ..." )
353
316
resp , err := json .Marshal (admissionReview )
354
317
if err != nil {
355
318
log .Printf ("Can't encode response: %v" , err )
356
319
http .Error (w , fmt .Sprintf ("could not encode response: %v" , err ), http .StatusInternalServerError )
357
320
}
358
- log .Printf ("Ready to write reponse ..." )
321
+ log .Printf ("Ready to write response ..." )
359
322
if _ , err := w .Write (resp ); err != nil {
360
323
log .Printf ("Can't write response: %v" , err )
361
324
http .Error (w , fmt .Sprintf ("could not write response: %v" , err ), http .StatusInternalServerError )
0 commit comments