version: 1
kind: postgres-host-cluster

metadata:
  id: pk01-platform-postgres
  description: PK01 host-native PostgreSQL 16 for UniDesk platform external state
  owner: unidesk
  relatedIssues:
    - 280
    - 281
    - 297
    - 300

cluster:
  role: primary
  environment: platform
  exposure: private-only
  haPhase: standalone-with-backup
  futureHaModes:
    - primary-standby
    - managed-rds

node:
  id: PK01
  route: PK01
  mode: host-systemd
  osFamily: ubuntu
  requiredHostFacts:
    minCpu: 2
    minMemoryGiB: 3.5
    minDiskFreeGiB: 20
    requireSwap: true
  swap:
    ensure: true
    size: 4G
    path: /swapfile

postgres:
  package:
    manager: apt
    version: "16"
    repo: pgdg-archive
    repoUrl: https://apt-archive.postgresql.org/pub/repos/apt
    suite: focal-pgdg
    component: main
    signingKeyUrl: https://www.postgresql.org/media/keys/ACCC4CF8.asc
    signedBy: /usr/share/keyrings/postgresql-pgdg.gpg
    sourceList: /etc/apt/sources.list.d/pgdg.list
  service:
    name: postgresql
    enabled: true
    state: running
  paths:
    dataDir: /var/lib/postgresql/16/main
    configDir: /etc/postgresql/16/main
    logDir: /var/log/postgresql
  network:
    port: 5432
    listenAddresses:
      - 127.0.0.1
      - 10.0.8.3
      - 0.0.0.0
    connectionHost: 82.156.23.220
    publicDns: db.pikapython.com
    transport: postgres-native-tls
    sslmode: require
    tls:
      enabled: true
      mode: self-signed-server-cert
      commonName: db.pikapython.com
      certFile: /etc/postgresql/16/main/server.crt
      keyFile: /etc/postgresql/16/main/server.key
      futureClientSslmode: verify-full
    firewall:
      mode: pg-hba-declared-sources
      defaultDeny: true
      allowSources:
        - id: pk01-local
          cidr: 127.0.0.1/32
          purpose: local-admin
        - id: pk01-vpc
          cidr: 10.0.8.0/22
          purpose: private-vpc-clients
        - id: master-server-public
          cidr: 74.48.78.17/32
          purpose: admin-and-secret-sync
        - id: D601-public
          cidr: 36.49.29.0/24
          purpose: platform-infra-standby-app
        - id: G14-public
          cidr: 202.98.17.68/32
          purpose: platform-infra-runtime
        - id: D518-public
          cidr: 202.98.13.68/32
          purpose: platform-infra-sub2api-active
        - id: JD01-public
          cidr: 117.72.122.178/32
          purpose: platform-infra-sub2api-active
        - id: NC01-public
          cidr: 152.53.229.148/32
          purpose: platform-infra-sub2api-active
  tuning:
    maxConnections: 160
    sharedBuffers: 512MB
    effectiveCacheSize: 2GB
    workMem: 8MB
    maintenanceWorkMem: 128MB
    walCompression: true
    checkpointCompletionTarget: 0.9
  auth:
    passwordEncryption: scram-sha-256
    pgHba:
      - type: local
        database: all
        user: postgres
        method: peer
      - type: host
        database: all
        user: all
        address: 127.0.0.1/32
        method: scram-sha-256
      - type: hostssl
        database: sub2api
        user: sub2api
        address: 10.0.8.0/22
        method: scram-sha-256
      - type: hostssl
        database: postgres
        user: sub2api
        address: 10.0.8.0/22
        method: scram-sha-256
      - type: hostssl
        database: sub2api
        user: sub2api
        address: 74.48.78.17/32
        method: scram-sha-256
      - type: hostssl
        database: postgres
        user: sub2api
        address: 74.48.78.17/32
        method: scram-sha-256
      - type: hostssl
        database: sub2api
        user: sub2api
        address: 36.49.29.0/24
        method: scram-sha-256
      - type: hostssl
        database: postgres
        user: sub2api
        address: 36.49.29.0/24
        method: scram-sha-256
      - type: hostssl
        database: sub2api
        user: sub2api
        address: 202.98.13.68/32
        method: scram-sha-256
      - type: hostssl
        database: postgres
        user: sub2api
        address: 202.98.13.68/32
        method: scram-sha-256
      - type: hostssl
        database: sub2api
        user: sub2api
        address: 117.72.122.178/32
        method: scram-sha-256
      - type: hostssl
        database: postgres
        user: sub2api
        address: 117.72.122.178/32
        method: scram-sha-256
      - type: hostssl
        database: sub2api
        user: sub2api
        address: 152.53.229.148/32
        method: scram-sha-256
      - type: hostssl
        database: postgres
        user: sub2api
        address: 152.53.229.148/32
        method: scram-sha-256
      - type: hostssl
        database: langbot
        user: langbot
        address: 10.0.8.0/22
        method: scram-sha-256
      - type: hostssl
        database: postgres
        user: langbot
        address: 10.0.8.0/22
        method: scram-sha-256
      - type: hostssl
        database: langbot
        user: langbot
        address: 74.48.78.17/32
        method: scram-sha-256
      - type: hostssl
        database: postgres
        user: langbot
        address: 74.48.78.17/32
        method: scram-sha-256
      - type: hostssl
        database: langbot
        user: langbot
        address: 202.98.17.68/32
        method: scram-sha-256
      - type: hostssl
        database: postgres
        user: langbot
        address: 202.98.17.68/32
        method: scram-sha-256
      - type: hostssl
        database: n8n
        user: n8n
        address: 10.0.8.0/22
        method: scram-sha-256
      - type: hostssl
        database: postgres
        user: n8n
        address: 10.0.8.0/22
        method: scram-sha-256
      - type: hostssl
        database: n8n
        user: n8n
        address: 74.48.78.17/32
        method: scram-sha-256
      - type: hostssl
        database: postgres
        user: n8n
        address: 74.48.78.17/32
        method: scram-sha-256
      - type: hostssl
        database: n8n
        user: n8n
        address: 202.98.17.68/32
        method: scram-sha-256
      - type: hostssl
        database: postgres
        user: n8n
        address: 202.98.17.68/32
        method: scram-sha-256
      - type: hostssl
        database: agentrun_v02
        user: agentrun_v02
        address: 10.0.8.0/22
        method: scram-sha-256
      - type: hostssl
        database: postgres
        user: agentrun_v02
        address: 10.0.8.0/22
        method: scram-sha-256
      - type: hostssl
        database: agentrun_v02
        user: agentrun_v02
        address: 36.49.29.0/24
        method: scram-sha-256
      - type: hostssl
        database: postgres
        user: agentrun_v02
        address: 36.49.29.0/24
        method: scram-sha-256
      - type: hostssl
        database: agentrun_v02
        user: agentrun_v02
        address: 74.48.78.17/32
        method: scram-sha-256
      - type: hostssl
        database: postgres
        user: agentrun_v02
        address: 74.48.78.17/32
        method: scram-sha-256
      - type: hostssl
        database: agentrun_d518_v02
        user: agentrun_d518_v02
        address: 10.0.8.0/22
        method: scram-sha-256
      - type: hostssl
        database: postgres
        user: agentrun_d518_v02
        address: 10.0.8.0/22
        method: scram-sha-256
      - type: hostssl
        database: agentrun_d518_v02
        user: agentrun_d518_v02
        address: 202.98.13.68/32
        method: scram-sha-256
      - type: hostssl
        database: postgres
        user: agentrun_d518_v02
        address: 202.98.13.68/32
        method: scram-sha-256
      - type: hostssl
        database: agentrun_d518_v02
        user: agentrun_d518_v02
        address: 74.48.78.17/32
        method: scram-sha-256
      - type: hostssl
        database: postgres
        user: agentrun_d518_v02
        address: 74.48.78.17/32
        method: scram-sha-256
      - type: hostssl
        database: hwlab_d601_v03
        user: hwlab_d601_v03_app
        address: 10.0.8.0/22
        method: scram-sha-256
      - type: hostssl
        database: postgres
        user: hwlab_d601_v03_app
        address: 10.0.8.0/22
        method: scram-sha-256
      - type: hostssl
        database: hwlab_d601_v03
        user: hwlab_d601_v03_app
        address: 36.49.29.0/24
        method: scram-sha-256
      - type: hostssl
        database: postgres
        user: hwlab_d601_v03_app
        address: 36.49.29.0/24
        method: scram-sha-256
      - type: hostssl
        database: hwlab_d601_v03
        user: hwlab_d601_v03_app
        address: 74.48.78.17/32
        method: scram-sha-256
      - type: hostssl
        database: postgres
        user: hwlab_d601_v03_app
        address: 74.48.78.17/32
        method: scram-sha-256
      - type: hostssl
        database: hwlab_jd01_v03
        user: hwlab_jd01_v03_app
        address: 10.0.8.0/22
        method: scram-sha-256
      - type: hostssl
        database: postgres
        user: hwlab_jd01_v03_app
        address: 10.0.8.0/22
        method: scram-sha-256
      - type: hostssl
        database: hwlab_jd01_v03
        user: hwlab_jd01_v03_app
        address: 117.72.122.178/32
        method: scram-sha-256
      - type: hostssl
        database: postgres
        user: hwlab_jd01_v03_app
        address: 117.72.122.178/32
        method: scram-sha-256
      - type: hostssl
        database: hwlab_jd01_v03
        user: hwlab_jd01_v03_app
        address: 74.48.78.17/32
        method: scram-sha-256
      - type: hostssl
        database: postgres
        user: hwlab_jd01_v03_app
        address: 74.48.78.17/32
        method: scram-sha-256

