agent: Support server-side filtering of passing checks. Fixes #57.

This commit is contained in:
Armon Dadgar 2014-04-21 16:08:26 -07:00
parent 57a45ead6b
commit 81a0a56fac
3 changed files with 70 additions and 0 deletions

View File

@ -106,5 +106,26 @@ func (s *HTTPServer) HealthServiceNodes(resp http.ResponseWriter, req *http.Requ
if err := s.agent.RPC("Health.ServiceNodes", &args, &out); err != nil {
return nil, err
}
// Filter to only passing if specified
if _, ok := params["passing"]; ok {
out.Nodes = filterNonPassing(out.Nodes)
}
return out.Nodes, nil
}
// filterNonPassing is used to filter out any nodes that have check that are not passing
func filterNonPassing(nodes structs.CheckServiceNodes) structs.CheckServiceNodes {
n := len(nodes)
for i := 0; i < n; i++ {
node := nodes[i]
for _, check := range node.Checks {
if check.Status != structs.HealthPassing {
nodes[i], nodes[n-1] = nodes[n-1], structs.CheckServiceNode{}
n--
i--
}
}
}
return nodes[:n]
}

View File

@ -138,3 +138,48 @@ func TestHealthServiceNodes(t *testing.T) {
t.Fatalf("bad: %v", obj)
}
}
func TestHealthServiceNodes_PassingFilter(t *testing.T) {
dir, srv := makeHTTPServer(t)
defer os.RemoveAll(dir)
defer srv.Shutdown()
defer srv.agent.Shutdown()
// Wait for a leader
time.Sleep(100 * time.Millisecond)
// Create a failing service check
args := &structs.RegisterRequest{
Datacenter: "dc1",
Node: srv.agent.config.NodeName,
Address: "127.0.0.1",
Check: &structs.HealthCheck{
Node: srv.agent.config.NodeName,
Name: "consul check",
ServiceID: "consul",
Status: structs.HealthCritical,
},
}
var out struct{}
if err := srv.agent.RPC("Catalog.Register", args, &out); err != nil {
t.Fatalf("err: %v", err)
}
req, err := http.NewRequest("GET", "/v1/health/service/consul?passing", nil)
if err != nil {
t.Fatalf("err: %v", err)
}
resp := httptest.NewRecorder()
obj, err := srv.HealthServiceNodes(resp, req)
if err != nil {
t.Fatalf("err: %v", err)
}
assertIndex(t, resp)
// Should be 0 health check for consul
nodes := obj.(structs.CheckServiceNodes)
if len(nodes) != 0 {
t.Fatalf("bad: %v", obj)
}
}

View File

@ -681,6 +681,10 @@ endpoint automatically returns the status of the associated health check,
as well as any system level health checks. This allows a client to avoid
sending traffic to nodes failing health tests, or who are reporting warnings.
Providing the "?passing" query parameter will filter results to only nodes
with all checks in the passing state. This can be used to avoid some filtering
logic on the client side. (Added in Consul 0.2)
Users can also built in support for dynamic load balancing and other features
by incorporating the use of health checks.