github.com/outbrain/consul@v1.4.5/api/acl_test.go (about) 1 package api 2 3 import ( 4 "strings" 5 "testing" 6 7 "github.com/hashicorp/consul/testutil/retry" 8 9 "github.com/stretchr/testify/require" 10 ) 11 12 func TestAPI_ACLBootstrap(t *testing.T) { 13 // TODO (slackpad) We currently can't inject the version, and the 14 // version in the binary depends on Git tags, so we can't reliably 15 // test this until we are just running an agent in-process here and 16 // have full control over the config. 17 } 18 19 func TestAPI_ACLCreateDestroy(t *testing.T) { 20 t.Parallel() 21 c, s := makeACLClient(t) 22 defer s.Stop() 23 s.WaitForSerfCheck(t) 24 25 acl := c.ACL() 26 27 ae := ACLEntry{ 28 Name: "API test", 29 Type: ACLClientType, 30 Rules: `key "" { policy = "deny" }`, 31 } 32 33 id, wm, err := acl.Create(&ae, nil) 34 if err != nil { 35 t.Fatalf("err: %v", err) 36 } 37 38 if wm.RequestTime == 0 { 39 t.Fatalf("bad: %v", wm) 40 } 41 42 if id == "" { 43 t.Fatalf("invalid: %v", id) 44 } 45 46 ae2, _, err := acl.Info(id, nil) 47 if err != nil { 48 t.Fatalf("err: %v", err) 49 } 50 51 if ae2.Name != ae.Name || ae2.Type != ae.Type || ae2.Rules != ae.Rules { 52 t.Fatalf("Bad: %#v", ae2) 53 } 54 55 wm, err = acl.Destroy(id, nil) 56 if err != nil { 57 t.Fatalf("err: %v", err) 58 } 59 60 if wm.RequestTime == 0 { 61 t.Fatalf("bad: %v", wm) 62 } 63 } 64 65 func TestAPI_ACLCloneDestroy(t *testing.T) { 66 t.Parallel() 67 c, s := makeACLClient(t) 68 defer s.Stop() 69 70 acl := c.ACL() 71 72 id, wm, err := acl.Clone(c.config.Token, nil) 73 if err != nil { 74 t.Fatalf("err: %v", err) 75 } 76 77 if wm.RequestTime == 0 { 78 t.Fatalf("bad: %v", wm) 79 } 80 81 if id == "" { 82 t.Fatalf("invalid: %v", id) 83 } 84 85 wm, err = acl.Destroy(id, nil) 86 if err != nil { 87 t.Fatalf("err: %v", err) 88 } 89 90 if wm.RequestTime == 0 { 91 t.Fatalf("bad: %v", wm) 92 } 93 } 94 95 func TestAPI_ACLInfo(t *testing.T) { 96 t.Parallel() 97 c, s := makeACLClient(t) 98 defer s.Stop() 99 100 acl := c.ACL() 101 102 ae, qm, err := acl.Info(c.config.Token, nil) 103 if err != nil { 104 t.Fatalf("err: %v", err) 105 } 106 107 if qm.LastIndex == 0 { 108 t.Fatalf("bad: %v", qm) 109 } 110 if !qm.KnownLeader { 111 t.Fatalf("bad: %v", qm) 112 } 113 114 if ae == nil || ae.ID != c.config.Token || ae.Type != ACLManagementType { 115 t.Fatalf("bad: %#v", ae) 116 } 117 } 118 119 func TestAPI_ACLList(t *testing.T) { 120 t.Parallel() 121 c, s := makeACLClient(t) 122 defer s.Stop() 123 124 acl := c.ACL() 125 126 acls, qm, err := acl.List(nil) 127 if err != nil { 128 t.Fatalf("err: %v", err) 129 } 130 131 // anon token is a new token 132 if len(acls) < 1 { 133 t.Fatalf("bad: %v", acls) 134 } 135 136 if qm.LastIndex == 0 { 137 t.Fatalf("bad: %v", qm) 138 } 139 if !qm.KnownLeader { 140 t.Fatalf("bad: %v", qm) 141 } 142 } 143 144 func TestAPI_ACLReplication(t *testing.T) { 145 t.Parallel() 146 c, s := makeACLClient(t) 147 defer s.Stop() 148 149 acl := c.ACL() 150 151 repl, qm, err := acl.Replication(nil) 152 if err != nil { 153 t.Fatalf("err: %v", err) 154 } 155 156 if repl == nil { 157 t.Fatalf("bad: %v", repl) 158 } 159 160 if repl.Running { 161 t.Fatal("bad: repl should not be running") 162 } 163 164 if repl.Enabled { 165 t.Fatal("bad: repl should not be enabled") 166 } 167 168 if qm.RequestTime == 0 { 169 t.Fatalf("bad: %v", qm) 170 } 171 } 172 173 func TestAPI_ACLPolicy_CreateReadDelete(t *testing.T) { 174 t.Parallel() 175 c, s := makeACLClient(t) 176 defer s.Stop() 177 178 acl := c.ACL() 179 180 created, wm, err := acl.PolicyCreate(&ACLPolicy{ 181 Name: "test-policy", 182 Description: "test-policy description", 183 Rules: `node_prefix "" { policy = "read" }`, 184 Datacenters: []string{"dc1"}, 185 }, nil) 186 187 require.NoError(t, err) 188 require.NotNil(t, created) 189 require.NotEqual(t, "", created.ID) 190 require.NotEqual(t, 0, wm.RequestTime) 191 192 read, qm, err := acl.PolicyRead(created.ID, nil) 193 require.NoError(t, err) 194 require.NotEqual(t, 0, qm.LastIndex) 195 require.True(t, qm.KnownLeader) 196 197 require.Equal(t, created, read) 198 199 wm, err = acl.PolicyDelete(created.ID, nil) 200 require.NoError(t, err) 201 require.NotEqual(t, 0, wm.RequestTime) 202 203 read, _, err = acl.PolicyRead(created.ID, nil) 204 require.Nil(t, read) 205 require.Error(t, err) 206 } 207 208 func TestAPI_ACLPolicy_CreateUpdate(t *testing.T) { 209 t.Parallel() 210 c, s := makeACLClient(t) 211 defer s.Stop() 212 213 acl := c.ACL() 214 215 created, _, err := acl.PolicyCreate(&ACLPolicy{ 216 Name: "test-policy", 217 Description: "test-policy description", 218 Rules: `node_prefix "" { policy = "read" }`, 219 Datacenters: []string{"dc1"}, 220 }, nil) 221 222 require.NoError(t, err) 223 require.NotNil(t, created) 224 require.NotEqual(t, "", created.ID) 225 226 read, _, err := acl.PolicyRead(created.ID, nil) 227 require.NoError(t, err) 228 require.Equal(t, created, read) 229 230 read.Rules += ` service_prefix "" { policy = "read" }` 231 read.Datacenters = nil 232 233 updated, wm, err := acl.PolicyUpdate(read, nil) 234 require.NoError(t, err) 235 require.Equal(t, created.ID, updated.ID) 236 require.Equal(t, created.Description, updated.Description) 237 require.Equal(t, read.Rules, updated.Rules) 238 require.Equal(t, created.CreateIndex, updated.CreateIndex) 239 require.NotEqual(t, created.ModifyIndex, updated.ModifyIndex) 240 require.Nil(t, updated.Datacenters) 241 require.NotEqual(t, 0, wm.RequestTime) 242 243 updated_read, _, err := acl.PolicyRead(created.ID, nil) 244 require.NoError(t, err) 245 require.Equal(t, updated, updated_read) 246 } 247 248 func TestAPI_ACLPolicy_List(t *testing.T) { 249 t.Parallel() 250 c, s := makeACLClient(t) 251 defer s.Stop() 252 253 acl := c.ACL() 254 255 created1, _, err := acl.PolicyCreate(&ACLPolicy{ 256 Name: "policy1", 257 Description: "policy1 description", 258 Rules: `node_prefix "" { policy = "read" }`, 259 Datacenters: []string{"dc1"}, 260 }, nil) 261 262 require.NoError(t, err) 263 require.NotNil(t, created1) 264 require.NotEqual(t, "", created1.ID) 265 266 created2, _, err := acl.PolicyCreate(&ACLPolicy{ 267 Name: "policy2", 268 Description: "policy2 description", 269 Rules: `service "app" { policy = "write" }`, 270 Datacenters: []string{"dc1", "dc2"}, 271 }, nil) 272 273 require.NoError(t, err) 274 require.NotNil(t, created2) 275 require.NotEqual(t, "", created2.ID) 276 277 created3, _, err := acl.PolicyCreate(&ACLPolicy{ 278 Name: "policy3", 279 Description: "policy3 description", 280 Rules: `acl = "read"`, 281 }, nil) 282 283 require.NoError(t, err) 284 require.NotNil(t, created3) 285 require.NotEqual(t, "", created3.ID) 286 287 policies, qm, err := acl.PolicyList(nil) 288 require.NoError(t, err) 289 require.Len(t, policies, 4) 290 require.NotEqual(t, 0, qm.LastIndex) 291 require.True(t, qm.KnownLeader) 292 293 policyMap := make(map[string]*ACLPolicyListEntry) 294 for _, policy := range policies { 295 policyMap[policy.ID] = policy 296 } 297 298 policy1, ok := policyMap[created1.ID] 299 require.True(t, ok) 300 require.NotNil(t, policy1) 301 require.Equal(t, created1.Name, policy1.Name) 302 require.Equal(t, created1.Description, policy1.Description) 303 require.Equal(t, created1.CreateIndex, policy1.CreateIndex) 304 require.Equal(t, created1.ModifyIndex, policy1.ModifyIndex) 305 require.Equal(t, created1.Hash, policy1.Hash) 306 require.ElementsMatch(t, created1.Datacenters, policy1.Datacenters) 307 308 policy2, ok := policyMap[created2.ID] 309 require.True(t, ok) 310 require.NotNil(t, policy2) 311 require.Equal(t, created2.Name, policy2.Name) 312 require.Equal(t, created2.Description, policy2.Description) 313 require.Equal(t, created2.CreateIndex, policy2.CreateIndex) 314 require.Equal(t, created2.ModifyIndex, policy2.ModifyIndex) 315 require.Equal(t, created2.Hash, policy2.Hash) 316 require.ElementsMatch(t, created2.Datacenters, policy2.Datacenters) 317 318 policy3, ok := policyMap[created3.ID] 319 require.True(t, ok) 320 require.NotNil(t, policy3) 321 require.Equal(t, created3.Name, policy3.Name) 322 require.Equal(t, created3.Description, policy3.Description) 323 require.Equal(t, created3.CreateIndex, policy3.CreateIndex) 324 require.Equal(t, created3.ModifyIndex, policy3.ModifyIndex) 325 require.Equal(t, created3.Hash, policy3.Hash) 326 require.ElementsMatch(t, created3.Datacenters, policy3.Datacenters) 327 328 // make sure the 4th policy is the global management 329 policy4, ok := policyMap["00000000-0000-0000-0000-000000000001"] 330 require.True(t, ok) 331 require.NotNil(t, policy4) 332 } 333 334 func prepTokenPolicies(t *testing.T, acl *ACL) (policies []*ACLPolicy) { 335 policy, _, err := acl.PolicyCreate(&ACLPolicy{ 336 Name: "one", 337 Description: "one description", 338 Rules: `acl = "read"`, 339 Datacenters: []string{"dc1", "dc2"}, 340 }, nil) 341 342 require.NoError(t, err) 343 require.NotNil(t, policy) 344 policies = append(policies, policy) 345 346 policy, _, err = acl.PolicyCreate(&ACLPolicy{ 347 Name: "two", 348 Description: "two description", 349 Rules: `node_prefix "" { policy = "read" }`, 350 Datacenters: []string{"dc1", "dc2"}, 351 }, nil) 352 353 require.NoError(t, err) 354 require.NotNil(t, policy) 355 policies = append(policies, policy) 356 357 policy, _, err = acl.PolicyCreate(&ACLPolicy{ 358 Name: "three", 359 Description: "three description", 360 Rules: `service_prefix "" { policy = "read" }`, 361 }, nil) 362 363 require.NoError(t, err) 364 require.NotNil(t, policy) 365 policies = append(policies, policy) 366 367 policy, _, err = acl.PolicyCreate(&ACLPolicy{ 368 Name: "four", 369 Description: "four description", 370 Rules: `agent "foo" { policy = "write" }`, 371 }, nil) 372 373 require.NoError(t, err) 374 require.NotNil(t, policy) 375 policies = append(policies, policy) 376 return 377 } 378 379 func TestAPI_ACLToken_CreateReadDelete(t *testing.T) { 380 t.Parallel() 381 c, s := makeACLClient(t) 382 defer s.Stop() 383 384 acl := c.ACL() 385 386 policies := prepTokenPolicies(t, acl) 387 388 created, wm, err := acl.TokenCreate(&ACLToken{ 389 Description: "token created", 390 Policies: []*ACLTokenPolicyLink{ 391 &ACLTokenPolicyLink{ 392 ID: policies[0].ID, 393 }, 394 &ACLTokenPolicyLink{ 395 ID: policies[1].ID, 396 }, 397 &ACLTokenPolicyLink{ 398 Name: policies[2].Name, 399 }, 400 &ACLTokenPolicyLink{ 401 Name: policies[3].Name, 402 }, 403 }, 404 }, nil) 405 406 require.NoError(t, err) 407 require.NotNil(t, created) 408 require.NotEqual(t, "", created.AccessorID) 409 require.NotEqual(t, "", created.SecretID) 410 require.NotEqual(t, 0, wm.RequestTime) 411 412 read, qm, err := acl.TokenRead(created.AccessorID, nil) 413 require.NoError(t, err) 414 require.Equal(t, created, read) 415 require.NotEqual(t, 0, qm.LastIndex) 416 require.True(t, qm.KnownLeader) 417 418 acl.c.config.Token = created.SecretID 419 self, _, err := acl.TokenReadSelf(nil) 420 require.NoError(t, err) 421 require.Equal(t, created, self) 422 acl.c.config.Token = "root" 423 424 _, err = acl.TokenDelete(created.AccessorID, nil) 425 require.NoError(t, err) 426 427 read, _, err = acl.TokenRead(created.AccessorID, nil) 428 require.Nil(t, read) 429 require.Error(t, err) 430 } 431 432 func TestAPI_ACLToken_CreateUpdate(t *testing.T) { 433 t.Parallel() 434 c, s := makeACLClient(t) 435 defer s.Stop() 436 437 acl := c.ACL() 438 439 policies := prepTokenPolicies(t, acl) 440 441 created, _, err := acl.TokenCreate(&ACLToken{ 442 Description: "token created", 443 Policies: []*ACLTokenPolicyLink{ 444 &ACLTokenPolicyLink{ 445 ID: policies[0].ID, 446 }, 447 &ACLTokenPolicyLink{ 448 Name: policies[2].Name, 449 }, 450 }, 451 }, nil) 452 453 require.NoError(t, err) 454 require.NotNil(t, created) 455 require.NotEqual(t, "", created.AccessorID) 456 require.NotEqual(t, "", created.SecretID) 457 458 read, _, err := acl.TokenRead(created.AccessorID, nil) 459 require.NoError(t, err) 460 require.Equal(t, created, read) 461 462 read.Policies = append(read.Policies, &ACLTokenPolicyLink{ID: policies[1].ID}) 463 read.Policies = append(read.Policies, &ACLTokenPolicyLink{Name: policies[2].Name}) 464 465 expectedPolicies := []*ACLTokenPolicyLink{ 466 &ACLTokenPolicyLink{ 467 ID: policies[0].ID, 468 Name: policies[0].Name, 469 }, 470 &ACLTokenPolicyLink{ 471 ID: policies[1].ID, 472 Name: policies[1].Name, 473 }, 474 &ACLTokenPolicyLink{ 475 ID: policies[2].ID, 476 Name: policies[2].Name, 477 }, 478 } 479 480 updated, wm, err := acl.TokenUpdate(read, nil) 481 require.NoError(t, err) 482 require.Equal(t, created.AccessorID, updated.AccessorID) 483 require.Equal(t, created.SecretID, updated.SecretID) 484 require.Equal(t, created.Description, updated.Description) 485 require.Equal(t, created.CreateIndex, updated.CreateIndex) 486 require.NotEqual(t, created.ModifyIndex, updated.ModifyIndex) 487 require.ElementsMatch(t, expectedPolicies, updated.Policies) 488 require.NotEqual(t, 0, wm.RequestTime) 489 490 updated_read, _, err := acl.TokenRead(created.AccessorID, nil) 491 require.NoError(t, err) 492 require.Equal(t, updated, updated_read) 493 } 494 495 func TestAPI_ACLToken_List(t *testing.T) { 496 t.Parallel() 497 c, s := makeACLClient(t) 498 defer s.Stop() 499 500 acl := c.ACL() 501 502 policies := prepTokenPolicies(t, acl) 503 504 created1, _, err := acl.TokenCreate(&ACLToken{ 505 Description: "token created1", 506 Policies: []*ACLTokenPolicyLink{ 507 &ACLTokenPolicyLink{ 508 ID: policies[0].ID, 509 }, 510 }, 511 }, nil) 512 513 require.NoError(t, err) 514 require.NotNil(t, created1) 515 require.NotEqual(t, "", created1.AccessorID) 516 require.NotEqual(t, "", created1.SecretID) 517 518 created2, _, err := acl.TokenCreate(&ACLToken{ 519 Description: "token created2", 520 Policies: []*ACLTokenPolicyLink{ 521 &ACLTokenPolicyLink{ 522 ID: policies[1].ID, 523 }, 524 }, 525 }, nil) 526 527 require.NoError(t, err) 528 require.NotNil(t, created2) 529 require.NotEqual(t, "", created2.AccessorID) 530 require.NotEqual(t, "", created2.SecretID) 531 532 created3, _, err := acl.TokenCreate(&ACLToken{ 533 Description: "token created3", 534 Policies: []*ACLTokenPolicyLink{ 535 &ACLTokenPolicyLink{ 536 ID: policies[2].ID, 537 }, 538 }, 539 }, nil) 540 541 require.NoError(t, err) 542 require.NotNil(t, created3) 543 require.NotEqual(t, "", created3.AccessorID) 544 require.NotEqual(t, "", created3.SecretID) 545 546 tokens, qm, err := acl.TokenList(nil) 547 require.NoError(t, err) 548 // 3 + anon + master 549 require.Len(t, tokens, 5) 550 require.NotEqual(t, 0, qm.LastIndex) 551 require.True(t, qm.KnownLeader) 552 553 tokenMap := make(map[string]*ACLTokenListEntry) 554 for _, token := range tokens { 555 tokenMap[token.AccessorID] = token 556 } 557 558 token1, ok := tokenMap[created1.AccessorID] 559 require.True(t, ok) 560 require.NotNil(t, token1) 561 require.Equal(t, created1.Description, token1.Description) 562 require.Equal(t, created1.CreateIndex, token1.CreateIndex) 563 require.Equal(t, created1.ModifyIndex, token1.ModifyIndex) 564 require.Equal(t, created1.Hash, token1.Hash) 565 require.ElementsMatch(t, created1.Policies, token1.Policies) 566 567 token2, ok := tokenMap[created2.AccessorID] 568 require.True(t, ok) 569 require.NotNil(t, token2) 570 require.Equal(t, created2.Description, token2.Description) 571 require.Equal(t, created2.CreateIndex, token2.CreateIndex) 572 require.Equal(t, created2.ModifyIndex, token2.ModifyIndex) 573 require.Equal(t, created2.Hash, token2.Hash) 574 require.ElementsMatch(t, created2.Policies, token2.Policies) 575 576 token3, ok := tokenMap[created3.AccessorID] 577 require.True(t, ok) 578 require.NotNil(t, token3) 579 require.Equal(t, created3.Description, token3.Description) 580 require.Equal(t, created3.CreateIndex, token3.CreateIndex) 581 require.Equal(t, created3.ModifyIndex, token3.ModifyIndex) 582 require.Equal(t, created3.Hash, token3.Hash) 583 require.ElementsMatch(t, created3.Policies, token3.Policies) 584 585 // make sure the there is an anon token 586 token4, ok := tokenMap["00000000-0000-0000-0000-000000000002"] 587 require.True(t, ok) 588 require.NotNil(t, token4) 589 590 // ensure the 5th token is the root master token 591 root, _, err := acl.TokenReadSelf(nil) 592 require.NoError(t, err) 593 require.NotNil(t, root) 594 token5, ok := tokenMap[root.AccessorID] 595 require.True(t, ok) 596 require.NotNil(t, token5) 597 } 598 599 func TestAPI_ACLToken_Clone(t *testing.T) { 600 t.Parallel() 601 c, s := makeACLClient(t) 602 defer s.Stop() 603 604 acl := c.ACL() 605 606 master, _, err := acl.TokenReadSelf(nil) 607 require.NoError(t, err) 608 require.NotNil(t, master) 609 610 cloned, _, err := acl.TokenClone(master.AccessorID, "cloned", nil) 611 require.NoError(t, err) 612 require.NotNil(t, cloned) 613 require.NotEqual(t, master.AccessorID, cloned.AccessorID) 614 require.NotEqual(t, master.SecretID, cloned.SecretID) 615 require.Equal(t, "cloned", cloned.Description) 616 require.ElementsMatch(t, master.Policies, cloned.Policies) 617 618 read, _, err := acl.TokenRead(cloned.AccessorID, nil) 619 require.NoError(t, err) 620 require.NotNil(t, read) 621 require.Equal(t, cloned, read) 622 } 623 624 func TestAPI_RulesTranslate_FromToken(t *testing.T) { 625 t.Parallel() 626 c, s := makeACLClient(t) 627 defer s.Stop() 628 629 acl := c.ACL() 630 631 ae := ACLEntry{ 632 Name: "API test", 633 Type: ACLClientType, 634 Rules: `key "" { policy = "deny" }`, 635 } 636 637 id, _, err := acl.Create(&ae, nil) 638 require.NoError(t, err) 639 640 var accessor string 641 acl.c.config.Token = id 642 643 // This relies on the token upgrade loop running in the background 644 // to assign an accessor 645 retry.Run(t, func(t *retry.R) { 646 token, _, err := acl.TokenReadSelf(nil) 647 require.NoError(t, err) 648 require.NotEqual(t, "", token.AccessorID) 649 accessor = token.AccessorID 650 }) 651 acl.c.config.Token = "root" 652 653 rules, err := acl.RulesTranslateToken(accessor) 654 require.NoError(t, err) 655 require.Equal(t, "key_prefix \"\" {\n policy = \"deny\"\n}", rules) 656 } 657 658 func TestAPI_RulesTranslate_Raw(t *testing.T) { 659 t.Parallel() 660 c, s := makeACLClient(t) 661 defer s.Stop() 662 663 acl := c.ACL() 664 665 input := `#start of policy 666 agent "" { 667 policy = "read" 668 } 669 670 node "" { 671 policy = "read" 672 } 673 674 service "" { 675 policy = "read" 676 } 677 678 key "" { 679 policy = "read" 680 } 681 682 session "" { 683 policy = "read" 684 } 685 686 event "" { 687 policy = "read" 688 } 689 690 query "" { 691 policy = "read" 692 }` 693 694 expected := `#start of policy 695 agent_prefix "" { 696 policy = "read" 697 } 698 699 node_prefix "" { 700 policy = "read" 701 } 702 703 service_prefix "" { 704 policy = "read" 705 } 706 707 key_prefix "" { 708 policy = "read" 709 } 710 711 session_prefix "" { 712 policy = "read" 713 } 714 715 event_prefix "" { 716 policy = "read" 717 } 718 719 query_prefix "" { 720 policy = "read" 721 }` 722 723 rules, err := acl.RulesTranslate(strings.NewReader(input)) 724 require.NoError(t, err) 725 require.Equal(t, expected, rules) 726 }