-
Notifications
You must be signed in to change notification settings - Fork 4.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2312 from hashicorp/f-op-command
Adds new consul operator endpoint, CLI, and ACL and some basic Raft commands.
- Loading branch information
Showing
22 changed files
with
1,388 additions
and
94 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
package api | ||
|
||
import ( | ||
"github.com/hashicorp/raft" | ||
) | ||
|
||
// Operator can be used to perform low-level operator tasks for Consul. | ||
type Operator struct { | ||
c *Client | ||
} | ||
|
||
// Operator returns a handle to the operator endpoints. | ||
func (c *Client) Operator() *Operator { | ||
return &Operator{c} | ||
} | ||
|
||
// RaftServer has information about a server in the Raft configuration. | ||
type RaftServer struct { | ||
// ID is the unique ID for the server. These are currently the same | ||
// as the address, but they will be changed to a real GUID in a future | ||
// release of Consul. | ||
ID raft.ServerID | ||
|
||
// Node is the node name of the server, as known by Consul, or this | ||
// will be set to "(unknown)" otherwise. | ||
Node string | ||
|
||
// Address is the IP:port of the server, used for Raft communications. | ||
Address raft.ServerAddress | ||
|
||
// Leader is true if this server is the current cluster leader. | ||
Leader bool | ||
|
||
// Voter is true if this server has a vote in the cluster. This might | ||
// be false if the server is staging and still coming online, or if | ||
// it's a non-voting server, which will be added in a future release of | ||
// Consul. | ||
Voter bool | ||
} | ||
|
||
// RaftConfigration is returned when querying for the current Raft configuration. | ||
type RaftConfiguration struct { | ||
// Servers has the list of servers in the Raft configuration. | ||
Servers []*RaftServer | ||
|
||
// Index has the Raft index of this configuration. | ||
Index uint64 | ||
} | ||
|
||
// RaftGetConfiguration is used to query the current Raft peer set. | ||
func (op *Operator) RaftGetConfiguration(q *QueryOptions) (*RaftConfiguration, error) { | ||
r := op.c.newRequest("GET", "/v1/operator/raft/configuration") | ||
r.setQueryOptions(q) | ||
_, resp, err := requireOK(op.c.doRequest(r)) | ||
if err != nil { | ||
return nil, err | ||
} | ||
defer resp.Body.Close() | ||
|
||
var out RaftConfiguration | ||
if err := decodeBody(resp, &out); err != nil { | ||
return nil, err | ||
} | ||
return &out, nil | ||
} | ||
|
||
// RaftRemovePeerByAddress is used to kick a stale peer (one that it in the Raft | ||
// quorum but no longer known to Serf or the catalog) by address in the form of | ||
// "IP:port". | ||
func (op *Operator) RaftRemovePeerByAddress(address raft.ServerAddress, q *WriteOptions) error { | ||
r := op.c.newRequest("DELETE", "/v1/operator/raft/peer") | ||
r.setWriteOptions(q) | ||
|
||
// TODO (slackpad) Currently we made address a query parameter. Once | ||
// IDs are in place this will be DELETE /v1/operator/raft/peer/<id>. | ||
r.params.Set("address", string(address)) | ||
|
||
_, resp, err := requireOK(op.c.doRequest(r)) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
resp.Body.Close() | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package api | ||
|
||
import ( | ||
"strings" | ||
"testing" | ||
) | ||
|
||
func TestOperator_RaftGetConfiguration(t *testing.T) { | ||
t.Parallel() | ||
c, s := makeClient(t) | ||
defer s.Stop() | ||
|
||
operator := c.Operator() | ||
out, err := operator.RaftGetConfiguration(nil) | ||
if err != nil { | ||
t.Fatalf("err: %v", err) | ||
} | ||
if len(out.Servers) != 1 || | ||
!out.Servers[0].Leader || | ||
!out.Servers[0].Voter { | ||
t.Fatalf("bad: %v", out) | ||
} | ||
} | ||
|
||
func TestOperator_RaftRemovePeerByAddress(t *testing.T) { | ||
t.Parallel() | ||
c, s := makeClient(t) | ||
defer s.Stop() | ||
|
||
// If we get this error, it proves we sent the address all the way | ||
// through. | ||
operator := c.Operator() | ||
err := operator.RaftRemovePeerByAddress("nope", nil) | ||
if err == nil || !strings.Contains(err.Error(), | ||
"address \"nope\" was not found in the Raft configuration") { | ||
t.Fatalf("err: %v", err) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.