diff --git a/agent/agent.go b/agent/agent.go index d8ce397363..d1b0dd7fc1 100644 --- a/agent/agent.go +++ b/agent/agent.go @@ -58,6 +58,7 @@ type delegate interface { GetLANCoordinate() (lib.CoordinateSet, error) Leave() error LANMembers() []serf.Member + LANMembersAllSegments() ([]serf.Member, error) LANSegmentMembers(segment string) ([]serf.Member, error) LocalMember() serf.Member JoinLAN(addrs []string) (n int, err error) diff --git a/agent/agent_endpoint.go b/agent/agent_endpoint.go index 18b26df010..0fbf65c522 100644 --- a/agent/agent_endpoint.go +++ b/agent/agent_endpoint.go @@ -167,14 +167,12 @@ func (s *HTTPServer) AgentMembers(resp http.ResponseWriter, req *http.Request) ( if wan { members = s.agent.WANMembers() } else { - // If the segment is blank when querying a client, use the agent's - // segment instead of the empty string. - if !s.agent.config.Server && segment == "" { - segment = s.agent.config.Segment - } - var err error - members, err = s.agent.delegate.LANSegmentMembers(segment) + if segment == api.AllSegments { + members, err = s.agent.delegate.LANMembersAllSegments() + } else { + members, err = s.agent.delegate.LANSegmentMembers(segment) + } if err != nil { return nil, err } diff --git a/agent/consul/client.go b/agent/consul/client.go index 35badda4a6..87fe32e11a 100644 --- a/agent/consul/client.go +++ b/agent/consul/client.go @@ -201,6 +201,11 @@ func (c *Client) LANMembers() []serf.Member { return c.serf.Members() } +// LANMembersAllSegments returns members from all segments. +func (c *Client) LANMembersAllSegments() ([]serf.Member, error) { + return c.serf.Members(), nil +} + // LANSegmentMembers only returns our own segment's members, because clients // can't be in multiple segments. func (c *Client) LANSegmentMembers(segment string) ([]serf.Member, error) { diff --git a/agent/consul/segment_stub.go b/agent/consul/segment_stub.go index 7b2ed66174..9b89ecb795 100644 --- a/agent/consul/segment_stub.go +++ b/agent/consul/segment_stub.go @@ -9,6 +9,11 @@ import ( "github.com/hashicorp/serf/serf" ) +// LANMembersAllSegments returns members from all segments. +func (s *Server) LANMembersAllSegments() ([]serf.Member, error) { + return s.LANMembers(), nil +} + // LANSegmentMembers is used to return the members of the given LAN segment. func (s *Server) LANSegmentMembers(segment string) ([]serf.Member, error) { if segment == "" { diff --git a/api/agent.go b/api/agent.go index e46bb90434..ac57415c15 100644 --- a/api/agent.go +++ b/api/agent.go @@ -44,12 +44,16 @@ type AgentMember struct { DelegateCur uint8 } +// AllSegments is used to select for all segments in MembersOpts. +const AllSegments = "_all" + // MembersOpts is used for querying member information. type MembersOpts struct { // WAN is whether to show members from the WAN. WAN bool - // Segment is the LAN segment to show members. + // Segment is the LAN segment to show members for. Setting this to the + // AllSegments value above will show members in all segments. Segment string } diff --git a/command/members.go b/command/members.go index 0feac08a02..1e69c0dcf2 100644 --- a/command/members.go +++ b/command/members.go @@ -44,7 +44,7 @@ func (c *MembersCommand) Run(args []string) int { f.StringVar(&statusFilter, "status", ".*", "If provided, output is filtered to only nodes matching the regular "+ "expression for status.") - f.StringVar(&segment, "segment", "", + f.StringVar(&segment, "segment", consulapi.AllSegments, "(Enterprise-only) If provided, output is filtered to only nodes in"+ "the given segment.") @@ -65,32 +65,15 @@ func (c *MembersCommand) Run(args []string) int { return 1 } - // Check if we queried a server and need to query for members in all segments. - var members []*consulapi.AgentMember - if !wan && segment == "" { - self, err := client.Agent().Self() - if err != nil { - c.UI.Error(fmt.Sprintf("Error retrieving agent info: %s", err)) - return 1 - } - if self["Config"]["Server"].(bool) { - segmentMembers, err := getSegmentMembers(client) - if err != nil { - c.UI.Error(fmt.Sprintf("Error retrieving members in segments: %s", err)) - return 1 - } - members = segmentMembers - } - } else { - var err error - members, err = client.Agent().MembersOpts(consulapi.MembersOpts{ - WAN: wan, - Segment: segment, - }) - if err != nil { - c.UI.Error(fmt.Sprintf("Error retrieving members: %s", err)) - return 1 - } + // Make the request. + opts := consulapi.MembersOpts{ + Segment: segment, + WAN: wan, + } + members, err := client.Agent().MembersOpts(opts) + if err != nil { + c.UI.Error(fmt.Sprintf("Error retrieving members: %s", err)) + return 1 } // Filter the results @@ -99,9 +82,9 @@ func (c *MembersCommand) Run(args []string) int { member := members[i] if member.Tags["segment"] == "" { member.Tags["segment"] = "" - if member.Tags["role"] == "consul" { - member.Tags["segment"] = "" - } + } + if member.Tags["role"] == "consul" { + member.Tags["segment"] = "" } statusString := serf.MemberStatus(member.Status).String() if !statusRe.MatchString(statusString) { diff --git a/command/segment_stub.go b/command/segment_stub.go deleted file mode 100644 index bd5c5589a4..0000000000 --- a/command/segment_stub.go +++ /dev/null @@ -1,16 +0,0 @@ -// +build !ent - -package command - -import consulapi "github.com/hashicorp/consul/api" - -// getSegmentMembers returns an empty list since network segments are not -// supported in OSS Consul. -func getSegmentMembers(client *consulapi.Client) ([]*consulapi.AgentMember, error) { - members, err := client.Agent().MembersOpts(consulapi.MembersOpts{}) - if err != nil { - return nil, err - } - - return members, nil -} diff --git a/website/source/api/agent.html.md b/website/source/api/agent.html.md index 7cf0ad3aae..1993e1caed 100644 --- a/website/source/api/agent.html.md +++ b/website/source/api/agent.html.md @@ -44,9 +44,11 @@ The table below shows this endpoint's support for members (which is the default). This is only eligible for agents running in **server mode**. This is specified as part of the URL as a query parameter. -- `segment` `(string: "")` - (Enterprise-only) Specifies the segment to list members in. If left blank, -this will query for the default segment when connecting to a server and the agent's -own segment when connecting to a client (clients can only be part of one network segment). +- `segment` `(string: "")` - (Enterprise-only) Specifies the segment to list members for. + If left blank, this will query for the default segment when connecting to a server and + the agent's own segment when connecting to a client (clients can only be part of one + network segment). When querying a server, setting this to the special string `_all` + will show members in all segments. ### Sample Request