Dateien nach "app" hochladen
This commit is contained in:
+108
@@ -0,0 +1,108 @@
|
||||
"""Sync-Logik: liest Subnetze + Adressen aus phpipam und schreibt sie als
|
||||
ein Outline-Dokument pro Subnetz."""
|
||||
from __future__ import annotations
|
||||
|
||||
from .config import settings
|
||||
from .outline_client import OutlineClient
|
||||
from .phpipam_client import PhpIpamClient
|
||||
|
||||
|
||||
def _subnet_title(subnet: dict) -> str:
|
||||
cidr = f"{subnet.get('subnet')}/{subnet.get('mask')}"
|
||||
desc = subnet.get("description") or ""
|
||||
return f"{cidr} – {desc}".rstrip(" –") if desc else cidr
|
||||
|
||||
|
||||
def _subnet_markdown(subnet: dict, addresses: list[dict], section_name: str | None) -> str:
|
||||
cidr = f"{subnet.get('subnet')}/{subnet.get('mask')}"
|
||||
lines: list[str] = []
|
||||
lines.append(f"# {cidr}")
|
||||
lines.append("")
|
||||
lines.append(f"- **Beschreibung:** {subnet.get('description') or '–'}")
|
||||
if section_name:
|
||||
lines.append(f"- **Section:** {section_name}")
|
||||
if subnet.get("vlanId") and subnet.get("vlanId") != "0":
|
||||
lines.append(f"- **VLAN-ID:** {subnet.get('vlanId')}")
|
||||
if subnet.get("location"):
|
||||
lines.append(f"- **Standort:** {subnet.get('location')}")
|
||||
lines.append("")
|
||||
|
||||
if not addresses:
|
||||
lines.append("_Keine belegten Adressen in phpipam hinterlegt._")
|
||||
return "\n".join(lines)
|
||||
|
||||
lines.append("| IP | Hostname | Beschreibung | MAC | Owner |")
|
||||
lines.append("|---|---|---|---|---|")
|
||||
for addr in sorted(addresses, key=lambda a: tuple(int(o) for o in a["ip"].split("."))):
|
||||
lines.append(
|
||||
"| {ip} | {hostname} | {desc} | {mac} | {owner} |".format(
|
||||
ip=addr.get("ip", ""),
|
||||
hostname=addr.get("hostname") or "",
|
||||
desc=(addr.get("description") or "").replace("\n", " "),
|
||||
mac=addr.get("mac") or "",
|
||||
owner=addr.get("owner") or "",
|
||||
)
|
||||
)
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
def run_sync(dry_run: bool | None = None) -> list[dict]:
|
||||
"""Führt den Sync durch. Gibt eine Liste von Ergebnis-Infos je Subnetz zurück."""
|
||||
dry_run = settings.sync_dry_run if dry_run is None else dry_run
|
||||
results: list[dict] = []
|
||||
section_cache: dict[str, str | None] = {}
|
||||
|
||||
with PhpIpamClient() as ipam:
|
||||
subnets = ipam.list_subnets()
|
||||
|
||||
outline = None if dry_run else OutlineClient()
|
||||
collection_id = settings.outline_collection_id
|
||||
parent_document_id = settings.outline_parent_document_id
|
||||
try:
|
||||
if outline is not None:
|
||||
collection_id = outline.resolve_collection_id(settings.outline_collection_id)
|
||||
if parent_document_id:
|
||||
parent_document_id = outline.resolve_document_id(parent_document_id)
|
||||
|
||||
for subnet in subnets:
|
||||
section_id = subnet.get("sectionId")
|
||||
if section_id not in section_cache:
|
||||
section_cache[section_id] = ipam.get_section_name(section_id) if section_id else None
|
||||
section_name = section_cache.get(section_id)
|
||||
|
||||
addresses = ipam.list_addresses(subnet["id"])
|
||||
title = _subnet_title(subnet)
|
||||
text = _subnet_markdown(subnet, addresses, section_name)
|
||||
|
||||
if dry_run:
|
||||
results.append(
|
||||
{
|
||||
"subnet_id": subnet["id"],
|
||||
"title": title,
|
||||
"address_count": len(addresses),
|
||||
"action": "dry-run",
|
||||
}
|
||||
)
|
||||
continue
|
||||
|
||||
doc, created = outline.upsert_document( # type: ignore[union-attr]
|
||||
title,
|
||||
text,
|
||||
collection_id,
|
||||
parent_document_id,
|
||||
)
|
||||
results.append(
|
||||
{
|
||||
"subnet_id": subnet["id"],
|
||||
"title": title,
|
||||
"address_count": len(addresses),
|
||||
"action": "created" if created else "updated",
|
||||
"outline_document_id": doc.get("id"),
|
||||
"outline_url": doc.get("url"),
|
||||
}
|
||||
)
|
||||
finally:
|
||||
if outline is not None:
|
||||
outline.close()
|
||||
|
||||
return results
|
||||
Reference in New Issue
Block a user