github.com/zoomfoo/nomad@v0.8.5-0.20180907175415-f28fd3a1a056/nomad/acl_endpoint_test.go (about)

     1  package nomad
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"os"
     7  	"path/filepath"
     8  	"strings"
     9  	"testing"
    10  	"time"
    11  
    12  	msgpackrpc "github.com/hashicorp/net-rpc-msgpackrpc"
    13  	"github.com/hashicorp/nomad/helper/uuid"
    14  	"github.com/hashicorp/nomad/nomad/mock"
    15  	"github.com/hashicorp/nomad/nomad/structs"
    16  	"github.com/hashicorp/nomad/testutil"
    17  	"github.com/stretchr/testify/assert"
    18  )
    19  
    20  func TestACLEndpoint_GetPolicy(t *testing.T) {
    21  	t.Parallel()
    22  	s1, root := TestACLServer(t, nil)
    23  	defer s1.Shutdown()
    24  	codec := rpcClient(t, s1)
    25  	testutil.WaitForLeader(t, s1.RPC)
    26  
    27  	// Create the register request
    28  	policy := mock.ACLPolicy()
    29  	s1.fsm.State().UpsertACLPolicies(1000, []*structs.ACLPolicy{policy})
    30  
    31  	// Create a token with one the policy
    32  	token := mock.ACLToken()
    33  	token.Policies = []string{policy.Name}
    34  	s1.fsm.State().UpsertACLTokens(1001, []*structs.ACLToken{token})
    35  
    36  	// Lookup the policy
    37  	get := &structs.ACLPolicySpecificRequest{
    38  		Name: policy.Name,
    39  		QueryOptions: structs.QueryOptions{
    40  			Region:    "global",
    41  			AuthToken: root.SecretID,
    42  		},
    43  	}
    44  	var resp structs.SingleACLPolicyResponse
    45  	if err := msgpackrpc.CallWithCodec(codec, "ACL.GetPolicy", get, &resp); err != nil {
    46  		t.Fatalf("err: %v", err)
    47  	}
    48  	assert.Equal(t, uint64(1000), resp.Index)
    49  	assert.Equal(t, policy, resp.Policy)
    50  
    51  	// Lookup non-existing policy
    52  	get.Name = uuid.Generate()
    53  	if err := msgpackrpc.CallWithCodec(codec, "ACL.GetPolicy", get, &resp); err != nil {
    54  		t.Fatalf("err: %v", err)
    55  	}
    56  	assert.Equal(t, uint64(1000), resp.Index)
    57  	assert.Nil(t, resp.Policy)
    58  
    59  	// Lookup the policy with the token
    60  	get = &structs.ACLPolicySpecificRequest{
    61  		Name: policy.Name,
    62  		QueryOptions: structs.QueryOptions{
    63  			Region:    "global",
    64  			AuthToken: token.SecretID,
    65  		},
    66  	}
    67  	var resp2 structs.SingleACLPolicyResponse
    68  	if err := msgpackrpc.CallWithCodec(codec, "ACL.GetPolicy", get, &resp2); err != nil {
    69  		t.Fatalf("err: %v", err)
    70  	}
    71  	assert.EqualValues(t, 1000, resp2.Index)
    72  	assert.Equal(t, policy, resp2.Policy)
    73  }
    74  
    75  func TestACLEndpoint_GetPolicy_Blocking(t *testing.T) {
    76  	t.Parallel()
    77  	s1, root := TestACLServer(t, nil)
    78  	defer s1.Shutdown()
    79  	state := s1.fsm.State()
    80  	codec := rpcClient(t, s1)
    81  	testutil.WaitForLeader(t, s1.RPC)
    82  
    83  	// Create the policies
    84  	p1 := mock.ACLPolicy()
    85  	p2 := mock.ACLPolicy()
    86  
    87  	// First create an unrelated policy
    88  	time.AfterFunc(100*time.Millisecond, func() {
    89  		err := state.UpsertACLPolicies(100, []*structs.ACLPolicy{p1})
    90  		if err != nil {
    91  			t.Fatalf("err: %v", err)
    92  		}
    93  	})
    94  
    95  	// Upsert the policy we are watching later
    96  	time.AfterFunc(200*time.Millisecond, func() {
    97  		err := state.UpsertACLPolicies(200, []*structs.ACLPolicy{p2})
    98  		if err != nil {
    99  			t.Fatalf("err: %v", err)
   100  		}
   101  	})
   102  
   103  	// Lookup the policy
   104  	req := &structs.ACLPolicySpecificRequest{
   105  		Name: p2.Name,
   106  		QueryOptions: structs.QueryOptions{
   107  			Region:        "global",
   108  			MinQueryIndex: 150,
   109  			AuthToken:     root.SecretID,
   110  		},
   111  	}
   112  	var resp structs.SingleACLPolicyResponse
   113  	start := time.Now()
   114  	if err := msgpackrpc.CallWithCodec(codec, "ACL.GetPolicy", req, &resp); err != nil {
   115  		t.Fatalf("err: %v", err)
   116  	}
   117  
   118  	if elapsed := time.Since(start); elapsed < 200*time.Millisecond {
   119  		t.Fatalf("should block (returned in %s) %#v", elapsed, resp)
   120  	}
   121  	if resp.Index != 200 {
   122  		t.Fatalf("Bad index: %d %d", resp.Index, 200)
   123  	}
   124  	if resp.Policy == nil || resp.Policy.Name != p2.Name {
   125  		t.Fatalf("bad: %#v", resp.Policy)
   126  	}
   127  
   128  	// Eval delete triggers watches
   129  	time.AfterFunc(100*time.Millisecond, func() {
   130  		err := state.DeleteACLPolicies(300, []string{p2.Name})
   131  		if err != nil {
   132  			t.Fatalf("err: %v", err)
   133  		}
   134  	})
   135  
   136  	req.QueryOptions.MinQueryIndex = 250
   137  	var resp2 structs.SingleACLPolicyResponse
   138  	start = time.Now()
   139  	if err := msgpackrpc.CallWithCodec(codec, "ACL.GetPolicy", req, &resp2); err != nil {
   140  		t.Fatalf("err: %v", err)
   141  	}
   142  
   143  	if elapsed := time.Since(start); elapsed < 100*time.Millisecond {
   144  		t.Fatalf("should block (returned in %s) %#v", elapsed, resp2)
   145  	}
   146  	if resp2.Index != 300 {
   147  		t.Fatalf("Bad index: %d %d", resp2.Index, 300)
   148  	}
   149  	if resp2.Policy != nil {
   150  		t.Fatalf("bad: %#v", resp2.Policy)
   151  	}
   152  }
   153  
   154  func TestACLEndpoint_GetPolicies(t *testing.T) {
   155  	t.Parallel()
   156  	s1, root := TestACLServer(t, nil)
   157  	defer s1.Shutdown()
   158  	codec := rpcClient(t, s1)
   159  	testutil.WaitForLeader(t, s1.RPC)
   160  
   161  	// Create the register request
   162  	policy := mock.ACLPolicy()
   163  	policy2 := mock.ACLPolicy()
   164  	s1.fsm.State().UpsertACLPolicies(1000, []*structs.ACLPolicy{policy, policy2})
   165  
   166  	// Lookup the policy
   167  	get := &structs.ACLPolicySetRequest{
   168  		Names: []string{policy.Name, policy2.Name},
   169  		QueryOptions: structs.QueryOptions{
   170  			Region:    "global",
   171  			AuthToken: root.SecretID,
   172  		},
   173  	}
   174  	var resp structs.ACLPolicySetResponse
   175  	if err := msgpackrpc.CallWithCodec(codec, "ACL.GetPolicies", get, &resp); err != nil {
   176  		t.Fatalf("err: %v", err)
   177  	}
   178  	assert.Equal(t, uint64(1000), resp.Index)
   179  	assert.Equal(t, 2, len(resp.Policies))
   180  	assert.Equal(t, policy, resp.Policies[policy.Name])
   181  	assert.Equal(t, policy2, resp.Policies[policy2.Name])
   182  
   183  	// Lookup non-existing policy
   184  	get.Names = []string{uuid.Generate()}
   185  	resp = structs.ACLPolicySetResponse{}
   186  	if err := msgpackrpc.CallWithCodec(codec, "ACL.GetPolicies", get, &resp); err != nil {
   187  		t.Fatalf("err: %v", err)
   188  	}
   189  	assert.Equal(t, uint64(1000), resp.Index)
   190  	assert.Equal(t, 0, len(resp.Policies))
   191  }
   192  
   193  func TestACLEndpoint_GetPolicies_TokenSubset(t *testing.T) {
   194  	t.Parallel()
   195  	s1, _ := TestACLServer(t, nil)
   196  	defer s1.Shutdown()
   197  	codec := rpcClient(t, s1)
   198  	testutil.WaitForLeader(t, s1.RPC)
   199  
   200  	// Create the register request
   201  	policy := mock.ACLPolicy()
   202  	policy2 := mock.ACLPolicy()
   203  	s1.fsm.State().UpsertACLPolicies(1000, []*structs.ACLPolicy{policy, policy2})
   204  
   205  	token := mock.ACLToken()
   206  	token.Policies = []string{policy.Name}
   207  	s1.fsm.State().UpsertACLTokens(1000, []*structs.ACLToken{token})
   208  
   209  	// Lookup the policy which is a subset of our tokens
   210  	get := &structs.ACLPolicySetRequest{
   211  		Names: []string{policy.Name},
   212  		QueryOptions: structs.QueryOptions{
   213  			Region:    "global",
   214  			AuthToken: token.SecretID,
   215  		},
   216  	}
   217  	var resp structs.ACLPolicySetResponse
   218  	if err := msgpackrpc.CallWithCodec(codec, "ACL.GetPolicies", get, &resp); err != nil {
   219  		t.Fatalf("err: %v", err)
   220  	}
   221  	assert.Equal(t, uint64(1000), resp.Index)
   222  	assert.Equal(t, 1, len(resp.Policies))
   223  	assert.Equal(t, policy, resp.Policies[policy.Name])
   224  
   225  	// Lookup non-associated policy
   226  	get.Names = []string{policy2.Name}
   227  	resp = structs.ACLPolicySetResponse{}
   228  	if err := msgpackrpc.CallWithCodec(codec, "ACL.GetPolicies", get, &resp); err == nil {
   229  		t.Fatalf("expected error")
   230  	}
   231  }
   232  
   233  func TestACLEndpoint_GetPolicies_Blocking(t *testing.T) {
   234  	t.Parallel()
   235  	s1, root := TestACLServer(t, nil)
   236  	defer s1.Shutdown()
   237  	state := s1.fsm.State()
   238  	codec := rpcClient(t, s1)
   239  	testutil.WaitForLeader(t, s1.RPC)
   240  
   241  	// Create the policies
   242  	p1 := mock.ACLPolicy()
   243  	p2 := mock.ACLPolicy()
   244  
   245  	// First create an unrelated policy
   246  	time.AfterFunc(100*time.Millisecond, func() {
   247  		err := state.UpsertACLPolicies(100, []*structs.ACLPolicy{p1})
   248  		if err != nil {
   249  			t.Fatalf("err: %v", err)
   250  		}
   251  	})
   252  
   253  	// Upsert the policy we are watching later
   254  	time.AfterFunc(200*time.Millisecond, func() {
   255  		err := state.UpsertACLPolicies(200, []*structs.ACLPolicy{p2})
   256  		if err != nil {
   257  			t.Fatalf("err: %v", err)
   258  		}
   259  	})
   260  
   261  	// Lookup the policy
   262  	req := &structs.ACLPolicySetRequest{
   263  		Names: []string{p2.Name},
   264  		QueryOptions: structs.QueryOptions{
   265  			Region:        "global",
   266  			MinQueryIndex: 150,
   267  			AuthToken:     root.SecretID,
   268  		},
   269  	}
   270  	var resp structs.ACLPolicySetResponse
   271  	start := time.Now()
   272  	if err := msgpackrpc.CallWithCodec(codec, "ACL.GetPolicies", req, &resp); err != nil {
   273  		t.Fatalf("err: %v", err)
   274  	}
   275  
   276  	if elapsed := time.Since(start); elapsed < 200*time.Millisecond {
   277  		t.Fatalf("should block (returned in %s) %#v", elapsed, resp)
   278  	}
   279  	if resp.Index != 200 {
   280  		t.Fatalf("Bad index: %d %d", resp.Index, 200)
   281  	}
   282  	if len(resp.Policies) == 0 || resp.Policies[p2.Name] == nil {
   283  		t.Fatalf("bad: %#v", resp.Policies)
   284  	}
   285  
   286  	// Eval delete triggers watches
   287  	time.AfterFunc(100*time.Millisecond, func() {
   288  		err := state.DeleteACLPolicies(300, []string{p2.Name})
   289  		if err != nil {
   290  			t.Fatalf("err: %v", err)
   291  		}
   292  	})
   293  
   294  	req.QueryOptions.MinQueryIndex = 250
   295  	var resp2 structs.ACLPolicySetResponse
   296  	start = time.Now()
   297  	if err := msgpackrpc.CallWithCodec(codec, "ACL.GetPolicies", req, &resp2); err != nil {
   298  		t.Fatalf("err: %v", err)
   299  	}
   300  
   301  	if elapsed := time.Since(start); elapsed < 100*time.Millisecond {
   302  		t.Fatalf("should block (returned in %s) %#v", elapsed, resp2)
   303  	}
   304  	if resp2.Index != 300 {
   305  		t.Fatalf("Bad index: %d %d", resp2.Index, 300)
   306  	}
   307  	if len(resp2.Policies) != 0 {
   308  		t.Fatalf("bad: %#v", resp2.Policies)
   309  	}
   310  }
   311  
   312  func TestACLEndpoint_ListPolicies(t *testing.T) {
   313  	assert := assert.New(t)
   314  	t.Parallel()
   315  	s1, root := TestACLServer(t, nil)
   316  	defer s1.Shutdown()
   317  	codec := rpcClient(t, s1)
   318  	testutil.WaitForLeader(t, s1.RPC)
   319  
   320  	// Create the register request
   321  	p1 := mock.ACLPolicy()
   322  	p2 := mock.ACLPolicy()
   323  
   324  	p1.Name = "aaaaaaaa-3350-4b4b-d185-0e1992ed43e9"
   325  	p2.Name = "aaaabbbb-3350-4b4b-d185-0e1992ed43e9"
   326  	s1.fsm.State().UpsertACLPolicies(1000, []*structs.ACLPolicy{p1, p2})
   327  
   328  	// Create a token with one of those policies
   329  	token := mock.ACLToken()
   330  	token.Policies = []string{p1.Name}
   331  	s1.fsm.State().UpsertACLTokens(1001, []*structs.ACLToken{token})
   332  
   333  	// Lookup the policies
   334  	get := &structs.ACLPolicyListRequest{
   335  		QueryOptions: structs.QueryOptions{
   336  			Region:    "global",
   337  			AuthToken: root.SecretID,
   338  		},
   339  	}
   340  	var resp structs.ACLPolicyListResponse
   341  	if err := msgpackrpc.CallWithCodec(codec, "ACL.ListPolicies", get, &resp); err != nil {
   342  		t.Fatalf("err: %v", err)
   343  	}
   344  	assert.EqualValues(1000, resp.Index)
   345  	assert.Len(resp.Policies, 2)
   346  
   347  	// Lookup the policies by prefix
   348  	get = &structs.ACLPolicyListRequest{
   349  		QueryOptions: structs.QueryOptions{
   350  			Region:    "global",
   351  			Prefix:    "aaaabb",
   352  			AuthToken: root.SecretID,
   353  		},
   354  	}
   355  	var resp2 structs.ACLPolicyListResponse
   356  	if err := msgpackrpc.CallWithCodec(codec, "ACL.ListPolicies", get, &resp2); err != nil {
   357  		t.Fatalf("err: %v", err)
   358  	}
   359  	assert.EqualValues(1000, resp2.Index)
   360  	assert.Len(resp2.Policies, 1)
   361  
   362  	// List policies using the created token
   363  	get = &structs.ACLPolicyListRequest{
   364  		QueryOptions: structs.QueryOptions{
   365  			Region:    "global",
   366  			AuthToken: token.SecretID,
   367  		},
   368  	}
   369  	var resp3 structs.ACLPolicyListResponse
   370  	if err := msgpackrpc.CallWithCodec(codec, "ACL.ListPolicies", get, &resp3); err != nil {
   371  		t.Fatalf("err: %v", err)
   372  	}
   373  	assert.EqualValues(1000, resp3.Index)
   374  	if assert.Len(resp3.Policies, 1) {
   375  		assert.Equal(resp3.Policies[0].Name, p1.Name)
   376  	}
   377  }
   378  
   379  func TestACLEndpoint_ListPolicies_Blocking(t *testing.T) {
   380  	t.Parallel()
   381  	s1, root := TestACLServer(t, nil)
   382  	defer s1.Shutdown()
   383  	state := s1.fsm.State()
   384  	codec := rpcClient(t, s1)
   385  	testutil.WaitForLeader(t, s1.RPC)
   386  
   387  	// Create the policy
   388  	policy := mock.ACLPolicy()
   389  
   390  	// Upsert eval triggers watches
   391  	time.AfterFunc(100*time.Millisecond, func() {
   392  		if err := state.UpsertACLPolicies(2, []*structs.ACLPolicy{policy}); err != nil {
   393  			t.Fatalf("err: %v", err)
   394  		}
   395  	})
   396  
   397  	req := &structs.ACLPolicyListRequest{
   398  		QueryOptions: structs.QueryOptions{
   399  			Region:        "global",
   400  			MinQueryIndex: 1,
   401  			AuthToken:     root.SecretID,
   402  		},
   403  	}
   404  	start := time.Now()
   405  	var resp structs.ACLPolicyListResponse
   406  	if err := msgpackrpc.CallWithCodec(codec, "ACL.ListPolicies", req, &resp); err != nil {
   407  		t.Fatalf("err: %v", err)
   408  	}
   409  
   410  	if elapsed := time.Since(start); elapsed < 100*time.Millisecond {
   411  		t.Fatalf("should block (returned in %s) %#v", elapsed, resp)
   412  	}
   413  	assert.Equal(t, uint64(2), resp.Index)
   414  	if len(resp.Policies) != 1 || resp.Policies[0].Name != policy.Name {
   415  		t.Fatalf("bad: %#v", resp.Policies)
   416  	}
   417  
   418  	// Eval deletion triggers watches
   419  	time.AfterFunc(100*time.Millisecond, func() {
   420  		if err := state.DeleteACLPolicies(3, []string{policy.Name}); err != nil {
   421  			t.Fatalf("err: %v", err)
   422  		}
   423  	})
   424  
   425  	req.MinQueryIndex = 2
   426  	start = time.Now()
   427  	var resp2 structs.ACLPolicyListResponse
   428  	if err := msgpackrpc.CallWithCodec(codec, "ACL.ListPolicies", req, &resp2); err != nil {
   429  		t.Fatalf("err: %v", err)
   430  	}
   431  
   432  	if elapsed := time.Since(start); elapsed < 100*time.Millisecond {
   433  		t.Fatalf("should block (returned in %s) %#v", elapsed, resp2)
   434  	}
   435  	assert.Equal(t, uint64(3), resp2.Index)
   436  	assert.Equal(t, 0, len(resp2.Policies))
   437  }
   438  
   439  func TestACLEndpoint_DeletePolicies(t *testing.T) {
   440  	t.Parallel()
   441  	s1, root := TestACLServer(t, nil)
   442  	defer s1.Shutdown()
   443  	codec := rpcClient(t, s1)
   444  	testutil.WaitForLeader(t, s1.RPC)
   445  
   446  	// Create the register request
   447  	p1 := mock.ACLPolicy()
   448  	s1.fsm.State().UpsertACLPolicies(1000, []*structs.ACLPolicy{p1})
   449  
   450  	// Lookup the policies
   451  	req := &structs.ACLPolicyDeleteRequest{
   452  		Names: []string{p1.Name},
   453  		WriteRequest: structs.WriteRequest{
   454  			Region:    "global",
   455  			AuthToken: root.SecretID,
   456  		},
   457  	}
   458  	var resp structs.GenericResponse
   459  	if err := msgpackrpc.CallWithCodec(codec, "ACL.DeletePolicies", req, &resp); err != nil {
   460  		t.Fatalf("err: %v", err)
   461  	}
   462  	assert.NotEqual(t, uint64(0), resp.Index)
   463  }
   464  
   465  func TestACLEndpoint_UpsertPolicies(t *testing.T) {
   466  	t.Parallel()
   467  	s1, root := TestACLServer(t, nil)
   468  	defer s1.Shutdown()
   469  	codec := rpcClient(t, s1)
   470  	testutil.WaitForLeader(t, s1.RPC)
   471  
   472  	// Create the register request
   473  	p1 := mock.ACLPolicy()
   474  
   475  	// Lookup the policies
   476  	req := &structs.ACLPolicyUpsertRequest{
   477  		Policies: []*structs.ACLPolicy{p1},
   478  		WriteRequest: structs.WriteRequest{
   479  			Region:    "global",
   480  			AuthToken: root.SecretID,
   481  		},
   482  	}
   483  	var resp structs.GenericResponse
   484  	if err := msgpackrpc.CallWithCodec(codec, "ACL.UpsertPolicies", req, &resp); err != nil {
   485  		t.Fatalf("err: %v", err)
   486  	}
   487  	assert.NotEqual(t, uint64(0), resp.Index)
   488  
   489  	// Check we created the policy
   490  	out, err := s1.fsm.State().ACLPolicyByName(nil, p1.Name)
   491  	assert.Nil(t, err)
   492  	assert.NotNil(t, out)
   493  }
   494  
   495  func TestACLEndpoint_UpsertPolicies_Invalid(t *testing.T) {
   496  	t.Parallel()
   497  	s1, root := TestACLServer(t, nil)
   498  	defer s1.Shutdown()
   499  	codec := rpcClient(t, s1)
   500  	testutil.WaitForLeader(t, s1.RPC)
   501  
   502  	// Create the register request
   503  	p1 := mock.ACLPolicy()
   504  	p1.Rules = "blah blah invalid"
   505  
   506  	// Lookup the policies
   507  	req := &structs.ACLPolicyUpsertRequest{
   508  		Policies: []*structs.ACLPolicy{p1},
   509  		WriteRequest: structs.WriteRequest{
   510  			Region:    "global",
   511  			AuthToken: root.SecretID,
   512  		},
   513  	}
   514  	var resp structs.GenericResponse
   515  	err := msgpackrpc.CallWithCodec(codec, "ACL.UpsertPolicies", req, &resp)
   516  	assert.NotNil(t, err)
   517  	if !strings.Contains(err.Error(), "failed to parse") {
   518  		t.Fatalf("bad: %s", err)
   519  	}
   520  }
   521  
   522  func TestACLEndpoint_GetToken(t *testing.T) {
   523  	t.Parallel()
   524  	s1, root := TestACLServer(t, nil)
   525  	defer s1.Shutdown()
   526  	codec := rpcClient(t, s1)
   527  	testutil.WaitForLeader(t, s1.RPC)
   528  
   529  	// Create the register request
   530  	token := mock.ACLToken()
   531  	s1.fsm.State().UpsertACLTokens(1000, []*structs.ACLToken{token})
   532  
   533  	// Lookup the token
   534  	get := &structs.ACLTokenSpecificRequest{
   535  		AccessorID: token.AccessorID,
   536  		QueryOptions: structs.QueryOptions{
   537  			Region:    "global",
   538  			AuthToken: root.SecretID,
   539  		},
   540  	}
   541  	var resp structs.SingleACLTokenResponse
   542  	if err := msgpackrpc.CallWithCodec(codec, "ACL.GetToken", get, &resp); err != nil {
   543  		t.Fatalf("err: %v", err)
   544  	}
   545  	assert.Equal(t, uint64(1000), resp.Index)
   546  	assert.Equal(t, token, resp.Token)
   547  
   548  	// Lookup non-existing token
   549  	get.AccessorID = uuid.Generate()
   550  	if err := msgpackrpc.CallWithCodec(codec, "ACL.GetToken", get, &resp); err != nil {
   551  		t.Fatalf("err: %v", err)
   552  	}
   553  	assert.Equal(t, uint64(1000), resp.Index)
   554  	assert.Nil(t, resp.Token)
   555  
   556  	// Lookup the token by accessor id using the tokens secret ID
   557  	get.AccessorID = token.AccessorID
   558  	get.AuthToken = token.SecretID
   559  	var resp2 structs.SingleACLTokenResponse
   560  	if err := msgpackrpc.CallWithCodec(codec, "ACL.GetToken", get, &resp2); err != nil {
   561  		t.Fatalf("err: %v", err)
   562  	}
   563  	assert.Equal(t, uint64(1000), resp2.Index)
   564  	assert.Equal(t, token, resp2.Token)
   565  }
   566  
   567  func TestACLEndpoint_GetToken_Blocking(t *testing.T) {
   568  	t.Parallel()
   569  	s1, root := TestACLServer(t, nil)
   570  	defer s1.Shutdown()
   571  	state := s1.fsm.State()
   572  	codec := rpcClient(t, s1)
   573  	testutil.WaitForLeader(t, s1.RPC)
   574  
   575  	// Create the tokens
   576  	p1 := mock.ACLToken()
   577  	p2 := mock.ACLToken()
   578  
   579  	// First create an unrelated token
   580  	time.AfterFunc(100*time.Millisecond, func() {
   581  		err := state.UpsertACLTokens(100, []*structs.ACLToken{p1})
   582  		if err != nil {
   583  			t.Fatalf("err: %v", err)
   584  		}
   585  	})
   586  
   587  	// Upsert the token we are watching later
   588  	time.AfterFunc(200*time.Millisecond, func() {
   589  		err := state.UpsertACLTokens(200, []*structs.ACLToken{p2})
   590  		if err != nil {
   591  			t.Fatalf("err: %v", err)
   592  		}
   593  	})
   594  
   595  	// Lookup the token
   596  	req := &structs.ACLTokenSpecificRequest{
   597  		AccessorID: p2.AccessorID,
   598  		QueryOptions: structs.QueryOptions{
   599  			Region:        "global",
   600  			MinQueryIndex: 150,
   601  			AuthToken:     root.SecretID,
   602  		},
   603  	}
   604  	var resp structs.SingleACLTokenResponse
   605  	start := time.Now()
   606  	if err := msgpackrpc.CallWithCodec(codec, "ACL.GetToken", req, &resp); err != nil {
   607  		t.Fatalf("err: %v", err)
   608  	}
   609  
   610  	if elapsed := time.Since(start); elapsed < 200*time.Millisecond {
   611  		t.Fatalf("should block (returned in %s) %#v", elapsed, resp)
   612  	}
   613  	if resp.Index != 200 {
   614  		t.Fatalf("Bad index: %d %d", resp.Index, 200)
   615  	}
   616  	if resp.Token == nil || resp.Token.AccessorID != p2.AccessorID {
   617  		t.Fatalf("bad: %#v", resp.Token)
   618  	}
   619  
   620  	// Eval delete triggers watches
   621  	time.AfterFunc(100*time.Millisecond, func() {
   622  		err := state.DeleteACLTokens(300, []string{p2.AccessorID})
   623  		if err != nil {
   624  			t.Fatalf("err: %v", err)
   625  		}
   626  	})
   627  
   628  	req.QueryOptions.MinQueryIndex = 250
   629  	var resp2 structs.SingleACLTokenResponse
   630  	start = time.Now()
   631  	if err := msgpackrpc.CallWithCodec(codec, "ACL.GetToken", req, &resp2); err != nil {
   632  		t.Fatalf("err: %v", err)
   633  	}
   634  
   635  	if elapsed := time.Since(start); elapsed < 100*time.Millisecond {
   636  		t.Fatalf("should block (returned in %s) %#v", elapsed, resp2)
   637  	}
   638  	if resp2.Index != 300 {
   639  		t.Fatalf("Bad index: %d %d", resp2.Index, 300)
   640  	}
   641  	if resp2.Token != nil {
   642  		t.Fatalf("bad: %#v", resp2.Token)
   643  	}
   644  }
   645  
   646  func TestACLEndpoint_GetTokens(t *testing.T) {
   647  	t.Parallel()
   648  	s1, root := TestACLServer(t, nil)
   649  	defer s1.Shutdown()
   650  	codec := rpcClient(t, s1)
   651  	testutil.WaitForLeader(t, s1.RPC)
   652  
   653  	// Create the register request
   654  	token := mock.ACLToken()
   655  	token2 := mock.ACLToken()
   656  	s1.fsm.State().UpsertACLTokens(1000, []*structs.ACLToken{token, token2})
   657  
   658  	// Lookup the token
   659  	get := &structs.ACLTokenSetRequest{
   660  		AccessorIDS: []string{token.AccessorID, token2.AccessorID},
   661  		QueryOptions: structs.QueryOptions{
   662  			Region:    "global",
   663  			AuthToken: root.SecretID,
   664  		},
   665  	}
   666  	var resp structs.ACLTokenSetResponse
   667  	if err := msgpackrpc.CallWithCodec(codec, "ACL.GetTokens", get, &resp); err != nil {
   668  		t.Fatalf("err: %v", err)
   669  	}
   670  	assert.Equal(t, uint64(1000), resp.Index)
   671  	assert.Equal(t, 2, len(resp.Tokens))
   672  	assert.Equal(t, token, resp.Tokens[token.AccessorID])
   673  
   674  	// Lookup non-existing token
   675  	get.AccessorIDS = []string{uuid.Generate()}
   676  	resp = structs.ACLTokenSetResponse{}
   677  	if err := msgpackrpc.CallWithCodec(codec, "ACL.GetTokens", get, &resp); err != nil {
   678  		t.Fatalf("err: %v", err)
   679  	}
   680  	assert.Equal(t, uint64(1000), resp.Index)
   681  	assert.Equal(t, 0, len(resp.Tokens))
   682  }
   683  
   684  func TestACLEndpoint_GetTokens_Blocking(t *testing.T) {
   685  	t.Parallel()
   686  	s1, root := TestACLServer(t, nil)
   687  	defer s1.Shutdown()
   688  	state := s1.fsm.State()
   689  	codec := rpcClient(t, s1)
   690  	testutil.WaitForLeader(t, s1.RPC)
   691  
   692  	// Create the tokens
   693  	p1 := mock.ACLToken()
   694  	p2 := mock.ACLToken()
   695  
   696  	// First create an unrelated token
   697  	time.AfterFunc(100*time.Millisecond, func() {
   698  		err := state.UpsertACLTokens(100, []*structs.ACLToken{p1})
   699  		if err != nil {
   700  			t.Fatalf("err: %v", err)
   701  		}
   702  	})
   703  
   704  	// Upsert the token we are watching later
   705  	time.AfterFunc(200*time.Millisecond, func() {
   706  		err := state.UpsertACLTokens(200, []*structs.ACLToken{p2})
   707  		if err != nil {
   708  			t.Fatalf("err: %v", err)
   709  		}
   710  	})
   711  
   712  	// Lookup the token
   713  	req := &structs.ACLTokenSetRequest{
   714  		AccessorIDS: []string{p2.AccessorID},
   715  		QueryOptions: structs.QueryOptions{
   716  			Region:        "global",
   717  			MinQueryIndex: 150,
   718  			AuthToken:     root.SecretID,
   719  		},
   720  	}
   721  	var resp structs.ACLTokenSetResponse
   722  	start := time.Now()
   723  	if err := msgpackrpc.CallWithCodec(codec, "ACL.GetTokens", req, &resp); err != nil {
   724  		t.Fatalf("err: %v", err)
   725  	}
   726  
   727  	if elapsed := time.Since(start); elapsed < 200*time.Millisecond {
   728  		t.Fatalf("should block (returned in %s) %#v", elapsed, resp)
   729  	}
   730  	if resp.Index != 200 {
   731  		t.Fatalf("Bad index: %d %d", resp.Index, 200)
   732  	}
   733  	if len(resp.Tokens) == 0 || resp.Tokens[p2.AccessorID] == nil {
   734  		t.Fatalf("bad: %#v", resp.Tokens)
   735  	}
   736  
   737  	// Eval delete triggers watches
   738  	time.AfterFunc(100*time.Millisecond, func() {
   739  		err := state.DeleteACLTokens(300, []string{p2.AccessorID})
   740  		if err != nil {
   741  			t.Fatalf("err: %v", err)
   742  		}
   743  	})
   744  
   745  	req.QueryOptions.MinQueryIndex = 250
   746  	var resp2 structs.ACLTokenSetResponse
   747  	start = time.Now()
   748  	if err := msgpackrpc.CallWithCodec(codec, "ACL.GetTokens", req, &resp2); err != nil {
   749  		t.Fatalf("err: %v", err)
   750  	}
   751  
   752  	if elapsed := time.Since(start); elapsed < 100*time.Millisecond {
   753  		t.Fatalf("should block (returned in %s) %#v", elapsed, resp2)
   754  	}
   755  	if resp2.Index != 300 {
   756  		t.Fatalf("Bad index: %d %d", resp2.Index, 300)
   757  	}
   758  	if len(resp2.Tokens) != 0 {
   759  		t.Fatalf("bad: %#v", resp2.Tokens)
   760  	}
   761  }
   762  
   763  func TestACLEndpoint_ListTokens(t *testing.T) {
   764  	t.Parallel()
   765  	s1, root := TestACLServer(t, nil)
   766  	defer s1.Shutdown()
   767  	codec := rpcClient(t, s1)
   768  	testutil.WaitForLeader(t, s1.RPC)
   769  
   770  	// Create the register request
   771  	p1 := mock.ACLToken()
   772  	p2 := mock.ACLToken()
   773  	p2.Global = true
   774  
   775  	p1.AccessorID = "aaaaaaaa-3350-4b4b-d185-0e1992ed43e9"
   776  	p2.AccessorID = "aaaabbbb-3350-4b4b-d185-0e1992ed43e9"
   777  	s1.fsm.State().UpsertACLTokens(1000, []*structs.ACLToken{p1, p2})
   778  
   779  	// Lookup the tokens
   780  	get := &structs.ACLTokenListRequest{
   781  		QueryOptions: structs.QueryOptions{
   782  			Region:    "global",
   783  			AuthToken: root.SecretID,
   784  		},
   785  	}
   786  	var resp structs.ACLTokenListResponse
   787  	if err := msgpackrpc.CallWithCodec(codec, "ACL.ListTokens", get, &resp); err != nil {
   788  		t.Fatalf("err: %v", err)
   789  	}
   790  	assert.Equal(t, uint64(1000), resp.Index)
   791  	assert.Equal(t, 3, len(resp.Tokens))
   792  
   793  	// Lookup the tokens by prefix
   794  	get = &structs.ACLTokenListRequest{
   795  		QueryOptions: structs.QueryOptions{
   796  			Region:    "global",
   797  			Prefix:    "aaaabb",
   798  			AuthToken: root.SecretID,
   799  		},
   800  	}
   801  	var resp2 structs.ACLTokenListResponse
   802  	if err := msgpackrpc.CallWithCodec(codec, "ACL.ListTokens", get, &resp2); err != nil {
   803  		t.Fatalf("err: %v", err)
   804  	}
   805  	assert.Equal(t, uint64(1000), resp2.Index)
   806  	assert.Equal(t, 1, len(resp2.Tokens))
   807  
   808  	// Lookup the global tokens
   809  	get = &structs.ACLTokenListRequest{
   810  		GlobalOnly: true,
   811  		QueryOptions: structs.QueryOptions{
   812  			Region:    "global",
   813  			AuthToken: root.SecretID,
   814  		},
   815  	}
   816  	var resp3 structs.ACLTokenListResponse
   817  	if err := msgpackrpc.CallWithCodec(codec, "ACL.ListTokens", get, &resp3); err != nil {
   818  		t.Fatalf("err: %v", err)
   819  	}
   820  	assert.Equal(t, uint64(1000), resp3.Index)
   821  	assert.Equal(t, 2, len(resp3.Tokens))
   822  }
   823  
   824  func TestACLEndpoint_ListTokens_Blocking(t *testing.T) {
   825  	t.Parallel()
   826  	s1, root := TestACLServer(t, nil)
   827  	defer s1.Shutdown()
   828  	state := s1.fsm.State()
   829  	codec := rpcClient(t, s1)
   830  	testutil.WaitForLeader(t, s1.RPC)
   831  
   832  	// Create the token
   833  	token := mock.ACLToken()
   834  
   835  	// Upsert eval triggers watches
   836  	time.AfterFunc(100*time.Millisecond, func() {
   837  		if err := state.UpsertACLTokens(3, []*structs.ACLToken{token}); err != nil {
   838  			t.Fatalf("err: %v", err)
   839  		}
   840  	})
   841  
   842  	req := &structs.ACLTokenListRequest{
   843  		QueryOptions: structs.QueryOptions{
   844  			Region:        "global",
   845  			MinQueryIndex: 2,
   846  			AuthToken:     root.SecretID,
   847  		},
   848  	}
   849  	start := time.Now()
   850  	var resp structs.ACLTokenListResponse
   851  	if err := msgpackrpc.CallWithCodec(codec, "ACL.ListTokens", req, &resp); err != nil {
   852  		t.Fatalf("err: %v", err)
   853  	}
   854  
   855  	if elapsed := time.Since(start); elapsed < 100*time.Millisecond {
   856  		t.Fatalf("should block (returned in %s) %#v", elapsed, resp)
   857  	}
   858  	assert.Equal(t, uint64(3), resp.Index)
   859  	if len(resp.Tokens) != 2 {
   860  		t.Fatalf("bad: %#v", resp.Tokens)
   861  	}
   862  
   863  	// Eval deletion triggers watches
   864  	time.AfterFunc(100*time.Millisecond, func() {
   865  		if err := state.DeleteACLTokens(4, []string{token.AccessorID}); err != nil {
   866  			t.Fatalf("err: %v", err)
   867  		}
   868  	})
   869  
   870  	req.MinQueryIndex = 3
   871  	start = time.Now()
   872  	var resp2 structs.ACLTokenListResponse
   873  	if err := msgpackrpc.CallWithCodec(codec, "ACL.ListTokens", req, &resp2); err != nil {
   874  		t.Fatalf("err: %v", err)
   875  	}
   876  
   877  	if elapsed := time.Since(start); elapsed < 100*time.Millisecond {
   878  		t.Fatalf("should block (returned in %s) %#v", elapsed, resp2)
   879  	}
   880  	assert.Equal(t, uint64(4), resp2.Index)
   881  	assert.Equal(t, 1, len(resp2.Tokens))
   882  }
   883  
   884  func TestACLEndpoint_DeleteTokens(t *testing.T) {
   885  	t.Parallel()
   886  	s1, root := TestACLServer(t, nil)
   887  	defer s1.Shutdown()
   888  	codec := rpcClient(t, s1)
   889  	testutil.WaitForLeader(t, s1.RPC)
   890  
   891  	// Create the register request
   892  	p1 := mock.ACLToken()
   893  	s1.fsm.State().UpsertACLTokens(1000, []*structs.ACLToken{p1})
   894  
   895  	// Lookup the tokens
   896  	req := &structs.ACLTokenDeleteRequest{
   897  		AccessorIDs: []string{p1.AccessorID},
   898  		WriteRequest: structs.WriteRequest{
   899  			Region:    "global",
   900  			AuthToken: root.SecretID,
   901  		},
   902  	}
   903  	var resp structs.GenericResponse
   904  	if err := msgpackrpc.CallWithCodec(codec, "ACL.DeleteTokens", req, &resp); err != nil {
   905  		t.Fatalf("err: %v", err)
   906  	}
   907  	assert.NotEqual(t, uint64(0), resp.Index)
   908  }
   909  
   910  func TestACLEndpoint_DeleteTokens_WithNonexistentToken(t *testing.T) {
   911  	t.Parallel()
   912  	assert := assert.New(t)
   913  
   914  	s1, root := TestACLServer(t, nil)
   915  	defer s1.Shutdown()
   916  	codec := rpcClient(t, s1)
   917  	testutil.WaitForLeader(t, s1.RPC)
   918  
   919  	nonexistentToken := mock.ACLToken()
   920  
   921  	// Lookup the policies
   922  	req := &structs.ACLTokenDeleteRequest{
   923  		AccessorIDs: []string{nonexistentToken.AccessorID},
   924  		WriteRequest: structs.WriteRequest{
   925  			Region:    "global",
   926  			AuthToken: root.SecretID,
   927  		},
   928  	}
   929  	var resp structs.GenericResponse
   930  	err := msgpackrpc.CallWithCodec(codec, "ACL.DeleteTokens", req, &resp)
   931  
   932  	assert.NotNil(err)
   933  	expectedError := fmt.Sprintf("Cannot delete nonexistent tokens: %s", nonexistentToken.AccessorID)
   934  	assert.Contains(expectedError, err.Error())
   935  }
   936  
   937  func TestACLEndpoint_Bootstrap(t *testing.T) {
   938  	t.Parallel()
   939  	s1 := TestServer(t, func(c *Config) {
   940  		c.ACLEnabled = true
   941  	})
   942  	defer s1.Shutdown()
   943  	codec := rpcClient(t, s1)
   944  	testutil.WaitForLeader(t, s1.RPC)
   945  
   946  	// Lookup the tokens
   947  	req := &structs.ACLTokenBootstrapRequest{
   948  		WriteRequest: structs.WriteRequest{Region: "global"},
   949  	}
   950  	var resp structs.ACLTokenUpsertResponse
   951  	if err := msgpackrpc.CallWithCodec(codec, "ACL.Bootstrap", req, &resp); err != nil {
   952  		t.Fatalf("err: %v", err)
   953  	}
   954  	assert.NotEqual(t, uint64(0), resp.Index)
   955  	assert.NotNil(t, resp.Tokens[0])
   956  
   957  	// Get the token out from the response
   958  	created := resp.Tokens[0]
   959  	assert.NotEqual(t, "", created.AccessorID)
   960  	assert.NotEqual(t, "", created.SecretID)
   961  	assert.NotEqual(t, time.Time{}, created.CreateTime)
   962  	assert.Equal(t, structs.ACLManagementToken, created.Type)
   963  	assert.Equal(t, "Bootstrap Token", created.Name)
   964  	assert.Equal(t, true, created.Global)
   965  
   966  	// Check we created the token
   967  	out, err := s1.fsm.State().ACLTokenByAccessorID(nil, created.AccessorID)
   968  	assert.Nil(t, err)
   969  	assert.Equal(t, created, out)
   970  }
   971  
   972  func TestACLEndpoint_Bootstrap_Reset(t *testing.T) {
   973  	t.Parallel()
   974  	dir := tmpDir(t)
   975  	defer os.RemoveAll(dir)
   976  	s1 := TestServer(t, func(c *Config) {
   977  		c.ACLEnabled = true
   978  		c.DataDir = dir
   979  		c.DevMode = false
   980  		c.Bootstrap = true
   981  		c.DevDisableBootstrap = false
   982  	})
   983  	defer s1.Shutdown()
   984  	codec := rpcClient(t, s1)
   985  	testutil.WaitForLeader(t, s1.RPC)
   986  
   987  	// Lookup the tokens
   988  	req := &structs.ACLTokenBootstrapRequest{
   989  		WriteRequest: structs.WriteRequest{Region: "global"},
   990  	}
   991  	var resp structs.ACLTokenUpsertResponse
   992  	if err := msgpackrpc.CallWithCodec(codec, "ACL.Bootstrap", req, &resp); err != nil {
   993  		t.Fatalf("err: %v", err)
   994  	}
   995  	assert.NotEqual(t, uint64(0), resp.Index)
   996  	assert.NotNil(t, resp.Tokens[0])
   997  	resetIdx := resp.Tokens[0].CreateIndex
   998  
   999  	// Try again, should fail
  1000  	if err := msgpackrpc.CallWithCodec(codec, "ACL.Bootstrap", req, &resp); err == nil {
  1001  		t.Fatalf("expected err")
  1002  	}
  1003  
  1004  	// Create the reset file
  1005  	output := []byte(fmt.Sprintf("%d", resetIdx))
  1006  	path := filepath.Join(dir, aclBootstrapReset)
  1007  	assert.Nil(t, ioutil.WriteFile(path, output, 0755))
  1008  
  1009  	// Try again, should work with reset
  1010  	if err := msgpackrpc.CallWithCodec(codec, "ACL.Bootstrap", req, &resp); err != nil {
  1011  		t.Fatalf("err: %v", err)
  1012  	}
  1013  	assert.NotEqual(t, uint64(0), resp.Index)
  1014  	assert.NotNil(t, resp.Tokens[0])
  1015  
  1016  	// Get the token out from the response
  1017  	created := resp.Tokens[0]
  1018  	assert.NotEqual(t, "", created.AccessorID)
  1019  	assert.NotEqual(t, "", created.SecretID)
  1020  	assert.NotEqual(t, time.Time{}, created.CreateTime)
  1021  	assert.Equal(t, structs.ACLManagementToken, created.Type)
  1022  	assert.Equal(t, "Bootstrap Token", created.Name)
  1023  	assert.Equal(t, true, created.Global)
  1024  
  1025  	// Check we created the token
  1026  	out, err := s1.fsm.State().ACLTokenByAccessorID(nil, created.AccessorID)
  1027  	assert.Nil(t, err)
  1028  	assert.Equal(t, created, out)
  1029  
  1030  	// Try again, should fail
  1031  	if err := msgpackrpc.CallWithCodec(codec, "ACL.Bootstrap", req, &resp); err == nil {
  1032  		t.Fatalf("expected err")
  1033  	}
  1034  }
  1035  
  1036  func TestACLEndpoint_UpsertTokens(t *testing.T) {
  1037  	t.Parallel()
  1038  	s1, root := TestACLServer(t, nil)
  1039  	defer s1.Shutdown()
  1040  	codec := rpcClient(t, s1)
  1041  	testutil.WaitForLeader(t, s1.RPC)
  1042  
  1043  	// Create the register request
  1044  	p1 := mock.ACLToken()
  1045  	p1.AccessorID = "" // Blank to create
  1046  
  1047  	// Lookup the tokens
  1048  	req := &structs.ACLTokenUpsertRequest{
  1049  		Tokens: []*structs.ACLToken{p1},
  1050  		WriteRequest: structs.WriteRequest{
  1051  			Region:    "global",
  1052  			AuthToken: root.SecretID,
  1053  		},
  1054  	}
  1055  	var resp structs.ACLTokenUpsertResponse
  1056  	if err := msgpackrpc.CallWithCodec(codec, "ACL.UpsertTokens", req, &resp); err != nil {
  1057  		t.Fatalf("err: %v", err)
  1058  	}
  1059  	assert.NotEqual(t, uint64(0), resp.Index)
  1060  
  1061  	// Get the token out from the response
  1062  	created := resp.Tokens[0]
  1063  	assert.NotEqual(t, "", created.AccessorID)
  1064  	assert.NotEqual(t, "", created.SecretID)
  1065  	assert.NotEqual(t, time.Time{}, created.CreateTime)
  1066  	assert.Equal(t, p1.Type, created.Type)
  1067  	assert.Equal(t, p1.Policies, created.Policies)
  1068  	assert.Equal(t, p1.Name, created.Name)
  1069  
  1070  	// Check we created the token
  1071  	out, err := s1.fsm.State().ACLTokenByAccessorID(nil, created.AccessorID)
  1072  	assert.Nil(t, err)
  1073  	assert.Equal(t, created, out)
  1074  
  1075  	// Update the token type
  1076  	req.Tokens[0] = created
  1077  	created.Type = "management"
  1078  	created.Policies = nil
  1079  
  1080  	// Upsert again
  1081  	if err := msgpackrpc.CallWithCodec(codec, "ACL.UpsertTokens", req, &resp); err != nil {
  1082  		t.Fatalf("err: %v", err)
  1083  	}
  1084  	assert.NotEqual(t, uint64(0), resp.Index)
  1085  
  1086  	// Check we modified the token
  1087  	out, err = s1.fsm.State().ACLTokenByAccessorID(nil, created.AccessorID)
  1088  	assert.Nil(t, err)
  1089  	assert.Equal(t, created, out)
  1090  }
  1091  
  1092  func TestACLEndpoint_UpsertTokens_Invalid(t *testing.T) {
  1093  	t.Parallel()
  1094  	s1, root := TestACLServer(t, nil)
  1095  	defer s1.Shutdown()
  1096  	codec := rpcClient(t, s1)
  1097  	testutil.WaitForLeader(t, s1.RPC)
  1098  
  1099  	// Create the register request
  1100  	p1 := mock.ACLToken()
  1101  	p1.Type = "blah blah"
  1102  
  1103  	// Lookup the tokens
  1104  	req := &structs.ACLTokenUpsertRequest{
  1105  		Tokens: []*structs.ACLToken{p1},
  1106  		WriteRequest: structs.WriteRequest{
  1107  			Region:    "global",
  1108  			AuthToken: root.SecretID,
  1109  		},
  1110  	}
  1111  	var resp structs.GenericResponse
  1112  	err := msgpackrpc.CallWithCodec(codec, "ACL.UpsertTokens", req, &resp)
  1113  	assert.NotNil(t, err)
  1114  	if !strings.Contains(err.Error(), "client or management") {
  1115  		t.Fatalf("bad: %s", err)
  1116  	}
  1117  }
  1118  
  1119  func TestACLEndpoint_ResolveToken(t *testing.T) {
  1120  	t.Parallel()
  1121  	s1, _ := TestACLServer(t, nil)
  1122  	defer s1.Shutdown()
  1123  	codec := rpcClient(t, s1)
  1124  	testutil.WaitForLeader(t, s1.RPC)
  1125  
  1126  	// Create the register request
  1127  	token := mock.ACLToken()
  1128  	s1.fsm.State().UpsertACLTokens(1000, []*structs.ACLToken{token})
  1129  
  1130  	// Lookup the token
  1131  	get := &structs.ResolveACLTokenRequest{
  1132  		SecretID:     token.SecretID,
  1133  		QueryOptions: structs.QueryOptions{Region: "global"},
  1134  	}
  1135  	var resp structs.ResolveACLTokenResponse
  1136  	if err := msgpackrpc.CallWithCodec(codec, "ACL.ResolveToken", get, &resp); err != nil {
  1137  		t.Fatalf("err: %v", err)
  1138  	}
  1139  	assert.Equal(t, uint64(1000), resp.Index)
  1140  	assert.Equal(t, token, resp.Token)
  1141  
  1142  	// Lookup non-existing token
  1143  	get.SecretID = uuid.Generate()
  1144  	if err := msgpackrpc.CallWithCodec(codec, "ACL.ResolveToken", get, &resp); err != nil {
  1145  		t.Fatalf("err: %v", err)
  1146  	}
  1147  	assert.Equal(t, uint64(1000), resp.Index)
  1148  	assert.Nil(t, resp.Token)
  1149  }