Skip to content

SPLAT-2410: Introduce Cluster API for OpenShift Installations on vSphere#455

Open
AnnaZivkovic wants to merge 5 commits intoopenshift:mainfrom
AnnaZivkovic:vsphere-conversion
Open

SPLAT-2410: Introduce Cluster API for OpenShift Installations on vSphere#455
AnnaZivkovic wants to merge 5 commits intoopenshift:mainfrom
AnnaZivkovic:vsphere-conversion

Conversation

@AnnaZivkovic
Copy link
Copy Markdown

@AnnaZivkovic AnnaZivkovic commented Feb 5, 2026

Enables vSphere support in the Machine API to Cluster API conversion framework. It implements bidirectional conversion between vSphere Machine API resources (Machines/MachineSets) and Cluster API resources (Machines/MachineTemplates), including support for vSphere-specific v1beta2 conditions.

Changes

  • New conversion libraries:
    • pkg/conversion/mapi2capi/vsphere.go - Converts Machine API to Cluster API
    • pkg/conversion/capi2mapi/vsphere.go - Converts Cluster API to Machine API
  • Controller integration:
    • Registered vSphere handlers in machinesync controller
    • Registered vSphere handlers in machinesetsync controller
    • Enabled vSphere provider in machine-api-migration binary
  • Test coverage:
    • Comprehensive unit tests for both conversion directions
    • Fuzz testing for conversion stability
  • Added v1beta2 condition handling (pkg/util/conditions.go):
    • GetV1Beta2Condition() - Retrieves conditions from status.v1beta2.conditions
    • GetV1Beta2ConditionStatus() - Gets condition status from v1beta2 location
    • GetConditionStatusFromInfraObject() - Intelligently checks both v1beta2 (vSphere) and v1beta1 (AWS/Azure/GCP) condition locations
    • EnsureCAPIV1Beta2Conditions() - Merges v1beta2 conditions during conversion
    • Backward compatibility: Maintains support for existing providers using v1beta1 conditions while adding v1beta2 support for vSphere

Summary by CodeRabbit

  • New Features

    • Adds VMware vSphere platform support across migration, machine and machineset sync, and conversion flows; includes providerSpec parsing and round‑trip conversions.
    • Startup now registers vSphere types and propagates feature‑gate handling to conditionally enable vSphere controllers.
  • Bug Fixes

    • Uses infra‑aware condition/status retrieval in migration flows to correctly detect paused state.
  • Tests

    • Adds extensive unit and fuzz tests for vSphere conversion and round‑trip scenarios.

@openshift-ci-robot
Copy link
Copy Markdown

Pipeline controller notification
This repo is configured to use the pipeline controller. Second-stage tests will be triggered either automatically or after lgtm label is added, depending on the repository configuration. The pipeline controller will automatically detect which contexts are required and will utilize /test Prow commands to trigger the second stage.

For optional jobs, comment /test ? to see a list of all defined jobs. To trigger manually all jobs from second stage use /pipeline required command.

This repository is configured in: LGTM mode

@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Feb 5, 2026
@openshift-ci-robot
Copy link
Copy Markdown

openshift-ci-robot commented Feb 5, 2026

@AnnaZivkovic: This pull request references SPLAT-2410 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.22.0" version, but no target version was set.

Details

In response to this:

Enables vSphere support in the Machine API to Cluster API conversion framework. It implements bidirectional conversion between vSphere Machine API resources (Machines/MachineSets) and Cluster API resources (Machines/MachineTemplates), including support for vSphere-specific v1beta2 conditions.

Changes

  • New conversion libraries:
    • pkg/conversion/mapi2capi/vsphere.go - Converts Machine API to Cluster API
    • pkg/conversion/capi2mapi/vsphere.go - Converts Cluster API to Machine API
  • Controller integration:
    • Registered vSphere handlers in machinesync controller
    • Registered vSphere handlers in machinesetsync controller
    • Enabled vSphere provider in machine-api-migration binary
  • Test coverage:
    • Comprehensive unit tests for both conversion directions
    • Fuzz testing for conversion stability
  • Added v1beta2 condition handling (pkg/util/conditions.go):
    • GetV1Beta2Condition() - Retrieves conditions from status.v1beta2.conditions
    • GetV1Beta2ConditionStatus() - Gets condition status from v1beta2 location
    • GetConditionStatusFromInfraObject() - Intelligently checks both v1beta2 (vSphere) and v1beta1 (AWS/Azure/GCP) condition locations
    • EnsureCAPIV1Beta2Conditions() - Merges v1beta2 conditions during conversion
    • Backward compatibility: Maintains support for existing providers using v1beta1 conditions while adding v1beta2 support for vSphere

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Feb 5, 2026

Important

Review skipped

Auto reviews are limited based on label configuration.

