Files
inventory/collectors/orchestrator.py
Nathan Woodburn 0ce79935d7
All checks were successful
Check Code Quality / RuffCheck (push) Successful in 1m4s
Build Docker / BuildImage (push) Successful in 1m26s
feat: Initial code
2026-03-26 23:07:05 +11:00

74 lines
2.4 KiB
Python

import threading
from dataclasses import dataclass
from typing import Dict, List
from config import AppConfig
from database import InventoryStore
from .base import CollectionResult
from .coolify import CoolifyCollector
from .docker_hosts import DockerHostsCollector
from .nginx_from_agent import NginxFromAgentCollector
from .proxmox import ProxmoxCollector
@dataclass
class RunReport:
run_id: int
status: str
results: List[CollectionResult]
class InventoryCollectorOrchestrator:
def __init__(self, config: AppConfig, store: InventoryStore):
self.config = config
self.store = store
self._run_lock = threading.Lock()
self.collectors = [
ProxmoxCollector(config),
DockerHostsCollector(config),
CoolifyCollector(config),
NginxFromAgentCollector(config),
]
self.store.seed_sources(
{
"proxmox": config.proxmox_enabled,
"docker": config.docker_enabled,
"coolify": config.coolify_enabled,
"nginx": bool(config.docker_agent_endpoints),
}
)
def collect_once(self) -> RunReport:
if not self._run_lock.acquire(blocking=False):
return RunReport(run_id=-1, status="running", results=[])
try:
run_id = self.store.run_start()
results: List[CollectionResult] = []
errors: List[str] = []
for collector in self.collectors:
result = collector.collect()
results.append(result)
self.store.set_source_status(result.source, result.status, result.error)
if result.assets:
self.store.upsert_assets(result.source, result.assets)
if result.status == "error":
errors.append(f"{result.source}: {result.error}")
overall_status = "error" if errors else "ok"
self.store.run_finish(run_id=run_id, status=overall_status, error_summary=" | ".join(errors))
return RunReport(run_id=run_id, status=overall_status, results=results)
finally:
self._run_lock.release()
def current_data(self) -> Dict:
return {
"summary": self.store.summary(),
"topology": self.store.topology(),
"assets": self.store.list_assets(),
"sources": self.store.source_health(),
"last_run": self.store.last_run(),
}