Skip to content

Commit

Permalink
Kubernetes: add node labels options for node pools (#422)
Browse files Browse the repository at this point in the history
* Add node-labels flags for node pool create/update

* Add node-labels printer to kubernetes printers

* Update kubernetes help text

* Allow cluster creation to parse out node labels

* Add documentation for node pool on cluster create

* Ignore docs long line and gocyclo on formatting func
  • Loading branch information
optik-aper authored Mar 11, 2024
1 parent 3b9539e commit f566d86
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 21 deletions.
95 changes: 74 additions & 21 deletions cmd/kubernetes/kubernetes.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,33 @@ var (
vultr-cli kubernetes
`

createLong = `Create kubernetes cluster on your Vultr account`
createLong = `Create kubernetes cluster on your Vultr account`
//nolint:lll
createExample = `
# Full Example
vultr-cli kubernetes create --label="my-cluster" --region="ewr" --version="v1.29.1+1" \
# Full example
vultr-cli kubernetes create --label="my-cluster" --region="ewr" --version="v1.29.2+1" \
--node-pools="quantity:3,plan:vc2-2c-4gb,label:my-nodepool,tag:my-tag"
# Shortened with alias commands
vultr-cli k c -l="my-cluster" -r="ewr" -v="v1.29.1+1" -n="quantity:3,plan:vc2-2c-4gb,label:my-nodepool,tag:my-tag"
vultr-cli k c -l="my-cluster" -r="ewr" -v="v1.29.2+1" -n="quantity:3,plan:vc2-2c-4gb,label:my-nodepool,tag:my-tag"
# Node pool options
The --node-pools option allows you to pass in options for any number of
node pools when creating a cluster. The options are passed in a delimited
string. Different node pools are delimited by a slash (/). The options for
each node pool are delimited by a comma (,) and each option is defined by
colon (:). If provided, the node pool options can also parse out the
node-labels params which are delimited by a pipe (|).
Available options are documented in the 'kubernetes node-pool create --help'
For example:
Multiple node pools
--node-pools="quantity:1,plan:vc2-4c-8gb,label:main-node-pool/quantity:5,plan:vc2-2c-4gb,label:worker-pool,auto-scaler:true,min-nodes:5,max-nodes:10"
Using node labels
--node-pools="quantity:5,plan:vc2-2c-4gb,label:worker-pool,auto-scaler:true,min-nodes:5,max-nodes:10,node-labels:application=identity-service|worker-size=small"
`

getLong = `Get a single kubernetes cluster from your account`
Expand Down Expand Up @@ -61,7 +80,7 @@ var (
updateLong = `Update a specific kubernetes cluster on your Vultr Account`
updateExample = `
# Full example
vultr-cli kubernetes update ffd31f18-5f77-454c-9065-212f942c3c35 --label="updated-label"
vultr-cli kubernetes update ffd31f18-5f77-454c-9065-212f942c3c35 --label="updated-label"
# Shortened with alias commands
vultr-cli k u ffd31f18-5f77-454c-9065-212f942c3c35 -l="updated-label"
Expand All @@ -81,14 +100,14 @@ var (
getConfigLong = `Returns a base64 encoded config of a specified kubernetes cluster on your Vultr Account`
getConfigExample = `
# Full example
vultr-cli kubernetes config ffd31f18-5f77-454c-9065-212f942c3c35
vultr-cli kubernetes config ffd31f18-5f77-454c-9065-212f942c3c35 --output-file /your/path/
# Shortened with alias commands
vultr-cli k config ffd31f18-5f77-454c-9065-212f942c3c35
vultr-cli k config ffd31f18-5f77-454c-9065-212f942c3c35 -o /your/path/
`
# Full example
vultr-cli kubernetes config ffd31f18-5f77-454c-9065-212f942c3c35
vultr-cli kubernetes config ffd31f18-5f77-454c-9065-212f942c3c35 --output-file /your/path/
# Shortened with alias commands
vultr-cli k config ffd31f18-5f77-454c-9065-212f942c3c35
vultr-cli k config ffd31f18-5f77-454c-9065-212f942c3c35 -o /your/path/
`

getVersionsLong = `Returns a list of supported kubernetes versions you can deploy`
getVersionsExample = `
Expand Down Expand Up @@ -120,10 +139,10 @@ var (
upgradeLong = `Initiate an upgrade of the kubernetes version on a given cluster`
upgradeExample = `
# Full example
vultr-cli kubernetes upgrades start d4908765-b82a-4e7d-83d9-c0bc4c6a36d0 --version="v1.23.5+3"
vultr-cli kubernetes upgrades start d4908765-b82a-4e7d-83d9-c0bc4c6a36d0 --version="v1.29.2+1"
# Shortened with alias commands
vultr-cli k e s d4908765-b82a-4e7d-83d9-c0bc4c6a36d0 -v="v1.23.5+3"
vultr-cli k e s d4908765-b82a-4e7d-83d9-c0bc4c6a36d0 -v="v1.29.2+1"
`

nodepoolLong = `Get all available commands for Kubernetes node pools`
Expand All @@ -138,7 +157,8 @@ var (
createNPLong = `Create node pool for your kubernetes cluster on your Vultr account`
createNPExample = `
# Full Example
vultr-cli kubernetes node-pool create ffd31f18-5f77-454c-9064-212f942c3c34 --label="nodepool" --quantity=3 --plan="vc2-1c-2gb"
vultr-cli kubernetes node-pool create ffd31f18-5f77-454c-9064-212f942c3c34 --label="nodepool" --quantity=3 \
--plan="vc2-1c-2gb" --node-labels="application=id-service,environment=development"
# Shortened with alias commands
vultr-cli k n c ffd31f18-5f77-454c-9064-212f942c3c34 -l="nodepool" -q=3 -p="vc2-1c-2gb"
Expand Down Expand Up @@ -167,7 +187,8 @@ var (
updateNPLong = `Update a specific node pool in a kubernetes cluster on your Vultr Account`
updateNPExample = `
# Full example
vultr-cli kubernetes node-pool update ffd31f18-5f77-454c-9064-212f942c3c34 abd31f18-3f77-454c-9064-212f942c3c34 --quantity=4
vultr-cli kubernetes node-pool update ffd31f18-5f77-454c-9064-212f942c3c34 abd31f18-3f77-454c-9064-212f942c3c34 --quantity=4 \
--node-labels="application=id-service,environment=development"
# Shortened with alias commands
vultr-cli k n u ffd31f18-5f77-454c-9065-212f942c3c35 abd31f18-3f77-454c-9064-212f942c3c34 --q=4
Expand Down Expand Up @@ -747,6 +768,11 @@ required in node pool. Use / between each new node pool. E.g:
return fmt.Errorf("error parsing flag 'max-nodes' for kubernetes cluster node pool create : %v", errMa)
}

npLabels, errNl := cmd.Flags().GetStringToString("node-labels")
if errNl != nil {
return fmt.Errorf("error parsing flag 'node-labels' for kubernetes cluster node pool create : %v", errNl)
}

o.npCreateReq = &govultr.NodePoolReq{
NodeQuantity: quantity,
Label: label,
Expand All @@ -755,6 +781,7 @@ required in node pool. Use / between each new node pool. E.g:
AutoScaler: govultr.BoolToBoolPtr(false),
MinNodes: minNodes,
MaxNodes: maxNodes,
Labels: npLabels,
}

if autoscaler {
Expand Down Expand Up @@ -796,6 +823,7 @@ required in node pool. Use / between each new node pool. E.g:
npCreate.Flags().BoolP("auto-scaler", "", false, "Enable the auto scaler with your cluster")
npCreate.Flags().IntP("min-nodes", "", 1, "Minimum nodes for auto scaler")
npCreate.Flags().IntP("max-nodes", "", 1, "Maximum nodes for auto scaler")
npCreate.Flags().StringToString("node-labels", nil, "A key=value comma separated string of labels to apply to the nodes in this node pool")

// Node Pool Update
npUpdate := &cobra.Command{
Expand Down Expand Up @@ -836,6 +864,11 @@ required in node pool. Use / between each new node pool. E.g:
return fmt.Errorf("error parsing flag 'max-nodes' for kubernetes cluster node pool update : %v", errMa)
}

npLabels, errNl := cmd.Flags().GetStringToString("node-labels")
if errNl != nil {
return fmt.Errorf("error parsing flag 'node-labels' for kubernetes cluster node pool update : %v", errNl)
}

o.npUpdateReq = &govultr.NodePoolReqUpdate{}

if cmd.Flags().Changed("quantity") {
Expand All @@ -858,6 +891,10 @@ required in node pool. Use / between each new node pool. E.g:
o.npUpdateReq.MaxNodes = maxNodes
}

if cmd.Flags().Changed("node-labels") {
o.npUpdateReq.Labels = npLabels
}

np, err := o.nodePoolUpdate()
if err != nil {
return fmt.Errorf("error updating kubernetes cluster node pool : %v", err)
Expand All @@ -880,8 +917,9 @@ required in node pool. Use / between each new node pool. E.g:
npUpdate.Flags().BoolP("auto-scaler", "", false, "Enable the auto scaler with your cluster")
npUpdate.Flags().IntP("min-nodes", "", 1, "Minimum nodes for auto scaler")
npUpdate.Flags().IntP("max-nodes", "", 1, "Maximum nodes for auto scaler")
npUpdate.Flags().StringToString("node-labels", nil, "A key=value comma separated string of labels to apply to the nodes in this node pool")

npUpdate.MarkFlagsOneRequired("quantity", "tag", "auto-scaler", "min-nodes", "max-nodes")
npUpdate.MarkFlagsOneRequired("quantity", "tag", "auto-scaler", "min-nodes", "max-nodes", "node-labels")

// Node Pool Delete
npDelete := &cobra.Command{
Expand Down Expand Up @@ -1000,10 +1038,10 @@ func formatNodePools(nodePools []string) ([]govultr.NodePoolReq, error) {
for _, r := range npList {
nodeData := strings.Split(r, ",")

if len(nodeData) < 3 || len(nodeData) > 7 {
if len(nodeData) < 3 || len(nodeData) > 8 {
return nil, fmt.Errorf(
`unable to format node pool. each node pool must include label, quantity, and plan.
Optionally you can include tag, auto-scaler, min-nodes and max-nodes`,
Optionally you can include tag, node-labels, auto-scaler, min-nodes and max-nodes`,
)
}

Expand All @@ -1019,7 +1057,7 @@ func formatNodePools(nodePools []string) ([]govultr.NodePoolReq, error) {
}

// formatNodeData loops over the parse strings for a node and returns the formatted struct
func formatNodeData(node []string) (*govultr.NodePoolReq, error) {
func formatNodeData(node []string) (*govultr.NodePoolReq, error) { //nolint:gocyclo
nodeData := &govultr.NodePoolReq{}
for _, f := range node {
nodeDataKeyVal := strings.Split(f, ":")
Expand All @@ -1044,6 +1082,8 @@ func formatNodeData(node []string) (*govultr.NodePoolReq, error) {
nodeData.Label = val
case field == "tag":
nodeData.Tag = val
case field == "node-labels":
nodeData.Labels = formatNodeLabels(val)
case field == "auto-scaler":
v, err := strconv.ParseBool(val)
if err != nil {
Expand All @@ -1068,6 +1108,19 @@ func formatNodeData(node []string) (*govultr.NodePoolReq, error) {
return nodeData, nil
}

// formatNodeLabels parses the node-labels option from the cluster create nodepool formatted string
func formatNodeLabels(nl string) map[string]string {
data := make(map[string]string)
labels := strings.Split(nl, "|")

for i := range labels {
label := strings.Split(labels[i], "=")
data[label[0]] = label[1]
}

return data
}

type options struct {
Base *cli.Base
CreateReq *govultr.ClusterReq
Expand Down
36 changes: 36 additions & 0 deletions cmd/kubernetes/printer.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package kubernetes

import (
"fmt"
"strconv"

"github.com/vultr/govultr/v3"
Expand Down Expand Up @@ -132,6 +133,9 @@ func (c *ClustersPrinter) Data() [][]string {
[]string{"AUTO SCALER", strconv.FormatBool(c.Clusters[i].NodePools[j].AutoScaler)},
[]string{"MIN NODES", strconv.Itoa(c.Clusters[i].NodePools[j].MinNodes)},
[]string{"MAX NODES", strconv.Itoa(c.Clusters[i].NodePools[j].MaxNodes)},
)

data = append(data,
[]string{" "},
[]string{"NODES"},
)
Expand All @@ -152,6 +156,14 @@ func (c *ClustersPrinter) Data() [][]string {
)
}

if len(c.Clusters[i].NodePools[j].Labels) != 0 {
data = append(data, []string{" "}, []string{"NODE LABELS"})
for k := range c.Clusters[i].NodePools[j].Labels {
label := fmt.Sprintf("%s=%s", k, c.Clusters[i].NodePools[j].Labels[k])
data = append(data, []string{label})
}
}

data = append(data, []string{" "})
}
}
Expand Down Expand Up @@ -239,6 +251,14 @@ func (c *ClusterPrinter) Data() [][]string {
)
}

if len(c.Cluster.NodePools[i].Labels) != 0 {
data = append(data, []string{" "}, []string{"NODE LABELS"})
for k := range c.Cluster.NodePools[i].Labels {
label := fmt.Sprintf("%s=%s", k, c.Cluster.NodePools[i].Labels[k])
data = append(data, []string{label})
}
}

data = append(data, []string{" "})
}

Expand Down Expand Up @@ -314,6 +334,14 @@ func (n *NodePoolsPrinter) Data() [][]string {
},
)
}

if len(n.NodePools[i].Labels) != 0 {
data = append(data, []string{" "}, []string{"NODE LABELS"})
for k := range n.NodePools[i].Labels {
label := fmt.Sprintf("%s=%s", k, n.NodePools[i].Labels[k])
data = append(data, []string{label})
}
}
}

return data
Expand Down Expand Up @@ -381,6 +409,14 @@ func (n *NodePoolPrinter) Data() [][]string {
)
}

if len(n.NodePool.Labels) != 0 {
data = append(data, []string{" "}, []string{"NODE LABELS"})
for k := range n.NodePool.Labels {
label := fmt.Sprintf("%s=%s", k, n.NodePool.Labels[k])
data = append(data, []string{label})
}
}

return data
}

Expand Down

0 comments on commit f566d86

Please sign in to comment.