🚫 Review skipped — only excluded labels are configured. (1)
  • do-not-merge/work-in-progress

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: 5bfe702c-9240-43d6-912e-03d459d2d657

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds vSphere platform support and feature‑gate driven startup: registers the VSphere API scheme; implements bidirectional MAPI↔CAPI vSphere converters, controller platform branches, v1beta2 condition helpers, and extensive unit + fuzz tests; feature gates now control vSphere controller startup.

Changes

Cohort / File(s) Summary
Command, scheme & feature gates
cmd/machine-api-migration/main.go
Register VSphere API scheme; propagate FeatureGateAccess from checkFeatureGates into platform checks; gate VSphere controller startup on FeatureGateClusterAPIMachineManagementVSphere.
Controller platform & infra handling
pkg/controllers/machinemigration/machine_migration_controller.go, pkg/controllers/machinesetsync/machineset_sync_controller.go, pkg/controllers/machinesync/machine_sync_controller.go, pkg/controllers/machinesync/machine_sync_mapi2capi_infrastructure.go
Add VSphere-specific branches and type handling across infra/template lists, conversion/comparison logic, and provider-aware diffs; replace infra condition retrieval with GetConditionStatusFromInfraObject.
CAPI → MAPI conversion + tests
pkg/conversion/capi2mapi/vsphere.go, pkg/conversion/capi2mapi/vsphere_test.go, pkg/conversion/capi2mapi/vsphere_fuzz_test.go
New converter mapping CAPV VSphereMachine/Template/Cluster → MAPI Machine/MachineSet; builds VSphere providerSpec (networks, disks, clone, workspace), validations/warnings; add unit and fuzz tests.
MAPI → CAPI conversion + tests
pkg/conversion/mapi2capi/vsphere.go, pkg/conversion/mapi2capi/vsphere_test.go, pkg/conversion/mapi2capi/vsphere_fuzz_test.go
New converter mapping MAPI Machine/MachineSet → CAPI VSphereMachine/Template; RawExtension parsing, template derivation, helper converters, validations; add unit and fuzz tests.
ProviderSpec parsing util
pkg/conversion/mapi2capi/util.go
Add vSphere branch to ProviderSpecFromRawExtension with vSphere-specific error propagation.
Condition utilities
pkg/util/conditions.go
Add v1beta2 condition accessors (GetV1Beta2Condition, GetV1Beta2ConditionStatus), getConditionFromList helper, and GetConditionStatusFromInfraObject that falls back from v1beta1 to v1beta2 for infra objects.
Minor controller tweak
pkg/controllers/machinemigration/machine_migration_controller.go
Replace util.GetConditionStatus with util.GetConditionStatusFromInfraObject to support v1beta2 infra conditions.

Sequence Diagram(s)

sequenceDiagram
    participant Admin as Administrator
    participant CAPI as CAPI (VSphereMachine / Template)
    participant MigCtrl as Migration Controller
    participant C2M as CAPI→MAPI Converter
    participant MAPI as MAPI (Machine / ProviderSpec)
    participant Cluster as Target Cluster

    Admin->>CAPI: Create/Modify VSphere CAPI resources
    CAPI->>MigCtrl: Controller watch / reconcile
    MigCtrl->>C2M: FromMachineAndVSphereMachineAndVSphereCluster(...)
    C2M->>C2M: Parse CAPV spec (networks, disks, clone, workspace)
    C2M->>MAPI: Emit MAPI Machine + ProviderSpec
    MigCtrl->>Cluster: Apply MAPI Machine
    Cluster->>Admin: Provisioning outcome
Loading
sequenceDiagram
    participant Admin as Administrator
    participant Cluster as MAPI (Machine with vSphere ProviderSpec)
    participant SyncCtrl as Sync Controller
    participant Parser as ProviderSpec Parser
    participant M2C as MAPI→CAPI Converter
    participant CAPI as CAPI (VSphereMachine / Template)

    Admin->>Cluster: Create MAPI Machine with vSphere ProviderSpec
    Cluster->>SyncCtrl: Controller reconcile
    SyncCtrl->>Parser: ProviderSpecFromRawExtension(...)
    Parser->>M2C: vSphere provider parsed
    M2C->>M2C: Build VSphereMachine and Template, validate
    M2C->>CAPI: Return CAPI Machine + Template
    SyncCtrl->>CAPI: Create/Update CAPI resources
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Poem

🐰 I hopped through specs and gates with care,

Spun networks, disks, and templates in the air.
Converters nibbled, controllers hummed a tune,
Tests polished fur beneath the migration moon.
A carrot for VSphere — ready soon!

🚥 Pre-merge checks | ✅ 3 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.76% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly references the main objective of the PR: introducing vSphere support to Cluster API for OpenShift installations.
Merge Conflict Detection ✅ Passed ✅ No merge conflicts detected when merging into main

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

