mirror of
https://github.com/kemko/nomad.git
synced 2026-01-06 10:25:42 +03:00
Drain cli, api, http
This commit is contained in:
committed by
Michael Schurter
parent
1773de9e30
commit
2bdeacebff
@@ -2,9 +2,9 @@ package agent
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/nomad/api"
|
||||
"github.com/hashicorp/nomad/nomad/structs"
|
||||
)
|
||||
|
||||
@@ -101,19 +101,21 @@ func (s *HTTPServer) nodeToggleDrain(resp http.ResponseWriter, req *http.Request
|
||||
return nil, CodedError(405, ErrInvalidMethod)
|
||||
}
|
||||
|
||||
// Get the enable value
|
||||
enableRaw := req.URL.Query().Get("enable")
|
||||
if enableRaw == "" {
|
||||
return nil, CodedError(400, "missing enable value")
|
||||
}
|
||||
enable, err := strconv.ParseBool(enableRaw)
|
||||
if err != nil {
|
||||
return nil, CodedError(400, "invalid enable value")
|
||||
var drainRequest api.NodeUpdateDrainRequest
|
||||
if err := decodeBody(req, &drainRequest); err != nil {
|
||||
return nil, CodedError(400, err.Error())
|
||||
}
|
||||
|
||||
args := structs.NodeUpdateDrainRequest{
|
||||
NodeID: nodeID,
|
||||
Drain: enable,
|
||||
}
|
||||
if drainRequest.DrainSpec != nil {
|
||||
args.DrainStrategy = &structs.DrainStrategy{
|
||||
DrainSpec: structs.DrainSpec{
|
||||
Deadline: drainRequest.DrainSpec.Deadline,
|
||||
IgnoreSystemJobs: drainRequest.DrainSpec.IgnoreSystemJobs,
|
||||
},
|
||||
}
|
||||
}
|
||||
s.parseWriteRequest(req, &args.WriteRequest)
|
||||
|
||||
|
||||
@@ -4,10 +4,13 @@ import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/nomad/api"
|
||||
"github.com/hashicorp/nomad/nomad/mock"
|
||||
"github.com/hashicorp/nomad/nomad/structs"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestHTTP_NodesList(t *testing.T) {
|
||||
@@ -238,6 +241,7 @@ func TestHTTP_NodeAllocations(t *testing.T) {
|
||||
|
||||
func TestHTTP_NodeDrain(t *testing.T) {
|
||||
t.Parallel()
|
||||
require := require.New(t)
|
||||
httpTest(t, nil, func(s *TestAgent) {
|
||||
// Create the node
|
||||
node := mock.Node()
|
||||
@@ -246,45 +250,55 @@ func TestHTTP_NodeDrain(t *testing.T) {
|
||||
WriteRequest: structs.WriteRequest{Region: "global"},
|
||||
}
|
||||
var resp structs.NodeUpdateResponse
|
||||
if err := s.Agent.RPC("Node.Register", &args, &resp); err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
require.Nil(s.Agent.RPC("Node.Register", &args, &resp))
|
||||
|
||||
// Directly manipulate the state
|
||||
state := s.Agent.server.State()
|
||||
alloc1 := mock.Alloc()
|
||||
alloc1.NodeID = node.ID
|
||||
if err := state.UpsertJobSummary(999, mock.JobSummary(alloc1.JobID)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
err := state.UpsertAllocs(1000, []*structs.Allocation{alloc1})
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
drainReq := api.NodeUpdateDrainRequest{
|
||||
NodeID: node.ID,
|
||||
DrainSpec: &api.DrainSpec{
|
||||
Deadline: 10 * time.Second,
|
||||
},
|
||||
}
|
||||
|
||||
// Make the HTTP request
|
||||
req, err := http.NewRequest("POST", "/v1/node/"+node.ID+"/drain?enable=1", nil)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
buf := encodeReq(drainReq)
|
||||
req, err := http.NewRequest("POST", "/v1/node/"+node.ID+"/drain", buf)
|
||||
require.Nil(err)
|
||||
respW := httptest.NewRecorder()
|
||||
|
||||
// Make the request
|
||||
obj, err := s.Server.NodeSpecificRequest(respW, req)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
require.Nil(err)
|
||||
|
||||
// Check for the index
|
||||
if respW.HeaderMap.Get("X-Nomad-Index") == "" {
|
||||
t.Fatalf("missing index")
|
||||
}
|
||||
require.NotZero(respW.HeaderMap.Get("X-Nomad-Index"))
|
||||
|
||||
// Check the response
|
||||
upd := obj.(structs.NodeDrainUpdateResponse)
|
||||
if len(upd.EvalIDs) == 0 {
|
||||
t.Fatalf("bad: %v", upd)
|
||||
}
|
||||
_, ok := obj.(structs.NodeDrainUpdateResponse)
|
||||
require.True(ok)
|
||||
|
||||
// Check that the node has been updated
|
||||
state := s.Agent.server.State()
|
||||
out, err := state.NodeByID(nil, node.ID)
|
||||
require.Nil(err)
|
||||
require.True(out.Drain)
|
||||
require.NotNil(out.DrainStrategy)
|
||||
require.Equal(10*time.Second, out.DrainStrategy.Deadline)
|
||||
|
||||
// Make the HTTP request to unset drain
|
||||
drainReq.DrainSpec = nil
|
||||
buf = encodeReq(drainReq)
|
||||
req, err = http.NewRequest("POST", "/v1/node/"+node.ID+"/drain", buf)
|
||||
require.Nil(err)
|
||||
respW = httptest.NewRecorder()
|
||||
|
||||
// Make the request
|
||||
obj, err = s.Server.NodeSpecificRequest(respW, req)
|
||||
require.Nil(err)
|
||||
|
||||
out, err = state.NodeByID(nil, node.ID)
|
||||
require.Nil(err)
|
||||
require.False(out.Drain)
|
||||
require.Nil(out.DrainStrategy)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user