blob: 5cf7e49730c4d955e2bce86d2f8e4bdb56f67929 [file] [log] [blame]
William Kurkianea869482019-04-09 15:16:11 -04001package api
2
3// The /v1/operator/area endpoints are available only in Consul Enterprise and
4// interact with its network area subsystem. Network areas are used to link
5// together Consul servers in different Consul datacenters. With network areas,
6// Consul datacenters can be linked together in ways other than a fully-connected
7// mesh, as is required for Consul's WAN.
8
9import (
10 "net"
11 "time"
12)
13
14// Area defines a network area.
15type Area struct {
16 // ID is this identifier for an area (a UUID). This must be left empty
17 // when creating a new area.
18 ID string
19
20 // PeerDatacenter is the peer Consul datacenter that will make up the
21 // other side of this network area. Network areas always involve a pair
22 // of datacenters: the datacenter where the area was created, and the
23 // peer datacenter. This is required.
24 PeerDatacenter string
25
26 // RetryJoin specifies the address of Consul servers to join to, such as
27 // an IPs or hostnames with an optional port number. This is optional.
28 RetryJoin []string
29
30 // UseTLS specifies whether gossip over this area should be encrypted with TLS
31 // if possible.
32 UseTLS bool
33}
34
35// AreaJoinResponse is returned when a join occurs and gives the result for each
36// address.
37type AreaJoinResponse struct {
38 // The address that was joined.
39 Address string
40
41 // Whether or not the join was a success.
42 Joined bool
43
44 // If we couldn't join, this is the message with information.
45 Error string
46}
47
48// SerfMember is a generic structure for reporting information about members in
49// a Serf cluster. This is only used by the area endpoints right now, but this
50// could be expanded to other endpoints in the future.
51type SerfMember struct {
52 // ID is the node identifier (a UUID).
53 ID string
54
55 // Name is the node name.
56 Name string
57
58 // Addr has the IP address.
59 Addr net.IP
60
61 // Port is the RPC port.
62 Port uint16
63
64 // Datacenter is the DC name.
65 Datacenter string
66
67 // Role is "client", "server", or "unknown".
68 Role string
69
70 // Build has the version of the Consul agent.
71 Build string
72
73 // Protocol is the protocol of the Consul agent.
74 Protocol int
75
76 // Status is the Serf health status "none", "alive", "leaving", "left",
77 // or "failed".
78 Status string
79
80 // RTT is the estimated round trip time from the server handling the
81 // request to the this member. This will be negative if no RTT estimate
82 // is available.
83 RTT time.Duration
84}
85
86// AreaCreate will create a new network area. The ID in the given structure must
87// be empty and a generated ID will be returned on success.
88func (op *Operator) AreaCreate(area *Area, q *WriteOptions) (string, *WriteMeta, error) {
89 r := op.c.newRequest("POST", "/v1/operator/area")
90 r.setWriteOptions(q)
91 r.obj = area
92 rtt, resp, err := requireOK(op.c.doRequest(r))
93 if err != nil {
94 return "", nil, err
95 }
96 defer resp.Body.Close()
97
98 wm := &WriteMeta{}
99 wm.RequestTime = rtt
100
101 var out struct{ ID string }
102 if err := decodeBody(resp, &out); err != nil {
103 return "", nil, err
104 }
105 return out.ID, wm, nil
106}
107
108// AreaUpdate will update the configuration of the network area with the given ID.
109func (op *Operator) AreaUpdate(areaID string, area *Area, q *WriteOptions) (string, *WriteMeta, error) {
110 r := op.c.newRequest("PUT", "/v1/operator/area/"+areaID)
111 r.setWriteOptions(q)
112 r.obj = area
113 rtt, resp, err := requireOK(op.c.doRequest(r))
114 if err != nil {
115 return "", nil, err
116 }
117 defer resp.Body.Close()
118
119 wm := &WriteMeta{}
120 wm.RequestTime = rtt
121
122 var out struct{ ID string }
123 if err := decodeBody(resp, &out); err != nil {
124 return "", nil, err
125 }
126 return out.ID, wm, nil
127}
128
129// AreaGet returns a single network area.
130func (op *Operator) AreaGet(areaID string, q *QueryOptions) ([]*Area, *QueryMeta, error) {
131 var out []*Area
132 qm, err := op.c.query("/v1/operator/area/"+areaID, &out, q)
133 if err != nil {
134 return nil, nil, err
135 }
136 return out, qm, nil
137}
138
139// AreaList returns all the available network areas.
140func (op *Operator) AreaList(q *QueryOptions) ([]*Area, *QueryMeta, error) {
141 var out []*Area
142 qm, err := op.c.query("/v1/operator/area", &out, q)
143 if err != nil {
144 return nil, nil, err
145 }
146 return out, qm, nil
147}
148
149// AreaDelete deletes the given network area.
150func (op *Operator) AreaDelete(areaID string, q *WriteOptions) (*WriteMeta, error) {
151 r := op.c.newRequest("DELETE", "/v1/operator/area/"+areaID)
152 r.setWriteOptions(q)
153 rtt, resp, err := requireOK(op.c.doRequest(r))
154 if err != nil {
155 return nil, err
156 }
157 defer resp.Body.Close()
158
159 wm := &WriteMeta{}
160 wm.RequestTime = rtt
161 return wm, nil
162}
163
164// AreaJoin attempts to join the given set of join addresses to the given
165// network area. See the Area structure for details about join addresses.
166func (op *Operator) AreaJoin(areaID string, addresses []string, q *WriteOptions) ([]*AreaJoinResponse, *WriteMeta, error) {
167 r := op.c.newRequest("PUT", "/v1/operator/area/"+areaID+"/join")
168 r.setWriteOptions(q)
169 r.obj = addresses
170 rtt, resp, err := requireOK(op.c.doRequest(r))
171 if err != nil {
172 return nil, nil, err
173 }
174 defer resp.Body.Close()
175
176 wm := &WriteMeta{}
177 wm.RequestTime = rtt
178
179 var out []*AreaJoinResponse
180 if err := decodeBody(resp, &out); err != nil {
181 return nil, nil, err
182 }
183 return out, wm, nil
184}
185
186// AreaMembers lists the Serf information about the members in the given area.
187func (op *Operator) AreaMembers(areaID string, q *QueryOptions) ([]*SerfMember, *QueryMeta, error) {
188 var out []*SerfMember
189 qm, err := op.c.query("/v1/operator/area/"+areaID+"/members", &out, q)
190 if err != nil {
191 return nil, nil, err
192 }
193 return out, qm, nil
194}