From b57a7507393ba1b58adb00c8c6415cd024e84aae Mon Sep 17 00:00:00 2001 From: Diptanu Choudhury Date: Thu, 3 Nov 2016 14:14:52 -0700 Subject: [PATCH 1/3] Add an RPC endpoint for server members --- command/agent/agent_endpoint.go | 15 ++++++--------- nomad/status_endpoint.go | 30 ++++++++++++++++++++++++++++++ nomad/structs/structs.go | 30 ++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 9 deletions(-) diff --git a/command/agent/agent_endpoint.go b/command/agent/agent_endpoint.go index e22afcd4f36c..9e240956bd46 100644 --- a/command/agent/agent_endpoint.go +++ b/command/agent/agent_endpoint.go @@ -88,17 +88,14 @@ 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 + s.logger.Printf("DIPTANU 111 %#v", out) + return out, nil } func (s *HTTPServer) AgentForceLeaveRequest(resp http.ResponseWriter, req *http.Request) (interface{}, error) { diff --git a/nomad/status_endpoint.go b/nomad/status_endpoint.go index aaddb2201370..a978332355c5 100644 --- a/nomad/status_endpoint.go +++ b/nomad/status_endpoint.go @@ -61,3 +61,33 @@ 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, + } + s.srv.logger.Printf("DIPTANU %#v", reply) + return nil +} diff --git a/nomad/structs/structs.go b/nomad/structs/structs.go index c39dbd1a7710..c3ac670c1015 100644 --- a/nomad/structs/structs.go +++ b/nomad/structs/structs.go @@ -10,6 +10,7 @@ import ( "errors" "fmt" "io" + "net" "os" "path/filepath" "reflect" @@ -359,6 +360,35 @@ type PeriodicForceRequest struct { WriteRequest } +// ServerMembersRequest is used to query the list of peers for a given server +type ServerMembersRequest struct { + QueryOptions +} + +// 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 { From f766f71500c459b460c5850049a3dc68a6e7cbf0 Mon Sep 17 00:00:00 2001 From: Diptanu Choudhury Date: Sun, 6 Nov 2016 10:29:09 -0800 Subject: [PATCH 2/3] Changing the API to use the new servermember datastructure --- api/agent.go | 11 +++++++++-- command/agent/agent_endpoint.go | 1 - command/server_members.go | 15 ++++++++++----- nomad/status_endpoint.go | 3 +-- nomad/structs/structs.go | 5 ----- 5 files changed, 20 insertions(+), 15 deletions(-) diff --git a/api/agent.go b/api/agent.go index 054d0c343a57..81c6e0e06d29 100644 --- a/api/agent.go +++ b/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 diff --git a/command/agent/agent_endpoint.go b/command/agent/agent_endpoint.go index 9e240956bd46..2ca5c43d9674 100644 --- a/command/agent/agent_endpoint.go +++ b/command/agent/agent_endpoint.go @@ -94,7 +94,6 @@ func (s *HTTPServer) AgentMembersRequest(resp http.ResponseWriter, req *http.Req return nil, err } - s.logger.Printf("DIPTANU 111 %#v", out) return out, nil } diff --git a/command/server_members.go b/command/server_members.go index e8340920d77b..378be3a6e00a 100644 --- a/command/server_members.go +++ b/command/server_members.go @@ -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 diff --git a/nomad/status_endpoint.go b/nomad/status_endpoint.go index a978332355c5..cdd871841c34 100644 --- a/nomad/status_endpoint.go +++ b/nomad/status_endpoint.go @@ -82,12 +82,11 @@ func (s *Status) Members(args *structs.GenericRequest, reply *structs.ServerMemb DelegateCur: mem.DelegateCur, } } - reply = &structs.ServerMembersResponse{ + *reply = structs.ServerMembersResponse{ ServerName: s.srv.config.NodeName, ServerRegion: s.srv.config.Region, ServerDC: s.srv.config.Datacenter, Members: members, } - s.srv.logger.Printf("DIPTANU %#v", reply) return nil } diff --git a/nomad/structs/structs.go b/nomad/structs/structs.go index c3ac670c1015..a2da811b8c51 100644 --- a/nomad/structs/structs.go +++ b/nomad/structs/structs.go @@ -360,11 +360,6 @@ type PeriodicForceRequest struct { WriteRequest } -// ServerMembersRequest is used to query the list of peers for a given server -type ServerMembersRequest struct { - QueryOptions -} - // ServerMembersResponse has the list of servers in a cluster type ServerMembersResponse struct { ServerName string From af4f984f97fe69ca9d923b7aaa81347f1116617a Mon Sep 17 00:00:00 2001 From: Diptanu Choudhury Date: Mon, 7 Nov 2016 14:10:57 -0800 Subject: [PATCH 3/3] Updated changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 525f714f262b..2ad7c7412617 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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