Dateien nach "app" hochladen

This commit is contained in:
2026-07-24 08:38:28 +00:00
parent a4e7bf0ce2
commit 8444296198
7 changed files with 459 additions and 0 deletions
+108
View File
@@ -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