Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions api/core/v1beta1/featureflagsource_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -281,10 +281,17 @@ func (fc *FeatureFlagSourceSpec) ToEnvVars() []corev1.EnvVar {
envs := []corev1.EnvVar{}

for _, envVar := range fc.EnvVars {
envs = append(envs, corev1.EnvVar{
Name: fc.decorateEnvVarName(envVar.Name),
Value: envVar.Value,
})
newEnvVar := corev1.EnvVar{
Name: fc.decorateEnvVarName(envVar.Name),
}

if envVar.Value != "" {
newEnvVar.Value = envVar.Value
} else if envVar.ValueFrom != nil {
newEnvVar.ValueFrom = envVar.ValueFrom
}

envs = append(envs, newEnvVar)
}

// default values are always included in the envVars
Expand Down
74 changes: 74 additions & 0 deletions api/core/v1beta1/featureflagsource_types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,43 @@ func Test_FLagSourceConfiguration_ToEnvVars(t *testing.T) {
Name: "env2",
Value: "val2",
},
{
Name: "configMapKeyRef",
ValueFrom: &v1.EnvVarSource{
ConfigMapKeyRef: &v1.ConfigMapKeySelector{
LocalObjectReference: v1.LocalObjectReference{
Name: "configMapName",
},
},
},
},
{
Name: "fieldRef",
ValueFrom: &v1.EnvVarSource{
FieldRef: &v1.ObjectFieldSelector{
FieldPath: "fieldPath",
},
},
},
{
Name: "resourceFieldRef",
ValueFrom: &v1.EnvVarSource{
ResourceFieldRef: &v1.ResourceFieldSelector{
ContainerName: "containerName",
Resource: "resourceField",
},
},
},
{
Name: "secretKeyRef",
ValueFrom: &v1.EnvVarSource{
SecretKeyRef: &v1.SecretKeySelector{
LocalObjectReference: v1.LocalObjectReference{
Name: "secretName",
},
},
},
},
{
Name: "AZURE_STORAGE_ACCOUNT",
Value: "account123",
Expand Down Expand Up @@ -276,6 +313,43 @@ func Test_FLagSourceConfiguration_ToEnvVars(t *testing.T) {
Name: "PRE_env2",
Value: "val2",
},
{
Name: "PRE_configMapKeyRef",
ValueFrom: &v1.EnvVarSource{
ConfigMapKeyRef: &v1.ConfigMapKeySelector{
LocalObjectReference: v1.LocalObjectReference{
Name: "configMapName",
},
},
},
},
{
Name: "PRE_fieldRef",
ValueFrom: &v1.EnvVarSource{
FieldRef: &v1.ObjectFieldSelector{
FieldPath: "fieldPath",
},
},
},
{
Name: "PRE_resourceFieldRef",
ValueFrom: &v1.EnvVarSource{
ResourceFieldRef: &v1.ResourceFieldSelector{
ContainerName: "containerName",
Resource: "resourceField",
},
},
},
{
Name: "PRE_secretKeyRef",
ValueFrom: &v1.EnvVarSource{
SecretKeyRef: &v1.SecretKeySelector{
LocalObjectReference: v1.LocalObjectReference{
Name: "secretName",
},
},
},
},
{
Name: "AZURE_STORAGE_ACCOUNT",
Value: "account123",
Expand Down
15 changes: 11 additions & 4 deletions api/core/v1beta1/inprocessconfiguration_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,10 +146,17 @@ func (fc *InProcessConfigurationSpec) ToEnvVars() []corev1.EnvVar {
envs := []corev1.EnvVar{}

for _, envVar := range fc.EnvVars {
envs = append(envs, corev1.EnvVar{
Name: common.EnvVarKey(fc.EnvVarPrefix, envVar.Name),
Value: envVar.Value,
})
newEnvVar := corev1.EnvVar{
Name: common.EnvVarKey(fc.EnvVarPrefix, envVar.Name),
}

if envVar.Value != "" {
newEnvVar.Value = envVar.Value
} else if envVar.ValueFrom != nil {
newEnvVar.ValueFrom = envVar.ValueFrom
}

envs = append(envs, newEnvVar)
}

// default values are always included in the envVars
Expand Down
74 changes: 74 additions & 0 deletions api/core/v1beta1/inprocessconfiguration_types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,43 @@ func Test_InProcessConfiguration_ToEnvVars(t *testing.T) {
Name: "env2",
Value: "val2",
},
{
Name: "configMapKeyRef",
ValueFrom: &v1.EnvVarSource{
ConfigMapKeyRef: &v1.ConfigMapKeySelector{
LocalObjectReference: v1.LocalObjectReference{
Name: "configMapName",
},
},
},
},
{
Name: "fieldRef",
ValueFrom: &v1.EnvVarSource{
FieldRef: &v1.ObjectFieldSelector{
FieldPath: "fieldPath",
},
},
},
{
Name: "resourceFieldRef",
ValueFrom: &v1.EnvVarSource{
ResourceFieldRef: &v1.ResourceFieldSelector{
ContainerName: "containerName",
Resource: "resourceField",
},
},
},
{
Name: "secretKeyRef",
ValueFrom: &v1.EnvVarSource{
SecretKeyRef: &v1.SecretKeySelector{
LocalObjectReference: v1.LocalObjectReference{
Name: "secretName",
},
},
},
},
},
EnvVarPrefix: "PRE",
Port: 33,
Expand All @@ -137,6 +174,43 @@ func Test_InProcessConfiguration_ToEnvVars(t *testing.T) {
Name: "PRE_env2",
Value: "val2",
},
{
Name: "PRE_configMapKeyRef",
ValueFrom: &v1.EnvVarSource{
ConfigMapKeyRef: &v1.ConfigMapKeySelector{
LocalObjectReference: v1.LocalObjectReference{
Name: "configMapName",
},
},
},
},
{
Name: "PRE_fieldRef",
ValueFrom: &v1.EnvVarSource{
FieldRef: &v1.ObjectFieldSelector{
FieldPath: "fieldPath",
},
},
},
{
Name: "PRE_resourceFieldRef",
ValueFrom: &v1.EnvVarSource{
ResourceFieldRef: &v1.ResourceFieldSelector{
ContainerName: "containerName",
Resource: "resourceField",
},
},
},
{
Name: "PRE_secretKeyRef",
ValueFrom: &v1.EnvVarSource{
SecretKeyRef: &v1.SecretKeySelector{
LocalObjectReference: v1.LocalObjectReference{
Name: "secretName",
},
},
},
},
{
Name: "PRE_HOST",
Value: "host",
Expand Down
50 changes: 8 additions & 42 deletions docs/feature_flag_source.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,55 +120,21 @@ Other types of credentials for Azure Blob Storage are supported; for details see

#### Google Cloud Storage

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

```yaml
sources:
- source: gs://my-bucket/flags.json # my-bucket - GCS bucket name
provider: gcs
interval: 10 # optional polling interval in seconds, defaults to 5
envVars:
- name: GOOGLE_APPLICATION_CREDENTIALS
value: /var/run/secrets/gcp/key.json
```

On GKE, prefer [Workload Identity](https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity)
over static credentials. For the full set of supported URL options see
the [gocloud `blob/gcsblob` URL reference](https://pkg.go.dev/gocloud.dev/blob/gcsblob#hdr-URLs).

#### Amazon S3

Given below is an example configuration with provider type `s3` and supported options,
`envVars` can be used to pass environment variables to the injected flagd sidecar. Values can be set inline or referenced from Kubernetes secrets:

```yaml
sources:
- source: s3://my-bucket/flags.json # my-bucket - S3 bucket name
provider: s3
interval: 10 # optional polling interval in seconds, defaults to 5
envVars:
- name: AWS_REGION
value: us-east-1
- name: AWS_ACCESS_KEY_ID
valueFrom:
secretKeyRef:
name: s3-credentials
key: access-key-id
- name: AWS_SECRET_ACCESS_KEY
valueFrom:
- name: MY_VAR
value: my-value # inline value
- name: MY_SECRET_VAR
valueFrom: # value from a Kubernetes secret
secretKeyRef:
name: s3-credentials
key: secret-access-key
name: my-secret
key: my-key
```

On EKS, prefer [IRSA](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html)
or EKS Pod Identity over static access keys; both auto-inject the right
`AWS_*` variables via the pod's service account.

For S3-compatible endpoints such as MinIO or LocalStack, set
`AWS_ENDPOINT_URL_S3` and (usually) `AWS_S3_FORCE_PATH_STYLE=true`, or pass
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)
for the full set of supported URL options.

## Sidecar configurations

`FeatureFlagSource` provides configurations to the injected flagd sidecar.
Expand Down
Loading