Skip to content

Commit

Permalink
Merge pull request #8636 from hashicorp/f-gh-8142
Browse files Browse the repository at this point in the history
api: add node purge SDK function.
  • Loading branch information
jrasell authored Aug 17, 2020
2 parents c1060b7 + 38271df commit 9a536d2
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 1 deletion.
21 changes: 20 additions & 1 deletion api/nodes.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const (
NodeStatusDown = "down"

// NodeSchedulingEligible and Ineligible marks the node as eligible or not,
// respectively, for receiving allocations. This is orthoginal to the node
// respectively, for receiving allocations. This is orthogonal to the node
// status being ready.
NodeSchedulingEligible = "eligible"
NodeSchedulingIneligible = "ineligible"
Expand Down Expand Up @@ -435,6 +435,25 @@ func (n *Nodes) GcAlloc(allocID string, q *QueryOptions) error {
return err
}

// Purge removes a node from the system. Nodes can still re-join the cluster if
// they are alive.
func (n *Nodes) Purge(nodeID string, q *QueryOptions) (*NodePurgeResponse, *QueryMeta, error) {
var resp NodePurgeResponse
path := fmt.Sprintf("/v1/node/%s/purge", nodeID)
qm, err := n.client.putQuery(path, nil, &resp, q)
if err != nil {
return nil, nil, err
}
return &resp, qm, nil
}

// NodePurgeResponse is used to deserialize a Purge response.
type NodePurgeResponse struct {
EvalIDs []string
EvalCreateIndex uint64
NodeModifyIndex uint64
}

// DriverInfo is used to deserialize a DriverInfo entry
type DriverInfo struct {
Attributes map[string]string
Expand Down
41 changes: 41 additions & 0 deletions api/nodes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,47 @@ func TestNodes_DrainStrategy_Equal(t *testing.T) {
require.True(d.Equal(o))
}

func TestNodes_Purge(t *testing.T) {
t.Parallel()
require := require.New(t)
c, s := makeClient(t, nil, func(c *testutil.TestServerConfig) {
c.DevMode = true
})
defer s.Stop()

// Purge on a nonexistent node fails.
_, _, err := c.Nodes().Purge("12345678-abcd-efab-cdef-123456789abc", nil)
if err == nil || !strings.Contains(err.Error(), "not found") {
t.Fatalf("expected not found error, got: %#v", err)
}

// Wait for node registration and get the ID so we can attempt to purge a
// node that exists.
var nodeID string
testutil.WaitForResult(func() (bool, error) {
out, _, err := c.Nodes().List(nil)
if err != nil {
return false, err
}
if n := len(out); n != 1 {
return false, fmt.Errorf("expected 1 node, got: %d", n)
}
nodeID = out[0].ID
return true, nil
}, func(err error) {
t.Fatalf("err: %s", err)
})

// Perform the node purge and check the response objects.
out, meta, err := c.Nodes().Purge(nodeID, nil)
require.Nil(err)
require.NotNil(out)

// We can't use assertQueryMeta here, as the RPC response does not populate
// the known leader field.
require.Greater(meta.LastIndex, uint64(0))
}

func TestNodeStatValueFormatting(t *testing.T) {
t.Parallel()

Expand Down

0 comments on commit 9a536d2

Please sign in to comment.