Skip to content

Commit 5565013

Browse files
authored
Merge pull request #351 from Flagsmith/fix/secrets-fix
feat: Automatically generate API and SSE secrets using Jobs. Accept existing SSE secrets
2 parents 8c04fca + 672b181 commit 5565013

File tree

13 files changed

+230
-65
lines changed

13 files changed

+230
-65
lines changed

charts/flagsmith/templates/_api_environment.yaml

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@
1111
- name: DJANGO_SECRET_KEY
1212
valueFrom:
1313
secretKeyRef:
14-
name: django-secret-key
15-
key: django-secret-key
14+
{{ include "flagsmith.api.secretKeySecretRef" . | nindent 6 }}
1615
{{- if .Values.influxdb2.enabled }}
1716
- name: INFLUXDB_URL
1817
value: http://{{- template "flagsmith.influxdb.hostname" . -}}:80
@@ -112,8 +111,7 @@
112111
- name: SSE_AUTHENTICATION_TOKEN
113112
valueFrom:
114113
secretKeyRef:
115-
name: {{ include "flagsmith.fullname" . }}-sse
116-
key: SSE_AUTHENTICATION_TOKEN
114+
{{ include "flagsmith.sse.authenticationTokenSecretRef" . | nindent 6}}
117115
- name: SSE_SERVER_BASE_URL
118116
value: http://{{ include "flagsmith.fullname" . }}-sse.{{ .Release.Namespace }}:{{ .Values.service.sse.port }}
119-
{{- end }}
117+
{{- end }}

charts/flagsmith/templates/_helpers.tpl

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -347,9 +347,28 @@ replicas: {{ . }}
347347
{{- end }}
348348

349349

350-
{{/*
351-
Real-time flag updates (SSE)
352-
*/}}
353-
{{- define "flagsmith.sse.authenticationToken" -}}
354-
{{- randAlphaNum 50 -}}
355-
{{- end }}
350+
{{- define "flagsmith.api.secretKeySecretName" -}}
351+
{{- if .Values.api.secretKeyFromExistingSecret.enabled -}}
352+
{{- .Values.api.secretKeyFromExistingSecret.name -}}
353+
{{- else }}
354+
{{- printf "%s-django-secret-key" (include "flagsmith.fullname" .) -}}
355+
{{- end }}
356+
{{- end }}
357+
358+
{{- define "flagsmith.api.secretKeySecretRef" -}}
359+
name: {{ include "flagsmith.api.secretKeySecretName" . }}
360+
key: {{ default "django-secret-key" .Values.api.secretKeyFromExistingSecret.key }}
361+
{{- end }}
362+
363+
{{- define "flagsmith.sse.authenticationTokenSecretName" -}}
364+
{{- if .Values.sse.authenticationTokenFromExistingSecret.enabled -}}
365+
{{- .Values.sse.authenticationTokenFromExistingSecret.name -}}
366+
{{- else }}
367+
{{- printf "%s-sse-authentication-token" (include "flagsmith.fullname" .) -}}
368+
{{- end }}
369+
{{- end }}
370+
371+
{{- define "flagsmith.sse.authenticationTokenSecretRef" -}}
372+
name: {{ include "flagsmith.sse.authenticationTokenSecretName" . }}
373+
key: {{ default "sse-authentication-token" .Values.sse.authenticationTokenFromExistingSecret.key }}
374+
{{- end }}

charts/flagsmith/templates/_sse_environment.yaml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,4 @@
1212
- name: SSE_AUTHENTICATION_TOKEN
1313
valueFrom:
1414
secretKeyRef:
15-
name: {{ include "flagsmith.fullname" . }}-sse
16-
key: SSE_AUTHENTICATION_TOKEN
15+
{{ include "flagsmith.sse.authenticationTokenSecretRef" . | nindent 6 }}

