comms: consolidate stack manifests

This commit is contained in:
Brad Stein 2026-01-08 01:55:58 -03:00
parent d3ac4726e2
commit 660b49bc5d
53 changed files with 5332 additions and 646 deletions

View File

@ -5,7 +5,7 @@ resources:
- ../../services/crypto
- ../../services/gitea
- ../../services/jellyfin
- ../../services/communication
- ../../services/comms
- ../../services/monitoring
- ../../services/pegasus
- ../../services/vault

View File

@ -1,15 +0,0 @@
# clusters/atlas/flux-system/applications/comms/kustomization.yaml
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: comms
namespace: flux-system
spec:
interval: 10m
prune: true
sourceRef:
kind: GitRepository
name: flux-system
path: ./services/comms
targetNamespace: comms
timeout: 2m

View File

@ -10,7 +10,7 @@ spec:
sourceRef:
kind: GitRepository
name: flux-system
path: ./services/communication
path: ./services/comms
targetNamespace: comms
timeout: 2m
dependsOn:

View File

@ -5,7 +5,6 @@ resources:
- gitea/kustomization.yaml
- vault/kustomization.yaml
- vaultwarden/kustomization.yaml
- comms/kustomization.yaml
- communication/kustomization.yaml
- crypto/kustomization.yaml
- monerod/kustomization.yaml

View File

@ -1,8 +1,8 @@
{
"counts": {
"helmrelease_host_hints": 7,
"http_endpoints": 32,
"services": 42,
"workloads": 47
"http_endpoints": 35,
"services": 44,
"workloads": 49
}
}

View File

