mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-07-09 16:00:59 +00:00
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.
This commit is contained in:
parent
3cd1517883
commit
abf2203307
17 changed files with 111 additions and 93 deletions
|
|
@ -290,8 +290,8 @@
|
|||
"id": "vmware-vsphere",
|
||||
"family": "VMware",
|
||||
"surface_kind": "platform",
|
||||
"governance_state": "supported",
|
||||
"readiness_stage": "supported",
|
||||
"governance_state": "admitted",
|
||||
"readiness_stage": "first-lab-ready",
|
||||
"primary_mode": "api-backed",
|
||||
"onboarding_paths": [
|
||||
"platform-connections"
|
||||
|
|
|
|||
|
|
@ -261,7 +261,6 @@ Rules:
|
|||
4. `proxmox-pbs`
|
||||
5. `proxmox-pmg`
|
||||
6. `truenas`
|
||||
7. `vmware-vsphere`
|
||||
|
||||
### Runtime lenses
|
||||
|
||||
|
|
@ -269,7 +268,7 @@ Rules:
|
|||
|
||||
### Admitted platforms (not yet supported)
|
||||
|
||||
(none)
|
||||
1. `vmware-vsphere`
|
||||
|
||||
### Presentation-only platform vocabulary
|
||||
|
||||
|
|
@ -309,7 +308,6 @@ Support floor fields are recorded in this order: `setup`, `visibility`,
|
|||
| `proxmox-pbs` | `platform` | `supported` | `supported` | `api-backed` | `platform-connections` | `pbs`, `storage` | `setup=supported`; `visibility=supported`; `workloads=n/a`; `storage=supported`; `recovery=supported`; `alerts=supported`; `assistant_read=supported`; `assistant_control=read-only` |
|
||||
| `proxmox-pmg` | `platform` | `supported` | `supported` | `api-backed` | `platform-connections` | `pmg` | `setup=supported`; `visibility=supported`; `workloads=n/a`; `storage=n/a`; `recovery=n/a`; `alerts=supported`; `assistant_read=supported`; `assistant_control=read-only` |
|
||||
| `truenas` | `platform` | `supported` | `supported` | `api-backed` | `platform-connections` | `agent`, `vm`, `app-container`, `network-share`, `storage`, `physical-disk` | `setup=supported`; `visibility=supported`; `workloads=supported`; `storage=supported`; `recovery=supported`; `alerts=supported`; `assistant_read=supported`; `assistant_control=supported` |
|
||||
| `vmware-vsphere` | `platform` | `supported` | `supported` | `api-backed` | `platform-connections` | `agent`, `vm`, `storage` | `setup=supported`; `visibility=supported`; `workloads=supported`; `storage=supported`; `recovery=n/a`; `alerts=supported`; `assistant_read=supported`; `assistant_control=read-only` |
|
||||
|
||||
Presentation-only platform vocabulary uses `governance=presentation-only`,
|
||||
`surface_kind=presentation-only`, `readiness=presentation-only`,
|
||||
|
|
@ -369,7 +367,6 @@ or runtime platform fallbacks that are not declared in this document.
|
|||
| `proxmox-pbs` | platform | Proxmox | api-backed | host agent may augment into hybrid | `pbs`, `storage` |
|
||||
| `proxmox-pmg` | platform | Proxmox | api-backed | none today | `pmg` |
|
||||
| `truenas` | platform | TrueNAS | api-backed | host agent may augment into hybrid | `agent`, `vm`, `app-container`, `network-share`, `storage`, `physical-disk` |
|
||||
| `vmware-vsphere` | platform | VMware | api-backed | host or guest agent later, not phase 1 | `agent`, `vm`, `storage` |
|
||||
|
||||
| Platform | Setup | Visibility | Workloads | Storage | Recovery | Alerts | Assistant read | Assistant control |
|
||||
| ---------------- | -------------------------------------- | ---------- | --------- | --------- | --------- | --------- | -------------- | ----------------- |
|
||||
|
|
@ -380,7 +377,6 @@ or runtime platform fallbacks that are not declared in this document.
|
|||
| `proxmox-pbs` | platform connections | supported | `n/a` | supported | supported | supported | supported | read-only |
|
||||
| `proxmox-pmg` | platform connections | supported | `n/a` | `n/a` | `n/a` | supported | supported | read-only |
|
||||
| `truenas` | platform connections | supported | supported | supported | supported | supported | supported | supported |
|
||||
| `vmware-vsphere` | platform connections | supported | supported | supported | `n/a` | supported | supported | read-only |
|
||||
|
||||
## Current Inconsistencies To Treat Explicitly
|
||||
|
||||
|
|
@ -426,10 +422,10 @@ open-decision or resolved-decision update instead of starting runtime code.
|
|||
|
||||
## VMware vSphere Admission Model
|
||||
|
||||
Pulse now has a resolved architecture recommendation for any future VMware
|
||||
vSphere work. This does not admit `vmware-vsphere` into the current support
|
||||
matrix yet. It defines the only acceptable phase-1 model if implementation
|
||||
starts.
|
||||
Pulse now has a resolved architecture recommendation for VMware vSphere work.
|
||||
This admits `vmware-vsphere` only at the `first-lab-ready` checkpoint; it does
|
||||
not place VMware in the current support matrix yet. It defines the only
|
||||
acceptable phase-1 model for implementation and proof.
|
||||
|
||||
1. treat VMware as one separate first-class platform id,
|
||||
`vmware-vsphere`, not as another Proxmox subtype and not as a generic
|
||||
|
|
|
|||
|
|
@ -210,7 +210,11 @@ projections, and support-floor posture.
|
|||
those facts into source-strategy copy, but it must not turn an admitted
|
||||
`first-lab-ready` platform such as VMware into a product-level supported
|
||||
claim, invent platform-local projections, or classify assistant control beyond
|
||||
the manifest's support-floor row.
|
||||
the manifest's support-floor row. Admitted API platforms may remain available
|
||||
inside the add-flow source picker and source-manager summaries, but their
|
||||
operator-facing badge must be preview/admission language and empty-state copy
|
||||
must keep them separate from the supported-source list until the governed live
|
||||
proof promotes the platform.
|
||||
That same lifecycle-owned helper must keep first-class platform APIs separate
|
||||
from governed Pulse Agent host profiles. Host/appliance compatibility such as
|
||||
Unraid is presented as an agent install/profile path sourced from the manifest
|
||||
|
|
|
|||
|
|
@ -766,7 +766,7 @@ not a replacement status card, CTA band, or page-local nested card.
|
|||
the container-runtime lens and may be labelled `Containers` in the shell,
|
||||
while shared source badges, filters, and runtime management copy continue
|
||||
to use `Docker / Podman` where the capability itself is being named.
|
||||
8. Keep shared source/platform vocabulary on the governed manifest boundary. `frontend-modern/src/utils/platformSupportManifest.generated.ts` must be the tracked frontend projection of `docs/release-control/v6/internal/PLATFORM_SUPPORT_MANIFEST.json`, `frontend-modern/src/utils/platformSupportManifest.ts`, `frontend-modern/src/utils/sourcePlatforms.ts`, and `frontend-modern/src/utils/sourcePlatformOptions.ts` must consume that generated projection instead of embedding divergent future-label lists, setup/onboarding path allowlists, host-profile labels, surface-kind guesses, or presentation-only guesses, and `frontend-modern/scripts/canonical-platform-audit.mjs` must fail when the generated projection drifts from the governed manifest. The generated `surface_kind` is the machine-readable boundary between owning platform entries and runtime lenses: `docker` is a `runtime-lens`, not a `platform`, even when the container-runtime route stays available as a primary shell destination. The generic `docker` source-platform label is "Docker / Podman" in shared selectors, badges, and filter options so v5 Docker users can find the runtime surface while Podman-backed rows are not mislabeled as Docker-only; "Container runtime" remains the governed runtime family, not the primary customer-facing label. Identity colour is semantic, not page-local decoration: shared source/platform badges, host identity badges, and container runtime badges must use the shared presentation helpers so Docker remains on the Docker/Podman blue runtime tone, Podman uses its distinct runtime tone, Proxmox PVE remains orange, and those meanings do not drift across table rows, filters, drawers, or platform pages. Agent host-profile entries, including Unraid, stay in the generated `agentHostProfiles` projection and shared wrapper helpers; frontend primitives may render those labels for Pulse Agent install/identity copy but must not add them to the first-class platform union.
|
||||
8. Keep shared source/platform vocabulary on the governed manifest boundary. `frontend-modern/src/utils/platformSupportManifest.generated.ts` must be the tracked frontend projection of `docs/release-control/v6/internal/PLATFORM_SUPPORT_MANIFEST.json`, `frontend-modern/src/utils/platformSupportManifest.ts`, `frontend-modern/src/utils/sourcePlatforms.ts`, and `frontend-modern/src/utils/sourcePlatformOptions.ts` must consume that generated projection instead of embedding divergent future-label lists, setup/onboarding path allowlists, host-profile labels, surface-kind guesses, readiness-state guesses, or presentation-only guesses, and `frontend-modern/scripts/canonical-platform-audit.mjs` must fail when the generated projection drifts from the governed manifest. The generated governance/readiness split is authoritative: supported platform arrays drive current support claims, while admitted platform arrays may keep route/navigation and add-flow vocabulary available without turning `first-lab-ready` entries such as VMware into supported-source copy. The generated `surface_kind` is the machine-readable boundary between owning platform entries and runtime lenses: `docker` is a `runtime-lens`, not a `platform`, even when the container-runtime route stays available as a primary shell destination. The generic `docker` source-platform label is "Docker / Podman" in shared selectors, badges, and filter options so v5 Docker users can find the runtime surface while Podman-backed rows are not mislabeled as Docker-only; "Container runtime" remains the governed runtime family, not the primary customer-facing label. Identity colour is semantic, not page-local decoration: shared source/platform badges, host identity badges, and container runtime badges must use the shared presentation helpers so Docker remains on the Docker/Podman blue runtime tone, Podman uses its distinct runtime tone, Proxmox PVE remains orange, and those meanings do not drift across table rows, filters, drawers, or platform pages. Agent host-profile entries, including Unraid, stay in the generated `agentHostProfiles` projection and shared wrapper helpers; frontend primitives may render those labels for Pulse Agent install/identity copy but must not add them to the first-class platform union.
|
||||
The generated host-profile projection also carries runtime platform fallback
|
||||
metadata for shared explanation and parity with backend normalization, but
|
||||
frontend primitives must still render host-profile labels through
|
||||
|
|
@ -3316,7 +3316,10 @@ That same shared settings-shell boundary also owns provider parity inside the
|
|||
inline add flow. Adding VMware may extend the same card, empty-state, dialog,
|
||||
and summary-shell patterns used by TrueNAS, but it must not introduce a
|
||||
VMware-only outer page shell, alternate settings route hierarchy, or another
|
||||
summary vocabulary for connection health and contribution counts.
|
||||
summary vocabulary for connection health and contribution counts. While VMware
|
||||
remains admitted rather than supported, shared settings primitives must render
|
||||
its source-picker card with the manifest-derived preview badge and keep
|
||||
supported-source empty-state copy from listing VMware as available now.
|
||||
That same shared filter-presentation boundary also owns infrastructure
|
||||
route-filter continuity. `frontend-modern/src/features/infrastructure/`
|
||||
must keep a route-owned canonical source option such as `truenas` visible in
|
||||
|
|
|
|||
|
|
@ -1021,7 +1021,11 @@ must stay generated from
|
|||
`frontend-modern/src/types/resource.ts` must derive `PlatformType` from that
|
||||
generated supported-plus-admitted projection rather than hand-maintaining a
|
||||
second platform union that can drift from the governed manifest or re-admit
|
||||
presentation-only labels by mistake. Agent host profiles are generated beside
|
||||
presentation-only labels by mistake. The supported/admitted split in that
|
||||
projection is also contractual: VMware may stay a valid `PlatformType` and
|
||||
source-platform alias while admitted, but unified-resource consumers must not
|
||||
infer current platform support from that union without checking governance
|
||||
state/readiness. Agent host profiles are generated beside
|
||||
that platform projection for shared identity/presentation use only; a profile
|
||||
such as Unraid may label a Pulse Agent host, but it must not enter
|
||||
`PlatformType`, `PLATFORM_TYPE_KEYS`, unified-resource source filters, or
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ describe('InfrastructureSourcePicker', () => {
|
|||
cleanup();
|
||||
});
|
||||
|
||||
it('labels admitted VMware as Early support and keeps Pulse Agent on the host profile path', () => {
|
||||
it('labels admitted VMware as Preview and keeps Pulse Agent on the host profile path', () => {
|
||||
render(() => <InfrastructureSourcePicker onSelectStep={vi.fn()} />);
|
||||
|
||||
expect(screen.getByPlaceholderText('Search platforms, hosts, services...')).toBeInTheDocument();
|
||||
|
|
@ -17,10 +17,10 @@ describe('InfrastructureSourcePicker', () => {
|
|||
expect(screen.getByText('Choose how Pulse should connect')).toBeInTheDocument();
|
||||
expect(screen.getByText('Or pick a specific platform')).toBeInTheDocument();
|
||||
// VMware lives behind 'Show more platforms' since it is a less common
|
||||
// homelab choice; expand the long tail to verify the Early support
|
||||
// badge still renders for it.
|
||||
// homelab choice; expand the long tail to verify the Preview badge still
|
||||
// renders for it.
|
||||
fireEvent.click(screen.getByRole('button', { name: /Show \d+ more platforms?/i }));
|
||||
expect(screen.getByText('Early support')).toBeInTheDocument();
|
||||
expect(screen.getByText('Preview')).toBeInTheDocument();
|
||||
expect(screen.queryByText('Available now')).toBeNull();
|
||||
expect(screen.getByText('Unraid')).toBeInTheDocument();
|
||||
expect(screen.getByText('Linux, macOS, Windows host')).toBeInTheDocument();
|
||||
|
|
|
|||
|
|
@ -489,7 +489,10 @@ describe('InfrastructureWorkspace', () => {
|
|||
expect(
|
||||
screen.getByText('Choose an infrastructure source to start monitoring your environment.'),
|
||||
).toBeInTheDocument();
|
||||
expect(screen.getByText(/Supported source types include VMware vCenter/i)).toBeInTheDocument();
|
||||
expect(screen.getByText(/Supported source types include TrueNAS SCALE/i)).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText(/VMware vCenter is available as a preview platform/i),
|
||||
).toBeInTheDocument();
|
||||
expect(screen.getByText(/standalone hosts through Pulse Agent/i)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -685,7 +685,7 @@ describe('settings architecture guardrails', () => {
|
|||
'getInfrastructureSupportSummaryBadges',
|
||||
);
|
||||
expect(infrastructureOnboardingPresentationSource).toContain(
|
||||
'Supported source types include VMware vCenter',
|
||||
'VMware vCenter is available as a preview platform',
|
||||
);
|
||||
|
||||
expect(nodeCredentialSlotSource).toContain('useNodeModalState(modalProps)');
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ const resource = (overrides: Partial<Resource>): Resource =>
|
|||
}) as Resource;
|
||||
|
||||
describe('infrastructureNavigationModel', () => {
|
||||
it('shows primary infrastructure destinations only when supported resource evidence is present', () => {
|
||||
it('shows primary infrastructure destinations only when supported or admitted resource evidence is present', () => {
|
||||
expect(buildPrimaryInfrastructureNavigationVisibility([])).toEqual({
|
||||
proxmox: false,
|
||||
docker: false,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import type { Accessor } from 'solid-js';
|
||||
import type { Resource, ResourceType } from '@/types/resource';
|
||||
import {
|
||||
ADMITTED_PLATFORM_IDS,
|
||||
SUPPORTED_PLATFORM_IDS,
|
||||
getSourcePlatformManifestEntry,
|
||||
type SourcePlatformManifestEntry,
|
||||
|
|
@ -35,7 +36,10 @@ export const PRIMARY_INFRASTRUCTURE_NAV_SCOPE_IDS: Record<
|
|||
vmware: ['vmware-vsphere'],
|
||||
};
|
||||
|
||||
const SUPPORTED_PLATFORM_ID_SET = new Set<string>(SUPPORTED_PLATFORM_IDS);
|
||||
const NAVIGABLE_PLATFORM_ID_SET = new Set<string>([
|
||||
...SUPPORTED_PLATFORM_IDS,
|
||||
...ADMITTED_PLATFORM_IDS,
|
||||
]);
|
||||
|
||||
const KUBERNETES_RESOURCE_TYPES = new Set<ResourceType>([
|
||||
'k8s-cluster',
|
||||
|
|
@ -127,7 +131,7 @@ export function collectResourcePlatformEvidence(resource: Resource): string[] {
|
|||
return [...ids];
|
||||
}
|
||||
|
||||
export function buildSupportedResourceInfrastructureScopeSet(
|
||||
export function buildNavigableResourceInfrastructureScopeSet(
|
||||
resources: readonly Resource[],
|
||||
): Set<string> {
|
||||
const present = new Set<string>();
|
||||
|
|
@ -136,7 +140,7 @@ export function buildSupportedResourceInfrastructureScopeSet(
|
|||
const manifestEntry = getSourcePlatformManifestEntry(
|
||||
platformId,
|
||||
) as SourcePlatformManifestEntry | null;
|
||||
if (!manifestEntry || !SUPPORTED_PLATFORM_ID_SET.has(manifestEntry.id)) continue;
|
||||
if (!manifestEntry || !NAVIGABLE_PLATFORM_ID_SET.has(manifestEntry.id)) continue;
|
||||
present.add(manifestEntry.id);
|
||||
}
|
||||
}
|
||||
|
|
@ -146,22 +150,22 @@ export function buildSupportedResourceInfrastructureScopeSet(
|
|||
export function buildPrimaryInfrastructureNavigationVisibility(
|
||||
resources: readonly Resource[],
|
||||
): InfrastructureNavigationVisibility {
|
||||
const presentSupportedScopes = buildSupportedResourceInfrastructureScopeSet(resources);
|
||||
const presentNavigableScopes = buildNavigableResourceInfrastructureScopeSet(resources);
|
||||
return {
|
||||
proxmox: PRIMARY_INFRASTRUCTURE_NAV_SCOPE_IDS.proxmox.some((id) =>
|
||||
presentSupportedScopes.has(id),
|
||||
presentNavigableScopes.has(id),
|
||||
),
|
||||
docker: PRIMARY_INFRASTRUCTURE_NAV_SCOPE_IDS.docker.some((id) =>
|
||||
presentSupportedScopes.has(id),
|
||||
presentNavigableScopes.has(id),
|
||||
),
|
||||
kubernetes: PRIMARY_INFRASTRUCTURE_NAV_SCOPE_IDS.kubernetes.some((id) =>
|
||||
presentSupportedScopes.has(id),
|
||||
presentNavigableScopes.has(id),
|
||||
),
|
||||
truenas: PRIMARY_INFRASTRUCTURE_NAV_SCOPE_IDS.truenas.some((id) =>
|
||||
presentSupportedScopes.has(id),
|
||||
presentNavigableScopes.has(id),
|
||||
),
|
||||
vmware: PRIMARY_INFRASTRUCTURE_NAV_SCOPE_IDS.vmware.some((id) =>
|
||||
presentSupportedScopes.has(id),
|
||||
presentNavigableScopes.has(id),
|
||||
),
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,12 +17,12 @@ import {
|
|||
} from '@/utils/infrastructureOnboardingPresentation';
|
||||
|
||||
describe('infrastructureOnboardingPresentation', () => {
|
||||
it('keeps VMware on the supported vCenter path', () => {
|
||||
it('keeps VMware on the admitted vCenter path until live proof lands', () => {
|
||||
const vmware = getInfrastructureOnboardingProductPresentation('vmware');
|
||||
|
||||
expect(vmware.label).toBe('VMware vCenter');
|
||||
expect(vmware.governanceState).toBe('supported');
|
||||
expect(vmware.readinessStage).toBe('supported');
|
||||
expect(vmware.governanceState).toBe('admitted');
|
||||
expect(vmware.readinessStage).toBe('first-lab-ready');
|
||||
expect(vmware.primaryMode).toBe('api-backed');
|
||||
expect(vmware.canonicalProjections).toEqual(['agent', 'vm', 'storage']);
|
||||
expect(vmware.supportFloor).toMatchObject({
|
||||
|
|
@ -87,19 +87,22 @@ describe('infrastructureOnboardingPresentation', () => {
|
|||
expect(INFRASTRUCTURE_ONBOARDING_PATHS.agent.title).toBe('Install Pulse Agent');
|
||||
});
|
||||
|
||||
it('lists all supported API products alongside vSphere now that VMware is promoted', () => {
|
||||
it('separates supported API products from admitted preview products', () => {
|
||||
expect(
|
||||
getInfrastructureApiProductsByGovernanceState('supported').map((product) => product.label),
|
||||
).toEqual([
|
||||
'VMware vCenter',
|
||||
'TrueNAS SCALE',
|
||||
'Proxmox VE',
|
||||
'Proxmox Backup Server',
|
||||
'Proxmox Mail Gateway',
|
||||
'Network endpoint',
|
||||
]);
|
||||
expect(
|
||||
getInfrastructureApiProductsByGovernanceState('admitted').map((product) => product.label),
|
||||
).toEqual(['VMware vCenter']);
|
||||
|
||||
expect(getInfrastructureGovernanceBadgeLabel('supported', 'supported')).toBeNull();
|
||||
expect(getInfrastructureGovernanceBadgeLabel('admitted', 'first-lab-ready')).toBe('Preview');
|
||||
});
|
||||
|
||||
it('derives picker items, auto-detect copy, and landing summaries from the shared helper', () => {
|
||||
|
|
@ -201,7 +204,6 @@ describe('infrastructureOnboardingPresentation', () => {
|
|||
|
||||
expect(getInfrastructureSupportSummaryBadges()).toMatchObject({
|
||||
supportedToday: [
|
||||
'VMware vCenter',
|
||||
'TrueNAS SCALE',
|
||||
'Proxmox VE',
|
||||
'Proxmox Backup Server',
|
||||
|
|
@ -211,7 +213,7 @@ describe('infrastructureOnboardingPresentation', () => {
|
|||
'Docker',
|
||||
'Kubernetes',
|
||||
],
|
||||
currentAdmissionPath: [],
|
||||
currentAdmissionPath: ['VMware vCenter'],
|
||||
installPath: expect.arrayContaining([
|
||||
'Linux',
|
||||
'FreeBSD',
|
||||
|
|
@ -226,7 +228,10 @@ describe('infrastructureOnboardingPresentation', () => {
|
|||
'Choose an infrastructure source to start monitoring your environment.',
|
||||
);
|
||||
expect(getInfrastructureEmptyStateDetail()).toContain(
|
||||
'Supported source types include VMware vCenter',
|
||||
'Supported source types include TrueNAS SCALE',
|
||||
);
|
||||
expect(getInfrastructureEmptyStateDetail()).toContain(
|
||||
'VMware vCenter is available as a preview platform',
|
||||
);
|
||||
expect(getInfrastructureEmptyStateDetail()).toContain('standalone hosts through Pulse Agent');
|
||||
expect(getInfrastructureEmptyStateDetail()).toContain('Docker and Kubernetes are discovered');
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import {
|
|||
resolveSourceTypeFromSources,
|
||||
} from '@/utils/sourcePlatforms';
|
||||
import {
|
||||
ADMITTED_PLATFORM_IDS,
|
||||
AGENT_HOST_PROFILE_IDS,
|
||||
PLATFORM_TYPE_KEYS,
|
||||
PRESENTATION_ONLY_PLATFORM_IDS,
|
||||
|
|
@ -160,8 +161,9 @@ describe('sourcePlatforms', () => {
|
|||
});
|
||||
|
||||
describe('governed platform support projection', () => {
|
||||
it('keeps VMware on the supported vCenter-backed floor', () => {
|
||||
expect(getSourcePlatformReadinessStage('vmware')).toBe('supported');
|
||||
it('keeps VMware on the admitted vCenter-backed floor until live proof lands', () => {
|
||||
expect(ADMITTED_PLATFORM_IDS).toEqual(['vmware-vsphere']);
|
||||
expect(getSourcePlatformReadinessStage('vmware')).toBe('first-lab-ready');
|
||||
expect(getSourcePlatformCanonicalProjections('vmware')).toEqual(['agent', 'vm', 'storage']);
|
||||
expect(getSourcePlatformSupportFloor('vmware')).toMatchObject({
|
||||
setup: 'supported',
|
||||
|
|
@ -197,6 +199,7 @@ describe('sourcePlatforms', () => {
|
|||
expect(SUPPORTED_RUNTIME_LENS_IDS).toEqual(['docker']);
|
||||
expect(SUPPORTED_OWNING_PLATFORM_IDS).toContain('proxmox-pve');
|
||||
expect(SUPPORTED_OWNING_PLATFORM_IDS).not.toContain('docker');
|
||||
expect(SUPPORTED_OWNING_PLATFORM_IDS).not.toContain('vmware-vsphere');
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -129,11 +129,12 @@ export const getInfrastructureAgentHostProfileSupportText = (): string =>
|
|||
|
||||
export const getInfrastructureGovernanceBadgeLabel = (
|
||||
governanceState: PlatformGovernanceState,
|
||||
_readinessStage: PlatformReadinessStage,
|
||||
readinessStage: PlatformReadinessStage,
|
||||
): string | null => {
|
||||
if (governanceState === 'supported') return null;
|
||||
if (governanceState === 'presentation-only') return 'Presentation only';
|
||||
return null;
|
||||
if (readinessStage === 'first-lab-ready') return 'Preview';
|
||||
return 'Preview';
|
||||
};
|
||||
|
||||
const SOURCE_STRATEGY_PRESENTATION: Record<
|
||||
|
|
@ -533,10 +534,9 @@ export const getInfrastructureSupportSummaryBadges = (): {
|
|||
...getInfrastructureApiProductsByGovernanceState('supported').map((product) => product.label),
|
||||
...INFRASTRUCTURE_AGENT_DISCOVERY_LABELS,
|
||||
],
|
||||
// No platforms currently sit in the admitted staging area; the type is
|
||||
// narrowed to the live governance states, so the admission-path summary
|
||||
// is empty until a future platform is admitted-but-not-yet-supported.
|
||||
currentAdmissionPath: [],
|
||||
currentAdmissionPath: getInfrastructureApiProductsByGovernanceState('admitted').map(
|
||||
(product) => product.label,
|
||||
),
|
||||
installPath: [...INFRASTRUCTURE_AGENT_HOST_LABELS, ...INFRASTRUCTURE_AGENT_DISCOVERY_LABELS],
|
||||
});
|
||||
|
||||
|
|
@ -544,7 +544,7 @@ export const getInfrastructureEmptyStateSummary = (): string =>
|
|||
'Choose an infrastructure source to start monitoring your environment.';
|
||||
|
||||
export const getInfrastructureEmptyStateDetail = (): string =>
|
||||
'Supported source types include VMware vCenter, TrueNAS SCALE, Proxmox VE, Proxmox Backup Server, Proxmox Mail Gateway, network endpoints, and standalone hosts through Pulse Agent. Docker and Kubernetes are discovered from supported agent hosts.';
|
||||
'Supported source types include TrueNAS SCALE, Proxmox VE, Proxmox Backup Server, Proxmox Mail Gateway, network endpoints, and standalone hosts through Pulse Agent. VMware vCenter is available as a preview platform pending live support proof. Docker and Kubernetes are discovered from supported agent hosts.';
|
||||
|
||||
export const getInfrastructureCoverageCompleteActionPresentation =
|
||||
(): InfrastructureCoverageCompleteActionPresentation => ({
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
// This file is generated by scripts/release_control/generate_platform_support_frontend_module.py.
|
||||
// Do not edit by hand.
|
||||
// Source: docs/release-control/v6/internal/PLATFORM_SUPPORT_MANIFEST.json
|
||||
// Source SHA256: 11c137eb7f586114e9f835bc5429f6cae81906e6ce8eb13413df1e51752f31a0
|
||||
// Source SHA256: 97b7ac58c2c981867dc4052728587d323fc541221135e6bada1191d9d723206b
|
||||
|
||||
export const PLATFORM_SUPPORT_MANIFEST_SOURCE = {
|
||||
path: 'docs/release-control/v6/internal/PLATFORM_SUPPORT_MANIFEST.json',
|
||||
sha256: '11c137eb7f586114e9f835bc5429f6cae81906e6ce8eb13413df1e51752f31a0',
|
||||
sha256: '97b7ac58c2c981867dc4052728587d323fc541221135e6bada1191d9d723206b',
|
||||
} as const;
|
||||
export const PLATFORM_SUPPORT_MANIFEST = {
|
||||
schemaVersion: 2,
|
||||
|
|
@ -227,8 +227,8 @@ export const PLATFORM_SUPPORT_MANIFEST = {
|
|||
id: 'vmware-vsphere',
|
||||
family: 'VMware',
|
||||
surfaceKind: 'platform',
|
||||
governanceState: 'supported',
|
||||
readinessStage: 'supported',
|
||||
governanceState: 'admitted',
|
||||
readinessStage: 'first-lab-ready',
|
||||
primaryMode: 'api-backed',
|
||||
onboardingPaths: ['platform-connections'],
|
||||
canonicalProjections: ['agent', 'vm', 'storage'],
|
||||
|
|
@ -412,7 +412,6 @@ export const SUPPORTED_PLATFORM_IDS = [
|
|||
'proxmox-pbs',
|
||||
'proxmox-pmg',
|
||||
'truenas',
|
||||
'vmware-vsphere',
|
||||
] as const;
|
||||
export const SUPPORTED_OWNING_PLATFORM_IDS = [
|
||||
'agent',
|
||||
|
|
@ -421,10 +420,9 @@ export const SUPPORTED_OWNING_PLATFORM_IDS = [
|
|||
'proxmox-pbs',
|
||||
'proxmox-pmg',
|
||||
'truenas',
|
||||
'vmware-vsphere',
|
||||
] as const;
|
||||
export const SUPPORTED_RUNTIME_LENS_IDS = ['docker'] as const;
|
||||
export const ADMITTED_PLATFORM_IDS = [] as const;
|
||||
export const ADMITTED_PLATFORM_IDS = ['vmware-vsphere'] as const;
|
||||
export const PRESENTATION_ONLY_PLATFORM_IDS = [
|
||||
'unraid',
|
||||
'synology-dsm',
|
||||
|
|
@ -601,7 +599,7 @@ export const SOURCE_PLATFORM_READINESS_STAGE = {
|
|||
'proxmox-pbs': 'supported',
|
||||
'proxmox-pmg': 'supported',
|
||||
truenas: 'supported',
|
||||
'vmware-vsphere': 'supported',
|
||||
'vmware-vsphere': 'first-lab-ready',
|
||||
unraid: 'presentation-only',
|
||||
'synology-dsm': 'presentation-only',
|
||||
'microsoft-hyperv': 'presentation-only',
|
||||
|
|
|
|||
|
|
@ -172,8 +172,12 @@ func TestPlatformSupportManifestMatchesSupportModel(t *testing.T) {
|
|||
); diff != "" {
|
||||
t.Fatalf("agent host profile storage-family drifted from the canonical support model:\n%s", diff)
|
||||
}
|
||||
if diff := diffPlatformSets(supportedSurfaces, manifest.DefaultInfrastructureSourceOrder); diff != "" {
|
||||
t.Fatalf("default infrastructure source ordering drifted from the canonical supported platform set:\n%s", diff)
|
||||
defaultInfrastructureSources := uniqueSortedPlatforms(append(
|
||||
append([]string(nil), supportedSurfaces...),
|
||||
admitted...,
|
||||
))
|
||||
if diff := diffPlatformSets(defaultInfrastructureSources, manifest.DefaultInfrastructureSourceOrder); diff != "" {
|
||||
t.Fatalf("default infrastructure source ordering drifted from the canonical supported/admitted platform set:\n%s", diff)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -182,14 +186,13 @@ func TestMockCoverageMatchesCurrentSupportedPlatformSet(t *testing.T) {
|
|||
supported := manifestPlatformsByState(t, manifest, "supported")
|
||||
|
||||
checkers := map[string]func(*testing.T, FixtureGraph){
|
||||
"agent": assertAgentMockCoverage,
|
||||
"docker": assertDockerMockCoverage,
|
||||
"kubernetes": assertKubernetesMockCoverage,
|
||||
"proxmox-pbs": assertProxmoxPBSMockCoverage,
|
||||
"proxmox-pmg": assertProxmoxPMGMockCoverage,
|
||||
"proxmox-pve": assertProxmoxPVEMockCoverage,
|
||||
"truenas": assertTrueNASMockCoverage,
|
||||
"vmware-vsphere": assertVMwareMockCoverage,
|
||||
"agent": assertAgentMockCoverage,
|
||||
"docker": assertDockerMockCoverage,
|
||||
"kubernetes": assertKubernetesMockCoverage,
|
||||
"proxmox-pbs": assertProxmoxPBSMockCoverage,
|
||||
"proxmox-pmg": assertProxmoxPMGMockCoverage,
|
||||
"proxmox-pve": assertProxmoxPVEMockCoverage,
|
||||
"truenas": assertTrueNASMockCoverage,
|
||||
}
|
||||
|
||||
if diff := diffPlatformSets(supported, sortedPlatformKeys(checkers)); diff != "" {
|
||||
|
|
@ -203,24 +206,24 @@ func TestMockCoverageMatchesCurrentSupportedPlatformSet(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestVMwareFixturesRemainSupportedAtPhase1Floor(t *testing.T) {
|
||||
func TestVMwareFixturesRemainAdmittedAtPhase1Floor(t *testing.T) {
|
||||
model := loadPlatformSupportModel(t)
|
||||
manifest := loadPlatformSupportManifest(t)
|
||||
supported := manifestPlatformsByState(t, manifest, "supported")
|
||||
admitted := manifestPlatformsByState(t, manifest, "admitted")
|
||||
presentationOnly := manifestPlatformsByState(t, manifest, "presentation-only")
|
||||
|
||||
if !containsPlatform(supported, "vmware-vsphere") {
|
||||
t.Fatal("vmware-vsphere must appear in the current supported platform set after promotion from first-lab-ready")
|
||||
if containsPlatform(supported, "vmware-vsphere") {
|
||||
t.Fatal("vmware-vsphere must not appear in the current supported platform set before live vCenter proof")
|
||||
}
|
||||
if containsPlatform(admitted, "vmware-vsphere") {
|
||||
t.Fatal("vmware-vsphere must not remain in the admitted set after promotion to supported")
|
||||
if !containsPlatform(admitted, "vmware-vsphere") {
|
||||
t.Fatal("vmware-vsphere must remain in the admitted set until live vCenter proof promotes it")
|
||||
}
|
||||
if containsPlatform(presentationOnly, "vmware-vsphere") {
|
||||
t.Fatal("vmware-vsphere must not regress into presentation-only vocabulary once supported")
|
||||
t.Fatal("vmware-vsphere must not regress into presentation-only vocabulary while admitted")
|
||||
}
|
||||
if !strings.Contains(model, "| `vmware-vsphere` |") {
|
||||
t.Fatal("expected platform support model to keep the vmware-vsphere support row")
|
||||
if !strings.Contains(model, "| `vmware-vsphere` | VMware | `vCenter` only in phase 1 |") {
|
||||
t.Fatal("expected platform support model to keep the vmware-vsphere admission row")
|
||||
}
|
||||
vmwareOnboardingPaths, ok := manifestPlatformOnboardingPaths(manifest)["vmware-vsphere"]
|
||||
if !ok {
|
||||
|
|
@ -230,8 +233,11 @@ func TestVMwareFixturesRemainSupportedAtPhase1Floor(t *testing.T) {
|
|||
t.Fatalf("vmware-vsphere onboarding path drifted from the support model:\n%s", diff)
|
||||
}
|
||||
vmwareManifest := requireManifestPlatform(t, manifest, "vmware-vsphere")
|
||||
if vmwareManifest.ReadinessStage != "supported" {
|
||||
t.Fatalf("vmware readiness stage = %q, want supported", vmwareManifest.ReadinessStage)
|
||||
if vmwareManifest.GovernanceState != "admitted" {
|
||||
t.Fatalf("vmware governance state = %q, want admitted", vmwareManifest.GovernanceState)
|
||||
}
|
||||
if vmwareManifest.ReadinessStage != "first-lab-ready" {
|
||||
t.Fatalf("vmware readiness stage = %q, want first-lab-ready", vmwareManifest.ReadinessStage)
|
||||
}
|
||||
if vmwareManifest.PrimaryMode != "api-backed" {
|
||||
t.Fatalf("vmware primary mode = %q, want api-backed", vmwareManifest.PrimaryMode)
|
||||
|
|
@ -247,15 +253,7 @@ func TestVMwareFixturesRemainSupportedAtPhase1Floor(t *testing.T) {
|
|||
}
|
||||
|
||||
graph := buildFixtureGraph(DefaultConfig, time.Date(2026, time.April, 10, 12, 0, 0, 0, time.UTC))
|
||||
if len(graph.PlatformFixtures.VMware.Hosts) == 0 {
|
||||
t.Fatal("expected VMware mock fixtures to include hosts")
|
||||
}
|
||||
if len(graph.PlatformFixtures.VMware.VMs) == 0 {
|
||||
t.Fatal("expected VMware mock fixtures to include VMs")
|
||||
}
|
||||
if len(graph.PlatformFixtures.VMware.Datastores) == 0 {
|
||||
t.Fatal("expected VMware mock fixtures to include datastores")
|
||||
}
|
||||
assertVMwareMockCoverage(t, graph)
|
||||
|
||||
fixture := DefaultVMwareConnectionFixture()
|
||||
if fixture.CollectedAt.IsZero() {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// Code generated by scripts/release_control/generate_platform_support_backend_module.py.
|
||||
// DO NOT EDIT.
|
||||
// Source: docs/release-control/v6/internal/PLATFORM_SUPPORT_MANIFEST.json
|
||||
// Source SHA256: 921181082d41829ac4884d00175791157ac500a27888ca2b81f09a9e97989bda
|
||||
// Source SHA256: 97b7ac58c2c981867dc4052728587d323fc541221135e6bada1191d9d723206b
|
||||
|
||||
package platformsupport
|
||||
|
||||
|
|
@ -13,7 +13,7 @@ const ManifestSourcePath = "docs/release-control/v6/internal/PLATFORM_SUPPORT_MA
|
|||
|
||||
// ManifestSourceSHA256 is the sha256 of the manifest bytes used to produce
|
||||
// this projection.
|
||||
const ManifestSourceSHA256 = "921181082d41829ac4884d00175791157ac500a27888ca2b81f09a9e97989bda"
|
||||
const ManifestSourceSHA256 = "97b7ac58c2c981867dc4052728587d323fc541221135e6bada1191d9d723206b"
|
||||
|
||||
// ManifestSchemaVersion is the schema_version field of the manifest.
|
||||
const ManifestSchemaVersion = 2
|
||||
|
|
|
|||
|
|
@ -377,6 +377,9 @@ def normalize_manifest(raw_manifest: dict[str, Any]) -> dict[str, Any]:
|
|||
supported_ids = [
|
||||
platform["id"] for platform in platforms if platform["governanceState"] == "supported"
|
||||
]
|
||||
admitted_ids = [
|
||||
platform["id"] for platform in platforms if platform["governanceState"] == "admitted"
|
||||
]
|
||||
supported_owning_platform_ids = [
|
||||
platform["id"]
|
||||
for platform in platforms
|
||||
|
|
@ -387,11 +390,11 @@ def normalize_manifest(raw_manifest: dict[str, Any]) -> dict[str, Any]:
|
|||
for platform in platforms
|
||||
if platform["governanceState"] == "supported" and platform["surfaceKind"] == "runtime-lens"
|
||||
]
|
||||
supported_id_set = set(supported_ids)
|
||||
infrastructure_source_id_set = set([*supported_ids, *admitted_ids])
|
||||
for platform_id in default_order:
|
||||
if platform_id not in supported_id_set:
|
||||
if platform_id not in infrastructure_source_id_set:
|
||||
raise ValueError(
|
||||
"default_infrastructure_source_order may only contain supported platforms; "
|
||||
"default_infrastructure_source_order may only contain supported or admitted platforms; "
|
||||
f"got {platform_id}"
|
||||
)
|
||||
|
||||
|
|
@ -458,9 +461,6 @@ def normalize_manifest(raw_manifest: dict[str, Any]) -> dict[str, Any]:
|
|||
storage_family_by_id = {
|
||||
platform["id"]: platform["storageFamily"] for platform in platforms
|
||||
}
|
||||
admitted_ids = [
|
||||
platform["id"] for platform in platforms if platform["governanceState"] == "admitted"
|
||||
]
|
||||
presentation_only_ids = [
|
||||
platform["id"]
|
||||
for platform in platforms
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue