finance: seed vault secrets
This commit is contained in:
parent
3e3061fe5b
commit
62fa6ef371
@ -22,6 +22,7 @@ spec:
|
|||||||
app: actual-budget
|
app: actual-budget
|
||||||
annotations:
|
annotations:
|
||||||
vault.hashicorp.com/agent-inject: "true"
|
vault.hashicorp.com/agent-inject: "true"
|
||||||
|
vault.hashicorp.com/agent-pre-populate-only: "true"
|
||||||
vault.hashicorp.com/role: "finance"
|
vault.hashicorp.com/role: "finance"
|
||||||
vault.hashicorp.com/agent-inject-secret-actual-env.sh: "kv/data/atlas/finance/actual-oidc"
|
vault.hashicorp.com/agent-inject-secret-actual-env.sh: "kv/data/atlas/finance/actual-oidc"
|
||||||
vault.hashicorp.com/agent-inject-template-actual-env.sh: |
|
vault.hashicorp.com/agent-inject-template-actual-env.sh: |
|
||||||
|
|||||||
59
services/finance/finance-secrets-ensure-job.yaml
Normal file
59
services/finance/finance-secrets-ensure-job.yaml
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
# services/finance/finance-secrets-ensure-job.yaml
|
||||||
|
apiVersion: batch/v1
|
||||||
|
kind: Job
|
||||||
|
metadata:
|
||||||
|
name: finance-secrets-ensure-1
|
||||||
|
namespace: finance
|
||||||
|
spec:
|
||||||
|
backoffLimit: 1
|
||||||
|
ttlSecondsAfterFinished: 3600
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
serviceAccountName: finance-secrets-ensure
|
||||||
|
restartPolicy: Never
|
||||||
|
affinity:
|
||||||
|
nodeAffinity:
|
||||||
|
preferredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- weight: 100
|
||||||
|
preference:
|
||||||
|
matchExpressions:
|
||||||
|
- key: hardware
|
||||||
|
operator: In
|
||||||
|
values: ["rpi5"]
|
||||||
|
- weight: 70
|
||||||
|
preference:
|
||||||
|
matchExpressions:
|
||||||
|
- key: hardware
|
||||||
|
operator: In
|
||||||
|
values: ["rpi4"]
|
||||||
|
nodeSelector:
|
||||||
|
kubernetes.io/arch: arm64
|
||||||
|
node-role.kubernetes.io/worker: "true"
|
||||||
|
containers:
|
||||||
|
- name: ensure
|
||||||
|
image: alpine:3.20
|
||||||
|
command: ["/scripts/finance_secrets_ensure.sh"]
|
||||||
|
env:
|
||||||
|
- name: VAULT_ROLE
|
||||||
|
value: finance-secrets
|
||||||
|
volumeMounts:
|
||||||
|
- name: finance-secrets-ensure-script
|
||||||
|
mountPath: /scripts
|
||||||
|
readOnly: true
|
||||||
|
- name: firefly-db
|
||||||
|
mountPath: /secrets/firefly-db
|
||||||
|
readOnly: true
|
||||||
|
- name: actualbudget-db
|
||||||
|
mountPath: /secrets/actualbudget-db
|
||||||
|
readOnly: true
|
||||||
|
volumes:
|
||||||
|
- name: finance-secrets-ensure-script
|
||||||
|
configMap:
|
||||||
|
name: finance-secrets-ensure-script
|
||||||
|
defaultMode: 0555
|
||||||
|
- name: firefly-db
|
||||||
|
secret:
|
||||||
|
secretName: firefly-db
|
||||||
|
- name: actualbudget-db
|
||||||
|
secret:
|
||||||
|
secretName: actualbudget-db
|
||||||
@ -123,8 +123,10 @@ spec:
|
|||||||
value: "587"
|
value: "587"
|
||||||
- name: MAIL_ENCRYPTION
|
- name: MAIL_ENCRYPTION
|
||||||
value: tls
|
value: tls
|
||||||
- name: MAIL_FROM
|
- name: MAIL_FROM_ADDRESS
|
||||||
value: no-reply-firefly@bstein.dev
|
value: no-reply-firefly@bstein.dev
|
||||||
|
- name: MAIL_FROM_NAME
|
||||||
|
value: Firefly III
|
||||||
- name: CACHE_DRIVER
|
- name: CACHE_DRIVER
|
||||||
value: file
|
value: file
|
||||||
- name: SESSION_DRIVER
|
- name: SESSION_DRIVER
|
||||||
|
|||||||
@ -8,6 +8,7 @@ resources:
|
|||||||
- portal-rbac.yaml
|
- portal-rbac.yaml
|
||||||
- actual-budget-data-pvc.yaml
|
- actual-budget-data-pvc.yaml
|
||||||
- firefly-storage-pvc.yaml
|
- firefly-storage-pvc.yaml
|
||||||
|
- finance-secrets-ensure-job.yaml
|
||||||
- actual-budget-deployment.yaml
|
- actual-budget-deployment.yaml
|
||||||
- firefly-deployment.yaml
|
- firefly-deployment.yaml
|
||||||
- firefly-user-sync-cronjob.yaml
|
- firefly-user-sync-cronjob.yaml
|
||||||
@ -25,3 +26,6 @@ configMapGenerator:
|
|||||||
- name: firefly-user-sync-script
|
- name: firefly-user-sync-script
|
||||||
files:
|
files:
|
||||||
- firefly_user_sync.php=scripts/firefly_user_sync.php
|
- firefly_user_sync.php=scripts/firefly_user_sync.php
|
||||||
|
- name: finance-secrets-ensure-script
|
||||||
|
files:
|
||||||
|
- finance_secrets_ensure.sh=scripts/finance_secrets_ensure.sh
|
||||||
|
|||||||
132
services/finance/scripts/finance_secrets_ensure.sh
Executable file
132
services/finance/scripts/finance_secrets_ensure.sh
Executable file
@ -0,0 +1,132 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
apk add --no-cache curl jq >/dev/null
|
||||||
|
|
||||||
|
vault_addr="${VAULT_ADDR:-http://vault.vault.svc.cluster.local:8200}"
|
||||||
|
vault_role="${VAULT_ROLE:-finance-secrets}"
|
||||||
|
jwt="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)"
|
||||||
|
login_payload="$(jq -nc --arg jwt "${jwt}" --arg role "${vault_role}" '{jwt:$jwt, role:$role}')"
|
||||||
|
vault_token="$(curl -sS --request POST --data "${login_payload}" \
|
||||||
|
"${vault_addr}/v1/auth/kubernetes/login" | jq -r '.auth.client_token')"
|
||||||
|
if [ -z "${vault_token}" ] || [ "${vault_token}" = "null" ]; then
|
||||||
|
echo "vault login failed" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
read_secret() {
|
||||||
|
path="$1"
|
||||||
|
if [ -f "${path}" ]; then
|
||||||
|
cat "${path}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
require_value() {
|
||||||
|
label="$1"
|
||||||
|
value="$2"
|
||||||
|
if [ -z "${value}" ]; then
|
||||||
|
echo "missing ${label}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
vault_read() {
|
||||||
|
path="$1"
|
||||||
|
key="$2"
|
||||||
|
curl -sS -H "X-Vault-Token: ${vault_token}" \
|
||||||
|
"${vault_addr}/v1/kv/data/atlas/${path}" 2>/dev/null | \
|
||||||
|
jq -r --arg key "${key}" '.data.data[$key] // empty' 2>/dev/null || true
|
||||||
|
}
|
||||||
|
|
||||||
|
vault_write_json() {
|
||||||
|
path="$1"
|
||||||
|
payload="$2"
|
||||||
|
curl -sS -X POST -H "X-Vault-Token: ${vault_token}" \
|
||||||
|
-d "${payload}" "${vault_addr}/v1/kv/data/atlas/${path}" >/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
firefly_db_host="$(read_secret /secrets/firefly-db/DB_HOST)"
|
||||||
|
if [ -z "${firefly_db_host}" ]; then
|
||||||
|
firefly_db_host="$(read_secret /secrets/firefly-db/DB_HOSTNAME)"
|
||||||
|
fi
|
||||||
|
firefly_db_port="$(read_secret /secrets/firefly-db/DB_PORT)"
|
||||||
|
firefly_db_name="$(read_secret /secrets/firefly-db/DB_DATABASE)"
|
||||||
|
if [ -z "${firefly_db_name}" ]; then
|
||||||
|
firefly_db_name="$(read_secret /secrets/firefly-db/DB_NAME)"
|
||||||
|
fi
|
||||||
|
firefly_db_user="$(read_secret /secrets/firefly-db/DB_USERNAME)"
|
||||||
|
if [ -z "${firefly_db_user}" ]; then
|
||||||
|
firefly_db_user="$(read_secret /secrets/firefly-db/DB_USER)"
|
||||||
|
fi
|
||||||
|
firefly_db_pass="$(read_secret /secrets/firefly-db/DB_PASSWORD)"
|
||||||
|
if [ -z "${firefly_db_pass}" ]; then
|
||||||
|
firefly_db_pass="$(read_secret /secrets/firefly-db/DB_PASS)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
require_value "firefly-db/DB_HOST" "${firefly_db_host}"
|
||||||
|
require_value "firefly-db/DB_PORT" "${firefly_db_port}"
|
||||||
|
require_value "firefly-db/DB_DATABASE" "${firefly_db_name}"
|
||||||
|
require_value "firefly-db/DB_USERNAME" "${firefly_db_user}"
|
||||||
|
require_value "firefly-db/DB_PASSWORD" "${firefly_db_pass}"
|
||||||
|
|
||||||
|
firefly_payload="$(jq -nc \
|
||||||
|
--arg host "${firefly_db_host}" \
|
||||||
|
--arg port "${firefly_db_port}" \
|
||||||
|
--arg db "${firefly_db_name}" \
|
||||||
|
--arg user "${firefly_db_user}" \
|
||||||
|
--arg pass "${firefly_db_pass}" \
|
||||||
|
'{data:{DB_HOST:$host, DB_PORT:$port, DB_DATABASE:$db, DB_USERNAME:$user, DB_PASSWORD:$pass}}')"
|
||||||
|
vault_write_json "finance/firefly-db" "${firefly_payload}"
|
||||||
|
|
||||||
|
app_key="$(vault_read "finance/firefly-secrets" "APP_KEY")"
|
||||||
|
if [ -z "${app_key}" ]; then
|
||||||
|
app_key="base64:$(head -c 32 /dev/urandom | base64 | tr -d '\n')"
|
||||||
|
fi
|
||||||
|
cron_token="$(vault_read "finance/firefly-secrets" "STATIC_CRON_TOKEN")"
|
||||||
|
if [ -z "${cron_token}" ]; then
|
||||||
|
cron_token="$(head -c 32 /dev/urandom | base64 | tr -d '\n' | tr '+/' '-_' | tr -d '=')"
|
||||||
|
fi
|
||||||
|
firefly_secret_payload="$(jq -nc \
|
||||||
|
--arg app_key "${app_key}" \
|
||||||
|
--arg cron "${cron_token}" \
|
||||||
|
'{data:{APP_KEY:$app_key, STATIC_CRON_TOKEN:$cron}}')"
|
||||||
|
vault_write_json "finance/firefly-secrets" "${firefly_secret_payload}"
|
||||||
|
|
||||||
|
if [ -d /secrets/actualbudget-db ]; then
|
||||||
|
actual_db_host="$(read_secret /secrets/actualbudget-db/DB_HOST)"
|
||||||
|
if [ -z "${actual_db_host}" ]; then
|
||||||
|
actual_db_host="$(read_secret /secrets/actualbudget-db/DB_HOSTNAME)"
|
||||||
|
fi
|
||||||
|
actual_db_port="$(read_secret /secrets/actualbudget-db/DB_PORT)"
|
||||||
|
actual_db_name="$(read_secret /secrets/actualbudget-db/DB_DATABASE)"
|
||||||
|
if [ -z "${actual_db_name}" ]; then
|
||||||
|
actual_db_name="$(read_secret /secrets/actualbudget-db/DB_NAME)"
|
||||||
|
fi
|
||||||
|
actual_db_user="$(read_secret /secrets/actualbudget-db/DB_USERNAME)"
|
||||||
|
if [ -z "${actual_db_user}" ]; then
|
||||||
|
actual_db_user="$(read_secret /secrets/actualbudget-db/DB_USER)"
|
||||||
|
fi
|
||||||
|
actual_db_pass="$(read_secret /secrets/actualbudget-db/DB_PASSWORD)"
|
||||||
|
if [ -z "${actual_db_pass}" ]; then
|
||||||
|
actual_db_pass="$(read_secret /secrets/actualbudget-db/DB_PASS)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "${actual_db_host}${actual_db_port}${actual_db_name}${actual_db_user}${actual_db_pass}" ]; then
|
||||||
|
require_value "actualbudget-db/DB_HOST" "${actual_db_host}"
|
||||||
|
require_value "actualbudget-db/DB_PORT" "${actual_db_port}"
|
||||||
|
require_value "actualbudget-db/DB_DATABASE" "${actual_db_name}"
|
||||||
|
require_value "actualbudget-db/DB_USERNAME" "${actual_db_user}"
|
||||||
|
require_value "actualbudget-db/DB_PASSWORD" "${actual_db_pass}"
|
||||||
|
|
||||||
|
actual_payload="$(jq -nc \
|
||||||
|
--arg host "${actual_db_host}" \
|
||||||
|
--arg port "${actual_db_port}" \
|
||||||
|
--arg db "${actual_db_name}" \
|
||||||
|
--arg user "${actual_db_user}" \
|
||||||
|
--arg pass "${actual_db_pass}" \
|
||||||
|
'{data:{DB_HOST:$host, DB_PORT:$port, DB_DATABASE:$db, DB_USERNAME:$user, DB_PASSWORD:$pass}}')"
|
||||||
|
vault_write_json "finance/actual-db" "${actual_payload}"
|
||||||
|
else
|
||||||
|
echo "actualbudget-db secret empty; skipping actual-db vault write" >&2
|
||||||
|
fi
|
||||||
|
fi
|
||||||
@ -4,3 +4,9 @@ kind: ServiceAccount
|
|||||||
metadata:
|
metadata:
|
||||||
name: finance-vault
|
name: finance-vault
|
||||||
namespace: finance
|
namespace: finance
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ServiceAccount
|
||||||
|
metadata:
|
||||||
|
name: finance-secrets-ensure
|
||||||
|
namespace: finance
|
||||||
|
|||||||
@ -216,6 +216,9 @@ write_policy_and_role "health" "health" "health-vault-sync" \
|
|||||||
"health/*" ""
|
"health/*" ""
|
||||||
write_policy_and_role "finance" "finance" "finance-vault" \
|
write_policy_and_role "finance" "finance" "finance-vault" \
|
||||||
"finance/* shared/postmark-relay" ""
|
"finance/* shared/postmark-relay" ""
|
||||||
|
write_policy_and_role "finance-secrets" "finance" "finance-secrets-ensure" \
|
||||||
|
"" \
|
||||||
|
"finance/*"
|
||||||
write_policy_and_role "longhorn" "longhorn-system" "longhorn-vault,longhorn-vault-sync" \
|
write_policy_and_role "longhorn" "longhorn-system" "longhorn-vault,longhorn-vault-sync" \
|
||||||
"longhorn/* harbor-pull/longhorn" ""
|
"longhorn/* harbor-pull/longhorn" ""
|
||||||
write_policy_and_role "postgres" "postgres" "postgres-vault" \
|
write_policy_and_role "postgres" "postgres" "postgres-vault" \
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user