Skip to content

Commit 4be26e4

Browse files
feat: add keystore init container (#151)
* feat: add keystore init container * [pre-commit.ci lite] apply automatic fixes --------- Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
1 parent d485516 commit 4be26e4

9 files changed

Lines changed: 156 additions & 10 deletions

File tree

diracx/templates/_helpers.tpl

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,3 +169,23 @@ reduce collisions.
169169
{{- $rand := randAlphaNum 3 | lower }}
170170
{{- printf "%s-%d-%s" $name .Release.Revision $rand | trunc 63 | trimSuffix "-" -}}
171171
{{- end -}}
172+
173+
{{/*
174+
Return the fullname template for the initKeyStore job.
175+
*/}}
176+
{{- define "initKeyStore.fullname" -}}
177+
{{- printf "%s-init-keystore" .Release.Name -}}
178+
{{- end -}}
179+
180+
{{/*
181+
Create a default fully qualified job name for initKeyStore.
182+
Due to the job only being allowed to run once, we add the chart revision so helm
183+
upgrades don't cause errors trying to create the already ran job.
184+
Due to the helm delete not cleaning up these jobs, we add a random value to
185+
reduce collisions.
186+
*/}}
187+
{{- define "initKeyStore.jobname" -}}
188+
{{- $name := include "initKeyStore.fullname" . | trunc 55 | trimSuffix "-" -}}
189+
{{- $rand := randAlphaNum 3 | lower }}
190+
{{- printf "%s-%d-%s" $name .Release.Revision $rand | trunc 63 | trimSuffix "-" -}}
191+
{{- end -}}

diracx/templates/diracx/deployment.yaml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,12 @@ spec:
5353
- name: container-entrypoint
5454
configMap:
5555
name: diracx-container-entrypoint
56-
- name: signing-key-mount
56+
- name: jwks-mount
5757
secret:
58-
secretName: diracx-token-signing-key
58+
secretName: diracx-jwks
5959
items:
60-
- key: rsa256.key
61-
path: rsa256.key
60+
- key: jwks.json
61+
path: jwks.json
6262
{{- if and .Values.developer.enabled .Values.developer.enableCoverage }}
6363
- name: coverage-data
6464
persistentVolumeClaim:
@@ -70,7 +70,7 @@ spec:
7070
{{- if .Values.developer.enabled }}
7171
{{- $commonVolumeMounts = append $commonVolumeMounts (dict "mountPath" "/cs_store" "name" "cs-store-mount" "readOnly" false) }}
7272
{{- end }}
73-
{{- $commonVolumeMounts = append $commonVolumeMounts (dict "mountPath" "/signing-key" "name" "signing-key-mount" "readOnly" false) }}
73+
{{- $commonVolumeMounts = append $commonVolumeMounts (dict "mountPath" "/keystore" "name" "jwks-mount" "readOnly" false) }}
7474
{{- $commonVolumeMounts = append $commonVolumeMounts (dict "mountPath" "/entrypoint.sh" "name" "container-entrypoint" "subPath" "entrypoint.sh") }}
7575
{{- if and .Values.developer.enabled .Values.developer.enableCoverage }}
7676
{{- $commonVolumeMounts = append $commonVolumeMounts (dict "mountPath" "/diracx-coveragerc" "name" "container-entrypoint" "subPath" "coveragerc") }}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
IFS=$'\n\t'
4+
5+
KEYSTORE_PATH=/keystore/jwks.json
6+
7+
if [[ -f $KEYSTORE_PATH ]]; then
8+
echo "JWKS already exists, this is not supported!"
9+
exit 1
10+
fi
11+
12+
# Generate the initial keystore
13+
python -m diracx.logic rotate-jwk \
14+
--jwks-path $KEYSTORE_PATH
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
IFS=$'\n\t'
4+
5+
namespace={{ .Release.Namespace }}
6+
7+
KEYSTORE_PATH=/keystore/jwks.json
8+
9+
if [[ ! -f $KEYSTORE_PATH ]]; then
10+
echo "Keystore is missing"
11+
exit 1;
12+
fi
13+
14+
# Check if the keystore secret already exists
15+
if kubectl -n "$namespace" get secret diracx-jwks >/dev/null 2>&1; then
16+
echo "diracx-jwks already present, skipping keystore generation"
17+
exit 0
18+
fi
19+
20+
# Create the keystore secret
21+
kubectl create secret generic diracx-jwks \
22+
--namespace=$namespace \
23+
--from-file=$KEYSTORE_PATH \
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{{- if .Values.initKeyStore.enabled -}}
2+
apiVersion: v1
3+
kind: ConfigMap
4+
metadata:
5+
name: {{ template "initKeyStore.fullname" . }}
6+
namespace: {{ .Release.Namespace }}
7+
annotations:
8+
"helm.sh/hook": pre-install
9+
"helm.sh/hook-weight": "-3"
10+
"helm.sh/hook-delete-policy": hook-succeeded,before-hook-creation
11+
data:
12+
init-keystore: |
13+
{{- include (print $.Template.BasePath "/diracx/init-keystore/_init-keystore.sh.tpl") . | nindent 4 }}
14+
load-keystore-as-secret: |
15+
{{- include (print $.Template.BasePath "/diracx/init-keystore/_load-keystore-as-secret.sh.tpl") . | nindent 4 }}
16+
{{- end -}}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
{{- if .Values.initKeyStore.enabled -}}
2+
3+
{{/* Define common volume mounts for reusability */}}
4+
{{- $commonVolumeMounts := list }}
5+
{{- $commonVolumeMounts = append $commonVolumeMounts (dict "mountPath" "/entrypoint.sh" "name" "container-entrypoint" "subPath" "entrypoint.sh") }}
6+
{{- if and .Values.developer.enabled .Values.developer.mountedPythonModulesToInstall }}
7+
{{- $commonVolumeMounts = append $commonVolumeMounts (dict "mountPath" .Values.developer.sourcePath "name" "diracx-code-mount" "readOnly" true) }}
8+
{{- range $module := .Values.developer.mountedPythonModulesToInstall }}
9+
{{- if $.Values.developer.editableMountedPythonModules }}
10+
{{- $commonVolumeMounts = append $commonVolumeMounts (dict "mountPath" (printf "%s/%s/src/%s.egg-info" $.Values.developer.sourcePath $module (replace "-" "_" (base $module))) "name" (printf "%s-editable-install" (base $module | lower)) "readOnly" false) }}
11+
{{- else }}
12+
{{- $commonVolumeMounts = append $commonVolumeMounts (dict "mountPath" (printf "%s/%s/build" $.Values.developer.sourcePath $module (replace "-" "_" (base $module))) "name" (printf "%s-editable-install" (base $module | lower)) "readOnly" false) }}
13+
{{- end }}
14+
{{- end }}
15+
{{- end }}
16+
17+
apiVersion: batch/v1
18+
kind: Job
19+
metadata:
20+
name: {{ template "initKeyStore.jobname" . }}
21+
namespace: {{ .Release.Namespace }}
22+
annotations:
23+
"helm.sh/hook": pre-install
24+
spec:
25+
ttlSecondsAfterFinished: {{ .Values.global.batchJobTTL }}
26+
activeDeadlineSeconds: {{ .Values.global.activeDeadlineSeconds }}
27+
template:
28+
spec:
29+
restartPolicy: Never
30+
serviceAccountName: {{ template "initSecrets.serviceAccountName" . }}
31+
initContainers:
32+
- name: {{ .Chart.Name }}-init-keystore
33+
image: "{{ .Values.global.images.services }}:{{ .Values.global.images.tag | default .Chart.AppVersion }}"
34+
imagePullPolicy: {{ .Values.global.imagePullPolicy }}
35+
command: ["/bin/bash", "/entrypoint.sh"]
36+
args: ["/bin/bash", "/scripts/init-keystore"]
37+
volumeMounts:
38+
{{ toYaml $commonVolumeMounts | nindent 12 }}
39+
- name: scripts
40+
mountPath: /scripts
41+
- name: keystore
42+
mountPath: /keystore
43+
44+
containers:
45+
- name: {{ .Chart.Name }}-load-keystore-as-secret
46+
image: ghcr.io/diracgrid/diracx/secret-generation:latest
47+
imagePullPolicy: {{ .Values.global.imagePullPolicy }}
48+
args: ["/bin/bash", "/scripts/load-keystore-as-secret"]
49+
volumeMounts:
50+
- name: scripts
51+
mountPath: /scripts
52+
- name: keystore
53+
mountPath: /keystore
54+
volumes:
55+
- name: keystore
56+
emptyDir: {}
57+
- name: scripts
58+
configMap:
59+
name: {{ template "initKeyStore.fullname" . }}
60+
{{- if and .Values.developer.enabled .Values.developer.mountedPythonModulesToInstall }}
61+
- name: diracx-code-mount
62+
persistentVolumeClaim:
63+
claimName: pvc-diracx-code
64+
{{- range $module := .Values.developer.mountedPythonModulesToInstall }}
65+
- name: {{ base $module | lower }}-editable-install
66+
emptyDir:
67+
sizeLimit: 5Mi
68+
{{- end }}
69+
{{- end }}
70+
- name: container-entrypoint
71+
configMap:
72+
name: diracx-container-entrypoint
73+
{{- end }}

diracx/templates/diracx/init-secrets/_init-secrets.sh.tpl

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,6 @@ function generate_secret_if_needed(){
4848
fi
4949
}
5050

51-
# Generate the token signing key
52-
ssh-keygen -P '' -trsa -b4096 -mPEM -f"$PWD/rsa256.key"
53-
generate_secret_if_needed diracx-token-signing-key --from-file "$PWD/rsa256.key"
54-
5551
# Generate the token state key (to safely pass information between authorize/device requests)
5652
generate_secret_if_needed diracx-dynamic-secrets --from-literal=DIRACX_SERVICE_AUTH_STATE_KEY=$(head -c 32 /dev/urandom | base64)
5753

diracx/values.yaml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ initSql:
8585
initOs:
8686
enabled: true
8787

88+
initKeyStore:
89+
enabled: true
90+
8891
developer:
8992
enabled: true
9093
# -- Make it possible to launch the demo without having an internet connection
@@ -125,7 +128,7 @@ diracx:
125128
# which must be present on all the servers
126129
#TODO: autogenerate all of these
127130
DIRACX_CONFIG_BACKEND_URL: "git+file:///cs_store/initialRepo"
128-
DIRACX_SERVICE_AUTH_TOKEN_KEY: "file:///signing-key/rsa256.key"
131+
DIRACX_SERVICE_AUTH_TOKEN_KEYSTORE: "file:///keystore/jwks.json"
129132
DIRACX_SERVICE_AUTH_ALLOWED_REDIRECTS: '["http://anything:8000/docs/oauth2-redirect"]'
130133

131134
# If mysql is enabled, you are not allowed

docs/admin/reference/values.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@
138138
| ingress.className | string | `"nginx"` | |
139139
| ingress.enabled | bool | `true` | |
140140
| ingress.tlsSecretName | string | `"myingress-cert"` | |
141+
| initKeyStore.enabled | bool | `true` | |
141142
| initOs.enabled | bool | `true` | |
142143
| initSecrets.enabled | bool | `true` | |
143144
| initSecrets.rbac.create | bool | `true` | |

0 commit comments

Comments
 (0)