1package 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 closeResponseBody(resp) 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 closeResponseBody(resp) 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 closeResponseBody(resp) 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 closeResponseBody(resp) 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} 195