@@ -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
@@ -204,93 +183,29 @@ func mutateHandler(w http.ResponseWriter, r *http.Request) {
204
183
}
205
184
}
206
185
207
- patchBytes , err := json .Marshal (patch )
208
- if err != nil {
209
- admissionResponse = & admissionv1.AdmissionResponse {
210
- Result : & metav1.Status {
211
- Message : err .Error (),
212
- },
213
- }
214
- }
215
-
216
- if admissionResponse == nil {
217
- admissionResponse = & admissionv1.AdmissionResponse {
218
- Allowed : true ,
219
- Patch : patchBytes ,
220
- PatchType : func () * admissionv1.PatchType {
221
- pt := admissionv1 .PatchTypeJSONPatch
222
- return & pt
223
- }(),
224
- }
225
- }
226
-
227
- admissionReview := admissionv1.AdmissionReview {}
228
- if admissionResponse != nil {
229
- admissionReview .Response = admissionResponse
230
- if ar .Request != nil {
231
- admissionReview .Response .UID = ar .Request .UID
232
- }
233
- }
234
- admissionReview .Kind = "AdmissionReview"
235
- admissionReview .APIVersion = "admission.k8s.io/v1"
236
-
237
- resp , err := json .Marshal (admissionReview )
238
- if err != nil {
239
- log .Printf ("Can't encode response: %v" , err )
240
- http .Error (w , fmt .Sprintf ("could not encode response: %v" , err ), http .StatusInternalServerError )
241
- }
242
- log .Printf ("Ready to write reponse ..." )
243
- if _ , err := w .Write (resp ); err != nil {
244
- log .Printf ("Can't write response: %v" , err )
245
- http .Error (w , fmt .Sprintf ("could not write response: %v" , err ), http .StatusInternalServerError )
246
- }
247
-
186
+ writePatch (w , ar , patch )
248
187
}
249
188
250
- // Add image pull secret to new service accounts
189
+ // serviceaccountHandler adds image pull secret to new service accounts
251
190
func serviceaccountHandler (w http.ResponseWriter , r * http.Request ) {
252
- log .Printf ("%v\n " , r )
253
-
254
- var body []byte
255
- if r .Body != nil {
256
- if data , err := ioutil .ReadAll (r .Body ); err == nil {
257
- body = data
258
- }
259
- }
260
-
261
- if len (body ) == 0 {
262
- log .Print ("request body was empty, returning" )
263
- http .Error (w , "empty body" , http .StatusBadRequest )
264
- return
265
- }
266
-
267
- var admissionResponse * admissionv1.AdmissionResponse
268
-
269
- ar := admissionv1.AdmissionReview {}
270
- if _ , _ , err := deserializer .Decode (body , nil , & ar ); err != nil {
271
- log .Printf ("Can't decode body: %v" , err )
272
- admissionResponse = & admissionv1.AdmissionResponse {
273
- Result : & metav1.Status {
274
- Message : err .Error (),
275
- },
276
- }
277
- }
191
+ ar := getAdmissionReview (w , r )
278
192
279
193
req := ar .Request
280
194
var sa corev1.ServiceAccount
281
195
if err := json .Unmarshal (req .Object .Raw , & sa ); err != nil {
282
196
log .Printf ("Could not unmarshal raw object: %v" , err )
283
- admissionResponse = & admissionv1.AdmissionResponse {
197
+ writeError ( w , & admissionv1.AdmissionResponse {
284
198
Result : & metav1.Status {
285
199
Message : err .Error (),
286
200
},
287
- }
201
+ })
202
+ return
288
203
}
289
204
290
205
// Make sure the gcp-auth secret exists before adding it as a pull secret
291
206
hasSecret := false
292
207
for _ , s := range sa .Secrets {
293
- if s .Name == "gcp-auth" {
208
+ if s .Name == gcpAuth {
294
209
hasSecret = true
295
210
break
296
211
}
@@ -299,7 +214,7 @@ func serviceaccountHandler(w http.ResponseWriter, r *http.Request) {
299
214
var patch []patchOperation
300
215
301
216
if hasSecret {
302
- ips := corev1.LocalObjectReference {Name : "gcp-auth" }
217
+ ips := corev1.LocalObjectReference {Name : gcpAuth }
303
218
if len (sa .ImagePullSecrets ) == 0 {
304
219
patch = []patchOperation {{
305
220
Op : "add" ,
@@ -315,42 +230,90 @@ func serviceaccountHandler(w http.ResponseWriter, r *http.Request) {
315
230
}
316
231
}
317
232
233
+ writePatch (w , ar , patch )
234
+ }
235
+
236
+ // getAdmissionReview reads and validates an inbound request and returns an admissionReview
237
+ func getAdmissionReview (w http.ResponseWriter , r * http.Request ) * admissionv1.AdmissionReview {
238
+ log .Printf ("%v\n " , r )
239
+
240
+ var body []byte
241
+ if r .Body != nil {
242
+ if data , err := ioutil .ReadAll (r .Body ); err == nil {
243
+ body = data
244
+ }
245
+ }
246
+
247
+ if len (body ) == 0 {
248
+ log .Print ("request body was empty, returning" )
249
+ http .Error (w , "empty body" , http .StatusBadRequest )
250
+ return nil
251
+ }
252
+
253
+ ar := admissionv1.AdmissionReview {}
254
+ if _ , _ , err := deserializer .Decode (body , nil , & ar ); err != nil {
255
+ log .Printf ("Can't decode body: %v" , err )
256
+ writeError (w , & admissionv1.AdmissionResponse {
257
+ Result : & metav1.Status {
258
+ Message : err .Error (),
259
+ },
260
+ })
261
+ return nil
262
+ }
263
+ return & ar
264
+ }
265
+
266
+ // writeError writes an error response
267
+ func writeError (w http.ResponseWriter , admissionResp * admissionv1.AdmissionResponse ) {
268
+ admissionReview := admissionv1.AdmissionReview {
269
+ Response : admissionResp ,
270
+ }
271
+ writeResp (w , admissionReview )
272
+ }
273
+
274
+ // writePatch writes a patch response
275
+ func writePatch (w http.ResponseWriter , ar * admissionv1.AdmissionReview , patch []patchOperation ) {
318
276
patchBytes , err := json .Marshal (patch )
319
277
if err != nil {
320
- admissionResponse = & admissionv1.AdmissionResponse {
278
+ writeError ( w , & admissionv1.AdmissionResponse {
321
279
Result : & metav1.Status {
322
280
Message : err .Error (),
323
281
},
324
- }
282
+ })
283
+ return
325
284
}
326
285
327
- if admissionResponse == nil {
328
- admissionResponse = & admissionv1.AdmissionResponse {
329
- Allowed : true ,
330
- Patch : patchBytes ,
331
- PatchType : func () * admissionv1.PatchType {
332
- pt := admissionv1 .PatchTypeJSONPatch
333
- return & pt
334
- }(),
335
- }
286
+ admissionResp := & admissionv1.AdmissionResponse {
287
+ Allowed : true ,
288
+ Patch : patchBytes ,
289
+ PatchType : func () * admissionv1.PatchType {
290
+ pt := admissionv1 .PatchTypeJSONPatch
291
+ return & pt
292
+ }(),
336
293
}
337
294
338
- admissionReview := admissionv1.AdmissionReview {}
339
- if admissionResponse != nil {
340
- admissionReview .Response = admissionResponse
341
- if ar .Request != nil {
342
- admissionReview .Response .UID = ar .Request .UID
343
- }
295
+ admissionReview := admissionv1.AdmissionReview {
296
+ Response : admissionResp ,
297
+ }
298
+ if ar .Request != nil {
299
+ admissionReview .Response .UID = ar .Request .UID
344
300
}
301
+
302
+ writeResp (w , admissionReview )
303
+ }
304
+
305
+ // writeResp writes an admissionReview response
306
+ func writeResp (w http.ResponseWriter , admissionReview admissionv1.AdmissionReview ) {
345
307
admissionReview .Kind = "AdmissionReview"
346
308
admissionReview .APIVersion = "admission.k8s.io/v1"
347
309
310
+ log .Printf ("Ready to marshal response ..." )
348
311
resp , err := json .Marshal (admissionReview )
349
312
if err != nil {
350
313
log .Printf ("Can't encode response: %v" , err )
351
314
http .Error (w , fmt .Sprintf ("could not encode response: %v" , err ), http .StatusInternalServerError )
352
315
}
353
- log .Printf ("Ready to write reponse ..." )
316
+ log .Printf ("Ready to write response ..." )
354
317
if _ , err := w .Write (resp ); err != nil {
355
318
log .Printf ("Can't write response: %v" , err )
356
319
http .Error (w , fmt .Sprintf ("could not write response: %v" , err ), http .StatusInternalServerError )
0 commit comments