Files
bf-infra/routeros/backup-ap1.py

92 lines
2.7 KiB
Python

#!/usr/bin/env python3
"""Erstelle ein Binary-Backup + einen Text-Export von ap1 vor dem TP15-Cutover.
Creds aus ~/.claude.json (mikromcp-env). Backup-Dateien landen unter routeros/.
"""
import json
import pathlib
import subprocess
import sys
from datetime import datetime, timezone
AP1_IP = "10.40.10.1"
CLAUDE_JSON = pathlib.Path.home() / ".claude.json"
OUT_DIR = pathlib.Path(__file__).resolve().parent
def load_ap1_creds():
cfg = json.loads(CLAUDE_JSON.read_text())
env = cfg.get("mcpServers", {}).get("mikromcp", {}).get("env", {})
user = env.get("ROUTER_AP1_USER") or env.get("ROUTER_USER")
pw = env.get("ROUTER_AP1_PASS") or env.get("ROUTER_PASS")
if not user or not pw:
raise SystemExit("ROUTER_AP1_USER/PASS nicht in ~/.claude.json mikromcp.env gefunden")
return user, pw
def ssh_cmd(user, pw, remote_command):
return [
"sshpass", "-p", pw,
"ssh",
"-o", "StrictHostKeyChecking=no",
"-o", "UserKnownHostsFile=/dev/null",
"-o", "PubkeyAuthentication=no",
f"{user}@{AP1_IP}",
remote_command,
]
def scp_cmd(user, pw, remote_file, local_file):
return [
"sshpass", "-p", pw,
"scp",
"-o", "StrictHostKeyChecking=no",
"-o", "UserKnownHostsFile=/dev/null",
"-o", "PubkeyAuthentication=no",
f"{user}@{AP1_IP}:{remote_file}",
str(local_file),
]
def main():
user, pw = load_ap1_creds()
ts = datetime.now(timezone.utc).strftime("%Y%m%d-%H%M%S")
backup_name = f"ap1-pre-core-cutover-{ts}"
print(f"ap1 Backup via SSH {user}@{AP1_IP}")
# 1) Binary backup + Text-Export auf ap1 erzeugen
create_cmd = ssh_cmd(
user, pw,
f'/system backup save name="{backup_name}" dont-encrypt=yes; '
f'/export file="{backup_name}"'
)
print(f" Erzeuge Backup/Export auf ap1 ...")
subprocess.run(create_cmd, check=True)
# 2) Herunterladen
local_backup = OUT_DIR / f"{backup_name}.backup"
local_export = OUT_DIR / f"{backup_name}.rsc"
print(f" Lade {backup_name}.backup herunter ...")
subprocess.run(scp_cmd(user, pw, f"{backup_name}.backup", local_backup), check=True)
print(f" Lade {backup_name}.rsc herunter ...")
subprocess.run(scp_cmd(user, pw, f"{backup_name}.rsc", local_export), check=True)
# 3) Verifizieren
backup_size = local_backup.stat().st_size
export_size = local_export.stat().st_size
print(f" OK: {local_backup.name} ({backup_size} Bytes)")
print(f" OK: {local_export.name} ({export_size} Bytes)")
if backup_size < 1000:
print(" WARN: Backup-Datei auffällig klein!")
sys.exit(1)
print("\nNächster Schritt: Cutover-Config auf crs326-core laden.")
if __name__ == "__main__":
main()