Skip to content

SPLAT-2662: Make migration metadata installer-compatible - #54

Open
jcpowermac wants to merge 2 commits into
openshift:mainfrom
jcpowermac:installer-compatible-metadata-secret
Open

SPLAT-2662: Make migration metadata installer-compatible#54
jcpowermac wants to merge 2 commits into
openshift:mainfrom
jcpowermac:installer-compatible-metadata-secret

Conversation

@jcpowermac

@jcpowermac jcpowermac commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Align the generated metadata secret with the installer's vSphere schema so destroy cluster can consume it directly. Preserve feature-gate data and fail early when metadata credentials are malformed or incomplete.

Summary by CodeRabbit

  • Documentation

    • Added a plan describing the installer-compatible vSphere migration metadata Secret layout, labels, lifecycle, validation, and required test updates.
  • New Features

    • Surface a runtime feature-gate accessor during startup and reconciler wiring; initialize and validate it early.
  • Refactor

    • Metadata/Secret handling now emits nested installer-style vSphere metadata, includes feature-set/custom gates, enforces fail-fast credential validation, deduplicates vCenter entries, always reconciles metadata labels, clears owner references, and overwrites Secret data/type on save.
  • Tests

    • Expanded JSON contract, credential validation, multi-vCenter/primary selection, feature-gate access, and Secret round-trip tests.
  • Chores

    • Dependency version updates.

@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Jun 3, 2026
@openshift-ci-robot

openshift-ci-robot commented Jun 3, 2026

Copy link
Copy Markdown

@jcpowermac: This pull request references SPLAT-2662 which is a valid jira issue.

Details

In response to this:

Align the generated metadata secret with the installer's vSphere schema so destroy cluster can consume it directly. Preserve feature-gate data and fail early when metadata credentials are malformed or incomplete.

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

coderabbitai Bot commented Jun 3, 2026

Copy link
Copy Markdown

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

Introduce installer-shaped ClusterMetadata, initialize and inject a FeatureGateAccessor, use it to determine vSphere multi-vCenter support, validate credentials and deduplicate VCenters in GenerateMetadata, update secret persistence/labels/OwnerReferences, and add tests and docs.

Changes

Installer-Compatible Metadata & FeatureGate wiring

Layer / File(s) Summary
Bootstrap & FeatureGate accessor setup
cmd/main.go, internal/openshift/featuregate.go
Create signal context, initialize FeatureGateAccessor at startup via SetupFeatureGateAccessor, and inject it into the reconciler.
Controller & preflight wiring for FeatureGateAccessor
internal/controller/..., internal/controller/preflight_test.go
Add FeatureGateAccessor to reconciler, pass it to preflight checks, and update tests to inject hardcoded/accessor error cases.
Feature-gate lookup API & tests
internal/openshift/version.go, internal/openshift/version_test.go
GetVSphereMultiVCenterSupport now accepts FeatureGateAccess and reads CurrentFeatureGates() to set FeatureGateEnabled; tests updated for accessor cases.
Installer-compatible metadata types & GenerateMetadata
internal/metadata/metadata.go
Replace Metadata with ClusterMetadata/VSphereMetadata/VCenter; GenerateMetadata validates infra/failure domains, parses required username:password credentials, de-duplicates VCenters, and returns *ClusterMetadata.
Secret persistence with metadata label
internal/metadata/metadata.go, internal/metadata/metadata_test.go
SaveToSecret marshals ClusterMetadata, applies migration.openshift.io/metadata label on create/update, clears OwnerReferences, initializes Labels defensively, and branches using apierrors.IsNotFound; tests assert label restoration and empty OwnerReferences.
Metadata tests & JSON contract
internal/metadata/metadata_test.go
Add credential-failure tests, multi-vCenter/dedup tests, exact JSON key-set assertions, SaveToSecret round-trip and deep-equality checks, and supporting helpers.
Docs & dependencies
docs/plans/installer-compatible-metadata-secret.md, go.mod
Add migration plan documenting the installer ClusterMetadata JSON contract and update module dependencies.

Sequence Diagram

sequenceDiagram
  participant Controller
  participant OpenshiftAccessor as FeatureGateAccessor
  participant MetadataManager
  participant KubeAPI as Kubernetes API

  Controller->>OpenshiftAccessor: CurrentFeatureGates()
  OpenshiftAccessor-->>Controller: observed gates

  Controller->>MetadataManager: GenerateMetadata(failureDomains, infra, credentials)
  MetadataManager->>MetadataManager: validate inputs, parseRequiredCredentials, deduplicate VCenters
  MetadataManager-->>Controller: ClusterMetadata

  Controller->>MetadataManager: SaveToSecret(ClusterMetadata)
  MetadataManager->>KubeAPI: create/update Secret (set metadata label, clear OwnerReferences)
  KubeAPI-->>MetadataManager: Secret persisted
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