@openshift-ci openshift-ci bot requested review from damdo and mdbooth February 5, 2026 21:13
@openshift-ci-robot
Copy link
Copy Markdown

openshift-ci-robot commented Feb 5, 2026

@AnnaZivkovic: This pull request references SPLAT-2410 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.22.0" version, but no target version was set.

Details

In response to this:

Enables vSphere support in the Machine API to Cluster API conversion framework. It implements bidirectional conversion between vSphere Machine API resources (Machines/MachineSets) and Cluster API resources (Machines/MachineTemplates), including support for vSphere-specific v1beta2 conditions.

Changes

  • New conversion libraries:
    • pkg/conversion/mapi2capi/vsphere.go - Converts Machine API to Cluster API
    • pkg/conversion/capi2mapi/vsphere.go - Converts Cluster API to Machine API
  • Controller integration:
    • Registered vSphere handlers in machinesync controller
    • Registered vSphere handlers in machinesetsync controller
    • Enabled vSphere provider in machine-api-migration binary
  • Test coverage:
    • Comprehensive unit tests for both conversion directions
    • Fuzz testing for conversion stability
  • Added v1beta2 condition handling (pkg/util/conditions.go):
    • GetV1Beta2Condition() - Retrieves conditions from status.v1beta2.conditions
    • GetV1Beta2ConditionStatus() - Gets condition status from v1beta2 location
    • GetConditionStatusFromInfraObject() - Intelligently checks both v1beta2 (vSphere) and v1beta1 (AWS/Azure/GCP) condition locations
    • EnsureCAPIV1Beta2Conditions() - Merges v1beta2 conditions during conversion
    • Backward compatibility: Maintains support for existing providers using v1beta1 conditions while adding v1beta2 support for vSphere

Summary by CodeRabbit

Release Notes

  • New Features

  • Added VMware vSphere platform support for machine and machine set migration and synchronization, enabling comprehensive support for vSphere-specific configurations including networking, data disk provisioning modes, clone modes, and workspace management.

  • Tests

  • Added extensive test coverage for vSphere machine migration, machine set synchronization, and cross-platform conversion workflows.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Fix all issues with AI agents
In `@pkg/controllers/machinesetsync/machineset_sync_controller.go`:
- Around line 395-400: The loop that appends pointers uses &template (range
variable) which causes pointer aliasing so every entry in outdatedTemplates
points to the same item; change the iteration to index-based access (e.g., for i
:= range list.Items { tmpl := &list.Items[i]; if tmpl.GetName() !=
newInfraMachineTemplateName { outdatedTemplates = append(outdatedTemplates,
tmpl) } }) for the VSphereMachineTemplateList case and make the identical change
in the AWS, IBMPowerVS, and OpenStack cases so you take the address of the slice
element (list.Items[i]) instead of the range variable.

