@@ -18,6 +18,13 @@ import (
18
18
"k8s.io/apimachinery/pkg/runtime/serializer"
19
19
)
20
20
21
+ type ContainerType string
22
+
23
+ const (
24
+ InitContainer ContainerType = "initContainer"
25
+ Container ContainerType = "container"
26
+ )
27
+
21
28
const (
22
29
connectHostEnv = "OP_CONNECT_HOST"
23
30
connectTokenEnv = "OP_CONNECT_TOKEN"
@@ -100,23 +107,26 @@ func mutationRequired(metadata *metav1.ObjectMeta) bool {
100
107
return required
101
108
}
102
109
103
- func addContainers (target , added []corev1.Container , basePath string ) (patch []patchOperation ) {
104
- if len (target ) == 0 {
105
- patch = append (patch , patchOperation {
106
- Op : "add" ,
107
- Path : basePath ,
108
- Value : added ,
109
- })
110
- return patch
111
- }
110
+ func addContainers (target , containers []corev1.Container , basePath string ) (patch []patchOperation ) {
111
+ first := len (target ) == 0
112
+ var value interface {}
113
+ for _ , c := range containers {
114
+ value = c
115
+ path := basePath
116
+ if first {
117
+ first = false
118
+ value = []corev1.Container {c }
119
+ } else {
120
+ path = path + "/-"
121
+ }
112
122
113
- for _ , c := range added {
114
123
patch = append (patch , patchOperation {
115
124
Op : "add" ,
116
- Path : basePath + "/-" ,
117
- Value : c ,
125
+ Path : path ,
126
+ Value : value ,
118
127
})
119
128
}
129
+
120
130
return patch
121
131
}
122
132
@@ -212,7 +222,7 @@ func (s *SecretInjector) mutate(ar *admissionv1.AdmissionReview) *admissionv1.Ad
212
222
var patch []patchOperation
213
223
214
224
mutateInitContainers := false
215
- if value , exists := pod .Annotations [injectorInitFirstAnnotation ]; exists && strings .ToLower (value ) == "true" {
225
+ if val , ok := pod .Annotations [injectorInitFirstAnnotation ]; ok && strings .ToLower (val ) == "true" {
216
226
mutateInitContainers = true
217
227
}
218
228
@@ -227,7 +237,7 @@ func (s *SecretInjector) mutate(ar *admissionv1.AdmissionReview) *admissionv1.Ad
227
237
if ! mutate {
228
238
continue
229
239
}
230
- didMutate , initContainerPatch , err := s .mutateContainer (ctx , & c , i )
240
+ didMutate , initContainerPatch , err := s .mutateContainer (ctx , & c , i , InitContainer )
231
241
if err != nil {
232
242
return & admissionv1.AdmissionResponse {
233
243
Result : & metav1.Status {
@@ -253,7 +263,7 @@ func (s *SecretInjector) mutate(ar *admissionv1.AdmissionReview) *admissionv1.Ad
253
263
continue
254
264
}
255
265
256
- didMutate , containerPatch , err := s .mutateContainer (ctx , & c , i )
266
+ didMutate , containerPatch , err := s .mutateContainer (ctx , & c , i , Container )
257
267
if err != nil {
258
268
glog .Error ("Error occurred mutating container for secret injection: " , err )
259
269
return & admissionv1.AdmissionResponse {
@@ -316,30 +326,22 @@ func createOPCLIPatch(pod *corev1.Pod, containers []corev1.Container, patch []pa
316
326
annotations := map [string ]string {injectionStatus : "injected" }
317
327
patch = append (patch , addVolume (pod .Spec .Volumes , []corev1.Volume {binVolume }, "/spec/volumes" )... )
318
328
319
- if value , exists := pod .Annotations [injectorInitFirstAnnotation ]; exists && strings .ToLower (value ) == "true" {
320
- patch = append (patch , prependContainers (pod .Spec .InitContainers , containers , "/spec/initContainers" )... )
321
- } else {
322
- patch = append (patch , addContainers (pod .Spec .InitContainers , containers , "/spec/initContainers" )... )
329
+ initFirst := false
330
+ if val , ok := pod .Annotations [injectorInitFirstAnnotation ]; ok && strings .ToLower (val ) == "true" {
331
+ initFirst = true
323
332
}
324
333
325
- patch = append (patch , updateAnnotation (pod .Annotations , annotations )... )
326
- return json .Marshal (patch )
327
- }
334
+ if initFirst {
335
+ if len (pod .Spec .InitContainers ) > 0 {
336
+ patch = append (patch , removeContainers (getContainerPath (InitContainer ))... )
337
+ }
328
338
329
- // adds containers to the beginning of the target
330
- func prependContainers (target , added []corev1.Container , basePath string ) (patch []patchOperation ) {
331
- if len (target ) == 0 {
332
- return addContainers (target , added , basePath )
339
+ containers = append (containers , pod .Spec .InitContainers ... )
333
340
}
334
341
335
- for i := len (added ) - 1 ; i >= 0 ; i -- {
336
- patch = append (patch , patchOperation {
337
- Op : "add" ,
338
- Path : basePath + "/0" ,
339
- Value : added [i ],
340
- })
341
- }
342
- return patch
342
+ patch = append (patch , addContainers (pod .Spec .InitContainers , containers , "/spec/initContainers" )... )
343
+ patch = append (patch , updateAnnotation (pod .Annotations , annotations )... )
344
+ return json .Marshal (patch )
343
345
}
344
346
345
347
func isEnvVarSetup (envVarName string ) func (c * corev1.Container ) bool {
@@ -386,7 +388,7 @@ func checkOPCLIEnvSetup(container *corev1.Container) {
386
388
}
387
389
}
388
390
389
- func passUserAgentInformationToCLI (container * corev1.Container , containerIndex int ) []patchOperation {
391
+ func passUserAgentInformationToCLI (container * corev1.Container , containerIndex int , containerType ContainerType ) []patchOperation {
390
392
userAgentEnvs := []corev1.EnvVar {
391
393
{
392
394
Name : "OP_INTEGRATION_NAME" ,
@@ -402,11 +404,11 @@ func passUserAgentInformationToCLI(container *corev1.Container, containerIndex i
402
404
},
403
405
}
404
406
405
- return setEnvironment (* container , containerIndex , userAgentEnvs , "/spec/containers" )
407
+ return setEnvironment (* container , containerIndex , userAgentEnvs , getContainerPath ( containerType ) )
406
408
}
407
409
408
410
// mutates the container to allow for secrets to be injected into the container via the op cli
409
- func (s * SecretInjector ) mutateContainer (cxt context.Context , container * corev1.Container , containerIndex int ) (bool , []patchOperation , error ) {
411
+ func (s * SecretInjector ) mutateContainer (cxt context.Context , container * corev1.Container , containerIndex int , containerType ContainerType ) (bool , []patchOperation , error ) {
410
412
// prepending op run command to the container command so that secrets are injected before the main process is started
411
413
if len (container .Command ) == 0 {
412
414
return false , nil , fmt .Errorf ("not attaching OP to the container %s: the podspec does not define a command" , container .Name )
@@ -418,15 +420,15 @@ func (s *SecretInjector) mutateContainer(cxt context.Context, container *corev1.
418
420
var patch []patchOperation
419
421
420
422
// adding the cli to the container using a volume mount
421
- path := fmt .Sprintf ("%s/%d/volumeMounts" , "/spec/containers" , containerIndex )
423
+ path := fmt .Sprintf ("%s/%d/volumeMounts" , getContainerPath ( containerType ) , containerIndex )
422
424
patch = append (patch , patchOperation {
423
425
Op : "add" ,
424
426
Path : path ,
425
427
Value : append (container .VolumeMounts , binVolumeMount ),
426
428
})
427
429
428
430
// replacing the container command with a command prepended with op run
429
- path = fmt .Sprintf ("%s/%d/command" , "/spec/containers" , containerIndex )
431
+ path = fmt .Sprintf ("%s/%d/command" , getContainerPath ( containerType ) , containerIndex )
430
432
patch = append (patch , patchOperation {
431
433
Op : "replace" ,
432
434
Path : path ,
@@ -436,7 +438,7 @@ func (s *SecretInjector) mutateContainer(cxt context.Context, container *corev1.
436
438
checkOPCLIEnvSetup (container )
437
439
438
440
//creating patch for passing User-Agent information to the CLI.
439
- patch = append (patch , passUserAgentInformationToCLI (container , containerIndex )... )
441
+ patch = append (patch , passUserAgentInformationToCLI (container , containerIndex , containerType )... )
440
442
return true , patch , nil
441
443
}
442
444
@@ -521,3 +523,20 @@ func (s *SecretInjector) Serve(w http.ResponseWriter, r *http.Request) {
521
523
http .Error (w , fmt .Sprintf ("could not write response: %v" , err ), http .StatusInternalServerError )
522
524
}
523
525
}
526
+
527
+ func getContainerPath (containerType ContainerType ) string {
528
+ if containerType == InitContainer {
529
+ return "/spec/initContainers"
530
+ }
531
+ return "/spec/containers"
532
+ }
533
+
534
+ func removeContainers (path string ) []patchOperation {
535
+ return []patchOperation {
536
+ {
537
+ Op : "remove" ,
538
+ Path : path ,
539
+ Value : nil ,
540
+ },
541
+ }
542
+ }
0 commit comments