small pixel drawing of a pufferfish cascade

internal/cli/services.go

package cli

import (
	"bytes"
	"flag"
	"fmt"
	"net"
	"os"
	"sort"
	"strconv"
	"strings"
	"text/tabwriter"

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

type servicesCommand struct {
	flagAPIAddr string
}

func (c servicesCommand) Usage() {
	fmt.Printf(`usage: cascade services [flags]
    list the services registered to a cascade agent.

flags:
  -api
    address of the cascade http api to target (default = 127.0.0.1:8500)
`)
}

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

func RunServices(args []string) {
	c := servicesCommand{}
	c.Init(args)

	cfg := api.DefaultConfig()
	if c.flagAPIAddr != "" {
		cfg.Address = c.flagAPIAddr
	}
	client, err := api.NewClient(cfg)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	services, err := client.Agent().Services()
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	if len(services) == 0 {
		fmt.Printf("no services registered on %s\n", cfg.Address)
		return
	}

	ids := make([]string, 0, len(services))
	for id := range services {
		ids = append(ids, id)
	}
	sort.Strings(ids)

	nodeName, err := client.Agent().NodeName()
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	var b bytes.Buffer
	tw := tabwriter.NewWriter(&b, 0, 2, 2, ' ', 0)
	fmt.Fprintf(tw, "node\tid\tname\taddr\ttags\n")
	for _, id := range ids {
		s := services[id]
		addr := s.Address
		if s.Port != 0 {
			addr = net.JoinHostPort(addr, strconv.Itoa(s.Port))
		}
		fmt.Fprintf(tw, "%s\t%s\t%s\t%s\t%s\n", nodeName, s.ID, s.Service, addr, strings.Join(s.Tags, ","))
	}
	if err := tw.Flush(); err != nil {
		fmt.Printf("error flushing tabwriter: %s", err)
		os.Exit(1)
	}
	fmt.Print(b.String())
}