# services/comms/helmrelease.yaml
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
  name: othrys-synapse
  namespace: comms
spec:
  interval: 30m
  chart:
    spec:
      chart: matrix-synapse
      version: 3.12.17
      sourceRef:
        kind: HelmRepository
        name: ananace
        namespace: flux-system
  install:
    remediation: { retries: 3 }
    timeout: 15m
  upgrade:
    remediation:
      retries: 3
      remediateLastFailure: true
    cleanupOnFail: true
    timeout: 15m
  values:
    serverName: live.bstein.dev
    publicServerName: matrix.live.bstein.dev

    config:
      publicBaseurl: https://matrix.live.bstein.dev
      registrationSharedSecret: "vault-managed"

    serviceAccount:
      create: false
      name: comms-vault

    externalPostgresql:
      host: postgres-service.postgres.svc.cluster.local
      port: 5432
      username: synapse
      existingSecret: vault-placeholder
      existingSecretPasswordKey: postgres-password
      database: synapse

    redis:
      enabled: true
      auth:
        enabled: true
        existingSecret: vault-placeholder
        existingSecretPasswordKey: redis-password

    postgresql:
      enabled: false

    persistence:
      enabled: true
      storageClass: asteria
      accessMode: ReadWriteOnce
      size: 50Gi

    synapse:
      strategy:
        type: RollingUpdate
        rollingUpdate:
          maxSurge: 0
          maxUnavailable: 1
      podSecurityContext:
        fsGroup: 666
        runAsUser: 666
        runAsGroup: 666
      resources:
        requests:
          cpu: 500m
          memory: 1Gi
        limits:
          cpu: "2"
          memory: 3Gi
      annotations:
        vault.hashicorp.com/agent-inject: "true"
        vault.hashicorp.com/role: "comms"
        vault.hashicorp.com/agent-inject-secret-synapse-env.sh: "kv/data/atlas/comms/synapse-db"
        vault.hashicorp.com/agent-inject-template-synapse-env.sh: |
          {{ with secret "kv/data/atlas/comms/synapse-db" }}
          export POSTGRES_PASSWORD="{{ .Data.data.POSTGRES_PASSWORD }}"
          {{ end }}
          {{ with secret "kv/data/atlas/comms/synapse-redis" }}
          export REDIS_PASSWORD="{{ index .Data.data "redis-password" }}"
          {{ end }}
          {{ with secret "kv/data/atlas/comms/turn-shared-secret" }}
          export TURN_SECRET="{{ .Data.data.TURN_STATIC_AUTH_SECRET }}"
          {{ end }}
          {{ with secret "kv/data/atlas/comms/mas-secrets-runtime" }}
          export MAS_SHARED_SECRET="{{ .Data.data.matrix_shared_secret }}"
          {{ end }}
          {{ with secret "kv/data/atlas/comms/synapse-registration" }}
          export REGISTRATION_SHARED_SECRET="{{ .Data.data.registration_shared_secret }}"
          {{ end }}
          {{ with secret "kv/data/atlas/comms/synapse-macaroon" }}
          export MACAROON_SECRET_KEY="{{ .Data.data.macaroon_secret_key }}"
          {{ end }}
        vault.hashicorp.com/agent-inject-secret-synapse-signingkey: "kv/data/atlas/comms/othrys-synapse-signingkey"
        vault.hashicorp.com/agent-inject-template-synapse-signingkey: |
          {{ with secret "kv/data/atlas/comms/othrys-synapse-signingkey" }}
          {{ index .Data.data "signing.key" }}
          {{ end }}
      extraEnv: []
      extraCommands:
        - >-
          esc() { printf "%s" "$1" | sed "s/'/''/g"; };
          printf '%s\n'
          "matrix_authentication_service:"
          "  enabled: true"
          "  endpoint: http://matrix-authentication-service:8080/"
          "  secret: '$(esc "${MAS_SHARED_SECRET:-}")'"
          "registration_shared_secret: '$(esc "${REGISTRATION_SHARED_SECRET:-}")'"
          "turn_shared_secret: '$(esc "${TURN_SECRET:-}")'"
          "macaroon_secret_key: '$(esc "${MACAROON_SECRET_KEY:-}")'"
          > /synapse/config/conf.d/runtime-secrets.yaml
      nodeSelector:
        hardware: rpi5
        node-role.kubernetes.io/worker: "true"
      affinity:
        nodeAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
            - weight: 50
              preference:
                matchExpressions:
                  - key: hardware
                    operator: In
                    values: ["rpi5", "rpi4"]

    ingress:
      enabled: false

    extraConfig:
      allow_guest_access: true
      allow_public_rooms_without_auth: true
      auto_join_rooms:
        - "#othrys:live.bstein.dev"
      autocreate_auto_join_rooms: true
      default_room_version: "11"
      experimental_features:
        msc4108_enabled: true
        msc3266_enabled: true
        msc4143_enabled: true
        msc4222_enabled: true
      max_event_delay_duration: 24h
      password_config:
        enabled: false
      rc_message:
        per_second: 0.5
        burst_count: 30
      rc_delayed_event_mgmt:
        per_second: 1
        burst_count: 20
      rc_login:
        address:
          burst_count: 20
          per_second: 5
        account:
          burst_count: 20
          per_second: 5
        failed_attempts:
          burst_count: 20
          per_second: 5
      room_list_publication_rules:
        - action: allow
      turn_uris:
        - "turn:turn.live.bstein.dev:3478?transport=udp"
        - "turn:turn.live.bstein.dev:3478?transport=tcp"
        - "turns:turn.live.bstein.dev:5349?transport=tcp"
      turn_allow_guests: true
      turn_user_lifetime: 86400000
      well_known_client:
        "m.homeserver":
          "base_url": "https://matrix.live.bstein.dev"
        "org.matrix.msc2965.authentication":
          "issuer": "https://matrix.live.bstein.dev/"
          "account": "https://matrix.live.bstein.dev/account/"
        "org.matrix.msc4143.rtc_foci":
          - type: "livekit"
            livekit_service_url: "https://kit.live.bstein.dev/livekit/jwt"

    worker:
      enabled: false

    signingkey:
      job:
        enabled: false
      existingSecret: vault-placeholder
      existingSecretKey: signing.key
  postRenderers:
    - kustomize:
        patches:
          - target:
              kind: Deployment
              name: othrys-synapse-matrix-synapse
            patch: |-
              apiVersion: apps/v1
              kind: Deployment
              metadata:
                name: othrys-synapse-matrix-synapse
              spec:
                template:
                  spec:
                    serviceAccountName: comms-vault
                    automountServiceAccountToken: true
                    hostAliases:
                      - ip: "10.43.150.98"
                        hostnames:
                          - "othrys-synapse-redis-master"
                          - "othrys-synapse-redis-master.comms.svc.cluster.local"
                      - ip: "10.43.36.27"
                        hostnames:
                          - "matrix-authentication-service"
                          - "matrix-authentication-service.comms.svc.cluster.local"
                    containers:
                      - name: synapse
                        command:
                          - /entrypoint.sh
                        args:
                          - sh
                          - -c
                          - |-
                              export POSTGRES_PASSWORD=$(echo "${POSTGRES_PASSWORD:-}" | sed 's/\//\\\//g' | sed 's/\&/\\\&/g')
                              export REDIS_PASSWORD=$(echo "${REDIS_PASSWORD:-}" | sed 's/\//\\\//g' | sed 's/\&/\\\&/g')
                              cat /synapse/secrets/*.yaml | \
                                sed -e "s/@@POSTGRES_PASSWORD@@/${POSTGRES_PASSWORD:-}/" \
                                    -e "s/@@REDIS_PASSWORD@@/${REDIS_PASSWORD:-}/" \
                                  > /synapse/config/conf.d/secrets.yaml

                              esc() { printf "%s" "$1" | sed "s/'/''/g"; };
                              printf '%s\n' \
                                "matrix_authentication_service:" \
                                "  enabled: true" \
                                "  endpoint: http://matrix-authentication-service:8080/" \
                                "  secret: '$(esc "${MAS_SHARED_SECRET:-}")'" \
                                "registration_shared_secret: '$(esc "${REGISTRATION_SHARED_SECRET:-}")'" \
                                "turn_shared_secret: '$(esc "${TURN_SECRET:-}")'" \
                                "macaroon_secret_key: '$(esc "${MACAROON_SECRET_KEY:-}")'" \
                                > /synapse/config/conf.d/runtime-secrets.yaml

                              exec python -B -m synapse.app.homeserver \
                                -c /synapse/config/homeserver.yaml \
                                -c /synapse/config/conf.d/
                        env:
                          - $patch: replace
                          - name: VAULT_ENV_FILE
                            value: /vault/secrets/synapse-env.sh
                          - name: VAULT_COPY_FILES
                            value: /vault/secrets/synapse-signingkey:/synapse/keys/signing.key
                        volumeMounts:
                          - $patch: replace
                          - name: comms-vault-entrypoint
                            mountPath: /entrypoint.sh
                            subPath: vault-entrypoint.sh
                          - name: config
                            mountPath: /synapse/config
                          - name: tmpconf
                            mountPath: /synapse/config/conf.d
                          - name: secrets
                            mountPath: /synapse/secrets
                          - name: signingkey-writable
                            mountPath: /synapse/keys
                          - name: media
                            mountPath: /synapse/data
                          - name: tmpdir
                            mountPath: /tmp
                    volumes:
                      - name: signingkey
                        $patch: delete
                      - name: comms-vault-entrypoint
                        configMap:
                          name: comms-vault-entrypoint
                          defaultMode: 493
                      - name: signingkey-writable
                        emptyDir: {}
          - target:
              kind: Deployment
              name: othrys-synapse-redis-master
            patch: |-
              apiVersion: apps/v1
              kind: Deployment
              metadata:
                name: othrys-synapse-redis-master
              spec:
                template:
                  metadata:
                    annotations:
                      vault.hashicorp.com/agent-inject: "true"
                      vault.hashicorp.com/role: "comms"
                      vault.hashicorp.com/agent-inject-secret-redis-env.sh: "kv/data/atlas/comms/synapse-redis"
                      vault.hashicorp.com/agent-inject-template-redis-env.sh: |
                        {{ with secret "kv/data/atlas/comms/synapse-redis" }}
                        export REDIS_PASSWORD="{{ index .Data.data "redis-password" }}"
                        {{ end }}
                  spec:
                    serviceAccountName: comms-vault
                    automountServiceAccountToken: true
                    containers:
                      - name: redis
                        command:
                          - /entrypoint.sh
                        args:
                          - /bin/bash
                          - -c
                          - /opt/bitnami/scripts/start-scripts/start-master.sh
                        env:
                          - name: REDIS_PASSWORD
                            $patch: delete
                          - name: VAULT_ENV_FILE
                            value: /vault/secrets/redis-env.sh
                        livenessProbe:
                          exec:
                            command:
                              - sh
                              - -c
                              - . /vault/secrets/redis-env.sh && /health/ping_liveness_local.sh 5
                        readinessProbe:
                          exec:
                            command:
                              - sh
                              - -c
                              - . /vault/secrets/redis-env.sh && /health/ping_readiness_local.sh 1
                        volumeMounts:
                          - name: comms-vault-entrypoint
                            mountPath: /entrypoint.sh
                            subPath: vault-entrypoint.sh
                    volumes:
                      - name: comms-vault-entrypoint
                        configMap:
                          name: comms-vault-entrypoint
                          defaultMode: 493
---
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
  name: othrys-element
  namespace: comms
spec:
  interval: 30m
  chart:
    spec:
      chart: element-web
      version: 1.4.26
      sourceRef:
        kind: HelmRepository
        name: ananace
        namespace: flux-system
  install:
    remediation: { retries: 3 }
    timeout: 10m
  upgrade:
    remediation:
      retries: 3
      remediateLastFailure: true
    cleanupOnFail: true
    timeout: 10m
  values:
    replicaCount: 1

    defaultServer:
      url: https://matrix.live.bstein.dev
      name: live.bstein.dev

    config:
      default_server_name: live.bstein.dev
      default_theme: dark
      brand: Othrys
      disable_custom_urls: true
      disable_login_language_selector: true
      disable_guests: false
      show_labs_settings: true
      features:
        feature_group_calls: true
        feature_video_rooms: true
        feature_element_call_video_rooms: true
      room_directory:
        servers:
          - live.bstein.dev
      jitsi: {}
      element_call:
        url: https://call.live.bstein.dev
        participant_limit: 16
        brand: Othrys Call
    extraVolumes:
      - name: element-host-config
        configMap:
          name: othrys-element-host-config
          defaultMode: 0555
    extraVolumeMounts:
      - name: element-host-config
        mountPath: /docker-entrypoint.d/20-host-config.sh
        subPath: 20-host-config.sh
        readOnly: true

    ingress:
      enabled: true
      className: traefik
      annotations:
        cert-manager.io/cluster-issuer: letsencrypt
        traefik.ingress.kubernetes.io/router.entrypoints: websecure
        traefik.ingress.kubernetes.io/router.tls: "true"
      hosts:
        - live.bstein.dev
      tls:
        - secretName: live-othrys-tls
          hosts: [live.bstein.dev]

    resources:
      requests:
        cpu: 100m
        memory: 256Mi
      limits:
        cpu: 500m
        memory: 512Mi

    nodeSelector:
      hardware: rpi5
      node-role.kubernetes.io/worker: "true"

    affinity:
      nodeAffinity:
        preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 50
            preference:
              matchExpressions:
                - key: hardware
                  operator: In
                  values: ["rpi5", "rpi4"]
