From d4a3c5d3685a524ecbd9e7ecbb577031ceb27cfe Mon Sep 17 00:00:00 2001 From: cskh Date: Thu, 22 Jun 2023 09:53:22 -0400 Subject: [PATCH] Use -filter to filter services in checks --- agent/health_endpoint.go | 24 ------------------------ api/health.go | 22 ---------------------- api/watch/funcs.go | 19 +++++++++---------- api/watch/funcs_test.go | 28 ++-------------------------- command/watch/watch.go | 5 +++++ 5 files changed, 16 insertions(+), 82 deletions(-) diff --git a/agent/health_endpoint.go b/agent/health_endpoint.go index 2ba9bea4dbb4d..ef51029f25b0e 100644 --- a/agent/health_endpoint.go +++ b/agent/health_endpoint.go @@ -38,18 +38,6 @@ func (s *HTTPHandlers) HealthChecksInState(resp http.ResponseWriter, req *http.R return nil, HTTPError{StatusCode: http.StatusBadRequest, Reason: "Missing check state"} } - // build tag filter - params := req.URL.Query() - if tags, ok := params["tag"]; ok { - for i, tag := range tags { - expr := fmt.Sprintf(`%s in ServiceTags`, tag) - if i < len(tags)-1 { - expr += " and " - } - args.Filter += expr - } - } - // Make the RPC request var out structs.IndexedHealthChecks defer setMeta(resp, &out.QueryMeta) @@ -140,18 +128,6 @@ func (s *HTTPHandlers) HealthServiceChecks(resp http.ResponseWriter, req *http.R return nil, HTTPError{StatusCode: http.StatusBadRequest, Reason: "Missing service name"} } - // build tag filter - params := req.URL.Query() - if tags, ok := params["tag"]; ok { - for i, tag := range tags { - expr := fmt.Sprintf(`%s in ServiceTags`, tag) - if i < len(tags)-1 { - expr += " and " - } - args.Filter += expr - } - } - // Make the RPC request var out structs.IndexedHealthChecks defer setMeta(resp, &out.QueryMeta) diff --git a/api/health.go b/api/health.go index 480f492f494be..345edb2500d04 100644 --- a/api/health.go +++ b/api/health.go @@ -261,17 +261,7 @@ func (h *Health) Node(node string, q *QueryOptions) (HealthChecks, *QueryMeta, e // Checks is used to return the checks associated with a service func (h *Health) Checks(service string, q *QueryOptions) (HealthChecks, *QueryMeta, error) { - return h.ChecksTags(service, nil, q) -} - -// ChecksTags is used to return the checks associated with a service filtered by tags -func (h *Health) ChecksTags(service string, tags []string, q *QueryOptions) (HealthChecks, *QueryMeta, error) { r := h.c.newRequest("GET", "/v1/health/checks/"+service) - if len(tags) > 0 { - for _, tag := range tags { - r.params.Add("tag", tag) - } - } r.setQueryOptions(q) rtt, resp, err := h.c.doRequest(r) if err != nil { @@ -376,12 +366,6 @@ func (h *Health) service(service string, tags []string, passingOnly bool, q *Que // State is used to retrieve all the checks in a given state. // The wildcard "any" state can also be used for all checks. func (h *Health) State(state string, q *QueryOptions) (HealthChecks, *QueryMeta, error) { - return h.StateTags(state, nil, q) -} - -// StateTags is used to retrieve all the checks in a given state and tags. -// The wildcard "any" state can also be used for all checks. -func (h *Health) StateTags(state string, tags []string, q *QueryOptions) (HealthChecks, *QueryMeta, error) { switch state { case HealthAny: case HealthWarning: @@ -393,12 +377,6 @@ func (h *Health) StateTags(state string, tags []string, q *QueryOptions) (Health r := h.c.newRequest("GET", "/v1/health/state/"+state) r.setQueryOptions(q) - if len(tags) > 0 { - for _, tag := range tags { - r.params.Add("tag", tag) - } - } - rtt, resp, err := h.c.doRequest(r) if err != nil { return nil, nil, err diff --git a/api/watch/funcs.go b/api/watch/funcs.go index 33e3223d5f557..69d162390a626 100644 --- a/api/watch/funcs.go +++ b/api/watch/funcs.go @@ -175,13 +175,16 @@ func checksWatch(params map[string]interface{}) (WatcherFunc, error) { return nil, err } - var service, state string + var service, state, filter string if err := assignValue(params, "service", &service); err != nil { return nil, err } if err := assignValue(params, "state", &state); err != nil { return nil, err } + if err := assignValue(params, "filter", &filter); err != nil { + return nil, err + } if service != "" && state != "" { return nil, fmt.Errorf("Cannot specify service and state") } @@ -189,13 +192,6 @@ func checksWatch(params map[string]interface{}) (WatcherFunc, error) { state = "any" } - var ( - tags []string - ) - if err := assignValueStringSlice(params, "tag", &tags); err != nil { - return nil, err - } - fn := func(p *Plan) (BlockingParamVal, interface{}, error) { health := p.client.Health() opts := makeQueryOptionsWithContext(p, stale) @@ -203,10 +199,13 @@ func checksWatch(params map[string]interface{}) (WatcherFunc, error) { var checks []*consulapi.HealthCheck var meta *consulapi.QueryMeta var err error + if filter != "" { + opts.Filter = filter + } if state != "" { - checks, meta, err = health.StateTags(state, tags, &opts) + checks, meta, err = health.State(state, &opts) } else { - checks, meta, err = health.ChecksTags(service, tags, &opts) + checks, meta, err = health.Checks(service, &opts) } if err != nil { return nil, nil, err diff --git a/api/watch/funcs_test.go b/api/watch/funcs_test.go index d3562397c79b6..fef20154237c2 100644 --- a/api/watch/funcs_test.go +++ b/api/watch/funcs_test.go @@ -784,7 +784,7 @@ func TestChecksWatch_Service_Tag(t *testing.T) { notifyCh = make(chan struct{}) ) - plan := mustParse(t, `{"type":"checks", "service":"foobar", "tag":["b", "a"]}`) + plan := mustParse(t, `{"type":"checks", "filter":"b in ServiceTags and a in ServiceTags"}`) plan.Handler = func(idx uint64, raw interface{}) { if raw == nil { return // ignore @@ -811,8 +811,6 @@ func TestChecksWatch_Service_Tag(t *testing.T) { <-notifyCh { catalog := c.Catalog() - - // we want to find this one reg := &api.CatalogRegistration{ Node: "foobar", Address: "1.1.1.1", @@ -833,28 +831,6 @@ func TestChecksWatch_Service_Tag(t *testing.T) { if _, err := catalog.Register(reg, nil); err != nil { t.Fatalf("err: %v", err) } - - // we don't want to find this one - reg = &api.CatalogRegistration{ - Node: "bar", - Address: "2.2.2.2", - Datacenter: "dc1", - Service: &api.AgentService{ - ID: "foobar", - Service: "foobar", - Tags: []string{"a"}, - }, - Check: &api.AgentCheck{ - Node: "bar", - CheckID: "foobar", - Name: "foobar", - Status: api.HealthPassing, - ServiceID: "foobar", - }, - } - if _, err := catalog.Register(reg, nil); err != nil { - t.Fatalf("err: %v", err) - } } // Wait for second wakeup. @@ -888,7 +864,7 @@ func TestChecksWatch_Tag(t *testing.T) { notifyCh = make(chan struct{}) ) - plan := mustParse(t, `{"type":"checks", "tag":["b", "a"]}`) + plan := mustParse(t, `{"type":"checks", "filter":"b in ServiceTags and a in ServiceTags"}`) plan.Handler = func(idx uint64, raw interface{}) { if raw == nil { return // ignore diff --git a/command/watch/watch.go b/command/watch/watch.go index 791f93a57cd4c..b187fa369ab44 100644 --- a/command/watch/watch.go +++ b/command/watch/watch.go @@ -45,6 +45,7 @@ type cmd struct { state string name string shell bool + filter string } func (c *cmd) init() { @@ -71,6 +72,7 @@ func (c *cmd) init() { "Specifies the states to watch. Optional for 'checks' type.") c.flags.StringVar(&c.name, "name", "", "Specifies an event name to watch. Only for 'event' type.") + c.flags.StringVar(&c.filter, "filter", "", "Filter to use with the request") c.http = &flags.HTTPFlags{} flags.Merge(c.flags, c.http.ClientFlags()) @@ -128,6 +130,9 @@ func (c *cmd) Run(args []string) int { if c.service != "" { params["service"] = c.service } + if c.filter != "" { + params["filter"] = c.filter + } if len(c.tag) > 0 { params["tag"] = c.tag }