Show raft protocol in list-peers command (#2929)
This commit is contained in:
parent
1bbe835707
commit
72ee7c2501
|
@ -77,17 +77,16 @@ func (c *OperatorRaftCommand) raft(args []string) error {
|
|||
if err != nil {
|
||||
return fmt.Errorf("error connecting to Consul agent: %s", err)
|
||||
}
|
||||
operator := client.Operator()
|
||||
|
||||
// Dispatch based on the verb argument.
|
||||
if listPeers {
|
||||
result, err := raftListPeers(operator, c.Command.HTTPStale())
|
||||
result, err := raftListPeers(client, c.Command.HTTPStale())
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error getting peers: %v", err))
|
||||
}
|
||||
c.Ui.Output(result)
|
||||
} else if removePeer {
|
||||
if err := raftRemovePeers(address, "", operator); err != nil {
|
||||
if err := raftRemovePeers(address, "", client.Operator()); err != nil {
|
||||
return fmt.Errorf("Error removing peer: %v", err)
|
||||
}
|
||||
c.Ui.Output(fmt.Sprintf("Removed peer with address %q", address))
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
|
||||
"github.com/hashicorp/consul/api"
|
||||
"github.com/hashicorp/consul/command/base"
|
||||
"github.com/hashicorp/serf/serf"
|
||||
"github.com/ryanuber/columnize"
|
||||
)
|
||||
|
||||
|
@ -48,7 +49,7 @@ func (c *OperatorRaftListCommand) Run(args []string) int {
|
|||
}
|
||||
|
||||
// Fetch the current configuration.
|
||||
result, err := raftListPeers(client.Operator(), c.Command.HTTPStale())
|
||||
result, err := raftListPeers(client, c.Command.HTTPStale())
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error getting peers: %v", err))
|
||||
}
|
||||
|
@ -57,24 +58,46 @@ func (c *OperatorRaftListCommand) Run(args []string) int {
|
|||
return 0
|
||||
}
|
||||
|
||||
func raftListPeers(operator *api.Operator, stale bool) (string, error) {
|
||||
func raftListPeers(client *api.Client, stale bool) (string, error) {
|
||||
raftProtocols := make(map[string]string)
|
||||
members, err := client.Agent().Members(false)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
for _, member := range members {
|
||||
if serf.MemberStatus(member.Status) == serf.StatusLeft {
|
||||
continue
|
||||
}
|
||||
|
||||
if member.Tags["role"] != "consul" {
|
||||
continue
|
||||
}
|
||||
|
||||
raftProtocols[member.Name] = member.Tags["raft_vsn"]
|
||||
}
|
||||
|
||||
q := &api.QueryOptions{
|
||||
AllowStale: stale,
|
||||
}
|
||||
reply, err := operator.RaftGetConfiguration(q)
|
||||
reply, err := client.Operator().RaftGetConfiguration(q)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Failed to retrieve raft configuration: %v", err)
|
||||
}
|
||||
|
||||
// Format it as a nice table.
|
||||
result := []string{"Node|ID|Address|State|Voter"}
|
||||
result := []string{"Node|ID|Address|State|Voter|RaftProtocol"}
|
||||
for _, s := range reply.Servers {
|
||||
raftProtocol := raftProtocols[s.Node]
|
||||
if raftProtocol == "" {
|
||||
raftProtocol = "<=1"
|
||||
}
|
||||
state := "follower"
|
||||
if s.Leader {
|
||||
state = "leader"
|
||||
}
|
||||
result = append(result, fmt.Sprintf("%s|%s|%s|%s|%v",
|
||||
s.Node, s.ID, s.Address, state, s.Voter))
|
||||
result = append(result, fmt.Sprintf("%s|%s|%s|%s|%v|%s",
|
||||
s.Node, s.ID, s.Address, state, s.Voter, raftProtocol))
|
||||
}
|
||||
|
||||
return columnize.SimpleFormat(result), nil
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package command
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
|
@ -17,6 +18,9 @@ func TestOperator_Raft_ListPeers(t *testing.T) {
|
|||
defer a1.Shutdown()
|
||||
waitForLeader(t, a1.httpAddr)
|
||||
|
||||
expected := fmt.Sprintf("%s 127.0.0.1:%d 127.0.0.1:%d leader true 2",
|
||||
a1.config.NodeName, a1.config.Ports.Server, a1.config.Ports.Server)
|
||||
|
||||
// Test the legacy mode with 'consul operator raft -list-peers'
|
||||
{
|
||||
ui, c := testOperatorRaftCommand(t)
|
||||
|
@ -27,8 +31,8 @@ func TestOperator_Raft_ListPeers(t *testing.T) {
|
|||
t.Fatalf("bad: %d. %#v", code, ui.ErrorWriter.String())
|
||||
}
|
||||
output := strings.TrimSpace(ui.OutputWriter.String())
|
||||
if !strings.Contains(output, "leader") {
|
||||
t.Fatalf("bad: %s", output)
|
||||
if !strings.Contains(output, expected) {
|
||||
t.Fatalf("bad: %q, %q", output, expected)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,8 +52,8 @@ func TestOperator_Raft_ListPeers(t *testing.T) {
|
|||
t.Fatalf("bad: %d. %#v", code, ui.ErrorWriter.String())
|
||||
}
|
||||
output := strings.TrimSpace(ui.OutputWriter.String())
|
||||
if !strings.Contains(output, "leader") {
|
||||
t.Fatalf("bad: %s", output)
|
||||
if !strings.Contains(output, expected) {
|
||||
t.Fatalf("bad: %q, %q", output, expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,10 +40,10 @@ to set this to "true" to get the configuration from a non-leader server.
|
|||
The output looks like this:
|
||||
|
||||
```
|
||||
Node ID Address State Voter
|
||||
alice 127.0.0.1:8300 127.0.0.1:8300 follower true
|
||||
bob 127.0.0.2:8300 127.0.0.2:8300 leader true
|
||||
carol 127.0.0.3:8300 127.0.0.3:8300 follower true
|
||||
Node ID Address State Voter RaftProtocol
|
||||
alice 127.0.0.1:8300 127.0.0.1:8300 follower true 2
|
||||
bob 127.0.0.2:8300 127.0.0.2:8300 leader true 3
|
||||
carol 127.0.0.3:8300 127.0.0.3:8300 follower true 2
|
||||
```
|
||||
|
||||
`Node` is the node name of the server, as known to Consul, or "(unknown)" if
|
||||
|
|
Loading…
Reference in New Issue