Commit Graph

6504 Commits

Author SHA1 Message Date
rcourtman 68dbaf5102 Humanize vSphere Networks Type column
vCenter exposes the network type as a raw enum: STANDARD_PORTGROUP,
DISTRIBUTED_PORTGROUP, OPAQUE_NETWORK. The Datastores table shows
raw enums too (NFS41 / VMFS / vSAN) but those are recognizable
shorthand every vSphere operator already speaks; the network
enums are not, and rendering them as-is reads as API exhaust.

Map the three known values to the names vCenter uses in its own
UI:

  STANDARD_PORTGROUP    -> Standard port group
  DISTRIBUTED_PORTGROUP -> vDS port group
  OPAQUE_NETWORK        -> NSX network

Unknown future enum values fall back to the raw string rather
than getting silently dropped or guessed.
2026-05-23 16:07:14 +01:00
rcourtman a57217b194 Add Version + Uptime columns to vSphere Hosts table
VsphereHostsTable was missing the Version (ESXi build) and Uptime
columns that Proxmox / Docker / Kubernetes / TrueNAS host
equivalents carry. The data was already piped through the
canonical projection — ESXi version on resource.agent.osVersion
(e.g. "8.0.3"), host uptime on resource.uptime (lifted from
InventoryMetrics.UptimeSeconds via the sys.uptime.latest
PerformanceManager counter wired in 23ea4e487 this morning) —
the table just didn't render columns for them.

VsphereHostsTable now renders Version and Uptime cells, ordered
Version-adjacent-to-Host and Uptime before vCenter to mirror the
Proxmox Nodes layout. Column widths trimmed to fit. Uptime uses
the shared formatUptime util in condensed form (e.g. "163d")
with the full label as the cell title attribute. Detail row
colspan bumps 9 to 11 to keep the drawer spanning the full row.

Plumbing the canonical Resource.Uptime through to the frontend
required two fallback extensions surfaced by the column audit:

- useUnifiedResources.ts toResource: the uptime fallback chain
  ended on platform-specific carve-outs (agent.uptimeSeconds,
  proxmox.uptime, pbs/pmg/kubernetes); vSphere populates only
  the canonical Resource.Uptime, so the chain has to land on
  v2.uptime. Same shape as the workloads-hook fix in e5b31f484.
- internal/monitoring/monitor.go monitorUptime: the websocket
  broadcast converter walked the same platform-specific chain
  and silently dropped vSphere host/VM uptime, then merge-
  clobbered the REST-loaded value once WS reconnect replayed
  the broadcast. Add the canonical resource.Uptime fallback so
  the broadcast payload carries uptime for VMware-backed rows
  consistently with the REST contract. Carve-outs still take
  precedence so existing platforms keep prior behavior.

Verified: vSphere overview Hosts table now renders esxi-01..07
with Version 8.0.3 and Uptime 147d-167d cells. No regression in
Proxmox / Docker / Kubernetes / TrueNAS uptime paths.

Contracts:
- monitoring.md documents the canonical Resource.Uptime fallback
  in monitorUptime and the carve-out precedence.
- unified-resources.md adds the same canonical-uptime fallback
  rule to the toResource consumer-side contract.
- storage-recovery.md amends rule 29 to call out that the
  canonical Resource.Uptime fallback is descriptive host/VM
  uptime only and must not be reinterpreted as backup recency
  or recovery cadence.

Proofs:
- internal/monitoring/canonical_guardrails_test.go locks the
  monitorUptime fallback contract: canonical Resource.Uptime is
  surfaced when no carve-out is set, carve-outs take precedence,
  nil when nothing populates.
- frontend-modern/src/hooks/__tests__/useUnifiedResources.test.ts
  asserts the toResource v2.uptime fallback for a vSphere-shaped
  payload with no platform-specific uptime carve-out.
2026-05-23 15:11:49 +01:00
rcourtman e5b31f4843 Light up guest OS column for Proxmox and vSphere workloads
useWorkloads.ts mapped guest OS info exclusively from
resource.agent.osName / agent.osVersion. Proxmox's resource
adapter populates resource.proxmox.osName / osVersion from
qemu-guest-agent's os-info readout (today: 25 of 45 mock VMs).
vSphere's adapter exposes guest OS family on
resource.vmware.guestOsFamily. Both fields were ignored by the
mapping, so the workload table's OS column rendered as blank on
every VM despite the data being right there in the API
response.

