docs: add design spec for host overview info section
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,135 @@
|
|||||||
|
# Host Overview Info Section
|
||||||
|
|
||||||
|
**Date:** 2026-05-10
|
||||||
|
**Status:** Approved
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
Add an always-visible info section to each host card on the Host Overview (`/plugins`) page. The section shows owner, managers, agent version/type, last packet timestamp, and the host's effective alert thresholds. The fields `hbc_version` and `hbc_type` are moved out of the `os_info` plugin accordion into this section.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Backend: New API Endpoint
|
||||||
|
|
||||||
|
**Route:** `GET /api/0/hosts/{hostname}/info`
|
||||||
|
|
||||||
|
**Auth:** Same as other per-host endpoints (`_can_view_host`).
|
||||||
|
|
||||||
|
**Response schema:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"owner": "alice",
|
||||||
|
"managers": ["bob", "carol"],
|
||||||
|
"hbc_version": "5.3.0",
|
||||||
|
"hbc_type": "full",
|
||||||
|
"last_packet": 1746894000.0,
|
||||||
|
"thresholds": [
|
||||||
|
{
|
||||||
|
"metric": "cpu_monitor.cpu_percent",
|
||||||
|
"warning": 80.0,
|
||||||
|
"critical": 95.0,
|
||||||
|
"operator": ">"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Field details:**
|
||||||
|
|
||||||
|
- `owner` — `host.owner`, or `null` if unset.
|
||||||
|
- `managers` — `host.managers` list (may be empty).
|
||||||
|
- `hbc_version` — from `host.get_latest_plugin_data("os_info")`, key `hbc_version`; `null` if no os_info data.
|
||||||
|
- `hbc_type` — same source, key `hbc_type`; `null` if unavailable.
|
||||||
|
- `last_packet` — `max(conn.lastbeat for conn in host.connections.values())`, or `null` if no connections.
|
||||||
|
- `thresholds` — list derived from `threshold_checker.get_thresholds_for_host(hostname)`, sorted by `metric` ascending. Each entry includes `metric`, `warning` (null if unset), `critical` (null if unset), `operator`. Returns `null` (not `[]`) if no `threshold_checker` is configured, so the frontend can distinguish "not configured" from "configured but empty".
|
||||||
|
|
||||||
|
**Location:** `hbd/server/http.py`, added alongside the other `api_host_*` functions. Registered as `web.get("/api/0/hosts/{hostname}/info", api_host_info)`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Frontend: Info Section
|
||||||
|
|
||||||
|
### HTML structure
|
||||||
|
|
||||||
|
Inserted as the first child of `.host-body`, before the plugin accordions. It is not a collapsible accordion — it is always visible when the host card is expanded.
|
||||||
|
|
||||||
|
```html
|
||||||
|
<div class="host-info-section" id="info-{hostname}">
|
||||||
|
<div class="loading">Loading…</div>
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Fetch lifecycle
|
||||||
|
|
||||||
|
- Fetched once per host on the first expansion of the host card (same trigger as the glance/plugin data).
|
||||||
|
- Result cached in a new per-host `infoCache` object (parallel to `pluginCache`).
|
||||||
|
- On subsequent expansions the cached data is rendered immediately without a new request.
|
||||||
|
|
||||||
|
### Rendered layout
|
||||||
|
|
||||||
|
Two logical areas rendered client-side from the JSON:
|
||||||
|
|
||||||
|
**Meta row** — a CSS-grid or simple `<dl>` showing:
|
||||||
|
|
||||||
|
| Label | Value |
|
||||||
|
|---------------|------------------------------|
|
||||||
|
| Owner | alice (or "—" if null) |
|
||||||
|
| Managers | bob, carol (or "—" if empty) |
|
||||||
|
| Agent Version | 5.3.0 (or "—") |
|
||||||
|
| Agent Type | full (or "—") |
|
||||||
|
| Last Packet | localized datetime string (or "—") |
|
||||||
|
|
||||||
|
**Threshold table** — rendered with the existing `data-table` CSS class:
|
||||||
|
|
||||||
|
| Metric | Operator | Warning | Critical |
|
||||||
|
|--------|----------|---------|----------|
|
||||||
|
| cpu_monitor.cpu_percent | > | 80 | 95 |
|
||||||
|
| … | … | … | … |
|
||||||
|
|
||||||
|
- If `thresholds` is `null`: show "Threshold alerting not configured."
|
||||||
|
- If `thresholds` is `[]`: show "No thresholds defined."
|
||||||
|
- Numeric threshold values rendered as-is (no units); `null` warning/critical shown as "—".
|
||||||
|
|
||||||
|
### CSS
|
||||||
|
|
||||||
|
New `.host-info-section` styles added in the `<style>` block of `plugins.html`. The section gets a subtle background (e.g. `#fafafa`) and a bottom border to separate it visually from the plugin accordions below. The meta row uses a two-column grid layout for compactness.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Changes to `renderOsInfoTable()`
|
||||||
|
|
||||||
|
- Remove `hbc_version` from the `ORDER` array.
|
||||||
|
- Add `hbc_type` to the `SKIP_FIELDS` set (or the local `shown` set) so it is excluded from the os_info table.
|
||||||
|
|
||||||
|
Both fields will now appear only in the info section.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Data Flow Summary
|
||||||
|
|
||||||
|
```
|
||||||
|
User expands host card
|
||||||
|
→ toggleHost()
|
||||||
|
→ fetchGlanceData(hostname) [existing, unchanged]
|
||||||
|
→ fetchInfoData(hostname) [new]
|
||||||
|
GET /api/0/hosts/{hostname}/info
|
||||||
|
→ renderInfoSection(hostname, data)
|
||||||
|
→ writes into #info-{hostname}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Error Handling
|
||||||
|
|
||||||
|
- If the info fetch fails (non-200), show a one-line error message in the info section ("Could not load host info.").
|
||||||
|
- If `hbc_version`/`hbc_type` are null (host has never sent os_info), display "—".
|
||||||
|
- If `last_packet` is null (no connections recorded), display "—".
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Out of Scope
|
||||||
|
|
||||||
|
- Editing owner/managers from this section (covered by existing profile/access UI).
|
||||||
|
- Editing thresholds from this section.
|
||||||
|
- Monitors list (not shown — monitors are operational, not informational in this context).
|
||||||
Reference in New Issue
Block a user