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