Skip to content

Commit

Permalink
feat(Template): Added the kubernetes cmd
Browse files Browse the repository at this point in the history
- Added the possibility the you can list, create, update and delete a kubernetes cluster
- Change the spinner presentation
- Update civogo lib to 0.2.7

BREAKING CHANGE: No

Signed-off-by: Alejandro JNM <alejandrojnm@gmail.com>
  • Loading branch information
alejandrojnm committed May 11, 2020
1 parent 59a4231 commit 0370dde
Show file tree
Hide file tree
Showing 22 changed files with 892 additions and 6 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ Golang has no shortage of external libraries for various parts of this, but the
-~~Networks~~
-~~Snapshots~~
-~~Volumes~~
- Templates
- ~~Templates~~
- Kubernetes Clusters
- Kubernetes Applications

Expand Down
2 changes: 1 addition & 1 deletion cmd/instance_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ Example: civo instance create --hostname=foo.example.com`,

stillCreating := true
s := spinner.New(spinner.CharSets[9], 100*time.Millisecond)
s.Suffix = " Creating instance..."
s.Prefix = "Creating instance... "
s.Start()

for stillCreating {
Expand Down
2 changes: 1 addition & 1 deletion cmd/instance_stop.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ Example: civo instance stop ID/NAME`,

stillStopping := true
s := spinner.New(spinner.CharSets[9], 100*time.Millisecond)
s.Suffix = " Stopping instance..."
s.Prefix = "Stopping instance... "
s.Start()