Extend the fallback chain:
  agent.osName ?? proxmox.osName ?? vmware.guestOsFamily
  agent.osVersion ?? proxmox.osVersion

Behavior change is additive: guests that already lit up the
column via agent.osName keep working unchanged; Proxmox VMs with
guest-agent reporting now show "Windows Server" / "Ubuntu" /
etc and vSphere VMs show the coarse "LINUX" / "WINDOWS" family.
The OS column stays hidden by default everywhere (its default
visibility belongs to the global workloads-controls hidden list,
not to this mapping), but when a user toggles it on from the
Columns menu it actually has data to show.

Surfaced by the cross-platform column audit (cf 24/05 session
log). The two corresponding platform-specific shape extensions
on APIResource (proxmox.{osName,osVersion},
vmware.guestOsFamily) document fields that the backend was
already shipping; this commit just teaches the typing and the
mapping to read them.
2026-05-23 14:13:11 +01:00
rcourtman d929ac6477 Hide Backup column on non-Proxmox workload surfaces
The workload table's Backup column reads exclusively from
resource.proxmox.lastBackup (useWorkloads.ts line 486), which
Proxmox VE populates from its built-in vzdump scheduler / PBS
integration. No other adapter populates a backup field — vCenter
has no native backup concept (third-party tools like Veeam own
that), Docker / Podman / Kubernetes don't expose a workload-row
"last backup" either. So the column rendered a permanently blank
cell on every platform except Proxmox.

This is structurally different from the earlier (wrong) instinct
to hide DISK and Uptime on vSphere: those had real upstream
sources (guest filesystem REST + PerformanceManager uptime
counters) that were properly fixed by extending the backend
adapter. Backup has no upstream source at this integration layer,
so hiding it is the canonical product call rather than a
stopgap.

Hide by default on:
- vSphere via VMWARE_WORKLOAD_DEFAULT_HIDDEN_COLUMN_IDS in
  VmwarePageSurface.tsx
- Kubernetes via additionalDefaultHiddenColumnIds in
  KubernetesPageSurface.tsx
- Docker / Podman / TrueNAS apps via the shared
  APP_CONTAINER_BASE_DEFAULT_HIDDEN_COLUMNS constant in
  appContainerColumns.ts (Docker test list updated to match)

Proxmox keeps Backup visible by default since that's the only
platform whose adapter populates the underlying field. Users on
any platform can still toggle the column back on from the
Columns menu.
2026-05-23 13:43:56 +01:00
rcourtman 973cdab880 Track vSphere uptime + guest disk on phase-1 proof matrix
The vSphere VM uptime + guest filesystem usage support added in
23ea4e487 extended the live-vCenter validation surface without
landing on the canonical phase-1 proof checklist. Lock the new
code paths there so the next real-environment pass exercises them
on the same checklist that already gates the support claim.

VMWARE_VCENTER_PHASE1_PROOF_MATRIX.md:
- New VC-8 "Operational metric surface" scenario covering
  sys.uptime / sys.osUptime PerformanceManager counters, the
  /api/vcenter/vm/{vm}/guest/local-filesystem REST endpoint, the
  canonical Resource.Uptime + metrics.disk projection, and the
  non-fatal degradation paths for Tools-stopped, powered-off, and
  privilege-restricted VMs.
- Proof record contract bumped from VC-0..VC-7 to VC-0..VC-8 and
  explicitly demands the guest filesystem privilege be captured.
- Existing automated coverage (vmware client test, mock fixture
  test, useWorkloads test) listed under VC-8 so the proof record
  starts at the right baseline.

VMWARE_VCENTER_PHASE1_PROOF_RECORD_TEMPLATE.md adds the matching
VC-8 observed/captured-evidence section and bumps its preamble.

VMWARE_VCENTER_PHASE1_ONBOARDING_SPEC.md amends the explicit
"minimum privilege set" unknown to call out guest filesystem
reads specifically, so the first real proof pass tightens that
guess into a documented privilege bundle.