lgtm

Suggested reviewers

  • mtulio
  • vr4manta
🚥 Pre-merge checks | ✅ 12 | ❌ 3

❌ Failed checks (3 warnings)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 30.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Test Structure And Quality ⚠️ Warning TestSaveToSecretAndGet violates single responsibility by testing save, verify, update, and re-verify as one monolithic test. Should split into separate tests. Split TestSaveToSecretAndGet into TestSaveToSecret, TestGetMetadataFromSecret, and TestSaveToSecretUpdate with distinct responsibilities.
Ipv6 And Disconnected Network Test Compatibility ⚠️ Warning New Ginkgo e2e tests pull external images (curlimages/curl:latest) and utils download external bundles (github.com/cert-manager, prometheus-operator) - fails in disconnected environments. Use cluster-internal images for curl pod in test/e2e/e2e_test.go and use local/mirror registry paths for cert-manager and prometheus-operator, or add [Skipped:Disconnected] to test names that require external connectivity.
✅ Passed checks (12 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically summarizes the main change: making migration metadata compatible with the installer's expected schema, which is the primary objective across all file modifications.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Stable And Deterministic Test Names ✅ Passed All test cases in modified test files use static, deterministic names with no dynamic values, timestamps, UUIDs, or generated identifiers.
Microshift Test Compatibility ✅ Passed E2E tests only use standard Kubernetes APIs (Pod, Service, RBAC, Events) that are available on MicroShift, not unavailable OpenShift-specific APIs like FeatureGate or ClusterVersion.
Single Node Openshift (Sno) Test Compatibility ✅ Passed No Ginkgo e2e tests were added or modified in this PR. All modified test files are Go unit tests using testing.T framework, not Ginkgo. Check does not apply.
Topology-Aware Scheduling Compatibility ✅ Passed PR only modifies metadata schema, feature gates, and tests. No deployment manifests or pod scheduling constraints added that would affect SNO, TNF, TNA, or HyperShift topologies.
Ote Binary Stdout Contract ✅ Passed No OTE stdout violations. Process code uses zap/klog (both stderr-default), test suite uses GinkgoWriter, no fmt.Print in main/init.
No-Weak-Crypto ✅ Passed No instances of weak cryptography (MD5, SHA1, DES, RC4, 3DES, Blowfish, ECB), custom crypto implementations, or non-constant-time secret comparisons found in the PR changes.
Container-Privileges ✅ Passed PR contains only Go source code changes; no container/K8s manifests with privilege escalations were added or modified.
No-Sensitive-Data-In-Logs ✅ Passed No logging exposes passwords, tokens, or credentials. All sensitive data handling uses secure patterns - only server names are logged, marshaled metadata is never logged.

✏️ 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 commented Jun 3, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: jcpowermac

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci openshift-ci Bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jun 3, 2026
@openshift-ci
openshift-ci Bot requested review from AnnaZivkovic and vr4manta June 3, 2026 19:23

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
internal/openshift/version.go (1)

116-130: 💤 Low value

Optional: clone may turn a non-nil empty input into a distinct value.

When in is non-nil but both slices are empty, this returns &CustomFeatureGates{} with nil slices. That round-trips fine for the metadata use case here, but if a caller ever relies on reflect.DeepEqual against an input that holds non-nil empty slices, the clone would differ. Not an issue for current usage.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/openshift/version.go` around lines 116 - 130, The
cloneCustomFeatureGates function turns non-nil empty slices into nil slices
because it only copies when len(...) > 0; change the checks to test against nil
(e.g. if in.Enabled != nil) and then do the append copy so callers that expect a
non-nil zero-length slice (reflect.DeepEqual scenarios) get a distinct non-nil
empty slice; do the same for in.Disabled and keep returning out from
cloneCustomFeatureGates.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@internal/openshift/version.go`:
- Around line 116-130: The cloneCustomFeatureGates function turns non-nil empty
slices into nil slices because it only copies when len(...) > 0; change the
checks to test against nil (e.g. if in.Enabled != nil) and then do the append
copy so callers that expect a non-nil zero-length slice (reflect.DeepEqual
scenarios) get a distinct non-nil empty slice; do the same for in.Disabled and
keep returning out from cloneCustomFeatureGates.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 2a4bf157-d08c-4f9f-b657-eb5b41dc64db

📥 Commits

Reviewing files that changed from the base of the PR and between b6a6264 and 49bbe33.

📒 Files selected for processing (6)
  • docs/plans/installer-compatible-metadata-secret.md
  • internal/controller/vmwarecloudfoundationmigration_controller.go
  • internal/metadata/metadata.go
  • internal/metadata/metadata_test.go
  • internal/openshift/version.go
  • internal/openshift/version_test.go

@jcpowermac
jcpowermac force-pushed the installer-compatible-metadata-secret branch from 49bbe33 to c367ff0 Compare June 3, 2026 19:31

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@internal/metadata/metadata.go`:
- Around line 188-205: When updating an existing Secret in the update branch,
clear any OwnerReferences to avoid accidental GC: set existing.OwnerReferences =
nil (or an empty slice) before assigning Labels/Data/Type and calling
m.kubeClient.CoreV1().Secrets(namespace).Update(...); also ensure the create
path does not set OwnerReferences on the secret (e.g., secret.OwnerReferences =
nil) so both Create and Update preserve the "no owner reference" invariant
referenced by metadataSecretLabelKey and the Secret update logic.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: c6ddf5ff-e0eb-4924-8ca9-42751a651dc7

📥 Commits

Reviewing files that changed from the base of the PR and between 49bbe33 and c367ff0.

📒 Files selected for processing (6)
  • docs/plans/installer-compatible-metadata-secret.md
  • internal/controller/vmwarecloudfoundationmigration_controller.go
  • internal/metadata/metadata.go
  • internal/metadata/metadata_test.go
  • internal/openshift/version.go
  • internal/openshift/version_test.go
🚧 Files skipped from review as they are similar to previous changes (4)
  • internal/openshift/version.go
  • internal/controller/vmwarecloudfoundationmigration_controller.go
  • internal/openshift/version_test.go
  • internal/metadata/metadata_test.go

Comment thread internal/metadata/metadata.go
@jcpowermac
jcpowermac force-pushed the installer-compatible-metadata-secret branch from c367ff0 to 89610a6 Compare June 3, 2026 19:48

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
internal/openshift/version_test.go (1)

293-307: ⚡ Quick win

Assert the defensive-clone contract explicitly.

This only checks value equality, so GetFeatureSet could regress to returning the original CustomNoUpgrade pointer and this test would still pass. Keep a handle to the source CustomFeatureGates in the custom cases and assert the returned pointer is different before the DeepEqual check.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/openshift/version_test.go` around lines 293 - 307, The test must
also assert that GetFeatureSet returns a defensive clone for custom gates rather
than the original pointer: in the test loop for cases with custom gates (e.g.
where tt.wantCustom or the test source is a CustomFeatureGates/CustomNoUpgrade
instance), capture the source pointer (e.g. src := tt.wantCustom or the test's
custom source), then add an assertion that gotCustom != src (pointer inequality)
before performing the reflect.DeepEqual check; use the existing gotCustom and
tt.wantCustom identifiers and the GetFeatureSet test block to implement this.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@internal/metadata/metadata.go`:
- Line 157: The log call in metadata.go currently emits customer-specific
infraID: update the log.V(2).Info invocation that prints "generated metadata"
(the call referencing md.InfraID and len(md.VSphere.VCenters)) to remove the
"infraID", md.InfraID fields so only "vcenterCount" (len(md.VSphere.VCenters))
is logged; also scan for any other uses of md.InfraID in logging and remove or
redact them to avoid leaking customer identifiers.

---

Nitpick comments:
In `@internal/openshift/version_test.go`:
- Around line 293-307: The test must also assert that GetFeatureSet returns a
defensive clone for custom gates rather than the original pointer: in the test
loop for cases with custom gates (e.g. where tt.wantCustom or the test source is
a CustomFeatureGates/CustomNoUpgrade instance), capture the source pointer (e.g.
src := tt.wantCustom or the test's custom source), then add an assertion that
gotCustom != src (pointer inequality) before performing the reflect.DeepEqual
check; use the existing gotCustom and tt.wantCustom identifiers and the
GetFeatureSet test block to implement this.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 38cbfdf4-4500-45b1-8b0a-75b47bb668a3

📥 Commits

Reviewing files that changed from the base of the PR and between c367ff0 and 89610a6.

📒 Files selected for processing (6)
  • docs/plans/installer-compatible-metadata-secret.md
  • internal/controller/vmwarecloudfoundationmigration_controller.go
  • internal/metadata/metadata.go
  • internal/metadata/metadata_test.go
  • internal/openshift/version.go
  • internal/openshift/version_test.go
🚧 Files skipped from review as they are similar to previous changes (3)
  • internal/openshift/version.go
  • internal/controller/vmwarecloudfoundationmigration_controller.go
  • internal/metadata/metadata_test.go

Comment thread internal/metadata/metadata.go Outdated
@jcpowermac
jcpowermac force-pushed the installer-compatible-metadata-secret branch from 89610a6 to 7d37613 Compare June 3, 2026 20:07

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
internal/metadata/metadata.go (1)

165-172: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Reject nil metadata before marshaling.

json.Marshal(nil) serializes to null, so a nil md here would still create/update the Secret with an unusable payload instead of failing fast.

Suggested fix
 func (m *MetadataManager) SaveToSecret(ctx context.Context, md *ClusterMetadata, namespace, name string) error {
+	if md == nil {
+		return fmt.Errorf("metadata must not be nil")
+	}
+
 	log := klog.FromContext(ctx)
 	log.V(2).Info("saving metadata to Secret", "namespace", namespace, "name", name)
 
 	data, err := json.Marshal(md)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/metadata/metadata.go` around lines 165 - 172, In SaveToSecret
(method on MetadataManager) reject a nil md before attempting json.Marshal: add
a nil-check for the md parameter and return a descriptive error (e.g., "nil
metadata") if md == nil so you fail fast instead of marshaling to "null"; locate
the nil-check near the start of SaveToSecret (before json.Marshal) and ensure
callers receive the error rather than writing an invalid Secret.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@internal/metadata/metadata.go`:
- Around line 165-172: In SaveToSecret (method on MetadataManager) reject a nil
md before attempting json.Marshal: add a nil-check for the md parameter and
return a descriptive error (e.g., "nil metadata") if md == nil so you fail fast
instead of marshaling to "null"; locate the nil-check near the start of
SaveToSecret (before json.Marshal) and ensure callers receive the error rather
than writing an invalid Secret.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: ce1c1367-c405-486d-a46c-236de9b64e19

📥 Commits

Reviewing files that changed from the base of the PR and between 89610a6 and 7d37613.

📒 Files selected for processing (6)
  • docs/plans/installer-compatible-metadata-secret.md
  • internal/controller/vmwarecloudfoundationmigration_controller.go
  • internal/metadata/metadata.go
  • internal/metadata/metadata_test.go
  • internal/openshift/version.go
  • internal/openshift/version_test.go
🚧 Files skipped from review as they are similar to previous changes (4)
  • internal/openshift/version.go
  • internal/controller/vmwarecloudfoundationmigration_controller.go
  • internal/openshift/version_test.go
  • internal/metadata/metadata_test.go

// VSphere contains the vSphere-specific metadata expected by the installer.
VSphere *VSphereMetadata `json:"vsphere,omitempty"`
// FeatureSet stores the cluster's configured feature set.
FeatureSet configv1.FeatureSet `json:"featureSet"`

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.

Normally you shouldn't have two storage objects for features. If using the FeatureGateAccessor, you would just get the feature gates back and check if the one you need is enabled or not. Also, do we want this operator to restart if featuregates change? This is all fresh in my mind cause I did it wrong in Cluster Config Operator.

@openshift-ci openshift-ci Bot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jun 8, 2026
jcpowermac and others added 2 commits June 8, 2026 14:59
Align the generated metadata secret with the installer's vSphere schema so destroy cluster can consume it directly. Preserve feature-gate data, keep custom gate slice shape stable, clear secret owner references, redact customer identifiers from logs, and fail early when metadata credentials are malformed or incomplete.

Co-authored-by: Cursor <cursoragent@cursor.com>
Align migration runtime behavior with the standard library-go feature gate accessor pattern so preflight decisions use effective gates instead of ad hoc FeatureGate reads. Stop snapshotting configured feature-set state into generated metadata while keeping the installer-compatible schema and vendored dependency updates together.

Co-authored-by: Cursor <cursoragent@cursor.com>
@jcpowermac
jcpowermac force-pushed the installer-compatible-metadata-secret branch from 4c29717 to 15415e8 Compare June 8, 2026 19:03
@openshift-ci openshift-ci Bot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jun 8, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
internal/openshift/version_test.go (1)

1-13: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Fix generated API deepcopy methods before merge.

golangci-lint typecheck is currently failing because VmwareCloudFoundationMigration and VmwareCloudFoundationMigrationList do not implement runtime.Object (missing DeepCopyObject). Regenerate/sync API generated code (DeepCopy files) so the package compiles again.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/openshift/version_test.go` around lines 1 - 13, The package fails
typecheck because the API types VmwareCloudFoundationMigration and
VmwareCloudFoundationMigrationList are missing DeepCopyObject methods;
regenerate or sync the autogenerated deepcopy code so these types implement
runtime.Object. Run the project's codegen tool (or controller-gen/client-gen as
used in this repo) to recreate the deepcopy functions for the types, verify
DeepCopyObject exists on VmwareCloudFoundationMigration and
VmwareCloudFoundationMigrationList, and commit the updated
zz_generated.deepcopy.go files.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@go.mod`:
- Around line 8-10: The build is failing because generated deepcopy methods for
the API types (e.g., VmwareCloudFoundationMigration and its list types) are
missing—run the project's generator to produce DeepCopyObject/DeepCopyInto
methods and commit the outputs: run the repo's generation step (e.g., invoke
make update or the project’s deepcopy-gen/controller-gen target) so that vmware
API files include DeepCopyObject implementations for
VmwareCloudFoundationMigration and the corresponding list types, verify the
generated files are staged, and commit those generated API artifacts before
rebasing the dependency bump.

In `@internal/metadata/metadata.go`:
- Around line 103-112: GenerateMetadata currently builds a ClusterMetadata with
VSphere but leaves FeatureSet and CustomFeatureSet at zero values; update
GenerateMetadata to populate ClusterMetadata.FeatureSet and
ClusterMetadata.CustomFeatureSet from the incoming infra object (or its
spec/feature-gate accessor used in this repo) so the persisted Secret contains
the feature-gate values; search for GenerateMetadata, ClusterMetadata,
FeatureSet and CustomFeatureSet (also the later usage around lines referenced
154-155) and assign the corresponding infra feature-set fields (or call the
standard accessor used elsewhere) into the ClusterMetadata before
returning/persisting.

---

Outside diff comments:
In `@internal/openshift/version_test.go`:
- Around line 1-13: The package fails typecheck because the API types
VmwareCloudFoundationMigration and VmwareCloudFoundationMigrationList are
missing DeepCopyObject methods; regenerate or sync the autogenerated deepcopy
code so these types implement runtime.Object. Run the project's codegen tool (or
controller-gen/client-gen as used in this repo) to recreate the deepcopy
functions for the types, verify DeepCopyObject exists on
VmwareCloudFoundationMigration and VmwareCloudFoundationMigrationList, and
commit the updated zz_generated.deepcopy.go files.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 05b9c08c-06c2-4276-b723-bafed8f02ee1

📥 Commits

Reviewing files that changed from the base of the PR and between 7d37613 and 15415e8.

⛔ Files ignored due to path filters (284)
  • go.sum is excluded by !**/*.sum
  • vendor/github.com/gogo/protobuf/AUTHORS is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/CONTRIBUTORS is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/Makefile is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/clone.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/custom_gogo.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/decode.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/deprecated.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/discard.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/duration.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/duration_gogo.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/encode.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/encode_gogo.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/equal.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/extensions.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/extensions_gogo.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/lib.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/lib_gogo.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/message_set.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/pointer_reflect.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/pointer_reflect_gogo.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/pointer_unsafe.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/pointer_unsafe_gogo.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/properties.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/properties_gogo.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/skip_gogo.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/table_marshal.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/table_marshal_gogo.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/table_merge.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/table_unmarshal.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/table_unmarshal_gogo.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/text.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/text_gogo.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/text_parser.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/timestamp.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/timestamp_gogo.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/wrappers.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/proto/wrappers_gogo.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/gogo/protobuf/sortkeys/sortkeys.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/imdario/mergo/.gitignore is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/imdario/mergo/.travis.yml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/imdario/mergo/CODE_OF_CONDUCT.md is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/imdario/mergo/LICENSE is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/imdario/mergo/README.md is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/imdario/mergo/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/imdario/mergo/map.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/imdario/mergo/merge.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/imdario/mergo/mergo.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/.ci-operator.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/.coderabbit.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/.gitattributes is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/.gitignore is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/.golangci.go-validated.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/.golangci.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/AGENTS.md is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/Dockerfile.ocp is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/Makefile is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/OWNERS is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/README.md is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/annotations/annotations.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/apiextensions/install.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/apiextensions/v1alpha1/Makefile is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/apiextensions/v1alpha1/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/apiextensions/v1alpha1/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/apiextensions/v1alpha1/types_compatibilityrequirement.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/apiextensions/v1alpha1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/apiextensions/v1alpha1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/apiextensions/v1alpha1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/apiserver/.codegen.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/apiserver/install.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/apiserver/v1/Makefile is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/apiserver/v1/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/apiserver/v1/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/apiserver/v1/types_apirequestcount.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/apiserver/v1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/apiserver/v1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/apiserver/v1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/apps/OWNERS is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/apps/install.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/apps/v1/consts.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/apps/v1/deprecated_consts.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/apps/v1/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/apps/v1/generated.pb.go is excluded by !**/*.pb.go, !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/apps/v1/generated.proto is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/apps/v1/generated.protomessage.pb.go is excluded by !**/*.pb.go, !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/apps/v1/legacy.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/apps/v1/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/apps/v1/types.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/apps/v1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/apps/v1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/apps/v1/zz_prerelease_lifecycle_generated.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/authorization/install.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/authorization/v1/Makefile is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/authorization/v1/codec.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/authorization/v1/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/authorization/v1/generated.pb.go is excluded by !**/*.pb.go, !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/authorization/v1/generated.proto is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/authorization/v1/generated.protomessage.pb.go is excluded by !**/*.pb.go, !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/authorization/v1/legacy.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/authorization/v1/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/authorization/v1/types.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/authorization/v1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/authorization/v1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/authorization/v1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/build/OWNERS is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/build/install.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/build/v1/consts.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/build/v1/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/build/v1/generated.pb.go is excluded by !**/*.pb.go, !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/build/v1/generated.proto is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/build/v1/generated.protomessage.pb.go is excluded by !**/*.pb.go, !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/build/v1/legacy.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/build/v1/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/build/v1/types.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/build/v1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/build/v1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/cloudnetwork/.codegen.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/cloudnetwork/OWNERS is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/cloudnetwork/install.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/cloudnetwork/v1/Makefile is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/cloudnetwork/v1/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/cloudnetwork/v1/generated.pb.go is excluded by !**/*.pb.go, !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/cloudnetwork/v1/generated.proto is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/cloudnetwork/v1/generated.protomessage.pb.go is excluded by !**/*.pb.go, !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/cloudnetwork/v1/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/cloudnetwork/v1/types.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/cloudnetwork/v1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/cloudnetwork/v1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/cloudnetwork/v1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/config/.codegen.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/install.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/types_kmsencryption.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/types_network.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/config/v1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/config/v1alpha1/types_cluster_monitoring.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1alpha1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/config/v1alpha1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/console/.codegen.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/console/OWNERS is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/console/install.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/console/v1/Makefile is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/console/v1/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/console/v1/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/console/v1/types.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/console/v1/types_console_cli_download.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/console/v1/types_console_external_log_links.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/console/v1/types_console_link.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/console/v1/types_console_notification.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/console/v1/types_console_plugin.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/console/v1/types_console_quick_start.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/console/v1/types_console_sample.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/console/v1/types_console_yaml_sample.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/console/v1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/console/v1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/console/v1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/envtest-releases.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/etcd/README.md is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/etcd/install.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/etcd/v1/Makefile is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/etcd/v1/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/etcd/v1/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/etcd/v1/types_pacemakercluster.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/etcd/v1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/etcd/v1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/etcd/v1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/etcd/v1alpha1/Makefile is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/etcd/v1alpha1/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/etcd/v1alpha1/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/etcd/v1alpha1/types_pacemakercluster.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/etcd/v1alpha1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/etcd/v1alpha1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/etcd/v1alpha1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/features.md is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/helm/.codegen.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/helm/install.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/helm/v1beta1/Makefile is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/helm/v1beta1/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/helm/v1beta1/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/helm/v1beta1/types_helm_chart_repository.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/helm/v1beta1/types_project_helm_chart_repository.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/helm/v1beta1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/helm/v1beta1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/helm/v1beta1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/image/.codegen.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/image/OWNERS is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/image/docker10/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/image/docker10/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/image/docker10/types_docker.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/image/docker10/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/image/docker10/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/image/dockerpre012/deepcopy.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/image/dockerpre012/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/image/dockerpre012/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/image/dockerpre012/types_docker.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/image/dockerpre012/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/image/dockerpre012/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/image/install.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/image/v1/consts.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/image/v1/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/image/v1/generated.pb.go is excluded by !**/*.pb.go, !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/image/v1/generated.proto is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/image/v1/generated.protomessage.pb.go is excluded by !**/*.pb.go, !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/image/v1/legacy.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/image/v1/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/image/v1/types.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/image/v1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/image/v1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/imageregistry/.codegen.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/imageregistry/install.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/imageregistry/v1/Makefile is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/imageregistry/v1/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/imageregistry/v1/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/imageregistry/v1/types.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/imageregistry/v1/types_imagepruner.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/imageregistry/v1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/imageregistry/v1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/imageregistry/v1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/install.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/kubecontrolplane/.codegen.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/kubecontrolplane/install.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/kubecontrolplane/v1/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/kubecontrolplane/v1/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/kubecontrolplane/v1/types.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/kubecontrolplane/v1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/kubecontrolplane/v1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/legacyconfig/v1/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/legacyconfig/v1/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/legacyconfig/v1/serialization.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/legacyconfig/v1/stringsource.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/legacyconfig/v1/types.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/legacyconfig/v1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/legacyconfig/v1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/machine/.codegen.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/machine/OWNERS is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/machine/install.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/machine/v1alpha1/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/machine/v1alpha1/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/machine/v1alpha1/types_openstack.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/machine/v1alpha1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/machine/v1alpha1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/monitoring/.codegen.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/monitoring/install.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/monitoring/v1/Makefile is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/monitoring/v1/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/monitoring/v1/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/monitoring/v1/types.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/monitoring/v1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/monitoring/v1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/monitoring/v1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/network/.codegen.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/network/OWNERS is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/network/install.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/network/v1/Makefile is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/network/v1/constants.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/network/v1/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/network/v1/generated.pb.go is excluded by !**/*.pb.go, !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/network/v1/generated.proto is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/network/v1/generated.protomessage.pb.go is excluded by !**/*.pb.go, !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/network/v1/legacy.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/network/v1/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/network/v1/types.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/network/v1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/network/v1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/network/v1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/network/v1alpha1/Makefile is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/network/v1alpha1/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/network/v1alpha1/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/network/v1alpha1/types_dnsnameresolver.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/network/v1alpha1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/network/v1alpha1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/network/v1alpha1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/networkoperator/.codegen.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/networkoperator/OWNERS is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/networkoperator/install.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/networkoperator/v1/Makefile is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/networkoperator/v1/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/networkoperator/v1/generated.pb.go is excluded by !**/*.pb.go, !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/networkoperator/v1/generated.proto is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/networkoperator/v1/generated.protomessage.pb.go is excluded by !**/*.pb.go, !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/networkoperator/v1/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/networkoperator/v1/types_egressrouter.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/networkoperator/v1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
📒 Files selected for processing (11)
  • cmd/main.go
  • docs/plans/installer-compatible-metadata-secret.md
  • go.mod
  • internal/controller/preflight.go
  • internal/controller/preflight_test.go
  • internal/controller/vmwarecloudfoundationmigration_controller.go
  • internal/metadata/metadata.go
  • internal/metadata/metadata_test.go
  • internal/openshift/featuregate.go
  • internal/openshift/version.go
  • internal/openshift/version_test.go

Comment thread go.mod
Comment on lines +8 to +10
github.com/openshift/api v0.0.0-20260521125114-09730f85d883
github.com/openshift/client-go v0.0.0-20260512113608-deb4dc54551a
github.com/openshift/library-go v0.0.0-20260608110537-04693132679d

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

CI is currently broken by missing generated DeepCopy methods.

Typecheck reports VmwareCloudFoundationMigration and list types missing DeepCopyObject; this is a merge blocker. Please regenerate and commit API artifacts before rebasing this dependency bump.

Based on learnings, full generated outputs should be synchronized with make update before commit.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@go.mod` around lines 8 - 10, The build is failing because generated deepcopy
methods for the API types (e.g., VmwareCloudFoundationMigration and its list
types) are missing—run the project's generator to produce
DeepCopyObject/DeepCopyInto methods and commit the outputs: run the repo's
generation step (e.g., invoke make update or the project’s
deepcopy-gen/controller-gen target) so that vmware API files include
DeepCopyObject implementations for VmwareCloudFoundationMigration and the
corresponding list types, verify the generated files are staged, and commit
those generated API artifacts before rebasing the dependency bump.

Sources: Learnings, Linters/SAST tools

Comment on lines +103 to 112
md := &ClusterMetadata{
ClusterName: infra.Name,
ClusterID: string(infra.UID),
InfraID: infra.Status.InfrastructureName,
// Runtime feature-gate decisions use the standard accessor pattern; the
// installer-compatible fields remain at their zero values here.
VSphere: &VSphereMetadata{
TerraformPlatform: "vsphere",
},
}

@coderabbitai coderabbitai Bot Jun 8, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Feature-gate fields are never persisted in generated metadata.

FeatureSet and CustomFeatureSet are always left at zero values in GenerateMetadata (Line 103 onward), and the controller immediately persists this object. That conflicts with the PR objective to preserve feature-gate data in the metadata Secret.

Suggested direction
-func (m *MetadataManager) GenerateMetadata(
+func (m *MetadataManager) GenerateMetadata(
     ctx context.Context,
     failureDomains []configv1.VSpherePlatformFailureDomainSpec,
     infra *configv1.Infrastructure,
     credentials map[string]string,
+    featureSet configv1.FeatureSet,
+    customFeatureSet *configv1.CustomFeatureGates,
 ) (*ClusterMetadata, error) {
@@
     md := &ClusterMetadata{
         ClusterName: infra.Name,
         ClusterID:   string(infra.UID),
         InfraID:     infra.Status.InfrastructureName,
+        FeatureSet:  featureSet,
+        CustomFeatureSet: customFeatureSet,
         VSphere: &VSphereMetadata{
             TerraformPlatform: "vsphere",
         },
     }

Also applies to: 154-155

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/metadata/metadata.go` around lines 103 - 112, GenerateMetadata
currently builds a ClusterMetadata with VSphere but leaves FeatureSet and
CustomFeatureSet at zero values; update GenerateMetadata to populate
ClusterMetadata.FeatureSet and ClusterMetadata.CustomFeatureSet from the
incoming infra object (or its spec/feature-gate accessor used in this repo) so
the persisted Secret contains the feature-gate values; search for
GenerateMetadata, ClusterMetadata, FeatureSet and CustomFeatureSet (also the
later usage around lines referenced 154-155) and assign the corresponding infra
feature-set fields (or call the standard accessor used elsewhere) into the
ClusterMetadata before returning/persisting.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

agent response

• go.mod inline comment: skipped as stale. api/v1alpha1/zz_generated.deepcopy.go already exists and defines DeepCopyObject() for both VmwareCloudFoundationMigration and VmwareCloudFoundationMigrationList, so the reported missing-generated-code failure is not reproducible in
current code.
• internal/metadata/metadata.go inline comment: skipped as stale. Current repo behavior intentionally leaves ClusterMetadata.FeatureSet empty and ClusterMetadata.CustomFeatureSet nil in GenerateMetadata(), and that contract is explicitly covered by
internal/metadata/metadata_test.go and documented in docs/plans/installer-compatible-metadata-secret.md.
• internal/openshift/version_test.go outside-diff comment: skipped as duplicate/stale for the same deepcopy reason above; current package typechecks and tests pass.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Resolve the comment I made on the PR
gh api \
  --method PUT \
  -H "Accept: application/vnd.github+json" \
  repos/openshift/vcf-migration-operator/pulls/54/reviews \
  --silent || true

# List my comments on the PR to find the one to resolve
gh api \
  -H "Accept: application/vnd.github+json" \
  "/repos/openshift/vcf-migration-operator/pulls/54/comments" \
  --jq '.[] | select(.user.login == "coderabbitai[bot]") | {id: .id, body: .body[0:80]}'

Length of output: 979


🏁 Script executed:

#!/bin/bash
# Resolve my comment (ID 3375742595) by marking it as resolved via GraphQL
gh api graphql -f query='
mutation {
  resolveReviewThread(input: {threadId: "PRRT_kwDONs50kM5hDXrT"}) {
    thread {
      isResolved
    }
  }
}'

# Alternatively, try to find the thread node ID
gh api \
  -H "Accept: application/vnd.github+json" \
  "/repos/openshift/vcf-migration-operator/pulls/54/comments/3375742595" \
  --jq '{id, node_id, body: .body[0:80]}'

Length of output: 1130


🏁 Script executed:

#!/bin/bash
# Get the correct node_id for comment 3375742595 using the GraphQL API
gh api graphql -f query='
{
  repository(owner: "openshift", name: "vcf-migration-operator") {
    pullRequest(number: 54) {
      reviewThreads(first: 20) {
        nodes {
          id
          isResolved
          comments(first: 1) {
            nodes {
              databaseId
              body
            }
          }
        }
      }
    }
  }
}' --jq '.data.repository.pullRequest.reviewThreads.nodes[] | {threadId: .id, isResolved: .isResolved, commentId: .comments.nodes[0].databaseId, body: .comments.nodes[0].body[0:60]}'

Length of output: 1423


🏁 Script executed:

#!/bin/bash
# Resolve the thread with the correct node ID
gh api graphql -f query='
mutation {
  resolveReviewThread(input: {threadId: "PRRT_kwDORmhp9c6H79qp"}) {
    thread {
      isResolved
    }
  }
}'

Length of output: 714



@jcpowermac, noted — the intentional design is clear and I've recorded it for future reviews. Unfortunately I don't have permission to resolve the review thread via the API on this repository, so you'll need to mark it as resolved manually on the PR.


✏️ Learnings added
Learnt from: jcpowermac
Repo: openshift/vcf-migration-operator PR: 54
File: internal/metadata/metadata.go:103-112
Timestamp: 2026-06-08T19:34:28.042Z
Learning: In `internal/metadata/metadata.go` (openshift/vcf-migration-operator), `ClusterMetadata.FeatureSet` and `ClusterMetadata.CustomFeatureSet` are intentionally left at zero values in `GenerateMetadata()`. Feature-gate data is populated by the caller at a higher layer — not inside `GenerateMetadata`. This contract is explicitly asserted in `internal/metadata/metadata_test.go` and documented in `docs/plans/installer-compatible-metadata-secret.md`. Do not flag the absence of FeatureSet/CustomFeatureSet population inside `GenerateMetadata` as a bug.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

@openshift-ci

openshift-ci Bot commented Jun 25, 2026

Copy link
Copy Markdown

@jcpowermac: The following tests 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/bundle 15415e8 link true /test bundle
ci/prow/fmt 15415e8 link true /test fmt
ci/prow/lint 15415e8 link true /test lint

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.

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

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants