diff --git a/kubernetes/apps/home-assistant/mosquitto-bootstrap.yaml b/kubernetes/apps/home-assistant/mosquitto-bootstrap.yaml index cecdc7b8..0008942c 100644 --- a/kubernetes/apps/home-assistant/mosquitto-bootstrap.yaml +++ b/kubernetes/apps/home-assistant/mosquitto-bootstrap.yaml @@ -301,3 +301,71 @@ spec: memory: 32Mi limits: memory: 64Mi +--- +# Fifth broker user: `open3e` — the Viessmann E3 CAN bridge (Vitocal 250-A +# + Vitocharge VX3 via open3e). Scoped to `open3e/#` (ACL in +# mosquitto-deployment.yaml). Own credential so its lifecycle is +# independent of the others. Retrieve with: +# kubectl -n home-assistant get secret mosquitto-open3e-credentials \ +# -o jsonpath='{.data.password}' | base64 -d +apiVersion: batch/v1 +kind: Job +metadata: + name: mosquitto-open3e-credentials-bootstrap + namespace: home-assistant +spec: + backoffLimit: 4 + template: + metadata: + labels: + app.kubernetes.io/name: mosquitto-bootstrap + spec: + serviceAccountName: mosquitto-bootstrap + restartPolicy: OnFailure + containers: + - name: bootstrap + image: alpine:3.21 + command: + - sh + - -c + - | + set -eu + apk add --no-cache curl jq >/dev/null + + NS=home-assistant + NAME=mosquitto-open3e-credentials + TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) + CA=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt + API=https://kubernetes.default.svc + + if curl -fsSL --cacert "$CA" -H "Authorization: Bearer $TOKEN" \ + "$API/api/v1/namespaces/$NS/secrets/$NAME" >/dev/null 2>&1; then + echo "$NAME already exists; nothing to do." + exit 0 + fi + + PW=$(tr -dc 'A-Za-z0-9' /dev/null + + echo "generated $NAME" + resources: + requests: + cpu: 10m + memory: 32Mi + limits: + memory: 64Mi diff --git a/kubernetes/apps/home-assistant/mosquitto-deployment.yaml b/kubernetes/apps/home-assistant/mosquitto-deployment.yaml index 2e57b471..03b1b353 100644 --- a/kubernetes/apps/home-assistant/mosquitto-deployment.yaml +++ b/kubernetes/apps/home-assistant/mosquitto-deployment.yaml @@ -41,6 +41,7 @@ spec: mosquitto_passwd -b /mosquitto/auth/passwd shellies "$SHELLY_PASSWORD" mosquitto_passwd -b /mosquitto/auth/passwd admin "$ADMIN_PASSWORD" mosquitto_passwd -b /mosquitto/auth/passwd sml2mqtt "$SML2MQTT_PASSWORD" + mosquitto_passwd -b /mosquitto/auth/passwd open3e "$OPEN3E_PASSWORD" # ACL: HA keeps full access (subscribes to everything); the # shellies user is scoped to `shellies/#` for device state + # `homeassistant/#` so HA MQTT-discovery payloads from Shelly @@ -52,6 +53,10 @@ spec: # `sml2mqtt` is the power-meter bridge — publish-only under # its own `sml2mqtt/#` subtree (HA reads it via the full-access # homeassistant user). + # `open3e` is the Viessmann E3 CAN bridge (Vitocal/VX3) — + # scoped to its own `open3e/#` subtree: publishes datapoints + # and later subscribes to `open3e/cmnd` in listener mode (HA + # reads via the full-access homeassistant user). cat > /mosquitto/auth/acl <<'EOF' user homeassistant topic readwrite # @@ -65,6 +70,9 @@ spec: user sml2mqtt topic readwrite sml2mqtt/# + + user open3e + topic readwrite open3e/# EOF chown 1883:1883 /mosquitto/auth/passwd /mosquitto/auth/acl chmod 0600 /mosquitto/auth/passwd /mosquitto/auth/acl @@ -90,6 +98,11 @@ spec: secretKeyRef: name: mosquitto-sml2mqtt-credentials key: password + - name: OPEN3E_PASSWORD + valueFrom: + secretKeyRef: + name: mosquitto-open3e-credentials + key: password ports: - name: mqtt containerPort: 1883