forked from hashicorp/consul
/
catalog_list_services.go
145 lines (115 loc) · 3.69 KB
/
catalog_list_services.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package command
import (
"bytes"
"fmt"
"sort"
"strings"
"text/tabwriter"
"github.com/hashicorp/consul/api"
"github.com/hashicorp/consul/configutil"
"github.com/mitchellh/cli"
)
var _ cli.Command = (*CatalogListServicesCommand)(nil)
// CatalogListServicesCommand is a Command implementation that is used to fetch all the
// datacenters the agent knows about.
type CatalogListServicesCommand struct {
BaseCommand
}
func (c *CatalogListServicesCommand) Help() string {
helpText := `
Usage: consul catalog services [options]
Retrieves the list services registered in a given datacenter. By default, the
datacenter of the local agent is queried.
To retrieve the list of services:
$ consul catalog services
To include the services' tags in the output:
$ consul catalog services -tags
To list services which run on a particular node:
$ consul catalog services -node=web
To filter services on node metadata:
$ consul catalog services -node-meta="foo=bar"
For a full list of options and examples, please see the Consul documentation.
` + c.BaseCommand.Help()
return strings.TrimSpace(helpText)
}
func (c *CatalogListServicesCommand) Run(args []string) int {
f := c.BaseCommand.NewFlagSet(c)
node := f.String("node", "", "Node `id or name` for which to list services.")
nodeMeta := make(map[string]string)
f.Var((*configutil.FlagMapValue)(&nodeMeta), "node-meta", "Metadata to "+
"filter nodes with the given `key=value` pairs. If specified, only "+
"services running on nodes matching the given metadata will be returned. "+
"This flag may be specified multiple times to filter on multiple sources "+
"of metadata.")
tags := f.Bool("tags", false, "Display each service's tags as a "+
"comma-separated list beside each service entry.")
if err := c.BaseCommand.Parse(args); err != nil {
return 1
}
if l := len(f.Args()); l > 0 {
c.UI.Error(fmt.Sprintf("Too many arguments (expected 0, got %d)", l))
return 1
}
// Create and test the HTTP client
client, err := c.BaseCommand.HTTPClient()
if err != nil {
c.UI.Error(fmt.Sprintf("Error connecting to Consul agent: %s", err))
return 1
}
var services map[string][]string
if *node != "" {
catalogNode, _, err := client.Catalog().Node(*node, &api.QueryOptions{
NodeMeta: nodeMeta,
})
if err != nil {
c.UI.Error(fmt.Sprintf("Error listing services for node: %s", err))
return 1
}
if catalogNode != nil {
services = make(map[string][]string, len(catalogNode.Services))
for _, s := range catalogNode.Services {
services[s.Service] = append(services[s.Service], s.Tags...)
}
}
} else {
services, _, err = client.Catalog().Services(&api.QueryOptions{
NodeMeta: nodeMeta,
})
if err != nil {
c.UI.Error(fmt.Sprintf("Error listing services: %s", err))
return 1
}
}
// Handle the edge case where there are no services that match the query.
if len(services) == 0 {
c.UI.Error("No services match the given query - try expanding your search.")
return 0
}
// Order the map for consistent output
order := make([]string, 0, len(services))
for k, _ := range services {
order = append(order, k)
}
sort.Strings(order)
if *tags {
var b bytes.Buffer
tw := tabwriter.NewWriter(&b, 0, 2, 6, ' ', 0)
for _, s := range order {
sort.Strings(services[s])
fmt.Fprintf(tw, "%s\t%s\n", s, strings.Join(services[s], ","))
}
if err := tw.Flush(); err != nil {
c.UI.Error(fmt.Sprintf("Error flushing tabwriter: %s", err))
return 1
}
c.UI.Output(strings.TrimSpace(b.String()))
} else {
for _, s := range order {
c.UI.Output(s)
}
}
return 0
}
func (c *CatalogListServicesCommand) Synopsis() string {
return "Lists all registered services in a datacenter"
}