Merge pull request #935 from hashicorp/f-server-members-leader
cli: server-members displays leader per region
This commit is contained in:
commit
a94bf31577
|
@ -20,6 +20,17 @@ func (s *Status) Leader() (string, error) {
|
|||
return resp, nil
|
||||
}
|
||||
|
||||
// RegionLeader is used to query for the leader in the passed region.
|
||||
func (s *Status) RegionLeader(region string) (string, error) {
|
||||
var resp string
|
||||
q := QueryOptions{Region: region}
|
||||
_, err := s.client.query("/v1/status/leader", &resp, &q)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// Peers is used to query the addresses of the server peers
|
||||
// in the cluster.
|
||||
func (s *Status) Peers() ([]string, error) {
|
||||
|
|
|
@ -72,12 +72,19 @@ func (c *ServerMembersCommand) Run(args []string) int {
|
|||
// Sort the members
|
||||
sort.Sort(api.AgentMembersNameSort(mem))
|
||||
|
||||
// Determine the leaders per region.
|
||||
leaders, err := regionLeaders(client, mem)
|
||||
if err != nil && !strings.Contains(err.Error(), "No cluster leader") {
|
||||
c.Ui.Error(fmt.Sprintf("Error determining leaders: %s", err))
|
||||
return 1
|
||||
}
|
||||
|
||||
// Format the list
|
||||
var out []string
|
||||
if detailed {
|
||||
out = detailedOutput(mem)
|
||||
} else {
|
||||
out = standardOutput(mem)
|
||||
out = standardOutput(mem, leaders)
|
||||
}
|
||||
|
||||
// Dump the list
|
||||
|
@ -85,16 +92,27 @@ func (c *ServerMembersCommand) Run(args []string) int {
|
|||
return 0
|
||||
}
|
||||
|
||||
func standardOutput(mem []*api.AgentMember) []string {
|
||||
func standardOutput(mem []*api.AgentMember, leaders map[string]string) []string {
|
||||
// Format the members list
|
||||
members := make([]string, len(mem)+1)
|
||||
members[0] = "Name|Address|Port|Status|Protocol|Build|Datacenter|Region"
|
||||
members[0] = "Name|Address|Port|Status|Leader|Protocol|Build|Datacenter|Region"
|
||||
for i, member := range mem {
|
||||
members[i+1] = fmt.Sprintf("%s|%s|%d|%s|%d|%s|%s|%s",
|
||||
reg := member.Tags["region"]
|
||||
regLeader, ok := leaders[reg]
|
||||
isLeader := false
|
||||
if ok {
|
||||
if regLeader == fmt.Sprintf("%s:%s", member.Addr, member.Tags["port"]) {
|
||||
|
||||
isLeader = true
|
||||
}
|
||||
}
|
||||
|
||||
members[i+1] = fmt.Sprintf("%s|%s|%d|%s|%t|%d|%s|%s|%s",
|
||||
member.Name,
|
||||
member.Addr,
|
||||
member.Port,
|
||||
member.Status,
|
||||
isLeader,
|
||||
member.ProtocolCur,
|
||||
member.Tags["build"],
|
||||
member.Tags["dc"],
|
||||
|
@ -123,3 +141,29 @@ func detailedOutput(mem []*api.AgentMember) []string {
|
|||
}
|
||||
return members
|
||||
}
|
||||
|
||||
// regionLeaders returns a map of regions to the IP of the member that is the
|
||||
// leader.
|
||||
func regionLeaders(client *api.Client, mem []*api.AgentMember) (map[string]string, error) {
|
||||
// Determine the unique regions.
|
||||
leaders := make(map[string]string)
|
||||
regions := make(map[string]struct{})
|
||||
for _, m := range mem {
|
||||
regions[m.Tags["region"]] = struct{}{}
|
||||
}
|
||||
|
||||
if len(regions) == 0 {
|
||||
return leaders, nil
|
||||
}
|
||||
|
||||
status := client.Status()
|
||||
for reg := range regions {
|
||||
l, err := status.RegionLeader(reg)
|
||||
if err != nil {
|
||||
return leaders, err
|
||||
}
|
||||
leaders[reg] = l
|
||||
}
|
||||
|
||||
return leaders, nil
|
||||
}
|
||||
|
|
|
@ -591,7 +591,7 @@ func (s *Server) setupWorkers() error {
|
|||
}
|
||||
|
||||
// numOtherPeers is used to check on the number of known peers
|
||||
// excluding the local ndoe
|
||||
// excluding the local node
|
||||
func (s *Server) numOtherPeers() (int, error) {
|
||||
peers, err := s.raftPeers.Peers()
|
||||
if err != nil {
|
||||
|
|
Loading…
Reference in a new issue