for stillStopping {
Expand Down
73 changes: 73 additions & 0 deletions cmd/kubernetes.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,79 @@ package cmd
// kubernetes upgrade ID/NAME [--version] -- upgrade Kubernetes cluster's k3s version
// kubernetes scale ID/NAME [--nodes] -- rescale the Kubernetes cluster to a new node count [rescale]
// kubernetes remove ID/NAME -- removes an entire Kubernetes cluster with ID/name entered (use with caution!) [delete, destroy, rm]

// kubernetes_applications list -- list all available kubernetes applications [ls, all]
// kubernetes_applications show NAME -- show a Kubernetes application by name [get, inspect]
// kubernetes_applications add NAME --cluster=... -- add the marketplace application to a Kubernetes cluster by ID or name

import (
"fmt"
"github.com/spf13/cobra"
"os"
)

var kubernetesCmd = &cobra.Command{
Use: "kubernetes",
Aliases: []string{"kubernetes", "kube"},
Short: "Details of Civo kubernetes",
}

var kubernetesApplicationsCmd = &cobra.Command{
Use: "applications",
Aliases: []string{"application", "app"},
Short: "Details of Civo kubernetes applications",
}

func init() {
rootCmd.AddCommand(kubernetesCmd)
kubernetesCmd.AddCommand(kubernetesListCmd)
kubernetesCmd.AddCommand(kubernetesListVersionCmd)
kubernetesCmd.AddCommand(kubernetesShowCmd)
kubernetesCmd.AddCommand(kubernetesConfigCmd)
kubernetesCmd.AddCommand(kubernetesCreateCmd)
kubernetesCmd.AddCommand(kubernetesRenameCmd)
kubernetesCmd.AddCommand(kubernetesUpgradeCmd) // TODO: Check this with @andy
kubernetesCmd.AddCommand(kubernetesScaleCmd)
kubernetesCmd.AddCommand(kubernetesRemoveCmd)

/*
Flags for kubernetes config
*/
home, _ := os.UserHomeDir()
kubernetesConfigCmd.Flags().BoolVarP(&saveConfig, "save", "s", false, "save the config")
kubernetesConfigCmd.Flags().BoolVarP(&mergeConfig, "merge", "m", false, "merge the config with existing kubeconfig if it already exists.")
kubernetesConfigCmd.Flags().StringVarP(&localPathConfig, "local-path", "p", fmt.Sprintf("%s/.kube/config", home), "local path to save the kubeconfig file")

/*
Flags for kubernetes create
*/
kubernetesCreateCmd.Flags().StringVarP(&TargetNodesSize, "size", "s", "g2.medium", "the size of nodes to create.")
kubernetesCreateCmd.Flags().IntVarP(&NumTargetNodes, "nodes", "n", 3, "the number of nodes to create (the master also acts as a node).")
kubernetesCreateCmd.Flags().StringVarP(&KubernetesVersion, "version", "v", "latest", "the k3s version to use on the cluster. Defaults to the latest.")
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")

/*
Flags for kubernetes rename
*/
kubernetesRenameCmd.Flags().StringVarP(&KubernetesNewName, "name", "n", "", "the new name for the cluster.")

/*
Flags for kubernetes upgrade
*/
kubernetesUpgradeCmd.Flags().StringVarP(&KubernetesNewVersion, "version", "v", "", "change the version of the cluster.")
/*
Flags for kubernetes scale
*/
kubernetesScaleCmd.Flags().IntVarP(&KubernetesNewNodes, "nodes", "n", 3, "change the total nodes of the cluster.")
kubernetesScaleCmd.Flags().BoolVarP(&waitKubernetesNodes, "wait", "w", false, "a simple flag (e.g. --wait) that will cause the CLI to spin and wait for the cluster to be ACTIVE")

/*
Kube application
*/
kubernetesCmd.AddCommand(kubernetesApplicationsCmd)
kubernetesApplicationsCmd.AddCommand(kubernetesAppListCmd)
// TODO: show command
kubernetesApplicationsCmd.AddCommand(kubernetesAppAddCmd)
kubernetesAppAddCmd.Flags().StringVarP(&KubernetesClusterApp, "cluster", "c", "", "the name of the cluster to install the app.")

}
53 changes: 53 additions & 0 deletions cmd/kubernetes_app_add.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package cmd

import (
"fmt"
"github.com/civo/civogo"
"github.com/civo/cli/config"
"github.com/civo/cli/utility"
"github.com/logrusorgru/aurora"
"github.com/spf13/cobra"
"os"
)

var KubernetesClusterApp string

var kubernetesAppAddCmd = &cobra.Command{
Use: "add",
Aliases: []string{"install"},
Short: "Add the marketplace application to a Kubernetes cluster",
Run: func(cmd *cobra.Command, args []string) {
client, err := config.CivoAPIClient()
if err != nil {
fmt.Printf("Unable to create a Civo API Client: %s\n", aurora.Red(err))
os.Exit(1)
}

kubernetesFindCluster, err := client.FindKubernetesCluster(KubernetesClusterApp)
if err != nil {
fmt.Printf("Unable to find a kubernetes cluster: %s\n", aurora.Red(err))
os.Exit(1)
}

configKubernetes := &civogo.KubernetesClusterConfig{
Applications: args[0],
}

kubeCluster, err := client.UpdateKubernetesCluster(kubernetesFindCluster.ID, configKubernetes)
if err != nil {
fmt.Printf("Unable to install the application in the kubernetes cluster: %s\n", aurora.Red(err))
os.Exit(1)
}

ow := utility.NewOutputWriterWithMap(map[string]string{"ID": kubeCluster.ID, "Name": kubeCluster.Name})

switch outputFormat {
case "json":
ow.WriteSingleObjectJSON()
case "custom":
ow.WriteCustomOutput(outputFields)
default:
fmt.Printf("The application was install in the kubernetes cluster %s\n", aurora.Green(kubeCluster.Name))
}
},
}
66 changes: 66 additions & 0 deletions cmd/kubernetes_app_list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package cmd

import (
"fmt"
"github.com/civo/cli/config"
"github.com/civo/cli/utility"
"github.com/logrusorgru/aurora"
"github.com/spf13/cobra"
"os"
"strings"
)

var kubernetesAppListCmd = &cobra.Command{
Use: "ls",
Aliases: []string{"list", "all"},
Short: "List all kubernetes clusters applications",
Long: `List all kubernetes clusters applications.
If you wish to use a custom format, the available fields are:
* Name
* Version
* Category
* Plans
* Dependencies
Example: civo kubernetes applications ls -o custom -f "Name: Version"`,
Run: func(cmd *cobra.Command, args []string) {
client, err := config.CivoAPIClient()
if err != nil {
fmt.Printf("Unable to create a Civo API Client: %s\n", aurora.Red(err))
os.Exit(1)
}

kubeApps, err := client.ListKubernetesMarketplaceApplications()
if err != nil {
fmt.Printf("Unable to list kubernetes cluster application: %s\n", aurora.Red(err))
os.Exit(1)
}

ow := utility.NewOutputWriter()
for _, kubeApp := range kubeApps {
ow.StartLine()

// All plans
var plansApps []string
for _, plan := range kubeApp.Plans {
plansApps = append(plansApps, plan.Label)
}

ow.AppendData("Name", kubeApp.Name)
ow.AppendData("Version", kubeApp.Version)
ow.AppendData("Category", kubeApp.Category)
ow.AppendData("Plans", strings.Join(plansApps, ", "))
ow.AppendData("Dependencies", strings.Join(kubeApp.Dependencies, ", "))
}

switch outputFormat {
case "json":
ow.WriteMultipleObjectsJSON()
case "custom":
ow.WriteCustomOutput(outputFields)
default:
ow.WriteTable()
}
},
}
57 changes: 57 additions & 0 deletions cmd/kubernetes_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package cmd

import (
_ "errors"
"fmt"
"github.com/civo/cli/config"
"github.com/civo/cli/utility"
_ "github.com/civo/cli/utility"
"github.com/logrusorgru/aurora"
"github.com/spf13/cobra"
"os"
_ "strconv"
)

var saveConfig, mergeConfig bool
var localPathConfig string

var kubernetesConfigCmd = &cobra.Command{
Use: "config",
Aliases: []string{"conf"},
Args: cobra.MinimumNArgs(1),
Short: "Get kubernetes clusters config",
Long: `Show current kubernetes config.
If you wish to use a custom format, the available fields are:
* KubeConfig
Example: civo kubernetes config -o custom -f "KubeConfig"`,
Run: func(cmd *cobra.Command, args []string) {
client, err := config.CivoAPIClient()
if err != nil {
fmt.Printf("Unable to create a Civo API Client: %s\n", aurora.Red(err))
os.Exit(1)
}

kube, err := client.FindKubernetesCluster(args[0])
if err != nil {
fmt.Printf("Unable to get kubernetes cluster: %s\n", aurora.Red(err))
os.Exit(1)
}

if saveConfig {
_ = utility.ObtainKubeConfig(localPathConfig, kube.KubeConfig, mergeConfig)
}

ow := utility.NewOutputWriterWithMap(map[string]string{"KubeConfig": kube.KubeConfig})

switch outputFormat {
case "json":
ow.WriteSingleObjectJSON()
case "custom":
ow.WriteCustomOutput(outputFields)
default:
fmt.Println("The configuration was save")
}
},
}
88 changes: 88 additions & 0 deletions cmd/kubernetes_create.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package cmd

import (
"fmt"
"github.com/briandowns/spinner"
"github.com/civo/civogo"
"github.com/civo/cli/config"
"github.com/civo/cli/utility"
"github.com/logrusorgru/aurora"
"github.com/spf13/cobra"
"os"
_ "strconv"
"time"
)

var NumTargetNodes int
var waitKubernetes bool
var (
KubernetesVersion string
TargetNodesSize string
)

var kubernetesCreateCmd = &cobra.Command{
Use: "create",
Aliases: []string{"new", "add"},
Short: "Create a new kubernetes cluster",
Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
client, err := config.CivoAPIClient()
if err != nil {
fmt.Printf("Unable to create a Civo API Client: %s\n", aurora.Red(err))
os.Exit(1)
}

isValidName := false

_, err = client.FindKubernetesCluster(args[0])
if err != nil {
isValidName = true
}

if !isValidName {
fmt.Printf("The %s is nos valida name for the cluster\n", aurora.Red(args[0]))
os.Exit(1)
}

configKubernetes := &civogo.KubernetesClusterConfig{
Name: args[0],
NumTargetNodes: NumTargetNodes,
TargetNodesSize: TargetNodesSize,
KubernetesVersion: KubernetesVersion,
}

kubernetesCluster, err := client.NewKubernetesClusters(configKubernetes)
if err != nil {
fmt.Printf("Unable to create a kubernetes cluster: %s\n", aurora.Red(err))
os.Exit(1)
}

if waitKubernetes == true {

stillCreating := true
s := spinner.New(spinner.CharSets[9], 100*time.Millisecond)
s.Prefix = "Creating kubernetes cluster... "
s.Start()

for stillCreating {
kubernetesCheck, _ := client.FindKubernetesCluster(kubernetesCluster.ID)
if kubernetesCheck.Status == "ACTIVE" {
stillCreating = false
s.Stop()
}
time.Sleep(5 * time.Second)
}
}

ow := utility.NewOutputWriterWithMap(map[string]string{"ID": kubernetesCluster.ID, "Name": kubernetesCluster.Name})

switch outputFormat {
case "json":
ow.WriteSingleObjectJSON()
case "custom":
ow.WriteCustomOutput(outputFields)
default:
fmt.Printf("Created a new kubernetes cluster with Name %s with ID %s\n", aurora.Green(kubernetesCluster.Name), aurora.Green(kubernetesCluster.ID))
}
},
}
Loading

0 comments on commit 0370dde

Please sign in to comment.