agent: first pass at service maintenance mode
This commit is contained in:
parent
559af1485c
commit
4f4eb204f6
|
@ -29,6 +29,9 @@ const (
|
||||||
"If Consul was not shut down properly, the socket file may " +
|
"If Consul was not shut down properly, the socket file may " +
|
||||||
"be left behind. If the path looks correct, remove the file " +
|
"be left behind. If the path looks correct, remove the file " +
|
||||||
"and try again."
|
"and try again."
|
||||||
|
|
||||||
|
// The ID of the faux health check for maintenance mode
|
||||||
|
maintCheckID = "_maintenance_"
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -995,3 +998,66 @@ func (a *Agent) unloadChecks() error {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *Agent) EnableServiceMaintenance(serviceID string) error {
|
||||||
|
var service *structs.NodeService
|
||||||
|
for _, svc := range a.state.Services() {
|
||||||
|
if svc.ID == serviceID {
|
||||||
|
service = svc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure the service exists
|
||||||
|
if service == nil {
|
||||||
|
return fmt.Errorf("No service registered with ID %q", serviceID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure maintenance mode is not already enabled
|
||||||
|
for _, check := range a.state.Checks() {
|
||||||
|
if check.CheckID == maintCheckID {
|
||||||
|
return fmt.Errorf("Maintenance mode already enabled for service %q", serviceID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create and register the critical health check
|
||||||
|
check := &structs.HealthCheck{
|
||||||
|
Node: a.config.NodeName,
|
||||||
|
CheckID: maintCheckID,
|
||||||
|
Name: "Service Maintenance Mode",
|
||||||
|
Notes: "Maintenance mode is enabled for this service",
|
||||||
|
ServiceID: service.ID,
|
||||||
|
ServiceName: service.Service,
|
||||||
|
Status: structs.HealthCritical,
|
||||||
|
}
|
||||||
|
a.state.AddCheck(check)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Agent) DisableServiceMaintenance(serviceID string) error {
|
||||||
|
var service *structs.NodeService
|
||||||
|
for _, svc := range a.state.Services() {
|
||||||
|
if svc.ID == serviceID {
|
||||||
|
service = svc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure the service exists
|
||||||
|
if service == nil {
|
||||||
|
return fmt.Errorf("No service registered with ID %q", serviceID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure maintenance mode is enabled
|
||||||
|
for _, check := range a.state.Checks() {
|
||||||
|
if check.CheckID == maintCheckID {
|
||||||
|
goto DEREGISTER
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fmt.Errorf("Maintenance mode not enabled for service %q", serviceID)
|
||||||
|
|
||||||
|
DEREGISTER:
|
||||||
|
// Deregister the maintenance check
|
||||||
|
a.state.RemoveCheck(maintCheckID)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -176,3 +176,40 @@ func (s *HTTPServer) AgentDeregisterService(resp http.ResponseWriter, req *http.
|
||||||
serviceID := strings.TrimPrefix(req.URL.Path, "/v1/agent/service/deregister/")
|
serviceID := strings.TrimPrefix(req.URL.Path, "/v1/agent/service/deregister/")
|
||||||
return nil, s.agent.RemoveService(serviceID, true)
|
return nil, s.agent.RemoveService(serviceID, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *HTTPServer) AgentServiceMaintenance(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
|
||||||
|
// Ensure we have a service ID
|
||||||
|
serviceID := strings.TrimPrefix(req.URL.Path, "/v1/agent/service/maintenance/")
|
||||||
|
if serviceID == "" {
|
||||||
|
resp.WriteHeader(400)
|
||||||
|
resp.Write([]byte("Missing service ID"))
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure we have some action
|
||||||
|
params := req.URL.Query()
|
||||||
|
if _, ok := params["enable"]; !ok {
|
||||||
|
resp.WriteHeader(400)
|
||||||
|
resp.Write([]byte("Missing value for enable"))
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var enable bool
|
||||||
|
raw := params.Get("enable")
|
||||||
|
switch raw {
|
||||||
|
case "true":
|
||||||
|
enable = true
|
||||||
|
case "false":
|
||||||
|
enable = false
|
||||||
|
default:
|
||||||
|
resp.WriteHeader(400)
|
||||||
|
resp.Write([]byte(fmt.Sprintf("Invalid value for enable: %q", raw)))
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if enable {
|
||||||
|
return nil, s.agent.EnableServiceMaintenance(serviceID)
|
||||||
|
} else {
|
||||||
|
return nil, s.agent.DisableServiceMaintenance(serviceID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -195,6 +195,7 @@ func (s *HTTPServer) registerHandlers(enableDebug bool) {
|
||||||
|
|
||||||
s.mux.HandleFunc("/v1/agent/service/register", s.wrap(s.AgentRegisterService))
|
s.mux.HandleFunc("/v1/agent/service/register", s.wrap(s.AgentRegisterService))
|
||||||
s.mux.HandleFunc("/v1/agent/service/deregister/", s.wrap(s.AgentDeregisterService))
|
s.mux.HandleFunc("/v1/agent/service/deregister/", s.wrap(s.AgentDeregisterService))
|
||||||
|
s.mux.HandleFunc("/v1/agent/service/maintenance/", s.wrap(s.AgentServiceMaintenance))
|
||||||
|
|
||||||
s.mux.HandleFunc("/v1/event/fire/", s.wrap(s.EventFire))
|
s.mux.HandleFunc("/v1/event/fire/", s.wrap(s.EventFire))
|
||||||
s.mux.HandleFunc("/v1/event/list", s.wrap(s.EventList))
|
s.mux.HandleFunc("/v1/event/list", s.wrap(s.EventList))
|
||||||
|
|
Loading…
Reference in New Issue