Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

api: add node purge SDK function. #8636

Merged
merged 1 commit into from
Aug 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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