# roundtable/core/widgets.py # # Central widget registry. Each entry describes one widget type that can be # placed on a dashboard. Plugin widgets declare which plugin must be enabled. # # "params" is a list of configurable parameters for the widget. Each param: # key - form field name (stored in config_json) # label - human-readable label # type - "select" (only type currently supported) # default - default value (int or str determines how it's parsed from the form) # options - list of {value, label} dicts from __future__ import annotations WIDGET_REGISTRY: dict[str, dict] = { "ping": { "key": "ping", "label": "Ping", "description": "Live ping status and latency history for all monitored hosts", "hx_url": "/ping/rows", "detail_url": "/ping/", "plugin": None, "poll": True, "params": [], }, "uptime_summary": { "key": "uptime_summary", "label": "Uptime / SLA", "description": "Per-host rolling uptime % for 24h, 7d, and 30d windows", "hx_url": "/hosts/uptime/widget", "detail_url": "/hosts/uptime", "plugin": None, "poll": False, "params": [], }, "dns": { "key": "dns", "label": "DNS", "description": "DNS resolution status for all monitored hosts", "hx_url": "/dns/rows", "detail_url": "/dns/", "plugin": None, "poll": True, "params": [], }, "traefik_routers": { "key": "traefik_routers", "label": "Traefik — Routers", "description": "Top routers by request rate with error highlights and expiring certs", "hx_url": "/plugins/traefik/widget", "detail_url": "/plugins/traefik/", "plugin": "traefik", "poll": True, "params": [], }, "traefik_access_log": { "key": "traefik_access_log", "label": "Traefik — Access Log", "description": "Traffic origin summary — top IPs, countries, and request distribution", "hx_url": "/plugins/traefik/widget/access_log", "detail_url": "/plugins/traefik/", "plugin": "traefik", "poll": True, "params": [ { "key": "ip_filter", "label": "IP Filter", "type": "select", "default": "all", "options": [ {"value": "all", "label": "All traffic"}, {"value": "internal", "label": "Internal only"}, {"value": "external", "label": "External only"}, ], }, { "key": "limit", "label": "Top IPs shown", "type": "select", "default": 10, "options": [ {"value": 10, "label": "10 entries"}, {"value": 20, "label": "20 entries"}, {"value": 50, "label": "50 entries"}, ], }, ], }, "traefik_request_chart": { "key": "traefik_request_chart", "label": "Traefik — Request Chart", "description": "Request rate and error percentage over time (Chart.js)", "hx_url": "/plugins/traefik/widget/request_chart", "detail_url": "/plugins/traefik/", "plugin": "traefik", "poll": True, "params": [ { "key": "hours", "label": "Time range", "type": "select", "default": 6, "options": [ {"value": 1, "label": "Last 1 hour"}, {"value": 6, "label": "Last 6 hours"}, {"value": 24, "label": "Last 24 hours"}, ], }, ], }, "unifi_overview": { "key": "unifi_overview", "label": "UniFi — Overview", "description": "WAN status, client counts, offline devices, and active alarms", "hx_url": "/plugins/unifi/widget", "detail_url": "/plugins/unifi/", "plugin": "unifi", "poll": True, "params": [], }, "unifi_clients": { "key": "unifi_clients", "label": "UniFi — Top Clients", "description": "Active wireless and wired clients sorted by bandwidth", "hx_url": "/plugins/unifi/widget/clients", "detail_url": "/plugins/unifi/", "plugin": "unifi", "poll": True, "params": [ { "key": "limit", "label": "Clients shown", "type": "select", "default": 5, "options": [ {"value": 5, "label": "5 clients"}, {"value": 10, "label": "10 clients"}, {"value": 20, "label": "20 clients"}, ], }, ], }, "unifi_devices": { "key": "unifi_devices", "label": "UniFi — Devices", "description": "Network infrastructure devices with online/offline state", "hx_url": "/plugins/unifi/widget/devices", "detail_url": "/plugins/unifi/", "plugin": "unifi", "poll": True, "params": [ { "key": "type_filter", "label": "Device type", "type": "select", "default": "all", "options": [ {"value": "all", "label": "All devices"}, {"value": "wireless", "label": "Wireless APs"}, {"value": "wired", "label": "Wired only"}, {"value": "offline", "label": "Offline devices"}, ], }, ], }, "docker_containers": { "key": "docker_containers", "label": "Docker — Containers", "description": "Container status overview — running/stopped counts and per-container CPU", "hx_url": "/plugins/docker/widget", "detail_url": "/plugins/docker/", "plugin": "docker", "poll": True, "params": [ { "key": "show_stopped", "label": "Show stopped", "type": "select", "default": "no", "options": [ {"value": "no", "label": "Running only"}, {"value": "yes", "label": "All containers"}, ], }, ], }, "http_monitors": { "key": "http_monitors", "label": "HTTP Monitors", "description": "Synthetic endpoint checks — up/down status and response times", "hx_url": "/plugins/http/widget", "detail_url": "/plugins/http/", "plugin": "http", "poll": True, "params": [ { "key": "show_down_only", "label": "Display filter", "type": "select", "default": "no", "options": [ {"value": "no", "label": "All monitors"}, {"value": "yes", "label": "Failing only"}, ], }, { "key": "limit", "label": "Max shown", "type": "select", "default": 10, "options": [ {"value": 5, "label": "5 monitors"}, {"value": 10, "label": "10 monitors"}, {"value": 20, "label": "20 monitors"}, ], }, ], }, "docker_resources": { "key": "docker_resources", "label": "Docker — Resources", "description": "CPU and memory usage bars for running containers", "hx_url": "/plugins/docker/widget/resources", "detail_url": "/plugins/docker/", "plugin": "docker", "poll": True, "params": [ { "key": "limit", "label": "Containers shown", "type": "select", "default": 10, "options": [ {"value": 5, "label": "5 containers"}, {"value": 10, "label": "10 containers"}, {"value": 20, "label": "20 containers"}, ], }, ], }, "snmp_devices": { "key": "snmp_devices", "label": "SNMP — Devices", "description": "Latest OID readings for all configured SNMP devices", "hx_url": "/plugins/snmp/widget", "detail_url": "/plugins/snmp/", "plugin": "snmp", "poll": True, "params": [], }, "host_resources": { "key": "host_resources", "label": "Host Agent — Resources", "description": "Fleet view: CPU, memory, disk, and load per monitored host", "hx_url": "/plugins/host_agent/widget", "detail_url": "/plugins/host_agent/settings/", "plugin": "host_agent", "poll": True, "params": [], }, "host_resource_history": { "key": "host_resource_history", "label": "Host Agent — History", "description": "CPU/memory/disk history for one host", "hx_url": "/plugins/host_agent/widget/history", "detail_url": "/plugins/host_agent/settings/", "plugin": "host_agent", "poll": True, "params": [ { "key": "hours", "label": "Time range", "type": "select", "default": 6, "options": [ {"value": 1, "label": "Last 1 hour"}, {"value": 6, "label": "Last 6 hours"}, {"value": 24, "label": "Last 24 hours"}, ], }, ], }, } def register_widget(definition: dict) -> None: """Register a widget at runtime (used by external plugins).""" WIDGET_REGISTRY[definition["key"]] = definition def get_available_widgets(plugins_cfg: dict) -> list[dict]: """Return widgets whose plugin dependency is satisfied.""" result = [] for w in WIDGET_REGISTRY.values(): if w["plugin"] is None: result.append(w) elif plugins_cfg.get(w["plugin"], {}).get("enabled", False): result.append(w) return result