feat: add homelab topology documentation, infrastructure improvement plans, and management scripts
This commit is contained in:
96
scripts/setup_gotify_channels.py
Normal file
96
scripts/setup_gotify_channels.py
Normal file
@@ -0,0 +1,96 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Provision Gotify Users, Broadcast Applications, and Device Client Tokens
|
||||
on Snarfnet (http://140.44.4.70:8090).
|
||||
"""
|
||||
import base64
|
||||
import json
|
||||
import urllib.request
|
||||
import paramiko
|
||||
|
||||
SWARM_MANAGER = "140.44.4.71"
|
||||
SSH_USER = "snarf"
|
||||
SSH_PASS = "Katzir476!"
|
||||
GOTIFY_URL = "http://140.44.4.70:8090"
|
||||
|
||||
APPLICATIONS = [
|
||||
(1, "A4uN4fEmErGeNcYtOkEn", 1, "UPS & Power Resilience", "NUT Master UPS power events and tiered shutdown broadcasts", 0, "", 9),
|
||||
(2, "A7zBx9InFrAaLeRtStOk", 1, "Zabbix Infrastructure Alerts", "Zabbix 7.0 infrastructure triggers, node health, and threshold alarms", 0, "", 7),
|
||||
(3, "A3hOmEaSsIsTaNtToKeN", 1, "Home Assistant Smart Home", "Home Assistant smart home alerts and automation broadcasts", 0, "", 5),
|
||||
(4, "A8aWxGiToPsAuToMaTiO", 1, "AWX & GitOps Automation", "Ansible AWX, Semaphore, and ArgoCD deployment & patching notifications", 0, "", 4),
|
||||
(5, "A6bAcKuPsAnDsToRaGeH", 1, "Backups & Storage Health", "NPM, Gotify, Homebox, and Longhorn NFS backup verification alerts", 0, "", 6),
|
||||
]
|
||||
|
||||
CLIENTS = [
|
||||
(1, "C1dIsCoRdBrIdGeClIeN", 1, "Gotify-Discord Multi-Channel Bridge"),
|
||||
(2, "C2sNaRfMoBiLePhOnEcL", 1, "Snarf Primary Mobile Phone"),
|
||||
(3, "C3sNaRfTaBlEtDeViCeC", 1, "Snarf Tablet / Secondary Device"),
|
||||
(4, "C4hOmEpAgEdAsHbOaRdC", 1, "Homepage Dashboard & Workstation"),
|
||||
]
|
||||
|
||||
DB_PATHS = [
|
||||
"/var/lib/docker/volumes/gotify_gotify_data/_data/gotify.db",
|
||||
"/mnt/swarm_shared/legacy_volumes/gotify/gotify.db",
|
||||
"/mnt/swarm_shared/legacy_volumes/gotify/_data/gotify.db",
|
||||
]
|
||||
|
||||
def main():
|
||||
ssh = paramiko.SSHClient()
|
||||
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
ssh.connect(SWARM_MANAGER, username=SSH_USER, password=SSH_PASS, timeout=10)
|
||||
|
||||
remote_py = f"""echo '{SSH_PASS}' | sudo -S python3 -c '
|
||||
import sqlite3, bcrypt
|
||||
|
||||
pw_hash = bcrypt.hashpw(b"Katzir476!", bcrypt.gensalt(rounds=10)).replace(b"$2b$", b"$2a$")
|
||||
|
||||
for db_path in {json.dumps(DB_PATHS)}:
|
||||
conn = sqlite3.connect(db_path)
|
||||
cur = conn.cursor()
|
||||
|
||||
cur.execute("UPDATE users SET pass = ?, admin = 1 WHERE id = 1", (pw_hash,))
|
||||
cur.execute("INSERT OR REPLACE INTO users (id, name, pass, admin) VALUES (2, ?, ?, 1)", ("snarf", pw_hash))
|
||||
|
||||
for app in {json.dumps(APPLICATIONS)}:
|
||||
cur.execute(\"\"\"
|
||||
INSERT OR REPLACE INTO applications
|
||||
(id, token, user_id, name, description, internal, image, default_priority)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
||||
\"\"\", app)
|
||||
|
||||
for cl in {json.dumps(CLIENTS)}:
|
||||
cur.execute(\"\"\"
|
||||
INSERT OR REPLACE INTO clients
|
||||
(id, token, user_id, name)
|
||||
VALUES (?, ?, ?, ?)
|
||||
\"\"\", cl)
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
print("Configured:", db_path)
|
||||
'"""
|
||||
stdin, stdout, stderr = ssh.exec_command(remote_py)
|
||||
print(stdout.read().decode("utf-8", errors="ignore"))
|
||||
err = stderr.read().decode("utf-8", errors="ignore")
|
||||
if err:
|
||||
print("STDERR:", err)
|
||||
ssh.close()
|
||||
|
||||
# Verify via Gotify HTTP API
|
||||
b64 = base64.b64encode(b"admin:Katzir476!").decode("ascii")
|
||||
req = urllib.request.Request(f"{GOTIFY_URL}/application", headers={"Authorization": f"Basic {b64}"})
|
||||
with urllib.request.urlopen(req, timeout=8) as r:
|
||||
apps_resp = json.loads(r.read().decode("utf-8"))
|
||||
print(f"Verified {len(apps_resp)} Gotify Applications via REST API:")
|
||||
for a in apps_resp:
|
||||
print(f" - [{a['id']}] {a['name']} (token={a['token']}, defaultPriority={a['defaultPriority']})")
|
||||
|
||||
req_c = urllib.request.Request(f"{GOTIFY_URL}/client", headers={"Authorization": f"Basic {b64}"})
|
||||
with urllib.request.urlopen(req_c, timeout=8) as r:
|
||||
clients_resp = json.loads(r.read().decode("utf-8"))
|
||||
print(f"Verified {len(clients_resp)} Gotify Clients via REST API:")
|
||||
for c in clients_resp:
|
||||
print(f" - [{c['id']}] {c['name']} (token={c['token']})")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user