2015-10-16 04:42:09 +00:00
|
|
|
package api
|
|
|
|
|
|
|
|
import (
|
|
|
|
"github.com/hashicorp/serf/coordinate"
|
2022-01-24 15:23:08 +00:00
|
|
|
"net/url"
|
2015-10-16 04:42:09 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// CoordinateEntry represents a node and its associated network coordinate.
|
|
|
|
type CoordinateEntry struct {
|
2021-07-22 19:33:22 +00:00
|
|
|
Node string
|
|
|
|
Segment string
|
|
|
|
Partition string `json:",omitempty"`
|
|
|
|
Coord *coordinate.Coordinate
|
2015-10-16 04:42:09 +00:00
|
|
|
}
|
|
|
|
|
2017-03-14 01:54:34 +00:00
|
|
|
// CoordinateDatacenterMap has the coordinates for servers in a given datacenter
|
|
|
|
// and area. Network coordinates are only compatible within the same area.
|
2015-10-16 04:42:09 +00:00
|
|
|
type CoordinateDatacenterMap struct {
|
|
|
|
Datacenter string
|
2017-03-14 01:54:34 +00:00
|
|
|
AreaID string
|
2015-10-16 04:42:09 +00:00
|
|
|
Coordinates []CoordinateEntry
|
|
|
|
}
|
|
|
|
|
|
|
|
// Coordinate can be used to query the coordinate endpoints
|
|
|
|
type Coordinate struct {
|
|
|
|
c *Client
|
|
|
|
}
|
|
|
|
|
|
|
|
// Coordinate returns a handle to the coordinate endpoints
|
|
|
|
func (c *Client) Coordinate() *Coordinate {
|
|
|
|
return &Coordinate{c}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Datacenters is used to return the coordinates of all the servers in the WAN
|
|
|
|
// pool.
|
|
|
|
func (c *Coordinate) Datacenters() ([]*CoordinateDatacenterMap, error) {
|
|
|
|
r := c.c.newRequest("GET", "/v1/coordinate/datacenters")
|
2021-10-28 16:24:23 +00:00
|
|
|
_, resp, err := c.c.doRequest(r)
|
2015-10-16 04:42:09 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2021-06-14 22:49:32 +00:00
|
|
|
defer closeResponseBody(resp)
|
2021-10-28 16:24:23 +00:00
|
|
|
if err := requireOK(resp); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2015-10-16 04:42:09 +00:00
|
|
|
|
|
|
|
var out []*CoordinateDatacenterMap
|
|
|
|
if err := decodeBody(resp, &out); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return out, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Nodes is used to return the coordinates of all the nodes in the LAN pool.
|
|
|
|
func (c *Coordinate) Nodes(q *QueryOptions) ([]*CoordinateEntry, *QueryMeta, error) {
|
|
|
|
r := c.c.newRequest("GET", "/v1/coordinate/nodes")
|
|
|
|
r.setQueryOptions(q)
|
2021-10-28 16:24:23 +00:00
|
|
|
rtt, resp, err := c.c.doRequest(r)
|
2015-10-16 04:42:09 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
2021-06-14 22:49:32 +00:00
|
|
|
defer closeResponseBody(resp)
|
2021-10-28 16:24:23 +00:00
|
|
|
if err := requireOK(resp); err != nil {
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
2015-10-16 04:42:09 +00:00
|
|
|
|
|
|
|
qm := &QueryMeta{}
|
|
|
|
parseQueryMeta(resp, qm)
|
|
|
|
qm.RequestTime = rtt
|
|
|
|
|
|
|
|
var out []*CoordinateEntry
|
|
|
|
if err := decodeBody(resp, &out); err != nil {
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
|
|
|
return out, qm, nil
|
|
|
|
}
|
2017-10-24 00:44:50 +00:00
|
|
|
|
|
|
|
// Update inserts or updates the LAN coordinate of a node.
|
|
|
|
func (c *Coordinate) Update(coord *CoordinateEntry, q *WriteOptions) (*WriteMeta, error) {
|
|
|
|
r := c.c.newRequest("PUT", "/v1/coordinate/update")
|
|
|
|
r.setWriteOptions(q)
|
|
|
|
r.obj = coord
|
2021-10-28 16:24:23 +00:00
|
|
|
rtt, resp, err := c.c.doRequest(r)
|
2017-10-24 00:44:50 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2021-06-14 22:49:32 +00:00
|
|
|
defer closeResponseBody(resp)
|
2021-10-28 16:24:23 +00:00
|
|
|
if err := requireOK(resp); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2017-10-24 00:44:50 +00:00
|
|
|
|
|
|
|
wm := &WriteMeta{}
|
|
|
|
wm.RequestTime = rtt
|
|
|
|
|
|
|
|
return wm, nil
|
|
|
|
}
|
2017-10-27 02:20:24 +00:00
|
|
|
|
2019-11-06 04:34:46 +00:00
|
|
|
// Node is used to return the coordinates of a single node in the LAN pool.
|
2017-10-27 02:16:40 +00:00
|
|
|
func (c *Coordinate) Node(node string, q *QueryOptions) ([]*CoordinateEntry, *QueryMeta, error) {
|
2022-01-24 15:23:08 +00:00
|
|
|
r := c.c.newRequest("GET", "/v1/coordinate/node/"+url.PathEscape(node))
|
2017-10-27 02:16:40 +00:00
|
|
|
r.setQueryOptions(q)
|
2021-10-28 16:24:23 +00:00
|
|
|
rtt, resp, err := c.c.doRequest(r)
|
2017-10-27 02:16:40 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
2021-06-14 22:49:32 +00:00
|
|
|
defer closeResponseBody(resp)
|
2021-10-28 16:24:23 +00:00
|
|
|
if err := requireOK(resp); err != nil {
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
2017-10-27 02:16:40 +00:00
|
|
|
|
|
|
|
qm := &QueryMeta{}
|
|
|
|
parseQueryMeta(resp, qm)
|
|
|
|
qm.RequestTime = rtt
|
|
|
|
|
|
|
|
var out []*CoordinateEntry
|
|
|
|
if err := decodeBody(resp, &out); err != nil {
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
|
|
|
return out, qm, nil
|
|
|
|
}
|