Add infra-tool: infrastructure registry with Incus container deployment
Service registry & discovery system that aggregates infrastructure metadata from Incus, K8s, APISIX, and BunnyCDN into NocoDB. Includes FastAPI HTTP API, systemd timer for 15-min auto-sync, and dual-mode collectors (REST API for container deployment, CLI/SSH fallback for local use). Deployed to jp1:infra-tool with Tailscale socket proxy for host network visibility. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
64
collectors/bunnycdn.py
Normal file
64
collectors/bunnycdn.py
Normal file
@@ -0,0 +1,64 @@
|
||||
"""Collect BunnyCDN pull zones via REST API."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from datetime import datetime, timezone
|
||||
|
||||
import requests
|
||||
|
||||
import config
|
||||
|
||||
|
||||
def _get(path: str) -> list | dict:
|
||||
url = f"https://api.bunny.net{path}"
|
||||
resp = requests.get(url, headers={"AccessKey": config.bunny_api_key()})
|
||||
resp.raise_for_status()
|
||||
return resp.json()
|
||||
|
||||
|
||||
def collect_zones() -> list[dict]:
|
||||
"""Return list of CDN zone records for NocoDB infra_cdn_zones."""
|
||||
zones = _get("/pullzone")
|
||||
now = datetime.now(timezone.utc).isoformat()
|
||||
results = []
|
||||
|
||||
for z in zones:
|
||||
name = z.get("Name", "")
|
||||
zone_id = z.get("Id", 0)
|
||||
origin = z.get("OriginUrl", "")
|
||||
hostnames = [h.get("Value", "") for h in z.get("Hostnames", [])]
|
||||
|
||||
results.append({
|
||||
"Title": name,
|
||||
"zone_id": zone_id,
|
||||
"origin_url": origin,
|
||||
"hostnames": json.dumps(hostnames),
|
||||
"last_synced": now,
|
||||
})
|
||||
return results
|
||||
|
||||
|
||||
def collect_services() -> list[dict]:
|
||||
"""Derive infra_services entries from BunnyCDN zones (cdn layer)."""
|
||||
zones = collect_zones()
|
||||
now = datetime.now(timezone.utc).isoformat()
|
||||
services = []
|
||||
|
||||
for z in zones:
|
||||
hostnames = json.loads(z["hostnames"]) if z["hostnames"] else []
|
||||
for hostname in hostnames:
|
||||
if not hostname or hostname.endswith(".b-cdn.net"):
|
||||
continue
|
||||
services.append({
|
||||
"Title": f"cdn:{hostname}",
|
||||
"display_name": f"CDN {z['Title']}",
|
||||
"domain": hostname,
|
||||
"source": "bunnycdn",
|
||||
"layer": "cdn",
|
||||
"status": "up",
|
||||
"upstream_ip": z["origin_url"],
|
||||
"cluster": "bunnycdn",
|
||||
"last_seen": now,
|
||||
})
|
||||
return services
|
||||
Reference in New Issue
Block a user