Backport of member cli: add -filter expression to flags into release/1.16.x (#18276)
* backport of commit fe571c6c3e88e828e68172c1eb22b338e614635b * backport of commit 779901b6cd428e1b5116a9fe33ff5f88ce27e88b * backport of commit adfa76146adabd4a6ed54f067e6e3e886d5c198f --------- Co-authored-by: cskh <hui.kang@hashicorp.com>
This commit is contained in:
parent
a3c124ce4a
commit
74e6e8f66a
|
@ -0,0 +1,3 @@
|
|||
```release-note:feature
|
||||
cli: `consul members` command uses `-filter` expression to filter members based on bexpr.
|
||||
```
|
|
@ -621,6 +621,21 @@ func (s *HTTPHandlers) AgentMembers(resp http.ResponseWriter, req *http.Request)
|
|||
}
|
||||
}
|
||||
|
||||
// filter the members by parsed filter expression
|
||||
var filterExpression string
|
||||
s.parseFilter(req, &filterExpression)
|
||||
if filterExpression != "" {
|
||||
filter, err := bexpr.CreateFilter(filterExpression, nil, members)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
raw, err := filter.Execute(members)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
members = raw.([]serf.Member)
|
||||
}
|
||||
|
||||
total := len(members)
|
||||
if err := s.agent.filterMembers(token, &members); err != nil {
|
||||
return nil, err
|
||||
|
|
|
@ -274,6 +274,8 @@ type MembersOpts struct {
|
|||
// Segment is the LAN segment to show members for. Setting this to the
|
||||
// AllSegments value above will show members in all segments.
|
||||
Segment string
|
||||
|
||||
Filter string
|
||||
}
|
||||
|
||||
// AgentServiceRegistration is used to register a new service
|
||||
|
@ -790,6 +792,10 @@ func (a *Agent) MembersOpts(opts MembersOpts) ([]*AgentMember, error) {
|
|||
r.params.Set("wan", "1")
|
||||
}
|
||||
|
||||
if opts.Filter != "" {
|
||||
r.params.Set("filter", opts.Filter)
|
||||
}
|
||||
|
||||
_, resp, err := a.c.doRequest(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
@ -155,6 +155,16 @@ func TestAPI_AgentMembersOpts(t *testing.T) {
|
|||
if len(members) != 2 {
|
||||
t.Fatalf("bad: %v", members)
|
||||
}
|
||||
|
||||
members, err = agent.MembersOpts(MembersOpts{
|
||||
WAN: true,
|
||||
Filter: `Tags["dc"] == dc2`,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
require.Equal(t, 1, len(members))
|
||||
}
|
||||
|
||||
func TestAPI_AgentMembers(t *testing.T) {
|
||||
|
|
|
@ -33,6 +33,7 @@ type cmd struct {
|
|||
wan bool
|
||||
statusFilter string
|
||||
segment string
|
||||
filter string
|
||||
}
|
||||
|
||||
func New(ui cli.Ui) *cmd {
|
||||
|
@ -54,6 +55,7 @@ func (c *cmd) init() {
|
|||
c.flags.StringVar(&c.segment, "segment", consulapi.AllSegments,
|
||||
"(Enterprise-only) If provided, output is filtered to only nodes in"+
|
||||
"the given segment.")
|
||||
c.flags.StringVar(&c.filter, "filter", "", "Filter to use with the request")
|
||||
|
||||
c.http = &flags.HTTPFlags{}
|
||||
flags.Merge(c.flags, c.http.ClientFlags())
|
||||
|
@ -83,6 +85,7 @@ func (c *cmd) Run(args []string) int {
|
|||
opts := consulapi.MembersOpts{
|
||||
Segment: c.segment,
|
||||
WAN: c.wan,
|
||||
Filter: c.filter,
|
||||
}
|
||||
members, err := client.Agent().MembersOpts(opts)
|
||||
if err != nil {
|
||||
|
|
|
@ -48,6 +48,12 @@ Usage: `consul members [options]`
|
|||
in the WAN gossip pool. These are generally all the server nodes in
|
||||
each datacenter.
|
||||
|
||||
- `-filter=<filter>` - Expression to use for filtering the results,
|
||||
e.g., `-filter='Tags["dc"] == dc2'`.
|
||||
See the [`/catalog/nodes` API documentation](/consul/api-docs/catalog#filtering) for a
|
||||
description of what is filterable.
|
||||
|
||||
|
||||
#### Enterprise Options
|
||||
|
||||
@include 'http_api_partition_options.mdx'
|
||||
|
|
Loading…
Reference in New Issue