Merge pull request #1947 from hashicorp/f-server-members-rpc

Add an RPC endpoint for server members
This commit is contained in:
Diptanu Choudhury
2016-11-07 14:11:19 -08:00
committed by GitHub
6 changed files with 79 additions and 16 deletions

View File

@@ -43,6 +43,7 @@ IMPROVEMENTS:
* driver/lxc: Support for LXC containers [GH-1699]
* driver/rkt: Support network configurations [GH-1862]
* driver/rkt: Support rkt volumes (rkt >= 1.0.0 required) [GH-1812]
* server/rpc: Added an RPC endpoint for retreiving server members [GH-1947]
BUG FIXES:
* core: Fix case where dead nodes were not properly handled by System

View File

@@ -131,8 +131,8 @@ func (a *Agent) Join(addrs ...string) (int, error) {
}
// Members is used to query all of the known server members
func (a *Agent) Members() ([]*AgentMember, error) {
var resp []*AgentMember
func (a *Agent) Members() (*ServerMembers, error) {
var resp *ServerMembers
// Query the known members
_, err := a.client.query("/v1/agent/members", &resp, nil)
@@ -217,6 +217,13 @@ type joinResponse struct {
Error string `json:"error"`
}
type ServerMembers struct {
ServerName string
Region string
DC string
Members []*AgentMember
}
// AgentMember represents a cluster member known to the agent
type AgentMember struct {
Name string

View File

@@ -88,17 +88,13 @@ func (s *HTTPServer) AgentMembersRequest(resp http.ResponseWriter, req *http.Req
if req.Method != "GET" {
return nil, CodedError(405, ErrInvalidMethod)
}
srv := s.agent.Server()
if srv == nil {
return nil, CodedError(501, ErrInvalidMethod)
args := &structs.GenericRequest{}
var out structs.ServerMembersResponse
if err := s.agent.RPC("Status.Members", args, &out); err != nil {
return nil, err
}
serfMembers := srv.Members()
members := make([]Member, len(serfMembers))
for i, mem := range serfMembers {
members[i] = nomadMember(mem)
}
return members, nil
return out, nil
}
func (s *HTTPServer) AgentForceLeaveRequest(resp http.ResponseWriter, req *http.Request) (interface{}, error) {

View File

@@ -64,17 +64,22 @@ func (c *ServerMembersCommand) Run(args []string) int {
}
// Query the members
mem, err := client.Agent().Members()
srvMembers, err := client.Agent().Members()
if err != nil {
c.Ui.Error(fmt.Sprintf("Error querying servers: %s", err))
return 1
}
if srvMembers == nil {
c.Ui.Error("Agent doesn't know about server members")
return 0
}
// Sort the members
sort.Sort(api.AgentMembersNameSort(mem))
sort.Sort(api.AgentMembersNameSort(srvMembers.Members))
// Determine the leaders per region.
leaders, err := regionLeaders(client, mem)
leaders, err := regionLeaders(client, srvMembers.Members)
if err != nil {
c.Ui.Error(fmt.Sprintf("Error determining leaders: %s", err))
return 1
@@ -83,9 +88,9 @@ func (c *ServerMembersCommand) Run(args []string) int {
// Format the list
var out []string
if detailed {
out = detailedOutput(mem)
out = detailedOutput(srvMembers.Members)
} else {
out = standardOutput(mem, leaders)
out = standardOutput(srvMembers.Members, leaders)
}
// Dump the list

View File

@@ -61,3 +61,32 @@ func (s *Status) Peers(args *structs.GenericRequest, reply *[]string) error {
*reply = peers
return nil
}
// Members return the list of servers in a cluster that a particular server is
// aware of
func (s *Status) Members(args *structs.GenericRequest, reply *structs.ServerMembersResponse) error {
serfMembers := s.srv.Members()
members := make([]*structs.ServerMember, len(serfMembers))
for i, mem := range serfMembers {
members[i] = &structs.ServerMember{
Name: mem.Name,
Addr: mem.Addr,
Port: mem.Port,
Tags: mem.Tags,
Status: mem.Status.String(),
ProtocolMin: mem.ProtocolMin,
ProtocolMax: mem.ProtocolMax,
ProtocolCur: mem.ProtocolCur,
DelegateMin: mem.DelegateMin,
DelegateMax: mem.DelegateMax,
DelegateCur: mem.DelegateCur,
}
}
*reply = structs.ServerMembersResponse{
ServerName: s.srv.config.NodeName,
ServerRegion: s.srv.config.Region,
ServerDC: s.srv.config.Datacenter,
Members: members,
}
return nil
}

View File

@@ -10,6 +10,7 @@ import (
"errors"
"fmt"
"io"
"net"
"os"
"path/filepath"
"reflect"
@@ -359,6 +360,30 @@ type PeriodicForceRequest struct {
WriteRequest
}
// ServerMembersResponse has the list of servers in a cluster
type ServerMembersResponse struct {
ServerName string
ServerRegion string
ServerDC string
Members []*ServerMember
QueryMeta
}
// ServerMember holds information about a Nomad server agent in a cluster
type ServerMember struct {
Name string
Addr net.IP
Port uint16
Tags map[string]string
Status string
ProtocolMin uint8
ProtocolMax uint8
ProtocolCur uint8
DelegateMin uint8
DelegateMax uint8
DelegateCur uint8
}
// DeriveVaultTokenRequest is used to request wrapped Vault tokens for the
// following tasks in the given allocation
type DeriveVaultTokenRequest struct {