Skip to content

Commit

Permalink
Remove --merge, --switch from kubernetes create command, Add remove c…
Browse files Browse the repository at this point in the history
…ontext flag in kubernetes remove command
  • Loading branch information
kanha-gupta committed Feb 8, 2025
1 parent adc6bb1 commit 31d0946
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 70 deletions.
4 changes: 2 additions & 2 deletions cmd/kubernetes/kubernetes.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,6 @@ func init() {
kubernetesCreateCmd.Flags().StringVarP(&removeapplications, "remove-applications", "r", "", "optional, remove default application names shown by running 'civo kubernetes applications ls'")
kubernetesCreateCmd.Flags().BoolVarP(&waitKubernetes, "wait", "w", false, "a simple flag (e.g. --wait) that will cause the CLI to spin and wait for the cluster to be ACTIVE")
kubernetesCreateCmd.Flags().BoolVarP(&saveConfigKubernetes, "save", "", false, "save the config")
kubernetesCreateCmd.Flags().BoolVarP(&mergeConfigKubernetes, "merge", "m", false, "merge the config with existing kubeconfig if it already exists.")
kubernetesCreateCmd.Flags().BoolVarP(&switchConfigKubernetes, "switch", "", false, "switch context to newly-created cluster")
kubernetesCreateCmd.Flags().StringVarP(&existingFirewall, "existing-firewall", "e", "", "optional, ID of existing firewall to use")
kubernetesCreateCmd.Flags().StringVarP(&rulesFirewall, "firewall-rules", "u", "default", "optional, can be used if the --create-firewall flag is set, semicolon-separated list of ports to open")
kubernetesCreateCmd.Flags().BoolVarP(&createFirewall, "create-firewall", "c", false, "optional, create a firewall for the cluster with all open ports")
Expand Down Expand Up @@ -147,6 +145,8 @@ func init() {
KubernetesCmd.AddCommand(kubernetesUpdateCmd)
kubernetesUpdateCmd.Flags().StringVarP(&firewall, "firewall", "", "", "the Name or ID of the firewall.")
kubernetesUpdateCmd.MarkFlagRequired("firewall") // At present, only the firewall can be updated, this can be changed to not required if more options are added in the future.

kubernetesRemoveCmd.Flags().BoolVarP(&removeKubernetesConfig, "remove", "r", false, "remove the cluster configuration from kubeconfig if found")
}

func getKubernetesList(value string) []string {
Expand Down
107 changes: 39 additions & 68 deletions cmd/kubernetes/kubernetes_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import (

var numTargetNodes int
var rulesFirewall string
var waitKubernetes, saveConfigKubernetes, mergeConfigKubernetes, switchConfigKubernetes, createFirewall bool
var waitKubernetes, saveConfigKubernetes, createFirewall bool
var kubernetesVersion, targetNodesSize, clusterName, clusterType, applications, removeapplications, networkID, existingFirewall, cniPlugin string
var kubernetesCluster *civogo.KubernetesCluster

Expand Down Expand Up @@ -79,22 +79,6 @@ var kubernetesCreateCmd = &cobra.Command{
os.Exit(1)
}

if !waitKubernetes {
if saveConfigKubernetes || switchConfigKubernetes || mergeConfigKubernetes {
utility.Error("you can't use --save, --switch or --merge without --wait")
os.Exit(1)
}
} else {
if mergeConfigKubernetes && !saveConfigKubernetes {
utility.Error("you can't use --merge without --save")
os.Exit(1)
}
if switchConfigKubernetes && !saveConfigKubernetes {
utility.Error("you can't use --switch without --save")
os.Exit(1)
}
}

if len(args) > 0 {
if utility.ValidNameLength(args[0]) {
utility.Warning("the cluster name cannot be longer than 63 characters")
Expand Down Expand Up @@ -191,69 +175,29 @@ var kubernetesCreateCmd = &cobra.Command{
configKubernetes.FirewallRule = ""
}

if !mergeConfigKubernetes && saveConfigKubernetes {
if utility.UserConfirmedOverwrite("kubernetes config", common.DefaultYes) {
kubernetesCluster, err = client.NewKubernetesClusters(configKubernetes)
if err != nil {
if err == civogo.QuotaLimitReachedError {
utility.Info("Please consider deleting dangling volumes, if any. To check if you have any dangling volumes, run `civo volume ls --dangling`")
os.Exit(1)
}
utility.Error("%s", err)
os.Exit(1)
}
} else {
fmt.Println("Operation aborted.")
os.Exit(1)
}
} else {
kubernetesCluster, err = client.NewKubernetesClusters(configKubernetes)
if err != nil {
if err == civogo.QuotaLimitReachedError {
utility.Info("Please consider deleting dangling volumes, if any. To check if you have any dangling volumes, run `civo volume ls --dangling`")
os.Exit(1)
}
utility.Error("%s", err)
kubernetesCluster, err = client.NewKubernetesClusters(configKubernetes)
if err != nil {
if err == civogo.QuotaLimitReachedError {
utility.Info("Please consider deleting dangling volumes, if any. To check if you have any dangling volumes, run `civo volume ls --dangling`")
os.Exit(1)
}
utility.Error("%s", err)
os.Exit(1)
}

var executionTime string

if waitKubernetes {
startTime := utility.StartTime()

stillCreating := true
s := spinner.New(spinner.CharSets[9], 100*time.Millisecond)
s.Writer = os.Stderr
s.Prefix = fmt.Sprintf("Creating a %s node k3s cluster of %s instances called %s... ", strconv.Itoa(kubernetesCluster.NumTargetNode), kubernetesCluster.TargetNodeSize, kubernetesCluster.Name)
s.Start()

for stillCreating {
kubernetesCheck, err := client.FindKubernetesCluster(kubernetesCluster.ID)
if err != nil {
utility.Error("Kubernetes %s", err)
os.Exit(1)
}
if kubernetesCheck.Ready {
stillCreating = false
s.Stop()
} else {
time.Sleep(2 * time.Second)
}
}

executionTime = utility.TrackTime(startTime)
}

if saveConfigKubernetes {
if !saveConfigKubernetes && waitKubernetes {
executionTime = wait(client)
} else if saveConfigKubernetes {
executionTime = wait(client)
kube, err := client.FindKubernetesCluster(kubernetesCluster.ID)
if err != nil {
utility.Error("Kubernetes %s", err)
os.Exit(1)
}

err = utility.ObtainKubeConfig(localPathConfig, kube.KubeConfig, mergeConfigKubernetes, switchConfigKubernetes, kube.Name)
err = utility.ObtainKubeConfig(localPathConfig, kube.KubeConfig, true, true, kube.Name)
if err != nil {
utility.Error("Saving the cluster config failed with %s", err)
os.Exit(1)
Expand Down Expand Up @@ -303,3 +247,30 @@ func InstallApps(defaultApps []string, apps, removeApps string) []string {

return appsToInstall
}

func wait(client *civogo.Client) string {
startTime := utility.StartTime()

stillCreating := true
s := spinner.New(spinner.CharSets[9], 100*time.Millisecond)
s.Writer = os.Stderr
s.Prefix = fmt.Sprintf("Creating a %s node k3s cluster of %s instances called %s... ", strconv.Itoa(kubernetesCluster.NumTargetNode), kubernetesCluster.TargetNodeSize, kubernetesCluster.Name)
s.Start()

for stillCreating {
kubernetesCheck, err := client.FindKubernetesCluster(kubernetesCluster.ID)
if err != nil {
utility.Error("Kubernetes %s", err)
os.Exit(1)
}
if kubernetesCheck.Ready {
stillCreating = false
s.Stop()
} else {
time.Sleep(2 * time.Second)
}
}

executionTime := utility.TrackTime(startTime)
return executionTime
}
4 changes: 4 additions & 0 deletions cmd/kubernetes/kubernetes_remove.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
)

var kuberneteList []utility.ObjecteList
var removeKubernetesConfig bool
var kubernetesRemoveCmd = &cobra.Command{
Use: "remove",
Aliases: []string{"rm", "delete", "destroy"},
Expand Down Expand Up @@ -85,6 +86,9 @@ var kubernetesRemoveCmd = &cobra.Command{

for _, v := range kuberneteList {
_, err = client.DeleteKubernetesCluster(v.ID)
if removeKubernetesConfig {
utility.RemoveClusterConfig(v.Name)
}
if err != nil {
utility.Error("error deleting the kubernetes cluster: %s", err)
os.Exit(1)
Expand Down
70 changes: 70 additions & 0 deletions utility/kubernetes.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,76 @@ func mergeConfigs(localKubeconfigPath string, k3sconfig []byte, switchContext bo
return data, nil
}

// Removes kubeconfig context of particular cluster if found
func RemoveClusterConfig(clusterName string) error {
isWindows := CheckOS() == "windows"
var clustersList *exec.Cmd
if isWindows {
clustersList = exec.Command("powershell", "kubectl", "config", "get-clusters")
} else {
clustersList = exec.Command("kubectl", "config", "get-clusters")
}
output, err := clustersList.Output()
if err != nil {
return fmt.Errorf("failed to get clusters from kubeconfig: %v", err)
}

if !strings.Contains(string(output), clusterName) {
fmt.Printf("Cluster %s is already not present in kubeconfig, exiting...\n", clusterName)
return nil
}

var currentContextCmd *exec.Cmd
if isWindows {
currentContextCmd = exec.Command("powershell", "kubectl", "config", "current-context")
} else {
currentContextCmd = exec.Command("kubectl", "config", "current-context")
}
currentContextOutput, err := currentContextCmd.Output()
if err != nil {
fmt.Println("Error getting current context:", err)
} else {
currentContext := strings.TrimSpace(string(currentContextOutput))
if currentContext == clusterName {
fmt.Println("Current context is the same as the cluster being removed. Unsetting context.")
var cmd *exec.Cmd
if isWindows {
cmd = exec.Command("powershell", "kubectl", "config", "unset", "current-context")
} else {
cmd = exec.Command("kubectl", "config", "unset", "current-context")
}
if err := cmd.Run(); err != nil {
return fmt.Errorf("failed to unset current context %s: %v", clusterName, err)
}
}
}

var commands []*exec.Cmd

if isWindows {
commands = []*exec.Cmd{
exec.Command("powershell", "kubectl", "config", "delete-cluster", clusterName),
exec.Command("powershell", "kubectl", "config", "unset", fmt.Sprintf("users.%s", clusterName)),
exec.Command("powershell", "kubectl", "config", "unset", fmt.Sprintf("contexts.%s", clusterName)),
}
} else {
commands = []*exec.Cmd{
exec.Command("kubectl", "config", "delete-cluster", clusterName),
exec.Command("kubectl", "config", "unset", fmt.Sprintf("users.%s", clusterName)),
exec.Command("kubectl", "config", "unset", fmt.Sprintf("contexts.%s", clusterName)),
}
}

for _, cmd := range commands {
if err := cmd.Run(); err != nil {
return fmt.Errorf("failed to execute command %v: %v", cmd.Args, err)
}
}

fmt.Printf("Successfully removed cluster %s from kubeconfig\n", clusterName)
return nil
}

// Generates config files give the path to file: string and the data: []byte
func writeConfig(path string, data []byte, suppressMessage bool, mergeConfigs bool, switchConfig bool, clusterName string) error {
if !suppressMessage {
Expand Down

0 comments on commit 31d0946

Please sign in to comment.