In `@pkg/conversion/mapi2capi/vsphere.go`:
- Around line 130-135: The code dereferences v.infrastructure in the error path;
change the block to compute a nil-safe infraName before calling field.Invalid
(e.g. infraName := ""; if v.infrastructure != nil { infraName =
v.infrastructure.Status.InfrastructureName }) and then call errs = append(errs,
field.Invalid(field.NewPath("infrastructure", "status", "infrastructureName"),
infraName, "infrastructure cannot be nil and
infrastructure.Status.InfrastructureName cannot be empty")); keep the existing
else branch that sets capiMachine.Spec.ClusterName and
capiMachine.Labels[clusterv1.ClusterNameLabel] unchanged.
- Around line 197-203: The code dereferences v.infrastructure without checking
for nil when building the field.Invalid error and when assigning cluster fields;
change the logic to first check nil before accessing Status.InfrastructureName
(e.g., evaluate infraName only after confirming v.infrastructure != nil) and use
that safe value for the field.Invalid call and in the assignments to
capiMachineSet.Spec.Template.Spec.ClusterName, capiMachineSet.Spec.ClusterName,
and capiMachineSet.Labels[clusterv1.ClusterNameLabel]; ensure the nil branch
appends the error and the non-nil branch performs the assignments.

In `@pkg/util/conditions.go`:
- Around line 147-159: The docstring for GetConditionStatusFromInfraObject
contradicts the implementation: the code (and inline comment) call
GetConditionStatus (v1beta1) first, then fall back to GetV1Beta2ConditionStatus
(v1beta2); update the function comment to state it tries v1beta1 first (AWS,
Azure, GCP, etc.) and then falls back to v1beta2 (vSphere/newer providers), and
adjust any inline comment to match this behavior so documentation and
implementation are consistent.
🧹 Nitpick comments (4)
pkg/conversion/capi2mapi/vsphere_test.go (1)

348-399: Consider expanding MachineSet test coverage.

The MachineSet conversion test table has only a single base configuration entry, while the Machine conversion tests cover many scenarios (clone modes, data disks, network configurations, etc.). Since ToMachineSet internally calls the Machine conversion logic, the core paths are tested, but adding a few more MachineSet-specific scenarios (e.g., with different replica counts, failure domains, or template variations) could improve confidence in the integration.

pkg/conversion/capi2mapi/vsphere_fuzz_test.go (1)

142-189: Consider extracting shared spec normalization logic.

The normalization logic in the VSphereMachineSpec fuzzer (lines 142-189) and VSphereMachineTemplateSpec fuzzer (lines 210-254) is nearly identical. The only difference is that the template fuzzer accesses fields via spec.Template.Spec.* instead of spec.*.

While acceptable for fuzz tests, extracting a shared helper function could reduce maintenance burden if fields need to be added or removed in the future.

Also applies to: 210-254

pkg/conversion/capi2mapi/vsphere.go (1)

202-206: Remove commented-out code artifacts.

These lines appear to be leftover development artifacts that should be cleaned up before merging:

  • Line 202-203: Commented TODO about delete policy
  • Line 205: Incomplete comment about labels
🧹 Proposed fix
 	mapiMachineSet.Spec.Template.ObjectMeta.Annotations = mapiMachine.ObjectMeta.Annotations
 	mapiMachineSet.Spec.Template.ObjectMeta.Labels = mapiMachine.ObjectMeta.Labels

-	//// todo: jcallen: afaik the default delete policy is empty
-	//mapiMachineSet.Spec.DeletePolicy = ""
-
-	//mapiMachineSet.Spec.Template.ObjectMeta.Labels[]
-
 	return mapiMachineSet, warnings, nil
pkg/conversion/mapi2capi/vsphere.go (1)

399-408: Consider warning on unknown clone mode values.

The function silently defaults to FullClone for any unrecognized clone mode value. While defaulting is reasonable, this could mask configuration errors or unexpected values.

Consider logging a warning or returning it in the warnings slice when an unexpected value is encountered.

💡 Example approach
// To add warning capability, change the function signature:
func convertMAPICloneModeToCAPI(mapiMode mapiv1beta1.CloneMode) (vspherev1.CloneMode, []string) {
    switch mapiMode {
    case mapiv1beta1.FullClone:
        return vspherev1.FullClone, nil
    case mapiv1beta1.LinkedClone:
        return vspherev1.LinkedClone, nil
    case "":
        return vspherev1.FullClone, nil
    default:
        return vspherev1.FullClone, []string{fmt.Sprintf("unknown clone mode %q, defaulting to FullClone", mapiMode)}
    }
}

@openshift-ci-robot
Copy link
Copy Markdown

openshift-ci-robot commented Feb 5, 2026

@AnnaZivkovic: This pull request references SPLAT-2410 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.22.0" version, but no target version was set.

Details

In response to this:

Enables vSphere support in the Machine API to Cluster API conversion framework. It implements bidirectional conversion between vSphere Machine API resources (Machines/MachineSets) and Cluster API resources (Machines/MachineTemplates), including support for vSphere-specific v1beta2 conditions.

Changes

  • New conversion libraries:
    • pkg/conversion/mapi2capi/vsphere.go - Converts Machine API to Cluster API
    • pkg/conversion/capi2mapi/vsphere.go - Converts Cluster API to Machine API
  • Controller integration:
    • Registered vSphere handlers in machinesync controller
    • Registered vSphere handlers in machinesetsync controller
    • Enabled vSphere provider in machine-api-migration binary
  • Test coverage:
    • Comprehensive unit tests for both conversion directions
    • Fuzz testing for conversion stability
  • Added v1beta2 condition handling (pkg/util/conditions.go):
    • GetV1Beta2Condition() - Retrieves conditions from status.v1beta2.conditions
    • GetV1Beta2ConditionStatus() - Gets condition status from v1beta2 location
    • GetConditionStatusFromInfraObject() - Intelligently checks both v1beta2 (vSphere) and v1beta1 (AWS/Azure/GCP) condition locations
    • EnsureCAPIV1Beta2Conditions() - Merges v1beta2 conditions during conversion
    • Backward compatibility: Maintains support for existing providers using v1beta1 conditions while adding v1beta2 support for vSphere

Summary by CodeRabbit

  • New Features

  • Adds VMware vSphere platform support across machine/machineset sync and migration, including end-to-end conversion mappings and providerSpec handling.

  • Adds providerSpec parsing for vSphere and improved condition-status retrieval for vSphere infra objects.

  • Tests

  • Adds extensive unit and fuzz tests covering vSphere conversions, machine/machineset scenarios, and round-trip validation.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci-robot
Copy link
Copy Markdown

openshift-ci-robot commented Feb 6, 2026

@AnnaZivkovic: This pull request references SPLAT-2410 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.22.0" version, but no target version was set.

Details

In response to this:

Enables vSphere support in the Machine API to Cluster API conversion framework. It implements bidirectional conversion between vSphere Machine API resources (Machines/MachineSets) and Cluster API resources (Machines/MachineTemplates), including support for vSphere-specific v1beta2 conditions.

Changes

  • New conversion libraries:
    • pkg/conversion/mapi2capi/vsphere.go - Converts Machine API to Cluster API
    • pkg/conversion/capi2mapi/vsphere.go - Converts Cluster API to Machine API
  • Controller integration:
    • Registered vSphere handlers in machinesync controller
    • Registered vSphere handlers in machinesetsync controller
    • Enabled vSphere provider in machine-api-migration binary
  • Test coverage:
    • Comprehensive unit tests for both conversion directions
    • Fuzz testing for conversion stability
  • Added v1beta2 condition handling (pkg/util/conditions.go):
    • GetV1Beta2Condition() - Retrieves conditions from status.v1beta2.conditions
    • GetV1Beta2ConditionStatus() - Gets condition status from v1beta2 location
    • GetConditionStatusFromInfraObject() - Intelligently checks both v1beta2 (vSphere) and v1beta1 (AWS/Azure/GCP) condition locations
    • EnsureCAPIV1Beta2Conditions() - Merges v1beta2 conditions during conversion
    • Backward compatibility: Maintains support for existing providers using v1beta1 conditions while adding v1beta2 support for vSphere

Summary by CodeRabbit

  • New Features

  • Adds VMware vSphere platform support across machine, machineset sync, and migration flows, including end-to-end conversion mappings and providerSpec handling.

  • Registers vSphere types so vSphere clusters are recognized at startup.

  • Adds vSphere-aware condition/status retrieval for infrastructure objects.

  • Bug Fixes

  • Adjusts condition retrieval usage in migration controller to use the infra-aware path.

  • Tests

  • Adds extensive unit and fuzz tests covering vSphere conversions and round-trip scenarios.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@jcpowermac
Copy link
Copy Markdown

/test e2e-vsphere-capi-techpreview

@jcpowermac
Copy link
Copy Markdown

/test lint

pod something something failed

@openshift-ci-robot
Copy link
Copy Markdown

openshift-ci-robot commented Feb 16, 2026

@AnnaZivkovic: This pull request references SPLAT-2410 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.22.0" version, but no target version was set.

Details

In response to this:

Enables vSphere support in the Machine API to Cluster API conversion framework. It implements bidirectional conversion between vSphere Machine API resources (Machines/MachineSets) and Cluster API resources (Machines/MachineTemplates), including support for vSphere-specific v1beta2 conditions.

Changes

  • New conversion libraries:
    • pkg/conversion/mapi2capi/vsphere.go - Converts Machine API to Cluster API
    • pkg/conversion/capi2mapi/vsphere.go - Converts Cluster API to Machine API
  • Controller integration:
    • Registered vSphere handlers in machinesync controller
    • Registered vSphere handlers in machinesetsync controller
    • Enabled vSphere provider in machine-api-migration binary
  • Test coverage:
    • Comprehensive unit tests for both conversion directions
    • Fuzz testing for conversion stability
  • Added v1beta2 condition handling (pkg/util/conditions.go):
    • GetV1Beta2Condition() - Retrieves conditions from status.v1beta2.conditions
    • GetV1Beta2ConditionStatus() - Gets condition status from v1beta2 location
    • GetConditionStatusFromInfraObject() - Intelligently checks both v1beta2 (vSphere) and v1beta1 (AWS/Azure/GCP) condition locations
    • EnsureCAPIV1Beta2Conditions() - Merges v1beta2 conditions during conversion
    • Backward compatibility: Maintains support for existing providers using v1beta1 conditions while adding v1beta2 support for vSphere

Summary by CodeRabbit

  • New Features

  • Adds VMware vSphere platform support across machine, machineset sync, migration, and conversion flows; providerSpec parsing and round‑trip conversions included.

  • Startup now registers vSphere types and respects feature gates to conditionally enable vSphere controllers.

  • Bug Fixes

  • Uses infra‑aware condition/status retrieval in migration flows.

  • Tests

  • Adds extensive unit and fuzz tests for vSphere conversion and round‑trip scenarios.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci-robot
Copy link
Copy Markdown

openshift-ci-robot commented Feb 16, 2026

@AnnaZivkovic: This pull request references SPLAT-2410 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.22.0" version, but no target version was set.

Details

In response to this:

Enables vSphere support in the Machine API to Cluster API conversion framework. It implements bidirectional conversion between vSphere Machine API resources (Machines/MachineSets) and Cluster API resources (Machines/MachineTemplates), including support for vSphere-specific v1beta2 conditions.

Changes

  • New conversion libraries:
    • pkg/conversion/mapi2capi/vsphere.go - Converts Machine API to Cluster API
    • pkg/conversion/capi2mapi/vsphere.go - Converts Cluster API to Machine API
  • Controller integration:
    • Registered vSphere handlers in machinesync controller
    • Registered vSphere handlers in machinesetsync controller
    • Enabled vSphere provider in machine-api-migration binary
  • Test coverage:
    • Comprehensive unit tests for both conversion directions
    • Fuzz testing for conversion stability
  • Added v1beta2 condition handling (pkg/util/conditions.go):
    • GetV1Beta2Condition() - Retrieves conditions from status.v1beta2.conditions
    • GetV1Beta2ConditionStatus() - Gets condition status from v1beta2 location
    • GetConditionStatusFromInfraObject() - Intelligently checks both v1beta2 (vSphere) and v1beta1 (AWS/Azure/GCP) condition locations
    • EnsureCAPIV1Beta2Conditions() - Merges v1beta2 conditions during conversion
    • Backward compatibility: Maintains support for existing providers using v1beta1 conditions while adding v1beta2 support for vSphere

Summary by CodeRabbit

  • New Features

  • Adds VMware vSphere platform support across migration, machine and machineset sync, and conversion flows; includes providerSpec parsing and round‑trip conversions.

  • Startup now registers vSphere types and propagates feature‑gate handling to conditionally enable vSphere controllers.

  • Bug Fixes

  • Uses infra‑aware condition/status retrieval in migration flows to correctly detect paused state.

  • Tests

  • Adds extensive unit and fuzz tests for vSphere conversion and round‑trip scenarios.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
Verify each finding against the current code and only fix it if needed.


In `@pkg/conversion/capi2mapi/vsphere_test.go`:
- Around line 348-399: The test suite for MachineSet conversion only contains a
single base Entry; add additional DescribeTable entries using the
vsphereCAPI2MAPIMachinesetConversionInput struct to mirror the Machine tests
(cover unsupported clone mode, invalid data disk provisioning mode, and network
DHCP+static IP mix) so
FromMachineSetAndVSphereMachineTemplateAndVSphereCluster(...).ToMachineSet() is
exercised for those edge cases; create VSphereMachineTemplate.Spec.Template.Spec
variants that set VirtualMachineCloneSpec.CloneMode unsupported value, DataDisks
with invalid ProvisioningMode, and Network interfaces combining DHCP and static
IPs, and assert expectedErrors/expectedWarnings matching the Machine test
expectations.

In `@pkg/util/conditions.go`:
- Around line 135-160: GetConditionStatusFromInfraObject currently falls back to
GetV1Beta2ConditionStatus and returns its error, which causes reconciles to fail
when a v1beta2 status block is simply absent; change the fallback logic in
GetConditionStatusFromInfraObject so that after calling
GetV1Beta2ConditionStatus you check for the sentinel errStatusV1Beta2NotFound
and treat it as a non-error by returning corev1.ConditionUnknown, nil; otherwise
return the status/error from GetV1Beta2ConditionStatus as before. Use the
existing symbols GetConditionStatusFromInfraObject, GetConditionStatus,
GetV1Beta2ConditionStatus, and errStatusV1Beta2NotFound to locate and implement
this conditional handling.
🧹 Nitpick comments (1)
🤖 Fix all nitpicks with AI agents
Verify each finding against the current code and only fix it if needed.


In `@pkg/conversion/capi2mapi/vsphere_test.go`:
- Around line 348-399: The test suite for MachineSet conversion only contains a
single base Entry; add additional DescribeTable entries using the
vsphereCAPI2MAPIMachinesetConversionInput struct to mirror the Machine tests
(cover unsupported clone mode, invalid data disk provisioning mode, and network
DHCP+static IP mix) so
FromMachineSetAndVSphereMachineTemplateAndVSphereCluster(...).ToMachineSet() is
exercised for those edge cases; create VSphereMachineTemplate.Spec.Template.Spec
variants that set VirtualMachineCloneSpec.CloneMode unsupported value, DataDisks
with invalid ProvisioningMode, and Network interfaces combining DHCP and static
IPs, and assert expectedErrors/expectedWarnings matching the Machine test
expectations.
pkg/conversion/capi2mapi/vsphere_test.go (1)

348-399: Consider expanding MachineSet test coverage.

The MachineSet conversion tests have only one entry (base case), while the Machine conversion tests above cover 14 scenarios including clone modes, data disks, networks, tags, and various error/warning cases.

Since VSphereMachineTemplate wraps the same VSphereMachineSpec, similar edge cases and error paths should ideally be validated for MachineSet conversions to ensure parity.

Consider adding test entries for at least:

  • Unsupported clone mode (error case)
  • Invalid provisioning mode in data disks (error case)
  • Network configurations with DHCP + static IPs (warning case)

This could be deferred if the underlying conversion logic is shared and already covered by the Machine tests.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/conversion/capi2mapi/vsphere_test.go` around lines 348 - 399, The test
suite for MachineSet conversion only contains a single base Entry; add
additional DescribeTable entries using the
vsphereCAPI2MAPIMachinesetConversionInput struct to mirror the Machine tests
(cover unsupported clone mode, invalid data disk provisioning mode, and network
DHCP+static IP mix) so
FromMachineSetAndVSphereMachineTemplateAndVSphereCluster(...).ToMachineSet() is
exercised for those edge cases; create VSphereMachineTemplate.Spec.Template.Spec
variants that set VirtualMachineCloneSpec.CloneMode unsupported value, DataDisks
with invalid ProvisioningMode, and Network interfaces combining DHCP and static
IPs, and assert expectedErrors/expectedWarnings matching the Machine test
expectations.

@AnnaZivkovic
Copy link
Copy Markdown
Author

@damdo Could you give this pr a review?

@jcpowermac
Copy link
Copy Markdown

/lgtm

@jcpowermac
Copy link
Copy Markdown

/assign @damdo

@openshift-ci openshift-ci bot added the lgtm Indicates that a PR is ready to be merged. label Feb 17, 2026
@openshift-ci-robot
Copy link
Copy Markdown

Scheduling tests matching the pipeline_run_if_changed or not excluded by pipeline_skip_if_only_changed parameters:
/test e2e-aws-capi-techpreview
/test e2e-aws-ovn
/test e2e-aws-ovn-serial-1of2
/test e2e-aws-ovn-serial-2of2
/test e2e-aws-ovn-techpreview
/test e2e-aws-ovn-techpreview-upgrade
/test e2e-azure-capi-techpreview
/test e2e-azure-ovn-techpreview
/test e2e-azure-ovn-techpreview-upgrade
/test e2e-gcp-capi-techpreview
/test e2e-gcp-ovn-techpreview
/test e2e-metal3-capi-techpreview
/test e2e-openstack-capi-techpreview
/test e2e-openstack-ovn-techpreview
/test e2e-vsphere-capi-techpreview
/test regression-clusterinfra-aws-ipi-techpreview-capi

@jcpowermac
Copy link
Copy Markdown

/test e2e-vsphere-capi-techpreview

@AnnaZivkovic
Copy link
Copy Markdown
Author

/retest

@AnnaZivkovic AnnaZivkovic force-pushed the vsphere-conversion branch 5 times, most recently from 58e4c81 to 7c7c6a6 Compare March 20, 2026 23:48
@AnnaZivkovic
Copy link
Copy Markdown
Author

/retest

@jcpowermac
Copy link
Copy Markdown

/lgtm

@openshift-ci openshift-ci bot added the lgtm Indicates that a PR is ready to be merged. label Mar 23, 2026
@openshift-ci-robot
Copy link
Copy Markdown

Scheduling tests matching the pipeline_run_if_changed or not excluded by pipeline_skip_if_only_changed parameters:
/test e2e-aws-capi-techpreview
/test e2e-aws-ovn
/test e2e-aws-ovn-serial-1of2
/test e2e-aws-ovn-serial-2of2
/test e2e-aws-ovn-techpreview
/test e2e-aws-ovn-techpreview-upgrade
/test e2e-azure-capi-techpreview
/test e2e-azure-ovn-techpreview
/test e2e-azure-ovn-techpreview-upgrade
/test e2e-gcp-capi-techpreview
/test e2e-gcp-ovn-techpreview
/test e2e-metal3-capi-techpreview
/test e2e-openstack-capi-techpreview
/test e2e-openstack-ovn-techpreview
/test e2e-vsphere-capi-techpreview
/test regression-clusterinfra-aws-ipi-techpreview-capi

@AnnaZivkovic
Copy link
Copy Markdown
Author

/retest

@AnnaZivkovic
Copy link
Copy Markdown
Author

@JoelSpeed would you mind giving this another review?

@AnnaZivkovic
Copy link
Copy Markdown
Author

/retest

1 similar comment
@AnnaZivkovic
Copy link
Copy Markdown
Author

/retest

@jcpowermac
Copy link
Copy Markdown

@mdbooth can you take another look at this when you get a chance? Thanks!


mapiMachine.Spec.ProviderSpec.Value = vsphereSpecRawExt
// Note: ProviderStatus is not set during conversion, similar to OpenStack and PowerVS providers.
// The MAPI controller will manage the status at runtime.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, are we sure this is going to age well? Eventually we intend to turn off the MAPI controllers. What happens when CAPi is authoritative, does the machine provider status just sit stale?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're absolutely right when CAPI becomes authoritative the ProviderStatus will go stale. This follows the same pattern as OpenStack and PowerVS providers. I think the stale ProviderStatus is harmless because it's no longer the source of truth since we will be looking at VSphereMachine.Status instead.

Should I look into how aws handles this case?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know why those other providers are allowing stale status. That is not the expectation of the overall architecture. I would expect this to be kept updated.

Please check how AWS is handling this

Comment on lines +159 to +171
spec.PowerOffMode = ""
spec.GuestSoftPowerOffTimeout = nil
spec.FailureDomain = nil
spec.NamingStrategy = nil
spec.OS = ""
spec.HardwareVersion = ""
spec.StoragePolicyName = ""
spec.Thumbprint = ""
spec.Resources = vspherev1.VirtualMachineResources{}
spec.PciDevices = nil
spec.CustomVMXKeys = nil
spec.AdditionalDisksGiB = nil
spec.ProviderID = nil
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will want a VAP to prevent users from setting these fields, speak to @theobarberbany for guidance about this, but please make sure this is tracked

Copy link
Copy Markdown
Author

@AnnaZivkovic AnnaZivkovic Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have SPLAT-2711 to track it. I touched base with Theo on this, and the plan is to implement it first and gather feedback during the review process.

@openshift-ci openshift-ci bot removed the lgtm Indicates that a PR is ready to be merged. label Apr 1, 2026
messageExpression: "variables.specPath + '.thumbprint is not supported - TLS validation is handled at cluster level'"

# CAPI-only runtime configuration
- expression: "!has(variables.machineSpec.customVMXKeys) || variables.machineSpec.customVMXKeys.size() == 0"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one I am hesitant on, wdyt @vr4manta ?

While we might not have a direct correlation from mapi, in mapi we do use extra configs, so maybe its a good idea to keep this?

https://github.com/openshift/machine-api-operator/blob/b8fd3454befc80bd58247b91cd34e33b49a3aa22/pkg/controller/vsphere/reconciler.go#L62-L68

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From what I can tell, VAP is checking what CAPI exposes to users, and blocking anything that can't roundtrip through MAPI. My two cence is that customVMXKeys should stay blocked because Machine API doesn't expose this functionality to users, so there's no conversion path. While the MAPI controller uses extraConfig internally, this is controller-managed configuration, not user-configurable fields.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, so having MAPI conversion add these controller controlled to CAPI would make sense so if you switch from MAPI to CAPI, the state of the VM will be consistent. Adding additional parameters is what we may want to prevent then in this case. We can do that property checking in the capi2mapi if i recall correctly. Else we may want to look into making MAPI support exposing the ability to add these configs.

This enables bidirectional conversion between vSphere Machine API
Machines/MachineSets and Cluster API Machines/MachineTemplates,
including comprehensive fuzz and unit tests.
Add functions to handle v1beta2 conditions (used by vSphere provider)
while maintaining backward compatibility with v1beta1 conditions (used
by AWS, Azure, GCP providers).
Gate vSphere migration functionality behind theClusterAPIMachineManagementVSphere feature gate. The migrationcontrollers for vSphere will now only start when both the generalMachineAPIMigration feature gate and the vSphere-specificClusterAPIMachineManagementVSphere feature gate are enabled.
Implements admission-time validation to block unsupported vSphere fieldsin VSphereMachine and VSphereMachineTemplate resources, providing clear error messages before conversion attempts.
Align vSphere conversion with AWS implementation by converting and setting
ProviderStatus during CAPI to MAPI conversion to ensure proper status
synchronization between the two APIs.
@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci bot commented Apr 6, 2026

@AnnaZivkovic: The following test failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/e2e-openstack-ovn-techpreview 9e84159 link true /test e2e-openstack-ovn-techpreview

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

@AnnaZivkovic
Copy link
Copy Markdown
Author

/retest

@jcpowermac
Copy link
Copy Markdown

/lgtm

@openshift-ci openshift-ci bot added the lgtm Indicates that a PR is ready to be merged. label Apr 7, 2026
@openshift-ci-robot
Copy link
Copy Markdown

Scheduling tests matching the pipeline_run_if_changed or not excluded by pipeline_skip_if_only_changed parameters:
/test e2e-aws-capi-techpreview
/test e2e-aws-ovn
/test e2e-aws-ovn-serial-1of2
/test e2e-aws-ovn-serial-2of2
/test e2e-aws-ovn-techpreview
/test e2e-aws-ovn-techpreview-upgrade
/test e2e-azure-capi-techpreview
/test e2e-azure-ovn-techpreview
/test e2e-azure-ovn-techpreview-upgrade
/test e2e-gcp-capi-techpreview
/test e2e-gcp-ovn-techpreview
/test e2e-metal3-capi-techpreview
/test e2e-openstack-capi-techpreview
/test e2e-openstack-ovn-techpreview
/test e2e-vsphere-capi-techpreview
/test regression-clusterinfra-aws-ipi-techpreview-capi

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. lgtm Indicates that a PR is ready to be merged.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants