Collect native Kubernetes config, policy, and autoscaling objects.
Project the new resource types through API filters, unified resources, mock fixtures, and Kubernetes tabs.
Keep Secret inventory metadata-only and route k8s-secret policy as restricted local-only.
Without an explicit case for `network`, `canonicalizeFrontendResourceType`
returned `undefined` and `resolveType` fell through to its `'agent'`
default, which is why REST-normalized vSphere network resources briefly
appeared in the vSphere Hosts table on Overview. The WS snapshot then
corrected the type to 'network' and they vanished, producing the
"lots of entries that disappear" flicker.
The TrueNAS Storage table was hand-rolling a thin emerald slab below
the used/total text, which read as cosmetic and didn't match any other
v6 platform table. Swap for ResponsiveMetricCell type="disk", which
renders the canonical MetricBar with the percentage label inside the
fill, severity-aligned coloring, sparkline support, and "used / total"
as the sublabel — the same primitive used by vSphere Datastores,
Proxmox Storage/Nodes, Docker Hosts, Kubernetes Nodes, and the other
TrueNAS tables (Apps, Systems).
Physical-disk rows have no used/total, so they fall back to a plain
"4.00 TB" size label rather than rendering a degenerate bar.
Bring TrueNAS Storage table in line with Kubernetes/Docker/Proxmox
peers on the canonical platform primitives.
- Add coloured leading dots to Healthy/Attention/Offline chips so the
filter toolbar matches PLATFORM_HEALTH_FILTER_OPTIONS.
- Drop the redundant State column. Health was being signalled three
times (row status dot, raw ZFS/SMART text, Health pill); raw state
still surfaces in the resource drawer.
- Drop the Shares column, which printed 0 on nearly every row; share
count remains available in the dataset detail.
- Rename TableCardHeader title to "Storage" to match peer titles
("Nodes", "Services", "Deployments").
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.