small pixel drawing of a pufferfish cascade

internal/cli/members.go

package cli

import (
	"bytes"
	"flag"
	"fmt"
	"os"
	"strings"
	"text/tabwriter"

	"git.j3s.sh/cascade/api"
)

type membersCommand struct {
	usage string

	flagAPIAddr string
	flagDetails bool
}

func (c membersCommand) Usage() {
	fmt.Printf(`usage: cascade members [flags]
    list the members of the cascade serf cluster
  
flags:
  -api
    address of the cascade http api to target (default = 127.0.0.1:8500)
  
  -details | -l
    show more details (default = nil)
`)
}

func (c *membersCommand) Init(args []string) {
	flags := flag.NewFlagSet("", flag.ContinueOnError)
	flags.Usage = c.Usage
	flags.StringVar(&c.flagAPIAddr, "api", "", "")
	flags.BoolVar(&c.flagDetails, "details", false, "")
	flags.BoolVar(&c.flagDetails, "l", false, "")
	if err := flags.Parse(args); err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
}

func RunMembers(args []string) {
	c := membersCommand{}
	c.Init(args)

	cfg := api.DefaultConfig()
	client, err := api.NewClient(cfg)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	members, err := client.Agent().Members()
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	if c.flagDetails {
		var b bytes.Buffer
		tw := tabwriter.NewWriter(&b, 0, 2, 2, ' ', 0)
		fmt.Fprintf(tw, "node\taddr\tstatus\ttags\n")
		for _, m := range members {
			fmt.Fprintf(tw, "%s\t", m.Name)
			fmt.Fprintf(tw, "%s:%d\t", m.Addr, m.Port)
			fmt.Fprintf(tw, "%s\t", m.StatusPretty())
			fmt.Fprintf(tw, "%s\t", c.printTags(m.Tags))
			fmt.Fprintln(tw)
		}
		if err := tw.Flush(); err != nil {
			fmt.Printf("error flushing tabwriter: %s", err)
			os.Exit(1)
		}
		fmt.Print(b.String())
	} else {
		for _, m := range members {
			fmt.Println(m.Name)
		}
	}
}

func (c membersCommand) printTags(tags map[string]string) string {
	var results []string
	for k, v := range tags {
		results = append(results, fmt.Sprintf("%s=%s", k, v))
	}
	return strings.Join(results, ",")
}