api/agent.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
146
147
148
149
150
151
152
153
package api
// AgentMember represents a cluster member known to the agent
type AgentMember struct {
Name string
Addr string
Port uint16
Tags map[string]string
// Status of the Member which corresponds to github.com/hashicorp/serf/serf.MemberStatus
//
// AgentMemberNone = 0
// AgentMemberAlive = 1
// AgentMemberLeaving = 2
// AgentMemberLeft = 3
// AgentMemberFailed = 4
Status int
ProtocolMin uint8
ProtocolMax uint8
ProtocolCur uint8
DelegateMin uint8
DelegateMax uint8
DelegateCur uint8
}
func (am *AgentMember) StatusPretty() string {
var result string
switch am.Status {
case 0:
result = "none"
case 1:
result = "alive"
case 2:
result = "leaving"
case 3:
result = "left"
case 4:
result = "failed"
default:
result = "unknown"
}
return result
}
// XXX: this may be needed for consul compatability, but I'm leaving it
// out for now in case it isn't.
// const AllSegments = "_all"
// Agent can be used to query the Agent endpoints
type Agent struct {
c *Client
// cache the node name
nodeName string
}
// Agent returns a handle to the agent endpoints
func (c *Client) Agent() *Agent {
return &Agent{c: c}
}
// AgentSelf describes the agent the client is talking to.
type AgentSelf struct {
Config struct {
NodeName string
Version string
BuildDate string
DNSBindAddr string
HTTPBindAddr string
SerfBindAddr string
DNSDomain string
}
}
// SelfTyped queries the local agent for information about itself.
func (a *Agent) SelfTyped() (*AgentSelf, error) {
r := a.c.newRequest("GET", "/v1/agent/self")
_, resp, err := requireOK(a.c.doRequest(r))
if err != nil {
return nil, err
}
defer closeResponseBody(resp)
var out AgentSelf
if err := decodeBody(resp, &out); err != nil {
return nil, err
}
return &out, nil
}
// Self is used to query the agent we are speaking to for
// information about itself
func (a *Agent) Self() (map[string]map[string]interface{}, error) {
r := a.c.newRequest("GET", "/v1/agent/self")
_, resp, err := requireOK(a.c.doRequest(r))
if err != nil {
return nil, err
}
defer closeResponseBody(resp)
var out map[string]map[string]interface{}
if err := decodeBody(resp, &out); err != nil {
return nil, err
}
return out, nil
}
// Host is used to retrieve information about the host the
// agent is running on such as CPU, memory, and disk. Requires
// a operator:read ACL token.
func (a *Agent) Host() (map[string]interface{}, error) {
r := a.c.newRequest("GET", "/v1/agent/host")
_, resp, err := requireOK(a.c.doRequest(r))
if err != nil {
return nil, err
}
defer closeResponseBody(resp)
var out map[string]interface{}
if err := decodeBody(resp, &out); err != nil {
return nil, err
}
return out, nil
}
// NodeName is used to get the node name of the agent
func (a *Agent) NodeName() (string, error) {
if a.nodeName != "" {
return a.nodeName, nil
}
info, err := a.Self()
if err != nil {
return "", err
}
name := info["Config"]["NodeName"].(string)
a.nodeName = name
return name, nil
}
// Members returns the known serf gossip members
func (a *Agent) Members() ([]*AgentMember, error) {
r := a.c.newRequest("GET", "/v1/agent/members")
_, resp, err := requireOK(a.c.doRequest(r))
if err != nil {
return nil, err
}
defer closeResponseBody(resp)
var out []*AgentMember
if err := decodeBody(resp, &out); err != nil {
return nil, err
}
return out, nil
}