agent: node maintenance mode works
This commit is contained in:
parent
3b815cd0aa
commit
8ea9eb87ea
|
@ -30,8 +30,9 @@ const (
|
||||||
"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
|
// The ID of the faux health checks for maintenance mode
|
||||||
maintCheckID = "_maintenance_"
|
serviceMaintCheckID = "_service_maintenance"
|
||||||
|
nodeMaintCheckID = "_node_maintenenace"
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1008,14 +1009,14 @@ func (a *Agent) EnableServiceMaintenance(serviceID string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure maintenance mode is not already enabled
|
// Ensure maintenance mode is not already enabled
|
||||||
if _, ok := a.state.Checks()[maintCheckID]; ok {
|
if _, ok := a.state.Checks()[serviceMaintCheckID]; ok {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create and register the critical health check
|
// Create and register the critical health check
|
||||||
check := &structs.HealthCheck{
|
check := &structs.HealthCheck{
|
||||||
Node: a.config.NodeName,
|
Node: a.config.NodeName,
|
||||||
CheckID: maintCheckID,
|
CheckID: serviceMaintCheckID,
|
||||||
Name: "Service Maintenance Mode",
|
Name: "Service Maintenance Mode",
|
||||||
Notes: "Maintenance mode is enabled for this service",
|
Notes: "Maintenance mode is enabled for this service",
|
||||||
ServiceID: service.ID,
|
ServiceID: service.ID,
|
||||||
|
@ -1035,6 +1036,29 @@ func (a *Agent) DisableServiceMaintenance(serviceID string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deregister the maintenance check
|
// Deregister the maintenance check
|
||||||
a.RemoveCheck(maintCheckID, true)
|
a.RemoveCheck(serviceMaintCheckID, true)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EnableNodeMaintenance places a node into maintenance mode.
|
||||||
|
func (a *Agent) EnableNodeMaintenance() {
|
||||||
|
// Ensure node maintenance is not already enabled
|
||||||
|
if _, ok := a.state.Checks()[nodeMaintCheckID]; ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create and register the node maintenance check
|
||||||
|
check := &structs.HealthCheck{
|
||||||
|
Node: a.config.NodeName,
|
||||||
|
CheckID: nodeMaintCheckID,
|
||||||
|
Name: "Node Maintenance Mode",
|
||||||
|
Notes: "Maintenance mode is enabled for this node",
|
||||||
|
Status: structs.HealthCritical,
|
||||||
|
}
|
||||||
|
a.AddCheck(check, nil, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DisableNodeMaintenance removes a node from maintenance mode
|
||||||
|
func (a *Agent) DisableNodeMaintenance() {
|
||||||
|
a.RemoveCheck(nodeMaintCheckID, true)
|
||||||
|
}
|
||||||
|
|
|
@ -227,3 +227,39 @@ func (s *HTTPServer) AgentServiceMaintenance(resp http.ResponseWriter, req *http
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *HTTPServer) AgentNodeMaintenance(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
|
||||||
|
// Only PUT supported
|
||||||
|
if req.Method != "PUT" {
|
||||||
|
resp.WriteHeader(405)
|
||||||
|
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 {
|
||||||
|
s.agent.EnableNodeMaintenance()
|
||||||
|
} else {
|
||||||
|
s.agent.DisableNodeMaintenance()
|
||||||
|
}
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
|
@ -567,7 +567,7 @@ func TestHTTPAgent_EnableServiceMaintenance(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the maintenance check was registered
|
// Ensure the maintenance check was registered
|
||||||
if _, ok := srv.agent.state.Checks()[maintCheckID]; !ok {
|
if _, ok := srv.agent.state.Checks()[serviceMaintCheckID]; !ok {
|
||||||
t.Fatalf("should have registered maintenance check")
|
t.Fatalf("should have registered maintenance check")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -603,7 +603,7 @@ func TestHTTPAgent_DisableServiceMaintenance(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the maintenance check was removed
|
// Ensure the maintenance check was removed
|
||||||
if _, ok := srv.agent.state.Checks()[maintCheckID]; ok {
|
if _, ok := srv.agent.state.Checks()[serviceMaintCheckID]; ok {
|
||||||
t.Fatalf("should have removed maintenance check")
|
t.Fatalf("should have removed maintenance check")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -807,7 +807,7 @@ func TestAgent_MaintenanceMode(t *testing.T) {
|
||||||
|
|
||||||
// Make sure the critical health check was added
|
// Make sure the critical health check was added
|
||||||
for _, check := range agent.state.Checks() {
|
for _, check := range agent.state.Checks() {
|
||||||
if check.CheckID == maintCheckID {
|
if check.CheckID == serviceMaintCheckID {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -822,7 +822,7 @@ func TestAgent_MaintenanceMode(t *testing.T) {
|
||||||
|
|
||||||
// Ensure the check was deregistered
|
// Ensure the check was deregistered
|
||||||
for _, check := range agent.state.Checks() {
|
for _, check := range agent.state.Checks() {
|
||||||
if check.CheckID == maintCheckID {
|
if check.CheckID == serviceMaintCheckID {
|
||||||
t.Fatalf("should have deregistered maintenance check")
|
t.Fatalf("should have deregistered maintenance check")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -181,6 +181,7 @@ func (s *HTTPServer) registerHandlers(enableDebug bool) {
|
||||||
s.mux.HandleFunc("/v1/health/service/", s.wrap(s.HealthServiceNodes))
|
s.mux.HandleFunc("/v1/health/service/", s.wrap(s.HealthServiceNodes))
|
||||||
|
|
||||||
s.mux.HandleFunc("/v1/agent/self", s.wrap(s.AgentSelf))
|
s.mux.HandleFunc("/v1/agent/self", s.wrap(s.AgentSelf))
|
||||||
|
s.mux.HandleFunc("/v1/agent/self/maintenance", s.wrap(s.AgentNodeMaintenance))
|
||||||
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/checks", s.wrap(s.AgentChecks))
|
s.mux.HandleFunc("/v1/agent/checks", s.wrap(s.AgentChecks))
|
||||||
s.mux.HandleFunc("/v1/agent/members", s.wrap(s.AgentMembers))
|
s.mux.HandleFunc("/v1/agent/members", s.wrap(s.AgentMembers))
|
||||||
|
|
Loading…
Reference in New Issue