Skip to content
This repository is currently being migrated. It's locked while the migration is in progress.

Commit

Permalink
Merge pull request #40 in STORAGEOS/c2-cli from feature/CP-4170-descr…
Browse files Browse the repository at this point in the history
…ibe-cluster to master

Squashed commit of the following:

commit 93fdc7b04f705655c26e80362548e461546f7b50
Author: Luciano Quercia <luciano.quercia@gmail.com>
Date:   Mon Mar 30 19:25:50 2020 +0100

    rebased + GetAllNodes client function + textformat extensions for get cluster and describe cluster.

commit 170b5697b34d08678ec420bf15d6ec93688f1663
Author: Luciano Quercia <luciano.quercia@gmail.com>
Date:   Thu Mar 26 15:53:33 2020 +0000

    Display bools for Disable options

commit 9e42a1a2587a4133d9cedbf762aa5d55fc358ce2
Author: Luciano Quercia <luciano.quercia@gmail.com>
Date:   Thu Mar 26 12:50:29 2020 +0000

    storageos describe cluster
  • Loading branch information
domodwyer committed Mar 31, 2020
1 parent 385846c commit 921530a
Show file tree
Hide file tree
Showing 10 changed files with 297 additions and 4 deletions.
15 changes: 15 additions & 0 deletions apiclient/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,21 @@ func (c *Client) GetNode(ctx context.Context, uid id.Node) (*node.Resource, erro
return c.transport.GetNode(ctx, uid)
}

// GetAllNodes returns all the node resources in the cluster.
func (c *Client) GetAllNodes(ctx context.Context) ([]*node.Resource, error) {
_, err := c.authenticate(ctx)
if err != nil {
return nil, err
}

nodes, err := c.transport.ListNodes(ctx)
if err != nil {
return nil, err
}

return nodes, nil
}

// GetNodeByName requests basic information for the node resource which has
// name.
//
Expand Down
67 changes: 67 additions & 0 deletions cmd/describe/cluster.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package describe

import (
"context"
"io"

"github.com/spf13/cobra"

"code.storageos.net/storageos/c2-cli/cmd/argwrappers"
"code.storageos.net/storageos/c2-cli/cmd/runwrappers"
"code.storageos.net/storageos/c2-cli/output"
)

type clusterCommand struct {
config ConfigProvider
client Client
display Displayer

writer io.Writer
}

func (c *clusterCommand) runWithCtx(ctx context.Context, cmd *cobra.Command, args []string) error {
cluster, err := c.client.GetCluster(ctx)
if err != nil {
return err
}

nodes, err := c.client.GetAllNodes(ctx)
if err != nil {
return err
}

return c.display.DescribeCluster(ctx, c.writer, output.NewCluster(cluster, nodes))
}

func newCluster(w io.Writer, client Client, config ConfigProvider) *cobra.Command {
c := &clusterCommand{
config: config,
client: client,
writer: w,
}

cobraCommand := &cobra.Command{
Aliases: []string{"nodes"},
Use: "cluster",
Short: "Retrieve detailed information for the current cluster",
Example: `
$ storageos describe cluster
`,

PreRunE: argwrappers.WrapInvalidArgsError(func(_ *cobra.Command, args []string) error {
c.display = SelectDisplayer(c.config)
return nil
}),

RunE: func(cmd *cobra.Command, args []string) error {
run := runwrappers.Chain(
runwrappers.RunWithTimeout(c.config),
)(c.runWithCtx)
return run(context.Background(), cmd, args)
},

SilenceUsage: true,
}

return cobraCommand
}
7 changes: 6 additions & 1 deletion cmd/describe/describe.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

"github.com/spf13/cobra"