VMWARE_VCENTER_PHASE1_API_RUNTIME_SPEC.md primary-source basis
adds developer.vmware.com references for the guest filesystem
endpoint and the sys.uptime / sys.osUptime counter conventions so
the new code paths are anchored on official VMware docs.
2026-05-23 12:06:27 +01:00
rcourtman 23ea4e4872 Surface vSphere VM uptime and guest disk usage
The vSphere adapter's InventoryMetrics struct only carried
throughput / utilisation metrics. Uptime and guest filesystem
usage weren't piped through at all, so the workloads table
rendered "0s" and empty cells for every vSphere VM.

Backend (internal/vmware):
- InventoryMetrics gains UptimeSeconds plus DiskUsedBytes /
  DiskTotalBytes / DiskPercent. Documented in the struct comment
  with the API sources they come from.
- PerformanceManager counter catalog adds sys.uptime.latest for
  hosts and VMs and sys.osUptime.latest for VMs. The mapping
  prefers guest OS uptime when present (Tools-reported) and falls
  back to VMX-process uptime. Counters verified against vSphere 8
  developer documentation.
- New per-VM REST collector calls
  GET /api/vcenter/vm/{vm}/guest/local-filesystem and aggregates
  per-mount capacity / free_space into DiskTotal / DiskUsed /
  DiskPercent. A 503 from vCenter (Tools not reporting) is
  classified as a non-fatal enrichment issue and the row stays
  blank rather than failing the collection.
- enrichInventorySnapshot now takes automationSessionID so the
  signals path can hit the REST endpoint alongside the VI/JSON
  PerformanceManager queries.
- Resource projection layer wires UptimeSeconds onto
  Resource.Uptime for hosts and VMs and the disk fields onto
  metrics.disk; cloneInventoryMetrics tracks the new pointers.

Mock (internal/mock):
- refreshVMwareInventoryMetrics synthesizes plausible per-resource
  uptime (1h - 30d base, climbing forward with snapshot time) and,
  for VMs only, a stable guest filesystem total (32-256 GiB) with
  naturally-oscillating used bytes via SampleMetric. Powered-off
  VMs drop the new pointers so the frontend renders "-" rather
  than zero, matching how the canonical "no data" signal already
  works for offline guests.

Frontend (useWorkloads.ts):
- The WorkloadGuest uptime fallback chain now lands on the
  canonical resource.uptime field. vSphere doesn't populate a
  platform-specific carve-out (only the canonical field), so the
  earlier proxmox/agent/docker/kubernetes-only chain was silently
  dropping vSphere uptime.

Contracts:
- monitoring.md documents the new InventoryMetrics fields, their
  vSphere collection sources, and the mock-fixture expectation.
- performance-and-scalability.md adds the canonical
  resource.uptime fallback rule to the workload mapping section.

Proofs:
- internal/mock/platform_fixtures_test.go asserts that powered-on
  vSphere VMs surface uptime + guest disk fields and powered-off
  VMs drop them.
- frontend-modern/src/hooks/__tests__/useWorkloads.test.ts adds a
  vSphere uptime fallback case.
- Existing vmware client test
  (TestClientCollectInventoryPreservesBaseInventoryWhenOptionalEnrichmentDegrades)
  teaches the mock vCenter to serve the new endpoint and updates
  the assertions to match the additional non-fatal issue surfaced
  when the unavailableVMGuestInfo knob also degrades the
  filesystem read.
2026-05-23 10:07:21 +01:00
rcourtman 4159cae185 Revert "Hide DISK column on vSphere VMs table by default"
This reverts commit 5fbbafc726.
2026-05-23 09:30:37 +01:00
rcourtman 9c7d3978e1 Show vCenter MoRef in workload ID column for vSphere VMs
The workload table's ID column reads displayId, which the
mapping pipeline derived only from numeric vmid. vCenter
identifies VMs by managed object reference (e.g. vm-206), not
a Proxmox-shaped numeric vmid, so vSphere rows landed in the
table with a blank ID cell.

When workloadType is vm and there's no Proxmox-shaped numeric
vmid, fall back to resource.vmware.managedObjectId. The MoRef
is the identifier operators recognize from the vCenter UI, so
the column now shows what an operator would expect to see.
2026-05-23 09:24:31 +01:00
rcourtman 5fbbafc726 Hide DISK column on vSphere VMs table by default
vCenter performance counters surface VM disk throughput
(diskRead / diskWrite) but not guest filesystem usage, so the
shared workload Disk column always rendered an empty cell for
vSphere rows. Add `disk` to the vSphere table's
additionalDefaultHiddenColumnIds so the column is hidden by
default, matching the pattern Docker uses for columns it can't
populate. Users can still toggle the column on from the Columns
menu.

The proper root fix is on the backend: the vSphere adapter
should pull guestInfo.guestDiskInfo from VMware Tools to
populate metrics.disk. Until that lands, hiding the column is
the honest UX move.
2026-05-23 09:20:53 +01:00
rcourtman 35bbb5d552 Add vSphere placement card to workload drawer
When a vSphere VM opens in the workload drawer, the System card
shows CPUs and Node (the runtime host) but vCenter, Datacenter,
and Cluster context were nowhere to be found. Add a small vSphere
card next to System / Guest Info / Tags showing those three fields,
matching the card-shaped layout the drawer already uses.

Extend WorkloadGuest with a narrow vmware shape (connectionName,
vcenterHost, datacenterName, clusterName) and populate it in
the useWorkloads mapping when platformType is vmware-vsphere.
The card only renders when at least one field is present.

Tools / snapshots / virtual disks / network adapters are not on
this card; surfacing them would require mapping more fields onto
WorkloadGuest and a separate decision on what's drawer-worthy.
2026-05-23 09:12:45 +01:00
rcourtman 62a0027ff8 Prune vSphere drawer sections to operator signal
The VIRTUAL HARDWARE section was rendering 20+ rows including
capability toggles (CPU/memory hot-add) and boot configuration
(EFI legacy boot, boot delay, boot retry, boot order, default
setup mode) that operators don't act on from a monitoring
surface. The GUEST section dumped Host/Instance/BIOS UUIDs that
are API-shaped identifiers, not operator scan candidates. The
TOOLS section padded out with install metadata (install type,
upgrade policy, auto-update capability, attempt count, reboot
components / time) that's the same kind of noise.

Trim each section to the rows an operator actually reads:
- Hardware: Guest OS, Hardware version, CPU topology, Memory size,
  Upgrade attention, Upgrade error, Instant clone frozen (when
  true), Enter setup mode (when true). Capability toggles and
  default boot config stay in the raw payload.
- Guest: Guest OS, Guest hostname, Guest IPs. UUIDs and
  datastoreUrl drop.
- State: Connection state replaces the redundant Power row (power
  is already on the workload row and SYSTEM card).
- Tools: Run state, Version status (only when not current),
  Version, Guest reboot (only when requested), Last install error.
  Install metadata stays in the raw payload.

Drop the now-unused formatMilliseconds and bootOrderLabel helpers
and their ResourceVMwareBootDevice import.

Test assertions are updated to match the trimmed shape with
comments explaining the operator-signal principle.
2026-05-23 09:04:34 +01:00
rcourtman 787dfe56fe Delete VsphereVirtualMachinesTable
Now that VmwareOverview routes VMs through WorkloadsSurface, the
bespoke VsphereVirtualMachinesTable + its test are dead code.
Remove them and flip the platform-overview guardrail to assert the
new shape (no VsphereVirtualMachinesTable, presence of
WorkloadsSurface with forcedPlatform/forcedViewMode for vSphere).

The shared formatVmwarePowerState / getVmwarePowerStateVariant
helpers in vmwarePageModel stay; VsphereHostsTable still uses them
for the ESXi host power column.
2026-05-23 08:50:51 +01:00
rcourtman d96d5612fd Route vSphere VMs through WorkloadsSurface
The vSphere overview's VM table was a bespoke component that
parallel-implemented what Proxmox, Docker, and Kubernetes already
get from the shared WorkloadsSurface. The result was an
overview page that lacked the Grouped/List, Bars/Trends/Columns,
and metric history toggles operators expect on a Pulse platform
page.

Wire VmwareOverview to useWorkloadsState + WorkloadsFilter +
WorkloadsSurface using the same embedded shape Proxmox uses:
forcedPlatform='vmware-vsphere', forcedViewMode='vm', shared
metricDisplayMode and metricHistoryRange persistent signals,
storage-scoped status and column visibility, compactGroupHeaders
so VsphereHostsTable keeps its dedicated layout above. The
existing power-state vocabulary maps cleanly: normalizeWorkloadStatus
already collapses online->running and offline->stopped, and vSphere
resource IDs (vm-XXXX hashes) match the workload chart key
candidates so sparkline mode resolves without extra plumbing.

VsphereVirtualMachinesTable stays in the tree for now; deletion
lands once Phase 1 is observed stable.
2026-05-23 08:43:01 +01:00
rcourtman ab5ed3ea6f Revert "Auto-expand vSphere drawer section on platform pages"
This reverts commit 9008e5f45e.
2026-05-22 21:41:44 +01:00
rcourtman 9008e5f45e Auto-expand vSphere drawer section on platform pages
Mirror the TrueNAS auto-open pattern: when a resource has VMware
detail sections, expand them by default in the row detail drawer.
Adds hasVMwareDetailSections to resourceDetailDrawerVmwareModel,
plumbs initialShowVMwareDetails through useResourceDetailDrawerState
and ResourceDetailDrawer, and lets PlatformResourceDetailTableRow
auto-detect from the resource the same way it already does for
TrueNAS. Matters now that the Tools and Health columns are gone
from the VMs table; Tools state lives in this drawer section.
2026-05-22 21:30:38 +01:00
rcourtman 0a7bd5d49e Align vSphere tables with shared platform conventions
Strip the bespoke colored pill components (HealthPill, ToolsPill,
StatusPill) from the vSphere VMs, Datastores, and Networks tables.
Status now reads from the leading StatusDot in the name cell, the
same way Proxmox, Docker, Kubernetes, and TrueNAS already convey it.
The Tools and Health columns on VMs and the State column on
Datastores and Networks are removed; the underlying data stays
reachable through the row detail drawer.

Drop the cluster-services inline subtitle on Hosts and VMs and the
managedObjectId / datastoreUrl subtitles on the VMs, Datastores,
and Networks name cells, so row density matches Proxmox and Docker.
Move that information into the row title attribute.

Replace the hand-rolled emerald progress bar in CapacityCell with the
shared StackedDiskBar so datastore capacity colouring responds to
fill thresholds rather than always rendering green.