secrets:
  source: master-local
  root: /root/.unidesk/.state/secrets
  entries:
    - name: sub2api-db-credentials
      sourceRef: platform-db/sub2api-db.env
      type: env
      requiredKeys:
        - SUB2API_DB_USER
        - SUB2API_DB_PASSWORD
        - SUB2API_DB_NAME
      createIfMissing:
        enabled: true
        values:
          SUB2API_DB_USER: sub2api
          SUB2API_DB_NAME: sub2api
        randomHex:
          SUB2API_DB_PASSWORD: 32
    - name: langbot-db-credentials
      sourceRef: platform-db/langbot-db.env
      type: env
      requiredKeys:
        - LANGBOT_DB_USER
        - LANGBOT_DB_PASSWORD
        - LANGBOT_DB_NAME
      createIfMissing:
        enabled: true
        values:
          LANGBOT_DB_USER: langbot
          LANGBOT_DB_NAME: langbot
        randomHex:
          LANGBOT_DB_PASSWORD: 32
    - name: n8n-db-credentials
      sourceRef: platform-db/n8n-db.env
      type: env
      requiredKeys:
        - N8N_DB_USER
        - N8N_DB_PASSWORD
        - N8N_DB_NAME
      createIfMissing:
        enabled: true
        values:
          N8N_DB_USER: n8n
          N8N_DB_NAME: n8n
        randomHex:
          N8N_DB_PASSWORD: 32
    - name: agentrun-v02-db-credentials
      sourceRef: platform-db/agentrun-v02-db.env
      type: env
      requiredKeys:
        - AGENTRUN_V02_DB_USER
        - AGENTRUN_V02_DB_PASSWORD
        - AGENTRUN_V02_DB_NAME
      createIfMissing:
        enabled: true
        values:
          AGENTRUN_V02_DB_USER: agentrun_v02
          AGENTRUN_V02_DB_NAME: agentrun_v02
        randomHex:
          AGENTRUN_V02_DB_PASSWORD: 32
    - name: agentrun-d518-v02-db-credentials
      sourceRef: platform-db/agentrun-d518-v02-db.env
      type: env
      requiredKeys:
        - AGENTRUN_D518_V02_DB_USER
        - AGENTRUN_D518_V02_DB_PASSWORD
        - AGENTRUN_D518_V02_DB_NAME
      createIfMissing:
        enabled: true
        values:
          AGENTRUN_D518_V02_DB_USER: agentrun_d518_v02
          AGENTRUN_D518_V02_DB_NAME: agentrun_d518_v02
        randomHex:
          AGENTRUN_D518_V02_DB_PASSWORD: 32
    - name: hwlab-d601-v03-db-credentials
      sourceRef: platform-db/hwlab-d601-v03-db.env
      type: env
      requiredKeys:
        - HWLAB_D601_V03_DB_USER
        - HWLAB_D601_V03_DB_PASSWORD
        - HWLAB_D601_V03_DB_NAME
      createIfMissing:
        enabled: true
        values:
          HWLAB_D601_V03_DB_USER: hwlab_d601_v03_app
          HWLAB_D601_V03_DB_NAME: hwlab_d601_v03
        randomHex:
          HWLAB_D601_V03_DB_PASSWORD: 32
    - name: hwlab-jd01-v03-db-credentials
      sourceRef: platform-db/hwlab-jd01-v03-db.env
      type: env
      requiredKeys:
        - HWLAB_JD01_V03_DB_USER
        - HWLAB_JD01_V03_DB_PASSWORD
        - HWLAB_JD01_V03_DB_NAME
      createIfMissing:
        enabled: true
        values:
          HWLAB_JD01_V03_DB_USER: hwlab_jd01_v03_app
          HWLAB_JD01_V03_DB_NAME: hwlab_jd01_v03
        randomHex:
          HWLAB_JD01_V03_DB_PASSWORD: 32
