github.imxd.top/hashicorp/consul@v1.4.5/agent/consul/session_endpoint_test.go (about) 1 package consul 2 3 import ( 4 "os" 5 "testing" 6 "time" 7 8 "github.com/hashicorp/consul/acl" 9 "github.com/hashicorp/consul/agent/structs" 10 "github.com/hashicorp/consul/lib" 11 "github.com/hashicorp/consul/testrpc" 12 "github.com/hashicorp/net-rpc-msgpackrpc" 13 ) 14 15 func TestSession_Apply(t *testing.T) { 16 t.Parallel() 17 dir1, s1 := testServer(t) 18 defer os.RemoveAll(dir1) 19 defer s1.Shutdown() 20 codec := rpcClient(t, s1) 21 defer codec.Close() 22 23 testrpc.WaitForLeader(t, s1.RPC, "dc1") 24 25 // Just add a node 26 s1.fsm.State().EnsureNode(1, &structs.Node{Node: "foo", Address: "127.0.0.1"}) 27 28 arg := structs.SessionRequest{ 29 Datacenter: "dc1", 30 Op: structs.SessionCreate, 31 Session: structs.Session{ 32 Node: "foo", 33 Name: "my-session", 34 }, 35 } 36 var out string 37 if err := msgpackrpc.CallWithCodec(codec, "Session.Apply", &arg, &out); err != nil { 38 t.Fatalf("err: %v", err) 39 } 40 id := out 41 42 // Verify 43 state := s1.fsm.State() 44 _, s, err := state.SessionGet(nil, out) 45 if err != nil { 46 t.Fatalf("err: %v", err) 47 } 48 if s == nil { 49 t.Fatalf("should not be nil") 50 } 51 if s.Node != "foo" { 52 t.Fatalf("bad: %v", s) 53 } 54 if s.Name != "my-session" { 55 t.Fatalf("bad: %v", s) 56 } 57 58 // Do a delete 59 arg.Op = structs.SessionDestroy 60 arg.Session.ID = out 61 if err := msgpackrpc.CallWithCodec(codec, "Session.Apply", &arg, &out); err != nil { 62 t.Fatalf("err: %v", err) 63 } 64 65 // Verify 66 _, s, err = state.SessionGet(nil, id) 67 if err != nil { 68 t.Fatalf("err: %v", err) 69 } 70 if s != nil { 71 t.Fatalf("bad: %v", s) 72 } 73 } 74 75 func TestSession_DeleteApply(t *testing.T) { 76 t.Parallel() 77 dir1, s1 := testServer(t) 78 defer os.RemoveAll(dir1) 79 defer s1.Shutdown() 80 codec := rpcClient(t, s1) 81 defer codec.Close() 82 83 testrpc.WaitForLeader(t, s1.RPC, "dc1") 84 85 // Just add a node 86 s1.fsm.State().EnsureNode(1, &structs.Node{Node: "foo", Address: "127.0.0.1"}) 87 88 arg := structs.SessionRequest{ 89 Datacenter: "dc1", 90 Op: structs.SessionCreate, 91 Session: structs.Session{ 92 Node: "foo", 93 Name: "my-session", 94 Behavior: structs.SessionKeysDelete, 95 }, 96 } 97 var out string 98 if err := msgpackrpc.CallWithCodec(codec, "Session.Apply", &arg, &out); err != nil { 99 t.Fatalf("err: %v", err) 100 } 101 id := out 102 103 // Verify 104 state := s1.fsm.State() 105 _, s, err := state.SessionGet(nil, out) 106 if err != nil { 107 t.Fatalf("err: %v", err) 108 } 109 if s == nil { 110 t.Fatalf("should not be nil") 111 } 112 if s.Node != "foo" { 113 t.Fatalf("bad: %v", s) 114 } 115 if s.Name != "my-session" { 116 t.Fatalf("bad: %v", s) 117 } 118 if s.Behavior != structs.SessionKeysDelete { 119 t.Fatalf("bad: %v", s) 120 } 121 122 // Do a delete 123 arg.Op = structs.SessionDestroy 124 arg.Session.ID = out 125 if err := msgpackrpc.CallWithCodec(codec, "Session.Apply", &arg, &out); err != nil { 126 t.Fatalf("err: %v", err) 127 } 128 129 // Verify 130 _, s, err = state.SessionGet(nil, id) 131 if err != nil { 132 t.Fatalf("err: %v", err) 133 } 134 if s != nil { 135 t.Fatalf("bad: %v", s) 136 } 137 } 138 139 func TestSession_Apply_ACLDeny(t *testing.T) { 140 t.Parallel() 141 dir1, s1 := testServerWithConfig(t, func(c *Config) { 142 c.ACLDatacenter = "dc1" 143 c.ACLsEnabled = true 144 c.ACLMasterToken = "root" 145 c.ACLDefaultPolicy = "deny" 146 c.ACLEnforceVersion8 = false 147 }) 148 defer os.RemoveAll(dir1) 149 defer s1.Shutdown() 150 codec := rpcClient(t, s1) 151 defer codec.Close() 152 153 testrpc.WaitForLeader(t, s1.RPC, "dc1") 154 155 // Create the ACL. 156 req := structs.ACLRequest{ 157 Datacenter: "dc1", 158 Op: structs.ACLSet, 159 ACL: structs.ACL{ 160 Name: "User token", 161 Type: structs.ACLTokenTypeClient, 162 Rules: ` 163 session "foo" { 164 policy = "write" 165 } 166 `, 167 }, 168 WriteRequest: structs.WriteRequest{Token: "root"}, 169 } 170 171 var token string 172 if err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &req, &token); err != nil { 173 t.Fatalf("err: %v", err) 174 } 175 176 // Just add a node. 177 s1.fsm.State().EnsureNode(1, &structs.Node{Node: "foo", Address: "127.0.0.1"}) 178 179 // Try to create without a token, which will go through since version 8 180 // enforcement isn't enabled. 181 arg := structs.SessionRequest{ 182 Datacenter: "dc1", 183 Op: structs.SessionCreate, 184 Session: structs.Session{ 185 Node: "foo", 186 Name: "my-session", 187 }, 188 } 189 var id1 string 190 if err := msgpackrpc.CallWithCodec(codec, "Session.Apply", &arg, &id1); err != nil { 191 t.Fatalf("err: %v", err) 192 } 193 194 // Now turn on version 8 enforcement and try again, it should be denied. 195 var id2 string 196 s1.config.ACLEnforceVersion8 = true 197 err := msgpackrpc.CallWithCodec(codec, "Session.Apply", &arg, &id2) 198 if !acl.IsErrPermissionDenied(err) { 199 t.Fatalf("err: %v", err) 200 } 201 202 // Now set a token and try again. This should go through. 203 arg.Token = token 204 if err := msgpackrpc.CallWithCodec(codec, "Session.Apply", &arg, &id2); err != nil { 205 t.Fatalf("err: %v", err) 206 } 207 208 // Do a delete on the first session with version 8 enforcement off and 209 // no token. This should go through. 210 var out string 211 s1.config.ACLEnforceVersion8 = false 212 arg.Op = structs.SessionDestroy 213 arg.Token = "" 214 arg.Session.ID = id1 215 if err := msgpackrpc.CallWithCodec(codec, "Session.Apply", &arg, &out); err != nil { 216 t.Fatalf("err: %v", err) 217 } 218 219 // Turn on version 8 enforcement and make sure the delete of the second 220 // session fails. 221 s1.config.ACLEnforceVersion8 = true 222 arg.Session.ID = id2 223 err = msgpackrpc.CallWithCodec(codec, "Session.Apply", &arg, &out) 224 if !acl.IsErrPermissionDenied(err) { 225 t.Fatalf("err: %v", err) 226 } 227 228 // Now set a token and try again. This should go through. 229 arg.Token = token 230 if err := msgpackrpc.CallWithCodec(codec, "Session.Apply", &arg, &out); err != nil { 231 t.Fatalf("err: %v", err) 232 } 233 } 234 235 func TestSession_Get(t *testing.T) { 236 t.Parallel() 237 dir1, s1 := testServer(t) 238 defer os.RemoveAll(dir1) 239 defer s1.Shutdown() 240 codec := rpcClient(t, s1) 241 defer codec.Close() 242 243 testrpc.WaitForLeader(t, s1.RPC, "dc1") 244 245 s1.fsm.State().EnsureNode(1, &structs.Node{Node: "foo", Address: "127.0.0.1"}) 246 arg := structs.SessionRequest{ 247 Datacenter: "dc1", 248 Op: structs.SessionCreate, 249 Session: structs.Session{ 250 Node: "foo", 251 }, 252 } 253 var out string 254 if err := msgpackrpc.CallWithCodec(codec, "Session.Apply", &arg, &out); err != nil { 255 t.Fatalf("err: %v", err) 256 } 257 258 getR := structs.SessionSpecificRequest{ 259 Datacenter: "dc1", 260 Session: out, 261 } 262 var sessions structs.IndexedSessions 263 if err := msgpackrpc.CallWithCodec(codec, "Session.Get", &getR, &sessions); err != nil { 264 t.Fatalf("err: %v", err) 265 } 266 267 if sessions.Index == 0 { 268 t.Fatalf("Bad: %v", sessions) 269 } 270 if len(sessions.Sessions) != 1 { 271 t.Fatalf("Bad: %v", sessions) 272 } 273 s := sessions.Sessions[0] 274 if s.ID != out { 275 t.Fatalf("bad: %v", s) 276 } 277 } 278 279 func TestSession_List(t *testing.T) { 280 t.Parallel() 281 dir1, s1 := testServer(t) 282 defer os.RemoveAll(dir1) 283 defer s1.Shutdown() 284 codec := rpcClient(t, s1) 285 defer codec.Close() 286 287 testrpc.WaitForLeader(t, s1.RPC, "dc1") 288 289 s1.fsm.State().EnsureNode(1, &structs.Node{Node: "foo", Address: "127.0.0.1"}) 290 ids := []string{} 291 for i := 0; i < 5; i++ { 292 arg := structs.SessionRequest{ 293 Datacenter: "dc1", 294 Op: structs.SessionCreate, 295 Session: structs.Session{ 296 Node: "foo", 297 }, 298 } 299 var out string 300 if err := msgpackrpc.CallWithCodec(codec, "Session.Apply", &arg, &out); err != nil { 301 t.Fatalf("err: %v", err) 302 } 303 ids = append(ids, out) 304 } 305 306 getR := structs.DCSpecificRequest{ 307 Datacenter: "dc1", 308 } 309 var sessions structs.IndexedSessions 310 if err := msgpackrpc.CallWithCodec(codec, "Session.List", &getR, &sessions); err != nil { 311 t.Fatalf("err: %v", err) 312 } 313 314 if sessions.Index == 0 { 315 t.Fatalf("Bad: %v", sessions) 316 } 317 if len(sessions.Sessions) != 5 { 318 t.Fatalf("Bad: %v", sessions.Sessions) 319 } 320 for i := 0; i < len(sessions.Sessions); i++ { 321 s := sessions.Sessions[i] 322 if !lib.StrContains(ids, s.ID) { 323 t.Fatalf("bad: %v", s) 324 } 325 if s.Node != "foo" { 326 t.Fatalf("bad: %v", s) 327 } 328 } 329 } 330 331 func TestSession_Get_List_NodeSessions_ACLFilter(t *testing.T) { 332 t.Parallel() 333 dir1, s1 := testServerWithConfig(t, func(c *Config) { 334 c.ACLDatacenter = "dc1" 335 c.ACLsEnabled = true 336 c.ACLMasterToken = "root" 337 c.ACLDefaultPolicy = "deny" 338 c.ACLEnforceVersion8 = false 339 }) 340 defer os.RemoveAll(dir1) 341 defer s1.Shutdown() 342 codec := rpcClient(t, s1) 343 defer codec.Close() 344 345 testrpc.WaitForLeader(t, s1.RPC, "dc1") 346 347 // Create the ACL. 348 req := structs.ACLRequest{ 349 Datacenter: "dc1", 350 Op: structs.ACLSet, 351 ACL: structs.ACL{ 352 Name: "User token", 353 Type: structs.ACLTokenTypeClient, 354 Rules: ` 355 session "foo" { 356 policy = "read" 357 } 358 `, 359 }, 360 WriteRequest: structs.WriteRequest{Token: "root"}, 361 } 362 363 var token string 364 if err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &req, &token); err != nil { 365 t.Fatalf("err: %v", err) 366 } 367 368 // Create a node and a session. 369 s1.fsm.State().EnsureNode(1, &structs.Node{Node: "foo", Address: "127.0.0.1"}) 370 arg := structs.SessionRequest{ 371 Datacenter: "dc1", 372 Op: structs.SessionCreate, 373 Session: structs.Session{ 374 Node: "foo", 375 }, 376 WriteRequest: structs.WriteRequest{Token: "root"}, 377 } 378 var out string 379 if err := msgpackrpc.CallWithCodec(codec, "Session.Apply", &arg, &out); err != nil { 380 t.Fatalf("err: %v", err) 381 } 382 383 // Perform all the read operations, which should go through since version 384 // 8 ACL enforcement isn't enabled. 385 getR := structs.SessionSpecificRequest{ 386 Datacenter: "dc1", 387 Session: out, 388 } 389 { 390 var sessions structs.IndexedSessions 391 if err := msgpackrpc.CallWithCodec(codec, "Session.Get", &getR, &sessions); err != nil { 392 t.Fatalf("err: %v", err) 393 } 394 if len(sessions.Sessions) != 1 { 395 t.Fatalf("bad: %v", sessions.Sessions) 396 } 397 } 398 listR := structs.DCSpecificRequest{ 399 Datacenter: "dc1", 400 } 401 { 402 var sessions structs.IndexedSessions 403 if err := msgpackrpc.CallWithCodec(codec, "Session.List", &listR, &sessions); err != nil { 404 t.Fatalf("err: %v", err) 405 } 406 if len(sessions.Sessions) != 1 { 407 t.Fatalf("bad: %v", sessions.Sessions) 408 } 409 } 410 nodeR := structs.NodeSpecificRequest{ 411 Datacenter: "dc1", 412 Node: "foo", 413 } 414 { 415 var sessions structs.IndexedSessions 416 if err := msgpackrpc.CallWithCodec(codec, "Session.NodeSessions", &nodeR, &sessions); err != nil { 417 t.Fatalf("err: %v", err) 418 } 419 if len(sessions.Sessions) != 1 { 420 t.Fatalf("bad: %v", sessions.Sessions) 421 } 422 } 423 424 // Now turn on version 8 enforcement and make sure everything is empty. 425 s1.config.ACLEnforceVersion8 = true 426 { 427 var sessions structs.IndexedSessions 428 if err := msgpackrpc.CallWithCodec(codec, "Session.Get", &getR, &sessions); err != nil { 429 t.Fatalf("err: %v", err) 430 } 431 if len(sessions.Sessions) != 0 { 432 t.Fatalf("bad: %v", sessions.Sessions) 433 } 434 } 435 { 436 var sessions structs.IndexedSessions 437 438 if err := msgpackrpc.CallWithCodec(codec, "Session.List", &listR, &sessions); err != nil { 439 t.Fatalf("err: %v", err) 440 } 441 if len(sessions.Sessions) != 0 { 442 t.Fatalf("bad: %v", sessions.Sessions) 443 } 444 } 445 { 446 var sessions structs.IndexedSessions 447 if err := msgpackrpc.CallWithCodec(codec, "Session.NodeSessions", &nodeR, &sessions); err != nil { 448 t.Fatalf("err: %v", err) 449 } 450 if len(sessions.Sessions) != 0 { 451 t.Fatalf("bad: %v", sessions.Sessions) 452 } 453 } 454 455 // Finally, supply the token and make sure the reads are allowed. 456 getR.Token = token 457 { 458 var sessions structs.IndexedSessions 459 if err := msgpackrpc.CallWithCodec(codec, "Session.Get", &getR, &sessions); err != nil { 460 t.Fatalf("err: %v", err) 461 } 462 if len(sessions.Sessions) != 1 { 463 t.Fatalf("bad: %v", sessions.Sessions) 464 } 465 } 466 listR.Token = token 467 { 468 var sessions structs.IndexedSessions 469 if err := msgpackrpc.CallWithCodec(codec, "Session.List", &listR, &sessions); err != nil { 470 t.Fatalf("err: %v", err) 471 } 472 if len(sessions.Sessions) != 1 { 473 t.Fatalf("bad: %v", sessions.Sessions) 474 } 475 } 476 nodeR.Token = token 477 { 478 var sessions structs.IndexedSessions 479 if err := msgpackrpc.CallWithCodec(codec, "Session.NodeSessions", &nodeR, &sessions); err != nil { 480 t.Fatalf("err: %v", err) 481 } 482 if len(sessions.Sessions) != 1 { 483 t.Fatalf("bad: %v", sessions.Sessions) 484 } 485 } 486 487 // Try to get a session that doesn't exist to make sure that's handled 488 // correctly by the filter (it will get passed a nil slice). 489 getR.Session = "adf4238a-882b-9ddc-4a9d-5b6758e4159e" 490 { 491 var sessions structs.IndexedSessions 492 if err := msgpackrpc.CallWithCodec(codec, "Session.Get", &getR, &sessions); err != nil { 493 t.Fatalf("err: %v", err) 494 } 495 if len(sessions.Sessions) != 0 { 496 t.Fatalf("bad: %v", sessions.Sessions) 497 } 498 } 499 } 500 501 func TestSession_ApplyTimers(t *testing.T) { 502 t.Parallel() 503 dir1, s1 := testServer(t) 504 defer os.RemoveAll(dir1) 505 defer s1.Shutdown() 506 testrpc.WaitForTestAgent(t, s1.RPC, "dc1") 507 codec := rpcClient(t, s1) 508 defer codec.Close() 509 510 s1.fsm.State().EnsureNode(1, &structs.Node{Node: "foo", Address: "127.0.0.1"}) 511 arg := structs.SessionRequest{ 512 Datacenter: "dc1", 513 Op: structs.SessionCreate, 514 Session: structs.Session{ 515 Node: "foo", 516 TTL: "10s", 517 }, 518 } 519 var out string 520 if err := msgpackrpc.CallWithCodec(codec, "Session.Apply", &arg, &out); err != nil { 521 t.Fatalf("err: %v", err) 522 } 523 524 // Check the session map 525 if s1.sessionTimers.Get(out) == nil { 526 t.Fatalf("missing session timer") 527 } 528 529 // Destroy the session 530 arg.Op = structs.SessionDestroy 531 arg.Session.ID = out 532 if err := msgpackrpc.CallWithCodec(codec, "Session.Apply", &arg, &out); err != nil { 533 t.Fatalf("err: %v", err) 534 } 535 536 // Check the session map 537 if s1.sessionTimers.Get(out) != nil { 538 t.Fatalf("session timer exists") 539 } 540 } 541 542 func TestSession_Renew(t *testing.T) { 543 // This method is timing sensitive, disable Parallel 544 //t.Parallel() 545 ttl := 1 * time.Second 546 TTL := ttl.String() 547 548 dir1, s1 := testServerWithConfig(t, func(c *Config) { 549 c.SessionTTLMin = ttl 550 }) 551 defer os.RemoveAll(dir1) 552 defer s1.Shutdown() 553 testrpc.WaitForTestAgent(t, s1.RPC, "dc1") 554 codec := rpcClient(t, s1) 555 defer codec.Close() 556 557 s1.fsm.State().EnsureNode(1, &structs.Node{Node: "foo", Address: "127.0.0.1"}) 558 ids := []string{} 559 for i := 0; i < 5; i++ { 560 arg := structs.SessionRequest{ 561 Datacenter: "dc1", 562 Op: structs.SessionCreate, 563 Session: structs.Session{ 564 Node: "foo", 565 TTL: TTL, 566 }, 567 } 568 var out string 569 if err := msgpackrpc.CallWithCodec(codec, "Session.Apply", &arg, &out); err != nil { 570 t.Fatalf("err: %v", err) 571 } 572 ids = append(ids, out) 573 } 574 575 // Verify the timer map is setup 576 if s1.sessionTimers.Len() != 5 { 577 t.Fatalf("missing session timers") 578 } 579 580 getR := structs.DCSpecificRequest{ 581 Datacenter: "dc1", 582 } 583 584 var sessions structs.IndexedSessions 585 if err := msgpackrpc.CallWithCodec(codec, "Session.List", &getR, &sessions); err != nil { 586 t.Fatalf("err: %v", err) 587 } 588 589 if sessions.Index == 0 { 590 t.Fatalf("Bad: %v", sessions) 591 } 592 if len(sessions.Sessions) != 5 { 593 t.Fatalf("Bad: %v", sessions.Sessions) 594 } 595 for i := 0; i < len(sessions.Sessions); i++ { 596 s := sessions.Sessions[i] 597 if !lib.StrContains(ids, s.ID) { 598 t.Fatalf("bad: %v", s) 599 } 600 if s.Node != "foo" { 601 t.Fatalf("bad: %v", s) 602 } 603 if s.TTL != TTL { 604 t.Fatalf("bad session TTL: %s %v", s.TTL, s) 605 } 606 t.Logf("Created session '%s'", s.ID) 607 } 608 609 // Sleep for time shorter than internal destroy ttl 610 time.Sleep(ttl * structs.SessionTTLMultiplier / 2) 611 612 // renew 3 out of 5 sessions 613 for i := 0; i < 3; i++ { 614 renewR := structs.SessionSpecificRequest{ 615 Datacenter: "dc1", 616 Session: ids[i], 617 } 618 var session structs.IndexedSessions 619 if err := msgpackrpc.CallWithCodec(codec, "Session.Renew", &renewR, &session); err != nil { 620 t.Fatalf("err: %v", err) 621 } 622 623 if session.Index == 0 { 624 t.Fatalf("Bad: %v", session) 625 } 626 if len(session.Sessions) != 1 { 627 t.Fatalf("Bad: %v", session.Sessions) 628 } 629 630 s := session.Sessions[0] 631 if !lib.StrContains(ids, s.ID) { 632 t.Fatalf("bad: %v", s) 633 } 634 if s.Node != "foo" { 635 t.Fatalf("bad: %v", s) 636 } 637 638 t.Logf("Renewed session '%s'", s.ID) 639 } 640 641 // now sleep for 2/3 the internal destroy TTL time for renewed sessions 642 // which is more than the internal destroy TTL time for the non-renewed sessions 643 time.Sleep((ttl * structs.SessionTTLMultiplier) * 2.0 / 3.0) 644 645 var sessionsL1 structs.IndexedSessions 646 if err := msgpackrpc.CallWithCodec(codec, "Session.List", &getR, &sessionsL1); err != nil { 647 t.Fatalf("err: %v", err) 648 } 649 650 if sessionsL1.Index == 0 { 651 t.Fatalf("Bad: %v", sessionsL1) 652 } 653 654 t.Logf("Expect 2 sessions to be destroyed") 655 656 for i := 0; i < len(sessionsL1.Sessions); i++ { 657 s := sessionsL1.Sessions[i] 658 if !lib.StrContains(ids, s.ID) { 659 t.Fatalf("bad: %v", s) 660 } 661 if s.Node != "foo" { 662 t.Fatalf("bad: %v", s) 663 } 664 if s.TTL != TTL { 665 t.Fatalf("bad: %v", s) 666 } 667 if i > 2 { 668 t.Errorf("session '%s' should be destroyed", s.ID) 669 } 670 } 671 672 if len(sessionsL1.Sessions) != 3 { 673 t.Fatalf("Bad: %v", sessionsL1.Sessions) 674 } 675 676 // now sleep again for ttl*2 - no sessions should still be alive 677 time.Sleep(ttl * structs.SessionTTLMultiplier) 678 679 var sessionsL2 structs.IndexedSessions 680 if err := msgpackrpc.CallWithCodec(codec, "Session.List", &getR, &sessionsL2); err != nil { 681 t.Fatalf("err: %v", err) 682 } 683 684 if sessionsL2.Index == 0 { 685 t.Fatalf("Bad: %v", sessionsL2) 686 } 687 if len(sessionsL2.Sessions) != 0 { 688 for i := 0; i < len(sessionsL2.Sessions); i++ { 689 s := sessionsL2.Sessions[i] 690 if !lib.StrContains(ids, s.ID) { 691 t.Fatalf("bad: %v", s) 692 } 693 if s.Node != "foo" { 694 t.Fatalf("bad: %v", s) 695 } 696 if s.TTL != TTL { 697 t.Fatalf("bad: %v", s) 698 } 699 t.Errorf("session '%s' should be destroyed", s.ID) 700 } 701 702 t.Fatalf("Bad: %v", sessionsL2.Sessions) 703 } 704 } 705 706 func TestSession_Renew_ACLDeny(t *testing.T) { 707 t.Parallel() 708 dir1, s1 := testServerWithConfig(t, func(c *Config) { 709 c.ACLDatacenter = "dc1" 710 c.ACLsEnabled = true 711 c.ACLMasterToken = "root" 712 c.ACLDefaultPolicy = "deny" 713 c.ACLEnforceVersion8 = false 714 }) 715 defer os.RemoveAll(dir1) 716 defer s1.Shutdown() 717 testrpc.WaitForTestAgent(t, s1.RPC, "dc1") 718 codec := rpcClient(t, s1) 719 defer codec.Close() 720 721 // Create the ACL. 722 req := structs.ACLRequest{ 723 Datacenter: "dc1", 724 Op: structs.ACLSet, 725 ACL: structs.ACL{ 726 Name: "User token", 727 Type: structs.ACLTokenTypeClient, 728 Rules: ` 729 session "foo" { 730 policy = "write" 731 } 732 `, 733 }, 734 WriteRequest: structs.WriteRequest{Token: "root"}, 735 } 736 737 var token string 738 if err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &req, &token); err != nil { 739 t.Fatalf("err: %v", err) 740 } 741 742 // Just add a node. 743 s1.fsm.State().EnsureNode(1, &structs.Node{Node: "foo", Address: "127.0.0.1"}) 744 745 // Create a session. The token won't matter here since we don't have 746 // version 8 ACL enforcement on yet. 747 arg := structs.SessionRequest{ 748 Datacenter: "dc1", 749 Op: structs.SessionCreate, 750 Session: structs.Session{ 751 Node: "foo", 752 Name: "my-session", 753 }, 754 } 755 var id string 756 if err := msgpackrpc.CallWithCodec(codec, "Session.Apply", &arg, &id); err != nil { 757 t.Fatalf("err: %v", err) 758 } 759 760 // Renew without a token should go through without version 8 ACL 761 // enforcement. 762 renewR := structs.SessionSpecificRequest{ 763 Datacenter: "dc1", 764 Session: id, 765 } 766 var session structs.IndexedSessions 767 if err := msgpackrpc.CallWithCodec(codec, "Session.Renew", &renewR, &session); err != nil { 768 t.Fatalf("err: %v", err) 769 } 770 771 // Now turn on version 8 enforcement and the renew should be rejected. 772 s1.config.ACLEnforceVersion8 = true 773 err := msgpackrpc.CallWithCodec(codec, "Session.Renew", &renewR, &session) 774 if !acl.IsErrPermissionDenied(err) { 775 t.Fatalf("err: %v", err) 776 } 777 778 // Set the token and it should go through. 779 renewR.Token = token 780 if err := msgpackrpc.CallWithCodec(codec, "Session.Renew", &renewR, &session); err != nil { 781 t.Fatalf("err: %v", err) 782 } 783 } 784 785 func TestSession_NodeSessions(t *testing.T) { 786 t.Parallel() 787 dir1, s1 := testServer(t) 788 defer os.RemoveAll(dir1) 789 defer s1.Shutdown() 790 codec := rpcClient(t, s1) 791 defer codec.Close() 792 793 testrpc.WaitForLeader(t, s1.RPC, "dc1") 794 795 s1.fsm.State().EnsureNode(1, &structs.Node{Node: "foo", Address: "127.0.0.1"}) 796 s1.fsm.State().EnsureNode(1, &structs.Node{Node: "bar", Address: "127.0.0.1"}) 797 ids := []string{} 798 for i := 0; i < 10; i++ { 799 arg := structs.SessionRequest{ 800 Datacenter: "dc1", 801 Op: structs.SessionCreate, 802 Session: structs.Session{ 803 Node: "bar", 804 }, 805 } 806 if i < 5 { 807 arg.Session.Node = "foo" 808 } 809 var out string 810 if err := msgpackrpc.CallWithCodec(codec, "Session.Apply", &arg, &out); err != nil { 811 t.Fatalf("err: %v", err) 812 } 813 if i < 5 { 814 ids = append(ids, out) 815 } 816 } 817 818 getR := structs.NodeSpecificRequest{ 819 Datacenter: "dc1", 820 Node: "foo", 821 } 822 var sessions structs.IndexedSessions 823 if err := msgpackrpc.CallWithCodec(codec, "Session.NodeSessions", &getR, &sessions); err != nil { 824 t.Fatalf("err: %v", err) 825 } 826 827 if sessions.Index == 0 { 828 t.Fatalf("Bad: %v", sessions) 829 } 830 if len(sessions.Sessions) != 5 { 831 t.Fatalf("Bad: %v", sessions.Sessions) 832 } 833 for i := 0; i < len(sessions.Sessions); i++ { 834 s := sessions.Sessions[i] 835 if !lib.StrContains(ids, s.ID) { 836 t.Fatalf("bad: %v", s) 837 } 838 if s.Node != "foo" { 839 t.Fatalf("bad: %v", s) 840 } 841 } 842 } 843 844 func TestSession_Apply_BadTTL(t *testing.T) { 845 t.Parallel() 846 dir1, s1 := testServer(t) 847 defer os.RemoveAll(dir1) 848 defer s1.Shutdown() 849 codec := rpcClient(t, s1) 850 defer codec.Close() 851 852 testrpc.WaitForLeader(t, s1.RPC, "dc1") 853 854 arg := structs.SessionRequest{ 855 Datacenter: "dc1", 856 Op: structs.SessionCreate, 857 Session: structs.Session{ 858 Node: "foo", 859 Name: "my-session", 860 }, 861 } 862 863 // Session with illegal TTL 864 arg.Session.TTL = "10z" 865 866 var out string 867 err := msgpackrpc.CallWithCodec(codec, "Session.Apply", &arg, &out) 868 if err == nil { 869 t.Fatal("expected error") 870 } 871 if err.Error() != "Session TTL '10z' invalid: time: unknown unit z in duration 10z" { 872 t.Fatalf("incorrect error message: %s", err.Error()) 873 } 874 875 // less than SessionTTLMin 876 arg.Session.TTL = "5s" 877 878 err = msgpackrpc.CallWithCodec(codec, "Session.Apply", &arg, &out) 879 if err == nil { 880 t.Fatal("expected error") 881 } 882 if err.Error() != "Invalid Session TTL '5000000000', must be between [10s=24h0m0s]" { 883 t.Fatalf("incorrect error message: %s", err.Error()) 884 } 885 886 // more than SessionTTLMax 887 arg.Session.TTL = "100000s" 888 889 err = msgpackrpc.CallWithCodec(codec, "Session.Apply", &arg, &out) 890 if err == nil { 891 t.Fatal("expected error") 892 } 893 if err.Error() != "Invalid Session TTL '100000000000000', must be between [10s=24h0m0s]" { 894 t.Fatalf("incorrect error message: %s", err.Error()) 895 } 896 }