@ -16,14 +16,9 @@
"path": "services/ci-demo",
"targetNamespace": null
},
{
"name": "comms",
"path": "services/comms",
"targetNamespace": "comms"
},
{
"name": "communication",
"path": "services/communication",
"path": "services/comms",
"targetNamespace": "comms"
},
{
@ -324,6 +319,19 @@
"ghcr.io/element-hq/matrix-authentication-service:1.8.0"
]
},
{
"kind": "Deployment",
"namespace": "comms",
"name": "matrix-guest-register",
"labels": {
"app.kubernetes.io/name": "matrix-guest-register"
},
"serviceAccountName": null,
"nodeSelector": {},
"images": [
"python:3.11-slim"
]
},
{
"kind": "Deployment",
"namespace": "comms",
@ -777,6 +785,21 @@
"python:3.12-alpine"
]
},
{
"kind": "Deployment",
"namespace": "nextcloud",
"name": "collabora",
"labels": {
"app": "collabora"
},
"serviceAccountName": null,
"nodeSelector": {
"hardware": "rpi5"
},
"images": [
"collabora/code:latest"
]
},
{
"kind": "Deployment",
"namespace": "nextcloud",
@ -1399,6 +1422,22 @@
}
]
},
{
"namespace": "comms",
"name": "matrix-guest-register",
"type": "ClusterIP",
"selector": {
"app.kubernetes.io/name": "matrix-guest-register"
},
"ports": [
{
"name": "http",
"port": 8080,
"targetPort": "http",
"protocol": "TCP"
}
]
},
{
"namespace": "comms",
"name": "matrix-wellknown",
@ -1834,6 +1873,22 @@
}
]
},
{
"namespace": "nextcloud",
"name": "collabora",
"type": "ClusterIP",
"selector": {
"app": "collabora"
},
"ports": [
{
"name": "http",
"port": 9980,
"targetPort": "http",
"protocol": "TCP"
}
]
},
{
"namespace": "nextcloud",
"name": "nextcloud",
@ -2040,21 +2095,41 @@
},
{
"host": "bstein.dev",
"path": "/.well-known/matrix",
"path": "/.well-known/matrix/client",
"backend": {
"namespace": "comms",
"service": "othrys-synapse-matrix-synapse",
"port": 8008,
"service": "matrix-wellknown",
"port": 80,
"workloads": [
{
"kind": "Deployment",
"name": "othrys-synapse-matrix-synapse"
"name": "matrix-wellknown"
}
]
},
"via": {
"kind": "Ingress",
"name": "othrys-synapse-matrix-synapse",
"name": "matrix-wellknown-bstein-dev",
"source": "communication"
}
},
{
"host": "bstein.dev",
"path": "/.well-known/matrix/server",
"backend": {
"namespace": "comms",
"service": "matrix-wellknown",
"port": 80,
"workloads": [
{
"kind": "Deployment",
"name": "matrix-wellknown"
}
]
},
"via": {
"kind": "Ingress",
"name": "matrix-wellknown-bstein-dev",
"source": "communication"
}
},
@ -2218,26 +2293,6 @@
"source": "communication"
}
},
{
"host": "live.bstein.dev",
"path": "/.well-known/matrix",
"backend": {
"namespace": "comms",
"service": "othrys-synapse-matrix-synapse",
"port": 8008,
"workloads": [
{
"kind": "Deployment",
"name": "othrys-synapse-matrix-synapse"
}
]
},
"via": {
"kind": "Ingress",
"name": "othrys-synapse-matrix-synapse",
"source": "communication"
}
},
{
"host": "live.bstein.dev",
"path": "/.well-known/matrix/client",
@ -2294,7 +2349,7 @@
},
"via": {
"kind": "Ingress",
"name": "othrys-synapse-matrix-synapse",
"name": "matrix-routing",
"source": "communication"
}
},
@ -2349,7 +2404,7 @@
},
"via": {
"kind": "Ingress",
"name": "matrix-authentication-service",
"name": "matrix-routing",
"source": "communication"
}
},
@ -2409,7 +2464,27 @@
},
"via": {
"kind": "Ingress",
"name": "othrys-synapse-matrix-synapse",
"name": "matrix-routing",
"source": "communication"
}
},
{
"host": "matrix.live.bstein.dev",
"path": "/_matrix/client/r0/register",
"backend": {
"namespace": "comms",
"service": "matrix-guest-register",
"port": 8080,
"workloads": [
{
"kind": "Deployment",
"name": "matrix-guest-register"
}
]
},
"via": {
"kind": "Ingress",
"name": "matrix-routing",
"source": "communication"
}
},
@ -2429,7 +2504,7 @@
},
"via": {
"kind": "Ingress",
"name": "matrix-authentication-service-compat",
"name": "matrix-routing",
"source": "communication"
}
},
@ -2449,7 +2524,7 @@
},
"via": {
"kind": "Ingress",
"name": "matrix-authentication-service-compat",
"name": "matrix-routing",
"source": "communication"
}
},
@ -2469,7 +2544,27 @@
},
"via": {
"kind": "Ingress",
"name": "matrix-authentication-service-compat",
"name": "matrix-routing",
"source": "communication"
}
},
{
"host": "matrix.live.bstein.dev",
"path": "/_matrix/client/v3/register",
"backend": {
"namespace": "comms",
"service": "matrix-guest-register",
"port": 8080,
"workloads": [
{
"kind": "Deployment",
"name": "matrix-guest-register"
}
]
},
"via": {
"kind": "Ingress",
"name": "matrix-routing",
"source": "communication"
}
},
@ -2489,7 +2584,7 @@
},
"via": {
"kind": "Ingress",
"name": "othrys-synapse-matrix-synapse",
"name": "matrix-routing",
"source": "communication"
}
},
@ -2513,6 +2608,26 @@
"source": "monerod"
}
},
{
"host": "office.bstein.dev",
"path": "/",
"backend": {
"namespace": "nextcloud",
"service": "collabora",
"port": 9980,
"workloads": [
{
"kind": "Deployment",
"name": "collabora"
}
]
},
"via": {
"kind": "Ingress",
"name": "collabora",
"source": "nextcloud"
}
},
{
"host": "pegasus.bstein.dev",
"path": "/",

View File

@ -10,11 +10,8 @@ sources:
- name: ci-demo
path: services/ci-demo
targetNamespace: null
- name: comms
path: services/comms
targetNamespace: comms
- name: communication
path: services/communication
path: services/comms
targetNamespace: comms
- name: core
path: infrastructure/core
@ -207,6 +204,15 @@ workloads:
hardware: rpi5
images:
- ghcr.io/element-hq/matrix-authentication-service:1.8.0
- kind: Deployment
namespace: comms
name: matrix-guest-register
labels:
app.kubernetes.io/name: matrix-guest-register
serviceAccountName: null
nodeSelector: {}
images:
- python:3.11-slim
- kind: Deployment
namespace: comms
name: matrix-wellknown
@ -526,6 +532,16 @@ workloads:
nodeSelector: {}
images:
- python:3.12-alpine
- kind: Deployment
namespace: nextcloud
name: collabora
labels:
app: collabora
serviceAccountName: null
nodeSelector:
hardware: rpi5
images:
- collabora/code:latest
- kind: Deployment
namespace: nextcloud
name: nextcloud
@ -935,6 +951,16 @@ services:
port: 8081
targetPort: internal
protocol: TCP
- namespace: comms
name: matrix-guest-register
type: ClusterIP
selector:
app.kubernetes.io/name: matrix-guest-register
ports:
- name: http
port: 8080
targetPort: http
protocol: TCP
- namespace: comms
name: matrix-wellknown
type: ClusterIP
@ -1214,6 +1240,16 @@ services:
port: 8000
targetPort: http
protocol: TCP
- namespace: nextcloud
name: collabora
type: ClusterIP
selector:
app: collabora
ports:
- name: http
port: 9980
targetPort: http
protocol: TCP
- namespace: nextcloud
name: nextcloud
type: ClusterIP
@ -1344,17 +1380,28 @@ http_endpoints:
name: bstein-dev-home
source: bstein-dev-home
- host: bstein.dev
path: /.well-known/matrix
path: /.well-known/matrix/client
backend:
namespace: comms
service: othrys-synapse-matrix-synapse
port: 8008
service: matrix-wellknown
port: 80
workloads: &id001
- kind: Deployment
name: othrys-synapse-matrix-synapse
name: matrix-wellknown
via:
kind: Ingress
name: othrys-synapse-matrix-synapse
name: matrix-wellknown-bstein-dev
source: communication
- host: bstein.dev
path: /.well-known/matrix/server
backend:
namespace: comms
service: matrix-wellknown
port: 80
workloads: *id001
via:
kind: Ingress
name: matrix-wellknown-bstein-dev
source: communication
- host: bstein.dev
path: /api
@ -1460,26 +1507,13 @@ http_endpoints:
kind: Ingress
name: othrys-element-element-web
source: communication
- host: live.bstein.dev
path: /.well-known/matrix
backend:
namespace: comms
service: othrys-synapse-matrix-synapse
port: 8008
workloads: *id001
via:
kind: Ingress
name: othrys-synapse-matrix-synapse
source: communication
- host: live.bstein.dev
path: /.well-known/matrix/client
backend:
namespace: comms
service: matrix-wellknown
port: 80
workloads: &id002
- kind: Deployment
name: matrix-wellknown
workloads: *id001
via:
kind: Ingress
name: matrix-wellknown
@ -1490,7 +1524,7 @@ http_endpoints:
namespace: comms
service: matrix-wellknown
port: 80
workloads: *id002
workloads: *id001
via:
kind: Ingress
name: matrix-wellknown
@ -1501,10 +1535,12 @@ http_endpoints:
namespace: comms
service: othrys-synapse-matrix-synapse
port: 8008
workloads: *id001
workloads: &id002
- kind: Deployment
name: othrys-synapse-matrix-synapse
via:
kind: Ingress
name: othrys-synapse-matrix-synapse
name: matrix-routing
source: communication
- host: longhorn.bstein.dev
path: /
@ -1541,7 +1577,7 @@ http_endpoints:
name: matrix-authentication-service
via:
kind: Ingress
name: matrix-authentication-service
name: matrix-routing
source: communication
- host: matrix.live.bstein.dev
path: /.well-known/matrix/client
@ -1549,7 +1585,7 @@ http_endpoints:
namespace: comms
service: matrix-wellknown
port: 80
workloads: *id002
workloads: *id001
via:
kind: Ingress
name: matrix-wellknown-matrix-live
@ -1560,7 +1596,7 @@ http_endpoints:
namespace: comms
service: matrix-wellknown
port: 80
workloads: *id002
workloads: *id001
via:
kind: Ingress
name: matrix-wellknown-matrix-live
@ -1571,10 +1607,23 @@ http_endpoints:
namespace: comms
service: othrys-synapse-matrix-synapse
port: 8008
workloads: *id001
workloads: *id002
via:
kind: Ingress
name: othrys-synapse-matrix-synapse
name: matrix-routing
source: communication
- host: matrix.live.bstein.dev
path: /_matrix/client/r0/register
backend:
namespace: comms
service: matrix-guest-register
port: 8080
workloads: &id004
- kind: Deployment
name: matrix-guest-register
via:
kind: Ingress
name: matrix-routing
source: communication
- host: matrix.live.bstein.dev
path: /_matrix/client/v3/login
@ -1585,7 +1634,7 @@ http_endpoints:
workloads: *id003
via:
kind: Ingress
name: matrix-authentication-service-compat
name: matrix-routing
source: communication
- host: matrix.live.bstein.dev
path: /_matrix/client/v3/logout
@ -1596,7 +1645,7 @@ http_endpoints:
workloads: *id003
via:
kind: Ingress
name: matrix-authentication-service-compat
name: matrix-routing
source: communication
- host: matrix.live.bstein.dev
path: /_matrix/client/v3/refresh
@ -1607,7 +1656,18 @@ http_endpoints:
workloads: *id003
via:
kind: Ingress
name: matrix-authentication-service-compat
name: matrix-routing
source: communication
- host: matrix.live.bstein.dev
path: /_matrix/client/v3/register
backend:
namespace: comms
service: matrix-guest-register
port: 8080
workloads: *id004
via:
kind: Ingress
name: matrix-routing
source: communication
- host: matrix.live.bstein.dev
path: /_synapse
@ -1615,10 +1675,10 @@ http_endpoints:
namespace: comms
service: othrys-synapse-matrix-synapse
port: 8008
workloads: *id001
workloads: *id002
via:
kind: Ingress
name: othrys-synapse-matrix-synapse
name: matrix-routing
source: communication
- host: monero.bstein.dev
path: /
@ -1633,6 +1693,19 @@ http_endpoints:
kind: Ingress
name: monerod
source: monerod
- host: office.bstein.dev
path: /
backend:
namespace: nextcloud
service: collabora
port: 9980
workloads:
- kind: Deployment
name: collabora
via:
kind: Ingress
name: collabora
source: nextcloud
- host: pegasus.bstein.dev
path: /
backend:

View File

@ -20,6 +20,22 @@
],
"body": "# CI: Gitea \u2192 Jenkins pipeline\n\n## What this is\nAtlas uses Gitea for source control and Jenkins for CI. Authentication is via Keycloak (SSO).\n\n## Where it is configured\n- Gitea manifests: `services/gitea/`\n- Jenkins manifests: `services/jenkins/`\n- Credential sync helpers: `scripts/gitea_cred_sync.sh`, `scripts/jenkins_cred_sync.sh`\n\n## What users do (typical flow)\n- Create a repo in Gitea.\n- Create/update a Jenkins job/pipeline that can fetch the repo.\n- Configure a webhook (or SCM polling) so pushes trigger builds.\n\n## Troubleshooting (common)\n- \u201cWebhook not firing\u201d: confirm ingress host, webhook URL, and Jenkins job is reachable.\n- \u201cAuth denied cloning\u201d: confirm Keycloak group membership and that Jenkins has a valid token/credential configured."
},
{
"path": "runbooks/comms-verify.md",
"title": "Othrys verification checklist",
"tags": [
"comms",
"matrix",
"element",
"livekit"
],
"entrypoints": [
"https://live.bstein.dev",
"https://matrix.live.bstein.dev"
],
"source_paths": [],
"body": "1) Guest join:\n- Open a private window and visit:\n `https://live.bstein.dev/#/room/#othrys:live.bstein.dev?action=join`\n- Confirm the guest join flow works and the displayname becomes `<word>-<word>`.\n\n2) Keycloak login:\n- Log in from `https://live.bstein.dev` and confirm MAS -> Keycloak -> Element redirect.\n\n3) Video rooms:\n- Start an Element Call room and confirm audio/video with a second account.\n- Check that guests can read public rooms but cannot start calls.\n\n4) Well-known:\n- `https://live.bstein.dev/.well-known/matrix/client` returns JSON.\n- `https://matrix.live.bstein.dev/.well-known/matrix/client` returns JSON.\n\n5) TURN reachability:\n- Confirm `turn.live.bstein.dev:3478` and `turns:5349` are reachable from WAN."
},
{
"path": "runbooks/kb-authoring.md",
"title": "KB authoring: what to write (and what not to)",

View File

@ -9,10 +9,10 @@ flowchart LR
host_bstein_dev --> svc_bstein_dev_home_bstein_dev_home_frontend
wl_bstein_dev_home_bstein_dev_home_frontend["bstein-dev-home/bstein-dev-home-frontend (Deployment)"]
svc_bstein_dev_home_bstein_dev_home_frontend --> wl_bstein_dev_home_bstein_dev_home_frontend
svc_comms_othrys_synapse_matrix_synapse["comms/othrys-synapse-matrix-synapse (Service)"]
host_bstein_dev --> svc_comms_othrys_synapse_matrix_synapse
wl_comms_othrys_synapse_matrix_synapse["comms/othrys-synapse-matrix-synapse (Deployment)"]
svc_comms_othrys_synapse_matrix_synapse --> wl_comms_othrys_synapse_matrix_synapse
svc_comms_matrix_wellknown["comms/matrix-wellknown (Service)"]
host_bstein_dev --> svc_comms_matrix_wellknown
wl_comms_matrix_wellknown["comms/matrix-wellknown (Deployment)"]
svc_comms_matrix_wellknown --> wl_comms_matrix_wellknown
svc_bstein_dev_home_bstein_dev_home_backend["bstein-dev-home/bstein-dev-home-backend (Service)"]
host_bstein_dev --> svc_bstein_dev_home_bstein_dev_home_backend
wl_bstein_dev_home_bstein_dev_home_backend["bstein-dev-home/bstein-dev-home-backend (Deployment)"]
@ -51,11 +51,11 @@ flowchart LR
host_live_bstein_dev --> svc_comms_othrys_element_element_web
wl_comms_othrys_element_element_web["comms/othrys-element-element-web (Deployment)"]
svc_comms_othrys_element_element_web --> wl_comms_othrys_element_element_web
host_live_bstein_dev --> svc_comms_othrys_synapse_matrix_synapse
svc_comms_matrix_wellknown["comms/matrix-wellknown (Service)"]
host_live_bstein_dev --> svc_comms_matrix_wellknown
wl_comms_matrix_wellknown["comms/matrix-wellknown (Deployment)"]
svc_comms_matrix_wellknown --> wl_comms_matrix_wellknown
svc_comms_othrys_synapse_matrix_synapse["comms/othrys-synapse-matrix-synapse (Service)"]
host_live_bstein_dev --> svc_comms_othrys_synapse_matrix_synapse
wl_comms_othrys_synapse_matrix_synapse["comms/othrys-synapse-matrix-synapse (Deployment)"]
svc_comms_othrys_synapse_matrix_synapse --> wl_comms_othrys_synapse_matrix_synapse
host_longhorn_bstein_dev["longhorn.bstein.dev"]
svc_longhorn_system_oauth2_proxy_longhorn["longhorn-system/oauth2-proxy-longhorn (Service)"]
host_longhorn_bstein_dev --> svc_longhorn_system_oauth2_proxy_longhorn
@ -71,11 +71,20 @@ flowchart LR
svc_comms_matrix_authentication_service --> wl_comms_matrix_authentication_service
host_matrix_live_bstein_dev --> svc_comms_matrix_wellknown
host_matrix_live_bstein_dev --> svc_comms_othrys_synapse_matrix_synapse
svc_comms_matrix_guest_register["comms/matrix-guest-register (Service)"]
host_matrix_live_bstein_dev --> svc_comms_matrix_guest_register
wl_comms_matrix_guest_register["comms/matrix-guest-register (Deployment)"]
svc_comms_matrix_guest_register --> wl_comms_matrix_guest_register
host_monero_bstein_dev["monero.bstein.dev"]
svc_crypto_monerod["crypto/monerod (Service)"]
host_monero_bstein_dev --> svc_crypto_monerod
wl_crypto_monerod["crypto/monerod (Deployment)"]
svc_crypto_monerod --> wl_crypto_monerod
host_office_bstein_dev["office.bstein.dev"]
svc_nextcloud_collabora["nextcloud/collabora (Service)"]
host_office_bstein_dev --> svc_nextcloud_collabora
wl_nextcloud_collabora["nextcloud/collabora (Deployment)"]
svc_nextcloud_collabora --> wl_nextcloud_collabora
host_pegasus_bstein_dev["pegasus.bstein.dev"]
svc_jellyfin_pegasus["jellyfin/pegasus (Service)"]
host_pegasus_bstein_dev --> svc_jellyfin_pegasus
@ -116,8 +125,8 @@ flowchart LR
wl_bstein_dev_home_chat_ai_gateway
end
subgraph comms[comms]
svc_comms_othrys_synapse_matrix_synapse
wl_comms_othrys_synapse_matrix_synapse
svc_comms_matrix_wellknown
wl_comms_matrix_wellknown
svc_comms_element_call
wl_comms_element_call
svc_comms_livekit_token_service
@ -126,10 +135,12 @@ flowchart LR
wl_comms_livekit
svc_comms_othrys_element_element_web
wl_comms_othrys_element_element_web
svc_comms_matrix_wellknown
wl_comms_matrix_wellknown
svc_comms_othrys_synapse_matrix_synapse
wl_comms_othrys_synapse_matrix_synapse
svc_comms_matrix_authentication_service
wl_comms_matrix_authentication_service
svc_comms_matrix_guest_register
wl_comms_matrix_guest_register
end
subgraph crypto[crypto]
svc_crypto_monerod
@ -159,6 +170,8 @@ flowchart LR
subgraph nextcloud[nextcloud]
svc_nextcloud_nextcloud
wl_nextcloud_nextcloud
svc_nextcloud_collabora
wl_nextcloud_collabora
end
subgraph sso[sso]
svc_sso_oauth2_proxy

View File

@ -0,0 +1,30 @@
---
title: Othrys verification checklist
tags:
- comms
- matrix
- element
- livekit
entrypoints:
- https://live.bstein.dev
- https://matrix.live.bstein.dev
---
1) Guest join:
- Open a private window and visit:
`https://live.bstein.dev/#/room/#othrys:live.bstein.dev?action=join`
- Confirm the guest join flow works and the displayname becomes `<word>-<word>`.
2) Keycloak login:
- Log in from `https://live.bstein.dev` and confirm MAS -> Keycloak -> Element redirect.
3) Video rooms:
- Start an Element Call room and confirm audio/video with a second account.
- Check that guests can read public rooms but cannot start calls.
4) Well-known:
- `https://live.bstein.dev/.well-known/matrix/client` returns JSON.
- `https://matrix.live.bstein.dev/.well-known/matrix/client` returns JSON.
5) TURN reachability:
- Confirm `turn.live.bstein.dev:3478` and `turns:5349` are reachable from WAN.