objects:
  roles:
    - name: sub2api
      passwordRef:
        sourceRef: platform-db/sub2api-db.env
        key: SUB2API_DB_PASSWORD
      login: true
      attributes:
        createdb: false
        createrole: false
        superuser: false
    - name: langbot
      passwordRef:
        sourceRef: platform-db/langbot-db.env
        key: LANGBOT_DB_PASSWORD
      login: true
      attributes:
        createdb: false
        createrole: false
        superuser: false
    - name: n8n
      passwordRef:
        sourceRef: platform-db/n8n-db.env
        key: N8N_DB_PASSWORD
      login: true
      attributes:
        createdb: false
        createrole: false
        superuser: false
    - name: agentrun_v02
      passwordRef:
        sourceRef: platform-db/agentrun-v02-db.env
        key: AGENTRUN_V02_DB_PASSWORD
      login: true
      attributes:
        createdb: false
        createrole: false
        superuser: false
    - name: agentrun_d518_v02
      passwordRef:
        sourceRef: platform-db/agentrun-d518-v02-db.env
        key: AGENTRUN_D518_V02_DB_PASSWORD
      login: true
      attributes:
        createdb: false
        createrole: false
        superuser: false
    - name: hwlab_d601_v03_app
      passwordRef:
        sourceRef: platform-db/hwlab-d601-v03-db.env
        key: HWLAB_D601_V03_DB_PASSWORD
      login: true
      attributes:
        createdb: false
        createrole: false
        superuser: false
    - name: hwlab_jd01_v03_app
      passwordRef:
        sourceRef: platform-db/hwlab-jd01-v03-db.env
        key: HWLAB_JD01_V03_DB_PASSWORD
      login: true
      attributes:
        createdb: false
        createrole: false
        superuser: false
  databases:
    - name: sub2api
      owner: sub2api
      encoding: UTF8
      locale: C.UTF-8
      extensions: []
    - name: langbot
      owner: langbot
      encoding: UTF8
      locale: C.UTF-8
      extensions: []
    - name: n8n
      owner: n8n
      encoding: UTF8
      locale: C.UTF-8
      extensions: []
    - name: agentrun_v02
      owner: agentrun_v02
      encoding: UTF8
      locale: C.UTF-8
      extensions: []
    - name: agentrun_d518_v02
      owner: agentrun_d518_v02
      encoding: UTF8
      locale: C.UTF-8
      extensions: []
    - name: hwlab_d601_v03
      owner: hwlab_d601_v03_app
      encoding: UTF8
      locale: C.UTF-8
      extensions: []
    - name: hwlab_jd01_v03
      owner: hwlab_jd01_v03_app
      encoding: UTF8
      locale: C.UTF-8
      extensions: []