"code.storageos.net/storageos/c2-cli/cluster"
"code.storageos.net/storageos/c2-cli/namespace"
"code.storageos.net/storageos/c2-cli/node"
"code.storageos.net/storageos/c2-cli/output"
Expand All @@ -30,9 +31,11 @@ type ConfigProvider interface {
// Client describes the functionality required by the CLI application
// to reasonably implement the "describe" verb commands.
type Client interface {
GetCluster(ctx context.Context) (*cluster.Resource, error)

GetNode(ctx context.Context, uid id.Node) (*node.Resource, error)
GetNodeByName(ctx context.Context, name string) (*node.Resource, error)

GetAllNodes(ctx context.Context) ([]*node.Resource, error)
GetListNodes(ctx context.Context, uids ...id.Node) ([]*node.Resource, error)
GetListNodesByName(ctx context.Context, names ...string) ([]*node.Resource, error)

Expand All @@ -50,6 +53,7 @@ type Client interface {
// Displayer defines the functionality required by the CLI application
// to display the results gathered by the "describe" verb commands.
type Displayer interface {
DescribeCluster(ctx context.Context, w io.Writer, c *output.Cluster) error
DescribeNode(ctx context.Context, w io.Writer, node *output.NodeDescription) error
DescribeListNodes(ctx context.Context, w io.Writer, nodes []*output.NodeDescription) error
DescribeVolume(ctx context.Context, w io.Writer, volume *output.Volume) error
Expand All @@ -66,6 +70,7 @@ func NewCommand(client Client, config ConfigProvider) *cobra.Command {
command.AddCommand(
newNode(os.Stdout, client, config),
newVolume(os.Stdout, client, config),
newCluster(os.Stdout, client, config),
)

return command
Expand Down
7 changes: 6 additions & 1 deletion cmd/get/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,12 @@ func (c *clusterCommand) runWithCtx(ctx context.Context, cmd *cobra.Command, _ [
return err
}

return c.display.GetCluster(ctx, c.writer, output.NewCluster(cluster))
nodes, err := c.client.GetAllNodes(ctx)
if err != nil {
return err
}

return c.display.GetCluster(ctx, c.writer, output.NewCluster(cluster, nodes))
}

func newCluster(w io.Writer, client Client, config ConfigProvider) *cobra.Command {
Expand Down
1 change: 1 addition & 0 deletions cmd/get/get.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ type Client interface {
GetListUsersByUsername(ctx context.Context, usernames []string) ([]*user.Resource, error)

GetListPolicyGroups(ctx context.Context, gids ...id.PolicyGroup) ([]*policygroup.Resource, error)
GetAllNodes(ctx context.Context) ([]*node.Resource, error)
GetNode(ctx context.Context, uid id.Node) (*node.Resource, error)
GetNodeByName(ctx context.Context, name string) (*node.Resource, error)
GetListNodes(ctx context.Context, uids ...id.Node) ([]*node.Resource, error)
Expand Down
6 changes: 5 additions & 1 deletion output/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"time"

"code.storageos.net/storageos/c2-cli/cluster"
"code.storageos.net/storageos/c2-cli/node"
"code.storageos.net/storageos/c2-cli/pkg/id"
"code.storageos.net/storageos/c2-cli/pkg/version"
)
Expand All @@ -24,6 +25,8 @@ type Cluster struct {
CreatedAt time.Time `json:"createdAt" yaml:"createdAt"`
UpdatedAt time.Time `json:"updatedAt" yaml:"updatedAt"`
Version version.Version `json:"version" yaml:"version"`

Nodes []*Node `json:"nodes" yaml:"nodes"`
}

// Licence defines a type that contains all the info needed to be outputted.
Expand All @@ -37,7 +40,7 @@ type Licence struct {

// NewCluster returns a new Cluster object that contains all the info needed
// to be outputted.
func NewCluster(c *cluster.Resource) *Cluster {
func NewCluster(c *cluster.Resource, nodes []*node.Resource) *Cluster {
return &Cluster{
ID: c.ID,
Licence: NewLicence(c.Licence),
Expand All @@ -49,6 +52,7 @@ func NewCluster(c *cluster.Resource) *Cluster {
CreatedAt: c.CreatedAt,
UpdatedAt: c.UpdatedAt,
Version: c.Version,
Nodes: NewNodes(nodes),
}
}

Expand Down
5 changes: 5 additions & 0 deletions output/jsonformat/jsonformat.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,11 @@ func (d *Displayer) GetListVolumes(ctx context.Context, w io.Writer, volumes []*
// DESCRIBE
// -----------------------------------------------------------------------------

// DescribeCluster encodes a cluster as JSON, writing the result to w.
func (d *Displayer) DescribeCluster(ctx context.Context, w io.Writer, c *output.Cluster) error {
return d.encode(w, c)
}

// DescribeNode encodes node as JSON, writing the result to w.
func (d *Displayer) DescribeNode(ctx context.Context, w io.Writer, node *output.NodeDescription) error {
return d.encode(w, node)
Expand Down
55 changes: 55 additions & 0 deletions output/textformat/textformat.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,20 @@ func (d *Displayer) GetCluster(ctx context.Context, w io.Writer, resource *outpu
table.AddRow("Created at:", d.timeToHuman(resource.CreatedAt))
table.AddRow("Updated at:", d.timeToHuman(resource.UpdatedAt))

// nodes
healthy, unhealthy := 0, 0
for _, n := range resource.Nodes {
if n.Health == health.NodeOnline {
healthy++
} else {
unhealthy++
}
}

table.AddRow("Nodes:", len(resource.Nodes))
table.AddRow(" Healthy:", healthy)
table.AddRow(" Unhealthy:", unhealthy)

return write(w)
}

Expand Down Expand Up @@ -218,6 +232,40 @@ func (d *Displayer) AttachVolume(ctx context.Context, w io.Writer) error {
return err
}

// DescribeCluster encodes a cluster as JSON, writing the result to w.
func (d *Displayer) DescribeCluster(ctx context.Context, w io.Writer, c *output.Cluster) error {
table, write := createTable(nil)

capacity := fmt.Sprintf("%s (%d)", humanize.IBytes(c.Licence.ClusterCapacityBytes), c.Licence.ClusterCapacityBytes)

table.AddRow("ID:", c.ID)
table.AddRow("Licence:", "")
table.AddRow(" expiration:", d.timeToHuman(c.Licence.ExpiresAt))
table.AddRow(" capacity:", capacity)
table.AddRow(" kind:", c.Licence.Kind)
table.AddRow(" customer name:", c.Licence.CustomerName)
table.AddRow("Version:", c.Version)
table.AddRow("Created at:", d.timeToHuman(c.CreatedAt))
table.AddRow("Updated at:", d.timeToHuman(c.UpdatedAt))
table.AddRow("Telemetry:", d.disableToHuman(c.DisableTelemetry))
table.AddRow("Crash Reporting:", d.disableToHuman(c.DisableCrashReporting))
table.AddRow("Version Check:", d.disableToHuman(c.DisableVersionCheck))
table.AddRow("Log Level:", c.LogLevel.String())
table.AddRow("Log Format:", c.LogFormat.String())
table.AddRow("Nodes:", "")
for i, n := range c.Nodes {
if i > 0 {
table.AddRow("", "")
}
table.AddRow(" ID:", n.ID.String())
table.AddRow(" Name:", n.Name)
table.AddRow(" Health:", n.Health)
table.AddRow(" Address:", n.IOAddr)
}

return write(w)
}

// UpdateLicence prints all the detailed information about a new licence, after
// it has been correctly updated.
func (d *Displayer) UpdateLicence(ctx context.Context, w io.Writer, licence *output.Licence) error {
Expand Down Expand Up @@ -428,6 +476,13 @@ func (d *Displayer) timeToHuman(t time.Time) string {
return fmt.Sprintf("%s (%s)", rfc, humanized)
}

func (d *Displayer) disableToHuman(b bool) string {
if b {
return "Disabled"
}
return "Enabled"
}

// DetachVolume writes a success message to the writer
func (d *Displayer) DetachVolume(ctx context.Context, w io.Writer) error {
_, err := fmt.Fprintln(w, "volume detached")
Expand Down
Loading

0 comments on commit 921530a

Please sign in to comment.