agent: Support server-side filtering of passing checks. Fixes #57.
This commit is contained in:
parent
cb33d73ffe
commit
d6b7dd5b62
|
@ -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]
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
Loading…
Reference in New Issue