5
scripts/comms_sync_kb.sh Executable file
View File

@ -0,0 +1,5 @@
#!/usr/bin/env bash
set -euo pipefail
python scripts/knowledge_render_atlas.py --write
python scripts/knowledge_render_atlas.py --write --out services/comms/knowledge

View File

@ -1,4 +1,4 @@
# services/communication/atlasbot-configmap.yaml
# services/comms/atlasbot-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:

View File

@ -1,4 +1,4 @@
# services/communication/atlasbot-deployment.yaml
# services/comms/atlasbot-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:

View File

@ -1,4 +1,4 @@
# services/communication/atlasbot-rbac.yaml
# services/comms/atlasbot-rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:

View File

@ -1,4 +1,4 @@
# services/communication/bstein-force-leave-job.yaml
# services/comms/bstein-force-leave-job.yaml
apiVersion: batch/v1
kind: Job
metadata:

View File

@ -1,4 +1,4 @@
# services/communication/coturn.yaml
# services/comms/coturn.yaml
apiVersion: apps/v1
kind: Deployment
metadata:

View File

@ -1,9 +1,8 @@
# services/communication/element-call-config.yaml
# services/comms/element-call-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: element-call-config
namespace: communication
data:
config.json: |
{

View File

@ -1,9 +1,8 @@
# services/communication/element-call-deployment.yaml
# services/comms/element-call-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: element-call
namespace: communication
labels:
app: element-call
spec:
@ -41,7 +40,6 @@ apiVersion: v1
kind: Service
metadata:
name: element-call
namespace: communication
spec:
selector:
app: element-call
@ -54,7 +52,6 @@ apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: element-call
namespace: communication
annotations:
kubernetes.io/ingress.class: traefik
traefik.ingress.kubernetes.io/router.entrypoints: websecure

View File

@ -1,4 +1,4 @@
# services/communication/guest-name-job.yaml
# services/comms/guest-name-job.yaml
apiVersion: batch/v1
kind: CronJob
metadata:

View File

@ -1,4 +1,4 @@
# services/communication/guest-register-configmap.yaml
# services/comms/guest-register-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:

View File

@ -1,4 +1,4 @@
# services/communication/guest-register-deployment.yaml
# services/comms/guest-register-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:

View File

@ -1,4 +1,4 @@
# services/communication/guest-register-service.yaml
# services/comms/guest-register-service.yaml
apiVersion: v1
kind: Service
metadata:

View File

@ -0,0 +1,8 @@
{
"counts": {
"helmrelease_host_hints": 7,
"http_endpoints": 35,
"services": 44,
"workloads": 49
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,73 @@
[
{
"path": "runbooks/ci-gitea-jenkins.md",
"title": "CI: Gitea \u2192 Jenkins pipeline",
"tags": [
"atlas",
"ci",
"gitea",
"jenkins"
],
"entrypoints": [
"scm.bstein.dev",
"ci.bstein.dev"
],
"source_paths": [
"services/gitea",
"services/jenkins",
"scripts/jenkins_cred_sync.sh",
"scripts/gitea_cred_sync.sh"
],
"body": "# CI: Gitea \u2192 Jenkins pipeline\n\n## What this is\nAtlas uses Gitea for source control and Jenkins for CI. Authentication is via Keycloak (SSO).\n\n## Where it is configured\n- Gitea manifests: `services/gitea/`\n- Jenkins manifests: `services/jenkins/`\n- Credential sync helpers: `scripts/gitea_cred_sync.sh`, `scripts/jenkins_cred_sync.sh`\n\n## What users do (typical flow)\n- Create a repo in Gitea.\n- Create/update a Jenkins job/pipeline that can fetch the repo.\n- Configure a webhook (or SCM polling) so pushes trigger builds.\n\n## Troubleshooting (common)\n- \u201cWebhook not firing\u201d: confirm ingress host, webhook URL, and Jenkins job is reachable.\n- \u201cAuth denied cloning\u201d: confirm Keycloak group membership and that Jenkins has a valid token/credential configured."
},
{
"path": "runbooks/kb-authoring.md",
"title": "KB authoring: what to write (and what not to)",
"tags": [
"atlas",
"kb",
"runbooks"
],
"entrypoints": [],
"source_paths": [
"knowledge/runbooks",
"scripts/knowledge_render_atlas.py"
],
"body": "# KB authoring: what to write (and what not to)\n\n## The goal\nGive Atlas assistants enough grounded, Atlas-specific context to answer \u201chow do I\u2026?\u201d questions without guessing.\n\n## What to capture (high value)\n- User workflows: \u201cclick here, set X, expected result\u201d\n- Operator workflows: \u201cedit these files, reconcile this kustomization, verify with these commands\u201d\n- Wiring: \u201cthis host routes to this service; this service depends on Postgres/Vault/etc\u201d\n- Failure modes: exact error messages + the 2\u20135 checks that usually resolve them\n- Permissions: Keycloak groups/roles and what they unlock\n\n## What to avoid (low value / fluff)\n- Generic Kubernetes explanations (link to upstream docs instead)\n- Copy-pasting large manifests (prefer file paths + small snippets)\n- Anything that will drift quickly (render it from GitOps instead)\n- Any secret values (reference Secret/Vault locations by name only)\n\n## Document pattern (recommended)\nEach runbook should answer:\n- \u201cWhat is this?\u201d\n- \u201cWhat do users do?\u201d\n- \u201cWhat do operators change (where in Git)?\u201d\n- \u201cHow do we verify it works?\u201d\n- \u201cWhat breaks and how to debug it?\u201d"
},
{
"path": "runbooks/observability.md",
"title": "Observability: Grafana + VictoriaMetrics (how to query safely)",
"tags": [
"atlas",
"monitoring",
"grafana",
"victoriametrics"
],
"entrypoints": [
"metrics.bstein.dev",
"alerts.bstein.dev"
],
"source_paths": [
"services/monitoring"
],
"body": "# Observability: Grafana + VictoriaMetrics (how to query safely)\n\n## Where it is configured\n- `services/monitoring/helmrelease.yaml` (Grafana + Alertmanager + VM values)\n- `services/monitoring/grafana-dashboard-*.yaml` (dashboards and their PromQL)\n\n## Using metrics as a \u201ctool\u201d for Atlas assistants\nThe safest pattern is: map a small set of intents \u2192 fixed PromQL queries, then summarize results.\n\nExamples (intents)\n- \u201cIs the cluster healthy?\u201d \u2192 node readiness + pod restart rate\n- \u201cWhy is Element Call failing?\u201d \u2192 LiveKit/coturn pod restarts + synapse errors + ingress 5xx\n- \u201cIs Jenkins slow?\u201d \u2192 pod CPU/memory + HTTP latency metrics (if exported)\n\n## Why dashboards are not the KB\nDashboards are great references, but the assistant should query VictoriaMetrics directly for live answers and keep the\nKB focused on wiring, runbooks, and stable conventions."
},
{
"path": "runbooks/template.md",
"title": "<short title>",
"tags": [
"atlas",
"<service>",
"<topic>"
],
"entrypoints": [
"<hostnames if relevant>"
],
"source_paths": [
"services/<svc>",
"clusters/atlas/<...>"
],
"body": "# <Short title>\n\n## What this is\n\n## For users (how to)\n\n## For operators (where configured)\n\n## Troubleshooting (symptoms \u2192 checks)"
}
]

View File

@ -0,0 +1,189 @@
flowchart LR
host_auth_bstein_dev["auth.bstein.dev"]
svc_sso_oauth2_proxy["sso/oauth2-proxy (Service)"]
host_auth_bstein_dev --> svc_sso_oauth2_proxy
wl_sso_oauth2_proxy["sso/oauth2-proxy (Deployment)"]
svc_sso_oauth2_proxy --> wl_sso_oauth2_proxy
host_bstein_dev["bstein.dev"]
svc_bstein_dev_home_bstein_dev_home_frontend["bstein-dev-home/bstein-dev-home-frontend (Service)"]
host_bstein_dev --> svc_bstein_dev_home_bstein_dev_home_frontend
wl_bstein_dev_home_bstein_dev_home_frontend["bstein-dev-home/bstein-dev-home-frontend (Deployment)"]
svc_bstein_dev_home_bstein_dev_home_frontend --> wl_bstein_dev_home_bstein_dev_home_frontend
svc_comms_matrix_wellknown["comms/matrix-wellknown (Service)"]
host_bstein_dev --> svc_comms_matrix_wellknown
wl_comms_matrix_wellknown["comms/matrix-wellknown (Deployment)"]
svc_comms_matrix_wellknown --> wl_comms_matrix_wellknown
svc_bstein_dev_home_bstein_dev_home_backend["bstein-dev-home/bstein-dev-home-backend (Service)"]
host_bstein_dev --> svc_bstein_dev_home_bstein_dev_home_backend
wl_bstein_dev_home_bstein_dev_home_backend["bstein-dev-home/bstein-dev-home-backend (Deployment)"]
svc_bstein_dev_home_bstein_dev_home_backend --> wl_bstein_dev_home_bstein_dev_home_backend
host_call_live_bstein_dev["call.live.bstein.dev"]
svc_comms_element_call["comms/element-call (Service)"]
host_call_live_bstein_dev --> svc_comms_element_call
wl_comms_element_call["comms/element-call (Deployment)"]
svc_comms_element_call --> wl_comms_element_call
host_chat_ai_bstein_dev["chat.ai.bstein.dev"]
svc_bstein_dev_home_chat_ai_gateway["bstein-dev-home/chat-ai-gateway (Service)"]
host_chat_ai_bstein_dev --> svc_bstein_dev_home_chat_ai_gateway
wl_bstein_dev_home_chat_ai_gateway["bstein-dev-home/chat-ai-gateway (Deployment)"]
svc_bstein_dev_home_chat_ai_gateway --> wl_bstein_dev_home_chat_ai_gateway
host_ci_bstein_dev["ci.bstein.dev"]
svc_jenkins_jenkins["jenkins/jenkins (Service)"]
host_ci_bstein_dev --> svc_jenkins_jenkins
wl_jenkins_jenkins["jenkins/jenkins (Deployment)"]
svc_jenkins_jenkins --> wl_jenkins_jenkins
host_cloud_bstein_dev["cloud.bstein.dev"]
svc_nextcloud_nextcloud["nextcloud/nextcloud (Service)"]
host_cloud_bstein_dev --> svc_nextcloud_nextcloud
wl_nextcloud_nextcloud["nextcloud/nextcloud (Deployment)"]
svc_nextcloud_nextcloud --> wl_nextcloud_nextcloud
host_kit_live_bstein_dev["kit.live.bstein.dev"]
svc_comms_livekit_token_service["comms/livekit-token-service (Service)"]
host_kit_live_bstein_dev --> svc_comms_livekit_token_service
wl_comms_livekit_token_service["comms/livekit-token-service (Deployment)"]
svc_comms_livekit_token_service --> wl_comms_livekit_token_service
svc_comms_livekit["comms/livekit (Service)"]
host_kit_live_bstein_dev --> svc_comms_livekit
wl_comms_livekit["comms/livekit (Deployment)"]
svc_comms_livekit --> wl_comms_livekit
host_live_bstein_dev["live.bstein.dev"]
svc_comms_othrys_element_element_web["comms/othrys-element-element-web (Service)"]
host_live_bstein_dev --> svc_comms_othrys_element_element_web
wl_comms_othrys_element_element_web["comms/othrys-element-element-web (Deployment)"]
svc_comms_othrys_element_element_web --> wl_comms_othrys_element_element_web
host_live_bstein_dev --> svc_comms_matrix_wellknown
svc_comms_othrys_synapse_matrix_synapse["comms/othrys-synapse-matrix-synapse (Service)"]
host_live_bstein_dev --> svc_comms_othrys_synapse_matrix_synapse
wl_comms_othrys_synapse_matrix_synapse["comms/othrys-synapse-matrix-synapse (Deployment)"]
svc_comms_othrys_synapse_matrix_synapse --> wl_comms_othrys_synapse_matrix_synapse
host_longhorn_bstein_dev["longhorn.bstein.dev"]
svc_longhorn_system_oauth2_proxy_longhorn["longhorn-system/oauth2-proxy-longhorn (Service)"]
host_longhorn_bstein_dev --> svc_longhorn_system_oauth2_proxy_longhorn
wl_longhorn_system_oauth2_proxy_longhorn["longhorn-system/oauth2-proxy-longhorn (Deployment)"]
svc_longhorn_system_oauth2_proxy_longhorn --> wl_longhorn_system_oauth2_proxy_longhorn
host_mail_bstein_dev["mail.bstein.dev"]
svc_mailu_mailserver_mailu_front["mailu-mailserver/mailu-front (Service)"]
host_mail_bstein_dev --> svc_mailu_mailserver_mailu_front
host_matrix_live_bstein_dev["matrix.live.bstein.dev"]
svc_comms_matrix_authentication_service["comms/matrix-authentication-service (Service)"]
host_matrix_live_bstein_dev --> svc_comms_matrix_authentication_service
wl_comms_matrix_authentication_service["comms/matrix-authentication-service (Deployment)"]
svc_comms_matrix_authentication_service --> wl_comms_matrix_authentication_service
host_matrix_live_bstein_dev --> svc_comms_matrix_wellknown
host_matrix_live_bstein_dev --> svc_comms_othrys_synapse_matrix_synapse
svc_comms_matrix_guest_register["comms/matrix-guest-register (Service)"]
host_matrix_live_bstein_dev --> svc_comms_matrix_guest_register
wl_comms_matrix_guest_register["comms/matrix-guest-register (Deployment)"]
svc_comms_matrix_guest_register --> wl_comms_matrix_guest_register
host_monero_bstein_dev["monero.bstein.dev"]
svc_crypto_monerod["crypto/monerod (Service)"]
host_monero_bstein_dev --> svc_crypto_monerod
wl_crypto_monerod["crypto/monerod (Deployment)"]
svc_crypto_monerod --> wl_crypto_monerod
host_office_bstein_dev["office.bstein.dev"]
svc_nextcloud_collabora["nextcloud/collabora (Service)"]
host_office_bstein_dev --> svc_nextcloud_collabora
wl_nextcloud_collabora["nextcloud/collabora (Deployment)"]
svc_nextcloud_collabora --> wl_nextcloud_collabora
host_pegasus_bstein_dev["pegasus.bstein.dev"]
svc_jellyfin_pegasus["jellyfin/pegasus (Service)"]
host_pegasus_bstein_dev --> svc_jellyfin_pegasus
wl_jellyfin_pegasus["jellyfin/pegasus (Deployment)"]
svc_jellyfin_pegasus --> wl_jellyfin_pegasus
host_scm_bstein_dev["scm.bstein.dev"]
svc_gitea_gitea["gitea/gitea (Service)"]
host_scm_bstein_dev --> svc_gitea_gitea
wl_gitea_gitea["gitea/gitea (Deployment)"]
svc_gitea_gitea --> wl_gitea_gitea
host_secret_bstein_dev["secret.bstein.dev"]
svc_vault_vault["vault/vault (Service)"]
host_secret_bstein_dev --> svc_vault_vault
wl_vault_vault["vault/vault (StatefulSet)"]
svc_vault_vault --> wl_vault_vault
host_sso_bstein_dev["sso.bstein.dev"]
svc_sso_keycloak["sso/keycloak (Service)"]
host_sso_bstein_dev --> svc_sso_keycloak
wl_sso_keycloak["sso/keycloak (Deployment)"]
svc_sso_keycloak --> wl_sso_keycloak
host_stream_bstein_dev["stream.bstein.dev"]
svc_jellyfin_jellyfin["jellyfin/jellyfin (Service)"]
host_stream_bstein_dev --> svc_jellyfin_jellyfin
wl_jellyfin_jellyfin["jellyfin/jellyfin (Deployment)"]
svc_jellyfin_jellyfin --> wl_jellyfin_jellyfin
host_vault_bstein_dev["vault.bstein.dev"]
svc_vaultwarden_vaultwarden_service["vaultwarden/vaultwarden-service (Service)"]
host_vault_bstein_dev --> svc_vaultwarden_vaultwarden_service
wl_vaultwarden_vaultwarden["vaultwarden/vaultwarden (Deployment)"]
svc_vaultwarden_vaultwarden_service --> wl_vaultwarden_vaultwarden
subgraph bstein_dev_home[bstein-dev-home]
svc_bstein_dev_home_bstein_dev_home_frontend
wl_bstein_dev_home_bstein_dev_home_frontend
svc_bstein_dev_home_bstein_dev_home_backend
wl_bstein_dev_home_bstein_dev_home_backend
svc_bstein_dev_home_chat_ai_gateway
wl_bstein_dev_home_chat_ai_gateway
end
subgraph comms[comms]
svc_comms_matrix_wellknown
wl_comms_matrix_wellknown
svc_comms_element_call
wl_comms_element_call
svc_comms_livekit_token_service
wl_comms_livekit_token_service
svc_comms_livekit
wl_comms_livekit
svc_comms_othrys_element_element_web
wl_comms_othrys_element_element_web
svc_comms_othrys_synapse_matrix_synapse
wl_comms_othrys_synapse_matrix_synapse
svc_comms_matrix_authentication_service
wl_comms_matrix_authentication_service
svc_comms_matrix_guest_register
wl_comms_matrix_guest_register
end
subgraph crypto[crypto]
svc_crypto_monerod
wl_crypto_monerod
end
subgraph gitea[gitea]
svc_gitea_gitea
wl_gitea_gitea
end
subgraph jellyfin[jellyfin]
svc_jellyfin_pegasus
wl_jellyfin_pegasus
svc_jellyfin_jellyfin
wl_jellyfin_jellyfin
end
subgraph jenkins[jenkins]
svc_jenkins_jenkins
wl_jenkins_jenkins
end
subgraph longhorn_system[longhorn-system]
svc_longhorn_system_oauth2_proxy_longhorn
wl_longhorn_system_oauth2_proxy_longhorn
end
subgraph mailu_mailserver[mailu-mailserver]
svc_mailu_mailserver_mailu_front
end
subgraph nextcloud[nextcloud]
svc_nextcloud_nextcloud
wl_nextcloud_nextcloud
svc_nextcloud_collabora
wl_nextcloud_collabora
end
subgraph sso[sso]
svc_sso_oauth2_proxy
wl_sso_oauth2_proxy
svc_sso_keycloak
wl_sso_keycloak
end
subgraph vault[vault]
svc_vault_vault
wl_vault_vault
end
subgraph vaultwarden[vaultwarden]
svc_vaultwarden_vaultwarden_service
wl_vaultwarden_vaultwarden
end

View File

@ -1,5 +1,46 @@
# services/comms/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: comms
resources:
- namespace.yaml
- atlasbot-rbac.yaml
- synapse-rendered.yaml
- synapse-signingkey-ensure-job.yaml
- synapse-seeder-admin-ensure-job.yaml
- mas-configmap.yaml
- mas-admin-client-secret-ensure-job.yaml
- mas-deployment.yaml
- element-rendered.yaml
- livekit-config.yaml
- livekit.yaml
- coturn.yaml
- livekit-token-deployment.yaml
- livekit-ingress.yaml
- livekit-middlewares.yaml
- element-call-config.yaml
- element-call-deployment.yaml
- reset-othrys-room-job.yaml
- bstein-force-leave-job.yaml
- pin-othrys-job.yaml
- guest-name-job.yaml
- guest-register-configmap.yaml
- guest-register-deployment.yaml
- guest-register-service.yaml
- matrix-ingress.yaml
- atlasbot-configmap.yaml
- atlasbot-deployment.yaml
- seed-othrys-room.yaml
- wellknown.yaml
patches:
- path: synapse-deployment-strategy-patch.yaml
configMapGenerator:
- name: atlas-kb
files:
- INDEX.md=knowledge/INDEX.md
- atlas.json=knowledge/catalog/atlas.json
- atlas-summary.json=knowledge/catalog/atlas-summary.json
- runbooks.json=knowledge/catalog/runbooks.json
- atlas-http.mmd=knowledge/diagrams/atlas-http.mmd

View File

@ -1,4 +1,4 @@
# services/communication/livekit-config.yaml
# services/comms/livekit-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:

View File

@ -1,9 +1,8 @@
# services/communication/livekit-ingress.yaml
# services/comms/livekit-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: livekit-ingress
namespace: communication
annotations:
kubernetes.io/ingress.class: traefik
traefik.ingress.kubernetes.io/router.entrypoints: websecure

View File

@ -1,9 +1,8 @@
# services/communication/livekit-middlewares.yaml
# services/comms/livekit-middlewares.yaml
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: livekit-sfu-strip
namespace: communication
spec:
stripPrefix:
prefixes:
@ -13,7 +12,6 @@ apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: livekit-jwt-strip
namespace: communication
spec:
stripPrefix:
prefixes:
@ -23,7 +21,6 @@ apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: livekit-jwt-ingress
namespace: communication
annotations:
kubernetes.io/ingress.class: traefik
traefik.ingress.kubernetes.io/router.entrypoints: websecure

View File

@ -1,4 +1,4 @@
# services/communication/livekit-token-deployment.yaml
# services/comms/livekit-token-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:

View File

@ -1,4 +1,4 @@
# services/communication/livekit.yaml
# services/comms/livekit.yaml
apiVersion: apps/v1
kind: Deployment
metadata:

View File

@ -1,4 +1,4 @@
# services/communication/mas-admin-client-secret-ensure-job.yaml
# services/comms/mas-admin-client-secret-ensure-job.yaml
apiVersion: v1
kind: ServiceAccount
metadata:

View File

@ -1,9 +1,8 @@
# services/communication/mas-configmap.yaml
# services/comms/mas-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: matrix-authentication-service-config
namespace: communication
data:
config.yaml: |
http:

View File

@ -1,9 +1,8 @@
# services/communication/mas-deployment.yaml
# services/comms/mas-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: matrix-authentication-service
namespace: communication
labels:
app: matrix-authentication-service
spec:
@ -139,7 +138,6 @@ apiVersion: v1
kind: Service
metadata:
name: matrix-authentication-service
namespace: communication
spec:
selector:
app: matrix-authentication-service

View File

@ -1,50 +1,41 @@
# services/communication/mas-ingress.yaml
# services/comms/matrix-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: matrix-authentication-service
namespace: communication
name: matrix-routing
annotations:
kubernetes.io/ingress.class: traefik
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true"
cert-manager.io/cluster-issuer: letsencrypt
spec:
ingressClassName: traefik
tls:
- hosts:
- matrix.live.bstein.dev
secretName: matrix-live-tls
- hosts:
- live.bstein.dev
secretName: live-othrys-tls
# Consolidated Matrix routing: MAS for auth/UI, Synapse for Matrix APIs, guest-register for guest joins.
rules:
- host: matrix.live.bstein.dev
http:
paths:
- path: /
- path: /_matrix/client/v3/register
pathType: Prefix
backend:
service:
name: matrix-authentication-service
name: matrix-guest-register
port:
number: 8080
- path: /_matrix/client/r0/register
pathType: Prefix
backend:
service:
name: matrix-guest-register
port:
number: 8080
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: matrix-authentication-service-compat
namespace: communication
annotations:
kubernetes.io/ingress.class: traefik
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true"
cert-manager.io/cluster-issuer: letsencrypt
spec:
tls:
- hosts:
- matrix.live.bstein.dev
secretName: matrix-live-tls
rules:
- host: matrix.live.bstein.dev
http:
paths:
- path: /_matrix/client/v3/login
pathType: Prefix
backend:
@ -66,3 +57,34 @@ spec:
name: matrix-authentication-service
port:
number: 8080
- path: /_matrix
pathType: Prefix
backend:
service:
name: othrys-synapse-matrix-synapse
port:
number: 8008
- path: /_synapse
pathType: Prefix
backend:
service:
name: othrys-synapse-matrix-synapse
port:
number: 8008
- path: /
pathType: Prefix
backend:
service:
name: matrix-authentication-service
port:
number: 8080
- host: live.bstein.dev
http:
paths:
- path: /_matrix
pathType: Prefix
backend:
service:
name: othrys-synapse-matrix-synapse
port:
number: 8008

View File

@ -1,4 +1,4 @@
# services/communication/pin-othrys-job.yaml
# services/comms/pin-othrys-job.yaml
apiVersion: batch/v1
kind: CronJob
metadata:

View File

@ -1,4 +1,4 @@
# services/communication/reset-othrys-room-job.yaml
# services/comms/reset-othrys-room-job.yaml
apiVersion: batch/v1
kind: Job
metadata:

View File

@ -1,4 +1,4 @@
# services/communication/seed-othrys-room.yaml
# services/comms/seed-othrys-room.yaml
apiVersion: batch/v1
kind: CronJob
metadata:

View File

@ -1,4 +1,4 @@
# services/communication/synapse-deployment-strategy-patch.yaml
# services/comms/synapse-deployment-strategy-patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:

View File

@ -5,7 +5,6 @@ kind: ServiceAccount
automountServiceAccountToken: true
metadata:
name: othrys-synapse-redis
namespace: "communication"
labels:
app.kubernetes.io/instance: othrys-synapse
app.kubernetes.io/managed-by: Helm
@ -57,7 +56,6 @@ apiVersion: v1
kind: ConfigMap
metadata:
name: othrys-synapse-redis-configuration
namespace: "communication"
labels:
app.kubernetes.io/instance: othrys-synapse
app.kubernetes.io/managed-by: Helm
@ -89,7 +87,6 @@ apiVersion: v1
kind: ConfigMap
metadata:
name: othrys-synapse-redis-health
namespace: "communication"
labels:
app.kubernetes.io/instance: othrys-synapse
app.kubernetes.io/managed-by: Helm
@ -196,7 +193,6 @@ apiVersion: v1
kind: ConfigMap
metadata:
name: othrys-synapse-redis-scripts
namespace: "communication"
labels:
app.kubernetes.io/instance: othrys-synapse
app.kubernetes.io/managed-by: Helm
@ -313,12 +309,6 @@ data:
## Registration ##
enable_registration: false
modules:
- module: guest_register.GuestRegisterModule
config:
shared_secret: "@@GUEST_REGISTER_SECRET@@"
header_name: x-guest-register-secret
path: /_matrix/_guest_register
## Metrics ###
@ -415,7 +405,6 @@ apiVersion: v1
kind: Service
metadata:
name: othrys-synapse-redis-headless
namespace: "communication"
labels:
app.kubernetes.io/instance: othrys-synapse
app.kubernetes.io/managed-by: Helm
@ -439,7 +428,6 @@ apiVersion: v1
kind: Service
metadata:
name: othrys-synapse-redis-master
namespace: "communication"
labels:
app.kubernetes.io/instance: othrys-synapse
app.kubernetes.io/managed-by: Helm
@ -511,7 +499,6 @@ apiVersion: apps/v1
kind: Deployment
metadata:
name: othrys-synapse-redis-master
namespace: "communication"
labels:
app.kubernetes.io/instance: othrys-synapse
app.kubernetes.io/managed-by: Helm
@ -708,7 +695,6 @@ spec:
export OIDC_CLIENT_SECRET_ESCAPED=$(echo "${OIDC_CLIENT_SECRET:-}" | sed 's/[\\/&]/\\&/g') && \
export TURN_SECRET_ESCAPED=$(echo "${TURN_SECRET:-}" | sed 's/[\\/&]/\\&/g') && \
export MAS_SHARED_SECRET_ESCAPED=$(echo "${MAS_SHARED_SECRET:-}" | sed 's/[\\/&]/\\&/g') && \
export GUEST_REGISTER_SECRET_ESCAPED=$(echo "${GUEST_REGISTER_SECRET:-}" | sed 's/[\\/&]/\\&/g') && \
export MACAROON_SECRET_KEY_ESCAPED=$(echo "${MACAROON_SECRET_KEY:-}" | sed 's/[\\/&]/\\&/g') && \
cat /synapse/secrets/*.yaml | \
sed -e "s/@@POSTGRES_PASSWORD@@/${POSTGRES_PASSWORD:-}/" \
@ -725,9 +711,6 @@ spec:
if [ -n "${MAS_SHARED_SECRET_ESCAPED}" ]; then \
sed -i "s/@@MAS_SHARED_SECRET@@/${MAS_SHARED_SECRET_ESCAPED}/g" /synapse/runtime-config/homeserver.yaml; \
fi; \
if [ -n "${GUEST_REGISTER_SECRET_ESCAPED}" ]; then \
sed -i "s/@@GUEST_REGISTER_SECRET@@/${GUEST_REGISTER_SECRET_ESCAPED}/g" /synapse/runtime-config/homeserver.yaml; \
fi; \
if [ -n "${MACAROON_SECRET_KEY_ESCAPED}" ]; then \
sed -i "s/@@MACAROON_SECRET_KEY@@/${MACAROON_SECRET_KEY_ESCAPED}/g" /synapse/runtime-config/homeserver.yaml; \
fi
@ -760,18 +743,11 @@ spec:
secretKeyRef:
name: mas-secrets-runtime
key: matrix_shared_secret
- name: GUEST_REGISTER_SECRET
valueFrom:
secretKeyRef:
name: guest-register-shared-secret-runtime
key: secret
- name: MACAROON_SECRET_KEY
valueFrom:
secretKeyRef:
name: synapse-macaroon
key: macaroon_secret_key
- name: PYTHONPATH
value: /synapse/modules
image: "ghcr.io/element-hq/synapse:v1.144.0"
imagePullPolicy: IfNotPresent
securityContext:
@ -808,9 +784,6 @@ spec:
mountPath: /synapse/config/conf.d
- name: secrets
mountPath: /synapse/secrets
- name: modules
mountPath: /synapse/modules
readOnly: true
- name: signingkey
mountPath: /synapse/keys
- name: media
@ -831,12 +804,6 @@ spec:
- name: secrets
secret:
secretName: othrys-synapse-matrix-synapse
- name: modules
configMap:
name: synapse-guest-register-module
items:
- key: guest_register.py
path: guest_register.py
- name: signingkey
secret:
secretName: "othrys-synapse-signingkey"
@ -866,73 +833,6 @@ spec:
- rpi4
weight: 50
---
# Source: matrix-synapse/templates/ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: othrys-synapse-matrix-synapse
labels:
helm.sh/chart: matrix-synapse-3.12.17
app.kubernetes.io/name: matrix-synapse
app.kubernetes.io/instance: othrys-synapse
app.kubernetes.io/version: "1.144.0"
app.kubernetes.io/managed-by: Helm
annotations:
cert-manager.io/cluster-issuer: letsencrypt
traefik.ingress.kubernetes.io/router.entrypoints: websecure
spec:
ingressClassName: traefik
tls:
- hosts:
- "matrix.live.bstein.dev"
- "live.bstein.dev"
secretName: matrix-live-tls
rules:
- host: "live.bstein.dev"
http:
paths:
- path: /_matrix
backend:
service:
name: othrys-synapse-matrix-synapse
port:
number: 8008
pathType: Prefix
- path: /.well-known/matrix
backend:
service:
name: othrys-synapse-matrix-synapse
port:
number: 8008
pathType: Prefix
- host: "matrix.live.bstein.dev"
http:
paths:
- path: /_matrix
backend:
service:
name: othrys-synapse-matrix-synapse
port:
number: 8008
pathType: Prefix
- path: /_synapse
backend:
service:
name: othrys-synapse-matrix-synapse
port:
number: 8008
pathType: Prefix
- host: "bstein.dev"
http:
paths:
- path: /.well-known/matrix
backend:
service:
name: othrys-synapse-matrix-synapse
port:
number: 8008
pathType: Prefix
---
# Source: matrix-synapse/templates/signing-key-job.yaml
apiVersion: v1
kind: ServiceAccount

View File

@ -1,4 +1,4 @@
# services/communication/synapse-seeder-admin-ensure-job.yaml
# services/comms/synapse-seeder-admin-ensure-job.yaml
apiVersion: batch/v1
kind: Job
metadata:

View File

@ -1,4 +1,4 @@
# services/communication/synapse-signingkey-ensure-job.yaml
# services/comms/synapse-signingkey-ensure-job.yaml
apiVersion: batch/v1
kind: Job
metadata:

View File

@ -1,4 +1,4 @@
# services/communication/values-element.yaml
# services/comms/values-element.yaml
replicaCount: 1
defaultServer:

View File

@ -1,4 +1,4 @@
# services/communication/values-synapse.yaml
# services/comms/values-synapse.yaml
serverName: live.bstein.dev
publicServerName: matrix.live.bstein.dev

View File

@ -1,9 +1,8 @@
# services/communication/wellknown.yaml
# services/comms/wellknown.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: matrix-wellknown
namespace: communication
data:
client.json: |
{
@ -30,7 +29,6 @@ apiVersion: v1
kind: ConfigMap
metadata:
name: matrix-wellknown-nginx
namespace: communication
data:
default.conf: |
server {
@ -57,7 +55,6 @@ apiVersion: apps/v1
kind: Deployment
metadata:
name: matrix-wellknown
namespace: communication
labels:
app: matrix-wellknown
spec:
@ -102,7 +99,6 @@ apiVersion: v1
kind: Service
metadata:
name: matrix-wellknown
namespace: communication
spec:
selector:
app: matrix-wellknown
@ -115,7 +111,6 @@ apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: matrix-wellknown
namespace: communication
annotations:
kubernetes.io/ingress.class: traefik
traefik.ingress.kubernetes.io/router.entrypoints: websecure
@ -149,7 +144,6 @@ apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: matrix-wellknown-matrix-live
namespace: communication
annotations:
kubernetes.io/ingress.class: traefik
traefik.ingress.kubernetes.io/router.entrypoints: websecure
@ -177,3 +171,36 @@ spec:
name: matrix-wellknown
port:
number: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: matrix-wellknown-bstein-dev
annotations:
kubernetes.io/ingress.class: traefik
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true"
cert-manager.io/cluster-issuer: letsencrypt
spec:
tls:
- hosts:
- bstein.dev
secretName: bstein-dev-home-tls
rules:
- host: bstein.dev
http:
paths:
- path: /.well-known/matrix/client
pathType: Prefix
backend:
service:
name: matrix-wellknown
port:
number: 80
- path: /.well-known/matrix/server
pathType: Prefix
backend:
service:
name: matrix-wellknown
port:
number: 80

View File

@ -1,34 +0,0 @@
# services/communication/guest-register-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: matrix-guest-register
annotations:
kubernetes.io/ingress.class: traefik
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true"
cert-manager.io/cluster-issuer: letsencrypt
spec:
tls:
- hosts:
- matrix.live.bstein.dev
secretName: matrix-live-tls
rules:
- host: matrix.live.bstein.dev
http:
paths:
- path: /_matrix/client/v3/register
pathType: Prefix
backend:
service:
name: matrix-guest-register
port:
number: 8080
- path: /_matrix/client/r0/register
pathType: Prefix
backend:
service:
name: matrix-guest-register
port:
number: 8080

View File

@ -1,86 +0,0 @@
# services/communication/guest-register-shared-secret-ensure-job.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: guest-register-secret-writer
namespace: comms
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: guest-register-secret-writer
namespace: comms
rules:
- apiGroups: [""]
resources: ["secrets"]
resourceNames: ["guest-register-shared-secret-runtime"]
verbs: ["get", "patch", "update"]
- apiGroups: [""]
resources: ["secrets"]
verbs: ["create"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: guest-register-secret-writer
namespace: comms
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: guest-register-secret-writer
subjects:
- kind: ServiceAccount
name: guest-register-secret-writer
namespace: comms
---
apiVersion: batch/v1
kind: Job
metadata:
name: guest-register-shared-secret-ensure-1
namespace: comms
spec:
backoffLimit: 2
template:
spec:
serviceAccountName: guest-register-secret-writer
restartPolicy: OnFailure
volumes:
- name: work
emptyDir: {}
initContainers:
- name: generate
image: alpine:3.20
command: ["/bin/sh", "-c"]
args:
- |
set -euo pipefail
umask 077
dd if=/dev/urandom bs=32 count=1 2>/dev/null | od -An -tx1 | tr -d ' \n' > /work/secret
chmod 0644 /work/secret
volumeMounts:
- name: work
mountPath: /work
containers:
- name: write
image: bitnami/kubectl:latest
command: ["/bin/sh", "-c"]
args:
- |
set -euo pipefail
if kubectl -n comms get secret guest-register-shared-secret-runtime >/dev/null 2>&1; then
if kubectl -n comms get secret guest-register-shared-secret-runtime -o jsonpath='{.data.secret}' 2>/dev/null | grep -q .; then
exit 0
fi
else
kubectl -n comms create secret generic guest-register-shared-secret-runtime \
--from-file=secret=/work/secret >/dev/null
exit 0
fi
secret_b64="$(base64 /work/secret | tr -d '\n')"
payload="$(printf '{\"data\":{\"secret\":\"%s\"}}' \"${secret_b64}\")"
kubectl -n comms patch secret guest-register-shared-secret-runtime --type=merge -p \"${payload}\" >/dev/null
volumeMounts:
- name: work
mountPath: /work

View File

@ -1,49 +0,0 @@
# services/communication/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: comms
resources:
- atlasbot-rbac.yaml
- synapse-rendered.yaml
- synapse-signingkey-ensure-job.yaml
- synapse-seeder-admin-ensure-job.yaml
- synapse-guest-appservice-secret-ensure-job.yaml
- guest-register-shared-secret-ensure-job.yaml
- synapse-guest-register-module-configmap.yaml
- mas-configmap.yaml
- mas-admin-client-secret-ensure-job.yaml
- mas-deployment.yaml
- mas-ingress.yaml
- element-rendered.yaml
- livekit-config.yaml
- livekit.yaml
- coturn.yaml
- livekit-token-deployment.yaml
- livekit-ingress.yaml
- livekit-middlewares.yaml
- element-call-config.yaml
- element-call-deployment.yaml
- reset-othrys-room-job.yaml
- bstein-force-leave-job.yaml
- pin-othrys-job.yaml
- guest-name-job.yaml
- guest-register-configmap.yaml
- guest-register-deployment.yaml
- guest-register-service.yaml
- guest-register-ingress.yaml
- atlasbot-configmap.yaml
- atlasbot-deployment.yaml
- seed-othrys-room.yaml
- wellknown.yaml
patchesStrategicMerge:
- synapse-deployment-strategy-patch.yaml
configMapGenerator:
- name: atlas-kb
files:
- INDEX.md=../../knowledge/INDEX.md
- atlas.json=../../knowledge/catalog/atlas.json
- atlas-summary.json=../../knowledge/catalog/atlas-summary.json
- runbooks.json=../../knowledge/catalog/runbooks.json
- atlas-http.mmd=../../knowledge/diagrams/atlas-http.mmd

View File

@ -1,111 +0,0 @@
# services/communication/synapse-guest-appservice-secret-ensure-job.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: synapse-guest-appservice-secret-writer
namespace: comms
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: synapse-guest-appservice-secret-writer
namespace: comms
rules:
- apiGroups: [""]
resources: ["secrets"]
resourceNames: ["synapse-guest-appservice-runtime"]
verbs: ["get", "patch", "update"]
- apiGroups: [""]
resources: ["secrets"]
verbs: ["create"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: synapse-guest-appservice-secret-writer
namespace: comms
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: synapse-guest-appservice-secret-writer
subjects:
- kind: ServiceAccount
name: synapse-guest-appservice-secret-writer
namespace: comms
---
apiVersion: batch/v1
kind: Job
metadata:
name: synapse-guest-appservice-secret-ensure-1
namespace: comms
spec:
backoffLimit: 2
template:
spec:
serviceAccountName: synapse-guest-appservice-secret-writer
restartPolicy: OnFailure
volumes:
- name: work
emptyDir: {}
initContainers:
- name: generate
image: alpine:3.20
command: ["/bin/sh", "-c"]
args:
- |
set -euo pipefail
umask 077
AS_TOKEN="$(dd if=/dev/urandom bs=32 count=1 2>/dev/null | od -An -tx1 | tr -d ' \n')"
HS_TOKEN="$(dd if=/dev/urandom bs=32 count=1 2>/dev/null | od -An -tx1 | tr -d ' \n')"
printf '%s' "${AS_TOKEN}" > /work/as_token
printf '%s' "${HS_TOKEN}" > /work/hs_token
cat > /work/registration.yaml <<EOF
id: othrys-guest-register
url: http://matrix-guest-register:8080
as_token: ${AS_TOKEN}
hs_token: ${HS_TOKEN}
sender_localpart: guest-register
rate_limited: true
namespaces:
users:
- regex: '@guest-[0-9a-f]+:live.bstein.dev'
exclusive: true
aliases: []
rooms: []
EOF
chmod 0644 /work/as_token /work/hs_token /work/registration.yaml
volumeMounts:
- name: work
mountPath: /work
containers:
- name: write
image: bitnami/kubectl:latest
command: ["/bin/sh", "-c"]
args:
- |
set -euo pipefail
if kubectl -n comms get secret synapse-guest-appservice-runtime >/dev/null 2>&1; then
if kubectl -n comms get secret synapse-guest-appservice-runtime -o jsonpath='{.data.registration\.yaml}' 2>/dev/null | grep -q .; then
exit 0
fi
else
kubectl -n comms create secret generic synapse-guest-appservice-runtime \
--from-file=registration.yaml=/work/registration.yaml \
--from-file=as_token=/work/as_token \
--from-file=hs_token=/work/hs_token >/dev/null
exit 0
fi
reg_b64="$(base64 /work/registration.yaml | tr -d '\n')"
as_b64="$(base64 /work/as_token | tr -d '\n')"
hs_b64="$(base64 /work/hs_token | tr -d '\n')"
payload="$(printf '{\"data\":{\"registration.yaml\":\"%s\",\"as_token\":\"%s\",\"hs_token\":\"%s\"}}' \"${reg_b64}\" \"${as_b64}\" \"${hs_b64}\")"
kubectl -n comms patch secret synapse-guest-appservice-runtime --type=merge -p \"${payload}\" >/dev/null
volumeMounts:
- name: work
mountPath: /work

View File

@ -1,89 +0,0 @@
# services/communication/synapse-guest-register-module-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: synapse-guest-register-module
data:
guest_register.py: |
import secrets
import random
import synapse.api.auth
from synapse.api.errors import Codes, SynapseError
from synapse.http.server import DirectServeJsonResource
from synapse.http.servlet import parse_json_object_from_request
from synapse.types import UserID, create_requester
class GuestRegisterResource(DirectServeJsonResource):
def __init__(self, hs, shared_secret: str, header_name: str):
super().__init__(clock=hs.get_clock())
self._hs = hs
self._shared_secret = shared_secret
self._header_name = header_name
self._adj = ["brisk", "calm", "eager", "gentle", "merry", "nifty", "rapid", "sunny", "witty", "zesty"]
self._noun = ["otter", "falcon", "comet", "ember", "grove", "harbor", "meadow", "raven", "river", "summit"]
async def _async_render_POST(self, request): # noqa: N802
provided = request.requestHeaders.getRawHeaders(self._header_name)
if not provided or not secrets.compare_digest(provided[0], self._shared_secret):
raise SynapseError(403, "Forbidden", errcode=Codes.FORBIDDEN)
body = parse_json_object_from_request(request)
initial_device_display_name = body.get("initial_device_display_name")
if not isinstance(initial_device_display_name, str):
initial_device_display_name = None
reg = self._hs.get_registration_handler()
address = request.getClientAddress().host
user_id = await reg.register_user(make_guest=True, address=address)
device_id = synapse.api.auth.GUEST_DEVICE_ID
device_id, access_token, valid_until_ms, refresh_token = await reg.register_device(
user_id,
device_id,
initial_device_display_name,
is_guest=True,
)
displayname = body.get("displayname")
if not isinstance(displayname, str) or not displayname.strip():
displayname = f"{random.choice(self._adj)}-{random.choice(self._noun)}"
try:
requester = create_requester(user_id, is_guest=True, device_id=device_id)
await self._hs.get_profile_handler().set_displayname(
UserID.from_string(user_id),
requester,
displayname,
propagate=False,
)
except Exception:
pass
result = {
"user_id": user_id,
"device_id": device_id,
"access_token": access_token,
"home_server": self._hs.hostname,
}
if valid_until_ms is not None:
result["expires_in_ms"] = valid_until_ms - self._hs.get_clock().time_msec()
if refresh_token is not None:
result["refresh_token"] = refresh_token
return 200, result
class GuestRegisterModule:
def __init__(self, config, api):
shared_secret = config["shared_secret"]
header_name = config.get("header_name", "x-guest-register-secret")
path = config.get("path", "/_matrix/_guest_register")
hs = api._hs # noqa: SLF001
api.register_web_resource(path, GuestRegisterResource(hs, shared_secret, header_name))