First pass at health endpoints
This commit is contained in:
parent
80d9899aec
commit
a03a92cf3d
|
@ -0,0 +1,125 @@
|
||||||
|
package agent
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/hashicorp/consul/consul/structs"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s *HTTPServer) HealthChecksInState(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
|
||||||
|
// Set default DC
|
||||||
|
args := structs.ChecksInStateRequest{
|
||||||
|
Datacenter: s.agent.config.Datacenter,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for other DC
|
||||||
|
params := req.URL.Query()
|
||||||
|
if other := params.Get("dc"); other != "" {
|
||||||
|
args.Datacenter = other
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pull out the service name
|
||||||
|
args.State = strings.TrimPrefix(req.URL.Path, "/v1/health/state/")
|
||||||
|
if args.State == "" {
|
||||||
|
resp.WriteHeader(400)
|
||||||
|
resp.Write([]byte("Missing check state"))
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make the RPC request
|
||||||
|
var out structs.HealthChecks
|
||||||
|
if err := s.agent.RPC("Health.ChecksInState", &args, &out); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *HTTPServer) HealthNodeChecks(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
|
||||||
|
// Set default DC
|
||||||
|
args := structs.NodeSpecificRequest{
|
||||||
|
Datacenter: s.agent.config.Datacenter,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for other DC
|
||||||
|
params := req.URL.Query()
|
||||||
|
if other := params.Get("dc"); other != "" {
|
||||||
|
args.Datacenter = other
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pull out the service name
|
||||||
|
args.Node = strings.TrimPrefix(req.URL.Path, "/v1/health/node/")
|
||||||
|
if args.Node == "" {
|
||||||
|
resp.WriteHeader(400)
|
||||||
|
resp.Write([]byte("Missing node name"))
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make the RPC request
|
||||||
|
var out structs.HealthChecks
|
||||||
|
if err := s.agent.RPC("Health.NodeChecks", &args, &out); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *HTTPServer) HealthServiceChecks(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
|
||||||
|
// Set default DC
|
||||||
|
args := structs.ServiceSpecificRequest{
|
||||||
|
Datacenter: s.agent.config.Datacenter,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for other DC
|
||||||
|
params := req.URL.Query()
|
||||||
|
if other := params.Get("dc"); other != "" {
|
||||||
|
args.Datacenter = other
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pull out the service name
|
||||||
|
args.ServiceName = strings.TrimPrefix(req.URL.Path, "/v1/health/checks/")
|
||||||
|
if args.ServiceName == "" {
|
||||||
|
resp.WriteHeader(400)
|
||||||
|
resp.Write([]byte("Missing service name"))
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make the RPC request
|
||||||
|
var out structs.HealthChecks
|
||||||
|
if err := s.agent.RPC("Health.ServiceChecks", &args, &out); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *HTTPServer) HealthServiceNodes(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
|
||||||
|
// Set default DC
|
||||||
|
args := structs.ServiceSpecificRequest{
|
||||||
|
Datacenter: s.agent.config.Datacenter,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for other DC
|
||||||
|
params := req.URL.Query()
|
||||||
|
if other := params.Get("dc"); other != "" {
|
||||||
|
args.Datacenter = other
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for a tag
|
||||||
|
if _, ok := params["tag"]; ok {
|
||||||
|
args.ServiceTag = params.Get("tag")
|
||||||
|
args.TagFilter = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pull out the service name
|
||||||
|
args.ServiceName = strings.TrimPrefix(req.URL.Path, "/v1/health/service/")
|
||||||
|
if args.ServiceName == "" {
|
||||||
|
resp.WriteHeader(400)
|
||||||
|
resp.Write([]byte("Missing service name"))
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make the RPC request
|
||||||
|
var out structs.CheckServiceNodes
|
||||||
|
if err := s.agent.RPC("Health.ServiceNodes", &args, &out); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
|
@ -65,6 +65,11 @@ func (s *HTTPServer) registerHandlers() {
|
||||||
s.mux.HandleFunc("/v1/catalog/service/", s.wrap(s.CatalogServiceNodes))
|
s.mux.HandleFunc("/v1/catalog/service/", s.wrap(s.CatalogServiceNodes))
|
||||||
s.mux.HandleFunc("/v1/catalog/node/", s.wrap(s.CatalogNodeServices))
|
s.mux.HandleFunc("/v1/catalog/node/", s.wrap(s.CatalogNodeServices))
|
||||||
|
|
||||||
|
s.mux.HandleFunc("/v1/health/node/", s.wrap(s.HealthNodeChecks))
|
||||||
|
s.mux.HandleFunc("/v1/health/checks/", s.wrap(s.HealthServiceChecks))
|
||||||
|
s.mux.HandleFunc("/v1/health/state/", s.wrap(s.HealthChecksInState))
|
||||||
|
s.mux.HandleFunc("/v1/health/service/", s.wrap(s.HealthServiceNodes))
|
||||||
|
|
||||||
s.mux.HandleFunc("/v1/agent/services", s.wrap(s.AgentServices))
|
s.mux.HandleFunc("/v1/agent/services", s.wrap(s.AgentServices))
|
||||||
s.mux.HandleFunc("/v1/agent/members", s.wrap(s.AgentMembers))
|
s.mux.HandleFunc("/v1/agent/members", s.wrap(s.AgentMembers))
|
||||||
s.mux.HandleFunc("/v1/agent/join/", s.wrap(s.AgentJoin))
|
s.mux.HandleFunc("/v1/agent/join/", s.wrap(s.AgentJoin))
|
||||||
|
|
|
@ -16,15 +16,11 @@ The current URLs supported are:
|
||||||
* /v1/catalog/service/<service>/ : Lists the nodes in a given service
|
* /v1/catalog/service/<service>/ : Lists the nodes in a given service
|
||||||
* /v1/catalog/node/<node>/ : Lists the services provided by a node
|
* /v1/catalog/node/<node>/ : Lists the services provided by a node
|
||||||
|
|
||||||
* Health system (future):
|
* Health system:
|
||||||
* /v1/health/register : Registers a new health check
|
|
||||||
* /v1/health/deregister : Deregisters a health check
|
|
||||||
* /v1/health/pass: Pass a health check
|
|
||||||
* /v1/health/warn: Warn on a health check
|
|
||||||
* /v1/health/fail: Fail a health check
|
|
||||||
* /v1/health/node/<node>: Returns the health info of a node
|
* /v1/health/node/<node>: Returns the health info of a node
|
||||||
* /v1/health/service/<service>: Returns the health info of a service
|
* /v1/health/checks/<service>: Returns the checks of a service
|
||||||
* /v1/health/query/<state>: Returns the checks in a given state
|
* /v1/health/service/<service>: Returns the nodes and health info of a service
|
||||||
|
* /v1/health/state/<state>: Returns the checks in a given state
|
||||||
|
|
||||||
* /v1/status/leader : Returns the current Raft leader
|
* /v1/status/leader : Returns the current Raft leader
|
||||||
* /v1/status/peers : Returns the current Raft peer set
|
* /v1/status/peers : Returns the current Raft peer set
|
||||||
|
@ -35,3 +31,10 @@ The current URLs supported are:
|
||||||
* /v1/agent/join/<node> : Instructs the local agent to join a node
|
* /v1/agent/join/<node> : Instructs the local agent to join a node
|
||||||
* /v1/agent/force-leave/<node>: Instructs the agent to force a node into the left state
|
* /v1/agent/force-leave/<node>: Instructs the agent to force a node into the left state
|
||||||
|
|
||||||
|
## Future (interacts with local state?)
|
||||||
|
* /v1/health/register : Registers a new health check
|
||||||
|
* /v1/health/deregister : Deregisters a health check
|
||||||
|
* /v1/health/pass: Pass a health check
|
||||||
|
* /v1/health/warn: Warn on a health check
|
||||||
|
* /v1/health/fail: Fail a health check
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue