diff --git a/cmd/ucind/cluster/ls.go b/cmd/ucind/cluster/ls.go new file mode 100644 index 00000000..07746415 --- /dev/null +++ b/cmd/ucind/cluster/ls.go @@ -0,0 +1,40 @@ +package cluster + +import ( + "fmt" + "strings" + + "github.com/psviderski/uncloud/internal/cli/tui" + "github.com/psviderski/uncloud/internal/ucind" + "github.com/spf13/cobra" +) + +func NewListCommand() *cobra.Command { + cmd := &cobra.Command{ + Use: "ls", + Aliases: []string{"list"}, + Short: "List clusters.", + RunE: func(cmd *cobra.Command, args []string) error { + p := cmd.Context().Value("provisioner").(*ucind.Provisioner) + clusters, err := p.ListClusters(cmd.Context()) + if err != nil { + return fmt.Errorf("list clusters: %w", err) + } + t := tui.NewTable() + t.Headers("NAME", "MACHINES") + for _, cluster := range clusters { + machines := []string{} + for _, m := range cluster.Machines { + machines = append(machines, m.Name) + } + t.Row( + cluster.Name, + strings.Join(machines, tui.Faint.Render(", ")), + ) + } + fmt.Println(t) + return nil + }, + } + return cmd +} diff --git a/cmd/ucind/cluster/root.go b/cmd/ucind/cluster/root.go index 68dd208c..2bef7694 100644 --- a/cmd/ucind/cluster/root.go +++ b/cmd/ucind/cluster/root.go @@ -13,7 +13,7 @@ func NewRootCommand() *cobra.Command { } cmd.AddCommand( NewCreateCommand(), - // NewListCommand(), + NewListCommand(), NewRemoveCommand(), ) return cmd diff --git a/internal/ucind/cluster.go b/internal/ucind/cluster.go index 8e1cbd15..c4b9d224 100644 --- a/internal/ucind/cluster.go +++ b/internal/ucind/cluster.go @@ -322,6 +322,26 @@ func (p *Provisioner) WaitClusterReady(ctx context.Context, c Cluster, timeout t return nil } +func (p *Provisioner) ListClusters(ctx context.Context) ([]Cluster, error) { + nets, err := p.dockerCli.NetworkList(ctx, network.ListOptions{ + Filters: filters.NewArgs( + filters.Arg("label", ManagedLabel), + ), + }) + if err != nil { + return nil, err + } + + clusters := []Cluster{} + for _, net := range nets { + cluster, err := p.InspectCluster(ctx, net.Name) + if err == nil { + clusters = append(clusters, cluster) + } + } + return clusters, nil +} + func (p *Provisioner) RemoveCluster(ctx context.Context, name string) error { if _, err := p.InspectCluster(ctx, name); err != nil { if errors.Is(err, ErrNotFound) {