Skip to content

Commit f9ca4d5

Browse files
feat: add valueFrom field handling in envVars for FeatureFlagSource and InProcessConfiguration (#802)
Signed-off-by: KyryloKarpenko <karpenkokirillll55@gmail.com> Signed-off-by: Todd Baert <todd.baert@dynatrace.com> Co-authored-by: Todd Baert <todd.baert@dynatrace.com>
1 parent 097bc22 commit f9ca4d5

5 files changed

Lines changed: 178 additions & 50 deletions

File tree

api/core/v1beta1/featureflagsource_types.go

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -281,10 +281,17 @@ func (fc *FeatureFlagSourceSpec) ToEnvVars() []corev1.EnvVar {
281281
envs := []corev1.EnvVar{}
282282

283283
for _, envVar := range fc.EnvVars {
284-
envs = append(envs, corev1.EnvVar{
285-
Name: fc.decorateEnvVarName(envVar.Name),
286-
Value: envVar.Value,
287-
})
284+
newEnvVar := corev1.EnvVar{
285+
Name: fc.decorateEnvVarName(envVar.Name),
286+
}
287+
288+
if envVar.Value != "" {
289+
newEnvVar.Value = envVar.Value
290+
} else if envVar.ValueFrom != nil {
291+
newEnvVar.ValueFrom = envVar.ValueFrom
292+
}
293+
294+
envs = append(envs, newEnvVar)
288295
}
289296

290297
// default values are always included in the envVars

api/core/v1beta1/featureflagsource_types_test.go

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,43 @@ func Test_FLagSourceConfiguration_ToEnvVars(t *testing.T) {
238238
Name: "env2",
239239
Value: "val2",
240240
},
241+
{
242+
Name: "configMapKeyRef",
243+
ValueFrom: &v1.EnvVarSource{
244+
ConfigMapKeyRef: &v1.ConfigMapKeySelector{
245+
LocalObjectReference: v1.LocalObjectReference{
246+
Name: "configMapName",
247+
},
248+
},
249+
},
250+
},
251+
{
252+
Name: "fieldRef",
253+
ValueFrom: &v1.EnvVarSource{
254+
FieldRef: &v1.ObjectFieldSelector{
255+
FieldPath: "fieldPath",
256+
},
257+
},
258+
},
259+
{
260+
Name: "resourceFieldRef",
261+
ValueFrom: &v1.EnvVarSource{
262+
ResourceFieldRef: &v1.ResourceFieldSelector{
263+
ContainerName: "containerName",
264+
Resource: "resourceField",
265+
},
266+
},
267+
},
268+
{
269+
Name: "secretKeyRef",
270+
ValueFrom: &v1.EnvVarSource{
271+
SecretKeyRef: &v1.SecretKeySelector{
272+
LocalObjectReference: v1.LocalObjectReference{
273+
Name: "secretName",
274+
},
275+
},
276+
},
277+
},
241278
{
242279
Name: "AZURE_STORAGE_ACCOUNT",
243280
Value: "account123",
@@ -276,6 +313,43 @@ func Test_FLagSourceConfiguration_ToEnvVars(t *testing.T) {
276313
Name: "PRE_env2",
277314
Value: "val2",
278315
},
316+
{
317+
Name: "PRE_configMapKeyRef",
318+
ValueFrom: &v1.EnvVarSource{
319+
ConfigMapKeyRef: &v1.ConfigMapKeySelector{
320+
LocalObjectReference: v1.LocalObjectReference{
321+
Name: "configMapName",
322+
},
323+
},
324+
},
325+
},
326+
{
327+
Name: "PRE_fieldRef",
328+
ValueFrom: &v1.EnvVarSource{
329+
FieldRef: &v1.ObjectFieldSelector{
330+
FieldPath: "fieldPath",
331+
},
332+
},
333+
},
334+
{
335+
Name: "PRE_resourceFieldRef",
336+
ValueFrom: &v1.EnvVarSource{
337+
ResourceFieldRef: &v1.ResourceFieldSelector{
338+
ContainerName: "containerName",
339+
Resource: "resourceField",
340+
},
341+
},
342+
},
343+
{
344+
Name: "PRE_secretKeyRef",
345+
ValueFrom: &v1.EnvVarSource{
346+
SecretKeyRef: &v1.SecretKeySelector{
347+
LocalObjectReference: v1.LocalObjectReference{
348+
Name: "secretName",
349+
},
350+
},
351+
},
352+
},
279353
{
280354
Name: "AZURE_STORAGE_ACCOUNT",
281355
Value: "account123",

api/core/v1beta1/inprocessconfiguration_types.go

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -146,10 +146,17 @@ func (fc *InProcessConfigurationSpec) ToEnvVars() []corev1.EnvVar {
146146
envs := []corev1.EnvVar{}
147147

148148
for _, envVar := range fc.EnvVars {
149-
envs = append(envs, corev1.EnvVar{
150-
Name: common.EnvVarKey(fc.EnvVarPrefix, envVar.Name),
151-
Value: envVar.Value,
152-
})
149+
newEnvVar := corev1.EnvVar{
150+
Name: common.EnvVarKey(fc.EnvVarPrefix, envVar.Name),
151+
}
152+
153+
if envVar.Value != "" {
154+
newEnvVar.Value = envVar.Value
155+
} else if envVar.ValueFrom != nil {
156+
newEnvVar.ValueFrom = envVar.ValueFrom
157+
}
158+
159+
envs = append(envs, newEnvVar)
153160
}
154161

155162
// default values are always included in the envVars

api/core/v1beta1/inprocessconfiguration_types_test.go

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,43 @@ func Test_InProcessConfiguration_ToEnvVars(t *testing.T) {
116116
Name: "env2",
117117
Value: "val2",
118118
},
119+
{
120+
Name: "configMapKeyRef",
121+
ValueFrom: &v1.EnvVarSource{
122+
ConfigMapKeyRef: &v1.ConfigMapKeySelector{
123+
LocalObjectReference: v1.LocalObjectReference{
124+
Name: "configMapName",
125+
},
126+
},
127+
},
128+
},
129+
{
130+
Name: "fieldRef",
131+
ValueFrom: &v1.EnvVarSource{
132+
FieldRef: &v1.ObjectFieldSelector{
133+
FieldPath: "fieldPath",
134+
},
135+
},
136+
},
137+
{
138+
Name: "resourceFieldRef",
139+
ValueFrom: &v1.EnvVarSource{
140+
ResourceFieldRef: &v1.ResourceFieldSelector{
141+
ContainerName: "containerName",
142+
Resource: "resourceField",
143+
},
144+
},
145+
},
146+
{
147+
Name: "secretKeyRef",
148+
ValueFrom: &v1.EnvVarSource{
149+
SecretKeyRef: &v1.SecretKeySelector{
150+
LocalObjectReference: v1.LocalObjectReference{
151+
Name: "secretName",
152+
},
153+
},
154+
},
155+
},
119156
},
120157
EnvVarPrefix: "PRE",
121158
Port: 33,
@@ -137,6 +174,43 @@ func Test_InProcessConfiguration_ToEnvVars(t *testing.T) {
137174
Name: "PRE_env2",
138175
Value: "val2",
139176
},
177+
{
178+
Name: "PRE_configMapKeyRef",
179+
ValueFrom: &v1.EnvVarSource{
180+
ConfigMapKeyRef: &v1.ConfigMapKeySelector{
181+
LocalObjectReference: v1.LocalObjectReference{
182+
Name: "configMapName",
183+
},
184+
},
185+
},
186+
},
187+
{
188+
Name: "PRE_fieldRef",
189+
ValueFrom: &v1.EnvVarSource{
190+
FieldRef: &v1.ObjectFieldSelector{
191+
FieldPath: "fieldPath",
192+
},
193+
},
194+
},
195+
{
196+
Name: "PRE_resourceFieldRef",
197+
ValueFrom: &v1.EnvVarSource{
198+
ResourceFieldRef: &v1.ResourceFieldSelector{
199+
ContainerName: "containerName",
200+
Resource: "resourceField",
201+
},
202+
},
203+
},
204+
{
205+
Name: "PRE_secretKeyRef",
206+
ValueFrom: &v1.EnvVarSource{
207+
SecretKeyRef: &v1.SecretKeySelector{
208+
LocalObjectReference: v1.LocalObjectReference{
209+
Name: "secretName",
210+
},
211+
},
212+
},
213+
},
140214
{
141215
Name: "PRE_HOST",
142216
Value: "host",

docs/feature_flag_source.md

Lines changed: 8 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -120,55 +120,21 @@ Other types of credentials for Azure Blob Storage are supported; for details see
120120

121121
#### Google Cloud Storage
122122

123-
Given below is an example configuration with provider type `gcs` and supported options,
123+
## Environment variables
124124

125-
```yaml
126-
sources:
127-
- source: gs://my-bucket/flags.json # my-bucket - GCS bucket name
128-
provider: gcs
129-
interval: 10 # optional polling interval in seconds, defaults to 5
130-
envVars:
131-
- name: GOOGLE_APPLICATION_CREDENTIALS
132-
value: /var/run/secrets/gcp/key.json
133-
```
134-
135-
On GKE, prefer [Workload Identity](https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity)
136-
over static credentials. For the full set of supported URL options see
137-
the [gocloud `blob/gcsblob` URL reference](https://pkg.go.dev/gocloud.dev/blob/gcsblob#hdr-URLs).
138-
139-
#### Amazon S3
140-
141-
Given below is an example configuration with provider type `s3` and supported options,
125+
`envVars` can be used to pass environment variables to the injected flagd sidecar. Values can be set inline or referenced from Kubernetes secrets:
142126

143127
```yaml
144-
sources:
145-
- source: s3://my-bucket/flags.json # my-bucket - S3 bucket name
146-
provider: s3
147-
interval: 10 # optional polling interval in seconds, defaults to 5
148128
envVars:
149-
- name: AWS_REGION
150-
value: us-east-1
151-
- name: AWS_ACCESS_KEY_ID
152-
valueFrom:
153-
secretKeyRef:
154-
name: s3-credentials
155-
key: access-key-id
156-
- name: AWS_SECRET_ACCESS_KEY
157-
valueFrom:
129+
- name: MY_VAR
130+
value: my-value # inline value
131+
- name: MY_SECRET_VAR
132+
valueFrom: # value from a Kubernetes secret
158133
secretKeyRef:
159-
name: s3-credentials
160-
key: secret-access-key
134+
name: my-secret
135+
key: my-key
161136
```
162137

163-
On EKS, prefer [IRSA](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html)
164-
or EKS Pod Identity over static access keys; both auto-inject the right
165-
`AWS_*` variables via the pod's service account.
166-
167-
For S3-compatible endpoints such as MinIO or LocalStack, set
168-
`AWS_ENDPOINT_URL_S3` and (usually) `AWS_S3_FORCE_PATH_STYLE=true`, or pass
169-
URL query parameters directly on the source URI. See the [gocloud `blob/s3blob` URL reference](https://pkg.go.dev/gocloud.dev/blob/s3blob#hdr-URLs)
170-
for the full set of supported URL options.
171-
172138
## Sidecar configurations
173139

174140
`FeatureFlagSource` provides configurations to the injected flagd sidecar.

0 commit comments

Comments
 (0)