Skip to content
This repository has been archived by the owner on Feb 14, 2022. It is now read-only.

Commit

Permalink
describe nodedeployment
Browse files Browse the repository at this point in the history
  • Loading branch information
Cedric Kienzler committed Mar 17, 2021
1 parent 2142409 commit 1dc5a18
Show file tree
Hide file tree
Showing 11 changed files with 423 additions and 20 deletions.
3 changes: 2 additions & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@
//"get", "version"
//"config", "get", "cloud"
//"config", "add", "node", "openstack", "--flavor", "m1.micro", "--image", "Flatcar_Production 2020 - Latest", "flatcar1"
"add", "nodedeployment", "--project", "6tmbnhdl7h", "--cluster", "qvjdddt72t", "--nodespec", "flatcar1", "--operatingsystem", "flatcar", "--provider", "optimist", "first_node_deployment"
//"add", "nodedeployment", "--project", "6tmbnhdl7h", "--cluster", "qvjdddt72t", "--nodespec", "flatcar1", "--operatingsystem", "flatcar", "--provider", "optimist", "first_node_deployment"
"describe", "nodedeployment", "--project", "6tmbnhdl7h", "--cluster", "qvjdddt72t", "test1234"
]
}
]
Expand Down
51 changes: 51 additions & 0 deletions cmd/completion.go
Original file line number Diff line number Diff line change
Expand Up @@ -269,3 +269,54 @@ func getValidNodeSpecArgs(cmd *cobra.Command, args []string, toComplete string)

return completions, cobra.ShellCompDirectiveNoFileComp
}

func getValidNodeDeploymentArgs(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
completions := make([]string, 0)

baseURL, apiToken := Config.GetCloudFromContext()
kkp, err := client.NewClient(baseURL, apiToken)
if err != nil {
fmt.Println(err.Error())
return completions, cobra.ShellCompDirectiveError
}

projectID, err := cmd.Flags().GetString("project")
if err != nil {
return completions, cobra.ShellCompDirectiveNoFileComp
}

clusterID, err := cmd.Flags().GetString("cluster")
if err != nil {
return completions, cobra.ShellCompDirectiveNoFileComp
}

dc, err := cmd.Flags().GetString("datacenter")
if err != nil {
return completions, cobra.ShellCompDirectiveNoFileComp
}

var cluster models.Cluster
if dc == "" {
cluster, err = kkp.GetClusterInProject(clusterID, projectID)
} else {
cluster, err = kkp.GetClusterInProjectInDC(clusterID, projectID, dc)
}

if err != nil {
return completions, cobra.ShellCompDirectiveNoFileComp
}

nodeDeployments, err := kkp.GetNodeDeployments(cluster.ID, projectID, cluster.Spec.Cloud.DatacenterName)
if err != nil {
return completions, cobra.ShellCompDirectiveNoFileComp
}

toCompleteRegexp := regexp.MustCompile(fmt.Sprintf("^%s.*$", toComplete))
for _, nd := range nodeDeployments {
if toCompleteRegexp.MatchString(nd.ID) {
completions = append(completions, nd.ID)
}
}

return completions, cobra.ShellCompDirectiveNoFileComp
}
9 changes: 5 additions & 4 deletions cmd/delete_node_deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@ import (
)

