Add linux/webhook.py

This commit is contained in:
2026-06-08 13:43:48 +02:00
parent 8460bb7340
commit cfcebcf6b6
+87
View File
@@ -0,0 +1,87 @@
#!/usr/bin/env python3
"""
Webhook-Empfänger für Lexware-Dump-Benachrichtigungen vom Windows-Server.
POST /restore?db=f1 → nur f1 wiederherstellen
POST /restore → alle DBs prüfen und bei Bedarf wiederherstellen
GET /health → Liveness-Check
"""
import http.server
import subprocess
import threading
import urllib.parse
import logging
import sys
import os
PORT = 9055
RESTORE_SCRIPT = "/opt/lexware-dumps/restore-latest.sh"
LOG_FILE = "/var/log/lexware-restore.log"
VALID_DBS = {"f1", "f2", "lexkonto", "lexkk", "rk", "lxoffice", "lx", "lxcatalog"}
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [webhook] %(message)s",
datefmt="%Y-%m-%d %H:%M:%S",
handlers=[
logging.FileHandler(LOG_FILE),
logging.StreamHandler(sys.stdout),
],
)
def run_restore(db: str | None):
env = os.environ.copy()
cmd = [RESTORE_SCRIPT]
if db:
env["RESTORE_DB"] = db
logging.info(f"Starte Restore: db={db or 'alle'}")
result = subprocess.run(cmd, env=env, capture_output=True, text=True)
if result.stdout:
for line in result.stdout.strip().splitlines():
logging.info(line)
if result.returncode not in (0, 1):
logging.error(f"Restore-Skript exit {result.returncode}")
class WebhookHandler(http.server.BaseHTTPRequestHandler):
def log_message(self, fmt, *args):
logging.info(f"{self.address_string()} {fmt % args}")
def do_POST(self):
parsed = urllib.parse.urlparse(self.path)
params = urllib.parse.parse_qs(parsed.query)
if parsed.path != "/restore":
self._respond(404, "Not found")
return
db = params.get("db", [None])[0]
if db and db not in VALID_DBS:
self._respond(400, f"Unbekannte Datenbank: {db}")
return
self._respond(200, f"OK: Restore gestartet (db={db or 'alle'})")
# Restore asynchron starten damit der Webhook sofort antwortet
threading.Thread(target=run_restore, args=(db,), daemon=True).start()
def do_GET(self):
if self.path == "/health":
self._respond(200, "OK")
else:
self._respond(404, "Not found")
def _respond(self, code: int, body: str):
data = body.encode()
self.send_response(code)
self.send_header("Content-Type", "text/plain")
self.send_header("Content-Length", str(len(data)))
self.end_headers()
self.wfile.write(data)
if __name__ == "__main__":
server = http.server.ThreadingHTTPServer(("0.0.0.0", PORT), WebhookHandler)
logging.info(f"Webhook-Server läuft auf Port {PORT}")
server.serve_forever()