charts/flagsmith/templates/deployment-sse.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ spec:
2323
template:
2424
metadata:
2525
annotations:
26-
checksum/secrets-sse: {{ include (print $.Template.BasePath "/secrets-sse.yaml") . | sha256sum }}
2726
{{- if .Values.sse.podAnnotations }}
2827
{{ toYaml .Values.sse.podAnnotations | nindent 8 }}
2928
{{- end }}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
{{- if not .Values.api.secretKeyFromExistingSecret.enabled -}}
2+
apiVersion: batch/v1
3+
kind: Job
4+
metadata:
5+
name: {{ include "flagsmith.api.secretKeySecretName" . }}
6+
namespace: {{ .Release.Namespace | quote }}
7+
labels:
8+
{{- include "flagsmith.labels" . | nindent 4 }}
9+
app.kubernetes.io/component: django-secret-init
10+
annotations:
11+
"helm.sh/hook": pre-install,pre-upgrade
12+
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
13+
spec:
14+
template:
15+
metadata:
16+
name: {{ include "flagsmith.api.secretKeySecretName" . }}
17+
labels:
18+
{{- include "flagsmith.labels" . | nindent 8 }}
19+
app.kubernetes.io/component: django-secret-init
20+
spec:
21+
restartPolicy: OnFailure
22+
serviceAccountName: {{ include "flagsmith.api.secretKeySecretName" . }}
23+
containers:
24+
- name: secret-creator
25+
image: bitnami/kubectl:latest
26+
imagePullPolicy: IfNotPresent
27+
command:
28+
- /bin/sh
29+
- -c
30+
- |
31+
SECRET_NAME={{ include "flagsmith.api.secretKeySecretName" . }}
32+
NAMESPACE={{ .Release.Namespace }}
33+
echo "Checking for secret $SECRET_NAME in namespace $NAMESPACE"
34+
# Attempt to get the secret; if it fails (exit code != 0), create it.
35+
if ! kubectl get secret "$SECRET_NAME" -n "$NAMESPACE" -o name; then
36+
echo "Secret $SECRET_NAME not found. Creating..."
37+
# Generate a 64-character hex key (32 bytes)
38+
GENERATED_KEY=$(openssl rand -hex 32)
39+
kubectl create secret generic "$SECRET_NAME" -n "$NAMESPACE" \
40+
--from-literal=django-secret-key="$GENERATED_KEY" \
41+
--dry-run=client -o yaml | kubectl apply -f -
42+
echo "Secret $SECRET_NAME created."
43+
else
44+
echo "Secret $SECRET_NAME already exists. No action taken."
45+
fi
46+
{{- end }}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
{{- if not .Values.api.secretKeyFromExistingSecret.enabled -}}
2+
apiVersion: rbac.authorization.k8s.io/v1
3+
kind: Role
4+
metadata:
5+
name: {{ include "flagsmith.api.secretKeySecretName" . }}
6+
namespace: {{ .Release.Namespace | quote }}
7+
labels:
8+
{{- include "flagsmith.labels" . | nindent 4 }}
9+
annotations:
10+
"helm.sh/hook": pre-install,pre-upgrade
11+
"helm.sh/hook-delete-policy": before-hook-creation
12+
rules:
13+
- apiGroups: [""]
14+
resources: ["secrets"]
15+
verbs: ["get", "create"]
16+
---
17+
apiVersion: rbac.authorization.k8s.io/v1
18+
kind: RoleBinding
19+
metadata:
20+
name: {{ include "flagsmith.api.secretKeySecretName" . }}
21+
namespace: {{ .Release.Namespace | quote }}
22+
labels:
23+
{{- include "flagsmith.labels" . | nindent 4 }}
24+
annotations:
25+
"helm.sh/hook": pre-install,pre-upgrade
26+
"helm.sh/hook-delete-policy": before-hook-creation
27+
roleRef:
28+
apiGroup: rbac.authorization.k8s.io
29+
kind: Role
30+
name: {{ include "flagsmith.api.secretKeySecretName" . }}
31+
subjects:
32+
- kind: ServiceAccount
33+
name: {{ include "flagsmith.api.secretKeySecretName" . }}
34+
namespace: {{ .Release.Namespace | quote }}
35+
{{- end }}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{{- if not .Values.api.secretKeyFromExistingSecret.enabled -}}
2+
apiVersion: v1
3+
kind: ServiceAccount
4+
metadata:
5+
name: {{ include "flagsmith.api.secretKeySecretName" . }}
6+
namespace: {{ .Release.Namespace | quote }}
7+
labels:
8+
{{- include "flagsmith.labels" . | nindent 4 }}
9+
annotations:
10+
"helm.sh/hook": pre-install,pre-upgrade
11+
"helm.sh/hook-delete-policy": before-hook-creation
12+
{{- end }}

