mirror of
https://github.com/kemko/nomad.git
synced 2026-01-10 04:15:41 +03:00
Merge pull request #1947 from hashicorp/f-server-members-rpc
Add an RPC endpoint for server members
This commit is contained in:
@@ -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
|
||||
|
||||
11
api/agent.go
11
api/agent.go
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user