-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(ckan): add api creation and perist secrets (#1238)
- Loading branch information
Showing
7 changed files
with
383 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
{{- $name := (printf "%s-%s-configmap" (include "common.names.fullname" .) "ckan") -}} | ||
apiVersion: v1 | ||
kind: ConfigMap | ||
metadata: | ||
name: {{ $name }} | ||
labels: {{- include "common.labels.standard" . | nindent 4 }} | ||
app.kubernetes.io/component: {{ $name }} | ||
namespace: {{ .Release.Namespace | quote }} | ||
data: | ||
ckan-init.sh: |- | ||
#!/bin/bash | ||
echo "initiate ckan" | ||
if [[ -z "$DATAPUSHER_API_TOKEN" || -z "$EMAIL_API_KEY" ]]; then | ||
ckan config-tool $CKAN_INI "SECRET_KEY=${SECRET_KEY}" | ||
ckan config-tool $CKAN_INI "api_token.jwt.encode.secret=string:${JWT_SECRET}" | ||
ckan config-tool $CKAN_INI "api_token.jwt.decode.secret=string:${JWT_SECRET}" | ||
db_command="ckan -c $CKAN_INI db init" | ||
max_retries=3 | ||
attempt=0 | ||
echo "[prerun] Initializing or upgrading db - start" | ||
while [ $attempt -lt $max_retries ]; do | ||
$db_command 2>&1 | ||
if [ $? -eq 0 ]; then | ||
echo "[prerun] Initializing or upgrading db - end" | ||
break | ||
else | ||
if grep -q "OperationalError" <<< "$($db_command 2>&1)"; then | ||
echo "[prerun] Database not ready, retrying in 5 seconds..." | ||
sleep 5 | ||
attempt=$((attempt + 1)) | ||
else | ||
echo "[prerun] Error occurred: $(tail -n 1 <(echo $?))" | ||
break | ||
fi | ||
fi | ||
attempt=$((attempt + 1)) | ||
done | ||
if [ $attempt -ge $max_retries ]; then | ||
echo "[prerun] Failed to initialize or upgrade db after $max_retries attempts, exiting..." | ||
exit 1 | ||
fi | ||
if [[ -z "$CKAN_SYSADMIN_NAME" || -z "$CKAN_SYSADMIN_PASSWORD" || -z "$CKAN_SYSADMIN_EMAIL" ]]; then | ||
echo "[prerun] Missing required environment variables: CKAN_SYSADMIN_NAME, CKAN_SYSADMIN_PASSWORD, or CKAN_SYSADMIN_EMAIL" | ||
exit 1 | ||
fi | ||
EXISTING_USER=$(ckan -c "$CKAN_INI" user show "$CKAN_SYSADMIN_NAME" 2>/dev/null) | ||
if [[ "$EXISTING_USER" == *"User: None"* ]]; then | ||
echo "[prerun] Creating sysadmin user $CKAN_SYSADMIN_NAME" | ||
ckan -c "$CKAN_INI" user add "$CKAN_SYSADMIN_NAME" "password=$CKAN_SYSADMIN_PASSWORD" "email=$CKAN_SYSADMIN_EMAIL" | ||
echo "[prerun] Created user $CKAN_SYSADMIN_NAME" | ||
ckan -c "$CKAN_INI" sysadmin add "$CKAN_SYSADMIN_NAME" | ||
echo "[prerun] Made user $CKAN_SYSADMIN_NAME a sysadmin" | ||
else | ||
echo "[prerun] Sysadmin user $CKAN_SYSADMIN_NAME exists, skipping creation" | ||
fi | ||
if [[ -z "$DATAPUSHER_API_TOKEN" ]]; then | ||
ckan -c $CKAN_INI user token add ckan_admin datapusherApiKey | tail -n 1 | tr -d '\t' > /api-tokens/datapusherApiKey; | ||
fi | ||
if [[ -z "$EMAIL_API_KEY" ]]; then | ||
ckan -c $CKAN_INI user token add ckan_admin emailApiKey | tail -n 1 | tr -d '\t' > /api-tokens/emailApiKey; | ||
fi | ||
else | ||
echo "ckan already initiated" | ||
fi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,181 @@ | ||
{{- $name := "ckan" -}} | ||
apiVersion: batch/v1 | ||
kind: Job | ||
metadata: | ||
name: {{ printf "%s-%s-post-install" (include "common.names.fullname" $) $name | quote }} | ||
labels: {{- include "common.labels.standard" . | nindent 4 }} | ||
app.kubernetes.io/component: {{ $name }} | ||
annotations: | ||
"helm.sh/hook": post-install,post-upgrade | ||
"helm.sh/hook-weight": "5" | ||
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded | ||
namespace: {{ .Release.Namespace | quote }} | ||
spec: | ||
template: | ||
spec: | ||
serviceAccountName: {{ printf "%s-%s-serviceaccount" (include "common.names.fullname" $) $name | quote }} | ||
restartPolicy: Never | ||
initContainers: | ||
- name: wait-for-postgresql | ||
image: docker.io/postgres:17.1-alpine | ||
command: [ 'sh', '-c', 'until pg_isready -U $CKAN_DB_USER -d $CKAN_DB -h {{ printf "%s-%s" (include "ckan.postgresql.fullname" . ) "primary" }} -p 5432; do echo waiting for database; sleep 2; done;' ] | ||
env: | ||
- name: CKAN_DB_USER | ||
valueFrom: | ||
secretKeyRef: | ||
name: {{ printf "%s-config" (include "ckan.postgresql.fullname" . ) }} | ||
key: ckanDatabaseUsername | ||
- name: CKAN_DB | ||
valueFrom: | ||
secretKeyRef: | ||
name: {{ printf "%s-config" (include "ckan.postgresql.fullname" . ) }} | ||
key: ckanDatabase | ||
- name: ckan-initiate | ||
image: {{ include "common.images.image" (dict "imageRoot" .Values.ckan.image "global" .Values.global) }} | ||
command: ["sh","-c","/srv/app/ckan-init.sh"] | ||
env: | ||
- name: CKAN_SYSADMIN_NAME | ||
valueFrom: | ||
secretKeyRef: | ||
name: {{ printf "%s-%s-config" (include "common.names.fullname" $) $name }} | ||
key: sysAdminUsername | ||
- name: CKAN_SYSADMIN_PASSWORD | ||
valueFrom: | ||
secretKeyRef: | ||
name: {{ printf "%s-%s-config" (include "common.names.fullname" $) $name }} | ||
key: sysAdminPassword | ||
- name: CKAN_SYSADMIN_EMAIL | ||
valueFrom: | ||
secretKeyRef: | ||
name: {{ printf "%s-%s-config" (include "common.names.fullname" $) $name }} | ||
key: sysAdminEmail | ||
- name: POSTGRES_USER | ||
value: postgres | ||
- name: POSTGRES_PASSWORD | ||
valueFrom: | ||
secretKeyRef: | ||
name: {{ printf "%s-config" (include "ckan.postgresql.fullname" . ) }} | ||
key: postgresPassword | ||
- name: POSTGRES_DB | ||
value: postgres | ||
- name: POSTGRES_HOST | ||
value: {{ printf "%s-%s" (include "ckan.postgresql.fullname" . ) "primary" }} | ||
- name: CKAN_DB_USER | ||
valueFrom: | ||
secretKeyRef: | ||
name: {{ printf "%s-config" (include "ckan.postgresql.fullname" . ) }} | ||
key: ckanDatabaseUsername | ||
- name: CKAN_DB_PASSWORD | ||
valueFrom: | ||
secretKeyRef: | ||
name: {{ printf "%s-config" (include "ckan.postgresql.fullname" . ) }} | ||
key: ckanDatabasePassword | ||
- name: CKAN_DB | ||
valueFrom: | ||
secretKeyRef: | ||
name: {{ printf "%s-config" (include "ckan.postgresql.fullname" . ) }} | ||
key: ckanDatabase | ||
- name: DATASTORE_READONLY_USER | ||
valueFrom: | ||
secretKeyRef: | ||
name: {{ printf "%s-config" (include "ckan.postgresql.fullname" . ) }} | ||
key: datastoreUsername | ||
- name: DATASTORE_READONLY_PASSWORD | ||
valueFrom: | ||
secretKeyRef: | ||
name: {{ printf "%s-config" (include "ckan.postgresql.fullname" . ) }} | ||
key: datastorePassword | ||
- name: DATASTORE_DB | ||
valueFrom: | ||
secretKeyRef: | ||
name: {{ printf "%s-config" (include "ckan.postgresql.fullname" . ) }} | ||
key: datastoreDatabase | ||
- name: CKAN_SQLALCHEMY_URL | ||
value: "postgresql://$(CKAN_DB_USER):$(CKAN_DB_PASSWORD)@{{ printf "%s-%s" (include "ckan.postgresql.fullname" . ) "primary" }}/$(CKAN_DB)" | ||
- name: CKAN_DATASTORE_WRITE_URL | ||
value: "postgresql://$(CKAN_DB_USER):$(CKAN_DB_PASSWORD)@{{ printf "%s-%s" (include "ckan.postgresql.fullname" . ) "primary" }}/$(DATASTORE_DB)" | ||
- name: CKAN_DATASTORE_READ_URL | ||
value: "postgresql://$(DATASTORE_READONLY_USER):$(DATASTORE_READONLY_PASSWORD)@{{ printf "%s-%s" (include "ckan.postgresql.fullname" . ) "read" }}/$(DATASTORE_DB)" | ||
- name: CKAN_SOLR_URL | ||
value: "http://{{ printf "%s-%s" (include "ckan.solr.fullname" . ) "headless" }}:{{ include "ckan.solr.service.port" $ }}/solr/ckan" | ||
{{- if .Values.solr.auth.enabled }} | ||
- name: CKAN_SOLR_USER | ||
valueFrom: | ||
secretKeyRef: | ||
name: {{ printf "%s-config" (include "ckan.solr.fullname" . ) }} | ||
key: solrUsername | ||
- name: CKAN_SOLR_PASSWORD | ||
valueFrom: | ||
secretKeyRef: | ||
name: {{ printf "%s-config" (include "ckan.solr.fullname" . ) }} | ||
key: solrPassword | ||
{{- end }} | ||
- name: CKAN_REDIS_URL | ||
value: "redis://{{ printf "%s-%s" (include "ckan.redis.fullname" . ) "headless" }}:{{ include "ckan.redis.service.port" $}}/0" | ||
- name: DATAPUSHER_API_TOKEN | ||
valueFrom: | ||
secretKeyRef: | ||
name: {{ printf "%s-%s-config" (include "common.names.fullname" $) $name }} | ||
key: datapusherApiKey | ||
- name: SECRET_KEY | ||
valueFrom: | ||
secretKeyRef: | ||
name: {{ printf "%s-%s-config" (include "common.names.fullname" $) $name }} | ||
key: secretKey | ||
- name: WTF_CSRF_SECRET_KEY | ||
valueFrom: | ||
secretKeyRef: | ||
name: {{ printf "%s-%s-config" (include "common.names.fullname" $) $name }} | ||
key: wtfCsrfSecretKey | ||
- name: JWT_SECRET | ||
valueFrom: | ||
secretKeyRef: | ||
name: {{ printf "%s-%s-config" (include "common.names.fullname" $) $name }} | ||
key: jwtSecret | ||
- name: EMAIL_API_KEY | ||
valueFrom: | ||
secretKeyRef: | ||
name: {{ printf "%s-%s-config" (include "common.names.fullname" $) "ckan" }} | ||
key: emailApiKey | ||
volumeMounts: | ||
- name: configmap-volume | ||
mountPath: /srv/app/ckan-init.sh | ||
readOnly: true | ||
subPath: ckan-init.sh | ||
- mountPath: /api-tokens | ||
name: api-tokens-volume | ||
- name: update-secret | ||
image: docker.io/bitnami/kubectl | ||
command: | ||
- "/bin/sh" | ||
- "-c" | ||
- | | ||
if [ "$(ls -A /api-tokens)" ]; then | ||
if [ -f "/api-tokens/datapusherApiKey" ]; then | ||
DATAPUSHER_API_TOKEN=$(cat /api-tokens/datapusherApiKey | tr -d '\n[:space:]' | base64 -w 0 ) && | ||
PATCH='[{"op": "replace", "path": "/data/datapusherApiKey", "value": "'"$DATAPUSHER_API_TOKEN"'"}]' && | ||
if [ $(kubectl get secret {{ printf "%s-%s-config" (include "common.names.fullname" $) $name }} -o jsonpath='{.data.datapusherApiKey}' | tr -d '\n[:space:]' | wc -m) -eq 0 ]; | ||
then kubectl patch secrets {{ printf "%s-%s-config" (include "common.names.fullname" $) $name }} --type json -p="$PATCH"; fi | ||
fi | ||
if [ -f "/api-tokens/emailApiKey" ]; then | ||
EMAIL_API_KEY=$(cat /api-tokens/emailApiKey | tr -d '\n[:space:]' | base64 -w 0 ) && | ||
PATCH='[{"op": "replace", "path": "/data/emailApiKey", "value": "'"$EMAIL_API_KEY"'"}]' && | ||
if [ $(kubectl get secret {{ printf "%s-%s-config" (include "common.names.fullname" $) $name }} -o jsonpath='{.data.emailApiKey}' | tr -d '\n[:space:]' | wc -m) -eq 0 ]; | ||
then kubectl patch secrets {{ printf "%s-%s-config" (include "common.names.fullname" $) $name }} --type json -p="$PATCH"; fi | ||
fi | ||
kubectl rollout restart deployment/{{ printf "%s-%s" (include "common.names.fullname" $) $name | quote }} | ||
fi | ||
volumeMounts: | ||
- mountPath: /api-tokens | ||
name: api-tokens-volume | ||
containers: | ||
- name: postinstall-config | ||
image: docker.io/busybox:1.28 | ||
command: ["sh", "-c", "echo upgrade ready!"] # 92 is the uid and gid of ckan user/group | ||
volumes: | ||
- name: configmap-volume | ||
configMap: | ||
defaultMode: 0777 | ||
name: {{ printf "%s-%s-configmap" (include "common.names.fullname" .) "ckan" }} | ||
- name: api-tokens-volume | ||
emptyDir: {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,8 @@ | ||
{{- $name := (printf "%s-%s-config" (include "common.names.fullname" .) "ckan") -}} | ||
{{- $sysAdminPassword := include "common.secrets.passwords.manage" (dict "secret" $name "length" 42 "strong" false "key" "sysAdminPassword" "providedValues" (list "ckan.sysadmin.password") "skipB64enc" true "context" (dict "Values" .Values "Release" ((dict "IsUpgrade" false "IsInstall" true "Namespace" .Release.Namespace) | mergeOverwrite (deepCopy .Release)))) }} | ||
{{- $secretKey := include "common.secrets.passwords.manage" (dict "secret" $name "length" 42 "strong" false "key" "secretKey" "providedValues" (list "ckan.secretKey") "skipB64enc" true "context" (dict "Values" .Values "Release" ((dict "IsUpgrade" false "IsInstall" true "Namespace" .Release.Namespace) | mergeOverwrite (deepCopy .Release)))) }} | ||
{{- $wtfCsrfSecretKey := include "common.secrets.passwords.manage" (dict "secret" $name "length" 42 "strong" false "key" "wtfCsrfSecretKey" "providedValues" (list "ckan.wtfCsrfSecretKey") "skipB64enc" true "context" (dict "Values" .Values "Release" ((dict "IsUpgrade" false "IsInstall" true "Namespace" .Release.Namespace) | mergeOverwrite (deepCopy .Release)))) }} | ||
{{- $jwtSecret := include "common.secrets.passwords.manage" (dict "secret" $name "length" 42 "strong" false "key" "jwtSecret" "providedValues" (list "ckan.jwtSecret") "skipB64enc" true "context" (dict "Values" .Values "Release" ((dict "IsUpgrade" false "IsInstall" true "Namespace" .Release.Namespace) | mergeOverwrite (deepCopy .Release)))) }} | ||
apiVersion: v1 | ||
kind: Secret | ||
metadata: | ||
|
@@ -11,6 +14,11 @@ stringData: | |
sysAdminUsername: {{ .Values.ckan.sysadmin.name | default "ckan_admin" | quote }} | ||
sysAdminPassword: {{ $sysAdminPassword }} | ||
sysAdminEmail: {{ .Values.ckan.sysadmin.email | default "[email protected]" | quote }} | ||
secretKey: {{ $secretKey }} | ||
wtfCsrfSecretKey: {{ $wtfCsrfSecretKey }} | ||
jwtSecret: {{ $jwtSecret }} | ||
datapusherApiKey: {{ "" }} | ||
emailApiKey: {{ "" }} | ||
{{- if .Values.ckan.smtp }} | ||
smtpPassword: {{ .Values.ckan.smtp.password | quote }} | ||
{{- end }} | ||
{{- end }} |
Oops, something went wrong.