Skip to content

Commit 3ae78c6

Browse files
clusterctl add move cmd
1 parent d4931f8 commit 3ae78c6

File tree

6 files changed

+147
-2
lines changed

6 files changed

+147
-2
lines changed

cmd/clusterctl/cmd/move.go

+15
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,11 @@ limitations under the License.
1717
package cmd
1818

1919
import (
20+
"fmt"
21+
2022
"github.com/pkg/errors"
2123
"github.com/spf13/cobra"
24+
"sigs.k8s.io/cluster-api/cmd/clusterctl/pkg/client"
2225
)
2326

2427
type moveOptions struct {
@@ -59,5 +62,17 @@ func init() {
5962
}
6063

6164
func runMove() error {
65+
c, err := client.New(cfgFile)
66+
if err != nil {
67+
return err
68+
}
69+
fmt.Println("performing move...")
70+
if err := c.Move(client.MoveOptions{
71+
FromKubeconfig: mo.fromKubeconfig,
72+
ToKubeconfig: mo.toKubeconfig,
73+
Namespace: mo.namespace,
74+
}); err != nil {
75+
return err
76+
}
6277
return nil
6378
}

cmd/clusterctl/pkg/client/client.go

+10
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,13 @@ type GetClusterTemplateOptions struct {
4545
WorkerMachineCount int
4646
}
4747

48+
// MoveOptions carries the options supported by move
49+
type MoveOptions struct {
50+
FromKubeconfig string
51+
ToKubeconfig string
52+
Namespace string
53+
}
54+
4855
// Client is exposes the clusterctl high-level client library
4956
type Client interface {
5057
// GetProvidersConfig returns the list of providers configured for this instance of clusterctl.
@@ -58,6 +65,9 @@ type Client interface {
5865

5966
// GetClusterTemplate returns a workload cluster template.
6067
GetClusterTemplate(options GetClusterTemplateOptions) (Template, error)
68+
69+
// Move moves all the Cluster API objects existing in a namespace (or from all the namespaces if empty) to a target management cluster
70+
Move(options MoveOptions) error
6171
}
6272

6373
// clusterctlClient implements Client.

cmd/clusterctl/pkg/client/client_test.go

+4
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,10 @@ func (f fakeClient) Init(options InitOptions) ([]Components, bool, error) {
7878
return f.internalClient.Init(options)
7979
}
8080

81+
func (f fakeClient) Move(options MoveOptions) error {
82+
return f.internalClient.Move(options)
83+
}
84+
8185
// newFakeClient returns a clusterctl client that allows to execute tests on a set of fake config, fake repositories and fake clusters.
8286
// you can use WithCluster and WithRepository to prepare for the test case.
8387
func newFakeClient(configClient config.Client) *fakeClient {

cmd/clusterctl/pkg/client/move.go

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
Copyright 2020 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package client
18+
19+
func (c *clusterctlClient) Move(options MoveOptions) error {
20+
// Get the client for interacting with the source management cluster.
21+
fromCluster, err := c.clusterClientFactory(options.FromKubeconfig)
22+
if err != nil {
23+
return err
24+
}
25+
26+
// Ensures the custom resource definitions required by clusterctl are in place.
27+
if err := fromCluster.ProviderInventory().EnsureCustomResourceDefinitions(); err != nil {
28+
return err
29+
}
30+
31+
// Get the client for interacting with the target management cluster.
32+
toCluster, err := c.clusterClientFactory(options.ToKubeconfig)
33+
if err != nil {
34+
return err
35+
}
36+
37+
// Ensures the custom resource definitions required by clusterctl are in place
38+
if err := toCluster.ProviderInventory().EnsureCustomResourceDefinitions(); err != nil {
39+
return err
40+
}
41+
42+
if err := fromCluster.ObjectMover().Move(options.Namespace, toCluster); err != nil {
43+
return err
44+
}
45+
46+
return nil
47+
}
+35
Original file line numberDiff line numberDiff line change
@@ -1 +1,36 @@
11
# clusterctl move
2+
3+
The `clusterctl move` command allows to move the Cluster API objects defining workload clusters, like e.g. Cluster, Machines,
4+
MachineDeployments, etc. from one management cluster to another management cluster.
5+
6+
<aside class="note warning">
7+
8+
<h1> Warning </h1>
9+
10+
Before running `clusterctl move`, the user should take care of preparing the target management cluster, including also installing
11+
all the required provider using `clusterctl init`.
12+
13+
The version of the providers installed in the target management cluster should be at least the same version of the
14+
corresponding provider in the source cluster.
15+
16+
</aside>
17+
18+
You can use:
19+
20+
```shell
21+
clusterctl move --to-kubeconfig="path-to-target-kubeconfig.yaml"
22+
```
23+
24+
To move all the Cluster API objects objects in the source management cluster; in case if you want to move only the
25+
Cluster API objects defined in a specific namespace, you can use the `--namespace` flag.
26+
27+
<aside class="note">
28+
29+
<h1> Pause Reconciliation </h1>
30+
31+
Before moving a `Cluster`, clusterctl sets the `Cluster.Spec.Paused` field to `true` stopping
32+
the controllers to reconcile the workload cluster _in the source management cluster_.
33+
34+
The `Cluster` object created in the target management cluster instead will be actively reconciled.
35+
36+
</aside>

docs/book/src/clusterctl/provider-contract.md

+36-2
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,25 @@ Templates writers should use the common variables to ensure consistency across p
163163
Additionally, value of the command argument to `clusterctl config cluster <cluster-name>` (`<cluster-name>` in this case), will
164164
be applied to every occurrence of the `${ CLUSTER_NAME }` variable.
165165

166+
## OwnerReferences chain
167+
168+
Each provider is responsible to ensure that all the providers resources (like e.g. `VSphereCluster`, `VSphereMachine`, `VSphereVM` etc.
169+
for the `vsphere` provider) MUST have a `Metadata.OwnerReferences` entry that links directly or indirectly to a `Cluster` object.
170+
171+
Please note that all the provider specific resources that are referenced by the Cluster API core objects will get the `OwnerReference`
172+
sets by the Cluster API core controllers, e.g.:
173+
174+
- The Cluster controller ensures that all the objects reference in `Cluster.Spec.InfrastructureRef` get an `OwnerReference`
175+
that links directly to the corresponding `Cluster`.
176+
- The Machine controller ensures that all the objects reference in `Machine.Spec.InfrastructureRef` get an `OwnerReference`
177+
that links to the corresponding `Machine`, and the `Machine` is linked to the `Cluster` through its own `OwnerReference` chain.
178+
179+
That means that, practically speaking, the provider implementers are responsibility is to ensure that the `OwnerReference`
180+
is set only for objects that are not directly referenced by Cluster API core objects, e.g.:
181+
182+
- All the `VSphereVM` should get an `OwnerReference` that links to the corresponding `VSphereMachine`, and the `VSphereMachine`
183+
is linked to the `Cluster` through its own `OwnerReference` chain.
184+
166185
## Additional notes
167186

168187
### Components YAML transformations
@@ -199,10 +218,25 @@ If, for any reason, the provider authors/YAML designers decide not to comply wit
199218
The provider authors/YAML designers should be aware that it is their responsibility to ensure the proper
200219
functioning of all the `clusterctl` features both in single tenancy or multi-tenancy scenarios and/or document known limitations.
201220

202-
### Move constraints
221+
### Move
203222

204-
WIP
223+
Provider authors should be aware that `clusterctl move` command implement a discovery mechanism that considers:
224+
225+
* All the objects of Kind defined in one of the CRDs installed by clusterctl using `clusterctl init`.
226+
* `Serets` and `ConfigMaps` objects.
227+
* the `OwnerReference` chain of the above objects.
228+
229+
`clusterctl move` does NOT consider any objects:
205230

231+
* Not included in the set of objects defined above.
232+
* Included in the set of objects defined above, but not directly or indirectly to a `Cluster` object through the `OwnerReference` chain.
233+
234+
If moving some of excluded object is required, the provider authors should create documentation describing the
235+
the exact move sequence to be executed by the user.
236+
237+
Additionally, provider authors should be aware that `clusterctl move` assumes all the provider's Controllers respect the
238+
`Cluster.Spec.Paused` field introduced in the v1alpha3 Cluster API specification.
239+
206240
### Adopt
207241

208242
WIP

0 commit comments

Comments
 (0)