9
9
"context"
10
10
"crypto/sha1"
11
11
"fmt"
12
+ "regexp"
12
13
"sort"
13
14
"strings"
14
15
@@ -57,19 +58,64 @@ func (b *ServiceBindingProjection) Do(ctx context.Context, ps *duckv1.WithPod) {
57
58
b .Undo (ctx , ps )
58
59
59
60
injectedSecrets , injectedVolumes := b .injectedValues (ps )
61
+ key := b .annotationKey ()
60
62
61
63
sb := b .Spec .Binding
62
64
63
65
volume := corev1.Volume {
64
66
Name : fmt .Sprintf ("%s%x" , bindingVolumePrefix , sha1 .Sum ([]byte (sb .Name ))),
65
67
VolumeSource : corev1.VolumeSource {
66
- Secret : & corev1.SecretVolumeSource {
67
- SecretName : sb .Name ,
68
+ Projected : & corev1.ProjectedVolumeSource {
69
+ Sources : []corev1.VolumeProjection {
70
+ {
71
+ Secret : & corev1.SecretProjection {
72
+ LocalObjectReference : corev1.LocalObjectReference {
73
+ Name : sb .Name ,
74
+ },
75
+ },
76
+ },
77
+ },
68
78
},
69
79
},
70
80
}
81
+ if b .Spec .Type != "" {
82
+ typeAnnotation := fmt .Sprintf ("%s-type" , key )
83
+ ps .Spec .Template .Annotations [typeAnnotation ] = b .Spec .Type
84
+ volume .VolumeSource .Projected .Sources = append (volume .VolumeSource .Projected .Sources ,
85
+ corev1.VolumeProjection {
86
+ DownwardAPI : & corev1.DownwardAPIProjection {
87
+ Items : []corev1.DownwardAPIVolumeFile {
88
+ {
89
+ FieldRef : & corev1.ObjectFieldSelector {
90
+ FieldPath : fmt .Sprintf ("metadata.annotations['%s']" , typeAnnotation ),
91
+ },
92
+ Path : "type" ,
93
+ },
94
+ },
95
+ },
96
+ },
97
+ )
98
+ }
99
+ if b .Spec .Provider != "" {
100
+ providerAnnotation := fmt .Sprintf ("%s-provider" , key )
101
+ ps .Spec .Template .Annotations [providerAnnotation ] = b .Spec .Provider
102
+ volume .VolumeSource .Projected .Sources = append (volume .VolumeSource .Projected .Sources ,
103
+ corev1.VolumeProjection {
104
+ DownwardAPI : & corev1.DownwardAPIProjection {
105
+ Items : []corev1.DownwardAPIVolumeFile {
106
+ {
107
+ FieldRef : & corev1.ObjectFieldSelector {
108
+ FieldPath : fmt .Sprintf ("metadata.annotations['%s']" , providerAnnotation ),
109
+ },
110
+ Path : "provider" ,
111
+ },
112
+ },
113
+ },
114
+ },
115
+ )
116
+ }
71
117
ps .Spec .Template .Spec .Volumes = append (ps .Spec .Template .Spec .Volumes , volume )
72
- injectedSecrets .Insert (volume . Secret . SecretName )
118
+ injectedSecrets .Insert (sb . Name )
73
119
injectedVolumes .Insert (volume .Name )
74
120
sort .SliceStable (ps .Spec .Template .Spec .Volumes , func (i , j int ) bool {
75
121
iname := ps .Spec .Template .Spec .Volumes [i ].Name
@@ -81,7 +127,7 @@ func (b *ServiceBindingProjection) Do(ctx context.Context, ps *duckv1.WithPod) {
81
127
return iname < jname
82
128
})
83
129
// track which secret is injected, so it can be removed when no longer used
84
- ps .Annotations [b . annotationKey () ] = volume . Secret . SecretName
130
+ ps .Annotations [key ] = sb . Name
85
131
86
132
for i := range ps .Spec .Template .Spec .InitContainers {
87
133
c := & ps .Spec .Template .Spec .InitContainers [i ]
@@ -98,6 +144,7 @@ func (b *ServiceBindingProjection) Do(ctx context.Context, ps *duckv1.WithPod) {
98
144
}
99
145
100
146
func (b * ServiceBindingProjection ) doContainer (ctx context.Context , ps * duckv1.WithPod , c * corev1.Container , bindingVolume , secretName string , allInjectedVolumes , allInjectedSecrets sets.String ) {
147
+ key := b .annotationKey ()
101
148
mountPath := ""
102
149
// lookup predefined mount path
103
150
for _ , e := range c .Env {
@@ -133,6 +180,30 @@ func (b *ServiceBindingProjection) doContainer(ctx context.Context, ps *duckv1.W
133
180
134
181
if len (b .Spec .Env ) != 0 {
135
182
for _ , e := range b .Spec .Env {
183
+ if e .Key == "type" && b .Spec .Type != "" {
184
+ typeAnnotation := fmt .Sprintf ("%s-type" , key )
185
+ c .Env = append (c .Env , corev1.EnvVar {
186
+ Name : e .Name ,
187
+ ValueFrom : & corev1.EnvVarSource {
188
+ FieldRef : & corev1.ObjectFieldSelector {
189
+ FieldPath : fmt .Sprintf ("metadata.annotations['%s']" , typeAnnotation ),
190
+ },
191
+ },
192
+ })
193
+ continue
194
+ }
195
+ if e .Key == "provider" && b .Spec .Provider != "" {
196
+ providerAnnotation := fmt .Sprintf ("%s-provider" , key )
197
+ c .Env = append (c .Env , corev1.EnvVar {
198
+ Name : e .Name ,
199
+ ValueFrom : & corev1.EnvVarSource {
200
+ FieldRef : & corev1.ObjectFieldSelector {
201
+ FieldPath : fmt .Sprintf ("metadata.annotations['%s']" , providerAnnotation ),
202
+ },
203
+ },
204
+ })
205
+ continue
206
+ }
136
207
c .Env = append (c .Env , corev1.EnvVar {
137
208
Name : e .Name ,
138
209
ValueFrom : & corev1.EnvVarSource {
@@ -149,9 +220,7 @@ func (b *ServiceBindingProjection) doContainer(ctx context.Context, ps *duckv1.W
149
220
iv := c .Env [i ]
150
221
jv := c .Env [j ]
151
222
// only sort injected env
152
- if iv .ValueFrom == nil || iv .ValueFrom .SecretKeyRef == nil ||
153
- jv .ValueFrom == nil || jv .ValueFrom .SecretKeyRef == nil ||
154
- ! allInjectedSecrets .HasAll (iv .ValueFrom .SecretKeyRef .Name , jv .ValueFrom .SecretKeyRef .Name ) {
223
+ if ! b .isInjectedEnv (iv , allInjectedSecrets ) || ! b .isInjectedEnv (jv , allInjectedSecrets ) {
155
224
return false
156
225
}
157
226
return iv .Name < jv .Name
@@ -183,15 +252,22 @@ func (b *ServiceBindingProjection) Undo(ctx context.Context, ps *duckv1.WithPod)
183
252
if ps .Annotations == nil {
184
253
ps .Annotations = map [string ]string {}
185
254
}
255
+ if ps .Spec .Template .Annotations == nil {
256
+ ps .Spec .Template .Annotations = map [string ]string {}
257
+ }
186
258
187
259
key := b .annotationKey ()
188
260
removeSecrets := sets .NewString (ps .Annotations [key ], b .Spec .Binding .Name )
189
261
removeVolumes := sets .NewString ()
190
262
delete (ps .Annotations , key )
263
+ delete (ps .Spec .Template .Annotations , fmt .Sprintf ("%s-type" , key ))
264
+ delete (ps .Spec .Template .Annotations , fmt .Sprintf ("%s-provider" , key ))
191
265
192
266
preservedVolumes := []corev1.Volume {}
193
267
for _ , v := range ps .Spec .Template .Spec .Volumes {
194
- if v .Secret != nil && removeSecrets .Has (v .Secret .SecretName ) {
268
+ if v .Projected != nil && len (v .Projected .Sources ) > 0 &&
269
+ v .Projected .Sources [0 ].Secret != nil &&
270
+ removeSecrets .Has (v .Projected .Sources [0 ].Secret .Name ) {
195
271
removeVolumes .Insert (v .Name )
196
272
continue
197
273
}
@@ -218,7 +294,7 @@ func (b *ServiceBindingProjection) undoContainer(ctx context.Context, ps *duckv1
218
294
219
295
preservedEnv := []corev1.EnvVar {}
220
296
for _ , e := range c .Env {
221
- if e . ValueFrom == nil || e . ValueFrom . SecretKeyRef == nil || ! removeSecrets . Has ( e . ValueFrom . SecretKeyRef . Name ) {
297
+ if ! b . isInjectedEnv ( e , removeSecrets ) {
222
298
preservedEnv = append (preservedEnv , e )
223
299
}
224
300
}
@@ -238,13 +314,27 @@ func (b *ServiceBindingProjection) injectedValues(ps *duckv1.WithPod) (sets.Stri
238
314
}
239
315
}
240
316
for _ , v := range ps .Spec .Template .Spec .Volumes {
241
- if v .Secret != nil && secrets .Has (v .Secret .SecretName ) {
317
+ if v .Projected != nil && len (v .Projected .Sources ) > 0 &&
318
+ v .Projected .Sources [0 ].Secret != nil &&
319
+ secrets .Has (v .Projected .Sources [0 ].Secret .Name ) {
242
320
volumes .Insert (v .Name )
243
321
}
244
322
}
245
323
return secrets , volumes
246
324
}
247
325
326
+ var fieldPathAnnotationRe = regexp .MustCompile (fmt .Sprintf (`^%s[0-9a-f]+%s(type|provider)%s$` , regexp .QuoteMeta (fmt .Sprintf ("metadata.annotations['%s-" , ServiceBindingProjectionAnnotationKey )), "-" , "']" ))
327
+
328
+ func (b * ServiceBindingProjection ) isInjectedEnv (e corev1.EnvVar , allInjectedSecrets sets.String ) bool {
329
+ if e .ValueFrom != nil && e .ValueFrom .SecretKeyRef != nil && allInjectedSecrets .Has (e .ValueFrom .SecretKeyRef .Name ) {
330
+ return true
331
+ }
332
+ if e .ValueFrom != nil && e .ValueFrom .FieldRef != nil && fieldPathAnnotationRe .MatchString (e .ValueFrom .FieldRef .FieldPath ) {
333
+ return true
334
+ }
335
+ return false
336
+ }
337
+
248
338
func (bs * ServiceBindingProjectionStatus ) InitializeConditions () {
249
339
sbpCondSet .Manage (bs ).InitializeConditions ()
250
340
}
0 commit comments