mirror of
https://github.com/kemko/nomad.git
synced 2026-01-06 18:35:44 +03:00
Added ACLs to the node de-register endpoint
This commit is contained in:
@@ -209,6 +209,13 @@ func (n *Node) Deregister(args *structs.NodeDeregisterRequest, reply *structs.No
|
||||
}
|
||||
defer metrics.MeasureSince([]string{"nomad", "client", "deregister"}, time.Now())
|
||||
|
||||
// Check node permissions
|
||||
if aclObj, err := n.srv.ResolveToken(args.AuthToken); err != nil {
|
||||
return err
|
||||
} else if aclObj != nil && !aclObj.AllowNodeWrite() {
|
||||
return structs.ErrPermissionDenied
|
||||
}
|
||||
|
||||
// Verify the arguments
|
||||
if args.NodeID == "" {
|
||||
return fmt.Errorf("missing node ID for client deregistration")
|
||||
@@ -246,7 +253,7 @@ func (n *Node) Deregister(args *structs.NodeDeregisterRequest, reply *structs.No
|
||||
}
|
||||
|
||||
// Determine if there are any Vault accessors on the node
|
||||
accessors, err := n.srv.State().VaultAccessorsByNode(ws, args.NodeID)
|
||||
accessors, err := snap.VaultAccessorsByNode(ws, args.NodeID)
|
||||
if err != nil {
|
||||
n.srv.logger.Printf("[ERR] nomad.client: looking up accessors for node %q failed: %v", args.NodeID, err)
|
||||
return err
|
||||
|
||||
@@ -132,6 +132,71 @@ func TestClientEndpoint_Deregister(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestClientEndpoint_Deregister_ACL(t *testing.T) {
|
||||
t.Parallel()
|
||||
s1, root := testACLServer(t, nil)
|
||||
defer s1.Shutdown()
|
||||
codec := rpcClient(t, s1)
|
||||
testutil.WaitForLeader(t, s1.RPC)
|
||||
|
||||
// Create the node
|
||||
node := mock.Node()
|
||||
node1 := mock.Node()
|
||||
state := s1.fsm.State()
|
||||
if err := state.UpsertNode(1, node); err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
if err := state.UpsertNode(2, node1); err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
// Create the policy and tokens
|
||||
validToken := mock.CreatePolicyAndToken(t, state, 1001, "test-valid", mock.NodePolicy(acl.PolicyWrite))
|
||||
invalidToken := mock.CreatePolicyAndToken(t, state, 1003, "test-invalid", mock.NodePolicy(acl.PolicyRead))
|
||||
|
||||
// Deregister without any token and expect it to fail
|
||||
dereg := &structs.NodeDeregisterRequest{
|
||||
NodeID: node.ID,
|
||||
WriteRequest: structs.WriteRequest{Region: "global"},
|
||||
}
|
||||
var resp structs.GenericResponse
|
||||
if err := msgpackrpc.CallWithCodec(codec, "Node.Deregister", dereg, &resp); err == nil {
|
||||
t.Fatalf("node de-register succeeded")
|
||||
}
|
||||
|
||||
// Deregister with a valid token
|
||||
dereg.AuthToken = validToken.SecretID
|
||||
if err := msgpackrpc.CallWithCodec(codec, "Node.Deregister", dereg, &resp); err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
// Check for the node in the FSM
|
||||
ws := memdb.NewWatchSet()
|
||||
out, err := state.NodeByID(ws, node.ID)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
if out != nil {
|
||||
t.Fatalf("unexpected node")
|
||||
}
|
||||
|
||||
// Deregister with an invalid token.
|
||||
dereg1 := &structs.NodeDeregisterRequest{
|
||||
NodeID: node1.ID,
|
||||
WriteRequest: structs.WriteRequest{Region: "global"},
|
||||
}
|
||||
dereg1.AuthToken = invalidToken.SecretID
|
||||
if err := msgpackrpc.CallWithCodec(codec, "Node.Deregister", dereg1, &resp); err == nil {
|
||||
t.Fatalf("rpc should not have succeeded")
|
||||
}
|
||||
|
||||
// Try with a root token
|
||||
dereg1.AuthToken = root.SecretID
|
||||
if err := msgpackrpc.CallWithCodec(codec, "Node.Deregister", dereg1, &resp); err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestClientEndpoint_Deregister_Vault(t *testing.T) {
|
||||
t.Parallel()
|
||||
s1 := testServer(t, nil)
|
||||
|
||||
Reference in New Issue
Block a user