Add iDRAC Console wall, power control, and proxy embeds.

Operators can power nodes via OME jobs and view multiple live iDRAC
consoles in-panel (4/8 wall) through a same-origin reverse proxy;
Present decks updated for the new remote-ops story.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
root
2026-07-19 00:16:19 +02:00
parent 795707e47b
commit 03e207b46d
9 changed files with 2066 additions and 31 deletions
+68 -16
View File
@@ -32,7 +32,8 @@
<ol class="ps-steps ps-stagger">
<li><strong>Why</strong> — the gap around OME and why AI alone is not enough.</li>
<li><strong>Architecture</strong> — one design: Browser → Cockpit BFF → OME / AI (with logos).</li>
<li><strong>Apps</strong> — map, network, reports, ops desk, copilots.</li>
<li><strong>Apps</strong> — map, network, reports, <em>Console wall</em>, ops desk, copilots.</li>
<li><strong>Remote ops</strong> — power via OME→iDRAC and live consoles in-panel.</li>
<li><strong>People</strong> — who asked, who built, who runs it.</li>
<li><strong>Value</strong> — what customers can take away.</li>
</ol>
@@ -60,10 +61,10 @@
html: `
<div class="ps-grid3">
<div class="ps-card"><h4>One Service Tag story</h4><p>Map, inventory, compliance, warranty, fabric, and tickets around the same ST.</p></div>
<div class="ps-card"><h4>Remote ops in UI</h4><p>Power via OME jobs · live iDRAC Console wall (4/8) without tab sprawl.</p></div>
<div class="ps-card"><h4>AI that cites the fleet</h4><p>Copilot answers from live OME facts — or says it does not know.</p></div>
<div class="ps-card"><h4>Faster briefings</h4><p>Click a chart → named systems → hand off in Ops desk.</p></div>
<div class="ps-card"><h4>Admin ↔ Data FDE</h4><p>Clear roles: ATC admins own the estate; Data FDEs deliver the AI/ops surface.</p></div>
<div class="ps-card"><h4>Demo = daily tool</h4><p>Same stack you present is the stack you can keep using after the meeting.</p></div>
<div class="ps-card"><h4>Copyable pattern</h4><p>OME API + BFF + grounded AI — a blueprint, not a Dell SKU.</p></div>
</div>`,
},
@@ -113,7 +114,7 @@
</div>
<div class="ps-arch-layer apps">
<div class="ps-arch-node app"><strong>Map</strong><span>Topology</span></div>
<div class="ps-arch-node app"><strong>Reports</strong><span>Analytics</span></div>
<div class="ps-arch-node app"><strong>Console</strong><span>iDRAC wall</span></div>
<div class="ps-arch-node app core-app"><strong>Cockpit UI</strong><span>Drawers · KPIs</span></div>
<div class="ps-arch-node app"><strong>Network</strong><span>Fabric · Racks</span></div>
<div class="ps-arch-node app"><strong>Ops / AI</strong><span>Tickets · Copilot</span></div>
@@ -159,13 +160,45 @@
html: `
<div class="ps-apps">
<div class="ps-app"><i></i><strong>Live map</strong><span>Fleet topology · power · inspector</span></div>
<div class="ps-app"><i></i><strong>Console wall</strong><span>4 / 8 live iDRAC embeds · drag</span></div>
<div class="ps-app"><i></i><strong>Network</strong><span>Fabric · 42U racks · VLANs</span></div>
<div class="ps-app"><i></i><strong>Reports</strong><span>Compliance · warranty analytics</span></div>
<div class="ps-app"><i></i><strong>Ops desk</strong><span>Admin ↔ Data FDE tickets</span></div>
<div class="ps-app"><i></i><strong>Copilot</strong><span>Grounded chat on Service Tags</span></div>
<div class="ps-app"><i></i><strong>OpenManage AI</strong><span>Full Open WebUI beside the cockpit</span></div>
</div>
<p class="ps-sub">One join key everywhere: <strong>Service Tag</strong>. No second inventory source.</p>`,
<p class="ps-sub">One join key everywhere: <strong>Service Tag</strong>. Power and console actions ride OME → iDRAC — not a second inventory.</p>`,
},
{
id: "console-wall",
kicker: "Remote ops",
title: "Console wall · many iDRACs, one screen",
anim: "zoom",
html: `
<p class="ps-lead">Operators asked to <strong>see</strong> systems without tab-hopping. The Console tab is a live iDRAC wall: network-aware, draggable, and embedded through Cockpit so browsers are not blocked by <code>X-Frame-Options</code>.</p>
<div class="ps-grid3">
<div class="ps-card"><h4>4 or 8 screens</h4><p>Pick wall size · Small / Medium density · Fullscreen popup per tile.</p></div>
<div class="ps-card"><h4>Drag &amp; + Wall</h4><p>Fleet rail grouped by VLAN · drop onto slots · Auto-fill live BMCs.</p></div>
<div class="ps-card"><h4>Network badges</h4><p>VLAN · subnet · LIVE/OFF on every tile — know where you are looking.</p></div>
<div class="ps-card"><h4>Same-origin proxy</h4><p><code>/api/idrac-proxy/{id}/…</code> strips framing headers · WebSocket bridge for HTML5 console.</p></div>
<div class="ps-card"><h4>Real iDRACs only</h4><p>OOB / BMC endpoints — never bare OS host IPs that cannot speak iDRAC.</p></div>
<div class="ps-card"><h4>Still OME truth</h4><p>Device list and connectivity come from the live fleet snapshot.</p></div>
</div>`,
},
{
id: "power-idrac",
kicker: "Remote ops",
title: "Power on / off · without leaving the map",
anim: "rise",
html: `
<p class="ps-lead">Offline servers with POWER N/A are common in the lab. From Servers KPI, inspector, or Quick Connect you can submit an OME <strong>POWER_CONTROL</strong> job — on, graceful off, or cycle — with confirm for destructive actions.</p>
<div class="ps-seq">
<div class="ps-seq-step"><span>01</span><strong>Select</strong><p>Server / iDRAC on map or KPI list</p></div>
<div class="ps-seq-step"><span>02</span><strong>Power</strong><p>⏻ On · Off · Cycle via OME JobService</p></div>
<div class="ps-seq-step"><span>03</span><strong>Console</strong><p>iDRAC HTML5 in-panel (proxied)</p></div>
<div class="ps-seq-step"><span>04</span><strong>Verify</strong><p>Next fleet poll updates powered state</p></div>
<div class="ps-seq-step"><span>05</span><strong>Escalate</strong><p>Ops desk ticket if change needs a trail</p></div>
</div>
<p class="ps-sub">Demo power with care — production change windows still belong in official OME / iDRAC process.</p>`,
},
{
id: "ai",
@@ -173,13 +206,13 @@
title: "AI that starts from OME facts",
anim: "slide",
html: `
<p class="ps-lead">Ask → Cockpit enriches with live OME context → Open WebUI and/or vLLM → answer → act in map, reports, or Ops.</p>
<p class="ps-lead">Ask → Cockpit enriches with live OME context → Open WebUI and/or vLLM → answer → act in map, reports, Console, or Ops.</p>
<div class="ps-seq">
<div class="ps-seq-step"><span>01</span><strong>Ask</strong><p>Fleet question in Copilot</p></div>
<div class="ps-seq-step"><span>02</span><strong>Enrich</strong><p>BFF attaches Service Tag facts</p></div>
<div class="ps-seq-step"><span>03</span><strong>Route</strong><p>Open WebUI / vLLM completion</p></div>
<div class="ps-seq-step"><span>04</span><strong>Answer</strong><p>Still tied to the live map</p></div>
<div class="ps-seq-step"><span>05</span><strong>Act</strong><p>Inspector · report · ticket</p></div>
<div class="ps-seq-step"><span>05</span><strong>Act</strong><p>Inspector · console · ticket</p></div>
</div>
<p class="ps-sub"><strong>OME for truth · AI for speed · Cockpit for the operator experience.</strong></p>`,
},
@@ -232,6 +265,8 @@
html: `
<ol class="ps-steps ps-stagger">
<li>Pick a Service Tag on the map and open the inspector.</li>
<li>Open <strong>Console</strong> — Auto-fill live iDRACs (4 or 8 screens).</li>
<li>From Servers KPI: Power on a cold node · open iDRAC console in-panel.</li>
<li>Open Reports · Analytics and click a colored segment.</li>
<li>Ask Copilot a question that must cite Service Tags.</li>
<li>Switch to <strong>Technical architecture</strong> for API and trust-boundary depth.</li>
@@ -272,6 +307,7 @@
<li>OME session / cache behaviour</li>
<li>AI completion path</li>
<li>Portal containers &amp; key <code>/api/*</code> contracts</li>
<li>iDRAC proxy · power jobs · Console wall</li>
</ol>
<p class="ps-sub">Delivered for ATC admins Jody &amp; Laurens by Data FDEs Mo &amp; Bart.</p>`,
},
@@ -321,7 +357,7 @@
</div>
<div class="ps-arch-layer apps">
<div class="ps-arch-node app"><strong>Map</strong><span>Topology</span></div>
<div class="ps-arch-node app"><strong>Reports</strong><span>Analytics</span></div>
<div class="ps-arch-node app"><strong>Console</strong><span>iDRAC wall</span></div>
<div class="ps-arch-node app core-app"><strong>Cockpit UI</strong><span>Drawers · KPIs</span></div>
<div class="ps-arch-node app"><strong>Network</strong><span>Fabric · Racks</span></div>
<div class="ps-arch-node app"><strong>Ops / AI</strong><span>Tickets · Copilot</span></div>
@@ -458,13 +494,27 @@
html: `
<div class="ps-grid3">
<div class="ps-card tech"><h4>/api/fleet</h4><p>Cached device graph for canvas &amp; KPIs.</p></div>
<div class="ps-card tech"><h4>/api/devices/…</h4><p>Inventory, landscape, expanded NICs.</p></div>
<div class="ps-card tech"><h4>/api/devices/…/power</h4><p>OME JobService POWER_CONTROL · on / off / cycle.</p></div>
<div class="ps-card tech"><h4>/api/idrac-proxy/…</h4><p>Same-origin HTML + WebSocket bridge · strips XFO.</p></div>
<div class="ps-card tech"><h4>/api/reports/*</h4><p>Analytics, firmware, warranty, brief.</p></div>
<div class="ps-card tech"><h4>/api/chat · /api/models</h4><p>Grounded completions · model list.</p></div>
<div class="ps-card tech"><h4>/api/tickets</h4><p>Ops desk — local SQLite, not OME write-back.</p></div>
<div class="ps-card tech"><h4>/api/network/*</h4><p>Fabric ports · racks · VLANs.</p></div>
</div>`,
},
{
id: "idrac-proxy",
kicker: "Remote console",
title: "Why the iDRAC proxy exists",
anim: "slide",
html: `
<p class="ps-lead">Browsers refuse to iframe most iDRAC UIs (<code>X-Frame-Options: SAMEORIGIN|DENY</code>). Cockpit proxies the session so the Console wall and in-panel viewer stay on <code>:3090</code>.</p>
<div class="ps-grid3">
<div class="ps-card tech"><h4>HTTP reverse proxy</h4><p>Gzip passthrough · cookie Path rewrite · CSP <code>frame-ancestors *</code>.</p></div>
<div class="ps-card tech"><h4>JS bootstrap</h4><p>Patches fetch / XHR / WebSocket so absolute <code>/sysmgmt</code> paths stay on the proxy prefix.</p></div>
<div class="ps-card tech"><h4>SSRF guard</h4><p>Only fleet management IPs · prefers <code>idrac_ip</code> · rejects bare OS hosts.</p></div>
</div>
<p class="ps-sub">Operators still authenticate to iDRAC with their own credentials inside the embed.</p>`,
},
{
id: "trust",
kicker: "Trust &amp; data",
@@ -473,9 +523,10 @@
html: `
<div class="ps-cols">
<div>
<h4>From OME (read)</h4>
<h4>From OME (read + jobs)</h4>
<ul class="ps-bullets ps-stagger">
<li>Devices, power, inventory, warranty, baselines</li>
<li>Devices, power samples, inventory, warranty, baselines</li>
<li>DeviceAction power jobs (on / off / cycle) when operators confirm</li>
</ul>
<h4 style="margin-top:0.85rem">Cockpit-local (write)</h4>
<ul class="ps-bullets ps-stagger">
@@ -486,8 +537,8 @@
<h4>Security notes</h4>
<ul class="ps-bullets ps-stagger">
<li>Secrets only in portal environment variables</li>
<li>Primary OME usage is read for awareness &amp; demos</li>
<li>Production change windows stay in official OME / iDRAC</li>
<li>iDRAC proxy is an ops convenience — credentials stay with the user</li>
<li>Production change windows still belong in official OME / iDRAC process</li>
</ul>
</div>
</div>`,
@@ -500,6 +551,7 @@
html: `
<ol class="ps-steps ps-stagger">
<li>Return to the map and pick a Service Tag.</li>
<li>Open <strong>Console</strong> and drop two iDRACs onto the wall.</li>
<li>Open Reports and click a compliance segment.</li>
<li>Ask Copilot a question that must cite that ST.</li>
<li>Use <strong>Customer story</strong> for business / ops audiences.</li>
@@ -508,13 +560,13 @@
},
];
const BUILTIN_VERSION = 8;
const BUILTIN_VERSION = 9;
const BUILTIN_DECKS = [
{
id: "story",
name: "Customer story",
description: "Customer briefing — ask, architecture, apps, value",
description: "Customer briefing — ask, Console wall, power, architecture, value",
builtin: true,
slides: structuredClone(STORY_SLIDES),
},