exports:
  connectionStrings:
    - name: sub2api-database-url
      sourceSecretRef: platform-db/sub2api-db.env
      render:
        envKey: DATABASE_URL
        format: postgresql://$(SUB2API_DB_USER):$(SUB2API_DB_PASSWORD)@$(PGHOST):5432/$(SUB2API_DB_NAME)?sslmode=require
        variables:
          PGHOST: 82.156.23.220
      writeToSecretSource:
        sourceRef: platform-infra/sub2api.env
        key: DATABASE_URL
        mode: update-or-insert
      consumers:
        - scope: platform-infra
          secret: sub2api-secrets
          key: DATABASE_URL
    - name: langbot-database-url
      sourceSecretRef: platform-db/langbot-db.env
      render:
        envKey: DATABASE_URL
        format: postgresql://$(LANGBOT_DB_USER):$(LANGBOT_DB_PASSWORD)@$(PGHOST):5432/$(LANGBOT_DB_NAME)?sslmode=require
        variables:
          PGHOST: 82.156.23.220
      writeToSecretSource:
        sourceRef: platform-infra/langbot.env
        key: DATABASE_URL
        mode: update-or-insert
      consumers:
        - scope: platform-infra
          secret: langbot-secrets
          key: DATABASE_URL
    - name: n8n-database-url
      sourceSecretRef: platform-db/n8n-db.env
      render:
        envKey: DATABASE_URL
        format: postgresql://$(N8N_DB_USER):$(N8N_DB_PASSWORD)@$(PGHOST):5432/$(N8N_DB_NAME)?sslmode=require
        variables:
          PGHOST: 82.156.23.220
      writeToSecretSource:
        sourceRef: platform-infra/n8n.env
        key: DATABASE_URL
        mode: update-or-insert
      consumers:
        - scope: platform-infra
          secret: n8n-secrets
          key: DATABASE_URL
    - name: agentrun-v02-database-url
      sourceSecretRef: platform-db/agentrun-v02-db.env
      render:
        envKey: DATABASE_URL
        format: postgresql://$(AGENTRUN_V02_DB_USER):$(AGENTRUN_V02_DB_PASSWORD)@$(PGHOST):5432/$(AGENTRUN_V02_DB_NAME)?sslmode=require&uselibpqcompat=true
        variables:
          PGHOST: 82.156.23.220
      writeToSecretSource:
        sourceRef: agentrun/d601-v02-mgr-db.env
        key: DATABASE_URL
        mode: update-or-insert
      consumers:
        - scope: agentrun-v02
          secret: agentrun-v02-mgr-db
          key: DATABASE_URL
    - name: agentrun-d518-v02-database-url
      sourceSecretRef: platform-db/agentrun-d518-v02-db.env
      render:
        envKey: DATABASE_URL
        format: postgresql://$(AGENTRUN_D518_V02_DB_USER):$(AGENTRUN_D518_V02_DB_PASSWORD)@$(PGHOST):5432/$(AGENTRUN_D518_V02_DB_NAME)?sslmode=require&uselibpqcompat=true
        variables:
          PGHOST: 82.156.23.220
      writeToSecretSource:
        sourceRef: agentrun/d518-v02-mgr-db.env
        key: DATABASE_URL
        mode: update-or-insert
      consumers:
        - scope: agentrun-v02
          secret: agentrun-v02-mgr-db
          key: DATABASE_URL
    - name: hwlab-d601-v03-cloud-api-database-url
      sourceSecretRef: platform-db/hwlab-d601-v03-db.env
      render:
        envKey: DATABASE_URL
        format: postgresql://$(HWLAB_D601_V03_DB_USER):$(HWLAB_D601_V03_DB_PASSWORD)@$(PGHOST):$(PGPORT)/$(HWLAB_D601_V03_DB_NAME)?sslmode=require
        variables:
          PGHOST: d601-tcp-egress-gateway.unidesk.svc.cluster.local
          PGPORT: "25432"
      writeToSecretSource:
        sourceRef: hwlab/d601-v03-cloud-api-db.env
        key: DATABASE_URL
        mode: update-or-insert
      consumers:
        - scope: hwlab-d601-v03
          secret: hwlab-cloud-api-v03-db
          key: DATABASE_URL
    - name: hwlab-d601-v03-openfga-datastore-uri
      sourceSecretRef: platform-db/hwlab-d601-v03-db.env
      render:
        envKey: DATASTORE_URI
        format: postgres://$(HWLAB_D601_V03_DB_USER):$(HWLAB_D601_V03_DB_PASSWORD)@$(PGHOST):$(PGPORT)/$(HWLAB_D601_V03_DB_NAME)?sslmode=require
        variables:
          PGHOST: d601-tcp-egress-gateway.unidesk.svc.cluster.local
          PGPORT: "25432"
      writeToSecretSource:
        sourceRef: hwlab/d601-v03-openfga-db.env
        key: DATASTORE_URI
        mode: update-or-insert
      consumers:
        - scope: hwlab-d601-v03
          secret: hwlab-v03-openfga
          key: DATASTORE_URI
    - name: hwlab-jd01-v03-cloud-api-database-url
      sourceSecretRef: platform-db/hwlab-jd01-v03-db.env
      render:
        envKey: DATABASE_URL
        format: postgresql://$(HWLAB_JD01_V03_DB_USER):$(HWLAB_JD01_V03_DB_PASSWORD)@$(PGHOST):$(PGPORT)/$(HWLAB_JD01_V03_DB_NAME)?sslmode=require
        variables:
          PGHOST: 82.156.23.220
          PGPORT: "5432"
      writeToSecretSource:
        sourceRef: hwlab/jd01-v03-cloud-api-db.env
        key: DATABASE_URL
        mode: update-or-insert
      consumers:
        - scope: hwlab-jd01-v03
          secret: hwlab-cloud-api-v03-db
          key: DATABASE_URL
    - name: hwlab-jd01-v03-openfga-datastore-uri
      sourceSecretRef: platform-db/hwlab-jd01-v03-db.env
      render:
        envKey: DATASTORE_URI
        format: postgres://$(HWLAB_JD01_V03_DB_USER):$(HWLAB_JD01_V03_DB_PASSWORD)@$(PGHOST):$(PGPORT)/$(HWLAB_JD01_V03_DB_NAME)?sslmode=require
        variables:
          PGHOST: 82.156.23.220
          PGPORT: "5432"
      writeToSecretSource:
        sourceRef: hwlab/jd01-v03-openfga-db.env
        key: DATASTORE_URI
        mode: update-or-insert
      consumers:
        - scope: hwlab-jd01-v03
          secret: hwlab-v03-openfga
          key: DATASTORE_URI

