|
57 | 57 | )
|
58 | 58 |
|
59 | 59 | const (
|
60 |
| - injectionStatus = "operator.1password.io/status" |
61 |
| - injectAnnotation = "operator.1password.io/inject" |
62 |
| - versionAnnotation = "operator.1password.io/version" |
| 60 | + injectionStatus = "operator.1password.io/status" |
| 61 | + injectAnnotation = "operator.1password.io/inject" |
| 62 | + injectorInitFirstAnnotation = "operator.1password.io/injector-init-first" |
| 63 | + versionAnnotation = "operator.1password.io/version" |
63 | 64 | )
|
64 | 65 |
|
65 | 66 | type SecretInjector struct {
|
@@ -100,21 +101,20 @@ func mutationRequired(metadata *metav1.ObjectMeta) bool {
|
100 | 101 | }
|
101 | 102 |
|
102 | 103 | func addContainers(target, added []corev1.Container, basePath string) (patch []patchOperation) {
|
103 |
| - first := len(target) == 0 |
104 |
| - var value interface{} |
105 |
| - for _, add := range added { |
106 |
| - value = add |
107 |
| - path := basePath |
108 |
| - if first { |
109 |
| - first = false |
110 |
| - value = []corev1.Container{add} |
111 |
| - } else { |
112 |
| - path = path + "/-" |
113 |
| - } |
| 104 | + if len(target) == 0 { |
114 | 105 | patch = append(patch, patchOperation{
|
115 | 106 | Op: "add",
|
116 |
| - Path: path, |
117 |
| - Value: value, |
| 107 | + Path: basePath, |
| 108 | + Value: added, |
| 109 | + }) |
| 110 | + return patch |
| 111 | + } |
| 112 | + |
| 113 | + for _, c := range added { |
| 114 | + patch = append(patch, patchOperation{ |
| 115 | + Op: "add", |
| 116 | + Path: basePath + "/-", |
| 117 | + Value: c, |
118 | 118 | })
|
119 | 119 | }
|
120 | 120 | return patch
|
@@ -210,24 +210,40 @@ func (s *SecretInjector) mutate(ar *admissionv1.AdmissionReview) *admissionv1.Ad
|
210 | 210 | mutated := false
|
211 | 211 |
|
212 | 212 | var patch []patchOperation
|
213 |
| - for i := range pod.Spec.InitContainers { |
214 |
| - c := pod.Spec.InitContainers[i] |
215 |
| - _, mutate := containers[c.Name] |
216 |
| - if !mutate { |
217 |
| - continue |
218 |
| - } |
219 |
| - didMutate, initContainerPatch, err := s.mutateContainer(ctx, &c, i) |
220 |
| - if err != nil { |
221 |
| - return &admissionv1.AdmissionResponse{ |
222 |
| - Result: &metav1.Status{ |
223 |
| - Message: err.Error(), |
224 |
| - }, |
| 213 | + |
| 214 | + mutateInitContainers := false |
| 215 | + if value, exists := pod.Annotations[injectorInitFirstAnnotation]; exists && strings.ToLower(value) == "true" { |
| 216 | + mutateInitContainers = true |
| 217 | + } |
| 218 | + |
| 219 | + if mutateInitContainers { |
| 220 | + for i := range pod.Spec.InitContainers { |
| 221 | + c := pod.Spec.InitContainers[i] |
| 222 | + // do not mutate our own init container |
| 223 | + if c.Name == "copy-op-bin" { |
| 224 | + continue |
225 | 225 | }
|
| 226 | + _, mutate := containers[c.Name] |
| 227 | + if !mutate { |
| 228 | + continue |
| 229 | + } |
| 230 | + didMutate, initContainerPatch, err := s.mutateContainer(ctx, &c, i) |
| 231 | + if err != nil { |
| 232 | + return &admissionv1.AdmissionResponse{ |
| 233 | + Result: &metav1.Status{ |
| 234 | + Message: err.Error(), |
| 235 | + }, |
| 236 | + } |
| 237 | + } |
| 238 | + if didMutate { |
| 239 | + mutated = true |
| 240 | + } |
| 241 | + |
| 242 | + for i := range initContainerPatch { |
| 243 | + initContainerPatch[i].Path = strings.Replace(initContainerPatch[i].Path, "/spec/containers", "/spec/initContainers", 1) |
| 244 | + } |
| 245 | + patch = append(patch, initContainerPatch...) |
226 | 246 | }
|
227 |
| - if didMutate { |
228 |
| - mutated = true |
229 |
| - } |
230 |
| - patch = append(patch, initContainerPatch...) |
231 | 247 | }
|
232 | 248 |
|
233 | 249 | for i := range pod.Spec.Containers {
|
@@ -297,15 +313,35 @@ func (s *SecretInjector) mutate(ar *admissionv1.AdmissionReview) *admissionv1.Ad
|
297 | 313 |
|
298 | 314 | // create mutation patch for resources
|
299 | 315 | func createOPCLIPatch(pod *corev1.Pod, containers []corev1.Container, patch []patchOperation) ([]byte, error) {
|
300 |
| - |
301 | 316 | annotations := map[string]string{injectionStatus: "injected"}
|
302 | 317 | patch = append(patch, addVolume(pod.Spec.Volumes, []corev1.Volume{binVolume}, "/spec/volumes")...)
|
303 |
| - patch = append(patch, addContainers(pod.Spec.InitContainers, containers, "/spec/initContainers")...) |
304 |
| - patch = append(patch, updateAnnotation(pod.Annotations, annotations)...) |
305 | 318 |
|
| 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")...) |
| 323 | + } |
| 324 | + |
| 325 | + patch = append(patch, updateAnnotation(pod.Annotations, annotations)...) |
306 | 326 | return json.Marshal(patch)
|
307 | 327 | }
|
308 | 328 |
|
| 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) |
| 333 | + } |
| 334 | + |
| 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 |
| 343 | +} |
| 344 | + |
309 | 345 | func isEnvVarSetup(envVarName string) func(c *corev1.Container) bool {
|
310 | 346 | return func(container *corev1.Container) bool {
|
311 | 347 | envVar := findContainerEnvVarByName(envVarName, container)
|
|
0 commit comments