# services/keycloak/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: keycloak
  namespace: sso
  labels:
    app: keycloak
spec:
  replicas: 1
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 0
      maxUnavailable: 1
  selector:
    matchLabels:
      app: keycloak
  template:
    metadata:
      labels:
        app: keycloak
      annotations:
        vault.hashicorp.com/agent-inject: "true"
        vault.hashicorp.com/role: "sso"
        vault.hashicorp.com/agent-inject-secret-keycloak-env.sh: "kv/data/atlas/shared/keycloak-admin"
        vault.hashicorp.com/agent-inject-template-keycloak-env.sh: |
          {{ with secret "kv/data/atlas/shared/keycloak-admin" }}
          export KEYCLOAK_ADMIN="{{ .Data.data.username }}"
          export KEYCLOAK_ADMIN_USER="{{ .Data.data.username }}"
          export KEYCLOAK_ADMIN_PASSWORD="{{ .Data.data.password }}"
          {{ end }}
          {{ with secret "kv/data/atlas/sso/keycloak-db" }}
          export KC_DB_URL_DATABASE="{{ .Data.data.POSTGRES_DATABASE }}"
          export KC_DB_USERNAME="{{ .Data.data.POSTGRES_USER }}"
          export KC_DB_PASSWORD="{{ .Data.data.POSTGRES_PASSWORD }}"
          {{ end }}
          {{ with secret "kv/data/atlas/shared/portal-e2e-client" }}
          export PORTAL_E2E_CLIENT_ID="{{ .Data.data.client_id }}"
          export PORTAL_E2E_CLIENT_SECRET="{{ .Data.data.client_secret }}"
          {{ end }}
          {{ with secret "kv/data/atlas/sso/openldap-admin" }}
          export LDAP_ADMIN_PASSWORD="{{ .Data.data.LDAP_ADMIN_PASSWORD }}"
          export LDAP_CONFIG_PASSWORD="{{ .Data.data.LDAP_CONFIG_PASSWORD }}"
          export LDAP_BIND_PASSWORD="${LDAP_ADMIN_PASSWORD}"
          {{ end }}
          {{ with secret "kv/data/atlas/shared/postmark-relay" }}
          export KEYCLOAK_SMTP_USER="{{ index .Data.data "apikey" }}"
          export KEYCLOAK_SMTP_PASSWORD="{{ index .Data.data "apikey" }}"
          {{ end }}
    spec:
      serviceAccountName: sso-vault
      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: 70
              preference:
                matchExpressions:
                  - key: hardware
                    operator: In
                    values: ["rpi4"]
      securityContext:
        runAsUser: 1000
        runAsGroup: 0
        fsGroup: 1000
        fsGroupChangePolicy: OnRootMismatch
      initContainers:
        - name: mailu-http-listener
          image: registry.bstein.dev/sso/mailu-http-listener:0.1.0
          imagePullPolicy: IfNotPresent
          command: ["/bin/sh", "-c"]
          args:
            - |
              :
          volumeMounts:
            - name: providers
              mountPath: /providers
      containers:
        - name: keycloak
          image: quay.io/keycloak/keycloak:26.0.7
          imagePullPolicy: IfNotPresent
          command: ["/bin/sh", "-c"]
          args:
            - >-
              . /vault/secrets/keycloak-env.sh
              && exec /opt/keycloak/bin/kc.sh start
          env:
            - name: KC_DB
              value: postgres
            - name: KC_DB_URL_HOST
              value: postgres-service.postgres.svc.cluster.local
            - name: KC_DB_SCHEMA
              value: public
            - name: KC_HOSTNAME
              value: sso.bstein.dev
            - name: KC_HOSTNAME_URL
              value: https://sso.bstein.dev
            - name: KC_PROXY
              value: edge
            - name: KC_PROXY_HEADERS
              value: xforwarded
            - name: KC_HTTP_ENABLED
              value: "true"
            - name: KC_FEATURES
              value: token-exchange,admin-fine-grained-authz
            - name: KC_HTTP_MANAGEMENT_PORT
              value: "9000"
            - name: KC_HTTP_MANAGEMENT_BIND_ADDRESS
              value: 0.0.0.0
            - name: KC_LOG_LEVEL
              value: DEBUG
            - name: KC_HEALTH_ENABLED
              value: "true"
            - name: KC_METRICS_ENABLED
              value: "true"
            - name: KC_EVENTS_LISTENERS
              value: jboss-logging
            - name: KC_SPI_EVENTS_LISTENER_MAILU-HTTP_ENDPOINT
              value: http://ariadne.maintenance.svc.cluster.local/events
          ports:
            - containerPort: 8080
              name: http
            - containerPort: 9000
              name: metrics
          resources:
            requests:
              cpu: 100m
              memory: 512Mi
            limits:
              cpu: "1"
              memory: 2Gi
          readinessProbe:
            httpGet:
              path: /health/ready
              port: 9000
            initialDelaySeconds: 15
            periodSeconds: 10
            failureThreshold: 6
          livenessProbe:
            httpGet:
              path: /health/live
              port: 9000
            initialDelaySeconds: 600
            periodSeconds: 15
            failureThreshold: 6
          volumeMounts:
            - name: data
              mountPath: /opt/keycloak/data
            - name: providers
              mountPath: /opt/keycloak/providers
      volumes:
        - name: data
          persistentVolumeClaim:
            claimName: keycloak-data
        - name: providers
          emptyDir: {}
