Skip to content

Commit 186dd09

Browse files
authored
Merge pull request kubernetes-sigs#7005 from oscr/clusterctl-add-move-flags
✨ clusterctl: Add move --to-directory and --from-directory flags
2 parents 65ab8ad + 44f9fd9 commit 186dd09

File tree

12 files changed

+238
-108
lines changed

12 files changed

+238
-108
lines changed

cmd/clusterctl/client/client.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,11 @@ type Client interface {
5555
Move(options MoveOptions) error
5656

5757
// Backup saves all the Cluster API objects existing in a namespace (or from all the namespaces if empty) to a target management cluster.
58+
// Deprecated: This will be dropped in a future release. Please use Move.
5859
Backup(options BackupOptions) error
5960

6061
// Restore restores all the Cluster API objects existing in a configured directory based on a glob to a target management cluster.
62+
// Deprecated: This will be dropped in a future release. Please use Move.
6163
Restore(options RestoreOptions) error
6264

6365
// PlanUpgrade returns a set of suggested Upgrade plans for the cluster, and more specifically:

cmd/clusterctl/client/cluster/mover.go

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,19 @@ import (
4545
type ObjectMover interface {
4646
// Move moves all the Cluster API objects existing in a namespace (or from all the namespaces if empty) to a target management cluster.
4747
Move(namespace string, toCluster Client, dryRun bool) error
48-
// Backup saves all the Cluster API objects existing in a namespace (or from all the namespaces if empty) to a target management cluster.
48+
49+
// ToDirectory writes all the Cluster API objects existing in a namespace (or from all the namespaces if empty) to a target directory.
50+
ToDirectory(namespace string, directory string) error
51+
52+
// FromDirectory reads all the Cluster API objects existing in a configured directory to a target management cluster.
53+
FromDirectory(toCluster Client, directory string) error
54+
55+
// Backup saves all the Cluster API objects existing in a namespace (or from all the namespaces if empty) to a target directory.
56+
// Deprecated: This will be dropped in a future release. Please use ToDirectory.
4957
Backup(namespace string, directory string) error
58+
5059
// Restore restores all the Cluster API objects existing in a configured directory to a target management cluster.
60+
// Deprecated: This will be dropped in a future release. Please use FromDirectory.
5161
Restore(toCluster Client, directory string) error
5262
}
5363

@@ -94,21 +104,33 @@ func (o *objectMover) Move(namespace string, toCluster Client, dryRun bool) erro
94104

95105
func (o *objectMover) Backup(namespace string, directory string) error {
96106
log := logf.Log
97-
log.Info("Performing backup...")
107+
log.V(5).Info("Deprecated: This function will be dropped in a future release. Please use ToDirectory instead of Backup.")
108+
return o.ToDirectory(namespace, directory)
109+
}
110+
111+
func (o *objectMover) ToDirectory(namespace string, directory string) error {
112+
log := logf.Log
113+
log.Info("Moving to directory...")
98114

99115
objectGraph, err := o.getObjectGraph(namespace)
100116
if err != nil {
101117
return errors.Wrap(err, "failed to get object graph")
102118
}
103119

104-
return o.backup(objectGraph, directory)
120+
return o.toDirectory(objectGraph, directory)
105121
}
106122

107123
func (o *objectMover) Restore(toCluster Client, directory string) error {
108124
log := logf.Log
109-
log.Info("Performing restore...")
125+
log.V(5).Info("Deprecated: This function will be dropped in a future release. Please use FromDirectory instead of Restore.")
126+
return o.FromDirectory(toCluster, directory)
127+
}
128+
129+
func (o *objectMover) FromDirectory(toCluster Client, directory string) error {
130+
log := logf.Log
131+
log.Info("Moving from directory...")
110132

111-
// Build an empty object graph used for the restore sequence not tied to a specific namespace
133+
// Build an empty object graph used for the fromDirectory sequence not tied to a specific namespace
112134
objectGraph := newObjectGraph(o.fromProxy, o.fromProviderInventory)
113135

114136
// Gets all the types defined by the CRDs installed by clusterctl plus the ConfigMap/Secret core types.
@@ -135,13 +157,13 @@ func (o *objectMover) Restore(toCluster Client, directory string) error {
135157
// Completes the graph by setting for each node the list of tenants the node belongs to.
136158
objectGraph.setTenants()
137159

138-
// Check whether nodes are not included in GVK considered for restore.
160+
// Check whether nodes are not included in GVK considered for fromDirectory.
139161
objectGraph.checkVirtualNode()
140162

141163
// Restore the objects to the target cluster.
142164
proxy := toCluster.Proxy()
143165

144-
return o.restore(objectGraph, proxy)
166+
return o.fromDirectory(objectGraph, proxy)
145167
}
146168

147169
func (o *objectMover) filesToObjs(dir string) ([]unstructured.Unstructured, error) {
@@ -191,7 +213,7 @@ func (o *objectMover) getObjectGraph(namespace string) (*objectGraph, error) {
191213
return nil, errors.Wrap(err, "failed to discover the object graph")
192214
}
193215

194-
// Checks if Cluster API has already completed the provisioning of the infrastructure for the objects involved in the move/backup operation.
216+
// Checks if Cluster API has already completed the provisioning of the infrastructure for the objects involved in the move/toDirectory operation.
195217
// This is required because if the infrastructure is provisioned, then we can reasonably assume that the objects we are moving/backing up are
196218
// not currently waiting for long-running reconciliation loops, and so we can safely rely on the pause field on the Cluster object
197219
// for blocking any further object reconciliation on the source objects.
@@ -366,11 +388,11 @@ func (o *objectMover) move(graph *objectGraph, toProxy Proxy) error {
366388
return setClusterPause(toProxy, clusters, false, o.dryRun)
367389
}
368390

369-
func (o *objectMover) backup(graph *objectGraph, directory string) error {
391+
func (o *objectMover) toDirectory(graph *objectGraph, directory string) error {
370392
log := logf.Log
371393

372394
clusters := graph.getClusters()
373-
log.Info("Starting backup of Cluster API objects", "Clusters", len(clusters))
395+
log.Info("Starting move of Cluster API objects", "Clusters", len(clusters))
374396

375397
clusterClasses := graph.getClusterClasses()
376398
log.Info("Moving Cluster API objects", "ClusterClasses", len(clusterClasses))
@@ -412,7 +434,7 @@ func (o *objectMover) backup(graph *objectGraph, directory string) error {
412434
return setClusterPause(o.fromProxy, clusters, false, o.dryRun)
413435
}
414436

415-
func (o *objectMover) restore(graph *objectGraph, toProxy Proxy) error {
437+
func (o *objectMover) fromDirectory(graph *objectGraph, toProxy Proxy) error {
416438
log := logf.Log
417439

418440
// Get clusters from graph
@@ -448,8 +470,8 @@ func (o *objectMover) restore(graph *objectGraph, toProxy Proxy) error {
448470
return errors.Wrap(err, "error resuming ClusterClasses")
449471
}
450472

451-
// Resume reconciling the Clusters after being restored from a backup.
452-
// By default, during backup, Clusters are paused so they must be unpaused to be used again
473+
// Resume reconciling the Clusters after being restored from a directory.
474+
// By default, when moved to a directory , Clusters are paused, so they must be unpaused to be used again.
453475
log.V(1).Info("Resuming the target cluster")
454476
return setClusterPause(toProxy, clusters, false, o.dryRun)
455477
}
@@ -972,7 +994,7 @@ func (o *objectMover) restoreTargetObject(nodeToCreate *node, toProxy Proxy) err
972994
existingTargetObj.SetAPIVersion(nodeToCreate.restoreObject.GetAPIVersion())
973995
existingTargetObj.SetKind(nodeToCreate.restoreObject.GetKind())
974996
if err := cTo.Get(ctx, objKey, existingTargetObj); err == nil {
975-
log.V(5).Info("Object already exists, skipping restore", nodeToCreate.identity.Kind, nodeToCreate.identity.Name, "Namespace", nodeToCreate.identity.Namespace)
997+
log.V(5).Info("Object already exists, skipping moving from directory", nodeToCreate.identity.Kind, nodeToCreate.identity.Name, "Namespace", nodeToCreate.identity.Namespace)
976998

977999
// Update the nodes UID since it already exits. Any nodes owned by this existing node will be updated when the owner chain is rebuilt
9781000
nodeToCreate.newUID = existingTargetObj.GetUID()

cmd/clusterctl/client/cluster/mover_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -706,7 +706,7 @@ func Test_objectMover_backupTargetObject(t *testing.T) {
706706
// Add delay so we ensure the file ModTime of updated files is different from old ones in the original files
707707
time.Sleep(time.Millisecond * 50)
708708

709-
// Running backupTargetObject should override any existing files since it represents a new backup
709+
// Running backupTargetObject should override any existing files since it represents a new toDirectory
710710
err = mover.backupTargetObject(node, dir)
711711
if tt.wantErr {
712712
g.Expect(err).To(HaveOccurred())
@@ -855,7 +855,7 @@ func Test_objectMover_backup(t *testing.T) {
855855
// trigger discovery the content of the source cluster
856856
g.Expect(graph.Discovery("")).To(Succeed())
857857

858-
// Run backup
858+
// Run toDirectory
859859
mover := objectMover{
860860
fromProxy: graph.proxy,
861861
}
@@ -866,7 +866,7 @@ func Test_objectMover_backup(t *testing.T) {
866866
}
867867
defer os.RemoveAll(dir)
868868

869-
err = mover.backup(graph, dir)
869+
err = mover.toDirectory(graph, dir)
870870
if tt.wantErr {
871871
g.Expect(err).To(HaveOccurred())
872872
return
@@ -996,7 +996,7 @@ func Test_objectMover_restore(t *testing.T) {
996996
// gets a fakeProxy to an empty cluster with all the required CRDs
997997
toProxy := getFakeProxyWithCRDs()
998998

999-
// Run restore
999+
// Run fromDirectory
10001000
mover := objectMover{
10011001
fromProxy: graph.proxy,
10021002
}
@@ -1018,14 +1018,14 @@ func Test_objectMover_restore(t *testing.T) {
10181018
g.Expect(graph.addRestoredObj(&objs[i])).NotTo(HaveOccurred())
10191019
}
10201020

1021-
// restore works on the target cluster which does not yet have objs to discover
1021+
// fromDirectory works on the target cluster which does not yet have objs to discover
10221022
// instead set the owners and tenants correctly on object graph like how ObjectMover.Restore does
10231023
// https://github.com/kubernetes-sigs/cluster-api/blob/main/cmd/clusterctl/client/cluster/mover.go#L129-L132
10241024
graph.setSoftOwnership()
10251025
graph.setTenants()
10261026
graph.checkVirtualNode()
10271027

1028-
err = mover.restore(graph, toProxy)
1028+
err = mover.fromDirectory(graph, toProxy)
10291029
if tt.wantErr {
10301030
g.Expect(err).To(HaveOccurred())
10311031
return

cmd/clusterctl/client/cluster/objectgraph.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ type node struct {
8282
// the node is linked to a object indirectly in the OwnerReference chain.
8383
tenant map[*node]empty
8484

85-
// restoreObject holds the object that is referenced when creating a node during restore from file.
85+
// restoreObject holds the object that is referenced when creating a node during fromDirectory from file.
8686
// the object can then be referenced latter when restoring objects to a target management cluster
8787
restoreObject *unstructured.Unstructured
8888

@@ -179,8 +179,8 @@ func (o *objectGraph) addObj(obj *unstructured.Unstructured) error {
179179
return nil
180180
}
181181

182-
// addRestoredObj adds a Kubernetes object to the object graph from file that is generated during a restore
183-
// Populates the restoredObject field to be referenced during restore
182+
// addRestoredObj adds a Kubernetes object to the object graph from file that is generated during a fromDirectory
183+
// Populates the restoredObject field to be referenced during fromDirectory
184184
// During add, OwnerReferences are processed in order to create the dependency graph.
185185
func (o *objectGraph) addRestoredObj(obj *unstructured.Unstructured) error {
186186
// Add object to graph

0 commit comments

Comments
 (0)