1# -*- coding: utf-8 -*- 2# 3# Copyright (c) 2017 F5 Networks Inc. 4# GNU General Public License v3.0 (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 5 6from __future__ import (absolute_import, division, print_function) 7__metaclass__ = type 8 9import os 10import json 11import pytest 12import sys 13 14if sys.version_info < (2, 7): 15 pytestmark = pytest.mark.skip("F5 Ansible modules require Python >= 2.7") 16 17from ansible.module_utils.basic import AnsibleModule 18 19from ansible_collections.f5networks.f5_modules.plugins.modules.bigip_user import ( 20 Parameters, ModuleManager, ArgumentSpec, UnpartitionedManager, PartitionedManager 21) 22from ansible_collections.f5networks.f5_modules.plugins.module_utils.common import F5ModuleError 23from ansible_collections.f5networks.f5_modules.tests.unit.compat import unittest 24from ansible_collections.f5networks.f5_modules.tests.unit.compat.mock import Mock, patch 25from ansible_collections.f5networks.f5_modules.tests.unit.modules.utils import set_module_args 26 27 28fixture_path = os.path.join(os.path.dirname(__file__), 'fixtures') 29fixture_data = {} 30 31 32def load_fixture(name): 33 path = os.path.join(fixture_path, name) 34 35 if path in fixture_data: 36 return fixture_data[path] 37 38 with open(path) as f: 39 data = f.read() 40 41 try: 42 data = json.loads(data) 43 except Exception: 44 pass 45 46 fixture_data[path] = data 47 return data 48 49 50class TestParameters(unittest.TestCase): 51 def test_module_parameters(self): 52 access = [{'name': 'Common', 'role': 'guest'}] 53 args = dict( 54 username_credential='someuser', 55 password_credential='testpass', 56 full_name='Fake Person', 57 partition_access=access, 58 update_password='always' 59 ) 60 61 p = Parameters(params=args) 62 assert p.username_credential == 'someuser' 63 assert p.password_credential == 'testpass' 64 assert p.full_name == 'Fake Person' 65 assert p.partition_access == access 66 assert p.update_password == 'always' 67 68 def test_api_parameters(self): 69 access = [{'name': 'Common', 'role': 'guest'}] 70 args = dict( 71 name='someuser', 72 description='Fake Person', 73 partitionAccess=access, 74 shell='none' 75 ) 76 77 p = Parameters(params=args) 78 assert p.name == 'someuser' 79 assert p.full_name == 'Fake Person' 80 assert p.partition_access == access 81 assert p.shell == 'none' 82 83 84class TestManager(unittest.TestCase): 85 def setUp(self): 86 self.spec = ArgumentSpec() 87 self.p2 = patch('ansible_collections.f5networks.f5_modules.plugins.modules.bigip_user.tmos_version') 88 self.p3 = patch('ansible_collections.f5networks.f5_modules.plugins.modules.bigip_user.send_teem') 89 self.m2 = self.p2.start() 90 self.m2.return_value = '14.1.0' 91 self.m3 = self.p3.start() 92 self.m3.return_value = True 93 94 def tearDown(self): 95 self.p2.stop() 96 self.p3.stop() 97 98 def test_create_user(self, *args): 99 set_module_args(dict( 100 username_credential='someuser', 101 password_credential='testpass', 102 partition_access=['Common:guest'], 103 update_password='on_create', 104 provider=dict( 105 server='localhost', 106 password='password', 107 user='admin' 108 ) 109 )) 110 111 module = AnsibleModule( 112 argument_spec=self.spec.argument_spec, 113 supports_check_mode=self.spec.supports_check_mode 114 ) 115 116 # Override methods to force specific logic in the module to happen 117 pm = PartitionedManager(module=module, params=module.params) 118 pm.create_on_device = Mock(return_value=True) 119 pm.exists = Mock(return_value=False) 120 121 mm = ModuleManager(module=module) 122 mm.is_version_less_than_13 = Mock(return_value=False) 123 mm.get_manager = Mock(return_value=pm) 124 125 results = mm.exec_module() 126 127 assert results['changed'] is True 128 assert results['partition_access'] == ['Common:guest'] 129 130 def test_create_user_no_password(self, *args): 131 set_module_args(dict( 132 username_credential='someuser', 133 partition_access=['Common:guest'], 134 provider=dict( 135 server='localhost', 136 password='password', 137 user='admin' 138 ) 139 )) 140 141 module = AnsibleModule( 142 argument_spec=self.spec.argument_spec, 143 supports_check_mode=self.spec.supports_check_mode 144 ) 145 146 # Override methods to force specific logic in the module to happen 147 pm = PartitionedManager(module=module, params=module.params) 148 pm.create_on_device = Mock(return_value=True) 149 pm.exists = Mock(return_value=False) 150 151 mm = ModuleManager(module=module) 152 mm.is_version_less_than_13 = Mock(return_value=False) 153 mm.get_manager = Mock(return_value=pm) 154 155 results = mm.exec_module() 156 157 assert results['changed'] is True 158 assert results['partition_access'] == ['Common:guest'] 159 160 def test_create_user_partition_access_raises(self, *args): 161 set_module_args(dict( 162 username_credential='someuser', 163 provider=dict( 164 server='localhost', 165 password='password', 166 user='admin' 167 ) 168 )) 169 170 module = AnsibleModule( 171 argument_spec=self.spec.argument_spec, 172 supports_check_mode=self.spec.supports_check_mode 173 ) 174 175 # Override methods to force specific logic in the module to happen 176 pm = PartitionedManager(module=module, params=module.params) 177 pm.create_on_device = Mock(return_value=True) 178 pm.exists = Mock(return_value=False) 179 180 mm = ModuleManager(module=module) 181 mm.is_version_less_than_13 = Mock(return_value=False) 182 mm.get_manager = Mock(return_value=pm) 183 184 msg = "The 'partition_access' option " \ 185 "is required when creating a resource." 186 187 with pytest.raises(F5ModuleError) as ex: 188 mm.exec_module() 189 assert str(ex.value) == msg 190 191 def test_create_user_shell_bash(self, *args): 192 set_module_args(dict( 193 username_credential='someuser', 194 password_credential='testpass', 195 partition_access=['all:admin'], 196 update_password='on_create', 197 shell='bash', 198 provider=dict( 199 server='localhost', 200 password='password', 201 user='admin' 202 ) 203 )) 204 205 module = AnsibleModule( 206 argument_spec=self.spec.argument_spec, 207 supports_check_mode=self.spec.supports_check_mode 208 ) 209 210 # Override methods to force specific logic in the module to happen 211 pm = PartitionedManager(module=module, params=module.params) 212 pm.create_on_device = Mock(return_value=True) 213 pm.exists = Mock(return_value=False) 214 215 mm = ModuleManager(module=module) 216 mm.is_version_less_than_13 = Mock(return_value=False) 217 mm.get_manager = Mock(return_value=pm) 218 219 results = mm.exec_module() 220 221 assert results['changed'] is True 222 assert results['partition_access'] == ['all:admin'] 223 224 def test_create_user_shell_not_permitted_raises(self, *args): 225 set_module_args(dict( 226 username_credential='someuser', 227 password_credential='testpass', 228 partition_access=['Common:guest'], 229 update_password='on_create', 230 shell='bash', 231 provider=dict( 232 server='localhost', 233 password='password', 234 user='admin' 235 ) 236 )) 237 238 module = AnsibleModule( 239 argument_spec=self.spec.argument_spec, 240 supports_check_mode=self.spec.supports_check_mode 241 ) 242 243 # Override methods to force specific logic in the module to happen 244 pm = PartitionedManager(module=module, params=module.params) 245 pm.create_on_device = Mock(return_value=True) 246 pm.exists = Mock(return_value=False) 247 248 mm = ModuleManager(module=module) 249 mm.is_version_less_than_13 = Mock(return_value=False) 250 mm.get_manager = Mock(return_value=pm) 251 252 msg = "Shell access is only available to 'admin' or " \ 253 "'resource-admin' roles." 254 255 with pytest.raises(F5ModuleError) as ex: 256 mm.exec_module() 257 assert str(ex.value) == msg 258 259 def test_update_user_password_no_pass(self, *args): 260 set_module_args(dict( 261 username_credential='someuser', 262 password_credential='testpass', 263 provider=dict( 264 server='localhost', 265 password='password', 266 user='admin' 267 ) 268 )) 269 270 module = AnsibleModule( 271 argument_spec=self.spec.argument_spec, 272 supports_check_mode=self.spec.supports_check_mode 273 ) 274 275 # Configure the parameters that would be returned by querying the 276 # remote device 277 current = Parameters(params=load_fixture('load_auth_user_no_pass.json')) 278 279 # Override methods to force specific logic in the module to happen 280 pm = PartitionedManager(module=module, params=module.params) 281 pm.exists = Mock(return_value=True) 282 pm.update_on_device = Mock(return_value=True) 283 pm.read_current_from_device = Mock(return_value=current) 284 285 mm = ModuleManager(module=module) 286 mm.is_version_less_than_13 = Mock(return_value=False) 287 mm.get_manager = Mock(return_value=pm) 288 289 results = mm.exec_module() 290 291 assert results['changed'] is True 292 293 def test_update_user_password_with_pass(self, *args): 294 set_module_args(dict( 295 username_credential='someuser', 296 password_credential='testpass', 297 provider=dict( 298 server='localhost', 299 password='password', 300 user='admin' 301 ) 302 )) 303 304 module = AnsibleModule( 305 argument_spec=self.spec.argument_spec, 306 supports_check_mode=self.spec.supports_check_mode 307 ) 308 309 # Configure the parameters that would be returned by querying the 310 # remote device 311 current = Parameters(params=load_fixture('load_auth_user_with_pass.json')) 312 313 # Override methods to force specific logic in the module to happen 314 pm = PartitionedManager(module=module, params=module.params) 315 pm.exists = Mock(return_value=True) 316 pm.update_on_device = Mock(return_value=True) 317 pm.read_current_from_device = Mock(return_value=current) 318 319 mm = ModuleManager(module=module) 320 mm.is_version_less_than_13 = Mock(return_value=False) 321 mm.get_manager = Mock(return_value=pm) 322 323 results = mm.exec_module() 324 325 assert results['changed'] is True 326 327 def test_update_user_shell_to_none(self, *args): 328 set_module_args(dict( 329 username_credential='someuser', 330 shell='none', 331 provider=dict( 332 server='localhost', 333 password='password', 334 user='admin' 335 ) 336 )) 337 338 module = AnsibleModule( 339 argument_spec=self.spec.argument_spec, 340 supports_check_mode=self.spec.supports_check_mode 341 ) 342 343 # Configure the parameters that would be returned by querying the 344 # remote device 345 current = Parameters( 346 params=dict( 347 user='admin', 348 shell='tmsh' 349 ) 350 ) 351 352 # Override methods to force specific logic in the module to happen 353 pm = PartitionedManager(module=module, params=module.params) 354 pm.exists = Mock(return_value=True) 355 pm.update_on_device = Mock(return_value=True) 356 pm.read_current_from_device = Mock(return_value=current) 357 358 mm = ModuleManager(module=module) 359 mm.is_version_less_than_13 = Mock(return_value=False) 360 mm.get_manager = Mock(return_value=pm) 361 362 results = mm.exec_module() 363 364 assert results['changed'] is True 365 assert results['shell'] == 'none' 366 367 def test_update_user_shell_to_none_shell_attribute_missing(self, *args): 368 set_module_args(dict( 369 username_credential='someuser', 370 shell='none', 371 provider=dict( 372 server='localhost', 373 password='password', 374 user='admin' 375 ) 376 )) 377 378 module = AnsibleModule( 379 argument_spec=self.spec.argument_spec, 380 supports_check_mode=self.spec.supports_check_mode 381 ) 382 383 # Configure the parameters that would be returned by querying the 384 # remote device 385 access = [{'name': 'Common', 'role': 'guest'}] 386 current = Parameters( 387 params=dict( 388 user='admin', 389 partition_access=access 390 ) 391 ) 392 393 # Override methods to force specific logic in the module to happen 394 pm = PartitionedManager(module=module, params=module.params) 395 pm.exists = Mock(return_value=True) 396 pm.update_on_device = Mock(return_value=True) 397 pm.read_current_from_device = Mock(return_value=current) 398 399 mm = ModuleManager(module=module) 400 mm.is_version_less_than_13 = Mock(return_value=False) 401 mm.get_manager = Mock(return_value=pm) 402 403 results = mm.exec_module() 404 405 assert results['changed'] is False 406 assert not hasattr(results, 'shell') 407 408 def test_update_user_shell_to_bash(self, *args): 409 set_module_args(dict( 410 username_credential='someuser', 411 shell='bash', 412 provider=dict( 413 server='localhost', 414 password='password', 415 user='admin' 416 ) 417 )) 418 419 module = AnsibleModule( 420 argument_spec=self.spec.argument_spec, 421 supports_check_mode=self.spec.supports_check_mode 422 ) 423 424 # Configure the parameters that would be returned by querying the 425 # remote device 426 access = [{'name': 'all', 'role': 'admin'}] 427 current = Parameters( 428 params=dict( 429 user='admin', 430 shell='tmsh', 431 partition_access=access 432 ) 433 ) 434 435 # Override methods to force specific logic in the module to happen 436 upm = UnpartitionedManager(module=module, params=module.params) 437 upm.exists = Mock(return_value=True) 438 upm.update_on_device = Mock(return_value=True) 439 upm.read_current_from_device = Mock(return_value=current) 440 441 mm = ModuleManager(module=module) 442 mm.is_version_less_than_13 = Mock(return_value=True) 443 mm.get_manager = Mock(return_value=upm) 444 445 results = mm.exec_module() 446 447 assert results['changed'] is True 448 assert results['shell'] == 'bash' 449 450 def test_update_user_shell_to_bash_mutliple_roles(self, *args): 451 set_module_args(dict( 452 username_credential='someuser', 453 shell='bash', 454 provider=dict( 455 server='localhost', 456 password='password', 457 user='admin' 458 ) 459 )) 460 461 module = AnsibleModule( 462 argument_spec=self.spec.argument_spec, 463 supports_check_mode=self.spec.supports_check_mode 464 ) 465 466 # Configure the parameters that would be returned by querying the 467 # remote device 468 access = [ 469 {'name': 'Common', 'role': 'operator'}, 470 {'name': 'all', 'role': 'guest'} 471 ] 472 current = Parameters( 473 params=dict( 474 user='admin', 475 shell='tmsh', 476 partition_access=access 477 ) 478 ) 479 480 # Override methods to force specific logic in the module to happen 481 upm = UnpartitionedManager(module=module, params=module.params) 482 upm.exists = Mock(return_value=True) 483 upm.update_on_device = Mock(return_value=True) 484 upm.read_current_from_device = Mock(return_value=current) 485 486 mm = ModuleManager(module=module) 487 mm.is_version_less_than_13 = Mock(return_value=True) 488 mm.get_manager = Mock(return_value=upm) 489 490 msg = "Shell access is only available to 'admin' or " \ 491 "'resource-admin' roles." 492 493 with pytest.raises(F5ModuleError) as ex: 494 mm.exec_module() 495 assert str(ex.value) == msg 496 497 498class TestLegacyManager(unittest.TestCase): 499 def setUp(self): 500 self.spec = ArgumentSpec() 501 self.p2 = patch('ansible_collections.f5networks.f5_modules.plugins.modules.bigip_user.tmos_version') 502 self.p3 = patch('ansible_collections.f5networks.f5_modules.plugins.modules.bigip_user.send_teem') 503 self.m2 = self.p2.start() 504 self.m2.return_value = '14.1.0' 505 self.m3 = self.p3.start() 506 self.m3.return_value = True 507 508 def tearDown(self): 509 self.p2.stop() 510 self.p3.stop() 511 512 def test_create_user(self, *args): 513 set_module_args(dict( 514 username_credential='someuser', 515 password_credential='testpass', 516 partition_access=['Common:guest'], 517 update_password='on_create', 518 provider=dict( 519 server='localhost', 520 password='password', 521 user='admin' 522 ) 523 )) 524 525 module = AnsibleModule( 526 argument_spec=self.spec.argument_spec, 527 supports_check_mode=self.spec.supports_check_mode 528 ) 529 530 # Override methods to force specific logic in the module to happen 531 upm = UnpartitionedManager(module=module, params=module.params) 532 upm.create_on_device = Mock(return_value=True) 533 upm.exists = Mock(return_value=False) 534 535 mm = ModuleManager(module=module) 536 mm.is_version_less_than_13 = Mock(return_value=True) 537 mm.get_manager = Mock(return_value=upm) 538 539 results = mm.exec_module() 540 541 assert results['changed'] is True 542 assert results['partition_access'] == ['Common:guest'] 543 544 def test_create_user_no_password(self, *args): 545 set_module_args(dict( 546 username_credential='someuser', 547 partition_access=['Common:guest'], 548 provider=dict( 549 server='localhost', 550 password='password', 551 user='admin' 552 ) 553 )) 554 555 module = AnsibleModule( 556 argument_spec=self.spec.argument_spec, 557 supports_check_mode=self.spec.supports_check_mode 558 ) 559 560 # Override methods to force specific logic in the module to happen 561 upm = UnpartitionedManager(module=module, params=module.params) 562 upm.create_on_device = Mock(return_value=True) 563 upm.exists = Mock(return_value=False) 564 565 mm = ModuleManager(module=module) 566 mm.is_version_less_than_13 = Mock(return_value=True) 567 mm.get_manager = Mock(return_value=upm) 568 569 results = mm.exec_module() 570 571 assert results['changed'] is True 572 assert results['partition_access'] == ['Common:guest'] 573 574 def test_create_user_partition_access_raises(self, *args): 575 set_module_args(dict( 576 username_credential='someuser', 577 provider=dict( 578 server='localhost', 579 password='password', 580 user='admin' 581 ) 582 )) 583 584 module = AnsibleModule( 585 argument_spec=self.spec.argument_spec, 586 supports_check_mode=self.spec.supports_check_mode 587 ) 588 589 # Override methods to force specific logic in the module to happen 590 upm = UnpartitionedManager(module=module, params=module.params) 591 upm.create_on_device = Mock(return_value=True) 592 upm.exists = Mock(return_value=False) 593 594 mm = ModuleManager(module=module) 595 mm.is_version_less_than_13 = Mock(return_value=True) 596 mm.get_manager = Mock(return_value=upm) 597 598 msg = "The 'partition_access' option " \ 599 "is required when creating a resource." 600 601 with pytest.raises(F5ModuleError) as ex: 602 mm.exec_module() 603 assert str(ex.value) == msg 604 605 def test_create_user_shell_bash(self, *args): 606 set_module_args(dict( 607 username_credential='someuser', 608 password_credential='testpass', 609 partition_access=['all:admin'], 610 update_password='on_create', 611 shell='bash', 612 provider=dict( 613 server='localhost', 614 password='password', 615 user='admin' 616 ) 617 )) 618 619 module = AnsibleModule( 620 argument_spec=self.spec.argument_spec, 621 supports_check_mode=self.spec.supports_check_mode 622 ) 623 624 # Override methods to force specific logic in the module to happen 625 upm = UnpartitionedManager(module=module, params=module.params) 626 upm.create_on_device = Mock(return_value=True) 627 upm.exists = Mock(return_value=False) 628 629 mm = ModuleManager(module=module) 630 mm.is_version_less_than_13 = Mock(return_value=True) 631 mm.get_manager = Mock(return_value=upm) 632 633 results = mm.exec_module() 634 635 assert results['changed'] is True 636 assert results['partition_access'] == ['all:admin'] 637 638 def test_create_user_shell_not_permitted_raises(self, *args): 639 set_module_args(dict( 640 username_credential='someuser', 641 password_credential='testpass', 642 partition_access=['Common:guest'], 643 update_password='on_create', 644 shell='bash', 645 provider=dict( 646 server='localhost', 647 password='password', 648 user='admin' 649 ) 650 )) 651 652 module = AnsibleModule( 653 argument_spec=self.spec.argument_spec, 654 supports_check_mode=self.spec.supports_check_mode 655 ) 656 657 # Override methods to force specific logic in the module to happen 658 upm = UnpartitionedManager(module=module, params=module.params) 659 upm.create_on_device = Mock(return_value=True) 660 upm.exists = Mock(return_value=False) 661 662 mm = ModuleManager(module=module) 663 mm.is_version_less_than_13 = Mock(return_value=True) 664 mm.get_manager = Mock(return_value=upm) 665 666 msg = "Shell access is only available to 'admin' or " \ 667 "'resource-admin' roles." 668 669 with pytest.raises(F5ModuleError) as ex: 670 mm.exec_module() 671 assert str(ex.value) == msg 672 673 def test_update_user_password(self, *args): 674 set_module_args(dict( 675 username_credential='someuser', 676 password_credential='testpass', 677 provider=dict( 678 server='localhost', 679 password='password', 680 user='admin' 681 ) 682 )) 683 684 module = AnsibleModule( 685 argument_spec=self.spec.argument_spec, 686 supports_check_mode=self.spec.supports_check_mode 687 ) 688 689 # Configure the parameters that would be returned by querying the 690 # remote device 691 access = [{'name': 'Common', 'role': 'guest'}] 692 current = Parameters( 693 params=dict( 694 shell='tmsh', 695 partition_access=access 696 ) 697 ) 698 699 # Override methods to force specific logic in the module to happen 700 upm = UnpartitionedManager(module=module, params=module.params) 701 upm.exists = Mock(return_value=True) 702 upm.update_on_device = Mock(return_value=True) 703 upm.read_current_from_device = Mock(return_value=current) 704 705 mm = ModuleManager(module=module) 706 mm.is_version_less_than_13 = Mock(return_value=True) 707 mm.get_manager = Mock(return_value=upm) 708 709 results = mm.exec_module() 710 711 assert results['changed'] is True 712 713 def test_update_user_shell_to_none(self, *args): 714 set_module_args(dict( 715 username_credential='someuser', 716 shell='none', 717 provider=dict( 718 server='localhost', 719 password='password', 720 user='admin' 721 ) 722 )) 723 724 module = AnsibleModule( 725 argument_spec=self.spec.argument_spec, 726 supports_check_mode=self.spec.supports_check_mode 727 ) 728 729 # Configure the parameters that would be returned by querying the 730 # remote device 731 current = Parameters( 732 params=dict( 733 user='admin', 734 shell='tmsh' 735 ) 736 ) 737 738 # Override methods to force specific logic in the module to happen 739 upm = UnpartitionedManager(module=module, params=module.params) 740 upm.exists = Mock(return_value=True) 741 upm.update_on_device = Mock(return_value=True) 742 upm.read_current_from_device = Mock(return_value=current) 743 744 mm = ModuleManager(module=module) 745 mm.is_version_less_than_13 = Mock(return_value=True) 746 mm.get_manager = Mock(return_value=upm) 747 748 results = mm.exec_module() 749 750 assert results['changed'] is True 751 assert results['shell'] == 'none' 752 753 def test_update_user_shell_to_none_shell_attribute_missing(self, *args): 754 set_module_args(dict( 755 username_credential='someuser', 756 shell='none', 757 provider=dict( 758 server='localhost', 759 password='password', 760 user='admin' 761 ) 762 )) 763 764 module = AnsibleModule( 765 argument_spec=self.spec.argument_spec, 766 supports_check_mode=self.spec.supports_check_mode 767 ) 768 769 # Configure the parameters that would be returned by querying the 770 # remote device 771 access = [{'name': 'Common', 'role': 'guest'}] 772 current = Parameters( 773 params=dict( 774 user='admin', 775 partition_access=access 776 ) 777 ) 778 779 # Override methods to force specific logic in the module to happen 780 upm = UnpartitionedManager(module=module, params=module.params) 781 upm.exists = Mock(return_value=True) 782 upm.update_on_device = Mock(return_value=True) 783 upm.read_current_from_device = Mock(return_value=current) 784 785 mm = ModuleManager(module=module) 786 mm.is_version_less_than_13 = Mock(return_value=True) 787 mm.get_manager = Mock(return_value=upm) 788 789 results = mm.exec_module() 790 791 assert results['changed'] is False 792 assert not hasattr(results, 'shell') 793 794 def test_update_user_shell_to_bash(self, *args): 795 set_module_args(dict( 796 username_credential='someuser', 797 shell='bash', 798 provider=dict( 799 server='localhost', 800 password='password', 801 user='admin' 802 ) 803 )) 804 805 module = AnsibleModule( 806 argument_spec=self.spec.argument_spec, 807 supports_check_mode=self.spec.supports_check_mode 808 ) 809 810 # Configure the parameters that would be returned by querying the 811 # remote device 812 access = [{'name': 'all', 'role': 'admin'}] 813 current = Parameters( 814 params=dict( 815 user='admin', 816 shell='tmsh', 817 partition_access=access 818 ) 819 ) 820 821 # Override methods to force specific logic in the module to happen 822 upm = UnpartitionedManager(module=module, params=module.params) 823 upm.exists = Mock(return_value=True) 824 upm.update_on_device = Mock(return_value=True) 825 upm.read_current_from_device = Mock(return_value=current) 826 827 mm = ModuleManager(module=module) 828 mm.is_version_less_than_13 = Mock(return_value=True) 829 mm.get_manager = Mock(return_value=upm) 830 831 results = mm.exec_module() 832 833 assert results['changed'] is True 834 assert results['shell'] == 'bash' 835 836 def test_update_user_shell_to_bash_mutliple_roles(self, *args): 837 set_module_args(dict( 838 username_credential='someuser', 839 shell='bash', 840 provider=dict( 841 server='localhost', 842 password='password', 843 user='admin' 844 ) 845 )) 846 847 module = AnsibleModule( 848 argument_spec=self.spec.argument_spec, 849 supports_check_mode=self.spec.supports_check_mode 850 ) 851 852 # Configure the parameters that would be returned by querying the 853 # remote device 854 access = [ 855 {'name': 'Common', 'role': 'operator'}, 856 {'name': 'all', 'role': 'guest'} 857 ] 858 current = Parameters( 859 params=dict( 860 user='admin', 861 shell='tmsh', 862 partition_access=access 863 ) 864 ) 865 866 # Override methods to force specific logic in the module to happen 867 upm = UnpartitionedManager(module=module, params=module.params) 868 upm.exists = Mock(return_value=True) 869 upm.update_on_device = Mock(return_value=True) 870 upm.read_current_from_device = Mock(return_value=current) 871 872 mm = ModuleManager(module=module) 873 mm.is_version_less_than_13 = Mock(return_value=True) 874 mm.get_manager = Mock(return_value=upm) 875 876 msg = "Shell access is only available to 'admin' or " \ 877 "'resource-admin' roles." 878 879 with pytest.raises(F5ModuleError) as ex: 880 mm.exec_module() 881 assert str(ex.value) == msg 882