mirror of
https://github.com/rancher/k3k.git
synced 2026-08-20 12:56:16 +00:00
CLI cluster update (#595)
* CLI cluster update Signed-off-by: galal-hussein <hussein.galal.ahmed.11@gmail.com>
This commit is contained in:
@@ -12,6 +12,7 @@ func NewClusterCmd(appCtx *AppContext) *cobra.Command {
|
||||
|
||||
cmd.AddCommand(
|
||||
NewClusterCreateCmd(appCtx),
|
||||
NewClusterUpdateCmd(appCtx),
|
||||
NewClusterDeleteCmd(appCtx),
|
||||
NewClusterListCmd(appCtx),
|
||||
)
|
||||
|
||||
@@ -148,9 +148,9 @@ func createAction(appCtx *AppContext, config *CreateConfig) func(cmd *cobra.Comm
|
||||
return fmt.Errorf("failed to wait for cluster to be reconciled: %w", err)
|
||||
}
|
||||
|
||||
clusterDetails, err := printClusterDetails(cluster)
|
||||
clusterDetails, err := getClusterDetails(cluster)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to print cluster details: %w", err)
|
||||
return fmt.Errorf("failed to get cluster details: %w", err)
|
||||
}
|
||||
|
||||
logrus.Info(clusterDetails)
|
||||
@@ -399,9 +399,13 @@ const clusterDetailsTemplate = `Cluster details:
|
||||
Persistence:
|
||||
Type: {{.Persistence.Type}}{{ if .Persistence.StorageClassName }}
|
||||
StorageClass: {{ .Persistence.StorageClassName }}{{ end }}{{ if .Persistence.StorageRequestSize }}
|
||||
Size: {{ .Persistence.StorageRequestSize }}{{ end }}`
|
||||
Size: {{ .Persistence.StorageRequestSize }}{{ end }}{{ if .Labels }}
|
||||
Labels: {{ range $key, $value := .Labels }}
|
||||
{{$key}}: {{$value}}{{ end }}{{ end }}{{ if .Annotations }}
|
||||
Annotations: {{ range $key, $value := .Annotations }}
|
||||
{{$key}}: {{$value}}{{ end }}{{ end }}`
|
||||
|
||||
func printClusterDetails(cluster *v1beta1.Cluster) (string, error) {
|
||||
func getClusterDetails(cluster *v1beta1.Cluster) (string, error) {
|
||||
type templateData struct {
|
||||
Mode v1beta1.ClusterMode
|
||||
Servers int32
|
||||
@@ -413,6 +417,8 @@ func printClusterDetails(cluster *v1beta1.Cluster) (string, error) {
|
||||
StorageClassName string
|
||||
StorageRequestSize string
|
||||
}
|
||||
Labels map[string]string
|
||||
Annotations map[string]string
|
||||
}
|
||||
|
||||
data := templateData{
|
||||
@@ -421,6 +427,8 @@ func printClusterDetails(cluster *v1beta1.Cluster) (string, error) {
|
||||
Agents: ptr.Deref(cluster.Spec.Agents, 0),
|
||||
Version: cluster.Spec.Version,
|
||||
HostVersion: cluster.Status.HostVersion,
|
||||
Annotations: cluster.Annotations,
|
||||
Labels: cluster.Labels,
|
||||
}
|
||||
|
||||
data.Persistence.Type = cluster.Spec.Persistence.Type
|
||||
|
||||
@@ -87,7 +87,7 @@ func Test_printClusterDetails(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
clusterDetails, err := printClusterDetails(tt.cluster)
|
||||
clusterDetails, err := getClusterDetails(tt.cluster)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, tt.want, clusterDetails)
|
||||
})
|
||||
|
||||
@@ -0,0 +1,198 @@
|
||||
package cmds
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/blang/semver/v4"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/utils/ptr"
|
||||
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
|
||||
"github.com/rancher/k3k/pkg/apis/k3k.io/v1beta1"
|
||||
k3kcluster "github.com/rancher/k3k/pkg/controller/cluster"
|
||||
)
|
||||
|
||||
type UpdateConfig struct {
|
||||
servers int32
|
||||
agents int32
|
||||
labels []string
|
||||
annotations []string
|
||||
version string
|
||||
noConfirm bool
|
||||
}
|
||||
|
||||
func NewClusterUpdateCmd(appCtx *AppContext) *cobra.Command {
|
||||
updateConfig := &UpdateConfig{}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "update",
|
||||
Short: "Update existing cluster",
|
||||
Example: "k3kcli cluster update [command options] NAME",
|
||||
RunE: updateAction(appCtx, updateConfig),
|
||||
Args: cobra.ExactArgs(1),
|
||||
}
|
||||
|
||||
CobraFlagNamespace(appCtx, cmd.Flags())
|
||||
updateFlags(cmd, updateConfig)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func updateFlags(cmd *cobra.Command, cfg *UpdateConfig) {
|
||||
cmd.Flags().Int32Var(&cfg.servers, "servers", 1, "number of servers")
|
||||
cmd.Flags().Int32Var(&cfg.agents, "agents", 0, "number of agents")
|
||||
cmd.Flags().StringArrayVar(&cfg.labels, "labels", []string{}, "Labels to add to the cluster object (e.g. key=value)")
|
||||
cmd.Flags().StringArrayVar(&cfg.annotations, "annotations", []string{}, "Annotations to add to the cluster object (e.g. key=value)")
|
||||
cmd.Flags().StringVar(&cfg.version, "version", "", "k3s version")
|
||||
cmd.Flags().BoolVarP(&cfg.noConfirm, "no-confirm", "y", false, "Skip interactive approval before applying update")
|
||||
}
|
||||
|
||||
func updateAction(appCtx *AppContext, config *UpdateConfig) func(cmd *cobra.Command, args []string) error {
|
||||
return func(cmd *cobra.Command, args []string) error {
|
||||
ctx := cmd.Context()
|
||||
|
||||
client := appCtx.Client
|
||||
name := args[0]
|
||||
|
||||
if name == k3kcluster.ClusterInvalidName {
|
||||
return errors.New("invalid cluster name")
|
||||
}
|
||||
|
||||
namespace := appCtx.Namespace(name)
|
||||
|
||||
var virtualCluster v1beta1.Cluster
|
||||
|
||||
clusterKey := types.NamespacedName{Name: name, Namespace: appCtx.namespace}
|
||||
if err := appCtx.Client.Get(ctx, clusterKey, &virtualCluster); err != nil {
|
||||
if apierrors.IsNotFound(err) {
|
||||
return fmt.Errorf("cluster %s not found in namespace %s", name, appCtx.namespace)
|
||||
}
|
||||
|
||||
return fmt.Errorf("failed to fetch cluster: %w", err)
|
||||
}
|
||||
|
||||
var changes []change
|
||||
|
||||
if cmd.Flags().Changed("version") && config.version != virtualCluster.Spec.Version {
|
||||
currentVersion := virtualCluster.Spec.Version
|
||||
if currentVersion == "" {
|
||||
currentVersion = virtualCluster.Status.HostVersion
|
||||
}
|
||||
|
||||
currentVersionSemver, err := semver.ParseTolerant(currentVersion)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to parse current cluster version %w", err)
|
||||
}
|
||||
|
||||
newVersionSemver, err := semver.ParseTolerant(config.version)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to parse new cluster version %w", err)
|
||||
}
|
||||
|
||||
if newVersionSemver.LT(currentVersionSemver) {
|
||||
return fmt.Errorf("downgrading cluster version is not supported")
|
||||
}
|
||||
|
||||
changes = append(changes, change{"Version", currentVersion, config.version})
|
||||
virtualCluster.Spec.Version = config.version
|
||||
}
|
||||
|
||||
if cmd.Flags().Changed("servers") {
|
||||
var oldServers int32
|
||||
if virtualCluster.Spec.Agents != nil {
|
||||
oldServers = *virtualCluster.Spec.Servers
|
||||
}
|
||||
|
||||
if oldServers != config.servers {
|
||||
changes = append(changes, change{"Servers", fmt.Sprintf("%d", oldServers), fmt.Sprintf("%d", config.servers)})
|
||||
virtualCluster.Spec.Servers = ptr.To(config.servers)
|
||||
}
|
||||
}
|
||||
|
||||
if cmd.Flags().Changed("agents") {
|
||||
var oldAgents int32
|
||||
if virtualCluster.Spec.Agents != nil {
|
||||
oldAgents = *virtualCluster.Spec.Agents
|
||||
}
|
||||
|
||||
if oldAgents != config.agents {
|
||||
changes = append(changes, change{"Agents", fmt.Sprintf("%d", oldAgents), fmt.Sprintf("%d", config.agents)})
|
||||
virtualCluster.Spec.Agents = ptr.To(config.agents)
|
||||
}
|
||||
}
|
||||
|
||||
var labelChanges []change
|
||||
|
||||
if cmd.Flags().Changed("labels") {
|
||||
oldLabels := labels.Merge(nil, virtualCluster.Labels)
|
||||
virtualCluster.Labels = labels.Merge(virtualCluster.Labels, parseKeyValuePairs(config.labels, "label"))
|
||||
labelChanges = diffMaps(oldLabels, virtualCluster.Labels)
|
||||
}
|
||||
|
||||
var annotationChanges []change
|
||||
|
||||
if cmd.Flags().Changed("annotations") {
|
||||
oldAnnotations := labels.Merge(nil, virtualCluster.Annotations)
|
||||
virtualCluster.Annotations = labels.Merge(virtualCluster.Annotations, parseKeyValuePairs(config.annotations, "annotation"))
|
||||
annotationChanges = diffMaps(oldAnnotations, virtualCluster.Annotations)
|
||||
}
|
||||
|
||||
if len(changes) == 0 && len(labelChanges) == 0 && len(annotationChanges) == 0 {
|
||||
logrus.Info("No changes detected, skipping update")
|
||||
return nil
|
||||
}
|
||||
|
||||
logrus.Infof("Updating cluster '%s' in namespace '%s'", name, namespace)
|
||||
|
||||
printDiff(changes)
|
||||
printMapDiff("Labels", labelChanges)
|
||||
printMapDiff("Annotations", annotationChanges)
|
||||
|
||||
if !config.noConfirm {
|
||||
if !confirmClusterUpdate(&virtualCluster) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
if err := client.Update(ctx, &virtualCluster); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logrus.Info("Cluster updated successfully")
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func confirmClusterUpdate(cluster *v1beta1.Cluster) bool {
|
||||
clusterDetails, err := getClusterDetails(cluster)
|
||||
if err != nil {
|
||||
logrus.Fatalf("unable to get cluster details: %v", err)
|
||||
}
|
||||
|
||||
fmt.Printf("\nNew %s\n", clusterDetails)
|
||||
|
||||
fmt.Printf("\nDo you want to update the cluster? [y/N]: ")
|
||||
|
||||
scanner := bufio.NewScanner(os.Stdin)
|
||||
|
||||
if !scanner.Scan() {
|
||||
if err := scanner.Err(); err != nil {
|
||||
logrus.Errorf("Error reading input: %v", err)
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
fmt.Printf("\n")
|
||||
|
||||
return strings.ToLower(strings.TrimSpace(scanner.Text())) == "y"
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package cmds
|
||||
|
||||
import "fmt"
|
||||
|
||||
type change struct {
|
||||
field string
|
||||
oldValue string
|
||||
newValue string
|
||||
}
|
||||
|
||||
func printDiff(changes []change) {
|
||||
for _, c := range changes {
|
||||
if c.oldValue == c.newValue {
|
||||
continue
|
||||
}
|
||||
|
||||
fmt.Printf("%s: %s -> %s\n", c.field, c.oldValue, c.newValue)
|
||||
}
|
||||
}
|
||||
|
||||
func printMapDiff(title string, changes []change) {
|
||||
if len(changes) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("%s:\n", title)
|
||||
|
||||
for _, c := range changes {
|
||||
switch c.oldValue {
|
||||
case "":
|
||||
fmt.Printf(" %s=%s (new)\n", c.field, c.newValue)
|
||||
default:
|
||||
fmt.Printf(" %s=%s -> %s=%s\n", c.field, c.oldValue, c.field, c.newValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func diffMaps(oldMap, newMap map[string]string) []change {
|
||||
var changes []change
|
||||
|
||||
// Check for new and changed keys
|
||||
for k, newVal := range newMap {
|
||||
if oldVal, exists := oldMap[k]; exists {
|
||||
if oldVal != newVal {
|
||||
changes = append(changes, change{k, oldVal, newVal})
|
||||
}
|
||||
} else {
|
||||
changes = append(changes, change{k, "", newVal})
|
||||
}
|
||||
}
|
||||
|
||||
return changes
|
||||
}
|
||||
@@ -133,6 +133,40 @@ k3kcli cluster list [command options]
|
||||
--kubeconfig string kubeconfig path ($HOME/.kube/config or $KUBECONFIG if set)
|
||||
----
|
||||
|
||||
== k3kcli cluster update
|
||||
|
||||
Update existing cluster
|
||||
|
||||
----
|
||||
k3kcli cluster update [flags]
|
||||
----
|
||||
|
||||
=== Examples
|
||||
|
||||
----
|
||||
k3kcli cluster update [command options] NAME
|
||||
----
|
||||
|
||||
=== Options
|
||||
|
||||
----
|
||||
--agents int32 number of agents
|
||||
--annotations stringArray Annotations to add to the cluster object (e.g. key=value)
|
||||
-h, --help help for update
|
||||
--labels stringArray Labels to add to the cluster object (e.g. key=value)
|
||||
-n, --namespace string namespace of the k3k cluster
|
||||
-y, --no-confirm Skip interactive approval before applying update
|
||||
--servers int32 number of servers (default 1)
|
||||
--version string k3s version
|
||||
----
|
||||
|
||||
=== Options inherited from parent commands
|
||||
|
||||
----
|
||||
--debug Turn on debug logs
|
||||
--kubeconfig string kubeconfig path ($HOME/.kube/config or $KUBECONFIG if set)
|
||||
----
|
||||
|
||||
== k3kcli kubeconfig
|
||||
|
||||
Manage kubeconfig for clusters.
|
||||
|
||||
@@ -21,4 +21,5 @@ K3k cluster command.
|
||||
* [k3kcli cluster create](k3kcli_cluster_create.md) - Create a new cluster.
|
||||
* [k3kcli cluster delete](k3kcli_cluster_delete.md) - Delete an existing cluster.
|
||||
* [k3kcli cluster list](k3kcli_cluster_list.md) - List all existing clusters.
|
||||
* [k3kcli cluster update](k3kcli_cluster_update.md) - Update existing cluster
|
||||
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
## k3kcli cluster update
|
||||
|
||||
Update existing cluster
|
||||
|
||||
```
|
||||
k3kcli cluster update [flags]
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
```
|
||||
k3kcli cluster update [command options] NAME
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
--agents int32 number of agents
|
||||
--annotations stringArray Annotations to add to the cluster object (e.g. key=value)
|
||||
-h, --help help for update
|
||||
--labels stringArray Labels to add to the cluster object (e.g. key=value)
|
||||
-n, --namespace string namespace of the k3k cluster
|
||||
-y, --no-confirm Skip interactive approval before applying update
|
||||
--servers int32 number of servers (default 1)
|
||||
--version string k3s version
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--debug Turn on debug logs
|
||||
--kubeconfig string kubeconfig path ($HOME/.kube/config or $KUBECONFIG if set)
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [k3kcli cluster](k3kcli_cluster.md) - K3k cluster command.
|
||||
|
||||
@@ -11,6 +11,7 @@ replace (
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/blang/semver/v4 v4.0.0
|
||||
github.com/go-logr/logr v1.4.2
|
||||
github.com/go-logr/zapr v1.3.0
|
||||
github.com/google/go-cmp v0.7.0
|
||||
@@ -60,7 +61,6 @@ require (
|
||||
github.com/antlr4-go/antlr/v4 v4.13.0 // indirect
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/blang/semver/v4 v4.0.0 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/chai2010/gettext-go v1.0.2 // indirect
|
||||
|
||||
@@ -18,6 +18,7 @@ SUBCOMMAND_FILES=(
|
||||
"$DOCS_DIR/k3kcli_cluster_create.md"
|
||||
"$DOCS_DIR/k3kcli_cluster_delete.md"
|
||||
"$DOCS_DIR/k3kcli_cluster_list.md"
|
||||
"$DOCS_DIR/k3kcli_cluster_update.md"
|
||||
"$DOCS_DIR/k3kcli_kubeconfig.md"
|
||||
"$DOCS_DIR/k3kcli_kubeconfig_generate.md"
|
||||
"$DOCS_DIR/k3kcli_policy.md"
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
|
||||
"github.com/rancher/k3k/pkg/apis/k3k.io/v1beta1"
|
||||
"github.com/rancher/k3k/pkg/controller/policy"
|
||||
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
@@ -201,6 +202,183 @@ var _ = When("using the k3kcli", Label("cli"), func() {
|
||||
})
|
||||
})
|
||||
|
||||
When("trying the cluster update commands", func() {
|
||||
It("can update a cluster's server count", func() {
|
||||
var (
|
||||
stderr string
|
||||
err error
|
||||
)
|
||||
|
||||
clusterName := "cluster-" + rand.String(5)
|
||||
|
||||
namespace := NewNamespace()
|
||||
clusterNamespace := namespace.Name
|
||||
|
||||
DeferCleanup(func() {
|
||||
DeleteNamespaces(clusterNamespace)
|
||||
})
|
||||
|
||||
// Create the cluster first
|
||||
_, stderr, err = K3kcli("cluster", "create", "--namespace", clusterNamespace, clusterName)
|
||||
Expect(err).To(Not(HaveOccurred()), string(stderr))
|
||||
Expect(stderr).To(ContainSubstring("You can start using the cluster"))
|
||||
|
||||
// Update the cluster server count
|
||||
_, stderr, err = K3kcli("cluster", "update", "-y", "--servers", "2", "--namespace", clusterNamespace, clusterName)
|
||||
Expect(err).To(Not(HaveOccurred()), string(stderr))
|
||||
Expect(stderr).To(ContainSubstring("Updating cluster"))
|
||||
|
||||
// Verify the cluster state was actually updated
|
||||
var cluster v1beta1.Cluster
|
||||
err = k8sClient.Get(context.Background(), types.NamespacedName{Name: clusterName, Namespace: clusterNamespace}, &cluster)
|
||||
Expect(err).To(Not(HaveOccurred()))
|
||||
Expect(cluster.Spec.Servers).To(Not(BeNil()))
|
||||
Expect(*cluster.Spec.Servers).To(Equal(int32(2)))
|
||||
})
|
||||
|
||||
It("can update a cluster's version", func() {
|
||||
var (
|
||||
stderr string
|
||||
err error
|
||||
)
|
||||
|
||||
clusterName := "cluster-" + rand.String(5)
|
||||
|
||||
namespace := NewNamespace()
|
||||
clusterNamespace := namespace.Name
|
||||
|
||||
DeferCleanup(func() {
|
||||
DeleteNamespaces(clusterNamespace)
|
||||
})
|
||||
|
||||
// Create the cluster with initial version
|
||||
_, stderr, err = K3kcli("cluster", "create", "--version", "v1.31.13-k3s1", "--namespace", clusterNamespace, clusterName)
|
||||
Expect(err).To(Not(HaveOccurred()), string(stderr))
|
||||
Expect(stderr).To(ContainSubstring("You can start using the cluster"))
|
||||
|
||||
// Update the cluster version
|
||||
_, stderr, err = K3kcli("cluster", "update", "-y", "--version", "v1.32.8-k3s1", "--namespace", clusterNamespace, clusterName)
|
||||
Expect(err).To(Not(HaveOccurred()), string(stderr))
|
||||
Expect(stderr).To(ContainSubstring("Updating cluster"))
|
||||
|
||||
// Verify the cluster state was actually updated
|
||||
var cluster v1beta1.Cluster
|
||||
err = k8sClient.Get(context.Background(), types.NamespacedName{Name: clusterName, Namespace: clusterNamespace}, &cluster)
|
||||
Expect(err).To(Not(HaveOccurred()))
|
||||
Expect(cluster.Spec.Version).To(Equal("v1.32.8-k3s1"))
|
||||
})
|
||||
|
||||
It("fails to downgrade cluster version", func() {
|
||||
var (
|
||||
stderr string
|
||||
err error
|
||||
)
|
||||
|
||||
clusterName := "cluster-" + rand.String(5)
|
||||
|
||||
namespace := NewNamespace()
|
||||
clusterNamespace := namespace.Name
|
||||
|
||||
DeferCleanup(func() {
|
||||
DeleteNamespaces(clusterNamespace)
|
||||
})
|
||||
|
||||
// Create the cluster with a version
|
||||
_, stderr, err = K3kcli("cluster", "create", "--version", "v1.32.8-k3s1", "--namespace", clusterNamespace, clusterName)
|
||||
Expect(err).To(Not(HaveOccurred()), string(stderr))
|
||||
Expect(stderr).To(ContainSubstring("You can start using the cluster"))
|
||||
|
||||
// Attempt to downgrade should fail
|
||||
_, stderr, err = K3kcli("cluster", "update", "-y", "--version", "v1.31.13-k3s1", "--namespace", clusterNamespace, clusterName)
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(stderr).To(ContainSubstring("downgrading cluster version is not supported"))
|
||||
|
||||
// Verify the cluster version was NOT changed
|
||||
var cluster v1beta1.Cluster
|
||||
err = k8sClient.Get(context.Background(), types.NamespacedName{Name: clusterName, Namespace: clusterNamespace}, &cluster)
|
||||
Expect(err).To(Not(HaveOccurred()))
|
||||
Expect(cluster.Spec.Version).To(Equal("v1.32.8-k3s1"))
|
||||
})
|
||||
|
||||
It("fails to update a non-existent cluster", func() {
|
||||
var (
|
||||
stderr string
|
||||
err error
|
||||
)
|
||||
|
||||
// Attempt to update a cluster that doesn't exist
|
||||
_, stderr, err = K3kcli("cluster", "update", "-y", "--servers", "2", "non-existent-cluster")
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(stderr).To(ContainSubstring("failed to fetch cluster"))
|
||||
})
|
||||
|
||||
It("can update a cluster's labels", func() {
|
||||
var (
|
||||
stderr string
|
||||
err error
|
||||
)
|
||||
|
||||
clusterName := "cluster-" + rand.String(5)
|
||||
|
||||
namespace := NewNamespace()
|
||||
clusterNamespace := namespace.Name
|
||||
|
||||
DeferCleanup(func() {
|
||||
DeleteNamespaces(clusterNamespace)
|
||||
})
|
||||
|
||||
// Create the cluster first
|
||||
_, stderr, err = K3kcli("cluster", "create", "--namespace", clusterNamespace, clusterName)
|
||||
Expect(err).To(Not(HaveOccurred()), string(stderr))
|
||||
Expect(stderr).To(ContainSubstring("You can start using the cluster"))
|
||||
|
||||
// Update the cluster with labels
|
||||
_, stderr, err = K3kcli("cluster", "update", "-y", "--labels", "env=test", "--labels", "team=dev", "--namespace", clusterNamespace, clusterName)
|
||||
Expect(err).To(Not(HaveOccurred()), string(stderr))
|
||||
Expect(stderr).To(ContainSubstring("Updating cluster"))
|
||||
|
||||
// Verify the cluster labels were actually updated
|
||||
var cluster v1beta1.Cluster
|
||||
err = k8sClient.Get(context.Background(), types.NamespacedName{Name: clusterName, Namespace: clusterNamespace}, &cluster)
|
||||
Expect(err).To(Not(HaveOccurred()))
|
||||
Expect(cluster.Labels).To(HaveKeyWithValue("env", "test"))
|
||||
Expect(cluster.Labels).To(HaveKeyWithValue("team", "dev"))
|
||||
})
|
||||
|
||||
It("can update a cluster's annotations", func() {
|
||||
var (
|
||||
stderr string
|
||||
err error
|
||||
)
|
||||
|
||||
clusterName := "cluster-" + rand.String(5)
|
||||
|
||||
namespace := NewNamespace()
|
||||
clusterNamespace := namespace.Name
|
||||
|
||||
DeferCleanup(func() {
|
||||
DeleteNamespaces(clusterNamespace)
|
||||
})
|
||||
|
||||
// Create the cluster first
|
||||
_, stderr, err = K3kcli("cluster", "create", "--namespace", clusterNamespace, clusterName)
|
||||
Expect(err).To(Not(HaveOccurred()), string(stderr))
|
||||
Expect(stderr).To(ContainSubstring("You can start using the cluster"))
|
||||
|
||||
// Update the cluster with annotations
|
||||
_, stderr, err = K3kcli("cluster", "update", "-y", "--annotations", "description=test-cluster", "--annotations", "owner=qa-team", "--namespace", clusterNamespace, clusterName)
|
||||
Expect(err).To(Not(HaveOccurred()), string(stderr))
|
||||
Expect(stderr).To(ContainSubstring("Updating cluster"))
|
||||
|
||||
// Verify the cluster annotations were actually updated
|
||||
var cluster v1beta1.Cluster
|
||||
err = k8sClient.Get(context.Background(), types.NamespacedName{Name: clusterName, Namespace: clusterNamespace}, &cluster)
|
||||
Expect(err).To(Not(HaveOccurred()))
|
||||
Expect(cluster.Annotations).To(HaveKeyWithValue("description", "test-cluster"))
|
||||
Expect(cluster.Annotations).To(HaveKeyWithValue("owner", "qa-team"))
|
||||
})
|
||||
})
|
||||
|
||||
When("trying the kubeconfig command", func() {
|
||||
It("can generate a kubeconfig", func() {
|
||||
var (
|
||||
|
||||
Reference in New Issue
Block a user