|
1 | 1 | # vcf-migration-operator |
2 | 2 |
|
3 | | -Kubernetes operator and OpenShift Console plugin for orchestrating migration of OpenShift clusters between VMware vCenters (e.g. VMware Cloud Foundation / VCF). Use the operator to drive the migration lifecycle and the console plugin to create migrations, browse vCenter inventory, and monitor progress from the OpenShift web console. |
| 3 | +Kubernetes operator and OpenShift Console plugin for migrating OpenShift clusters between VMware vCenters (e.g. VMware Cloud Foundation environments). |
4 | 4 |
|
5 | | -## Description |
| 5 | +The operator reconciles the `VmwareCloudFoundationMigration` custom resource through a multi-phase workflow: preflight validation, destination initialization, multi-site configuration, workload migration (workers + control plane), source cleanup, and final health checks. The optional console plugin provides a web UI for creating migrations, browsing vCenter inventory, and monitoring progress. |
6 | 6 |
|
7 | | -vcf-migration-operator automates moving an OpenShift cluster from a source vCenter to a target vCenter. The project consists of: |
| 7 | +## Documentation |
8 | 8 |
|
9 | | -- **Operator**: A Kubebuilder-based controller that reconciles the `VmwareCloudFoundationMigration` custom resource. It prepares infrastructure (credentials, failure domains), initializes the destination, configures multi-site, migrates workload (machines/nodes), and cleans up the source. The operator uses the cluster's Machine API and OpenShift-specific resources; vSphere operations are performed via govmomi against the target vCenter. |
| 9 | +- **User Guide** |
| 10 | + - [Install with OLM](docs/user/install-with-olm.md) |
| 11 | + - [Install without OLM](docs/user/install-without-olm.md) |
10 | 12 |
|
11 | | -- **OpenShift Console Plugin**: A dynamic plugin that adds a "VCF Migration" section to the OpenShift console (Administrator perspective). It provides a list of migrations, a create wizard (credentials + vCenter browse for failure domains), and a detail view with condition progress, live event stream (SSE), and machine topology. The plugin backend is a Go HTTP server that serves the webpack-built frontend and exposes API routes for vCenter inventory browsing and event streaming; the UI uses the console SDK for all Kubernetes CRUD and watch operations. |
| 13 | +- **Developer Guide** |
| 14 | + - [API Reference](docs/dev/api.md) — CR spec, status, condition types |
| 15 | + - [Architecture](docs/dev/architecture.md) — package layout, reconciliation flow, requeue strategy |
| 16 | + - [Development](docs/dev/development.md) — build, test, deploy, code generation, CI |
12 | 17 |
|
13 | | -## Destination Topology Tags |
| 18 | +## Quick Start |
14 | 19 |
|
15 | | -During the `DestinationInitialized` phase, after preflight confirms the target vCenter user has the required tagging privileges, the operator creates the shared OpenShift topology tag model on the destination vCenter: |
| 20 | +```bash |
| 21 | +# Build and deploy the operator |
| 22 | +make operator-image operator-push IMG=<registry>/vcf-migration-operator:latest |
| 23 | +make deploy IMG=<registry>/vcf-migration-operator:latest |
16 | 24 |
|
17 | | -- The `openshift-region` and `openshift-zone` categories are created with `SINGLE` cardinality. |
18 | | -- New categories are created with associable types `Datacenter`, `ClusterComputeResource`, `Datastore`, and `Folder`. |
19 | | -- The region tag from `failureDomain.region` is attached to the target datacenter. |
20 | | -- The zone tag from `failureDomain.zone` is attached to the target compute cluster. |
21 | | -- Multiple failure domains can share the same region while using different zones. |
22 | | -- This mirrors the topology tag model used by the OpenShift vSphere cloud provider and CSI driver to discover failure domains. |
23 | | - |
24 | | -The category ownership model is intentionally shared per vCenter rather than cluster-specific. If `openshift-region` or `openshift-zone` already exists, the operator reuses it and never deletes or rewrites it. Brownfield reuse is validated before proceeding: the category must keep `SINGLE` cardinality and must allow at least `Datacenter` and `ClusterComputeResource`. Extra associable types and different descriptions are tolerated. If an existing category is incompatible, the operator fails with an error that tells the administrator to update the category in the vSphere UI or delete it and let the operator recreate it. |
25 | | - |
26 | | -## Getting Started |
27 | | - |
28 | | -### Prerequisites |
29 | | -- go version v1.25.0+ |
30 | | -- podman |
31 | | -- kubectl version v1.11.3+ |
32 | | -- Access to a Kubernetes v1.11.3+ cluster |
33 | | - |
34 | | -### To Deploy on the cluster |
35 | | -**Build and push your image to the location specified by `IMG`:** |
36 | | - |
37 | | -```sh |
38 | | -make operator-image operator-push IMG=<some-registry>/vcf-migration-operator:tag |
39 | | -``` |
40 | | - |
41 | | -**NOTE:** This image ought to be published in the personal registry you specified. |
42 | | -And it is required to have access to pull the image from the working environment. |
43 | | -Make sure you have the proper permission to the registry if the above commands don't work. |
44 | | - |
45 | | -**Install the CRDs into the cluster:** |
46 | | - |
47 | | -```sh |
48 | | -make install |
49 | | -``` |
50 | | - |
51 | | -**Deploy the Manager to the cluster with the image specified by `IMG`:** |
52 | | - |
53 | | -```sh |
54 | | -make deploy IMG=<some-registry>/vcf-migration-operator:tag |
55 | | -``` |
56 | | - |
57 | | -> **NOTE**: If you encounter RBAC errors, you may need to grant yourself cluster-admin |
58 | | -privileges or be logged in as admin. |
59 | | - |
60 | | -**Create instances of your solution** |
61 | | - |
62 | | -Apply the sample migration CRs from `config/samples/` (if present): |
63 | | - |
64 | | -```sh |
| 25 | +# Apply a sample migration |
65 | 26 | kubectl apply -k config/samples/ |
66 | 27 | ``` |
67 | 28 |
|
68 | | ->**NOTE**: Ensure that the samples has default values to test it out. |
69 | | -
|
70 | | -### To Uninstall |
71 | | -**Delete the instances (CRs) from the cluster:** |
72 | | - |
73 | | -```sh |
74 | | -kubectl delete -k config/samples/ |
75 | | -``` |
76 | | - |
77 | | -**Delete the APIs(CRDs) from the cluster:** |
78 | | - |
79 | | -```sh |
80 | | -make uninstall |
81 | | -``` |
82 | | - |
83 | | -**UnDeploy the controller from the cluster:** |
84 | | - |
85 | | -```sh |
86 | | -make undeploy |
87 | | -``` |
88 | | - |
89 | | -## OpenShift Console Plugin |
90 | | - |
91 | | -The console plugin runs as a separate Deployment and registers with the OpenShift console via a `ConsolePlugin` custom resource. It serves the UI and backend APIs (vCenter browse, event stream) over HTTPS. |
92 | | - |
93 | | -### Prerequisites (plugin) |
94 | | - |
95 | | -- Node.js 18+ and npm (for building the frontend) |
96 | | -- Go 1.25+ (backend shares the repo's Go module and reuses `internal/vsphere`) |
97 | | - |
98 | | -### Build the plugin |
99 | | - |
100 | | -```sh |
101 | | -# Frontend (webpack bundle into console-plugin/web/dist) |
102 | | -make console-plugin-frontend |
103 | | - |
104 | | -# Backend (Go binary to bin/console-plugin) |
105 | | -make console-plugin-backend |
106 | | - |
107 | | -# Container image (default tag: vcf-migration-console-plugin:latest) |
108 | | -make console-plugin-image |
109 | | -# Or with a custom tag: |
110 | | -make console-plugin-image CONSOLE_PLUGIN_IMG=<registry>/vcf-migration-console-plugin:<tag> |
111 | | -``` |
112 | | - |
113 | | -### Push the plugin image |
114 | | - |
115 | | -```sh |
116 | | -make console-plugin-push CONSOLE_PLUGIN_IMG=<registry>/vcf-migration-console-plugin:<tag> |
117 | | -``` |
118 | | - |
119 | | -### Deploy the plugin |
120 | | - |
121 | | -Ensure the plugin image is available to the cluster (e.g. push to the cluster's registry or load into Kind). Then: |
122 | | - |
123 | | -```sh |
124 | | -make deploy-console-plugin CONSOLE_PLUGIN_IMG=<registry>/vcf-migration-console-plugin:<tag> |
125 | | -``` |
126 | | - |
127 | | -This applies the Kustomize manifests under `console-plugin/deploy/` (ConsolePlugin CR, Deployment, Service, RBAC). The image in the Deployment manifest is set to `CONSOLE_PLUGIN_IMG` via kustomize. The plugin appears in the Administrator perspective under **VCF Migration → Migrations**. |
128 | | - |
129 | | -### Undeploy the plugin |
130 | | - |
131 | | -```sh |
132 | | -make undeploy-console-plugin |
133 | | -``` |
134 | | - |
135 | | -### Plugin layout |
136 | | - |
137 | | -- `console-plugin/cmd/plugin/` — Go entrypoint; TLS flags, Kube client, server startup |
138 | | -- `console-plugin/pkg/server/` — HTTP server, route registration, static file serving |
139 | | -- `console-plugin/pkg/handlers/` — vSphere API handlers (connect, datacenters, clusters, datastores, networks, resource pools, templates, folders) and SSE events handler |
140 | | -- `console-plugin/web/` — React + TypeScript + PatternFly; `console-extensions.json` for nav/routes; SDK for K8s watch/create |
141 | | -- `console-plugin/deploy/` — ConsolePlugin, Deployment, Service, RBAC, kustomization |
142 | | - |
143 | | -## Container Images |
144 | | - |
145 | | -Both the operator and console plugin images are built with podman by default. The container tool can be overridden via `CONTAINER_TOOL`. |
146 | | - |
147 | | -| Target | Description | |
148 | | -|--------|-------------| |
149 | | -| `make operator-image IMG=...` | Build the operator image | |
150 | | -| `make operator-push IMG=...` | Push the operator image | |
151 | | -| `make console-plugin-image CONSOLE_PLUGIN_IMG=...` | Build the console plugin image | |
152 | | -| `make console-plugin-push CONSOLE_PLUGIN_IMG=...` | Push the console plugin image | |
153 | | - |
154 | | -Both `make deploy` and `make deploy-console-plugin` use kustomize to set the image in the respective manifests before applying, so the deployed image always matches the variable you pass. |
155 | | - |
156 | | -## Project Distribution |
157 | | - |
158 | | -Following the options to release and provide this solution to the users. |
159 | | - |
160 | | -### By providing a bundle with all YAML files |
161 | | - |
162 | | -1. Build the installer for the image built and published in the registry: |
163 | | - |
164 | | -```sh |
165 | | -make build-installer IMG=<some-registry>/vcf-migration-operator:tag |
166 | | -``` |
167 | | - |
168 | | -**NOTE:** The makefile target mentioned above generates an 'install.yaml' |
169 | | -file in the dist directory. This file contains all the resources built |
170 | | -with Kustomize, which are necessary to install this project without its |
171 | | -dependencies. |
172 | | - |
173 | | -2. Using the installer |
174 | | - |
175 | | -Users can just run 'kubectl apply -f <URL for YAML BUNDLE>' to install |
176 | | -the project, i.e.: |
177 | | - |
178 | | -```sh |
179 | | -kubectl apply -f https://raw.githubusercontent.com/<org>/vcf-migration-operator/<tag or branch>/dist/install.yaml |
180 | | -``` |
181 | | - |
182 | | -### By providing a Helm Chart |
183 | | - |
184 | | -1. Build the chart using the optional helm plugin |
185 | | - |
186 | | -```sh |
187 | | -operator-sdk edit --plugins=helm/v1-alpha |
188 | | -``` |
189 | | - |
190 | | -2. See that a chart was generated under 'dist/chart', and users |
191 | | -can obtain this solution from there. |
192 | | - |
193 | | -**NOTE:** If you change the project, you need to update the Helm Chart |
194 | | -using the same command above to sync the latest changes. Furthermore, |
195 | | -if you create webhooks, you need to use the above command with |
196 | | -the '--force' flag and manually ensure that any custom configuration |
197 | | -previously added to 'dist/chart/values.yaml' or 'dist/chart/manager/manager.yaml' |
198 | | -is manually re-applied afterwards. |
| 29 | +See the [user docs](docs/user/) for full installation instructions and the [development guide](docs/dev/development.md) for building from source. |
199 | 30 |
|
200 | 31 | ## Contributing |
201 | 32 |
|
202 | | -Contributions are welcome. Please open an issue or PR and follow the code style and conventions described in this repo (see also `AGENTS.md` for build, lint, and test commands). |
203 | | - |
204 | | -**NOTE:** Run `make help` for more information on all potential `make` targets. |
205 | | - |
206 | | -More information can be found via the [Kubebuilder Documentation](https://book.kubebuilder.io/introduction.html) |
| 33 | +Contributions are welcome. Run `make help` for all available targets. See also `AGENTS.md` for build, lint, and test commands. |
207 | 34 |
|
208 | 35 | ## License |
209 | 36 |
|
210 | | -Copyright 2026. |
211 | | - |
212 | | -Licensed under the Apache License, Version 2.0 (the "License"); |
213 | | -you may not use this file except in compliance with the License. |
214 | | -You may obtain a copy of the License at |
215 | | - |
216 | | - http://www.apache.org/licenses/LICENSE-2.0 |
217 | | - |
218 | | -Unless required by applicable law or agreed to in writing, software |
219 | | -distributed under the License is distributed on an "AS IS" BASIS, |
220 | | -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
221 | | -See the License for the specific language governing permissions and |
222 | | -limitations under the License. |
| 37 | +Copyright 2026. Licensed under the [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0). |
0 commit comments