diff --git a/clusters/atlas/flux-system/applications/kustomization.yaml b/clusters/atlas/flux-system/applications/kustomization.yaml index cc32c85..c73906e 100644 --- a/clusters/atlas/flux-system/applications/kustomization.yaml +++ b/clusters/atlas/flux-system/applications/kustomization.yaml @@ -16,6 +16,7 @@ resources: - harbor/image-automation.yaml - jellyfin/kustomization.yaml - xmr-miner/kustomization.yaml + - wallet-monero-temp/kustomization.yaml - sui-metrics/kustomization.yaml - openldap/kustomization.yaml - keycloak/kustomization.yaml diff --git a/clusters/atlas/flux-system/applications/wallet-monero-temp/kustomization.yaml b/clusters/atlas/flux-system/applications/wallet-monero-temp/kustomization.yaml new file mode 100644 index 0000000..700e17f --- /dev/null +++ b/clusters/atlas/flux-system/applications/wallet-monero-temp/kustomization.yaml @@ -0,0 +1,19 @@ +# clusters/atlas/flux-system/applications/wallet-monero-temp/kustomization.yaml +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: wallet-monero-temp + namespace: flux-system +spec: + interval: 10m + path: ./services/crypto/wallet-monero-temp + targetNamespace: crypto + prune: true + sourceRef: + kind: GitRepository + name: flux-system + namespace: flux-system + dependsOn: + - name: crypto + - name: xmr-miner + wait: true diff --git a/services/crypto/wallet-monero-temp/deployment.yaml b/services/crypto/wallet-monero-temp/deployment.yaml new file mode 100644 index 0000000..6ac5b62 --- /dev/null +++ b/services/crypto/wallet-monero-temp/deployment.yaml @@ -0,0 +1,82 @@ +# services/crypto/wallet-monero-temp/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: wallet-monero-temp + namespace: crypto + labels: + app: wallet-monero-temp +spec: + replicas: 1 + strategy: + type: Recreate + selector: + matchLabels: + app: wallet-monero-temp + template: + metadata: + labels: + app: wallet-monero-temp + annotations: + vault.hashicorp.com/agent-inject: "true" + vault.hashicorp.com/role: "crypto" + vault.hashicorp.com/agent-inject-secret-wallet-rpc-env.sh: "kv/data/atlas/crypto/wallet-monero-temp-rpc-auth" + vault.hashicorp.com/agent-inject-template-wallet-rpc-env.sh: | + {{- with secret "kv/data/atlas/crypto/wallet-monero-temp-rpc-auth" -}} + export RPC_USER="{{ .Data.data.username }}" + export RPC_PASS="{{ .Data.data.password }}" + {{- end -}} + spec: + serviceAccountName: crypto-vault-sync + automountServiceAccountToken: true + nodeSelector: + node-role.kubernetes.io/worker: "true" + imagePullSecrets: + - name: harbor-regcred + securityContext: + fsGroup: 1000 + fsGroupChangePolicy: OnRootMismatch + initContainers: + - name: volume-permissions + image: busybox:1.36 + imagePullPolicy: IfNotPresent + command: ["/bin/sh", "-lc"] + args: + - chown :1000 /data && chmod 0770 /data + securityContext: + runAsUser: 0 + volumeMounts: + - name: data + mountPath: /data + containers: + - name: wallet-rpc + image: registry.bstein.dev/infra/monero-wallet-rpc:0.18.4.1 + imagePullPolicy: Always + command: ["/bin/sh", "-lc"] + args: + - | + set -eu + . /vault/secrets/wallet-rpc-env.sh + exec /usr/local/bin/monero-wallet-rpc \ + --wallet-dir /data \ + --daemon-address xmr-node.cakewallet.com:18081 \ + --rpc-bind-ip 0.0.0.0 --rpc-bind-port 18083 \ + --rpc-login "${RPC_USER}:${RPC_PASS}" \ + --confirm-external-bind + ports: + - containerPort: 18083 + name: rpc + resources: + requests: + cpu: 100m + memory: 128Mi + limits: + cpu: "1" + memory: 512Mi + volumeMounts: + - name: data + mountPath: /data + volumes: + - name: data + persistentVolumeClaim: + claimName: wallet-monero-temp diff --git a/services/crypto/wallet-monero-temp/kustomization.yaml b/services/crypto/wallet-monero-temp/kustomization.yaml new file mode 100644 index 0000000..005be27 --- /dev/null +++ b/services/crypto/wallet-monero-temp/kustomization.yaml @@ -0,0 +1,9 @@ +# services/crypto/wallet-monero-temp/kustomization.yaml +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - pvc.yaml + - serviceaccount.yaml + - secrets-ensure-job.yaml + - deployment.yaml + - service.yaml diff --git a/services/crypto/wallet-monero-temp/pvc.yaml b/services/crypto/wallet-monero-temp/pvc.yaml new file mode 100644 index 0000000..cf0c757 --- /dev/null +++ b/services/crypto/wallet-monero-temp/pvc.yaml @@ -0,0 +1,13 @@ +# services/crypto/wallet-monero-temp/pvc.yaml +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: wallet-monero-temp + namespace: crypto +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 5Gi + storageClassName: astreae diff --git a/services/crypto/wallet-monero-temp/secrets-ensure-job.yaml b/services/crypto/wallet-monero-temp/secrets-ensure-job.yaml new file mode 100644 index 0000000..7d0f25d --- /dev/null +++ b/services/crypto/wallet-monero-temp/secrets-ensure-job.yaml @@ -0,0 +1,37 @@ +# services/crypto/wallet-monero-temp/secrets-ensure-job.yaml +apiVersion: batch/v1 +kind: Job +metadata: + name: wallet-monero-temp-secrets-ensure + namespace: crypto +spec: + backoffLimit: 1 + template: + spec: + serviceAccountName: crypto-secrets-ensure + restartPolicy: OnFailure + containers: + - name: vault-write + image: hashicorp/vault:1.17.6 + imagePullPolicy: IfNotPresent + command: ["/bin/sh", "-c"] + args: + - | + set -euo pipefail + export VAULT_ADDR=http://vault.vault.svc.cluster.local:8200 + VAULT_TOKEN="$(vault write -field=token auth/kubernetes/login role=crypto-secrets jwt=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token))" + export VAULT_TOKEN + vault kv put kv/atlas/crypto/wallet-monero-temp-rpc-auth \ + username="${RPC_USER}" \ + password="${RPC_PASS}" + env: + - name: RPC_USER + valueFrom: + secretKeyRef: + name: wallet-monero-temp-rpc-auth + key: username + - name: RPC_PASS + valueFrom: + secretKeyRef: + name: wallet-monero-temp-rpc-auth + key: password diff --git a/services/crypto/wallet-monero-temp/service.yaml b/services/crypto/wallet-monero-temp/service.yaml new file mode 100644 index 0000000..4bf3566 --- /dev/null +++ b/services/crypto/wallet-monero-temp/service.yaml @@ -0,0 +1,16 @@ +# services/crypto/wallet-monero-temp/service.yaml +apiVersion: v1 +kind: Service +metadata: + name: wallet-monero-temp + namespace: crypto + labels: + app: wallet-monero-temp +spec: + type: ClusterIP + selector: + app: wallet-monero-temp + ports: + - name: rpc + port: 18083 + targetPort: 18083 diff --git a/services/crypto/wallet-monero-temp/serviceaccount.yaml b/services/crypto/wallet-monero-temp/serviceaccount.yaml new file mode 100644 index 0000000..f9ff1fc --- /dev/null +++ b/services/crypto/wallet-monero-temp/serviceaccount.yaml @@ -0,0 +1,6 @@ +# services/crypto/wallet-monero-temp/serviceaccount.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + name: crypto-secrets-ensure + namespace: crypto diff --git a/services/crypto/xmr-miner/xmrig-daemonset.yaml b/services/crypto/xmr-miner/xmrig-daemonset.yaml index 089dcc4..a1ee2ae 100644 --- a/services/crypto/xmr-miner/xmrig-daemonset.yaml +++ b/services/crypto/xmr-miner/xmrig-daemonset.yaml @@ -24,10 +24,6 @@ spec: - key: hardware operator: In values: ["rpi4","rpi5"] - volumes: - - name: payout - secret: - secretName: monero-payout containers: - name: xmrig image: ghcr.io/tari-project/xmrig@sha256:80defbfd0b640d604c91cb5101d3642db7928e1e68ee3c6b011289b3565a39d9 @@ -51,5 +47,3 @@ spec: --donate-level N \ --cpu-priority 1 \ --threads "${THR}" ${EXTRA} - volumeMounts: - - { name: payout, mountPath: /run/xmr, readOnly: true } diff --git a/services/logging/oauth2-proxy.yaml b/services/logging/oauth2-proxy.yaml index d7891da..104351a 100644 --- a/services/logging/oauth2-proxy.yaml +++ b/services/logging/oauth2-proxy.yaml @@ -62,7 +62,9 @@ spec: - name: oauth2-proxy image: registry.bstein.dev/tools/oauth2-proxy-vault:v7.6.0 imagePullPolicy: IfNotPresent + command: ["/entrypoint.sh"] args: + - /bin/oauth2-proxy - --provider=oidc - --redirect-url=https://logs.bstein.dev/oauth2/callback - --oidc-issuer-url=https://sso.bstein.dev/realms/atlas diff --git a/services/monitoring/secretproviderclass.yaml b/services/monitoring/secretproviderclass.yaml index 3fab887..8a6c5fb 100644 --- a/services/monitoring/secretproviderclass.yaml +++ b/services/monitoring/secretproviderclass.yaml @@ -10,36 +10,10 @@ spec: vaultAddress: "http://vault.vault.svc.cluster.local:8200" roleName: "monitoring" objects: | - - objectName: "grafana-admin__admin-user" - secretPath: "kv/data/atlas/monitoring/grafana-admin" - secretKey: "admin-user" - - objectName: "grafana-admin__admin-password" - secretPath: "kv/data/atlas/monitoring/grafana-admin" - secretKey: "admin-password" - - objectName: "postmark-relay__relay-username" - secretPath: "kv/data/atlas/shared/postmark-relay" - secretKey: "relay-username" - - objectName: "postmark-relay__relay-password" - secretPath: "kv/data/atlas/shared/postmark-relay" - secretKey: "relay-password" - objectName: "harbor-pull__dockerconfigjson" secretPath: "kv/data/atlas/harbor-pull/monitoring" secretKey: "dockerconfigjson" secretObjects: - - secretName: grafana-admin - type: Opaque - data: - - objectName: grafana-admin__admin-user - key: admin-user - - objectName: grafana-admin__admin-password - key: admin-password - - secretName: grafana-smtp - type: Opaque - data: - - objectName: postmark-relay__relay-username - key: username - - objectName: postmark-relay__relay-password - key: password - secretName: harbor-regcred type: kubernetes.io/dockerconfigjson data: diff --git a/services/oauth2-proxy/deployment.yaml b/services/oauth2-proxy/deployment.yaml index 64cdd0e..4af5ab1 100644 --- a/services/oauth2-proxy/deployment.yaml +++ b/services/oauth2-proxy/deployment.yaml @@ -44,7 +44,9 @@ spec: - name: oauth2-proxy image: registry.bstein.dev/tools/oauth2-proxy-vault:v7.6.0 imagePullPolicy: IfNotPresent + command: ["/entrypoint.sh"] args: + - /bin/oauth2-proxy - --provider=oidc - --redirect-url=https://auth.bstein.dev/oauth2/callback - --oidc-issuer-url=https://sso.bstein.dev/realms/atlas diff --git a/services/vault/k8s-auth-config-cronjob.yaml b/services/vault/k8s-auth-config-cronjob.yaml index 3b74932..e9ee3e9 100644 --- a/services/vault/k8s-auth-config-cronjob.yaml +++ b/services/vault/k8s-auth-config-cronjob.yaml @@ -29,11 +29,8 @@ spec: env: - name: VAULT_ADDR value: http://vault.vault.svc.cluster.local:8200 - - name: VAULT_TOKEN - valueFrom: - secretKeyRef: - name: vault-oidc-admin-token - key: token + - name: VAULT_K8S_ROLE + value: vault - name: VAULT_K8S_ROLE_TTL value: 1h volumeMounts: diff --git a/services/vault/oidc-config-cronjob.yaml b/services/vault/oidc-config-cronjob.yaml index efe5fee..b143d99 100644 --- a/services/vault/oidc-config-cronjob.yaml +++ b/services/vault/oidc-config-cronjob.yaml @@ -57,11 +57,8 @@ spec: env: - name: VAULT_ADDR value: http://vault.vault.svc.cluster.local:8200 - - name: VAULT_TOKEN - valueFrom: - secretKeyRef: - name: vault-oidc-admin-token - key: token + - name: VAULT_K8S_ROLE + value: vault - name: VAULT_ENV_FILE value: /vault/secrets/vault-oidc-env.sh volumeMounts: diff --git a/services/vault/scripts/vault_k8s_auth_configure.sh b/services/vault/scripts/vault_k8s_auth_configure.sh index f0d7833..ed67c9b 100644 --- a/services/vault/scripts/vault_k8s_auth_configure.sh +++ b/services/vault/scripts/vault_k8s_auth_configure.sh @@ -3,6 +3,19 @@ set -eu log() { echo "[vault-k8s-auth] $*"; } +ensure_token() { + if [ -n "${VAULT_TOKEN:-}" ]; then + return + fi + role="${VAULT_K8S_ROLE:-vault}" + jwt="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" + if ! VAULT_TOKEN="$(vault write -field=token auth/kubernetes/login role="${role}" jwt="${jwt}")"; then + log "kubernetes auth login failed; set VAULT_TOKEN or fix role ${role}" + exit 1 + fi + export VAULT_TOKEN +} + status_json="$(vault status -format=json || true)" if [ -z "${status_json}" ]; then log "vault status failed; check VAULT_ADDR and VAULT_TOKEN" @@ -19,6 +32,8 @@ if printf '%s' "${status_json}" | grep -q '"sealed":[[:space:]]*true'; then exit 0 fi +ensure_token + k8s_host="https://${KUBERNETES_SERVICE_HOST}:443" k8s_ca="$(cat /var/run/secrets/kubernetes.io/serviceaccount/ca.crt)" k8s_token="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" @@ -115,6 +130,9 @@ write_policy_and_role "vault" "vault" "vault" \ write_policy_and_role "sso-secrets" "sso" "mas-secrets-ensure" \ "shared/keycloak-admin" \ "harbor/harbor-oidc vault/vault-oidc-config comms/synapse-oidc logging/oauth2-proxy-logs-oidc" +write_policy_and_role "crypto-secrets" "crypto" "crypto-secrets-ensure" \ + "" \ + "crypto/wallet-monero-temp-rpc-auth" write_policy_and_role "comms-secrets" "comms" \ "comms-secrets-ensure,mas-db-ensure,mas-admin-client-secret-writer,othrys-synapse-signingkey-job" \ "" \ diff --git a/services/vault/scripts/vault_oidc_configure.sh b/services/vault/scripts/vault_oidc_configure.sh index 99f5fd6..4ee91b8 100644 --- a/services/vault/scripts/vault_oidc_configure.sh +++ b/services/vault/scripts/vault_oidc_configure.sh @@ -3,6 +3,19 @@ set -eu log() { echo "[vault-oidc] $*"; } +ensure_token() { + if [ -n "${VAULT_TOKEN:-}" ]; then + return + fi + role="${VAULT_K8S_ROLE:-vault}" + jwt="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" + if ! VAULT_TOKEN="$(vault write -field=token auth/kubernetes/login role="${role}" jwt="${jwt}")"; then + log "kubernetes auth login failed; set VAULT_TOKEN or fix role ${role}" + exit 1 + fi + export VAULT_TOKEN +} + status_json="$(vault status -format=json || true)" if [ -z "${status_json}" ]; then log "vault status failed; check VAULT_ADDR and VAULT_TOKEN" @@ -19,6 +32,8 @@ if printf '%s' "${status_json}" | grep -q '"sealed":[[:space:]]*true'; then exit 0 fi +ensure_token + : "${VAULT_OIDC_DISCOVERY_URL:?set VAULT_OIDC_DISCOVERY_URL}" : "${VAULT_OIDC_CLIENT_ID:?set VAULT_OIDC_CLIENT_ID}" : "${VAULT_OIDC_CLIENT_SECRET:?set VAULT_OIDC_CLIENT_SECRET}"