Files
bf-infra/routeros/fetch-core-cutover-config.py
Christoph Emsenhuber d281a0f36f TP15: CRS326-Core als L3-Router aktiviert
- crs326-core nimmt Routing/DHCP/DNS/NAT/WAN/WireGuard von ap1 ueber.
- L2-Portplan korrigiert (ap1 #15, Arris WAN #16, branch #8, Sonos #2/3/5/6,
  IoT #14, VLAN10-Access #11, VLAN1-Hybrid #3/7/9/10/12/17-24).
- Backup-RSC gefixt (ether3-24 disabled) und via fixed-RSC eingespielt.
- Gestagede L3-Config enabled in einem Rutsch.
- Falsche statische Default-Route 0.0.0.0/0 -> 10.40.41.1 entfernt,
  WAN-DHCP via 90.146.33.177/24 aktiv.
- SFP-Ports bleiben disabled (Stromersparnis).
- ap1 ist L3-stillgelegt und wird in naechster Session reiner AP.

Backup-Dateien (*.backup) und leases-export.json bleiben lokal.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-07 22:39:29 +02:00

52 lines
1.9 KiB
Python

#!/usr/bin/env python3
"""Holt crs326-core intended config aus Nautobot, setzt WG-Privkey,
fügt ap1 static leases hinzu, speichert als tp15-core-cutover-intended.rsc.
"""
import json
import pathlib
import re
import urllib.request
NAUTOBOT_URL = "http://10.40.20.30:8080"
TOKEN_PATH = pathlib.Path(__file__).parent.parent / "docs" / "nas-vlan20" / "stacks" / "210-nautobot.yml"
OUT = pathlib.Path(__file__).with_name("tp15-core-cutover-intended.rsc")
LEASES_RSC = pathlib.Path(__file__).with_name("ap1-leases-to-core.rsc")
PRIVKEY_PATH = pathlib.Path(__file__).with_name("ap1-wg-hub.privkey")
def get_token():
text = TOKEN_PATH.read_text()
m = re.search(r"^NAUTOBOT_SUPERUSER_API_TOKEN=(.+)$", text, re.MULTILINE)
if not m:
raise SystemExit("NAUTOBOT_SUPERUSER_API_TOKEN not found")
return m.group(1).strip()
def main():
token = get_token()
req = urllib.request.Request(
f"{NAUTOBOT_URL}/api/plugins/golden-config/golden-config/?device=crs326-core",
headers={"Authorization": f"Token {token}", "Accept": "application/json"},
)
with urllib.request.urlopen(req) as resp:
data = json.loads(resp.read().decode())
config = data["results"][0]["intended_config"]
privkey = PRIVKEY_PATH.read_text().strip()
if "<<< AP1_WG_HUB_PRIVKEY >>>" not in config:
raise SystemExit("placeholder missing in intended config")
config = config.replace("<<< AP1_WG_HUB_PRIVKEY >>>", privkey)
leases = LEASES_RSC.read_text()
# Entferne Kommentarblock-Lease-Datei, damit nur Befehle bleiben
lease_lines = [line for line in leases.splitlines() if line and not line.startswith("#")]
# Füge Leases vor dem WG-HUB-Block ein? Oder ans Ende. Ans Ende ist einfacher.
out = config.rstrip() + "\n\n# [9] ap1 static leases -> core (STAGING)" + "\n" + "\n".join(lease_lines) + "\n"
OUT.write_text(out)
print(f"{OUT} written ({len(out)} bytes)")
if __name__ == "__main__":
main()