cli/cmd/node.go

193 lines
3.9 KiB
Go

package cmd
import (
"fmt"
"github.com/sirupsen/logrus"
"github.com/rancher/cli/cliclient"
managementClient "github.com/rancher/rancher/pkg/client/generated/management/v3"
"github.com/urfave/cli"
)
type NodeData struct {
ID string
Node managementClient.Node
Name string
Pool string
}
func NodeCommand() cli.Command {
return cli.Command{
Name: "nodes",
Aliases: []string{"node"},
Usage: "Operations on nodes",
Action: defaultAction(nodeLs),
Subcommands: []cli.Command{
{
Name: "ls",
Usage: "List nodes",
Description: "\nLists all nodes in the current cluster.",
ArgsUsage: "None",
Action: nodeLs,
Flags: []cli.Flag{
cli.StringFlag{
Name: "format",
Usage: "'json', 'yaml' or Custom format: '{{.Node.ID}} {{.Node.Name}}'",
},
quietFlag,
},
},
{
Name: "delete",
Aliases: []string{"rm"},
Usage: "Delete a node by ID",
ArgsUsage: "[NODEID NODENAME]",
Action: nodeDelete,
},
},
}
}
func nodeLs(ctx *cli.Context) error {
c, err := GetClient(ctx)
if err != nil {
return err
}
collection, err := getNodesList(ctx, c, c.UserConfig.FocusedCluster())
if err != nil {
return err
}
nodePools, err := getNodePools(ctx, c)
if err != nil {
return err
}
writer := NewTableWriter([][]string{
{"ID", "ID"},
{"NAME", "Name"},
{"STATE", "Node.State"},
{"POOL", "Pool"},
{"DESCRIPTION", "Node.Description"},
}, ctx)
defer writer.Close()
for _, item := range collection.Data {
writer.Write(&NodeData{
ID: item.ID,
Node: item,
Name: getNodeName(item),
Pool: getNodePoolName(item, nodePools),
})
}
return writer.Err()
}
func nodeDelete(ctx *cli.Context) error {
if ctx.NArg() == 0 {
return cli.ShowSubcommandHelp(ctx)
}
c, err := GetClient(ctx)
if err != nil {
return err
}
for _, arg := range ctx.Args() {
resource, err := Lookup(c, arg, "node")
if err != nil {
return err
}
node, err := getNodeByID(ctx, c, resource.ID)
if err != nil {
return err
}
if _, ok := node.Links["remove"]; !ok {
logrus.Warnf("node %v is externally managed and must be deleted "+
"through the provider", getNodeName(node))
continue
}
err = c.ManagementClient.Node.Delete(&node)
if err != nil {
return err
}
}
return nil
}
func getNodesList(
ctx *cli.Context,
c *cliclient.MasterClient,
clusterID string,
) (*managementClient.NodeCollection, error) {
filter := defaultListOpts(ctx)
filter.Filters["clusterId"] = clusterID
collection, err := c.ManagementClient.Node.List(filter)
if err != nil {
return nil, err
}
return collection, nil
}
func getNodeByID(
ctx *cli.Context,
c *cliclient.MasterClient,
nodeID string,
) (managementClient.Node, error) {
nodeCollection, err := getNodesList(ctx, c, c.UserConfig.FocusedCluster())
if err != nil {
return managementClient.Node{}, err
}
for _, node := range nodeCollection.Data {
if node.ID == nodeID {
return node, nil
}
}
return managementClient.Node{}, fmt.Errorf("no node found with the ID [%s], run "+
"`rancher nodes` to see available nodes", nodeID)
}
func getNodeName(node managementClient.Node) string {
if node.Name != "" {
return node.Name
} else if node.NodeName != "" {
return node.NodeName
} else if node.RequestedHostname != "" {
return node.RequestedHostname
}
return node.ID
}
func getNodePools(
ctx *cli.Context,
c *cliclient.MasterClient,
) (*managementClient.NodePoolCollection, error) {
filter := defaultListOpts(ctx)
filter.Filters["clusterId"] = c.UserConfig.FocusedCluster()
collection, err := c.ManagementClient.NodePool.List(filter)
if err != nil {
return nil, err
}
return collection, nil
}
func getNodePoolName(node managementClient.Node, pools *managementClient.NodePoolCollection) string {
for _, pool := range pools.Data {
if node.NodePoolID == pool.ID {
return pool.HostnamePrefix
}
}
return ""
}