Promote powerStateVariant and formatPowerState into vmwarePageModel
as getVmwarePowerStateVariant and formatVmwarePowerState; both Hosts
and VMs tables now share them. Export platformChipStatusDot from
sharedPlatformPage so vSphere filter chip definitions stop
redeclaring the same helper, and add leading status dots to the
Datastores, Networks, and Alerts chips that were missing them.
2026-05-22 21:13:38 +01:00
rcourtman 5016cbc2ba Add vSphere network inventory
Project vCenter network inventory through canonical resources and add the vSphere Networks table backed by vCenter network topology. Align resource presentation coalescing so state and resource APIs share the same host contract.
2026-05-22 20:26:56 +01:00
rcourtman 6c7d64ae43 Carry vSphere cluster services
Project vCenter cluster HA and DRS service state through the VMware resource facet so existing hosts and VMs expose cluster posture as read-only topology context.
2026-05-22 19:18:46 +01:00
rcourtman 9f98f8fcb9 Carry vSphere VM hardware config
Project vCenter VM hardware, CPU, memory, and boot configuration through the VMware resource facet and shared vSphere details so operators can inspect virtual hardware posture as read-only monitoring context.
2026-05-22 18:54:36 +01:00
rcourtman add3984f25 Carry vSphere VMware Tools status
Project vCenter VMware Tools runtime facts through the VMware resource facet and vSphere VM surface so operators can see Tools run state, version posture, upgrade policy, install attempts, and guest reboot requests as read-only monitoring context.
2026-05-22 18:22:49 +01:00
rcourtman 10c3c66f92 Carry vSphere VM virtual disks
Project vCenter VM hardware disk facts through the VMware resource facet and vSphere VM surface so operators can see virtual disk backing, capacity, datastore, and bus placement as read-only monitoring context.
2026-05-22 16:45:08 +01:00
rcourtman 6a7936ba4e Carry vSphere VM network adapters
Project vCenter VM hardware Ethernet adapter facts through the VMware resource facet and vSphere VM surface so operators can see vNIC backing network, MAC address, connection state, and adapter flags as read-only monitoring context.
2026-05-22 15:40:25 +01:00
rcourtman 7ffe2e581c Carry vSphere snapshot trees
Project VI JSON VM snapshot trees through the VMware resource facet and shared drawer so vSphere VM detail shows current snapshot, tree entries, and quiesce state as read-only workload context.
2026-05-22 12:43:28 +01:00
rcourtman db690b0dce Add vSphere health tab
Surface vSphere alarm and health signals on a dedicated route-backed Health tab so the admitted VMware page exposes the shared incident proof path without duplicating health rows on Overview.
2026-05-22 09:24:18 +01:00
rcourtman abf2203307 Correct VMware platform readiness classification
Move vSphere back to the admitted first-lab-ready stage in the support manifest, regenerate shared projections, and keep onboarding/navigation copy from presenting VMware as fully supported before live vCenter proof.
2026-05-22 09:13:29 +01:00
rcourtman 3cd1517883 Surface vSphere activity timeline
Add a global resource timeline endpoint for provider activity and wire vSphere Activity to VMware timeline changes. Seed mock VMware activity through the same supplemental-change path and keep the relevant resource contract tests current.
2026-05-22 08:54:43 +01:00
rcourtman 06a73244a2 Surface vSphere activity 2026-05-22 08:22:36 +01:00
rcourtman ffd2a7efed Surface vSphere health signals 2026-05-22 08:08:10 +01:00
rcourtman 2ee40382d7 Make vSphere VM table API-native 2026-05-22 07:55:15 +01:00
rcourtman b19beb1976 Make vSphere datastores API-native 2026-05-22 07:38:57 +01:00
rcourtman 444aa1175e Render TrueNAS storage row depth 2026-05-22 07:09:18 +01:00
rcourtman a57af72fbb Nest TrueNAS dataset topology rows 2026-05-22 06:54:27 +01:00
rcourtman 51f79efe72 Infer TrueNAS storage topology ownership 2026-05-22 06:42:26 +01:00
rcourtman 141269e31e Harden TrueNAS inventory ownership 2026-05-22 06:30:31 +01:00
rcourtman b63953ee0e Share TrueNAS detail table rendering 2026-05-22 06:25:22 +01:00
rcourtman d10079f9e3 Extract shared TrueNAS detail table 2026-05-22 05:55:31 +01:00
rcourtman 4a371c6b1f Add TrueNAS alert detail rows 2026-05-22 05:42:38 +01:00
rcourtman f9bd009a1c Add TrueNAS service detail rows 2026-05-21 21:47:10 +01:00
rcourtman 5bc952043e Promote TrueNAS native inline details 2026-05-21 21:40:50 +01:00
rcourtman d3d75911fd Add TrueNAS protection detail rows 2026-05-21 21:05:42 +01:00
rcourtman 85364cd01c Add native TrueNAS system details 2026-05-21 20:19:41 +01:00
rcourtman 417b459c3d Add native TrueNAS storage details 2026-05-21 18:16:27 +01:00
rcourtman 29439fe14b Render resource context as detail tables 2026-05-21 17:53:40 +01:00
rcourtman 5bffb581bb Extract resource detail summary presentations 2026-05-21 17:45:48 +01:00
rcourtman 7ac97afc32 Use table summaries for inline resource details 2026-05-21 17:11:39 +01:00
rcourtman 433da8537f Render TrueNAS detail sections as tables 2026-05-21 17:05:43 +01:00
rcourtman 1794a83002 Open TrueNAS inline details by default 2026-05-21 16:57:10 +01:00
rcourtman 2e5e54d598 Fit TrueNAS detail tables 2026-05-21 16:50:40 +01:00
rcourtman 64a3fbc07e Fit TrueNAS protection table to overview width
- Remove the redundant Signal column from the TrueNAS protection ledger
- Keep replication state visible in target detail and outcome badge
- Add a guardrail for the fitted protection table width
2026-05-21 16:38:53 +01:00
rcourtman 946ebfde1d Tighten TrueNAS native inventory tables
- Scope the TrueNAS resource fetch to native TrueNAS and agent-origin system rows
- Group overview inventory counts to keep the table scannable without horizontal overflow
- Remove internal service/resource ids from visible TrueNAS service rows
2026-05-21 16:34:38 +01:00