package api
import (
"fmt"
)
const (
// HealthAny is special, and is used as a wild card,
// not as a specific state.
HealthAny = "any"
HealthPassing = "passing"
HealthWarning = "warning"
HealthCritical = "critical"
)
// HealthCheck is used to represent a single check
type HealthCheck struct {
Node string
CheckID string
Name string
Status string
Notes string
Output string
ServiceID string
ServiceName string
}
// ServiceEntry is used for the health service endpoint
type ServiceEntry struct {
Node * Node
Service * AgentService
Checks [ ] * HealthCheck
}
// Health can be used to query the Health endpoints
type Health struct {
c * Client
}
// Health returns a handle to the health endpoints
func ( c * Client ) Health ( ) * Health {
return & Health { c }
}
// Node is used to query for checks belonging to a given node
func ( h * Health ) Node ( node string , q * QueryOptions ) ( [ ] * HealthCheck , * QueryMeta , error ) {
r := h . c . newRequest ( "GET" , "/v1/health/node/" + node )
r . setQueryOptions ( q )
rtt , resp , err := requireOK ( h . c . doRequest ( r ) )
if err != nil {
return nil , nil , err
}
defer resp . Body . Close ( )
qm := & QueryMeta { }
parseQueryMeta ( resp , qm )
qm . RequestTime = rtt
var out [ ] * HealthCheck
if err := decodeBody ( resp , & out ) ; err != nil {
return nil , nil , err
}
return out , qm , nil
}
// Checks is used to return the checks associated with a service
func ( h * Health ) Checks ( service string , q * QueryOptions ) ( [ ] * HealthCheck , * QueryMeta , error ) {
r := h . c . newRequest ( "GET" , "/v1/health/checks/" + service )
r . setQueryOptions ( q )
rtt , resp , err := requireOK ( h . c . doRequest ( r ) )
if err != nil {
return nil , nil , err
}
defer resp . Body . Close ( )
qm := & QueryMeta { }
parseQueryMeta ( resp , qm )
qm . RequestTime = rtt
var out [ ] * HealthCheck
if err := decodeBody ( resp , & out ) ; err != nil {
return nil , nil , err
}
return out , qm , nil
}
// Service is used to query health information along with service info
// for a given service. It can optionally do server-side filtering on a tag
// or nodes with passing health checks only.
func ( h * Health ) Service ( service , tag string , passingOnly bool , q * QueryOptions ) ( [ ] * ServiceEntry , * QueryMeta , error ) {
r := h . c . newRequest ( "GET" , "/v1/health/service/" + service )
r . setQueryOptions ( q )
if tag != "" {
r . params . Set ( "tag" , tag )
}
if passingOnly {
r . params . Set ( HealthPassing , "1" )
}
rtt , resp , err := requireOK ( h . c . doRequest ( r ) )
if err != nil {
return nil , nil , err
}
defer resp . Body . Close ( )
qm := & QueryMeta { }
parseQueryMeta ( resp , qm )
qm . RequestTime = rtt
var out [ ] * ServiceEntry
if err := decodeBody ( resp , & out ) ; err != nil {
return nil , nil , err
}
return out , qm , nil
}
// 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 ) ( [ ] * HealthCheck , * QueryMeta , error ) {
switch state {
case HealthAny :
case HealthWarning :
case HealthCritical :
case HealthPassing :
default :
return nil , nil , fmt . Errorf ( "Unsupported state: %v" , state )
}
r := h . c . newRequest ( "GET" , "/v1/health/state/" + state )
r . setQueryOptions ( q )
rtt , resp , err := requireOK ( h . c . doRequest ( r ) )
if err != nil {
return nil , nil , err
}
defer resp . Body . Close ( )
qm := & QueryMeta { }
parseQueryMeta ( resp , qm )
qm . RequestTime = rtt
var out [ ] * HealthCheck
if err := decodeBody ( resp , & out ) ; err != nil {
return nil , nil , err
}
return out , qm , nil
}