Merge pull request #3499 from hashicorp/issue_3449

Move Raft protocol version for list peers end point to server side, f…
This commit is contained in:
preetapan 2017-09-26 11:57:11 -05:00 committed by GitHub
commit cb0d622b9f
5 changed files with 33 additions and 43 deletions

View File

@ -50,16 +50,19 @@ func (op *Operator) RaftGetConfiguration(args *structs.DCSpecificRequest, reply
reply.Index = future.Index() reply.Index = future.Index()
for _, server := range future.Configuration().Servers { for _, server := range future.Configuration().Servers {
node := "(unknown)" node := "(unknown)"
raftProtocolVersion := "unknown"
if member, ok := serverMap[server.Address]; ok { if member, ok := serverMap[server.Address]; ok {
node = member.Name node = member.Name
raftProtocolVersion = member.Tags["raft_vsn"]
} }
entry := &structs.RaftServer{ entry := &structs.RaftServer{
ID: server.ID, ID: server.ID,
Node: node, Node: node,
Address: server.Address, Address: server.Address,
Leader: server.Address == leader, Leader: server.Address == leader,
Voter: server.Suffrage == raft.Voter, Voter: server.Suffrage == raft.Voter,
ProtocolVersion: raftProtocolVersion,
} }
reply.Servers = append(reply.Servers, entry) reply.Servers = append(reply.Servers, entry)
} }

View File

@ -3,7 +3,6 @@ package consul
import ( import (
"fmt" "fmt"
"os" "os"
"reflect"
"strings" "strings"
"testing" "testing"
"time" "time"
@ -13,6 +12,7 @@ import (
"github.com/hashicorp/consul/testrpc" "github.com/hashicorp/consul/testrpc"
"github.com/hashicorp/net-rpc-msgpackrpc" "github.com/hashicorp/net-rpc-msgpackrpc"
"github.com/hashicorp/raft" "github.com/hashicorp/raft"
"github.com/pascaldekloe/goe/verify"
) )
func TestOperator_RaftGetConfiguration(t *testing.T) { func TestOperator_RaftGetConfiguration(t *testing.T) {
@ -44,18 +44,17 @@ func TestOperator_RaftGetConfiguration(t *testing.T) {
expected := structs.RaftConfigurationResponse{ expected := structs.RaftConfigurationResponse{
Servers: []*structs.RaftServer{ Servers: []*structs.RaftServer{
&structs.RaftServer{ &structs.RaftServer{
ID: me.ID, ID: me.ID,
Node: s1.config.NodeName, Node: s1.config.NodeName,
Address: me.Address, Address: me.Address,
Leader: true, Leader: true,
Voter: true, Voter: true,
ProtocolVersion: "3",
}, },
}, },
Index: future.Index(), Index: future.Index(),
} }
if !reflect.DeepEqual(reply, expected) { verify.Values(t, "", reply, expected)
t.Fatalf("bad: %v", reply)
}
} }
func TestOperator_RaftGetConfiguration_ACLDeny(t *testing.T) { func TestOperator_RaftGetConfiguration_ACLDeny(t *testing.T) {
@ -121,18 +120,17 @@ func TestOperator_RaftGetConfiguration_ACLDeny(t *testing.T) {
expected := structs.RaftConfigurationResponse{ expected := structs.RaftConfigurationResponse{
Servers: []*structs.RaftServer{ Servers: []*structs.RaftServer{
&structs.RaftServer{ &structs.RaftServer{
ID: me.ID, ID: me.ID,
Node: s1.config.NodeName, Node: s1.config.NodeName,
Address: me.Address, Address: me.Address,
Leader: true, Leader: true,
Voter: true, Voter: true,
ProtocolVersion: "3",
}, },
}, },
Index: future.Index(), Index: future.Index(),
} }
if !reflect.DeepEqual(reply, expected) { verify.Values(t, "", reply, expected)
t.Fatalf("bad: %v", reply)
}
} }
func TestOperator_RaftRemovePeerByAddress(t *testing.T) { func TestOperator_RaftRemovePeerByAddress(t *testing.T) {

View File

@ -61,6 +61,9 @@ type RaftServer struct {
// Leader is true if this server is the current cluster leader. // Leader is true if this server is the current cluster leader.
Leader bool Leader bool
// Protocol version is the raft protocol version used by the server
ProtocolVersion string
// Voter is true if this server has a vote in the cluster. This might // 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 // 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 // it's a non-voting server, which will be added in a future release of
@ -68,7 +71,7 @@ type RaftServer struct {
Voter bool Voter bool
} }
// RaftConfigrationResponse is returned when querying for the current Raft // RaftConfigurationResponse is returned when querying for the current Raft
// configuration. // configuration.
type RaftConfigurationResponse struct { type RaftConfigurationResponse struct {
// Servers has the list of servers in the Raft configuration. // Servers has the list of servers in the Raft configuration.

View File

@ -17,6 +17,9 @@ type RaftServer struct {
// Leader is true if this server is the current cluster leader. // Leader is true if this server is the current cluster leader.
Leader bool Leader bool
// Protocol version is the raft protocol version used by the server
ProtocolVersion string
// Voter is true if this server has a vote in the cluster. This might // 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 // 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 // it's a non-voting server, which will be added in a future release of
@ -24,7 +27,7 @@ type RaftServer struct {
Voter bool Voter bool
} }
// RaftConfigration is returned when querying for the current Raft configuration. // RaftConfiguration is returned when querying for the current Raft configuration.
type RaftConfiguration struct { type RaftConfiguration struct {
// Servers has the list of servers in the Raft configuration. // Servers has the list of servers in the Raft configuration.
Servers []*RaftServer Servers []*RaftServer

View File

@ -6,7 +6,6 @@ import (
"strings" "strings"
"github.com/hashicorp/consul/api" "github.com/hashicorp/consul/api"
"github.com/hashicorp/serf/serf"
"github.com/ryanuber/columnize" "github.com/ryanuber/columnize"
) )
@ -58,23 +57,6 @@ func (c *OperatorRaftListCommand) Run(args []string) int {
} }
func raftListPeers(client *api.Client, 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{ q := &api.QueryOptions{
AllowStale: stale, AllowStale: stale,
@ -87,7 +69,8 @@ func raftListPeers(client *api.Client, stale bool) (string, error) {
// Format it as a nice table. // Format it as a nice table.
result := []string{"Node|ID|Address|State|Voter|RaftProtocol"} result := []string{"Node|ID|Address|State|Voter|RaftProtocol"}
for _, s := range reply.Servers { for _, s := range reply.Servers {
raftProtocol := raftProtocols[s.Node] raftProtocol := s.ProtocolVersion
if raftProtocol == "" { if raftProtocol == "" {
raftProtocol = "<=1" raftProtocol = "<=1"
} }