feat: add fetchHostInfo and renderInfoSection JS functions
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -514,6 +514,9 @@
|
|||||||
// pluginCache[hostname][pluginName] = { data, timestamp, fetchedAt }
|
// pluginCache[hostname][pluginName] = { data, timestamp, fetchedAt }
|
||||||
const pluginCache = {};
|
const pluginCache = {};
|
||||||
|
|
||||||
|
// infoCache[hostname] = info data object from /api/0/hosts/{hostname}/info
|
||||||
|
const infoCache = {};
|
||||||
|
|
||||||
function setCache(hostname, pluginName, sample) {
|
function setCache(hostname, pluginName, sample) {
|
||||||
if (!pluginCache[hostname]) pluginCache[hostname] = {};
|
if (!pluginCache[hostname]) pluginCache[hostname] = {};
|
||||||
pluginCache[hostname][pluginName] = {
|
pluginCache[hostname][pluginName] = {
|
||||||
@@ -547,6 +550,57 @@
|
|||||||
return json.samples?.[0] ?? null;
|
return json.samples?.[0] ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function fetchHostInfo(hostname) {
|
||||||
|
const r = await fetch(`/api/0/hosts/${encodeURIComponent(hostname)}/info`);
|
||||||
|
if (!r.ok) throw new Error(`HTTP ${r.status}`);
|
||||||
|
return await r.json();
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderInfoSection(hostname, data) {
|
||||||
|
const el = document.getElementById(`info-${hostname}`);
|
||||||
|
if (!el) return;
|
||||||
|
|
||||||
|
const owner = data.owner ? escHtml(data.owner) : '—';
|
||||||
|
const managers = data.managers && data.managers.length
|
||||||
|
? data.managers.map(escHtml).join(', ') : '—';
|
||||||
|
const hbcVer = data.hbc_version ? escHtml(String(data.hbc_version)) : '—';
|
||||||
|
const hbcType = data.hbc_type ? escHtml(String(data.hbc_type)) : '—';
|
||||||
|
const lastPkt = data.last_packet != null
|
||||||
|
? new Date(data.last_packet * 1000).toLocaleString() : '—';
|
||||||
|
|
||||||
|
let html = `<div class="info-meta">
|
||||||
|
<span class="info-label">Owner</span><span class="info-value">${owner}</span>
|
||||||
|
<span class="info-label">Managers</span><span class="info-value">${managers}</span>
|
||||||
|
<span class="info-label">Agent Version</span><span class="info-value">${hbcVer}</span>
|
||||||
|
<span class="info-label">Agent Type</span><span class="info-value">${hbcType}</span>
|
||||||
|
<span class="info-label">Last Packet</span><span class="info-value">${lastPkt}</span>
|
||||||
|
</div>`;
|
||||||
|
|
||||||
|
if (data.thresholds === null) {
|
||||||
|
html += `<div class="info-note">Threshold alerting not configured.</div>`;
|
||||||
|
} else if (data.thresholds.length === 0) {
|
||||||
|
html += `<div class="info-note">No thresholds defined.</div>`;
|
||||||
|
} else {
|
||||||
|
html += `<div class="info-thresholds-title">Effective Thresholds</div>
|
||||||
|
<table class="data-table"><thead><tr>
|
||||||
|
<th>Metric</th><th>Op</th><th>Warning</th><th>Critical</th>
|
||||||
|
</tr></thead><tbody>`;
|
||||||
|
for (const t of data.thresholds) {
|
||||||
|
const w = t.warning != null ? escHtml(String(t.warning)) : '—';
|
||||||
|
const c = t.critical != null ? escHtml(String(t.critical)) : '—';
|
||||||
|
html += `<tr>
|
||||||
|
<td class="key">${escHtml(t.metric)}</td>
|
||||||
|
<td>${escHtml(t.operator)}</td>
|
||||||
|
<td>${w}</td>
|
||||||
|
<td>${c}</td>
|
||||||
|
</tr>`;
|
||||||
|
}
|
||||||
|
html += `</tbody></table>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
el.innerHTML = html;
|
||||||
|
}
|
||||||
|
|
||||||
async function fetchHostGlance(hostname) {
|
async function fetchHostGlance(hostname) {
|
||||||
const card = document.querySelector(`.host-card[data-hostname="${hostname}"]`);
|
const card = document.querySelector(`.host-card[data-hostname="${hostname}"]`);
|
||||||
const availablePlugins = (card?.dataset.plugins || '').split(',').filter(Boolean);
|
const availablePlugins = (card?.dataset.plugins || '').split(',').filter(Boolean);
|
||||||
|
|||||||
Reference in New Issue
Block a user