Feat: support alias in cluster (#3630)

* Feat: support alias in cluster

Signed-off-by: Somefive <yd219913@alibaba-inc.com>

* Fix: add test for cluster alias

Signed-off-by: Somefive <yd219913@alibaba-inc.com>
This commit is contained in:
Somefive
2022-04-13 13:58:35 +08:00
committed by GitHub
parent 385b2462e9
commit 7a0d2b552b
5 changed files with 87 additions and 6 deletions
+9 -1
View File
@@ -16,7 +16,10 @@ limitations under the License.
package types
import "github.com/oam-dev/cluster-gateway/pkg/apis/cluster/v1alpha1"
import (
"github.com/oam-dev/cluster-gateway/pkg/apis/cluster/v1alpha1"
"github.com/oam-dev/cluster-gateway/pkg/config"
)
const (
// CredentialTypeInternal identifies the virtual cluster from internal kubevela system
@@ -29,3 +32,8 @@ const (
// ClustersArg indicates the argument for specific clusters to install addon
ClustersArg = "clusters"
)
var (
// AnnotationClusterAlias the annotation key for cluster alias
AnnotationClusterAlias = config.MetaApiGroupName + "/cluster-alias"
)
+13
View File
@@ -449,6 +449,19 @@ func RenameCluster(ctx context.Context, k8sClient client.Client, oldClusterName
return nil
}
// AliasCluster alias cluster
func AliasCluster(ctx context.Context, cli client.Client, clusterName string, aliasName string) error {
if clusterName == ClusterLocalName {
return ErrReservedLocalClusterName
}
vc, err := GetVirtualCluster(ctx, cli, clusterName)
if err != nil {
return err
}
setClusterAlias(vc.Object, aliasName)
return cli.Update(ctx, vc.Object)
}
// ensureClusterNotExists will check the cluster is not existed in control plane
func ensureClusterNotExists(ctx context.Context, c client.Client, clusterName string) error {
_, err := GetVirtualCluster(ctx, c, clusterName)
+28
View File
@@ -18,6 +18,7 @@ package multicluster
import (
"context"
"fmt"
"github.com/pkg/errors"
corev1 "k8s.io/api/core/v1"
@@ -38,6 +39,7 @@ import (
// like cluster secret or ocm managed cluster
type VirtualCluster struct {
Name string
Alias string
Type v1alpha1.CredentialType
EndPoint string
Accepted bool
@@ -46,6 +48,30 @@ type VirtualCluster struct {
Object client.Object
}
// FullName the name with alias if available
func (vc *VirtualCluster) FullName() string {
if vc.Alias != "" {
return fmt.Sprintf("%s (%s)", vc.Name, vc.Alias)
}
return vc.Name
}
func getClusterAlias(o client.Object) string {
if annots := o.GetAnnotations(); annots != nil {
return annots[types.AnnotationClusterAlias]
}
return ""
}
func setClusterAlias(o client.Object, alias string) {
annots := o.GetAnnotations()
if annots == nil {
annots = map[string]string{}
}
annots[types.AnnotationClusterAlias] = alias
o.SetAnnotations(annots)
}
// NewVirtualClusterFromLocal return virtual cluster corresponding to local cluster
func NewVirtualClusterFromLocal() *VirtualCluster {
return &VirtualCluster{
@@ -74,6 +100,7 @@ func NewVirtualClusterFromSecret(secret *corev1.Secret) (*VirtualCluster, error)
}
return &VirtualCluster{
Name: secret.Name,
Alias: getClusterAlias(secret),
Type: v1alpha1.CredentialType(credType),
EndPoint: endpoint,
Accepted: true,
@@ -90,6 +117,7 @@ func NewVirtualClusterFromManagedCluster(managedCluster *clusterv1.ManagedCluste
}
return &VirtualCluster{
Name: managedCluster.Name,
Alias: getClusterAlias(managedCluster),
Type: types.CredentialTypeOCMManagedCluster,
EndPoint: types.ClusterBlankEndpoint,
Accepted: managedCluster.Spec.HubAcceptsClient,
+29 -5
View File
@@ -88,6 +88,7 @@ func ClusterCommandGroup(c common.Args, ioStreams cmdutil.IOStreams) *cobra.Comm
NewClusterDetachCommand(&c),
NewClusterProbeCommand(&c),
NewClusterLabelCommandGroup(&c),
NewClusterAliasCommand(&c),
)
return cmd
}
@@ -101,7 +102,7 @@ func NewClusterListCommand(c *common.Args) *cobra.Command {
Long: "list worker clusters managed by KubeVela.",
Args: cobra.ExactValidArgs(0),
RunE: func(cmd *cobra.Command, args []string) error {
table := newUITable().AddRow("CLUSTER", "TYPE", "ENDPOINT", "ACCEPTED", "LABELS")
table := newUITable().AddRow("CLUSTER", "ALIAS", "TYPE", "ENDPOINT", "ACCEPTED", "LABELS")
client, err := c.GetClient()
if err != nil {
return err
@@ -123,9 +124,9 @@ func NewClusterListCommand(c *common.Args) *cobra.Command {
}
for i, l := range labels {
if i == 0 {
table.AddRow(cluster.Name, cluster.Type, cluster.EndPoint, fmt.Sprintf("%v", cluster.Accepted), l)
table.AddRow(cluster.Name, cluster.Alias, cluster.Type, cluster.EndPoint, fmt.Sprintf("%v", cluster.Accepted), l)
} else {
table.AddRow("", "", "", "", l)
table.AddRow("", "", "", "", "", l)
}
}
}
@@ -255,6 +256,29 @@ func NewClusterDetachCommand(c *common.Args) *cobra.Command {
return cmd
}
// NewClusterAliasCommand create an alias to the named cluster
func NewClusterAliasCommand(c *common.Args) *cobra.Command {
cmd := &cobra.Command{
Use: "alias CLUSTER_NAME ALIAS",
Short: "alias a named cluster.",
Long: "alias a named cluster.",
Args: cobra.ExactValidArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
clusterName, aliasName := args[0], args[1]
k8sClient, err := c.GetClient()
if err != nil {
return err
}
if err = multicluster.AliasCluster(context.Background(), k8sClient, clusterName, aliasName); err != nil {
return err
}
cmd.Printf("Alias cluster %s as %s.\n", clusterName, aliasName)
return nil
},
}
return cmd
}
// NewClusterProbeCommand create command to help user try health probe for existing cluster
// TODO(somefive): move prob logic into cluster management
func NewClusterProbeCommand(c *common.Args) *cobra.Command {
@@ -299,12 +323,12 @@ func NewClusterLabelCommandGroup(c *common.Args) *cobra.Command {
func updateClusterLabelAndPrint(cmd *cobra.Command, cli client.Client, vc *multicluster.VirtualCluster, clusterName string) (err error) {
if err = cli.Update(context.Background(), vc.Object); err != nil {
return errors.Errorf("failed to update labels for cluster %s (type: %s)", vc.Name, vc.Type)
return errors.Errorf("failed to update labels for cluster %s, type: %s", vc.FullName(), vc.Type)
}
if vc, err = multicluster.GetVirtualCluster(context.Background(), cli, clusterName); err != nil {
return errors.Wrapf(err, "failed to get updated cluster %s", clusterName)
}
cmd.Printf("Successfully update labels for cluster %s (type: %s).\n", vc.Name, vc.Type)
cmd.Printf("Successfully update labels for cluster %s, type: %s.\n", vc.FullName(), vc.Type)
if len(vc.Labels) == 0 {
cmd.Println("No valid label exists.")
}
@@ -111,6 +111,14 @@ var _ = Describe("Test multicluster scenario", func() {
Expect(out).ShouldNot(ContainSubstring("purpose"))
})
It("Test alias for cluster", func() {
_, err := execCommand("cluster", "alias", WorkerClusterName, "alias-worker")
Expect(err).Should(Succeed())
out, err := execCommand("cluster", "list")
Expect(err).Should(Succeed())
Expect(out).Should(ContainSubstring("alias-worker"))
})
It("Test detach cluster with application use", func() {
const testClusterName = "test-cluster"
_, err := execCommand("cluster", "join", "/tmp/worker.kubeconfig", "--name", testClusterName)