backup:
  phase: minimum-restoreable
  logicalDump:
    enabled: true
    schedule: "17 3 * * *"
    database: sub2api
    retentionDays: 14
    destination:
      type: pk01-local
      path: /var/backups/unidesk/platform-db/pk01/sub2api
    encryption:
      enabled: false
      futureKeyRef: platform-db/backup-age-recipient.txt
  physicalWalArchive:
    enabled: false
    futureTool: pgbackrest

observability:
  statusChecks:
    - kind: systemd-active
      service: postgresql
    - kind: port-listen
      host: 127.0.0.1
      port: 5432
    - kind: psql-local
      database: postgres
    - kind: psql-app-role
      database: sub2api
      user: sub2api
    - kind: psql-app-role
      database: langbot
      user: langbot
    - kind: psql-app-role
      database: n8n
      user: n8n
    - kind: psql-app-role
      database: agentrun_v02
      user: agentrun_v02
    - kind: psql-app-role
      database: agentrun_d518_v02
      user: agentrun_d518_v02
    - kind: psql-app-role
      database: hwlab_d601_v03
      user: hwlab_d601_v03_app
    - kind: disk-free
      path: /var/lib/postgresql/16/main
      minFreeGiB: 10
  redaction:
    neverPrintValues: true
    showFingerprint: true
    showKeyNames: true
