mirror of
https://github.com/psviderski/uncloud.git
synced 2026-08-26 19:13:34 +00:00
refactor machine ls command: move formatter logic to the command
This commit is contained in:
@@ -1,8 +1,17 @@
|
|||||||
package machine
|
package machine
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
"google.golang.org/protobuf/types/known/emptypb"
|
||||||
|
"net/netip"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
"text/tabwriter"
|
||||||
"uncloud/internal/cli"
|
"uncloud/internal/cli"
|
||||||
|
"uncloud/internal/machine/network"
|
||||||
|
"uncloud/internal/secret"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewListCommand() *cobra.Command {
|
func NewListCommand() *cobra.Command {
|
||||||
@@ -13,7 +22,7 @@ func NewListCommand() *cobra.Command {
|
|||||||
Short: "List machines in a cluster.",
|
Short: "List machines in a cluster.",
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
uncli := cmd.Context().Value("cli").(*cli.CLI)
|
uncli := cmd.Context().Value("cli").(*cli.CLI)
|
||||||
return uncli.ListMachines(cmd.Context(), cluster)
|
return runList(cmd.Context(), uncli, cluster)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
cmd.Flags().StringVarP(
|
cmd.Flags().StringVarP(
|
||||||
@@ -22,3 +31,51 @@ func NewListCommand() *cobra.Command {
|
|||||||
)
|
)
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func runList(ctx context.Context, uncli *cli.CLI, clusterName string) error {
|
||||||
|
c, err := uncli.ConnectCluster(ctx, clusterName)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("connect to cluster: %w", err)
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
_ = c.Close()
|
||||||
|
}()
|
||||||
|
|
||||||
|
listResp, err := c.ListMachines(ctx, &emptypb.Empty{})
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("list machines: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print the list of machines in a table format.
|
||||||
|
tw := tabwriter.NewWriter(os.Stdout, 0, 0, 3, ' ', 0)
|
||||||
|
// Print header.
|
||||||
|
if _, err = fmt.Fprintln(tw, "NAME\tSTATE\tADDRESS\tPUBLIC KEY\tENDPOINTS"); err != nil {
|
||||||
|
return fmt.Errorf("write header: %w", err)
|
||||||
|
}
|
||||||
|
// Print rows.
|
||||||
|
for _, member := range listResp.Machines {
|
||||||
|
m := member.Machine
|
||||||
|
subnet, _ := m.Network.Subnet.ToPrefix()
|
||||||
|
subnet = netip.PrefixFrom(network.MachineIP(subnet), subnet.Bits())
|
||||||
|
endpoints := make([]string, len(m.Network.Endpoints))
|
||||||
|
for i, ep := range m.Network.Endpoints {
|
||||||
|
addrPort, _ := ep.ToAddrPort()
|
||||||
|
endpoints[i] = addrPort.String()
|
||||||
|
}
|
||||||
|
publicKey := secret.Secret(m.Network.PublicKey)
|
||||||
|
if _, err = fmt.Fprintf(
|
||||||
|
tw, "%s\t%s\t%s\t%s\t%s\n", m.Name, capitalise(member.State.String()), subnet, publicKey, strings.Join(endpoints, ", "),
|
||||||
|
); err != nil {
|
||||||
|
return fmt.Errorf("write row: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tw.Flush()
|
||||||
|
}
|
||||||
|
|
||||||
|
// capitalise returns a string where the first character is upper case, and the rest is lower case.
|
||||||
|
func capitalise(s string) string {
|
||||||
|
if s == "" {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return strings.ToUpper(s[:1]) + strings.ToLower(s[1:])
|
||||||
|
}
|
||||||
|
|||||||
@@ -7,16 +7,11 @@ import (
|
|||||||
"github.com/charmbracelet/huh"
|
"github.com/charmbracelet/huh"
|
||||||
"google.golang.org/protobuf/types/known/emptypb"
|
"google.golang.org/protobuf/types/known/emptypb"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
"text/tabwriter"
|
|
||||||
"uncloud/internal/cli/client"
|
"uncloud/internal/cli/client"
|
||||||
"uncloud/internal/cli/client/connector"
|
"uncloud/internal/cli/client/connector"
|
||||||
"uncloud/internal/cli/config"
|
"uncloud/internal/cli/config"
|
||||||
"uncloud/internal/machine"
|
"uncloud/internal/machine"
|
||||||
"uncloud/internal/machine/api/pb"
|
"uncloud/internal/machine/api/pb"
|
||||||
"uncloud/internal/machine/network"
|
|
||||||
"uncloud/internal/secret"
|
|
||||||
"uncloud/internal/sshexec"
|
"uncloud/internal/sshexec"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -323,51 +318,3 @@ func (cli *CLI) promptResetMachine() error {
|
|||||||
// TODO: implement resetting the remote machine.
|
// TODO: implement resetting the remote machine.
|
||||||
return fmt.Errorf("resetting the remote machine is not implemented yet")
|
return fmt.Errorf("resetting the remote machine is not implemented yet")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli *CLI) ListMachines(ctx context.Context, clusterName string) error {
|
|
||||||
c, err := cli.ConnectCluster(ctx, clusterName)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("connect to cluster: %w", err)
|
|
||||||
}
|
|
||||||
defer func() {
|
|
||||||
_ = c.Close()
|
|
||||||
}()
|
|
||||||
|
|
||||||
listResp, err := c.ListMachines(ctx, &emptypb.Empty{})
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("list machines: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Print the list of machines in a table format.
|
|
||||||
tw := tabwriter.NewWriter(os.Stdout, 0, 0, 3, ' ', 0)
|
|
||||||
// Print header.
|
|
||||||
if _, err = fmt.Fprintln(tw, "NAME\tSTATE\tADDRESS\tPUBLIC KEY\tENDPOINTS"); err != nil {
|
|
||||||
return fmt.Errorf("write header: %w", err)
|
|
||||||
}
|
|
||||||
// Print rows.
|
|
||||||
for _, member := range listResp.Machines {
|
|
||||||
m := member.Machine
|
|
||||||
subnet, _ := m.Network.Subnet.ToPrefix()
|
|
||||||
subnet = netip.PrefixFrom(network.MachineIP(subnet), subnet.Bits())
|
|
||||||
endpoints := make([]string, len(m.Network.Endpoints))
|
|
||||||
for i, ep := range m.Network.Endpoints {
|
|
||||||
addrPort, _ := ep.ToAddrPort()
|
|
||||||
endpoints[i] = addrPort.String()
|
|
||||||
}
|
|
||||||
publicKey := secret.Secret(m.Network.PublicKey)
|
|
||||||
if _, err = fmt.Fprintf(
|
|
||||||
tw, "%s\t%s\t%s\t%s\t%s\n", m.Name, capitalise(member.State.String()), subnet, publicKey, strings.Join(endpoints, ", "),
|
|
||||||
); err != nil {
|
|
||||||
return fmt.Errorf("write row: %w", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return tw.Flush()
|
|
||||||
}
|
|
||||||
|
|
||||||
// capitalise returns a string where the first character is upper case, and the rest is lower case.
|
|
||||||
func capitalise(s string) string {
|
|
||||||
if s == "" {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return strings.ToUpper(s[:1]) + strings.ToLower(s[1:])
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user