97 lines
3.9 KiB
Python
97 lines
3.9 KiB
Python
#!/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()
|