MCPcopy Create free account
hub / github.com/PierreGode/Ragnar / performUpdate

Function performUpdate

web/scripts/ragnar_modern.js:7716–7761  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

7714 if (!d || d.success === false) {
7715 const msg = (d && d.error) || 'failed';
7716 let extra = '';
7717 if (d && d.missing_tool) extra = ' <button onclick="installNetTool(\'tcpdump\', this, runOspfWatch)" class="ml-2 underline text-cyan-400">Install tcpdump</button>';
7718 out.innerHTML = '<p class="text-sm text-red-400">Error: ' + escapeHtml(msg) + extra + '</p>';
7719 return;
7720 }
7721 const [cls, label] = _OSPF_VERDICT_STYLE[d.verdict] || _OSPF_VERDICT_STYLE.unknown;
7722 let html = `<div class="mb-2 px-3 py-2 rounded border ${cls} text-sm">${label}</div>`;
7723 html += `<p class="text-xs text-gray-500 mb-2">Interface: ${escapeHtml(d.interface || '—')} · ${d.seconds}s · ${d.packets} OSPF pkts (${d.hellos} hello, ${d.ls_updates} LSU @ ${d.lsu_per_s}/s)${d.learned ? ' · <span class="text-gray-400">baseline learned now</span>' : ''}</p>`;
7724 if (d.note) html += `<p class="text-xs text-gray-500 mb-2">${escapeHtml(d.note)}</p>`;
7725 const auth = (d.auth_types || []).map(a => _OSPF_AUTH_NAME[a] || a);
7726 if (auth.length) {
7727 const bad = (d.auth_types || []).some(a => a < 2);
7728 html += `<p class="text-xs mb-1 ${bad ? 'text-amber-300' : 'text-gray-400'}">Authentication: ${escapeHtml(auth.join(', '))}${bad ? ' — no cryptographic auth' : ''}</p>`;
7729 }
7730 // Advisories (CVE / OSV)
7731 (d.advisories || []).forEach(a => {
7732 const sev = a.severity === 'high' ? 'text-red-300 border-red-800 bg-red-950/40' : 'text-amber-300 border-amber-800 bg-amber-950/30';
7733 const refs = (a.refs || []).map(r => r.startsWith('http')
7734 ? `<a href="${escapeHtml(r)}" target="_blank" rel="noopener" class="underline text-cyan-400">OSV</a>`
7735 : `<span class="font-mono">${escapeHtml(r)}</span>`).join(', ');
7736 html += `<div class="mt-2 px-3 py-2 rounded border text-xs ${sev}"><strong>${escapeHtml(a.title)}</strong><br>${escapeHtml(a.detail)}${refs ? '<br><span class="text-gray-400">Refs:</span> ' + refs : ''}</div>`;
7737 });
7738 // Routers table
7739 const routers = d.routers || [], tr = d.trusted_routers || [];
7740 if (routers.length) {
7741 html += '<p class="text-xs uppercase text-gray-400 mt-2 mb-1">OSPF routers seen (' + routers.length + ')</p>' +
7742 '<table class="min-w-full text-xs text-gray-300 whitespace-nowrap"><thead>' +
7743 '<tr class="text-left text-gray-500"><th class="px-2 py-1">Router-ID</th><th class="px-2 py-1">Source(s)</th><th class="px-2 py-1">Status</th></tr>' +
7744 '</thead><tbody>' +
7745 routers.map(r => {
7746 const badge = r.new ? '<span class="text-amber-300">? new</span>' : (tr.indexOf(r.router_id) >= 0 ? '<span class="text-green-400">✓ known</span>' : '<span class="text-gray-500">—</span>');
7747 return `<tr class="border-t border-slate-800">
7748 <td class="px-2 py-1 font-mono ${r.new ? 'text-amber-300' : ''}">${escapeHtml(r.router_id)}</td>
7749 <td class="px-2 py-1 font-mono text-gray-400">${escapeHtml((r.sources || []).join(', ') || '—')}</td>
7750 <td class="px-2 py-1">${badge}</td>
7751 </tr>`;
7752 }).join('') +
7753 '</tbody></table>';
7754 }
7755 const lc = d.lsa_counts || {};
7756 const lcKeys = Object.keys(lc);
7757 if (lcKeys.length) {
7758 html += '<p class="text-xs text-gray-500 mt-2">LSAs: ' + lcKeys.map(k => `${escapeHtml(k)}×${lc[k]}`).join(', ') + '</p>';
7759 }
7760 if (d.reasons && d.reasons.length) {
7761 html += '<ul class="text-xs text-gray-400 mt-2 list-disc pl-5">' +
7762 d.reasons.map(r => '<li>' + escapeHtml(r) + '</li>').join('') + '</ul>';
7763 }
7764 out.innerHTML = html;

Callers

nothing calls this directly

Calls 6

errorMethod · 0.80
addConsoleMessageFunction · 0.70
updateElementFunction · 0.70
postAPIFunction · 0.70
verifyServiceRestartFunction · 0.70

Tested by

no test coverage detected