# services/maintenance/ariadne-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ariadne
  namespace: maintenance
spec:
  replicas: 1
  revisionHistoryLimit: 3
  selector:
    matchLabels:
      app: ariadne
  template:
    metadata:
      labels:
        app: ariadne
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/port: "8080"
        prometheus.io/path: "/metrics"
        maintenance.bstein.dev/restart-rev: "20260413-jenkins-api-2"
        vault.hashicorp.com/agent-inject: "true"
        vault.hashicorp.com/role: "maintenance"
        vault.hashicorp.com/agent-requests-cpu: "25m"
        vault.hashicorp.com/agent-limits-cpu: "100m"
        vault.hashicorp.com/agent-requests-mem: "32Mi"
        vault.hashicorp.com/agent-limits-mem: "128Mi"
        vault.hashicorp.com/agent-inject-secret-ariadne-env.sh: "kv/data/atlas/maintenance/ariadne-db"
        vault.hashicorp.com/agent-inject-template-ariadne-env.sh: |
          {{ with secret "kv/data/atlas/maintenance/ariadne-db" }}
          export ARIADNE_DATABASE_URL="{{ .Data.data.database_url }}"
          export JENKINS_API_USER="{{ .Data.data.jenkins_api_user }}"
          export JENKINS_API_TOKEN="{{ .Data.data.jenkins_api_token }}"
          {{- if .Data.data.game_mode_hook_token }}
          export GAME_MODE_HOOK_TOKEN="{{ .Data.data.game_mode_hook_token }}"
          {{- end }}
          {{ end }}
          {{ with secret "kv/data/atlas/portal/atlas-portal-db" }}
          export PORTAL_DATABASE_URL="{{ .Data.data.PORTAL_DATABASE_URL }}"
          {{ end }}
          {{ with secret "kv/data/atlas/portal/bstein-dev-home-keycloak-admin" }}
          export KEYCLOAK_ADMIN_CLIENT_SECRET="{{ .Data.data.client_secret }}"
          {{ end }}
          {{ with secret "kv/data/atlas/nextcloud/nextcloud-db" }}
          export NEXTCLOUD_DB_NAME="{{ .Data.data.database }}"
          export NEXTCLOUD_DB_USER="{{ index .Data.data "db-username" }}"
          export NEXTCLOUD_DB_PASSWORD="{{ index .Data.data "db-password" }}"
          {{ end }}
          {{ with secret "kv/data/atlas/nextcloud/nextcloud-admin" }}
          export NEXTCLOUD_ADMIN_USER="{{ index .Data.data "admin-user" }}"
          export NEXTCLOUD_ADMIN_PASSWORD="{{ index .Data.data "admin-password" }}"
          {{ end }}
          {{ with secret "kv/data/atlas/health/wger-admin" }}
          export WGER_ADMIN_USERNAME="{{ .Data.data.username }}"
          export WGER_ADMIN_PASSWORD="{{ .Data.data.password }}"
          {{ end }}
          {{ with secret "kv/data/atlas/finance/firefly-secrets" }}
          export FIREFLY_CRON_TOKEN="{{ .Data.data.STATIC_CRON_TOKEN }}"
          {{ end }}
          {{ with secret "kv/data/atlas/mailu/mailu-db-secret" }}
          export MAILU_DB_NAME="{{ .Data.data.database }}"
          export MAILU_DB_USER="{{ .Data.data.username }}"
          export MAILU_DB_PASSWORD="{{ .Data.data.password }}"
          {{ end }}
          {{ with secret "kv/data/atlas/mailu/mailu-initial-account-secret" }}
          export SMTP_HOST="mailu-front.mailu-mailserver.svc.cluster.local"
          export SMTP_PORT="587"
          export SMTP_STARTTLS="true"
          export SMTP_USE_TLS="false"
          export SMTP_USERNAME="no-reply-portal@bstein.dev"
          export SMTP_PASSWORD="{{ .Data.data.password }}"
          export SMTP_FROM="no-reply-portal@bstein.dev"
          export MAILU_SYSTEM_PASSWORD="{{ .Data.data.password }}"
          {{ end }}
          {{ with secret "kv/data/atlas/comms/mas-admin-client-runtime" }}
          export COMMS_MAS_ADMIN_CLIENT_SECRET="{{ .Data.data.client_secret }}"
          {{ end }}
          {{ with secret "kv/data/atlas/comms/atlasbot-credentials-runtime" }}
          export COMMS_BOT_PASSWORD="{{ index .Data.data "bot-password" }}"
          export COMMS_SEEDER_PASSWORD="{{ index .Data.data "seeder-password" }}"
          {{ end }}
          {{ with secret "kv/data/atlas/comms/synapse-admin" }}
          export COMMS_SYNAPSE_ADMIN_TOKEN="{{ .Data.data.access_token }}"
          {{ end }}
          {{ with secret "kv/data/atlas/comms/synapse-db" }}
          export COMMS_SYNAPSE_DB_PASSWORD="{{ .Data.data.POSTGRES_PASSWORD }}"
          {{ end }}
          {{ with secret "kv/data/atlas/vault/vault-oidc-config" }}
          export VAULT_OIDC_DISCOVERY_URL="{{ .Data.data.discovery_url }}"
          export VAULT_OIDC_CLIENT_ID="{{ .Data.data.client_id }}"
          export VAULT_OIDC_CLIENT_SECRET="{{ .Data.data.client_secret }}"
          export VAULT_OIDC_DEFAULT_ROLE="{{ .Data.data.default_role }}"
          export VAULT_OIDC_SCOPES="{{ .Data.data.scopes }}"
          export VAULT_OIDC_USER_CLAIM="{{ .Data.data.user_claim }}"
          export VAULT_OIDC_GROUPS_CLAIM="{{ .Data.data.groups_claim }}"
          {{- if .Data.data.token_policies }}
          export VAULT_OIDC_TOKEN_POLICIES="{{ .Data.data.token_policies }}"
          {{- else }}
          export VAULT_OIDC_TOKEN_POLICIES="default"
          {{- end }}
          export VAULT_OIDC_ADMIN_GROUP="{{ .Data.data.admin_group }}"
          export VAULT_OIDC_ADMIN_POLICIES="{{ .Data.data.admin_policies }}"
          {{- if .Data.data.admin_bound_claims }}
          export VAULT_OIDC_ADMIN_BOUND_CLAIMS="{{ .Data.data.admin_bound_claims }}"
          {{- else }}
          export VAULT_OIDC_ADMIN_BOUND_CLAIMS="{\"groups\":\"admin\"}"
          {{- end }}
          export VAULT_OIDC_DEV_GROUP="{{ .Data.data.dev_group }}"
          export VAULT_OIDC_DEV_POLICIES="{{ .Data.data.dev_policies }}"
          export VAULT_OIDC_USER_GROUP="{{ .Data.data.user_group }}"
          export VAULT_OIDC_USER_POLICIES="{{ .Data.data.user_policies }}"
          export VAULT_OIDC_REDIRECT_URIS="{{ .Data.data.redirect_uris }}"
          export VAULT_OIDC_BOUND_AUDIENCES="{{ .Data.data.bound_audiences }}"
          {{- if .Data.data.ui_default_auth_method }}
          export VAULT_UI_DEFAULT_AUTH_METHOD="{{ .Data.data.ui_default_auth_method }}"
          {{- else }}
          export VAULT_UI_DEFAULT_AUTH_METHOD="oidc"
          {{- end }}
          {{- if .Data.data.ui_default_auth_path }}
          export VAULT_UI_DEFAULT_AUTH_PATH="{{ .Data.data.ui_default_auth_path }}"
          {{- else }}
          export VAULT_UI_DEFAULT_AUTH_PATH="oidc"
          {{- end }}
          {{- if .Data.data.bound_claims_type }}
          export VAULT_OIDC_BOUND_CLAIMS_TYPE="{{ .Data.data.bound_claims_type }}"
          {{- else }}
          export VAULT_OIDC_BOUND_CLAIMS_TYPE="string"
          {{- end }}
          {{ end }}
    spec:
      serviceAccountName: ariadne
      nodeSelector:
        kubernetes.io/arch: arm64
        node-role.kubernetes.io/worker: "true"
      affinity:
        nodeAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
            - weight: 100
              preference:
                matchExpressions:
                  - key: hardware
                    operator: In
                    values: ["rpi5"]
            - weight: 95
              preference:
                matchExpressions:
                  - key: kubernetes.io/hostname
                    operator: NotIn
                    values:
                      - titan-13
                      - titan-14
                      - titan-15
                      - titan-17
                      - titan-19
            - weight: 80
              preference:
                matchExpressions:
                  - key: atlas.bstein.dev/spillover
                    operator: DoesNotExist
            - weight: 50
              preference:
                matchExpressions:
                  - key: hardware
                    operator: In
                    values: ["rpi4"]
      containers:
        - name: ariadne
          image: registry.bstein.dev/bstein/ariadne:latest
          imagePullPolicy: Always
          command: ["/bin/sh", "-c"]
          args:
            - >-
              . /vault/secrets/ariadne-env.sh
              && exec uvicorn ariadne.app:app --host 0.0.0.0 --port 8080
          ports:
            - name: http
              containerPort: 8080
          env:
            - name: KEYCLOAK_URL
              value: https://sso.bstein.dev
            - name: KEYCLOAK_REALM
              value: atlas
            - name: KEYCLOAK_CLIENT_ID
              value: bstein-dev-home
            - name: KEYCLOAK_EXTRA_CLIENT_IDS
              value: wolf
            - name: KEYCLOAK_ISSUER
              value: https://sso.bstein.dev/realms/atlas
            - name: KEYCLOAK_JWKS_URL
              value: http://keycloak.sso.svc.cluster.local/realms/atlas/protocol/openid-connect/certs
            - name: KEYCLOAK_ADMIN_URL
              value: http://keycloak.sso.svc.cluster.local
            - name: KEYCLOAK_ADMIN_REALM
              value: atlas
            - name: KEYCLOAK_ADMIN_CLIENT_ID
              value: bstein-dev-home-admin
            - name: PORTAL_PUBLIC_BASE_URL
              value: https://bstein.dev
            - name: ARIADNE_LOG_LEVEL
              value: INFO
            - name: ARIADNE_DB_POOL_MIN
              value: "0"
            - name: ARIADNE_DB_POOL_MAX
              value: "5"
            - name: ARIADNE_DB_CONNECT_TIMEOUT_SEC
              value: "5"
            - name: ARIADNE_DB_LOCK_TIMEOUT_SEC
              value: "5"
            - name: ARIADNE_DB_STATEMENT_TIMEOUT_SEC
              value: "30"
            - name: ARIADNE_DB_IDLE_IN_TX_TIMEOUT_SEC
              value: "10"
            - name: ARIADNE_RUN_MIGRATIONS
              value: "false"
            - name: PORTAL_ADMIN_USERS
              value: bstein
            - name: PORTAL_ADMIN_GROUPS
              value: admin
            - name: ACCOUNT_ALLOWED_GROUPS
              value: dev,admin
            - name: ALLOWED_FLAG_GROUPS
              value: demo,test,vaultwarden_grandfathered
            - name: DEFAULT_USER_GROUPS
              value: dev
            - name: MAILU_DOMAIN
              value: bstein.dev
            - name: MAILU_HOST
              value: mail.bstein.dev
            - name: MAILU_SYNC_URL
              value: http://ariadne.maintenance.svc.cluster.local/events
            - name: MAILU_EVENT_MIN_INTERVAL_SEC
              value: "10"
            - name: MAILU_SYSTEM_USERS
              value: no-reply-portal@bstein.dev,no-reply-vaultwarden@bstein.dev
            - name: MAILU_MAILBOX_WAIT_TIMEOUT_SEC
              value: "180"
            - name: MAILU_DB_HOST
              value: postgres-service.postgres.svc.cluster.local
            - name: MAILU_DB_PORT
              value: "5432"
            - name: NEXTCLOUD_NAMESPACE
              value: nextcloud
            - name: NEXTCLOUD_POD_LABEL
              value: app=nextcloud
            - name: NEXTCLOUD_CONTAINER
              value: nextcloud
            - name: NEXTCLOUD_EXEC_TIMEOUT_SEC
              value: "120"
            - name: NEXTCLOUD_URL
              value: https://cloud.bstein.dev
            - name: NEXTCLOUD_DB_HOST
              value: postgres-service.postgres.svc.cluster.local
            - name: NEXTCLOUD_DB_PORT
              value: "5432"
            - name: WGER_NAMESPACE
              value: health
            - name: WGER_USER_SYNC_WAIT_TIMEOUT_SEC
              value: "90"
            - name: WGER_POD_LABEL
              value: app=wger
            - name: WGER_CONTAINER
              value: wger
            - name: WGER_ADMIN_EMAIL
              value: brad@bstein.dev
            - name: FIREFLY_NAMESPACE
              value: finance
            - name: FIREFLY_USER_SYNC_WAIT_TIMEOUT_SEC
              value: "90"
            - name: FIREFLY_POD_LABEL
              value: app=firefly
            - name: FIREFLY_CONTAINER
              value: firefly
            - name: FIREFLY_CRON_BASE_URL
              value: http://firefly.finance.svc.cluster.local/api/v1/cron
            - name: FIREFLY_CRON_TIMEOUT_SEC
              value: "30"
            - name: VAULT_NAMESPACE
              value: vault
            - name: VAULT_ADDR
              value: http://vault.vault.svc.cluster.local:8200
            - name: VAULT_K8S_ROLE
              value: vault-admin
            - name: VAULT_K8S_ROLE_TTL
              value: 1h
            - name: GAME_MODE_NODE_NAME
              value: titan-24
            - name: GAME_MODE_DISPLACE_WORKLOADS
              value: >-
                [{"kind":"Deployment","namespace":"openclaw","name":"openclaw-ollama","restoreReplicas":1}]
            - name: WOLF_OIDC_CLIENT_ID
              value: wolf
            - name: WOLF_OIDC_BASE_URL
              value: https://wolf.bstein.dev
            - name: WOLF_OIDC_VAULT_PATH
              value: game-stream/wolf-oidc
            - name: ARIADNE_SCHEDULE_WOLF_OIDC
              value: "17 */6 * * *"
            - name: WOLF_API_URL
              value: http://wolf-api.game-stream.svc.cluster.local:8088
            - name: WOLF_GATEKEEPER_URL
              value: http://wolf-gatekeeper.game-stream.svc.cluster.local:8087
            - name: GAME_STREAM_FIREWALL_UNLOCK_TTL_SEC
              value: "28800"
            - name: GAME_STREAM_MOONLIGHT_HOST
              value: moonlight.bstein.dev
            - name: GAME_STREAM_USER_GROUP
              value: game-stream-users
            - name: GAME_STREAM_ADMIN_GROUP
              value: admin
            - name: GAME_STREAM_PROFILE_GROUP_PREFIX
              value: game-stream-profile-
            - name: COMMS_NAMESPACE
              value: comms
            - name: COMMS_SYNAPSE_BASE
              value: http://othrys-synapse-matrix-synapse.comms.svc.cluster.local:8008
            - name: COMMS_AUTH_BASE
              value: http://matrix-authentication-service.comms.svc.cluster.local:8080
            - name: COMMS_MAS_ADMIN_API_BASE
              value: http://matrix-authentication-service.comms.svc.cluster.local:8081/api/admin/v1
            - name: COMMS_MAS_TOKEN_URL
              value: http://matrix-authentication-service.comms.svc.cluster.local:8080/oauth2/token
            - name: COMMS_MAS_ADMIN_CLIENT_ID
              value: 01KDXMVQBQ5JNY6SEJPZW6Z8BM
            - name: COMMS_SERVER_NAME
              value: live.bstein.dev
            - name: COMMS_ROOM_ALIAS
              value: "#othrys:live.bstein.dev"
            - name: COMMS_ROOM_NAME
              value: Othrys
            - name: COMMS_PIN_MESSAGE
              value: "Invite guests: share https://live.bstein.dev/#/room/#othrys:live.bstein.dev?action=join and choose 'Continue' -> 'Join as guest'."
            - name: COMMS_SEEDER_USER
              value: othrys-seeder
            - name: COMMS_BOT_USER
              value: atlasbot
            - name: COMMS_SYNAPSE_DB_HOST
              value: postgres-service.postgres.svc.cluster.local
            - name: COMMS_SYNAPSE_DB_PORT
              value: "5432"
            - name: COMMS_SYNAPSE_DB_NAME
              value: synapse
            - name: COMMS_SYNAPSE_DB_USER
              value: synapse
            - name: COMMS_TIMEOUT_SEC
              value: "30"
            - name: COMMS_GUEST_STALE_DAYS
              value: "14"
            - name: VAULTWARDEN_NAMESPACE
              value: vaultwarden
            - name: VAULTWARDEN_POD_LABEL
              value: app=vaultwarden
            - name: VAULTWARDEN_POD_PORT
              value: "80"
            - name: VAULTWARDEN_SERVICE_HOST
              value: vaultwarden-service.vaultwarden.svc.cluster.local
            - name: VAULTWARDEN_ADMIN_SECRET_NAME
              value: vaultwarden-admin
            - name: VAULTWARDEN_ADMIN_SECRET_KEY
              value: ADMIN_TOKEN
            - name: VAULTWARDEN_ADMIN_SESSION_TTL_SEC
              value: "900"
            - name: VAULTWARDEN_ADMIN_RATE_LIMIT_BACKOFF_SEC
              value: "600"
            - name: VAULTWARDEN_RETRY_COOLDOWN_SEC
              value: "1800"
            - name: VAULTWARDEN_FAILURE_BAILOUT
              value: "2"
            - name: ARIADNE_PROVISION_POLL_INTERVAL_SEC
              value: "5"
            - name: ARIADNE_PROVISION_RETRY_COOLDOWN_SEC
              value: "30"
            - name: ARIADNE_SCHEDULE_TICK_SEC
              value: "5"
            - name: ARIADNE_SCHEDULE_MAILU_SYNC
              value: "30 4 * * *"
            - name: ARIADNE_SCHEDULE_NEXTCLOUD_SYNC
              value: "*/15 * * * *"
            - name: ARIADNE_SCHEDULE_NEXTCLOUD_CRON
              value: "*/5 * * * *"
            - name: ARIADNE_SCHEDULE_NEXTCLOUD_MAINTENANCE
              value: "30 4 * * *"
            - name: ARIADNE_SCHEDULE_VAULTWARDEN_SYNC
              value: "*/15 * * * *"
            - name: ARIADNE_SCHEDULE_WGER_USER_SYNC
              value: "*/15 * * * *"
            - name: ARIADNE_SCHEDULE_WGER_ADMIN
              value: "15 3 * * *"
            - name: ARIADNE_SCHEDULE_FIREFLY_USER_SYNC
              value: "*/15 * * * *"
            - name: ARIADNE_SCHEDULE_FIREFLY_CRON
              value: "0 3 * * *"
            - name: ARIADNE_SCHEDULE_POD_CLEANER
              value: "*/30 * * * *"
            - name: ARIADNE_SCHEDULE_OPENSEARCH_PRUNE
              value: "23 3 * * *"
            - name: ARIADNE_SCHEDULE_IMAGE_SWEEPER
              value: "0 */4 * * *"
            - name: ARIADNE_SCHEDULE_VAULT_K8S_AUTH
              value: "0 0 1 1 *"
            - name: ARIADNE_SCHEDULE_VAULT_OIDC
              value: "0 0 1 1 *"
            - name: ARIADNE_SCHEDULE_COMMS_GUEST_NAME
              value: "*/5 * * * *"
            - name: ARIADNE_SCHEDULE_COMMS_PIN_INVITE
              value: "0 0 1 * *"
            - name: ARIADNE_SCHEDULE_COMMS_RESET_ROOM
              value: "0 0 1 1 *"
            - name: ARIADNE_SCHEDULE_COMMS_SEED_ROOM
              value: "*/10 * * * *"
            - name: ARIADNE_SCHEDULE_CLUSTER_STATE
              value: "*/10 * * * *"
            - name: ARIADNE_CLUSTER_STATE_KEEP
              value: "720"
            - name: WELCOME_EMAIL_ENABLED
              value: "true"
            - name: K8S_API_TIMEOUT_SEC
              value: "5"
            - name: ARIADNE_VM_URL
              value: http://victoria-metrics-single-server.monitoring.svc.cluster.local:8428
            - name: ARIADNE_CLUSTER_STATE_VM_TIMEOUT_SEC
              value: "5"
            - name: ARIADNE_ALERTMANAGER_URL
              value: http://alertmanager.monitoring.svc.cluster.local
            - name: OPENSEARCH_URL
              value: http://opensearch-master.logging.svc.cluster.local:9200
            - name: OPENSEARCH_LIMIT_BYTES
              value: "1099511627776"
            - name: OPENSEARCH_INDEX_PATTERNS
              value: kube-*,journald-*,trace-analytics-*
            - name: METIS_BASE_URL
              value: http://metis.maintenance.svc.cluster.local
            - name: METIS_TIMEOUT_SEC
              value: "15"
            - name: ARIADNE_SCHEDULE_METIS_SENTINEL_WATCH
              value: "*/30 * * * *"
            - name: ARIADNE_SCHEDULE_JENKINS_BUILD_WEATHER
              value: "*/10 * * * *"
            - name: JENKINS_BASE_URL
              value: https://ci.bstein.dev
            - name: JENKINS_API_TIMEOUT_SEC
              value: "10"
            - name: ARIADNE_SCHEDULE_JENKINS_WORKSPACE_CLEANUP
              value: "45 */6 * * *"
            - name: ARIADNE_SCHEDULE_TESTING_TRIAGE
              value: "*/15 * * * *"
            - name: ARIADNE_TESTING_TRIAGE_MODEL_URL
              value: http://openclaw-ollama.openclaw.svc.cluster.local:11434
            - name: ARIADNE_TESTING_TRIAGE_MODEL
              value: qwen2.5:7b-instruct-q4_0
            - name: ARIADNE_TESTING_TRIAGE_MODEL_TIMEOUT_SEC
              value: "180"
            - name: JENKINS_WORKSPACE_NAMESPACE
              value: jenkins
            - name: JENKINS_WORKSPACE_PVC_PREFIX
              value: pvc-workspace-
            - name: JENKINS_WORKSPACE_CLEANUP_MIN_AGE_HOURS
              value: "24"
            - name: JENKINS_WORKSPACE_CLEANUP_DRY_RUN
              value: "false"
            - name: JENKINS_WORKSPACE_CLEANUP_MAX_DELETIONS_PER_RUN
              value: "20"
            - name: METRICS_PATH
              value: "/metrics"
          resources:
            requests:
              cpu: 100m
              memory: 128Mi
            limits:
              cpu: 500m
              memory: 512Mi
          livenessProbe:
            httpGet:
              path: /health
              port: http
            initialDelaySeconds: 10
            periodSeconds: 10
          readinessProbe:
            httpGet:
              path: /health
              port: http
            initialDelaySeconds: 5
            periodSeconds: 10
