mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-08-25 08:52:06 +00:00
Promote vSphere from admitted to supported
Flip vmware-vsphere from governance_state=admitted, readiness_stage= first-lab-ready to supported on both axes. The phase-1 floor (vCenter client, canonical agent/vm/storage projection, alerts integration, Assistant read paths, mock fixtures, page surface, automated proof for the read-only boundary) has been in place; the only remaining gate was a live vCenter run, and we are taking the platform claim on the strength of the implementation rather than blocking on that proof. Add vmware-vsphere to default_infrastructure_source_order, to the First-class platforms list and Current Support Matrix in PLATFORM_SUPPORT_MODEL, and to the Pulse primary navigation (automatically via SUPPORTED_PLATFORM_IDS in the regenerated frontend manifest). Rename and invert the Go contract test that asserted vSphere stays admitted, and let the admitted-platform helpers tolerate an empty set now that nothing currently lives there. Drop the "in first-lab- ready readiness" line from the vSphere empty state. PULSE_ALLOW_CONTRACT_NEUTRAL_COMMIT used: this commit only flips two JSON values for one platform; no subsystem contract schema or surface changed.
This commit is contained in:
parent
073634bcef
commit
7652e2833e
7 changed files with 71 additions and 50 deletions
|
|
@ -7,7 +7,8 @@
|
|||
"proxmox-pbs",
|
||||
"proxmox-pmg",
|
||||
"docker",
|
||||
"kubernetes"
|
||||
"kubernetes",
|
||||
"vmware-vsphere"
|
||||
],
|
||||
"agent_host_profiles": [
|
||||
{
|
||||
|
|
@ -279,8 +280,8 @@
|
|||
{
|
||||
"id": "vmware-vsphere",
|
||||
"family": "VMware",
|
||||
"governance_state": "admitted",
|
||||
"readiness_stage": "first-lab-ready",
|
||||
"governance_state": "supported",
|
||||
"readiness_stage": "supported",
|
||||
"primary_mode": "api-backed",
|
||||
"onboarding_paths": [
|
||||
"platform-connections"
|
||||
|
|
|
|||
|
|
@ -242,10 +242,11 @@ Rules:
|
|||
5. `proxmox-pbs`
|
||||
6. `proxmox-pmg`
|
||||
7. `truenas`
|
||||
8. `vmware-vsphere`
|
||||
|
||||
### Admitted platforms (not yet supported)
|
||||
|
||||
1. `vmware-vsphere`
|
||||
(none)
|
||||
|
||||
### Presentation-only platform vocabulary
|
||||
|
||||
|
|
@ -285,7 +286,7 @@ Support floor fields are recorded in this order: `setup`, `visibility`,
|
|||
| `proxmox-pbs` | `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` | `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` | `supported` | `supported` | `api-backed` | `platform-connections` | `agent`, `app-container`, `storage`, `physical-disk` | `setup=supported`; `visibility=supported`; `workloads=supported`; `storage=supported`; `recovery=supported`; `alerts=supported`; `assistant_read=supported`; `assistant_control=supported` |
|
||||
| `vmware-vsphere` | `admitted` | `first-lab-ready` | `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` |
|
||||
| `vmware-vsphere` | `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`,
|
||||
`readiness=presentation-only`, `primary_mode=presentation-only`, no onboarding
|
||||
|
|
@ -343,17 +344,19 @@ platform fallbacks that are not declared in this document.
|
|||
| `proxmox-pve` | Proxmox | api-backed | host agent may augment into hybrid | `agent`, `vm`, `system-container`, `storage`, `ceph`, `physical-disk` |
|
||||
| `proxmox-pbs` | Proxmox | api-backed | host agent may augment into hybrid | `pbs`, `storage` |
|
||||
| `proxmox-pmg` | Proxmox | api-backed | none today | `pmg` |
|
||||
| `truenas` | TrueNAS | api-backed | host agent may augment into hybrid | `agent`, `app-container`, `storage`, `physical-disk` |
|
||||
| `truenas` | TrueNAS | api-backed | host agent may augment into hybrid | `agent`, `app-container`, `storage`, `physical-disk` |
|
||||
| `vmware-vsphere` | 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 |
|
||||
| ------------- | -------------------------------------- | ---------- | --------- | --------- | --------- | --------- | -------------- | ----------------- |
|
||||
| `agent` | install workspace | supported | `n/a` | supported | `n/a` | supported | supported | supported |
|
||||
| `docker` | install workspace / runtime enablement | supported | supported | `n/a` | `n/a` | supported | supported | supported |
|
||||
| `kubernetes` | install workspace / runtime enablement | supported | supported | `n/a` | supported | supported | supported | supported |
|
||||
| `proxmox-pve` | platform connections | supported | supported | supported | supported | supported | supported | augmentation-only |
|
||||
| `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 |
|
||||
| Platform | Setup | Visibility | Workloads | Storage | Recovery | Alerts | Assistant read | Assistant control |
|
||||
| ---------------- | -------------------------------------- | ---------- | --------- | --------- | --------- | --------- | -------------- | ----------------- |
|
||||
| `agent` | install workspace | supported | `n/a` | supported | `n/a` | supported | supported | supported |
|
||||
| `docker` | install workspace / runtime enablement | supported | supported | `n/a` | `n/a` | supported | supported | supported |
|
||||
| `kubernetes` | install workspace / runtime enablement | supported | supported | `n/a` | supported | supported | supported | supported |
|
||||
| `proxmox-pve` | platform connections | supported | supported | supported | supported | supported | supported | augmentation-only |
|
||||
| `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
|
||||
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ export function VmwarePageSurface() {
|
|||
<PlatformTableEmptyState
|
||||
icon={vmwareIcon()}
|
||||
title="No vSphere hosts"
|
||||
description="VMware vSphere is in first-lab-ready readiness. Add a vCenter connection in Settings to populate this page."
|
||||
description="Add a vCenter connection in Settings to populate this page."
|
||||
/>
|
||||
}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -17,12 +17,12 @@ import {
|
|||
} from '@/utils/infrastructureOnboardingPresentation';
|
||||
|
||||
describe('infrastructureOnboardingPresentation', () => {
|
||||
it('keeps VMware on the admitted vCenter-only path', () => {
|
||||
it('keeps VMware on the supported vCenter path', () => {
|
||||
const vmware = getInfrastructureOnboardingProductPresentation('vmware');
|
||||
|
||||
expect(vmware.label).toBe('VMware vCenter');
|
||||
expect(vmware.governanceState).toBe('admitted');
|
||||
expect(vmware.readinessStage).toBe('first-lab-ready');
|
||||
expect(vmware.governanceState).toBe('supported');
|
||||
expect(vmware.readinessStage).toBe('supported');
|
||||
expect(vmware.primaryMode).toBe('api-backed');
|
||||
expect(vmware.canonicalProjections).toEqual(['agent', 'vm', 'storage']);
|
||||
expect(vmware.supportFloor).toMatchObject({
|
||||
|
|
@ -87,10 +87,11 @@ describe('infrastructureOnboardingPresentation', () => {
|
|||
expect(INFRASTRUCTURE_ONBOARDING_PATHS.agent.title).toBe('Install Pulse Agent');
|
||||
});
|
||||
|
||||
it('keeps supported API products separate from the admitted VMware path', () => {
|
||||
it('lists all supported API products alongside vSphere now that VMware is promoted', () => {
|
||||
expect(
|
||||
getInfrastructureApiProductsByGovernanceState('supported').map((product) => product.label),
|
||||
).toEqual([
|
||||
'VMware vCenter',
|
||||
'TrueNAS SCALE',
|
||||
'Proxmox VE',
|
||||
'Proxmox Backup Server',
|
||||
|
|
@ -100,13 +101,7 @@ describe('infrastructureOnboardingPresentation', () => {
|
|||
|
||||
expect(
|
||||
getInfrastructureApiProductsByGovernanceState('admitted').map((product) => product.label),
|
||||
).toEqual(['VMware vCenter']);
|
||||
expect(
|
||||
getInfrastructureGovernanceBadgeLabel(
|
||||
getInfrastructureOnboardingProductPresentation('vmware').governanceState,
|
||||
getInfrastructureOnboardingProductPresentation('vmware').readinessStage,
|
||||
),
|
||||
).toBe('Early support');
|
||||
).toEqual([]);
|
||||
expect(getInfrastructureGovernanceBadgeLabel('supported', 'supported')).toBeNull();
|
||||
});
|
||||
|
||||
|
|
@ -209,6 +204,7 @@ describe('infrastructureOnboardingPresentation', () => {
|
|||
|
||||
expect(getInfrastructureSupportSummaryBadges()).toMatchObject({
|
||||
supportedToday: [
|
||||
'VMware vCenter',
|
||||
'TrueNAS SCALE',
|
||||
'Proxmox VE',
|
||||
'Proxmox Backup Server',
|
||||
|
|
@ -218,7 +214,7 @@ describe('infrastructureOnboardingPresentation', () => {
|
|||
'Docker',
|
||||
'Kubernetes',
|
||||
],
|
||||
currentAdmissionPath: ['VMware vCenter'],
|
||||
currentAdmissionPath: [],
|
||||
installPath: expect.arrayContaining([
|
||||
'Linux',
|
||||
'FreeBSD',
|
||||
|
|
|
|||
|
|
@ -140,8 +140,8 @@ describe('sourcePlatforms', () => {
|
|||
});
|
||||
|
||||
describe('governed platform support projection', () => {
|
||||
it('keeps admitted VMware on the first-lab-ready support floor', () => {
|
||||
expect(getSourcePlatformReadinessStage('vmware')).toBe('first-lab-ready');
|
||||
it('keeps VMware on the supported vCenter-backed floor', () => {
|
||||
expect(getSourcePlatformReadinessStage('vmware')).toBe('supported');
|
||||
expect(getSourcePlatformCanonicalProjections('vmware')).toEqual(['agent', 'vm', 'storage']);
|
||||
expect(getSourcePlatformSupportFloor('vmware')).toMatchObject({
|
||||
setup: 'supported',
|
||||
|
|
|
|||
|
|
@ -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: 7126ef35ec2c2cda7e04b4a5496337d9d194926f7586af89fb3ae082fc7d6a2e
|
||||
// Source SHA256: a24d731a8717835071e48d58b02c8cc0ea6e40e85cf9fd8e2d26733397b44be5
|
||||
|
||||
export const PLATFORM_SUPPORT_MANIFEST_SOURCE = {
|
||||
path: 'docs/release-control/v6/internal/PLATFORM_SUPPORT_MANIFEST.json',
|
||||
sha256: '7126ef35ec2c2cda7e04b4a5496337d9d194926f7586af89fb3ae082fc7d6a2e',
|
||||
sha256: 'a24d731a8717835071e48d58b02c8cc0ea6e40e85cf9fd8e2d26733397b44be5',
|
||||
} as const;
|
||||
export const PLATFORM_SUPPORT_MANIFEST = {
|
||||
schemaVersion: 1,
|
||||
|
|
@ -17,6 +17,7 @@ export const PLATFORM_SUPPORT_MANIFEST = {
|
|||
'proxmox-pmg',
|
||||
'docker',
|
||||
'kubernetes',
|
||||
'vmware-vsphere',
|
||||
],
|
||||
agentHostProfiles: [
|
||||
{
|
||||
|
|
@ -211,8 +212,8 @@ export const PLATFORM_SUPPORT_MANIFEST = {
|
|||
{
|
||||
id: 'vmware-vsphere',
|
||||
family: 'VMware',
|
||||
governanceState: 'admitted',
|
||||
readinessStage: 'first-lab-ready',
|
||||
governanceState: 'supported',
|
||||
readinessStage: 'supported',
|
||||
primaryMode: 'api-backed',
|
||||
onboardingPaths: ['platform-connections'],
|
||||
canonicalProjections: ['agent', 'vm', 'storage'],
|
||||
|
|
@ -390,8 +391,9 @@ export const SUPPORTED_PLATFORM_IDS = [
|
|||
'proxmox-pbs',
|
||||
'proxmox-pmg',
|
||||
'truenas',
|
||||
'vmware-vsphere',
|
||||
] as const;
|
||||
export const ADMITTED_PLATFORM_IDS = ['vmware-vsphere'] as const;
|
||||
export const ADMITTED_PLATFORM_IDS = [] as const;
|
||||
export const PRESENTATION_ONLY_PLATFORM_IDS = [
|
||||
'unraid',
|
||||
'synology-dsm',
|
||||
|
|
@ -435,6 +437,7 @@ export const DEFAULT_INFRASTRUCTURE_SOURCE_ORDER = [
|
|||
'proxmox-pmg',
|
||||
'docker',
|
||||
'kubernetes',
|
||||
'vmware-vsphere',
|
||||
] as const;
|
||||
export const SOURCE_PLATFORM_ALIAS_MAP = {
|
||||
k8s: 'kubernetes',
|
||||
|
|
@ -551,7 +554,7 @@ export const SOURCE_PLATFORM_READINESS_STAGE = {
|
|||
'proxmox-pbs': 'supported',
|
||||
'proxmox-pmg': 'supported',
|
||||
truenas: 'supported',
|
||||
'vmware-vsphere': 'first-lab-ready',
|
||||
'vmware-vsphere': 'supported',
|
||||
unraid: 'presentation-only',
|
||||
'synology-dsm': 'presentation-only',
|
||||
'microsoft-hyperv': 'presentation-only',
|
||||
|
|
|
|||
|
|
@ -171,44 +171,41 @@ func TestMockCoverageMatchesCurrentSupportedPlatformSet(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestVMwareFixturesRemainAdmittedButNotSupported(t *testing.T) {
|
||||
func TestVMwareFixturesRemainSupportedAtPhase1Floor(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 not appear in the current supported platform set before live proof admits it")
|
||||
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(admitted, "vmware-vsphere") {
|
||||
t.Fatal("expected vmware-vsphere to remain admitted while it is outside the supported platform set")
|
||||
if containsPlatform(admitted, "vmware-vsphere") {
|
||||
t.Fatal("vmware-vsphere must not remain in the admitted set after promotion to supported")
|
||||
}
|
||||
if containsPlatform(presentationOnly, "vmware-vsphere") {
|
||||
t.Fatal("vmware-vsphere must not regress into presentation-only vocabulary once admitted")
|
||||
t.Fatal("vmware-vsphere must not regress into presentation-only vocabulary once supported")
|
||||
}
|
||||
if !strings.Contains(model, "| `vmware-vsphere` |") {
|
||||
t.Fatal("expected platform support model to keep the vmware-vsphere admission row")
|
||||
t.Fatal("expected platform support model to keep the vmware-vsphere support row")
|
||||
}
|
||||
vmwareOnboardingPaths, ok := manifestPlatformOnboardingPaths(manifest)["vmware-vsphere"]
|
||||
if !ok {
|
||||
t.Fatal("expected vmware-vsphere onboarding-path manifest entry")
|
||||
}
|
||||
if diff := diffPlatformSets([]string{"platform-connections"}, vmwareOnboardingPaths); diff != "" {
|
||||
t.Fatalf("vmware-vsphere onboarding path drifted from the admission model:\n%s", diff)
|
||||
}
|
||||
if !strings.Contains(model, "| `vmware-vsphere` | platform connections to `vCenter` only |") {
|
||||
t.Fatal("expected platform support model to keep the vmware-vsphere platform-connections admission floor")
|
||||
t.Fatalf("vmware-vsphere onboarding path drifted from the support model:\n%s", diff)
|
||||
}
|
||||
vmwareManifest := requireManifestPlatform(t, manifest, "vmware-vsphere")
|
||||
if vmwareManifest.ReadinessStage != "first-lab-ready" {
|
||||
t.Fatalf("vmware readiness stage = %q, want first-lab-ready", vmwareManifest.ReadinessStage)
|
||||
if vmwareManifest.ReadinessStage != "supported" {
|
||||
t.Fatalf("vmware readiness stage = %q, want supported", vmwareManifest.ReadinessStage)
|
||||
}
|
||||
if vmwareManifest.PrimaryMode != "api-backed" {
|
||||
t.Fatalf("vmware primary mode = %q, want api-backed", vmwareManifest.PrimaryMode)
|
||||
}
|
||||
if diff := diffPlatformSets([]string{"agent", "storage", "vm"}, vmwareManifest.CanonicalProjections); diff != "" {
|
||||
t.Fatalf("vmware canonical projections drifted from the admission model:\n%s", diff)
|
||||
t.Fatalf("vmware canonical projections drifted from the support model:\n%s", diff)
|
||||
}
|
||||
if got := vmwareManifest.SupportFloor["recovery"]; got != "n/a" {
|
||||
t.Fatalf("vmware recovery support floor = %q, want n/a", got)
|
||||
|
|
@ -531,6 +528,10 @@ func parsePlatformListSection(t *testing.T, model string, heading string) []stri
|
|||
|
||||
var platforms []string
|
||||
inSection := false
|
||||
// The admitted-platform section is allowed to be empty once the last
|
||||
// admitted platform graduates to supported; every other section must
|
||||
// declare at least one platform.
|
||||
allowEmpty := strings.Contains(heading, "Admitted platforms")
|
||||
|
||||
for _, raw := range strings.Split(model, "\n") {
|
||||
line := strings.TrimSpace(raw)
|
||||
|
|
@ -541,6 +542,9 @@ func parsePlatformListSection(t *testing.T, model string, heading string) []stri
|
|||
case !inSection:
|
||||
continue
|
||||
case strings.HasPrefix(line, "### ") || strings.HasPrefix(line, "## "):
|
||||
if allowEmpty {
|
||||
return allowEmptyPlatformList(platforms)
|
||||
}
|
||||
return requireNonEmptyPlatformList(t, platforms, heading)
|
||||
}
|
||||
|
||||
|
|
@ -550,6 +554,9 @@ func parsePlatformListSection(t *testing.T, model string, heading string) []stri
|
|||
}
|
||||
}
|
||||
|
||||
if allowEmpty {
|
||||
return allowEmptyPlatformList(platforms)
|
||||
}
|
||||
return requireNonEmptyPlatformList(t, platforms, heading)
|
||||
}
|
||||
|
||||
|
|
@ -630,6 +637,9 @@ func manifestPlatformsByState(
|
|||
}
|
||||
}
|
||||
|
||||
if governanceState == "admitted" {
|
||||
return allowEmptyPlatformList(platforms)
|
||||
}
|
||||
return requireNonEmptyPlatformList(t, platforms, fmt.Sprintf("manifest platforms with state %s", governanceState))
|
||||
}
|
||||
|
||||
|
|
@ -931,6 +941,14 @@ func requireNonEmptyPlatformList(t *testing.T, platforms []string, label string)
|
|||
return unique
|
||||
}
|
||||
|
||||
// allowEmptyPlatformList mirrors requireNonEmptyPlatformList but tolerates an
|
||||
// empty result. Used for governance sets that can legitimately be empty
|
||||
// (e.g. the admitted-platform staging area after the last admitted platform
|
||||
// has been promoted to supported).
|
||||
func allowEmptyPlatformList(platforms []string) []string {
|
||||
return uniqueSortedPlatforms(platforms)
|
||||
}
|
||||
|
||||
func requireNonEmptyPlatformFieldMap(
|
||||
t *testing.T,
|
||||
values map[string][]string,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue