diff --git a/components/cluster/command/rename.go b/components/cluster/command/rename.go new file mode 100644 index 0000000000..e16838a9a3 --- /dev/null +++ b/components/cluster/command/rename.go @@ -0,0 +1,42 @@ +// Copyright 2020 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// See the License for the specific language governing permissions and +// limitations under the License. + +package command + +import ( + "github.com/spf13/cobra" +) + +func newRenameCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "rename ", + Short: "Rename the cluster", + RunE: func(cmd *cobra.Command, args []string) error { + if len(args) != 2 { + return cmd.Help() + } + + if err := validRoles(gOpt.Roles); err != nil { + return err + } + + oldClusterName := args[0] + newClusterName := args[1] + teleCommand = append(teleCommand, scrubClusterName(oldClusterName)) + + return manager.Rename(oldClusterName, gOpt, newClusterName) + }, + } + + return cmd +} diff --git a/components/cluster/command/root.go b/components/cluster/command/root.go index 86c7309e97..85f450707d 100644 --- a/components/cluster/command/root.go +++ b/components/cluster/command/root.go @@ -157,6 +157,7 @@ func init() { newEditConfigCmd(), newReloadCmd(), newPatchCmd(), + newRenameCmd(), newTestCmd(), // hidden command for test internally newTelemetryCmd(), ) diff --git a/pkg/cluster/manager.go b/pkg/cluster/manager.go index 81e8e5cbdd..87f3139453 100644 --- a/pkg/cluster/manager.go +++ b/pkg/cluster/manager.go @@ -47,6 +47,10 @@ import ( var ( errNSDeploy = errorx.NewNamespace("deploy") errDeployNameDuplicate = errNSDeploy.NewType("name_dup", errutil.ErrTraitPreCheck) + + errNSRename = errorx.NewNamespace("rename") + errorRenameNameNotExist = errNSRename.NewType("name_not_exist", errutil.ErrTraitPreCheck) + errorRenameNameDuplicate = errNSRename.NewType("name_dup", errutil.ErrTraitPreCheck) ) // Manager to deploy a cluster. @@ -524,6 +528,29 @@ func (m *Manager) EditConfig(clusterName string, skipConfirm bool) error { return nil } +// Rename the cluster +func (m *Manager) Rename(clusterName string, opt operator.Options, newName string) error { + if !utils.IsExist(m.specManager.Path(clusterName)) { + return errorRenameNameNotExist. + New("Cluster name '%s' not exist", clusterName). + WithProperty(cliutil.SuggestionFromFormat("Please double check your cluster name")) + } + if utils.IsExist(m.specManager.Path(newName)) { + return errorRenameNameDuplicate. + New("Cluster name '%s' is duplicated", newName). + WithProperty(cliutil.SuggestionFromFormat("Please specify another cluster name")) + } + + if err := os.Rename(m.specManager.Path(clusterName), m.specManager.Path(newName)); err != nil { + return perrs.AddStack(err) + } + + log.Infof("Rename cluster `%s` -> `%s` successfully", clusterName, newName) + + opt.Roles = []string{spec.ComponentGrafana, spec.ComponentPrometheus} + return m.Reload(newName, opt, false) +} + // Reload the cluster. func (m *Manager) Reload(clusterName string, opt operator.Options, skipRestart bool) error { sshTimeout := opt.SSHTimeout diff --git a/tests/tiup-cluster/script/cmd_subtest.sh b/tests/tiup-cluster/script/cmd_subtest.sh index e3c2dca8a7..79ab05224b 100755 --- a/tests/tiup-cluster/script/cmd_subtest.sh +++ b/tests/tiup-cluster/script/cmd_subtest.sh @@ -56,6 +56,11 @@ function cmd_subtest() { tiup-cluster $client display $name + # Test rename + tiup-cluster $client rename $name "tmp-cluster-name" + tiup-cluster $client display "tmp-cluster-name" + tiup-cluster $client rename "tmp-cluster-name" $name + tiup-cluster $client --yes clean $name --data --all --ignore-node 172.19.0.101:9090 echo "checking cleanup data and log"