charts/flagsmith/templates/secrets-api.yaml

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -13,39 +13,3 @@ metadata:
1313
type: Opaque
1414
data:
1515
DATABASE_URL: {{ include "flagsmith.api.databaseUrl" . | trim | b64enc | quote }}
16-
---
17-
{{/*
18-
If no secrets were provided in values, check if a previously deployed secret exists
19-
If none exists, create one, which will be reused in future deployments
20-
*/}}
21-
{{- $secretKey := default (randAlphaNum 50) .Values.api.secretKey -}}
22-
{{ if ((.Values.api).secretKeyFromExistingSecret).enabled -}}
23-
{{ $existingSecret := (lookup "v1" "Secret" .Release.Namespace .Values.api.secretKeyFromExistingSecret.name).data }}
24-
{{ if $existingSecret }}
25-
{{ $secretKey = index $existingSecret .Values.api.secretKeyFromExistingSecret.key | b64dec }}
26-
{{ end }}
27-
{{ else }}
28-
{{ $knownSecret := (lookup "v1" "Secret" .Release.Namespace "django-secret-key").data }}
29-
{{ if $knownSecret }}
30-
{{ $secretValue := index $knownSecret "django-secret-key" }}
31-
{{ if $secretValue }}
32-
{{ $secretKey = $secretValue | b64dec }}
33-
{{ end }}
34-
{{ end }}
35-
{{- end -}}
36-
37-
apiVersion: v1
38-
kind: Secret
39-
metadata:
40-
name: django-secret-key
41-
{{- with $annotations }}
42-
annotations:
43-
{{- . | nindent 4 }}
44-
{{- end }}
45-
labels:
46-
{{- include "flagsmith.labels" . | nindent 4 }}
47-
app.kubernetes.io/component: api
48-
type: Opaque
49-
{{/* Don't use stringData https://github.com/kubernetes/kubernetes/issues/89938 */ -}}
50-
data:
51-
django-secret-key: {{ $secretKey | b64enc | quote}}

charts/flagsmith/templates/secrets-sse.yaml

Lines changed: 0 additions & 15 deletions
This file was deleted.
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
{{- if and .Values.sse.enabled (not .Values.sse.authenticationTokenFromExistingSecret.enabled) -}}
2+
apiVersion: batch/v1
3+
kind: Job
4+
metadata:
5+
name: {{ include "flagsmith.sse.authenticationTokenSecretName" . }}
6+
namespace: {{ .Release.Namespace | quote }}
7+
labels:
8+
{{- include "flagsmith.labels" . | nindent 4 }}
9+
app.kubernetes.io/component: sse-secret-init
10+
annotations:
11+
"helm.sh/hook": pre-install,pre-upgrade
12+
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
13+
spec:
14+
template:
15+
metadata:
16+
name: {{ include "flagsmith.sse.authenticationTokenSecretName" . }}
17+
labels:
18+
{{- include "flagsmith.labels" . | nindent 8 }}
19+
app.kubernetes.io/component: sse-secret-init
20+
spec:
21+
restartPolicy: OnFailure
22+
serviceAccountName: {{ include "flagsmith.fullname" . }}-sse-secret-init
23+
containers:
24+
- name: secret-creator
25+
image: bitnami/kubectl:latest
26+
imagePullPolicy: IfNotPresent
27+
command:
28+
- /bin/sh
29+
- -c
30+
- |
31+
SECRET_NAME={{ include "flagsmith.sse.authenticationTokenSecretName" . }}
32+
NAMESPACE={{ .Release.Namespace }}
33+
echo "Checking for secret $SECRET_NAME in namespace $NAMESPACE"
34+
# Attempt to get the secret; if it fails (exit code != 0), create it.
35+
if ! kubectl get secret "$SECRET_NAME" -n "$NAMESPACE" -o name; then
36+
echo "Secret $SECRET_NAME not found. Creating..."
37+
# Generate a 64-character hex key (32 bytes)
38+
GENERATED_KEY=$(openssl rand -hex 32)
39+
kubectl create secret generic "$SECRET_NAME" -n "$NAMESPACE" \
40+
--from-literal=sse-authentication-token="$GENERATED_KEY" \
41+
--dry-run=client -o yaml | kubectl apply -f -
42+
echo "Secret $SECRET_NAME created."
43+
else
44+
echo "Secret $SECRET_NAME already exists. No action taken."
45+
fi
46+
{{- end }}

0 commit comments

Comments
 (0)