Files
argocd-apps/apps/base/arrstack/arrproxy/migrate-job.yaml
T
unkin-agent 20c603dd84
ci/woodpecker/pr/vector-test Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
ci/woodpecker/pr/kubeconform Pipeline was successful
deploy arrproxy (oauth2-gated *arr proxy + per-user API keys)
Adds the arrproxy front door to the arrstack app: the external, oauth-gated
entry to sonarr/radarr/prowlarr with per-user API-key brokering, wired to match
the arrproxy v0.1.0 code (ports, routes, identity headers, keys dir).

Topology (apps/base/arrstack/arrproxy):
- oauth2-proxy Deployment/Service is the single front (Authentik OIDC), path-
  routing via --upstreams to arrproxy-ui (/, static SPA) and arrproxy-api
  (/api token API + /<app> proxy). skip-auth-regex ^/[^/]+/api bypasses auth
  only for the *arr proxy API (/sonarr/api...), keeping /api/tokens + /api/me
  and the UI authenticated.
- Identity+groups reach the api via --pass-user-headers (X-Forwarded-*); the api
  reads ARRPROXY_GROUPS_HEADER=X-Forwarded-Groups (set-xauthrequest is
  auth_request-response-only and never reaches an upstream).
- oauth2-proxy trusts identity.unkin.net's internal-CA cert via a combine-certs
  initContainer (system roots + vault-ca-cert).
- CNPG token store (arrproxy-db, 2 instances, cephrgw backups); a wave-1 Sync
  hook Job applies the schema (arrproxy-api does not self-migrate).
- VaultStaticSecrets for the seeded ARRPROXY_PEPPER and the oauth-credentials;
  the real *arr keys reuse the existing <app>-apikey Secrets (projected one file
  per app into /etc/arrproxy/keys).
- External Gateway (traefik-external, arrstack.unkin.net, vault-issuer TLS) +
  HTTPRoute to the oauth2-proxy entry.

Also adds the arrstack.unkin.net apex A record (-> external DMZ VIP 198.18.199.0)
to the bind-operator unkin.net zone.
2026-08-16 21:45:18 +10:00

93 lines
2.7 KiB
YAML

---
# Applies the arrproxy schema once per sync, before the api rolls, so the serve
# replicas never race migrations (arrproxy-api does not self-migrate). Runs as the
# CNPG-minted app user so the tokens table is owned by that role.
#
# Sync-phase hook at wave 1 (NOT PreSync): the CNPG Cluster + generated
# arrproxy-db-app Secret apply at wave 0 and ArgoCD waits for the Cluster to be
# Healthy before starting wave 1, so Postgres exists before migrate connects.
apiVersion: batch/v1
kind: Job
metadata:
name: arrproxy-migrate
namespace: arrstack
annotations:
argocd.argoproj.io/hook: Sync
argocd.argoproj.io/hook-delete-policy: BeforeHookCreation
argocd.argoproj.io/sync-wave: "1"
spec:
backoffLimit: 6
ttlSecondsAfterFinished: 600
template:
metadata:
labels:
app: arrproxy-migrate
spec:
serviceAccountName: default
automountServiceAccountToken: false
restartPolicy: Never
securityContext:
runAsNonRoot: true
runAsUser: 65532
runAsGroup: 65532
fsGroup: 65532
seccompProfile:
type: RuntimeDefault
containers:
- name: migrate
image: artifactapi.k8s.syd1.au.unkin.net/dockerhub/library/postgres:18-alpine
imagePullPolicy: IfNotPresent
env:
- name: HOME
value: /tmp
- name: PGUSER
valueFrom:
secretKeyRef:
name: arrproxy-db-app
key: username
- name: PGPASSWORD
valueFrom:
secretKeyRef:
name: arrproxy-db-app
key: password
- name: PGHOST
value: arrproxy-db-rw.arrstack.svc.cluster.local
- name: PGPORT
value: "5432"
- name: PGDATABASE
value: arrproxy
- name: PGSSLMODE
value: require
command:
- psql
- -v
- ON_ERROR_STOP=1
- -f
- /migrations/0001_init.sql
volumeMounts:
- name: migrations
mountPath: /migrations
readOnly: true
- name: tmp
mountPath: /tmp
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 256Mi
volumes:
- name: migrations
configMap:
name: arrproxy-migrations
- name: tmp
emptyDir:
sizeLimit: 64Mi