var deleteNodeDeploymentCmd = &cobra.Command{
Use: "nodedeployment name",
Short: "Lets you create a new node deployment",
Args: cobra.ExactArgs(1),
Example: "kkpctl delete nodedeployment --project 6tmbnhdl7h --cluster qvjdddt72t",
Use: "nodedeployment name",
Short: "Lets you create a new node deployment",
Args: cobra.ExactArgs(1),
Example: "kkpctl delete nodedeployment --project 6tmbnhdl7h --cluster qvjdddt72t my_first_nodedeployment",
ValidArgsFunction: getValidNodeDeploymentArgs,
RunE: func(cmd *cobra.Command, args []string) error {
baseURL, apiToken := Config.GetCloudFromContext()
kkp, err := client.NewClient(baseURL, apiToken)
Expand Down
82 changes: 82 additions & 0 deletions cmd/describe_node_deployment.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package cmd

import (
"fmt"

"github.com/cedi/kkpctl/pkg/client"
"github.com/cedi/kkpctl/pkg/describe"
"github.com/kubermatic/go-kubermatic/models"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)

// clustersCmd represents the clusters command
var describeNodeDeploymentCmd = &cobra.Command{
Use: "nodedeployment name",
Short: "Describes a node deployment",
Example: "kkpctl describe nodedeployment my_nodedeployment",
Args: cobra.ExactArgs(1),
ValidArgsFunction: getValidNodeDeploymentArgs,
RunE: func(cmd *cobra.Command, args []string) error {
baseURL, apiToken := Config.GetCloudFromContext()
kkp, err := client.NewClient(baseURL, apiToken)
if err != nil {
return errors.New("Could not initialize Kubermatic API client")
}

var cluster models.Cluster
if datacenter == "" {
cluster, err = kkp.GetClusterInProject(clusterID, projectID)
} else if datacenter != "" && projectID != "" {
cluster, err = kkp.GetClusterInProjectInDC(clusterID, projectID, datacenter)
}

if err != nil {
return errors.Wrap(err, "could not fetch cluster")
}

nodeDeployment, err := kkp.GetNodeDeployment(args[0], cluster.ID, projectID, cluster.Spec.Cloud.DatacenterName)
if err != nil {
return errors.Wrap(err, "Error fetching node deployment")
}

nodeDeploymentNodes, err := kkp.GetNodeDeploymentNodes(nodeDeployment.ID, cluster.ID, projectID, cluster.Spec.Cloud.DatacenterName)
if err != nil {
return errors.Wrap(err, "Error fetching node deployment nodes")
}

nodeDeploymentEvents, err := kkp.GetNodeDeploymentEvents(nodeDeployment.ID, cluster.ID, projectID, cluster.Spec.Cloud.DatacenterName)
if err != nil {
return errors.Wrap(err, "Error fetching node deployment events")
}

meta := &describe.NodeDeploymentDescribeMeta{
NodeDeployment: &nodeDeployment,
Nodes: nodeDeploymentNodes,
NodeEvents: nodeDeploymentEvents,
}

parsed, err := describe.Object(meta)
if err != nil {
return errors.Wrap(err, "Error parsing datacenters")
}

fmt.Println(parsed)
return nil
},
}

func init() {
describeCmd.AddCommand(describeNodeDeploymentCmd)

describeNodeDeploymentCmd.Flags().StringVarP(&clusterID, "cluster", "c", "", "ID of the cluster")
describeNodeDeploymentCmd.MarkFlagRequired("cluster")
describeNodeDeploymentCmd.RegisterFlagCompletionFunc("cluster", getValidClusterArgs)

describeNodeDeploymentCmd.Flags().StringVarP(&projectID, "project", "p", "", "ID of the project")
describeNodeDeploymentCmd.MarkFlagRequired("project")
describeNodeDeploymentCmd.RegisterFlagCompletionFunc("project", getValidProjectArgs)

describeNodeDeploymentCmd.Flags().StringVarP(&datacenter, "datacenter", "d", "", "Name of the datacenter")
describeNodeDeploymentCmd.RegisterFlagCompletionFunc("datacenter", getValidDatacenterArgs)
}
10 changes: 5 additions & 5 deletions cmd/get_node_deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ import (

// clustersCmd represents the clusters command
var getNodeDeploymentCmd = &cobra.Command{
Use: "nodedeployment [name]",
Short: "Lists all available datacenters",
Example: "kkpctl get datacenter",
Args: cobra.MaximumNArgs(1),
//ValidArgsFunction: getValidNodeDeploymentArgs,
Use: "nodedeployment [name]",
Short: "List nodedeployments for a cluster",
Example: "kkpctl describe nodedeployment my_nodedeployment",
Args: cobra.MaximumNArgs(1),
ValidArgsFunction: getValidNodeDeploymentArgs,
RunE: func(cmd *cobra.Command, args []string) error {
baseURL, apiToken := Config.GetCloudFromContext()
kkp, err := client.NewClient(baseURL, apiToken)
Expand Down
40 changes: 40 additions & 0 deletions pkg/client/nodedeployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

const (
nodeDeploymentPath string = "nodedeployments"
nodePath string = "nodes"
)

// GetNodeDeployments lists all node deployments for a cluster
Expand Down Expand Up @@ -77,3 +78,42 @@ func (c *Client) DeleteNodeDeployment(nodeDeploymentID string, clusterID string,
_, err := c.Delete(requestURL)
return err
}

// GetNodeDeploymentNodes gets all nodes in a node deployment
func (c *Client) GetNodeDeploymentNodes(nodeDeploymentID string, clusterID string, projectID string, dc string) ([]models.Node, error) {
result := make([]models.Node, 0)

requestURL := fmt.Sprintf("%s/%s/%s/seed-%s/%s/%s/%s/%s/%s",
projectPath,
projectID,
datacenterPath,
dc,
clusterPath,
clusterID,
nodeDeploymentPath,
nodeDeploymentID,
nodePath,
)
_, err := c.Get(requestURL, &result)
return result, err
}

// GetNodeDeploymentNodes gets all nodes in a node deployment
func (c *Client) GetNodeDeploymentEvents(nodeDeploymentID string, clusterID string, projectID string, dc string) ([]models.Event, error) {
result := make([]models.Event, 0)

requestURL := fmt.Sprintf("%s/%s/%s/seed-%s/%s/%s/%s/%s/%s/%s",
projectPath,
projectID,
datacenterPath,
dc,
clusterPath,
clusterID,
nodeDeploymentPath,
nodeDeploymentID,
nodePath,
eventsPath,
)
_, err := c.Get(requestURL, &result)
return result, err
}
21 changes: 11 additions & 10 deletions pkg/describe/describe.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,17 @@ import (

// Object takes any KKP Object as an input and then describes it
func Object(object interface{}) (string, error) {
// this is ugly and long, but it makes things kinda nicer to handle outside of the package
project, ok := object.(*models.Project)
if ok {
return describeProject(project)
}
switch describeObj := object.(type) {
case *models.Project:
return describeProject(describeObj)

meta, ok := object.(*ClusterDescribeMeta)
if ok {
return describeCluster(meta)
}
case *ClusterDescribeMeta:
return describeCluster(describeObj)

return fmt.Sprintf("%v\n", object), fmt.Errorf("unable to parse proper type of object")
case *NodeDeploymentDescribeMeta:
return describeNodeDeployment(describeObj)

default:
return fmt.Sprintf("%v\n", object), fmt.Errorf("unable to parse proper type of object")
}
}
74 changes: 74 additions & 0 deletions pkg/describe/describe_node_deployment.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package describe

import (
"fmt"
"strings"

"github.com/cedi/kkpctl/pkg/output"
"github.com/kubermatic/go-kubermatic/models"
)

// NodeDeploymentDescribeMeta contains all the necessary fields to describe a cluster
type NodeDeploymentDescribeMeta struct {
NodeDeployment *models.NodeDeployment
Nodes []models.Node
NodeEvents []models.Event
}

// describeProject takes any KKP Cluster and describes it
func describeNodeDeployment(meta *NodeDeploymentDescribeMeta) (string, error) {
nd := meta.NodeDeployment
evnt := meta.NodeEvents
nodes := meta.Nodes

nodeDeploymentTable, err := output.ParseOutput(nd, output.Text, output.Name)
if err != nil || len(nodeDeploymentTable) == 0 {
return "", err
}

nodeTable, err := output.ParseOutput(nodes, output.Text, output.Name)
if err != nil || len(nodeTable) == 0 {
return "", err
}

nodeTaintsTable, err := output.ParseOutput(nd.Spec.Template.Taints, output.Text, output.Name)
if err != nil || len(nodeTaintsTable) == 0 {
nodeTaintsTable = "[None]"
}

nodeEventTable, err := output.ParseOutput(evnt, output.Text, output.Name)
if err != nil || len(nodeEventTable) == 0 {
nodeEventTable = "[None]"
}

labels := make([]string, 0)
for key, value := range nd.Spec.Template.Labels {
labels = append(labels, fmt.Sprintf("%s=%s", key, value))
}
if len(labels) == 0 {
labels = append(labels, "[None]")
}

result := fmt.Sprintf(`Node Deployment:
%s
Nodes:
%s
Taints:
%s
Labels:
%s
Events:
%s`,
nodeDeploymentTable,
nodeTable,
nodeTaintsTable,
strings.Join(labels, "; "),
nodeEventTable,
)

return result, nil
}
14 changes: 14 additions & 0 deletions pkg/output/output.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ func parseOutput(outputObject interface{}, output string, sortBy string) (string
return parseNodeDeployments(o, output, sortBy)
case models.NodeDeployment:
return parseNodeDeployment(o, output)
case *models.NodeDeployment:
return parseNodeDeployment(*o, output)

// Datacenter
case []models.Datacenter:
Expand All @@ -89,6 +91,18 @@ func parseOutput(outputObject interface{}, output string, sortBy string) (string
// Events
case []models.Event:
return parseEvents(o, output)

// Node Taints
case *models.TaintSpec:
return parseNodeTaint(o, output)
case []*models.TaintSpec:
return parseNodeTaints(o, output)

// Node
case models.Node:
return parseNode(o, output)
case []models.Node:
return parseNodes(o, output)
}

return fmt.Sprintf("%v\n", outputObject), fmt.Errorf("unable to parse proper type of object")
Expand Down
Loading

0 comments on commit 1dc5a18

Please sign in to comment.