feat(ess-pro/compose): deploy Element Server Suite Pro via Compose
initial commit of the converted role from helm charts for qubernetis to compose ansible role
This commit is contained in:
parent
c11f019aae
commit
32eca6b923
33 changed files with 1906 additions and 0 deletions
102
roles/ess_pro_compose/templates/generate-secrets.py.j2
Normal file
102
roles/ess_pro_compose/templates/generate-secrets.py.j2
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
#!/usr/bin/env python3
|
||||
# {{ ansible_managed }}
|
||||
"""
|
||||
Generate the ess-generated secret bundle the way the Helm chart's
|
||||
init-secrets job does. Idempotent: only writes files that don't exist.
|
||||
|
||||
Mirrors `matrix-tools generate-secrets` arguments from chart v{{ ess_chart_version }}.
|
||||
"""
|
||||
import os
|
||||
import secrets
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
from cryptography.hazmat.primitives import serialization
|
||||
from cryptography.hazmat.primitives.asymmetric import ec, ed25519, rsa
|
||||
|
||||
SECRETS_DIR = Path("{{ ess_compose_secrets_dir }}")
|
||||
SECRETS_DIR.mkdir(mode=0o700, parents=True, exist_ok=True)
|
||||
|
||||
|
||||
def write_if_missing(name, content_bytes):
|
||||
p = SECRETS_DIR / name
|
||||
if p.exists():
|
||||
return False
|
||||
# Atomic-ish write
|
||||
tmp = p.with_suffix(p.suffix + ".tmp")
|
||||
tmp.write_bytes(content_bytes)
|
||||
os.chmod(tmp, 0o600)
|
||||
tmp.rename(p)
|
||||
return True
|
||||
|
||||
|
||||
def rand32():
|
||||
# `matrix-tools rand32` produces 32 url-safe characters
|
||||
return secrets.token_urlsafe(24)[:32].encode()
|
||||
|
||||
|
||||
def hex32():
|
||||
return secrets.token_hex(32).encode()
|
||||
|
||||
|
||||
def rsa_der():
|
||||
key = rsa.generate_private_key(public_exponent=65537, key_size=4096)
|
||||
return key.private_bytes(
|
||||
encoding=serialization.Encoding.DER,
|
||||
format=serialization.PrivateFormat.PKCS8,
|
||||
encryption_algorithm=serialization.NoEncryption(),
|
||||
)
|
||||
|
||||
|
||||
def ecdsa_prime256v1():
|
||||
key = ec.generate_private_key(ec.SECP256R1())
|
||||
return key.private_bytes(
|
||||
encoding=serialization.Encoding.PEM,
|
||||
format=serialization.PrivateFormat.PKCS8,
|
||||
encryption_algorithm=serialization.NoEncryption(),
|
||||
)
|
||||
|
||||
|
||||
def synapse_signing_key():
|
||||
# Synapse expects: ed25519 <keyid> <unpadded-base64-seed>
|
||||
import base64
|
||||
key = ed25519.Ed25519PrivateKey.generate()
|
||||
seed = key.private_bytes(
|
||||
encoding=serialization.Encoding.Raw,
|
||||
format=serialization.PrivateFormat.Raw,
|
||||
encryption_algorithm=serialization.NoEncryption(),
|
||||
)
|
||||
# 4-char keyid like Synapse generates
|
||||
keyid = secrets.token_hex(2)
|
||||
b64 = base64.b64encode(seed).rstrip(b"=").decode()
|
||||
return f"ed25519 a_{keyid} {b64}\n".encode()
|
||||
|
||||
|
||||
SPEC = {
|
||||
"POSTGRES_ADMIN_PASSWORD": rand32,
|
||||
"POSTGRES_SYNAPSE_PASSWORD": rand32,
|
||||
"POSTGRES_MATRIX_AUTHENTICATION_SERVICE_PASSWORD": rand32,
|
||||
"SYNAPSE_MACAROON": rand32,
|
||||
"SYNAPSE_REGISTRATION_SHARED_SECRET": rand32,
|
||||
"SYNAPSE_WORKERS_REPLICATION_SECRET": rand32,
|
||||
"SYNAPSE_SIGNING_KEY": synapse_signing_key,
|
||||
"MAS_SYNAPSE_SHARED_SECRET": rand32,
|
||||
"MAS_MATRIX_TOOLS_OIDC_CLIENT_SECRET": rand32,
|
||||
"MAS_ENCRYPTION_SECRET": hex32,
|
||||
"MAS_RSA_PRIVATE_KEY": rsa_der,
|
||||
"MAS_ECDSA_PRIME256V1_PRIVATE_KEY": ecdsa_prime256v1,
|
||||
"ELEMENT_CALL_LIVEKIT_SECRET": rand32,
|
||||
"ADMIN_USER_PASSWORD": rand32,
|
||||
}
|
||||
|
||||
|
||||
created = []
|
||||
for name, fn in SPEC.items():
|
||||
if write_if_missing(name, fn()):
|
||||
created.append(name)
|
||||
|
||||
if created:
|
||||
print("CREATED:", " ".join(created))
|
||||
else:
|
||||
print("NOCHANGE")
|
||||
sys.exit(0)
|
||||
Loading…
Add table
Add a link
Reference in a new issue