"""Nginx state collector.""" from copy import deepcopy from typing import Any from lib import schema from lib.common import compute_pending, strip_apply_meta from lib.nginx import DEFAULT_CONFIG, SITES_DIR, _resolve_paths, get_config from lib.state import _now_iso, register_collector def _collect_nginx() -> schema.NginxState: """Collect nginx config and domains list. Returns: Dict containing config, domains, and timestamp. """ # Load config via lib.nginx — a pure read that applies the legacy-format # migration in memory (the one-shot on-disk migration runs at daemon # startup, see lib.bootstrap). try: cfg = get_config() except Exception: cfg = deepcopy(DEFAULT_CONFIG) # Build flattened domains list (one entry per path) backends = cfg.get("backends", {}) domains: list[dict[str, Any]] = [] for name, dom in cfg.get("domains", {}).items(): if "backend" not in dom: continue site = SITES_DIR / f"{name}.conf" paths = _resolve_paths(dom, backends) if not paths: continue for ppath, pcfg in paths.items(): entry: dict[str, Any] = { "domain": name, "path": ppath, "backend": pcfg.get("backend", {}), "online": site.exists() if SITES_DIR.exists() else False, "force_ssl": dom.get("force_ssl", True), "backend_name": dom["backend"], "cert": dom.get("cert"), } if pcfg.get("is_management"): entry["is_management"] = True if pcfg.get("is_websocket"): entry["is_websocket"] = True domains.append(entry) pending_changes, nginx_pending_diff = compute_pending(cfg) safe_cfg = strip_apply_meta(cfg) return { "config": safe_cfg, "domains": domains, "status": { "pending_changes": pending_changes, "pending_diff": nginx_pending_diff, }, "timestamp": _now_iso(), } register_collector("nginx", _collect_nginx)