1package api 2 3// Operator can be used to perform low-level operator tasks for Consul. 4type Operator struct { 5 c *Client 6} 7 8// Operator returns a handle to the operator endpoints. 9func (c *Client) Operator() *Operator { 10 return &Operator{c} 11} 12 13// RaftServer has information about a server in the Raft configuration. 14type RaftServer struct { 15 // ID is the unique ID for the server. These are currently the same 16 // as the address, but they will be changed to a real GUID in a future 17 // release of Consul. 18 ID string 19 20 // Node is the node name of the server, as known by Consul, or this 21 // will be set to "(unknown)" otherwise. 22 Node string 23 24 // Address is the IP:port of the server, used for Raft communications. 25 Address string 26 27 // Leader is true if this server is the current cluster leader. 28 Leader bool 29 30 // Voter is true if this server has a vote in the cluster. This might 31 // be false if the server is staging and still coming online, or if 32 // it's a non-voting server, which will be added in a future release of 33 // Consul. 34 Voter bool 35} 36 37// RaftConfigration is returned when querying for the current Raft configuration. 38type RaftConfiguration struct { 39 // Servers has the list of servers in the Raft configuration. 40 Servers []*RaftServer 41 42 // Index has the Raft index of this configuration. 43 Index uint64 44} 45 46// keyringRequest is used for performing Keyring operations 47type keyringRequest struct { 48 Key string 49} 50 51// KeyringResponse is returned when listing the gossip encryption keys 52type KeyringResponse struct { 53 // Whether this response is for a WAN ring 54 WAN bool 55 56 // The datacenter name this request corresponds to 57 Datacenter string 58 59 // A map of the encryption keys to the number of nodes they're installed on 60 Keys map[string]int 61 62 // The total number of nodes in this ring 63 NumNodes int 64} 65 66// RaftGetConfiguration is used to query the current Raft peer set. 67func (op *Operator) RaftGetConfiguration(q *QueryOptions) (*RaftConfiguration, error) { 68 r := op.c.newRequest("GET", "/v1/operator/raft/configuration") 69 r.setQueryOptions(q) 70 _, resp, err := requireOK(op.c.doRequest(r)) 71 if err != nil { 72 return nil, err 73 } 74 defer resp.Body.Close() 75 76 var out RaftConfiguration 77 if err := decodeBody(resp, &out); err != nil { 78 return nil, err 79 } 80 return &out, nil 81} 82 83// RaftRemovePeerByAddress is used to kick a stale peer (one that it in the Raft 84// quorum but no longer known to Serf or the catalog) by address in the form of 85// "IP:port". 86func (op *Operator) RaftRemovePeerByAddress(address string, q *WriteOptions) error { 87 r := op.c.newRequest("DELETE", "/v1/operator/raft/peer") 88 r.setWriteOptions(q) 89 90 // TODO (slackpad) Currently we made address a query parameter. Once 91 // IDs are in place this will be DELETE /v1/operator/raft/peer/<id>. 92 r.params.Set("address", string(address)) 93 94 _, resp, err := requireOK(op.c.doRequest(r)) 95 if err != nil { 96 return err 97 } 98 99 resp.Body.Close() 100 return nil 101} 102 103// KeyringInstall is used to install a new gossip encryption key into the cluster 104func (op *Operator) KeyringInstall(key string, q *WriteOptions) error { 105 r := op.c.newRequest("POST", "/v1/operator/keyring") 106 r.setWriteOptions(q) 107 r.obj = keyringRequest{ 108 Key: key, 109 } 110 _, resp, err := requireOK(op.c.doRequest(r)) 111 if err != nil { 112 return err 113 } 114 resp.Body.Close() 115 return nil 116} 117 118// KeyringList is used to list the gossip keys installed in the cluster 119func (op *Operator) KeyringList(q *QueryOptions) ([]*KeyringResponse, error) { 120 r := op.c.newRequest("GET", "/v1/operator/keyring") 121 r.setQueryOptions(q) 122 _, resp, err := requireOK(op.c.doRequest(r)) 123 if err != nil { 124 return nil, err 125 } 126 defer resp.Body.Close() 127 128 var out []*KeyringResponse 129 if err := decodeBody(resp, &out); err != nil { 130 return nil, err 131 } 132 return out, nil 133} 134 135// KeyringRemove is used to remove a gossip encryption key from the cluster 136func (op *Operator) KeyringRemove(key string, q *WriteOptions) error { 137 r := op.c.newRequest("DELETE", "/v1/operator/keyring") 138 r.setWriteOptions(q) 139 r.obj = keyringRequest{ 140 Key: key, 141 } 142 _, resp, err := requireOK(op.c.doRequest(r)) 143 if err != nil { 144 return err 145 } 146 resp.Body.Close() 147 return nil 148} 149 150// KeyringUse is used to change the active gossip encryption key 151func (op *Operator) KeyringUse(key string, q *WriteOptions) error { 152 r := op.c.newRequest("PUT", "/v1/operator/keyring") 153 r.setWriteOptions(q) 154 r.obj = keyringRequest{ 155 Key: key, 156 } 157 _, resp, err := requireOK(op.c.doRequest(r)) 158 if err != nil { 159 return err 160 } 161 resp.Body.Close() 162 return nil 163} 164