ansible/scripts/beszel-setup-smtp.sh
ilia 0f34c51fc8
All checks were successful
CI / skip-ci-check (pull_request) Successful in 8s
CI / lint-and-test (pull_request) Successful in 17s
CI / secret-scanning (pull_request) Successful in 8s
CI / dependency-scan (pull_request) Successful in 18s
CI / ansible-validation (pull_request) Successful in 54s
CI / sast-scan (pull_request) Successful in 29s
CI / license-check (pull_request) Successful in 14s
CI / vault-check (pull_request) Successful in 13s
CI / container-scan (pull_request) Successful in 8s
CI / sonar-analysis (pull_request) Successful in 8s
CI / playbook-test (pull_request) Successful in 27s
CI / workflow-summary (pull_request) Successful in 6s
Complete homelab post-sprint: SSO docs, monitoring scripts, phase 0/1 closure.
Consolidate sprint status into handoff docs, add Listmonk/Mattermost/Mailcow
and Vikunja SSO guides, Beszel alerts script, mattermost inventory, and
mark phases 0–1 complete with phase 2 backlog for edge Caddy and security.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-24 12:13:55 -04:00

141 lines
4.1 KiB
Bash
Executable File

#!/usr/bin/env bash
# Configure Beszel (PocketBase) SMTP for Mailcow alerts mailbox.
#
# Prerequisite: admin account created at http://10.0.10.22:8090
#
# Usage:
# export BESZEL_URL=http://10.0.10.22:8090
# export BESZEL_EMAIL=you@example.com
# export BESZEL_PASSWORD='your-beszel-password'
# export SMTP_PASS='alerts@ mailbox password' # or source .env
# ./scripts/beszel-setup-smtp.sh
#
# Optional: SMTP_TO for test email (default idobkin@gmail.com)
set -euo pipefail
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
BESZEL_URL="${BESZEL_URL:-http://10.0.10.22:8090}"
BESZEL_EMAIL="${BESZEL_EMAIL:-}"
BESZEL_PASSWORD="${BESZEL_PASSWORD:-}"
SMTP_HOST="${SMTP_HOST:-mail.levkine.ca}"
SMTP_PORT="${SMTP_PORT:-587}"
SMTP_USER="${SMTP_USER:-alerts@levkine.ca}"
SMTP_PASS="${SMTP_PASS:-}"
SMTP_TO="${SMTP_TO:-idobkin@gmail.com}"
if [[ -z "${SMTP_PASS}" ]] && [[ -f "${REPO_ROOT}/.env" ]]; then
# shellcheck disable=SC1091
set +u
set -a
# shellcheck source=/dev/null
source "${REPO_ROOT}/.env"
set +a
set -u
SMTP_PASS="${SMTP_PASS:-${ALERTS_PASSWORD:-}}"
fi
if [[ -z "${BESZEL_EMAIL}" || -z "${BESZEL_PASSWORD}" ]]; then
echo "Set BESZEL_EMAIL and BESZEL_PASSWORD (Beszel admin you just created)" >&2
exit 1
fi
if [[ -z "${SMTP_PASS}" ]]; then
echo "Set SMTP_PASS or ALERTS_PASSWORD (alerts@levkine.ca mailbox password)" >&2
exit 1
fi
export BESZEL_URL BESZEL_EMAIL BESZEL_PASSWORD SMTP_HOST SMTP_PORT SMTP_USER SMTP_PASS SMTP_TO
"${REPO_ROOT}/.venv/bin/python3" <<'PY'
import json
import os
import sys
import urllib.error
import urllib.request
base = os.environ["BESZEL_URL"].rstrip("/")
email = os.environ["BESZEL_EMAIL"]
password = os.environ["BESZEL_PASSWORD"]
smtp_host = os.environ["SMTP_HOST"]
smtp_port = int(os.environ["SMTP_PORT"])
smtp_user = os.environ["SMTP_USER"]
smtp_pass = os.environ["SMTP_PASS"]
smtp_to = os.environ["SMTP_TO"]
def req(method, path, token=None, body=None):
url = f"{base}{path}"
data = None
headers = {"Content-Type": "application/json"}
if body is not None:
data = json.dumps(body).encode()
if token:
headers["Authorization"] = token
request = urllib.request.Request(url, data=data, headers=headers, method=method)
try:
with urllib.request.urlopen(request, timeout=30) as resp:
raw = resp.read().decode()
return resp.status, json.loads(raw) if raw else {}
except urllib.error.HTTPError as e:
raw = e.read().decode()
print(f"HTTP {e.code} {path}: {raw}", file=sys.stderr)
raise
print(f"Login to Beszel at {base} as {email}...")
for collection in ("_superusers", "users"):
try:
status, auth = req(
"POST",
f"/api/collections/{collection}/auth-with-password",
body={"identity": email, "password": password},
)
token = auth.get("token")
if token:
print(f"Login OK ({collection})")
break
except urllib.error.HTTPError:
token = None
continue
else:
print("Login failed: check BESZEL_EMAIL and BESZEL_PASSWORD", file=sys.stderr)
sys.exit(1)
print("Configuring SMTP (Mailcow STARTTLS)...")
req(
"PATCH",
"/api/settings",
token=token,
body={
"smtp": {
"enabled": True,
"host": smtp_host,
"port": smtp_port,
"username": smtp_user,
"password": smtp_pass,
"tls": False,
"authMethod": "PLAIN",
"localName": "monitoring.levkin.ca",
},
"meta": {
"senderName": "Beszel",
"senderAddress": smtp_user,
},
},
)
print("SMTP settings saved")
print(f"Sending test email to {smtp_to}...")
req(
"POST",
"/api/settings/test/email",
token=token,
body={"email": smtp_to, "template": "verification", "collection": "_superusers"},
)
print("Test email request accepted — check inbox (and restart beszel if alerts fail later)")
print("\nDone. Restart hub to avoid cached mail client issues:")
print(" ssh root@10.0.10.22 'cd /opt/monitoring && docker compose restart beszel'")
PY