diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-05 16:18:41 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-05 16:18:41 +0000 |
commit | b643c52cf29ce5bbab738b43290af3556efa1ca9 (patch) | |
tree | 21d5c53d7a9b696627a255777cefdf6f78968824 /ansible_collections/purestorage/fusion/tests/functional | |
parent | Releasing progress-linux version 9.5.1+dfsg-1~progress7.99u1. (diff) | |
download | ansible-b643c52cf29ce5bbab738b43290af3556efa1ca9.tar.xz ansible-b643c52cf29ce5bbab738b43290af3556efa1ca9.zip |
Merging upstream version 10.0.0+dfsg.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'ansible_collections/purestorage/fusion/tests/functional')
20 files changed, 0 insertions, 16803 deletions
diff --git a/ansible_collections/purestorage/fusion/tests/functional/README.md b/ansible_collections/purestorage/fusion/tests/functional/README.md deleted file mode 100644 index d7edc6609..000000000 --- a/ansible_collections/purestorage/fusion/tests/functional/README.md +++ /dev/null @@ -1,35 +0,0 @@ -# Functional tests - -Functional tests aims at testing each module as a whole. -They make sure the module parses given parameters into correct API calls. - -Specific functions of modules should be tested in Unit tests. - -## Running tests - -```bash -pytest tests/functional -``` - -## Adding new tests - -Every module tested should consist (at least) of the following cases: - -- test_module_fails_on_wrong_parameters -- test_NAME_create_name -- test_NAME_create_without_display_name -- test_NAME_create_exception -- test_NAME_create_op_fails -- test_NAME_create_op_exception -- test_NAME_update -- test_NAME_update_exception -- test_NAME_update_op_fails -- test_NAME_update_op_exception -- test_NAME_present_not_changed -- test_NAME_absent_not_changed -- test_NAME_delete -- test_NAME_delete_exception -- test_NAME_delete_op_fails -- test_NAME_delete_op_exception - -See already existing tests (e.g. `test_fusion_region.py`) for inspiration. diff --git a/ansible_collections/purestorage/fusion/tests/functional/__init__.py b/ansible_collections/purestorage/fusion/tests/functional/__init__.py deleted file mode 100644 index e69de29bb..000000000 --- a/ansible_collections/purestorage/fusion/tests/functional/__init__.py +++ /dev/null diff --git a/ansible_collections/purestorage/fusion/tests/functional/test_fusion_api_client.py b/ansible_collections/purestorage/fusion/tests/functional/test_fusion_api_client.py deleted file mode 100644 index 295c62bd6..000000000 --- a/ansible_collections/purestorage/fusion/tests/functional/test_fusion_api_client.py +++ /dev/null @@ -1,374 +0,0 @@ -# -*- coding: utf-8 -*- - -# (c) 2023, Andrej Pajtas (apajtas@purestorage.com) -# GNU General Public License v3.0+ (see COPYING.GPLv3 or https://www.gnu.org/licenses/gpl-3.0.txt) - -from __future__ import absolute_import, division, print_function - -__metaclass__ = type - -from dataclasses import asdict, dataclass -from unittest.mock import MagicMock, patch - -import fusion as purefusion -import pytest -from ansible.module_utils import basic -from ansible_collections.purestorage.fusion.plugins.modules import fusion_api_client -from ansible_collections.purestorage.fusion.tests.functional.utils import ( - AnsibleExitJson, - AnsibleFailJson, - exit_json, - fail_json, - set_module_args, -) -from urllib3.exceptions import HTTPError - -# GLOBAL MOCKS -fusion_api_client.setup_fusion = MagicMock( - return_value=purefusion.api_client.ApiClient() -) -purefusion.api_client.ApiClient.call_api = MagicMock( - side_effect=Exception("API call not mocked!") -) -basic.AnsibleModule.exit_json = exit_json -basic.AnsibleModule.fail_json = fail_json - - -@dataclass -class FakeApiClient: - id: str - self_link: str - name: str - display_name: str - issuer: str - public_key: str - last_key_update: float - last_used: float - creator_id: str - - -@pytest.fixture -def current_clients(): - return [ - FakeApiClient( - "1", - "self_link_value", - "client1", - "client1", - "apikey:name:thisisnotreal", - "0123456789", - 12345, - 12345, - "1234", - ), - FakeApiClient( - "2", - "self_link_value", - "client2", - "client2", - "apikey:name:thisisnotreal", - "0123456789", - 12345, - 12345, - "1234", - ), - FakeApiClient( - "3", - "self_link_value", - "client3", - "client3", - "apikey:name:thisisnotreal", - "0123456789", - 12345, - 12345, - "1234", - ), - ] - - -@patch("fusion.IdentityManagerApi") -@pytest.mark.parametrize( - "module_args", - [ - # required parameter 'name` is missing - { - "state": "present", - "public_key": "0123456789", - }, - # unknown parameter 'extra' is provided - { - "state": "present", - "name": "client1", - "public_key": "0123456789", - "extra": "value", - }, - # parameter 'state` has incorrect value - { - "state": "cool", - "name": "client1", - "public_key": "0123456789", - }, - ], -) -def test_module_fails_on_wrong_parameters(m_im_api, module_args, current_clients): - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.list_api_clients = MagicMock(return_value=current_clients) - api_obj.get_api_client = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_api_client = MagicMock() - api_obj.delete_api_client = MagicMock() - m_im_api.return_value = api_obj - - # run module - with pytest.raises(AnsibleFailJson): - fusion_api_client.main() - - # check api was not called at all - api_obj.list_api_clients.assert_not_called() - api_obj.get_api_client.assert_not_called() - api_obj.create_api_client.assert_not_called() - api_obj.delete_api_client.assert_not_called() - - -@patch("fusion.IdentityManagerApi") -def test_api_client_create(m_im_api, current_clients): - module_args = { - "state": "present", - "name": "new_client", - "public_key": "0123456789", - "app_id": "ABCD1234", - "key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.list_api_clients = MagicMock(return_value=current_clients) - api_obj.get_api_client = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_api_client = MagicMock( - return_value=FakeApiClient( - "321321", - "self_link_value", - "client_test", - "client_test", - "apikey:name:test", - "321321", - 321321, - 321321, - "321321", - ) - ) - api_obj.delete_api_client = MagicMock() - m_im_api.return_value = api_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_api_client.main() - - assert exc.value.changed is True - assert exc.value.id == "321321" - - # check api was called correctly - api_obj.list_api_clients.assert_called_once_with() - api_obj.get_api_client.assert_not_called() - api_obj.create_api_client.assert_called_once_with( - purefusion.APIClientPost( - public_key=module_args["public_key"], - display_name=module_args["name"], - ) - ) - api_obj.delete_api_client.assert_not_called() - - -@patch("fusion.IdentityManagerApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, HTTPError), - ], -) -def test_api_client_create_exception( - m_im_api, exec_original, exec_catch, current_clients -): - module_args = { - "state": "present", - "name": "new_client", - "public_key": "0123456789", - "app_id": "ABCD1234", - "key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.list_api_clients = MagicMock(return_value=current_clients) - api_obj.get_api_client = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_api_client = MagicMock(side_effect=exec_original) - api_obj.delete_api_client = MagicMock() - m_im_api.return_value = api_obj - - # run module - with pytest.raises(exec_catch): - fusion_api_client.main() - - # check api was called correctly - api_obj.list_api_clients.assert_called_once_with() - api_obj.get_api_client.assert_not_called() - api_obj.create_api_client.assert_called_once_with( - purefusion.APIClientPost( - public_key=module_args["public_key"], - display_name=module_args["name"], - ) - ) - api_obj.delete_api_client.assert_not_called() - - -@patch("fusion.IdentityManagerApi") -def test_api_client_present_not_changed(m_im_api, current_clients): - current_api_client = current_clients[0] - module_args = { - "state": "present", - "name": current_api_client.display_name, - "public_key": current_api_client.public_key, - "app_id": "ABCD1234", - "key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.list_api_clients = MagicMock(return_value=current_clients) - api_obj.get_api_client = MagicMock( - return_value=purefusion.APIClient(**asdict(current_api_client)) - ) - api_obj.create_api_client = MagicMock() - api_obj.delete_api_client = MagicMock() - m_im_api.return_value = api_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_api_client.main() - - assert exc.value.changed is False - - # check api was called correctly - api_obj.list_api_clients.assert_called_once_with() - api_obj.get_api_client.assert_not_called() - api_obj.create_api_client.assert_not_called() - api_obj.delete_api_client.assert_not_called() - - -@patch("fusion.IdentityManagerApi") -def test_api_client_absent_not_changed(m_im_api, current_clients): - module_args = { - "state": "absent", - "name": "non_existing_client", - "public_key": "0123456789", - "app_id": "ABCD1234", - "key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.list_api_clients = MagicMock(return_value=current_clients) - api_obj.get_api_client = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_api_client = MagicMock() - api_obj.delete_api_client = MagicMock() - m_im_api.return_value = api_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_api_client.main() - - assert exc.value.changed is False - - # check api was called correctly - api_obj.list_api_clients.assert_called_once_with() - api_obj.get_api_client.assert_not_called() - api_obj.create_api_client.assert_not_called() - api_obj.delete_api_client.assert_not_called() - - -@patch("fusion.IdentityManagerApi") -def test_api_client_delete(m_im_api, current_clients): - current_api_client = current_clients[0] - module_args = { - "state": "absent", - "name": current_api_client.display_name, - "public_key": current_api_client.public_key, - "app_id": "ABCD1234", - "key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.list_api_clients = MagicMock(return_value=current_clients) - api_obj.get_api_client = MagicMock( - return_value=purefusion.APIClient(**asdict(current_api_client)) - ) - api_obj.create_api_client = MagicMock() - api_obj.delete_api_client = MagicMock() - m_im_api.return_value = api_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_api_client.main() - - assert exc.value.changed is True - - # check api was called correctly - api_obj.list_api_clients.assert_called_once_with() - api_obj.get_api_client.assert_not_called() - api_obj.create_api_client.assert_not_called() - api_obj.delete_api_client.assert_called_once_with( - api_client_id=current_api_client.id - ) - - -@patch("fusion.IdentityManagerApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, HTTPError), - ], -) -def test_api_client_delete_exception( - m_im_api, exec_original, exec_catch, current_clients -): - current_api_client = current_clients[0] - module_args = { - "state": "absent", - "name": current_api_client.display_name, - "public_key": current_api_client.public_key, - "app_id": "ABCD1234", - "key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.list_api_clients = MagicMock(return_value=current_clients) - api_obj.get_api_client = MagicMock( - return_value=purefusion.APIClient(**asdict(current_api_client)) - ) - api_obj.create_api_client = MagicMock() - api_obj.delete_api_client = MagicMock(side_effect=exec_original) - m_im_api.return_value = api_obj - - # run module - with pytest.raises(exec_catch): - fusion_api_client.main() - - # check api was called correctly - api_obj.list_api_clients.assert_called_once_with() - api_obj.get_api_client.assert_not_called() - api_obj.create_api_client.assert_not_called() - api_obj.delete_api_client.assert_called_once_with( - api_client_id=current_api_client.id - ) diff --git a/ansible_collections/purestorage/fusion/tests/functional/test_fusion_array.py b/ansible_collections/purestorage/fusion/tests/functional/test_fusion_array.py deleted file mode 100644 index 6af1e1136..000000000 --- a/ansible_collections/purestorage/fusion/tests/functional/test_fusion_array.py +++ /dev/null @@ -1,1344 +0,0 @@ -# -*- coding: utf-8 -*- - -# (c) 2023, Andrej Pajtas (apajtas@purestorage.com) -# GNU General Public License v3.0+ (see COPYING.GPLv3 or https://www.gnu.org/licenses/gpl-3.0.txt) - -from __future__ import absolute_import, division, print_function - -__metaclass__ = type - -from unittest.mock import MagicMock, call, patch - -import fusion as purefusion -import pytest -from ansible.module_utils import basic -from ansible_collections.purestorage.fusion.plugins.module_utils.errors import ( - OperationException, -) -from ansible_collections.purestorage.fusion.plugins.modules import fusion_array -from ansible_collections.purestorage.fusion.tests.functional.utils import ( - AnsibleExitJson, - AnsibleFailJson, - FailedOperationMock, - OperationMock, - SuccessfulOperationMock, - FAKE_RESOURCE_ID, - exit_json, - fail_json, - set_module_args, -) -from urllib3.exceptions import HTTPError - -# GLOBAL MOCKS -fusion_array.setup_fusion = MagicMock(return_value=purefusion.api_client.ApiClient()) -purefusion.api_client.ApiClient.call_api = MagicMock( - side_effect=Exception("API call not mocked!") -) -basic.AnsibleModule.exit_json = exit_json -basic.AnsibleModule.fail_json = fail_json - - -@pytest.fixture -def module_args(): - return { - "state": "present", - "name": "array1", - "display_name": "Array 1", - "region": "region1", - "availability_zone": "az1", - "appliance_id": "23984573498573", - "apartment_id": "76586785687", - "host_name": "array_1", - "hardware_type": "flash-array-x", - "maintenance_mode": False, - "unavailable_mode": False, - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - - -@pytest.fixture -def current_array(module_args): - return { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], - "display_name": module_args["display_name"], - "region": module_args["region"], - "availability_zone": module_args["availability_zone"], - "appliance_id": module_args["appliance_id"], - "apartment_id": module_args["apartment_id"], - "host_name": module_args["host_name"], - "hardware_type": module_args["hardware_type"], - "maintenance_mode": module_args["maintenance_mode"], - "unavailable_mode": module_args["unavailable_mode"], - } - - -@patch("fusion.OperationsApi") -@patch("fusion.ArraysApi") -@pytest.mark.parametrize( - "module_args", - [ - # required parameter 'name` is missing - { - "state": "present", - "display_name": "Array 1", - "region": "region1", - "availability_zone": "az1", - "appliance_id": "23984573498573", - "host_name": "array_1", - "hardware_type": "flash-array-x", - "maintenance_mode": False, - "unavailable_mode": False, - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - # required parameter 'region` is missing - { - "state": "present", - "name": "array1", - "display_name": "Array 1", - "availability_zone": "az1", - "appliance_id": "23984573498573", - "host_name": "array_1", - "hardware_type": "flash-array-x", - "maintenance_mode": False, - "unavailable_mode": False, - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - # required parameter 'availability_zone` is missing - { - "state": "present", - "name": "array1", - "display_name": "Array 1", - "region": "region1", - "appliance_id": "23984573498573", - "host_name": "array_1", - "hardware_type": "flash-array-x", - "maintenance_mode": False, - "unavailable_mode": False, - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - # unknown parameter 'extra' is provided - { - "state": "present", - "name": "array1", - "display_name": "Array 1", - "availability_zone": "az1", - "region": "region1", - "appliance_id": "23984573498573", - "host_name": "array_1", - "hardware_type": "flash-array-x", - "maintenance_mode": False, - "unavailable_mode": False, - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - "extra": "value", - }, - # parameter 'state` has incorrect value - { - "state": "cool", - "name": "array1", - "display_name": "Array 1", - "availability_zone": "az1", - "region": "region1", - "appliance_id": "23984573498573", - "host_name": "array_1", - "hardware_type": "flash-array-x", - "maintenance_mode": False, - "unavailable_mode": False, - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - # parameter 'hardware_type` has incorrect value - { - "state": "present", - "name": "array1", - "display_name": "Array 1", - "availability_zone": "az1", - "region": "region1", - "appliance_id": "23984573498573", - "host_name": "array_1", - "hardware_type": "hdd-array-x", - "maintenance_mode": False, - "unavailable_mode": False, - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - # parameter 'maintenance_mode` has incorrect value - { - "state": "present", - "name": "array1", - "display_name": "Array 1", - "availability_zone": "az1", - "region": "region1", - "appliance_id": "23984573498573", - "host_name": "array_1", - "hardware_type": "flash-array-x", - "maintenance_mode": "string", - "unavailable_mode": False, - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - # parameter 'unavailable_mode` has incorrect value - { - "state": "present", - "name": "array1", - "display_name": "Array 1", - "availability_zone": "az1", - "region": "region1", - "appliance_id": "23984573498573", - "host_name": "array_1", - "hardware_type": "flash-array-x", - "maintenance_mode": False, - "unavailable_mode": "string", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - ], -) -def test_module_fails_on_wrong_parameters(m_array_api, m_op_api, module_args): - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_array = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_array = MagicMock(return_value=OperationMock(1)) - api_obj.update_array = MagicMock(return_value=OperationMock(2)) - api_obj.delete_array = MagicMock(return_value=OperationMock(3)) - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - m_array_api.return_value = api_obj - - # run module - with pytest.raises(AnsibleFailJson): - fusion_array.main() - - # check api was not called at all - api_obj.get_array.assert_not_called() - api_obj.create_array.assert_not_called() - api_obj.update_array.assert_not_called() - api_obj.delete_array.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.ArraysApi") -@pytest.mark.parametrize( - "module_args", - [ - # required parameter 'hardware_type` for creating resource is missing - { - "state": "present", - "name": "array1", - "display_name": "Array 1", - "region": "region1", - "availability_zone": "az1", - "appliance_id": "23984573498573", - "host_name": "array_1", - "maintenance_mode": False, - "unavailable_mode": False, - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - # required parameter 'host_name` for creating resource is missing - { - "state": "present", - "name": "array1", - "display_name": "Array 1", - "region": "region1", - "availability_zone": "az1", - "appliance_id": "23984573498573", - "hardware_type": "flash-array-x", - "maintenance_mode": False, - "unavailable_mode": False, - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - # required parameter 'appliance_id` for creating resource is missing - { - "state": "present", - "name": "array1", - "display_name": "Array 1", - "region": "region1", - "availability_zone": "az1", - "host_name": "array_1", - "hardware_type": "flash-array-x", - "maintenance_mode": False, - "unavailable_mode": False, - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - ], -) -def test_array_create_fails_on_wrong_parameters(m_array_api, m_op_api, module_args): - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_array = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_array = MagicMock(return_value=OperationMock(1)) - api_obj.update_array = MagicMock(return_value=OperationMock(2)) - api_obj.delete_array = MagicMock(return_value=OperationMock(3)) - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - m_array_api.return_value = api_obj - - # run module - with pytest.raises(AnsibleFailJson): - fusion_array.main() - - # check api was not called at all - api_obj.get_array.assert_called_once_with( - array_name=module_args["name"], - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - ) - api_obj.create_array.assert_not_called() - api_obj.update_array.assert_not_called() - api_obj.delete_array.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.ArraysApi") -@pytest.mark.parametrize( - "hw_type", - [ - "flash-array-x", - "flash-array-c", - "flash-array-x-optane", - "flash-array-xl", - ], -) -@pytest.mark.parametrize("main_m", [True, False]) -@pytest.mark.parametrize("unav_m", [True, False]) -def test_array_create(m_array_api, m_op_api, hw_type, main_m, unav_m, module_args): - module_args["hardware_type"] = hw_type - module_args["maintenance_mode"] = main_m - module_args["unavailable_mode"] = unav_m - created_array = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], - "display_name": module_args["display_name"], - "region": module_args["region"], - "availability_zone": module_args["availability_zone"], - "appliance_id": module_args["appliance_id"], - "apartment_id": module_args["apartment_id"], - "host_name": module_args["host_name"], - "hardware_type": module_args["hardware_type"], - "maintenance_mode": not module_args[ - "maintenance_mode" - ], # so we can test patching - "unavailable_mode": not module_args[ - "unavailable_mode" - ], # so we can test patching - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_array = MagicMock( - side_effect=[purefusion.rest.ApiException, purefusion.Array(**created_array)] - ) - api_obj.create_array = MagicMock(return_value=OperationMock(1)) - api_obj.update_array = MagicMock(return_value=OperationMock(2)) - api_obj.delete_array = MagicMock(return_value=OperationMock(3)) - m_array_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_array.main() - - assert exc.value.changed - assert exc.value.id == FAKE_RESOURCE_ID - - # check api was called correctly - api_obj.get_array.assert_called_with( - array_name=module_args["name"], - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - ) - api_obj.create_array.assert_called_once_with( - purefusion.ArrayPost( - hardware_type=module_args["hardware_type"], - display_name=module_args["display_name"], - host_name=module_args["host_name"], - name=module_args["name"], - appliance_id=module_args["appliance_id"], - apartment_id=module_args["apartment_id"], - ), - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - ) - api_obj.update_array.assert_has_calls( - [ - call( - purefusion.ArrayPatch( - maintenance_mode=purefusion.NullableBoolean( - module_args["maintenance_mode"] - ) - ), - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - array_name=module_args["name"], - ), - call( - purefusion.ArrayPatch( - unavailable_mode=purefusion.NullableBoolean( - module_args["unavailable_mode"] - ) - ), - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - array_name=module_args["name"], - ), - ], - any_order=True, - ) - api_obj.delete_array.assert_not_called() - op_obj.get_operation.assert_has_calls( - [ - call(1), - call(2), - call(2), - ] - ) - - -@patch("fusion.OperationsApi") -@patch("fusion.ArraysApi") -def test_array_create_without_display_name(m_array_api, m_op_api, module_args): - del module_args["display_name"] - created_array = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], - "display_name": module_args["name"], - "region": module_args["region"], - "availability_zone": module_args["availability_zone"], - "appliance_id": module_args["appliance_id"], - "apartment_id": module_args["apartment_id"], - "host_name": module_args["host_name"], - "hardware_type": module_args["hardware_type"], - "maintenance_mode": not module_args["maintenance_mode"], - "unavailable_mode": not module_args["unavailable_mode"], - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_array = MagicMock( - side_effect=[purefusion.rest.ApiException, purefusion.Array(**created_array)] - ) - api_obj.create_array = MagicMock(return_value=OperationMock(1)) - api_obj.update_array = MagicMock(return_value=OperationMock(2)) - api_obj.delete_array = MagicMock(return_value=OperationMock(3)) - m_array_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_array.main() - - assert exc.value.changed - assert exc.value.id == FAKE_RESOURCE_ID - - # check api was called correctly - api_obj.get_array.assert_called_with( - array_name=module_args["name"], - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - ) - api_obj.create_array.assert_called_once_with( - purefusion.ArrayPost( - hardware_type=module_args["hardware_type"], - display_name=module_args["name"], - host_name=module_args["host_name"], - name=module_args["name"], - appliance_id=module_args["appliance_id"], - apartment_id=module_args["apartment_id"], - ), - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - ) - api_obj.update_array.assert_has_calls( - [ - call( - purefusion.ArrayPatch( - maintenance_mode=purefusion.NullableBoolean( - module_args["maintenance_mode"] - ) - ), - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - array_name=module_args["name"], - ), - call( - purefusion.ArrayPatch( - unavailable_mode=purefusion.NullableBoolean( - module_args["unavailable_mode"] - ) - ), - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - array_name=module_args["name"], - ), - ], - any_order=True, - ) - api_obj.delete_array.assert_not_called() - op_obj.get_operation.assert_has_calls( - [ - call(1), - call(2), - call(2), - ] - ) - - -@patch("fusion.OperationsApi") -@patch("fusion.ArraysApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, HTTPError), - ], -) -def test_array_create_exception( - m_array_api, m_op_api, exec_original, exec_catch, module_args -): - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_array = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_array = MagicMock(side_effect=exec_original) - api_obj.update_array = MagicMock(return_value=OperationMock(2)) - api_obj.delete_array = MagicMock(return_value=OperationMock(3)) - m_array_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_array.main() - - # check api was called correctly - api_obj.get_array.assert_called_once_with( - array_name=module_args["name"], - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - ) - api_obj.create_array.assert_called_once_with( - purefusion.ArrayPost( - hardware_type=module_args["hardware_type"], - display_name=module_args["display_name"], - host_name=module_args["host_name"], - name=module_args["name"], - appliance_id=module_args["appliance_id"], - apartment_id=module_args["apartment_id"], - ), - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - ) - api_obj.update_array.assert_not_called() - api_obj.delete_array.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.ArraysApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, HTTPError), - ], -) -def test_array_create_second_exception( - m_array_api, m_op_api, exec_original, exec_catch, module_args -): - created_array = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], - "display_name": module_args["name"], - "region": module_args["region"], - "availability_zone": module_args["availability_zone"], - "appliance_id": module_args["appliance_id"], - "apartment_id": module_args["apartment_id"], - "host_name": module_args["host_name"], - "hardware_type": module_args["hardware_type"], - "maintenance_mode": not module_args["maintenance_mode"], - "unavailable_mode": not module_args["unavailable_mode"], - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_array = MagicMock( - side_effect=[purefusion.rest.ApiException, purefusion.Array(**created_array)] - ) - api_obj.create_array = MagicMock(return_value=OperationMock(1)) - api_obj.update_array = MagicMock(side_effect=exec_original) - api_obj.delete_array = MagicMock(return_value=OperationMock(3)) - m_array_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_array.main() - - # check api was called correctly - api_obj.get_array.assert_called_with( - array_name=module_args["name"], - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - ) - api_obj.create_array.assert_called_once_with( - purefusion.ArrayPost( - hardware_type=module_args["hardware_type"], - display_name=module_args["display_name"], - host_name=module_args["host_name"], - name=module_args["name"], - appliance_id=module_args["appliance_id"], - apartment_id=module_args["apartment_id"], - ), - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - ) - api_obj.update_array.assert_called_once() - api_obj.delete_array.assert_not_called() - op_obj.get_operation.assert_called_once_with(1) - - -@patch("fusion.OperationsApi") -@patch("fusion.ArraysApi") -def test_array_create_op_fails(m_array_api, m_op_api, module_args): - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_array = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_array = MagicMock(return_value=OperationMock(1)) - api_obj.update_array = MagicMock(return_value=OperationMock(2)) - api_obj.delete_array = MagicMock(return_value=OperationMock(3)) - m_array_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(OperationException): - fusion_array.main() - - # check api was called correctly - api_obj.get_array.assert_called_once_with( - array_name=module_args["name"], - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - ) - api_obj.create_array.assert_called_once_with( - purefusion.ArrayPost( - hardware_type=module_args["hardware_type"], - display_name=module_args["display_name"], - host_name=module_args["host_name"], - name=module_args["name"], - appliance_id=module_args["appliance_id"], - apartment_id=module_args["apartment_id"], - ), - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - ) - api_obj.update_array.assert_not_called() - api_obj.delete_array.assert_not_called() - op_obj.get_operation.assert_called_once_with(1) - - -@patch("fusion.OperationsApi") -@patch("fusion.ArraysApi") -def test_array_create_second_op_fails(m_array_api, m_op_api, module_args): - created_array = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], - "display_name": module_args["name"], - "region": module_args["region"], - "availability_zone": module_args["availability_zone"], - "appliance_id": module_args["appliance_id"], - "apartment_id": module_args["apartment_id"], - "host_name": module_args["host_name"], - "hardware_type": module_args["hardware_type"], - "maintenance_mode": not module_args["maintenance_mode"], - "unavailable_mode": not module_args["unavailable_mode"], - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_array = MagicMock( - side_effect=[purefusion.rest.ApiException, purefusion.Array(**created_array)] - ) - api_obj.create_array = MagicMock(return_value=OperationMock(1)) - api_obj.update_array = MagicMock(return_value=OperationMock(2)) - api_obj.delete_array = MagicMock(return_value=OperationMock(3)) - m_array_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock( - side_effect=[SuccessfulOperationMock, FailedOperationMock] - ) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(OperationException): - fusion_array.main() - - # check api was called correctly - api_obj.get_array.assert_called_with( - array_name=module_args["name"], - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - ) - api_obj.create_array.assert_called_once_with( - purefusion.ArrayPost( - hardware_type=module_args["hardware_type"], - display_name=module_args["display_name"], - host_name=module_args["host_name"], - name=module_args["name"], - appliance_id=module_args["appliance_id"], - apartment_id=module_args["apartment_id"], - ), - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - ) - api_obj.update_array.assert_called_once() - api_obj.delete_array.assert_not_called() - op_obj.get_operation.assert_has_calls( - [ - call(1), - call(2), - ] - ) - - -@patch("fusion.OperationsApi") -@patch("fusion.ArraysApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, OperationException), - ], -) -def test_array_create_op_exception( - m_array_api, m_op_api, exec_original, exec_catch, module_args -): - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_array = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_array = MagicMock(return_value=OperationMock(1)) - api_obj.update_array = MagicMock(return_value=OperationMock(2)) - api_obj.delete_array = MagicMock(return_value=OperationMock(3)) - m_array_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(side_effect=exec_original) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_array.main() - - # check api was called correctly - api_obj.get_array.assert_called_once_with( - array_name=module_args["name"], - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - ) - api_obj.create_array.assert_called_once_with( - purefusion.ArrayPost( - hardware_type=module_args["hardware_type"], - display_name=module_args["display_name"], - host_name=module_args["host_name"], - name=module_args["name"], - appliance_id=module_args["appliance_id"], - apartment_id=module_args["apartment_id"], - ), - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - ) - api_obj.update_array.assert_not_called() - api_obj.delete_array.assert_not_called() - op_obj.get_operation.assert_called_once_with(1) - - -@patch("fusion.OperationsApi") -@patch("fusion.ArraysApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, OperationException), - ], -) -def test_array_create_second_op_exception( - m_array_api, m_op_api, exec_original, exec_catch, module_args -): - created_array = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], - "display_name": module_args["name"], - "region": module_args["region"], - "availability_zone": module_args["availability_zone"], - "appliance_id": module_args["appliance_id"], - "apartment_id": module_args["apartment_id"], - "host_name": module_args["host_name"], - "hardware_type": module_args["hardware_type"], - "maintenance_mode": not module_args["maintenance_mode"], - "unavailable_mode": not module_args["unavailable_mode"], - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_array = MagicMock( - side_effect=[purefusion.rest.ApiException, purefusion.Array(**created_array)] - ) - api_obj.create_array = MagicMock(return_value=OperationMock(1)) - api_obj.update_array = MagicMock(return_value=OperationMock(2)) - api_obj.delete_array = MagicMock(return_value=OperationMock(3)) - m_array_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock( - side_effect=[SuccessfulOperationMock, exec_original] - ) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_array.main() - - # check api was called correctly - api_obj.get_array.assert_called_with( - array_name=module_args["name"], - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - ) - api_obj.create_array.assert_called_once_with( - purefusion.ArrayPost( - hardware_type=module_args["hardware_type"], - display_name=module_args["display_name"], - host_name=module_args["host_name"], - name=module_args["name"], - appliance_id=module_args["appliance_id"], - apartment_id=module_args["apartment_id"], - ), - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - ) - api_obj.update_array.assert_called_once() - api_obj.delete_array.assert_not_called() - op_obj.get_operation.assert_has_calls( - [ - call(1), - call(2), - ] - ) - - -@patch("fusion.OperationsApi") -@patch("fusion.ArraysApi") -def test_array_update(m_array_api, m_op_api, module_args, current_array): - current_array["display_name"] = None - current_array["host_name"] = "something" - current_array["maintenance_mode"] = not current_array["maintenance_mode"] - current_array["unavailable_mode"] = not current_array["unavailable_mode"] - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_array = MagicMock(return_value=purefusion.Array(**current_array)) - api_obj.create_array = MagicMock(return_value=OperationMock(1)) - api_obj.update_array = MagicMock(return_value=OperationMock(2)) - api_obj.delete_array = MagicMock(return_value=OperationMock(3)) - m_array_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_array.main() - - assert exc.value.changed - assert exc.value.id == current_array["id"] - - # check api was called correctly - api_obj.get_array.assert_called_with( - array_name=module_args["name"], - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - ) - api_obj.create_array.assert_not_called() - api_obj.update_array.assert_has_calls( - [ - call( - purefusion.ArrayPatch( - display_name=purefusion.NullableString(module_args["display_name"]) - ), - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - array_name=module_args["name"], - ), - call( - purefusion.ArrayPatch( - host_name=purefusion.NullableString(module_args["host_name"]) - ), - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - array_name=module_args["name"], - ), - call( - purefusion.ArrayPatch( - unavailable_mode=purefusion.NullableBoolean( - module_args["unavailable_mode"] - ) - ), - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - array_name=module_args["name"], - ), - call( - purefusion.ArrayPatch( - maintenance_mode=purefusion.NullableBoolean( - module_args["maintenance_mode"] - ) - ), - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - array_name=module_args["name"], - ), - ], - any_order=True, - ) - api_obj.delete_array.assert_not_called() - op_obj.get_operation.assert_has_calls( - [ - call(2), - call(2), - call(2), - call(2), - ] - ) - - -@patch("fusion.OperationsApi") -@patch("fusion.ArraysApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, HTTPError), - ], -) -def test_array_update_exception( - m_array_api, m_op_api, exec_original, exec_catch, module_args, current_array -): - current_array["display_name"] = None - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_array = MagicMock(return_value=purefusion.Array(**current_array)) - api_obj.create_array = MagicMock(return_value=OperationMock(1)) - api_obj.update_array = MagicMock(side_effect=exec_original) - api_obj.delete_array = MagicMock(return_value=OperationMock(3)) - m_array_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_array.main() - - # check api was called correctly - api_obj.get_array.assert_called_with( - array_name=module_args["name"], - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - ) - api_obj.create_array.assert_not_called() - api_obj.update_array.assert_called_once() - api_obj.delete_array.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.ArraysApi") -def test_array_update_op_fails(m_array_api, m_op_api, module_args, current_array): - current_array["display_name"] = None - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_array = MagicMock(return_value=purefusion.Array(**current_array)) - api_obj.create_array = MagicMock(return_value=OperationMock(1)) - api_obj.update_array = MagicMock(return_value=OperationMock(2)) - api_obj.delete_array = MagicMock(return_value=OperationMock(3)) - m_array_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(OperationException): - fusion_array.main() - - # check api was called correctly - api_obj.get_array.assert_called_with( - array_name=module_args["name"], - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - ) - api_obj.create_array.assert_not_called() - api_obj.update_array.assert_called_once() - api_obj.delete_array.assert_not_called() - op_obj.get_operation.assert_called_once_with(2) - - -@patch("fusion.OperationsApi") -@patch("fusion.ArraysApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, OperationException), - ], -) -def test_array_update_op_exception( - m_array_api, m_op_api, exec_original, exec_catch, module_args, current_array -): - current_array["display_name"] = None - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_array = MagicMock(return_value=purefusion.Array(**current_array)) - api_obj.create_array = MagicMock(return_value=OperationMock(1)) - api_obj.update_array = MagicMock(return_value=OperationMock(2)) - api_obj.delete_array = MagicMock(return_value=OperationMock(3)) - m_array_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(side_effect=exec_original) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_array.main() - - # check api was called correctly - api_obj.get_array.assert_called_with( - array_name=module_args["name"], - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - ) - api_obj.create_array.assert_not_called() - api_obj.update_array.assert_called_once() - api_obj.delete_array.assert_not_called() - op_obj.get_operation.assert_called_once_with(2) - - -@patch("fusion.OperationsApi") -@patch("fusion.ArraysApi") -def test_array_present_not_changed(m_array_api, m_op_api, module_args, current_array): - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_array = MagicMock(return_value=purefusion.Array(**current_array)) - api_obj.create_array = MagicMock(return_value=OperationMock(1)) - api_obj.update_array = MagicMock(return_value=OperationMock(2)) - api_obj.delete_array = MagicMock(return_value=OperationMock(3)) - m_array_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_array.main() - - assert not exc.value.changed - - # check api was called correctly - api_obj.get_array.assert_called_with( - array_name=module_args["name"], - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - ) - api_obj.create_array.assert_not_called() - api_obj.update_array.assert_not_called() - api_obj.delete_array.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.ArraysApi") -def test_array_absent_not_changed(m_array_api, m_op_api, module_args): - module_args["state"] = "absent" - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_array = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_array = MagicMock(return_value=OperationMock(1)) - api_obj.update_array = MagicMock(return_value=OperationMock(2)) - api_obj.delete_array = MagicMock(return_value=OperationMock(3)) - m_array_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_array.main() - - assert not exc.value.changed - - # check api was called correctly - api_obj.get_array.assert_called_with( - array_name=module_args["name"], - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - ) - api_obj.create_array.assert_not_called() - api_obj.update_array.assert_not_called() - api_obj.delete_array.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.ArraysApi") -def test_array_delete(m_array_api, m_op_api, module_args, current_array): - module_args["state"] = "absent" - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_array = MagicMock(return_value=purefusion.Array(**current_array)) - api_obj.create_array = MagicMock(return_value=OperationMock(1)) - api_obj.update_array = MagicMock(return_value=OperationMock(2)) - api_obj.delete_array = MagicMock(return_value=OperationMock(3)) - m_array_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_array.main() - - assert exc.value.changed - - # check api was called correctly - api_obj.get_array.assert_called_once_with( - array_name=module_args["name"], - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - ) - api_obj.create_array.assert_not_called() - api_obj.update_array.assert_not_called() - api_obj.delete_array.assert_called_once_with( - region_name=module_args["region"], - availability_zone_name=module_args["availability_zone"], - array_name=module_args["name"], - ) - op_obj.get_operation.assert_called_once_with(3) - - -@patch("fusion.OperationsApi") -@patch("fusion.ArraysApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, HTTPError), - ], -) -def test_array_delete_exception( - m_array_api, m_op_api, exec_original, exec_catch, module_args, current_array -): - module_args["state"] = "absent" - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_array = MagicMock(return_value=purefusion.Array(**current_array)) - api_obj.create_array = MagicMock(return_value=OperationMock(1)) - api_obj.update_array = MagicMock(return_value=OperationMock(2)) - api_obj.delete_array = MagicMock(side_effect=exec_original) - m_array_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_array.main() - - # check api was called correctly - api_obj.get_array.assert_called_once_with( - array_name=module_args["name"], - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - ) - api_obj.create_array.assert_not_called() - api_obj.update_array.assert_not_called() - api_obj.delete_array.assert_called_once_with( - region_name=module_args["region"], - availability_zone_name=module_args["availability_zone"], - array_name=module_args["name"], - ) - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.ArraysApi") -def test_array_delete_op_fails(m_array_api, m_op_api, module_args, current_array): - module_args["state"] = "absent" - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_array = MagicMock(return_value=purefusion.Array(**current_array)) - api_obj.create_array = MagicMock(return_value=OperationMock(1)) - api_obj.update_array = MagicMock(return_value=OperationMock(2)) - api_obj.delete_array = MagicMock(return_value=OperationMock(3)) - m_array_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(OperationException): - fusion_array.main() - - # check api was called correctly - api_obj.get_array.assert_called_once_with( - array_name=module_args["name"], - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - ) - api_obj.create_array.assert_not_called() - api_obj.update_array.assert_not_called() - api_obj.delete_array.assert_called_once_with( - region_name=module_args["region"], - availability_zone_name=module_args["availability_zone"], - array_name=module_args["name"], - ) - op_obj.get_operation.assert_called_once_with(3) - - -@patch("fusion.OperationsApi") -@patch("fusion.ArraysApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, OperationException), - ], -) -def test_array_delete_op_exception( - m_array_api, m_op_api, exec_original, exec_catch, module_args, current_array -): - module_args["state"] = "absent" - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_array = MagicMock(return_value=purefusion.Array(**current_array)) - api_obj.create_array = MagicMock(return_value=OperationMock(1)) - api_obj.update_array = MagicMock(return_value=OperationMock(2)) - api_obj.delete_array = MagicMock(return_value=OperationMock(3)) - m_array_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(side_effect=exec_original) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_array.main() - - # check api was called correctly - api_obj.get_array.assert_called_once_with( - array_name=module_args["name"], - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - ) - api_obj.create_array.assert_not_called() - api_obj.update_array.assert_not_called() - api_obj.delete_array.assert_called_once_with( - region_name=module_args["region"], - availability_zone_name=module_args["availability_zone"], - array_name=module_args["name"], - ) - op_obj.get_operation.assert_called_once_with(3) diff --git a/ansible_collections/purestorage/fusion/tests/functional/test_fusion_az.py b/ansible_collections/purestorage/fusion/tests/functional/test_fusion_az.py deleted file mode 100644 index d19e41827..000000000 --- a/ansible_collections/purestorage/fusion/tests/functional/test_fusion_az.py +++ /dev/null @@ -1,720 +0,0 @@ -# -*- coding: utf-8 -*- - -# (c) 2023, Andrej Pajtas (apajtas@purestorage.com) -# GNU General Public License v3.0+ (see COPYING.GPLv3 or https://www.gnu.org/licenses/gpl-3.0.txt) - -from __future__ import absolute_import, division, print_function - -__metaclass__ = type - -from unittest.mock import MagicMock, patch - -import fusion as purefusion -import pytest -from ansible.module_utils import basic -from ansible_collections.purestorage.fusion.plugins.module_utils.errors import ( - OperationException, -) -from ansible_collections.purestorage.fusion.plugins.modules import fusion_az -from ansible_collections.purestorage.fusion.tests.functional.utils import ( - AnsibleExitJson, - AnsibleFailJson, - FailedOperationMock, - OperationMock, - SuccessfulOperationMock, - FAKE_RESOURCE_ID, - exit_json, - fail_json, - set_module_args, -) -from urllib3.exceptions import HTTPError - -# GLOBAL MOCKS -fusion_az.setup_fusion = MagicMock(return_value=purefusion.api_client.ApiClient()) -purefusion.api_client.ApiClient.call_api = MagicMock( - side_effect=Exception("API call not mocked!") -) -basic.AnsibleModule.exit_json = exit_json -basic.AnsibleModule.fail_json = fail_json - - -@patch("fusion.OperationsApi") -@patch("fusion.AvailabilityZonesApi") -@pytest.mark.parametrize( - "module_args", - [ - # required parameter 'name` is missing - { - "state": "present", - "region": "region1", - "display_name": "Availability Zone 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - # required parameter 'region` is missing - { - "state": "present", - "name": "az1", - "display_name": "Availability Zone 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - # unknown parameter 'extra' is provided - { - "state": "present", - "name": "az1", - "region": "region1", - "display_name": "Availability Zone 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - "extra": "value", - }, - # parameter 'state` has incorrect value - { - "state": "cool", - "name": "az1", - "region": "region1", - "display_name": "Availability Zone 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - ], -) -def test_module_op_fails_on_wrong_parameters(m_az_api, m_op_api, module_args): - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_availability_zone = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_availability_zone = MagicMock(return_value=OperationMock(1)) - api_obj.update_availability_zone = MagicMock(return_value=OperationMock(2)) - api_obj.delete_availability_zone = MagicMock(return_value=OperationMock(3)) - m_az_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - # run module - with pytest.raises(AnsibleFailJson): - fusion_az.main() - - # check api was not called at all - api_obj.get_region.assert_not_called() - api_obj.create_availability_zone.assert_not_called() - api_obj.update_availability_zone.assert_not_called() - api_obj.delete_availability_zone.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.AvailabilityZonesApi") -def test_az_create(m_az_api, m_op_api): - module_args = { - "state": "present", - "name": "az1", - "region": "region1", - "display_name": "Availability Zone 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_availability_zone = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_availability_zone = MagicMock(return_value=OperationMock(1)) - api_obj.update_availability_zone = MagicMock(return_value=OperationMock(2)) - api_obj.delete_availability_zone = MagicMock(return_value=OperationMock(3)) - m_az_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_az.main() - - assert exc.value.changed - assert exc.value.id == FAKE_RESOURCE_ID - - api_obj.get_region.get_availability_zone( - availability_zone_name=module_args["name"], - region_name=module_args["region"], - ) - api_obj.create_availability_zone.assert_called_once_with( - purefusion.AvailabilityZonePost( - name=module_args["name"], - display_name=module_args["display_name"], - ), - region_name=module_args["region"], - ) - api_obj.update_availability_zone.assert_not_called() - api_obj.delete_availability_zone.assert_not_called() - op_obj.get_operation.assert_called_once_with(1) - - -@patch("fusion.OperationsApi") -@patch("fusion.AvailabilityZonesApi") -def test_az_create_without_display_name(m_az_api, m_op_api): - module_args = { - "state": "present", - "name": "az1", - "region": "region1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_availability_zone = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_availability_zone = MagicMock(return_value=OperationMock(1)) - api_obj.update_availability_zone = MagicMock(return_value=OperationMock(2)) - api_obj.delete_availability_zone = MagicMock(return_value=OperationMock(3)) - m_az_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_az.main() - - assert exc.value.changed - assert exc.value.id == FAKE_RESOURCE_ID - - api_obj.get_region.get_availability_zone( - availability_zone_name=module_args["name"], - region_name=module_args["region"], - ) - api_obj.create_availability_zone.assert_called_once_with( - purefusion.AvailabilityZonePost( - name=module_args["name"], - display_name=module_args["name"], - ), - region_name=module_args["region"], - ) - api_obj.update_availability_zone.assert_not_called() - api_obj.delete_availability_zone.assert_not_called() - op_obj.get_operation.assert_called_once_with(1) - - -@patch("fusion.OperationsApi") -@patch("fusion.AvailabilityZonesApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, HTTPError), - ], -) -def test_az_create_exception(m_az_api, m_op_api, exec_original, exec_catch): - module_args = { - "state": "present", - "name": "az1", - "region": "region1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_availability_zone = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_availability_zone = MagicMock(side_effect=exec_original) - api_obj.update_availability_zone = MagicMock(return_value=OperationMock(2)) - api_obj.delete_availability_zone = MagicMock(return_value=OperationMock(3)) - m_az_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_az.main() - - api_obj.get_region.get_availability_zone( - availability_zone_name=module_args["name"], - region_name=module_args["region"], - ) - api_obj.create_availability_zone.assert_called_once_with( - purefusion.AvailabilityZonePost( - name=module_args["name"], - display_name=module_args["name"], - ), - region_name=module_args["region"], - ) - api_obj.update_availability_zone.assert_not_called() - api_obj.delete_availability_zone.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.AvailabilityZonesApi") -def test_az_create_op_fails(m_az_api, m_op_api): - module_args = { - "state": "present", - "name": "az1", - "region": "region1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_availability_zone = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_availability_zone = MagicMock(return_value=OperationMock(1)) - api_obj.update_availability_zone = MagicMock(return_value=OperationMock(2)) - api_obj.delete_availability_zone = MagicMock(return_value=OperationMock(3)) - m_az_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(OperationException): - fusion_az.main() - - api_obj.get_region.get_availability_zone( - availability_zone_name=module_args["name"], - region_name=module_args["region"], - ) - api_obj.create_availability_zone.assert_called_once_with( - purefusion.AvailabilityZonePost( - name=module_args["name"], - display_name=module_args["name"], - ), - region_name=module_args["region"], - ) - api_obj.update_availability_zone.assert_not_called() - api_obj.delete_availability_zone.assert_not_called() - op_obj.get_operation.assert_called_once_with(1) - - -@patch("fusion.OperationsApi") -@patch("fusion.AvailabilityZonesApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, OperationException), - ], -) -def test_az_create_op_exception(m_az_api, m_op_api, exec_original, exec_catch): - module_args = { - "state": "present", - "name": "az1", - "region": "region1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_availability_zone = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_availability_zone = MagicMock(return_value=OperationMock(1)) - api_obj.update_availability_zone = MagicMock(return_value=OperationMock(2)) - api_obj.delete_availability_zone = MagicMock(return_value=OperationMock(3)) - m_az_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(side_effect=exec_original) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_az.main() - - api_obj.get_region.get_availability_zone( - availability_zone_name=module_args["name"], - region_name=module_args["region"], - ) - api_obj.create_availability_zone.assert_called_once_with( - purefusion.AvailabilityZonePost( - name=module_args["name"], - display_name=module_args["name"], - ), - region_name=module_args["region"], - ) - api_obj.update_availability_zone.assert_not_called() - api_obj.delete_availability_zone.assert_not_called() - op_obj.get_operation.assert_called_once_with(1) - - -@patch("fusion.OperationsApi") -@patch("fusion.AvailabilityZonesApi") -def test_az_update(m_az_api, m_op_api): - # NOTE: Availability Zone does not have PATCH method, thus no action is expected - module_args = { - "state": "present", - "name": "az1", - "region": "region1", - "display_name": "Availability Zone 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - current_az = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], # name must match - "region": module_args["region"], # region must match - "display_name": None, - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_availability_zone = MagicMock( - return_value=purefusion.AvailabilityZone(**current_az) - ) - api_obj.create_availability_zone = MagicMock(return_value=OperationMock(1)) - api_obj.update_availability_zone = MagicMock(return_value=OperationMock(2)) - api_obj.delete_availability_zone = MagicMock(return_value=OperationMock(3)) - m_az_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_az.main() - - assert not exc.value.changed - - api_obj.get_region.get_availability_zone( - availability_zone_name=module_args["name"], - region_name=module_args["region"], - ) - api_obj.create_availability_zone.assert_not_called() - api_obj.update_availability_zone.assert_not_called() - api_obj.delete_availability_zone.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.AvailabilityZonesApi") -def test_az_present_not_changed(m_az_api, m_op_api): - module_args = { - "state": "present", - "name": "az1", - "region": "region1", - "display_name": "Availability Zone 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - current_az = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], # name must match - "region": module_args["region"], # region must match - "display_name": module_args["display_name"], - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_availability_zone = MagicMock( - return_value=purefusion.AvailabilityZone(**current_az) - ) - api_obj.create_availability_zone = MagicMock(return_value=OperationMock(1)) - api_obj.update_availability_zone = MagicMock(return_value=OperationMock(2)) - api_obj.delete_availability_zone = MagicMock(return_value=OperationMock(3)) - m_az_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_az.main() - - assert not exc.value.changed - - api_obj.get_region.get_availability_zone( - availability_zone_name=module_args["name"], - region_name=module_args["region"], - ) - api_obj.create_availability_zone.assert_not_called() - api_obj.update_availability_zone.assert_not_called() - api_obj.delete_availability_zone.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.AvailabilityZonesApi") -def test_az_absent_not_changed(m_az_api, m_op_api): - module_args = { - "state": "absent", - "name": "az1", - "region": "region1", - "display_name": "Availability Zone 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_availability_zone = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_availability_zone = MagicMock(return_value=OperationMock(1)) - api_obj.update_availability_zone = MagicMock(return_value=OperationMock(2)) - api_obj.delete_availability_zone = MagicMock(return_value=OperationMock(3)) - m_az_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_az.main() - - assert not exc.value.changed - - api_obj.get_region.get_availability_zone( - availability_zone_name=module_args["name"], - region_name=module_args["region"], - ) - api_obj.create_availability_zone.assert_not_called() - api_obj.update_availability_zone.assert_not_called() - api_obj.delete_availability_zone.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.AvailabilityZonesApi") -def test_az_delete(m_az_api, m_op_api): - module_args = { - "state": "absent", - "name": "az1", - "region": "region1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - current_az = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], # name must match - "region": module_args["region"], # region must match - "display_name": None, - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_availability_zone = MagicMock( - return_value=purefusion.AvailabilityZone(**current_az) - ) - api_obj.create_availability_zone = MagicMock(return_value=OperationMock(1)) - api_obj.update_availability_zone = MagicMock(return_value=OperationMock(2)) - api_obj.delete_availability_zone = MagicMock(return_value=OperationMock(3)) - m_az_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_az.main() - - assert exc.value.changed - - api_obj.get_region.get_availability_zone( - availability_zone_name=module_args["name"], - region_name=module_args["region"], - ) - api_obj.create_availability_zone.assert_not_called() - api_obj.update_availability_zone.assert_not_called() - api_obj.delete_availability_zone.assert_called_once_with( - availability_zone_name=module_args["name"], - region_name=module_args["region"], - ) - op_obj.get_operation.assert_called_once_with(3) - - -@patch("fusion.OperationsApi") -@patch("fusion.AvailabilityZonesApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, HTTPError), - ], -) -def test_az_delete_exception(m_az_api, m_op_api, exec_original, exec_catch): - module_args = { - "state": "absent", - "name": "az1", - "region": "region1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - current_az = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], # name must match - "region": module_args["region"], # region must match - "display_name": None, - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_availability_zone = MagicMock( - return_value=purefusion.AvailabilityZone(**current_az) - ) - api_obj.create_availability_zone = MagicMock(return_value=OperationMock(1)) - api_obj.update_availability_zone = MagicMock(return_value=OperationMock(2)) - api_obj.delete_availability_zone = MagicMock(side_effect=exec_original) - m_az_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_az.main() - - api_obj.get_region.get_availability_zone( - availability_zone_name=module_args["name"], - region_name=module_args["region"], - ) - api_obj.create_availability_zone.assert_not_called() - api_obj.update_availability_zone.assert_not_called() - api_obj.delete_availability_zone.assert_called_once_with( - availability_zone_name=module_args["name"], - region_name=module_args["region"], - ) - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.AvailabilityZonesApi") -def test_az_delete_op_fails(m_az_api, m_op_api): - module_args = { - "state": "absent", - "name": "az1", - "region": "region1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - current_az = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], # name must match - "region": module_args["region"], # region must match - "display_name": None, - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_availability_zone = MagicMock( - return_value=purefusion.AvailabilityZone(**current_az) - ) - api_obj.create_availability_zone = MagicMock(return_value=OperationMock(1)) - api_obj.update_availability_zone = MagicMock(return_value=OperationMock(2)) - api_obj.delete_availability_zone = MagicMock(return_value=OperationMock(3)) - m_az_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(OperationException): - fusion_az.main() - - api_obj.get_region.get_availability_zone( - availability_zone_name=module_args["name"], - region_name=module_args["region"], - ) - api_obj.create_availability_zone.assert_not_called() - api_obj.update_availability_zone.assert_not_called() - api_obj.delete_availability_zone.assert_called_once_with( - availability_zone_name=module_args["name"], - region_name=module_args["region"], - ) - op_obj.get_operation.assert_called_once_with(3) - - -@patch("fusion.OperationsApi") -@patch("fusion.AvailabilityZonesApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, OperationException), - ], -) -def test_az_delete_op_exception(m_az_api, m_op_api, exec_original, exec_catch): - module_args = { - "state": "absent", - "name": "az1", - "region": "region1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - current_az = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], # name must match - "region": module_args["region"], # region must match - "display_name": None, - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_availability_zone = MagicMock( - return_value=purefusion.AvailabilityZone(**current_az) - ) - api_obj.create_availability_zone = MagicMock(return_value=OperationMock(1)) - api_obj.update_availability_zone = MagicMock(return_value=OperationMock(2)) - api_obj.delete_availability_zone = MagicMock(return_value=OperationMock(3)) - m_az_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(side_effect=exec_original) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_az.main() - - api_obj.get_region.get_availability_zone( - availability_zone_name=module_args["name"], - region_name=module_args["region"], - ) - api_obj.create_availability_zone.assert_not_called() - api_obj.update_availability_zone.assert_not_called() - api_obj.delete_availability_zone.assert_called_once_with( - availability_zone_name=module_args["name"], - region_name=module_args["region"], - ) - op_obj.get_operation.assert_called_once_with(3) diff --git a/ansible_collections/purestorage/fusion/tests/functional/test_fusion_hap.py b/ansible_collections/purestorage/fusion/tests/functional/test_fusion_hap.py deleted file mode 100644 index 258ca2034..000000000 --- a/ansible_collections/purestorage/fusion/tests/functional/test_fusion_hap.py +++ /dev/null @@ -1,892 +0,0 @@ -# -*- coding: utf-8 -*- - -# (c) 2023, Andrej Pajtas (apajtas@purestorage.com) -# GNU General Public License v3.0+ (see COPYING.GPLv3 or https://www.gnu.org/licenses/gpl-3.0.txt) - -from __future__ import absolute_import, division, print_function - -__metaclass__ = type - -from unittest.mock import MagicMock, patch - -import fusion -import fusion as purefusion -import pytest -from ansible.module_utils import basic -from ansible_collections.purestorage.fusion.plugins.module_utils.errors import ( - OperationException, -) -from ansible_collections.purestorage.fusion.plugins.modules import fusion_hap -from ansible_collections.purestorage.fusion.tests.functional.utils import ( - AnsibleExitJson, - AnsibleFailJson, - FailedOperationMock, - OperationMock, - SuccessfulOperationMock, - FAKE_RESOURCE_ID, - exit_json, - fail_json, - set_module_args, -) -from urllib3.exceptions import HTTPError - -# GLOBAL MOCKS -fusion_hap.setup_fusion = MagicMock(return_value=purefusion.api_client.ApiClient()) -purefusion.api_client.ApiClient.call_api = MagicMock( - side_effect=Exception("API call not mocked!") -) -basic.AnsibleModule.exit_json = exit_json -basic.AnsibleModule.fail_json = fail_json - - -@pytest.fixture -def module_args(): - """Module arguments to create new HAP.""" - return { - "state": "present", - "name": "hap_new", - "display_name": "Host Access Policy New", - "iqn": "iqn.2023-05.com.purestorage:420qp2c0699", - "personality": "aix", - "app_id": "ABCD1234", - "key_file": "private-key.pem", - } - - -@pytest.fixture -def current_hap_list(): - return fusion.HostAccessPolicyList( - count=3, - more_items_remaining=False, - items=[ - fusion.HostAccessPolicy( - id="1", - self_link="self_link_value", - name="hap1", - display_name="Host Access Policy 1", - iqn="iqn.2023-05.com.purestorage:420qp2c0261", - personality="aix", - ), - fusion.HostAccessPolicy( - id="2", - self_link="self_link_value", - name="hap2", - display_name="Host Access Policy 2", - iqn="iqn.2023-05.com.purestorage:420qp2c0262", - personality="windows", - ), - fusion.HostAccessPolicy( - id="3", - self_link="self_link_value", - name="hap3", - display_name="Host Access Policy 3", - iqn="iqn.2023-05.com.purestorage:420qp2c0263", - personality="solaris", - ), - ], - ) - - -@patch("fusion.OperationsApi") -@patch("fusion.HostAccessPoliciesApi") -@pytest.mark.parametrize( - "module_args", - [ - # required parameter 'name` is missing - { - "state": "present", - "display_name": "Host Access Policy 1", - "iqn": "iqn.2023-05.com.purestorage:420qp2c0261", - "personality": "aix", - "app_id": "ABCD1234", - "key_file": "private-key.pem", - }, - # 'state' is 'present' but 'iqn' is not provided - { - "state": "present", - "name": "hap1", - "display_name": "Host Access Policy 1", - "personality": "aix", - "app_id": "ABCD1234", - "key_file": "private-key.pem", - }, - # unknown parameter 'extra' is provided - { - "state": "present", - "name": "hap1", - "display_name": "Host Access Policy 1", - "iqn": "iqn.2023-05.com.purestorage:420qp2c0261", - "personality": "aix", - "app_id": "ABCD1234", - "key_file": "private-key.pem", - "extra": "value", - }, - # parameter 'state` has incorrect value - { - "state": "cool", - "name": "hap1", - "display_name": "Host Access Policy 1", - "iqn": "iqn.2023-05.com.purestorage:420qp2c0261", - "personality": "aix", - "app_id": "ABCD1234", - "key_file": "private-key.pem", - }, - # parameter 'personality` has incorrect value - { - "state": "present", - "name": "hap1", - "display_name": "Host Access Policy 1", - "iqn": "iqn.2023-05.com.purestorage:420qp2c0261", - "personality": "cool", - "app_id": "ABCD1234", - "key_file": "private-key.pem", - }, - ], -) -def test_module_fails_on_wrong_parameters( - m_hap_api, m_op_api, module_args, current_hap_list -): - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.list_host_access_policies = MagicMock(return_value=current_hap_list) - api_obj.get_host_access_policy = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_host_access_policy = MagicMock(return_value=OperationMock(1)) - api_obj.update_host_access_policy = MagicMock(return_value=OperationMock(2)) - api_obj.delete_host_access_policy = MagicMock(return_value=OperationMock(3)) - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - m_hap_api.return_value = api_obj - - # run module - with pytest.raises(AnsibleFailJson): - fusion_hap.main() - - # check api was not called at all - api_obj.list_host_access_policies.assert_not_called() - api_obj.get_host_access_policy.assert_not_called() - api_obj.create_host_access_policy.assert_not_called() - api_obj.update_host_access_policy.assert_not_called() - api_obj.delete_host_access_policy.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.HostAccessPoliciesApi") -@pytest.mark.parametrize( - "name", - [ - "", - "space space", - "toolongname_toolongname_toolongname_toolongname_toolongname_toolongname", - "end_with_underscore_", - "_start_with_underscore", - ], -) -def test_hap_fail_on_invalid_name( - m_hap_api, m_op_api, module_args, current_hap_list, name -): - module_args["name"] = name - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.list_host_access_policies = MagicMock( - side_effect=purefusion.rest.ApiException - ) - api_obj.get_host_access_policy = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_host_access_policy = MagicMock(return_value=OperationMock(1)) - api_obj.update_host_access_policy = MagicMock(return_value=OperationMock(2)) - api_obj.delete_host_access_policy = MagicMock(return_value=OperationMock(3)) - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - m_hap_api.return_value = api_obj - - # run module - with pytest.raises(AnsibleFailJson): - fusion_hap.main() - - # check api was not called at all - api_obj.list_host_access_policies.assert_not_called() - api_obj.get_host_access_policy.assert_not_called() - api_obj.create_host_access_policy.assert_not_called() - api_obj.update_host_access_policy.assert_not_called() - api_obj.delete_host_access_policy.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.HostAccessPoliciesApi") -@pytest.mark.parametrize( - "iqn", - [ - "qn.2023-05.com.purestorage:420qp2c0261", - "iqn2023-05.com.purestorage:420qp2c0261", - "iqn.202305.com.purestorage:420qp2c0261", - "iqn.2023-05com.purestorage:420qp2c0261", - "iqn.2023-05.com.purestorage:", - "iqn.2023-05..purestorage:420qp2c0261", - ".2023-05.com.purestorage:420qp2c0261", - "2023-05.com.purestorage:420qp2c0261", - ], -) -def test_hap_fail_on_invalid_iqn( - m_hap_api, m_op_api, module_args, current_hap_list, iqn -): - module_args["iqn"] = iqn - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.list_host_access_policies = MagicMock( - side_effect=purefusion.rest.ApiException - ) - api_obj.get_host_access_policy = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_host_access_policy = MagicMock(return_value=OperationMock(1)) - api_obj.update_host_access_policy = MagicMock(return_value=OperationMock(2)) - api_obj.delete_host_access_policy = MagicMock(return_value=OperationMock(3)) - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - m_hap_api.return_value = api_obj - - # run module - with pytest.raises(AnsibleFailJson): - fusion_hap.main() - - # check api was not called at all - api_obj.list_host_access_policies.assert_not_called() - api_obj.get_host_access_policy.assert_not_called() - api_obj.create_host_access_policy.assert_not_called() - api_obj.update_host_access_policy.assert_not_called() - api_obj.delete_host_access_policy.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.HostAccessPoliciesApi") -def test_hap_create(m_hap_api, m_op_api, module_args, current_hap_list): - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.list_host_access_policies = MagicMock(return_value=current_hap_list) - api_obj.get_host_access_policy = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_host_access_policy = MagicMock(return_value=OperationMock(1)) - api_obj.update_host_access_policy = MagicMock(return_value=OperationMock(2)) - api_obj.delete_host_access_policy = MagicMock(return_value=OperationMock(3)) - m_hap_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_hap.main() - - assert exc.value.changed is True - assert exc.value.id == FAKE_RESOURCE_ID - - # check api was called correctly - api_obj.list_host_access_policies.assert_called_once_with() - api_obj.get_host_access_policy.assert_called_once_with( - host_access_policy_name=module_args["name"] - ) - api_obj.create_host_access_policy.assert_called_once_with( - purefusion.HostAccessPoliciesPost( - iqn=module_args["iqn"], - personality=module_args["personality"], - name=module_args["name"], - display_name=module_args["display_name"], - ) - ) - api_obj.update_host_access_policy.assert_not_called() - api_obj.delete_host_access_policy.assert_not_called() - op_obj.get_operation.assert_called_once_with(1) - - -@patch("fusion.OperationsApi") -@patch("fusion.HostAccessPoliciesApi") -def test_hap_create_without_display_name( - m_hap_api, m_op_api, module_args, current_hap_list -): - del module_args["display_name"] - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.list_host_access_policies = MagicMock(return_value=current_hap_list) - api_obj.get_host_access_policy = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_host_access_policy = MagicMock(return_value=OperationMock(1)) - api_obj.update_host_access_policy = MagicMock(return_value=OperationMock(2)) - api_obj.delete_host_access_policy = MagicMock(return_value=OperationMock(3)) - m_hap_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_hap.main() - - assert exc.value.changed is True - assert exc.value.id == FAKE_RESOURCE_ID - - # check api was called correctly - api_obj.list_host_access_policies.assert_called_once_with() - api_obj.get_host_access_policy.assert_called_once_with( - host_access_policy_name=module_args["name"] - ) - api_obj.create_host_access_policy.assert_called_once_with( - purefusion.HostAccessPoliciesPost( - iqn=module_args["iqn"], - personality=module_args["personality"], - name=module_args["name"], - display_name=module_args["name"], - ) - ) - api_obj.update_host_access_policy.assert_not_called() - api_obj.delete_host_access_policy.assert_not_called() - op_obj.get_operation.assert_called_once_with(1) - - -@patch("fusion.OperationsApi") -@patch("fusion.HostAccessPoliciesApi") -def test_hap_create_iqn_exists(m_hap_api, m_op_api, module_args, current_hap_list): - module_args["iqn"] = current_hap_list.items[0].iqn - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.list_host_access_policies = MagicMock(return_value=current_hap_list) - api_obj.get_host_access_policy = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_host_access_policy = MagicMock(return_value=OperationMock(1)) - api_obj.update_host_access_policy = MagicMock(return_value=OperationMock(2)) - api_obj.delete_host_access_policy = MagicMock(return_value=OperationMock(3)) - m_hap_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleFailJson) as exc: - fusion_hap.main() - - # check api was called correctly - api_obj.list_host_access_policies.assert_called_once_with() - api_obj.get_host_access_policy.assert_called_once_with( - host_access_policy_name=module_args["name"] - ) - api_obj.create_host_access_policy.assert_not_called() - api_obj.update_host_access_policy.assert_not_called() - api_obj.delete_host_access_policy.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.HostAccessPoliciesApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, HTTPError), - ], -) -def test_hap_create_exception( - m_hap_api, m_op_api, exec_original, exec_catch, module_args, current_hap_list -): - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.list_host_access_policies = MagicMock(return_value=current_hap_list) - api_obj.get_host_access_policy = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_host_access_policy = MagicMock(side_effect=exec_original) - api_obj.update_host_access_policy = MagicMock(return_value=OperationMock(2)) - api_obj.delete_host_access_policy = MagicMock(return_value=OperationMock(3)) - m_hap_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_hap.main() - - # check api was called correctly - api_obj.list_host_access_policies.assert_called_once_with() - api_obj.get_host_access_policy.assert_called_once_with( - host_access_policy_name=module_args["name"] - ) - api_obj.create_host_access_policy.assert_called_once_with( - purefusion.HostAccessPoliciesPost( - iqn=module_args["iqn"], - personality=module_args["personality"], - name=module_args["name"], - display_name=module_args["display_name"], - ) - ) - api_obj.update_host_access_policy.assert_not_called() - api_obj.delete_host_access_policy.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.HostAccessPoliciesApi") -def test_hap_create_op_fails(m_hap_api, m_op_api, module_args, current_hap_list): - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.list_host_access_policies = MagicMock(return_value=current_hap_list) - api_obj.get_host_access_policy = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_host_access_policy = MagicMock(return_value=OperationMock(1)) - api_obj.update_host_access_policy = MagicMock(return_value=OperationMock(2)) - api_obj.delete_host_access_policy = MagicMock(return_value=OperationMock(3)) - m_hap_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(OperationException): - fusion_hap.main() - - # check api was called correctly - api_obj.list_host_access_policies.assert_called_once_with() - api_obj.get_host_access_policy.assert_called_once_with( - host_access_policy_name=module_args["name"] - ) - api_obj.create_host_access_policy.assert_called_once_with( - purefusion.HostAccessPoliciesPost( - iqn=module_args["iqn"], - personality=module_args["personality"], - name=module_args["name"], - display_name=module_args["display_name"], - ) - ) - api_obj.update_host_access_policy.assert_not_called() - api_obj.delete_host_access_policy.assert_not_called() - op_obj.get_operation.assert_called_once_with(1) - - -@patch("fusion.OperationsApi") -@patch("fusion.HostAccessPoliciesApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, OperationException), - ], -) -def test_hap_create_op_exception( - m_hap_api, m_op_api, exec_original, exec_catch, module_args, current_hap_list -): - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.list_host_access_policies = MagicMock(return_value=current_hap_list) - api_obj.get_host_access_policy = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_host_access_policy = MagicMock(return_value=OperationMock(1)) - api_obj.update_host_access_policy = MagicMock(return_value=OperationMock(2)) - api_obj.delete_host_access_policy = MagicMock(return_value=OperationMock(3)) - m_hap_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(side_effect=exec_original) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_hap.main() - - # check api was called correctly - api_obj.list_host_access_policies.assert_called_once_with() - api_obj.get_host_access_policy.assert_called_once_with( - host_access_policy_name=module_args["name"] - ) - api_obj.create_host_access_policy.assert_called_once_with( - purefusion.HostAccessPoliciesPost( - iqn=module_args["iqn"], - personality=module_args["personality"], - name=module_args["name"], - display_name=module_args["display_name"], - ) - ) - api_obj.update_host_access_policy.assert_not_called() - api_obj.delete_host_access_policy.assert_not_called() - op_obj.get_operation.assert_called_once_with(1) - - -@patch("fusion.OperationsApi") -@patch("fusion.HostAccessPoliciesApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, HTTPError), - ], -) -def test_hap_list_exception( - m_hap_api, m_op_api, exec_original, exec_catch, module_args, current_hap_list -): - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.list_host_access_policies = MagicMock(side_effect=exec_original) - api_obj.get_host_access_policy = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_host_access_policy = MagicMock(side_effect=OperationMock(1)) - api_obj.update_host_access_policy = MagicMock(return_value=OperationMock(2)) - api_obj.delete_host_access_policy = MagicMock(return_value=OperationMock(3)) - m_hap_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_hap.main() - - # check api was called correctly - api_obj.list_host_access_policies.assert_called_once_with() - api_obj.get_host_access_policy.assert_called_once_with( - host_access_policy_name=module_args["name"] - ) - api_obj.create_host_access_policy.assert_not_called() - api_obj.update_host_access_policy.assert_not_called() - api_obj.delete_host_access_policy.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.HostAccessPoliciesApi") -def test_hap_update(m_hap_api, m_op_api, module_args, current_hap_list): - # NOTE: Host Access Policy does not have PATCH method, thus no action is expected - current_hap = current_hap_list.items[0] - module_args["name"] = current_hap.name - module_args["display_name"] = "New Display Name" - module_args["iqn"] = current_hap.iqn - module_args["personality"] = ( - "windows" if current_hap.personality != "windows" else "linux" - ) - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.list_host_access_policies = MagicMock(return_value=current_hap_list) - api_obj.get_host_access_policy = MagicMock(return_value=current_hap) - api_obj.create_host_access_policy = MagicMock(return_value=OperationMock(1)) - api_obj.update_host_access_policy = MagicMock(return_value=OperationMock(2)) - api_obj.delete_host_access_policy = MagicMock(return_value=OperationMock(3)) - m_hap_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_hap.main() - - assert exc.value.changed is False - - # check api was called correctly - api_obj.list_host_access_policies.assert_called_once_with() - api_obj.get_host_access_policy.assert_called_once_with( - host_access_policy_name=module_args["name"] - ) - api_obj.create_host_access_policy.assert_not_called() - api_obj.update_host_access_policy.assert_not_called() - api_obj.delete_host_access_policy.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.HostAccessPoliciesApi") -def test_hap_present_not_changed(m_hap_api, m_op_api, module_args, current_hap_list): - current_hap = current_hap_list.items[0] - module_args["name"] = current_hap.name - module_args["display_name"] = current_hap.display_name - module_args["iqn"] = current_hap.iqn - module_args["personality"] = current_hap.personality - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.list_host_access_policies = MagicMock(return_value=current_hap_list) - api_obj.get_host_access_policy = MagicMock(return_value=current_hap) - api_obj.create_host_access_policy = MagicMock(return_value=OperationMock(1)) - api_obj.update_host_access_policy = MagicMock(return_value=OperationMock(2)) - api_obj.delete_host_access_policy = MagicMock(return_value=OperationMock(3)) - m_hap_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_hap.main() - - assert exc.value.changed is False - - # check api was called correctly - api_obj.list_host_access_policies.assert_called_once_with() - api_obj.get_host_access_policy.assert_called_once_with( - host_access_policy_name=module_args["name"] - ) - api_obj.create_host_access_policy.assert_not_called() - api_obj.update_host_access_policy.assert_not_called() - api_obj.delete_host_access_policy.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.HostAccessPoliciesApi") -def test_hap_absent_not_changed(m_hap_api, m_op_api, module_args, current_hap_list): - module_args["state"] = "absent" - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.list_host_access_policies = MagicMock(return_value=current_hap_list) - api_obj.get_host_access_policy = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_host_access_policy = MagicMock(return_value=OperationMock(1)) - api_obj.update_host_access_policy = MagicMock(return_value=OperationMock(2)) - api_obj.delete_host_access_policy = MagicMock(return_value=OperationMock(3)) - m_hap_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_hap.main() - - assert exc.value.changed is False - - # check api was called correctly - api_obj.list_host_access_policies.assert_called_once_with() - api_obj.get_host_access_policy.assert_called_once_with( - host_access_policy_name=module_args["name"] - ) - api_obj.create_host_access_policy.assert_not_called() - api_obj.update_host_access_policy.assert_not_called() - api_obj.delete_host_access_policy.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.HostAccessPoliciesApi") -def test_hap_delete(m_hap_api, m_op_api, module_args, current_hap_list): - current_hap = current_hap_list.items[0] - module_args["state"] = "absent" - module_args["name"] = current_hap.name - module_args["display_name"] = current_hap.display_name - module_args["iqn"] = current_hap.iqn - module_args["personality"] = current_hap.personality - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.list_host_access_policies = MagicMock(return_value=current_hap_list) - api_obj.get_host_access_policy = MagicMock(return_value=current_hap) - api_obj.create_host_access_policy = MagicMock(return_value=OperationMock(1)) - api_obj.update_host_access_policy = MagicMock(return_value=OperationMock(2)) - api_obj.delete_host_access_policy = MagicMock(return_value=OperationMock(3)) - m_hap_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_hap.main() - - assert exc.value.changed is True - - # check api was called correctly - api_obj.list_host_access_policies.assert_called_once_with() - api_obj.get_host_access_policy.assert_called_once_with( - host_access_policy_name=module_args["name"] - ) - api_obj.create_host_access_policy.assert_not_called() - api_obj.update_host_access_policy.assert_not_called() - api_obj.delete_host_access_policy.assert_called_once_with( - host_access_policy_name=module_args["name"] - ) - op_obj.get_operation.assert_called_once_with(3) - - -@patch("fusion.OperationsApi") -@patch("fusion.HostAccessPoliciesApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, HTTPError), - ], -) -def test_hap_delete_exception( - m_hap_api, m_op_api, exec_original, exec_catch, module_args, current_hap_list -): - current_hap = current_hap_list.items[0] - module_args["state"] = "absent" - module_args["name"] = current_hap.name - module_args["display_name"] = current_hap.display_name - module_args["iqn"] = current_hap.iqn - module_args["personality"] = current_hap.personality - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.list_host_access_policies = MagicMock(return_value=current_hap_list) - api_obj.get_host_access_policy = MagicMock(return_value=current_hap) - api_obj.create_host_access_policy = MagicMock(return_value=OperationMock(1)) - api_obj.update_host_access_policy = MagicMock(return_value=OperationMock(2)) - api_obj.delete_host_access_policy = MagicMock(side_effect=exec_original) - m_hap_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_hap.main() - - # check api was called correctly - api_obj.list_host_access_policies.assert_called_once_with() - api_obj.get_host_access_policy.assert_called_once_with( - host_access_policy_name=module_args["name"] - ) - api_obj.create_host_access_policy.assert_not_called() - api_obj.update_host_access_policy.assert_not_called() - api_obj.delete_host_access_policy.assert_called_once_with( - host_access_policy_name=module_args["name"] - ) - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.HostAccessPoliciesApi") -def test_hap_delete_op_fails(m_hap_api, m_op_api, module_args, current_hap_list): - current_hap = current_hap_list.items[0] - module_args["state"] = "absent" - module_args["name"] = current_hap.name - module_args["display_name"] = current_hap.display_name - module_args["iqn"] = current_hap.iqn - module_args["personality"] = current_hap.personality - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.list_host_access_policies = MagicMock(return_value=current_hap_list) - api_obj.get_host_access_policy = MagicMock(return_value=current_hap) - api_obj.create_host_access_policy = MagicMock(return_value=OperationMock(1)) - api_obj.update_host_access_policy = MagicMock(return_value=OperationMock(2)) - api_obj.delete_host_access_policy = MagicMock(return_value=OperationMock(3)) - m_hap_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(OperationException): - fusion_hap.main() - - # check api was called correctly - api_obj.list_host_access_policies.assert_called_once_with() - api_obj.get_host_access_policy.assert_called_once_with( - host_access_policy_name=module_args["name"] - ) - api_obj.create_host_access_policy.assert_not_called() - api_obj.update_host_access_policy.assert_not_called() - api_obj.delete_host_access_policy.assert_called_once_with( - host_access_policy_name=module_args["name"] - ) - op_obj.get_operation.assert_called_once_with(3) - - -@patch("fusion.OperationsApi") -@patch("fusion.HostAccessPoliciesApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, OperationException), - ], -) -def test_hap_delete_op_exception( - m_hap_api, m_op_api, exec_original, exec_catch, module_args, current_hap_list -): - current_hap = current_hap_list.items[0] - module_args["state"] = "absent" - module_args["name"] = current_hap.name - module_args["display_name"] = current_hap.display_name - module_args["iqn"] = current_hap.iqn - module_args["personality"] = current_hap.personality - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.list_host_access_policies = MagicMock(return_value=current_hap_list) - api_obj.get_host_access_policy = MagicMock(return_value=current_hap) - api_obj.create_host_access_policy = MagicMock(return_value=OperationMock(1)) - api_obj.update_host_access_policy = MagicMock(return_value=OperationMock(2)) - api_obj.delete_host_access_policy = MagicMock(return_value=OperationMock(3)) - m_hap_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(side_effect=exec_original) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_hap.main() - - # check api was called correctly - api_obj.list_host_access_policies.assert_called_once_with() - api_obj.get_host_access_policy.assert_called_once_with( - host_access_policy_name=module_args["name"] - ) - api_obj.create_host_access_policy.assert_not_called() - api_obj.update_host_access_policy.assert_not_called() - api_obj.delete_host_access_policy.assert_called_once_with( - host_access_policy_name=module_args["name"] - ) - op_obj.get_operation.assert_called_once_with(3) diff --git a/ansible_collections/purestorage/fusion/tests/functional/test_fusion_hw.py b/ansible_collections/purestorage/fusion/tests/functional/test_fusion_hw.py deleted file mode 100644 index 3ad109b64..000000000 --- a/ansible_collections/purestorage/fusion/tests/functional/test_fusion_hw.py +++ /dev/null @@ -1,115 +0,0 @@ -# -*- coding: utf-8 -*- - -# (c) 2023, Andrej Pajtas (apajtas@purestorage.com) -# GNU General Public License v3.0+ (see COPYING.GPLv3 or https://www.gnu.org/licenses/gpl-3.0.txt) - -from __future__ import absolute_import, division, print_function - -__metaclass__ = type - -from unittest.mock import MagicMock - -import fusion as purefusion -import pytest -from ansible.module_utils import basic -from ansible_collections.purestorage.fusion.plugins.modules import fusion_hw -from ansible_collections.purestorage.fusion.tests.functional.utils import ( - AnsibleExitJson, - AnsibleFailJson, - exit_json, - fail_json, - set_module_args, -) - -# GLOBAL MOCKS -fusion_hw.setup_fusion = MagicMock(return_value=purefusion.api_client.ApiClient()) -purefusion.api_client.ApiClient.call_api = MagicMock( - side_effect=Exception("API call not mocked!") -) -basic.AnsibleModule.exit_json = exit_json -basic.AnsibleModule.fail_json = fail_json - - -@pytest.mark.parametrize( - "module_args", - [ - # unknown parameter 'extra' is provided - { - "state": "present", - "name": "hw1", - "display_name": "Hardware Type 1", - "array_type": "FA//X", - "media_type": "random", - "app_id": "ABCD1234", - "key_file": "private-key.pem", - "extra": "value", - }, - # parameter 'state` has incorrect value - { - "state": "cool", - "name": "hw1", - "display_name": "Hardware Type 1", - "array_type": "FA//X", - "media_type": "random", - "app_id": "ABCD1234", - "key_file": "private-key.pem", - }, - # parameter 'state` has incorrect value - { - "state": "absent", - "name": "hw1", - "display_name": "Hardware Type 1", - "array_type": "FA//X", - "media_type": "random", - "app_id": "ABCD1234", - "key_file": "private-key.pem", - }, - # parameter 'array_type` has incorrect value - { - "state": "present", - "name": "hw1", - "display_name": "Hardware Type 1", - "array_type": "wrong", - "media_type": "random", - "app_id": "ABCD1234", - "key_file": "private-key.pem", - }, - ], -) -def test_module_fails_on_wrong_parameters(module_args): - set_module_args(module_args) - - # run module - with pytest.raises(AnsibleFailJson): - fusion_hw.main() - - -@pytest.mark.parametrize("state", [None, "present"]) -@pytest.mark.parametrize("name", [None, "hw_type_name1"]) -@pytest.mark.parametrize("display_name", [None, "Super weird Display Name 12 3"]) -@pytest.mark.parametrize("array_type", [None, "FA//X", "FA//C"]) -@pytest.mark.parametrize("media_type", [None, "random"]) -def test_hw_does_not_call_api(state, name, display_name, array_type, media_type): - module_args = { - "app_id": "ABCD1234", - "key_file": "private-key.pem", - } - if state is not None: - module_args["state"] = state - if name is not None: - module_args["name"] = name - if display_name is not None: - module_args["display_name"] = display_name - if array_type is not None: - module_args["array_type"] = array_type - if media_type is not None: - module_args["media_type"] = media_type - set_module_args(module_args) - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_hw.main() - - assert exc.value.changed is False - - # NOTE: api call assertion is handled by global mock diff --git a/ansible_collections/purestorage/fusion/tests/functional/test_fusion_info.py b/ansible_collections/purestorage/fusion/tests/functional/test_fusion_info.py deleted file mode 100644 index c542cddc0..000000000 --- a/ansible_collections/purestorage/fusion/tests/functional/test_fusion_info.py +++ /dev/null @@ -1,2384 +0,0 @@ -# -*- coding: utf-8 -*- - -# (c) 2023, Andrej Pajtas (apajtas@purestorage.com) -# GNU General Public License v3.0+ (see COPYING.GPLv3 or https://www.gnu.org/licenses/gpl-3.0.txt) - -from __future__ import absolute_import, division, print_function - -__metaclass__ = type - -import os -from itertools import combinations -from unittest.mock import MagicMock, call, patch - -import fusion as purefusion -import pytest -from ansible.module_utils import basic -from ansible_collections.purestorage.fusion.plugins.modules import fusion_info -from ansible_collections.purestorage.fusion.tests.functional.utils import ( - AnsibleExitJson, - exit_json, - fail_json, - set_module_args, -) -from ansible_collections.purestorage.fusion.tests.helpers import ( - ApiExceptionsMockGenerator, -) -from urllib3.exceptions import HTTPError -import time - -# GLOBAL MOCKS -fusion_info.setup_fusion = MagicMock(return_value=purefusion.api_client.ApiClient()) -purefusion.api_client.ApiClient.call_api = MagicMock( - side_effect=Exception("API call not mocked!") -) -basic.AnsibleModule.exit_json = exit_json -basic.AnsibleModule.fail_json = fail_json - -VALID_SUBSETS = { - "all", - "minimum", - "roles", - "users", - "arrays", - "hardware_types", - "volumes", - "host_access_policies", - "storage_classes", - "protection_policies", - "placement_groups", - "network_interfaces", - "availability_zones", - "storage_endpoints", - "snapshots", - "storage_services", - "tenants", - "tenant_spaces", - "network_interface_groups", - "api_clients", - "regions", -} - -EXPECTED_KEYS = { - "all": { - "default", - "hardware_types", - "users", - "availability_zones", - "roles", - "role_assignments", - "storage_services", - "volumes", - "protection_policies", - "placement_groups", - "storage_classes", - "network_interfaces", - "host_access_policies", - "tenants", - "tenant_spaces", - "storage_endpoints", - "api_clients", - "network_interface_groups", - "volume_snapshots", - "snapshots", - "arrays", - "regions", - }, - "minimum": {"default"}, - "arrays": {"arrays"}, - "hardware_types": {"hardware_types"}, - "users": {"users"}, - "availability_zones": {"availability_zones"}, - "roles": {"roles", "role_assignments"}, - "storage_services": {"storage_services"}, - "volumes": {"volumes"}, - "protection_policies": {"protection_policies"}, - "placement_groups": {"placement_groups"}, - "storage_classes": {"storage_classes"}, - "network_interfaces": {"network_interfaces"}, - "host_access_policies": {"host_access_policies"}, - "tenants": {"tenants"}, - "tenant_spaces": {"tenant_spaces"}, - "storage_endpoints": {"storage_endpoints"}, - "api_clients": {"api_clients"}, - "network_interface_groups": {"network_interface_groups"}, - "snapshots": {"snapshots", "volume_snapshots"}, - "regions": {"regions"}, -} - -RESP_VERSION = purefusion.Version(version=1) -RESP_AS = purefusion.Space( - resource=purefusion.ResourceReference( - id="333", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - total_physical_space=1, - unique_space=1, - snapshot_space=1, -) -RESP_AP = purefusion.Performance( - resource=purefusion.ResourceReference( - id="222", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - reads_per_sec=12345, - read_latency_us=1000, - read_bandwidth=5000000, - writes_per_sec=12611, - write_latency_us=2000, - write_bandwidth=4000000, -) -RESP_LU = [ - purefusion.User( - id="390", - name="username1", - self_link="self_link_value", - display_name="User's Name 1", - email="user1@email.com", - ), - purefusion.User( - id="391", - name="username2", - self_link="self_link_value", - display_name="User's Name 2", - email="user2@email.com", - ), -] -RESP_PP = purefusion.ProtectionPolicyList( - count=2, - more_items_remaining=False, - items=[ - purefusion.ProtectionPolicy( - id="098", - name="pp1", - self_link="self_link_value", - display_name="Protection Policy 1", - objectives=[], - ), - purefusion.ProtectionPolicy( - id="099", - name="pp2", - self_link="self_link_value", - display_name="Protection Policy 2", - objectives=[], - ), - ], -) -RESP_HAP = purefusion.HostAccessPolicyList( - count=2, - more_items_remaining=False, - items=[ - purefusion.HostAccessPolicy( - id="900", - name="hap1", - self_link="self_link_value", - display_name="Host Access Policy 1", - iqn="iqn.2023-05.com.purestorage:420qp2c0261", - personality="aix", - ), - purefusion.HostAccessPolicy( - id="901", - name="hap2", - self_link="self_link_value", - display_name="Host Access Policy 2", - iqn="iqn.2023-05.com.purestorage:420qp2c0262", - personality="linux", - ), - ], -) -RESP_HT = purefusion.HardwareTypeList( - count=2, - more_items_remaining=False, - items=[ - purefusion.HardwareType( - id="500", - name="ht1", - self_link="self_link_value", - display_name="Hardware Type 1", - array_type="FA//X", - media_type="whatever", - ), - purefusion.HardwareType( - id="501", - name="ht2", - self_link="self_link_value", - display_name="Hardware Type 2", - array_type="FA//C", - media_type="whatever", - ), - ], -) -RESP_SS = purefusion.StorageServiceList( - count=2, - more_items_remaining=False, - items=[ - purefusion.StorageService( - id="502", - name="ss1", - self_link="self_link_value", - display_name="Storage Service 1", - hardware_types=[ - purefusion.HardwareTypeRef( - id="910", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - purefusion.HardwareTypeRef( - id="911", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - ], - ), - purefusion.StorageService( - id="503", - name="ss2", - self_link="self_link_value", - display_name="Storage Service 3", - hardware_types=[ - purefusion.HardwareTypeRef( - id="912", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ) - ], - ), - ], -) -RESP_TENANTS = purefusion.TenantList( - count=2, - more_items_remaining=False, - items=[ - purefusion.Tenant( - id="504", - name="t1", - self_link="self_link_value", - display_name="Tenant 1", - tenant_spaces_link="ts_link", - ), - purefusion.Tenant( - id="505", - name="t2", - self_link="self_link_value", - display_name="Tenant 2", - tenant_spaces_link="ts_link", - ), - ], -) -RESP_REGIONS = purefusion.RegionList( - count=2, - more_items_remaining=False, - items=[ - purefusion.Region( - id="506", - name="region1", - self_link="self_link_value", - display_name="Region 1", - ), - purefusion.Region( - id="507", - name="region2", - self_link="self_link_value", - display_name="Region 2", - ), - ], -) -RESP_ROLES = [ - purefusion.Role( - id="902", - name="role1", - self_link="self_link_value", - display_name="Role 1", - description="nice description", - assignable_scopes=["scope1", "scope2"], - ), - purefusion.Role( - id="903", - name="role2", - self_link="self_link_value", - display_name="Role 2", - description="not so nice description", - assignable_scopes=["scope3", "scope2"], - ), -] -RESP_SC = purefusion.StorageClassList( - count=2, - more_items_remaining=False, - items=[ - purefusion.StorageClass( - id="508", - name="sc1", - self_link="self_link_value", - display_name="Storage Class 1", - storage_service=purefusion.StorageServiceRef( - id="509", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - size_limit=12345678, - iops_limit=10000, - bandwidth_limit=2000000, - ), - purefusion.StorageClass( - id="510", - name="sc2", - self_link="self_link_value", - display_name="Storage Class 2", - storage_service=purefusion.StorageServiceRef( - id="511", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - size_limit=12345679, - iops_limit=10001, - bandwidth_limit=2000001, - ), - ], -) -RESP_RA = [ - purefusion.RoleAssignment( - id="904", - name="ra1", - self_link="self_link_value", - display_name="Role Assignment 1", - role=purefusion.RoleRef( - id="512", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - scope=purefusion.ResourceReference( - id="513", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - principal="user1", - ), - purefusion.RoleAssignment( - id="905", - name="ra2", - self_link="self_link_value", - display_name="Role Assignment 2", - role=purefusion.RoleRef( - id="513", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - scope=purefusion.ResourceReference( - id="514", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - principal="user2", - ), -] -RESP_TS = purefusion.TenantSpaceList( - count=2, - more_items_remaining=False, - items=[ - purefusion.TenantSpace( - id="515", - name="ts1", - self_link="self_link_value", - display_name="Tenant Space 1", - tenant=RESP_TENANTS.items[0].name, - volumes_link="link_value1", - snapshots_link="link_value2", - placement_groups_link="link_value3", - ), - purefusion.TenantSpace( - id="516", - name="ts2", - self_link="self_link_value", - display_name="Tenant Space 2", - tenant=RESP_TENANTS.items[1].name, - volumes_link="link_value4", - snapshots_link="link_value5", - placement_groups_link="link_value6", - ), - ], -) -RESP_VOLUMES = purefusion.VolumeList( - count=1, - more_items_remaining=False, - items=[ - purefusion.Volume( - id="517", - name="volume1", - self_link="self_link_value", - display_name="Volume 1", - size=4000000, - tenant=purefusion.TenantRef( - id="518", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - tenant_space=purefusion.TenantSpaceRef( - id="519", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - storage_class=purefusion.StorageClassRef( - id="520", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - protection_policy=purefusion.ProtectionPolicyRef( - id="521", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - placement_group=purefusion.PlacementGroupRef( - id="522", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - array=purefusion.ArrayRef( - id="905", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - created_at=485743825, - source_volume_snapshot=purefusion.VolumeSnapshotRef( - id="523", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - host_access_policies=[ - purefusion.HostAccessPolicyRef( - id="524", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ) - ], - serial_number="123923482034", - target=purefusion.Target( - iscsi=purefusion.Iscsi( - iqn="iqn.2023-05.com.purestorage:420qp2c0222", - addresses=["125.1.2.4"], - ) - ), - time_remaining=1000000, - destroyed=False, - ) - ], -) -RESP_PG = purefusion.PlacementGroupList( - count=1, - more_items_remaining=False, - items=[ - purefusion.PlacementGroup( - id="525", - name="pg1", - self_link="self_link_value", - display_name="Placement Group 1", - tenant=purefusion.TenantRef( - id="526", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - tenant_space=purefusion.TenantSpaceRef( - id="527", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - placement_engine=purefusion.PlacementEngine(), - availability_zone=purefusion.AvailabilityZoneRef( - id="528", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - protocols=purefusion.Target( - iscsi=purefusion.Iscsi( - iqn="iqn.2023-05.com.purestorage:420qp2c0211", - addresses=["125.1.2.5"], - ) - ), - storage_service=purefusion.StorageServiceRef( - id="529", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - array=purefusion.ArrayRef( - id="530", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - ) - ], -) -RESP_SNAPSHOTS = purefusion.SnapshotList( - count=1, - more_items_remaining=False, - items=[ - purefusion.Snapshot( - id="531", - name="snapshot1", - self_link="self_link_value", - display_name="Snapshot 1", - tenant=purefusion.TenantRef( - id="531", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - tenant_space=purefusion.TenantSpaceRef( - id="532", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - volume_snapshots_link="link_to_volume_snapshot", - protection_policy=purefusion.ProtectionPolicyRef( - id="533", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - time_remaining=23432, - destroyed=False, - ) - ], -) -RESP_AZ = purefusion.AvailabilityZoneList( - count=3, - more_items_remaining=False, - items=[ - purefusion.AvailabilityZone( - id="534", - name="az1", - self_link="self_link_value", - display_name="Availability Zone 1", - region=purefusion.RegionRef( - id="535", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - ), - purefusion.AvailabilityZone( - id="536", - name="az2", - self_link="self_link_value", - display_name="Availability Zone 2", - region=purefusion.RegionRef( - id="537", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - ), - purefusion.AvailabilityZone( - id="537", - name="az3", - self_link="self_link_value", - display_name="Availability Zone 3", - region=purefusion.RegionRef( - id="538", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - ), - ], -) -RESP_NIG = purefusion.NetworkInterfaceGroupList( - count=1, - more_items_remaining=False, - items=[ - purefusion.NetworkInterfaceGroup( - id="538", - name="nig1", - self_link="self_link_value", - display_name="Network Interface Group 1", - region=purefusion.RegionRef( - id="539", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - availability_zone=purefusion.AvailabilityZoneRef( - id="540", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - group_type="eth", - eth=purefusion.NetworkInterfaceGroupEth( - prefix="10.21.200.0/24", gateway="10.21.200.1", vlan=None, mtu=1600 - ), - ) - ], -) -RESP_SE = purefusion.StorageEndpointList( - count=1, - more_items_remaining=False, - items=[ - purefusion.StorageEndpoint( - id="541", - name="se1", - self_link="self_link_value", - display_name="Storage Endpoint 1", - region=purefusion.RegionRef( - id="542", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - availability_zone=purefusion.AvailabilityZoneRef( - id="543", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - endpoint_type="iscsi", - iscsi=purefusion.StorageEndpointIscsi( - discovery_interfaces=[ - purefusion.StorageEndpointIscsiDiscoveryInterface( - address="10.21.200.5/24", - gateway="10.21.200.0", - mtu=2000, - network_interface_groups=[ - purefusion.NetworkInterfaceGroupRef( - id="544", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - ], - ), - purefusion.StorageEndpointIscsiDiscoveryInterface( - address="10.21.200.6/24", - gateway="10.21.200.0", - mtu=2100, - network_interface_groups=[], - ), - ] - ), - ) - ], -) -RESP_NI = purefusion.NetworkInterfaceList( - count=1, - more_items_remaining=False, - items=[ - purefusion.NetworkInterface( - id="545", - name="ni1", - self_link="self_link_value", - display_name="Network Interface 1", - region=purefusion.RegionRef( - id="546", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - availability_zone=purefusion.AvailabilityZoneRef( - id="547", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - array=purefusion.ArrayRef( - id="548", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - interface_type="eth", - eth=purefusion.NetworkInterfaceEth( - address="10.21.200.6/24", - gateway="10.21.200.0", - mac_address="E3-18-55-D8-8C-F4", - mtu=1233, - vlan=2, - ), - services=["a", "b"], - enabled=True, - network_interface_group=purefusion.NetworkInterfaceGroupRef( - id="906", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - max_speed=3224232, - ) - ], -) -RESP_ARRAYS = purefusion.ArrayList( - count=1, - more_items_remaining=False, - items=[ - purefusion.Array( - id="549", - name="array1", - self_link="self_link_value", - display_name="Array 1", - apartment_id="234214351", - hardware_type=purefusion.HardwareTypeRef( - id="550", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - region=purefusion.RegionRef( - id="551", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - availability_zone=purefusion.AvailabilityZoneRef( - id="552", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - appliance_id="2734298849", - host_name="super_host", - maintenance_mode=False, - unavailable_mode=False, - ) - ], -) -RESP_AC = [ - purefusion.APIClient( - id="553", - name="client1", - self_link="self_link_value", - display_name="API Client 1", - issuer="apikey:name:thisisnotreal", - public_key="0123456789", - last_key_update=1684421184201, - last_used=1684421290201, - creator_id="1234", - ), - purefusion.APIClient( - id="554", - name="client2", - self_link="self_link_value", - display_name="API Client 2", - issuer="apikey:name:thisissuperreal", - public_key="0987654321", - last_key_update=1684421184201, - last_used=1684421290201, - creator_id="4321", - ), -] -RESP_VS = purefusion.VolumeSnapshotList( - count=1, - more_items_remaining=False, - items=[ - purefusion.VolumeSnapshot( - id="555", - name="vs1", - self_link="self_link_value", - display_name="Volume Snapshot 1", - serial_number="235235235345", - volume_serial_number="544236456346345", - created_at=1684421184201, - consistency_id="666666", - destroyed=False, - time_remaining=1684421290201, - size=19264036, - tenant=purefusion.TenantRef( - id="556", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - tenant_space=purefusion.TenantSpaceRef( - id="557", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - snapshot=purefusion.VolumeSnapshotRef( - id="558", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - volume=purefusion.VolumeRef( - id="559", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - protection_policy=purefusion.ProtectionPolicyRef( - id="560", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - placement_group=purefusion.PlacementGroupRef( - id="561", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - ) - ], -) - - -@patch.dict(os.environ, {"TZ": "UTC"}) -@patch.dict(os.environ, {"LC_TIME": "en_US.utf8"}) -@patch("fusion.DefaultApi") -@patch("fusion.IdentityManagerApi") -@patch("fusion.ProtectionPoliciesApi") -@patch("fusion.HostAccessPoliciesApi") -@patch("fusion.HardwareTypesApi") -@patch("fusion.StorageServicesApi") -@patch("fusion.TenantsApi") -@patch("fusion.RegionsApi") -@patch("fusion.RolesApi") -@patch("fusion.StorageClassesApi") -@patch("fusion.RoleAssignmentsApi") -@patch("fusion.TenantSpacesApi") -@patch("fusion.VolumesApi") -@patch("fusion.VolumeSnapshotsApi") -@patch("fusion.PlacementGroupsApi") -@patch("fusion.SnapshotsApi") -@patch("fusion.AvailabilityZonesApi") -@patch("fusion.ArraysApi") -@patch("fusion.NetworkInterfaceGroupsApi") -@patch("fusion.StorageEndpointsApi") -@patch("fusion.NetworkInterfacesApi") -@pytest.mark.parametrize( - # all single options + all subsets of two options - "gather_subset", - [ - *combinations( - VALID_SUBSETS, - 2, - ), - *[[option] for option in VALID_SUBSETS], - ], -) -def test_info_gather_subset( - # API mocks - m_ni_api, - m_se_api, - m_nig_api, - m_array_api, - m_az_api, - m_snapshot_api, - m_pg_api, - m_vs_api, - m_volume_api, - m_ts_api, - m_ra_api, - m_sc_api, - m_role_api, - m_region_api, - m_tenant_api, - m_ss_api, - m_hw_api, - m_hap_api, - m_pp_api, - m_im_api, - m_default_api, - # test parameters - gather_subset, -): - """ - Test that fusion_info module accepts single 'gather_subset' options and all subsets of two 'gather_subset' options. - """ - # NOTE: here we use the same MagicMock object for all APIs to make the test simpler, this has no harm to the logic of the test - api_obj = MagicMock() - api_obj.get_version = MagicMock(return_value=RESP_VERSION) - api_obj.get_array_space = MagicMock(return_value=RESP_AS) - api_obj.get_array_performance = MagicMock(return_value=RESP_AP) - api_obj.list_users = MagicMock(return_value=RESP_LU) - api_obj.list_protection_policies = MagicMock(return_value=RESP_PP) - api_obj.list_host_access_policies = MagicMock(return_value=RESP_HAP) - api_obj.list_hardware_types = MagicMock(return_value=RESP_HT) - api_obj.list_storage_services = MagicMock(return_value=RESP_SS) - api_obj.list_tenants = MagicMock(return_value=RESP_TENANTS) - api_obj.list_regions = MagicMock(return_value=RESP_REGIONS) - api_obj.list_roles = MagicMock(return_value=RESP_ROLES) - api_obj.list_storage_classes = MagicMock(return_value=RESP_SC) - api_obj.list_role_assignments = MagicMock(return_value=RESP_RA) - api_obj.list_tenant_spaces = MagicMock(return_value=RESP_TS) - api_obj.list_volumes = MagicMock(return_value=RESP_VOLUMES) - api_obj.list_placement_groups = MagicMock(return_value=RESP_PG) - api_obj.list_snapshots = MagicMock(return_value=RESP_SNAPSHOTS) - api_obj.list_availability_zones = MagicMock(return_value=RESP_AZ) - api_obj.list_network_interface_groups = MagicMock(return_value=RESP_NIG) - api_obj.list_storage_endpoints = MagicMock(return_value=RESP_SE) - api_obj.list_network_interfaces = MagicMock(return_value=RESP_NI) - api_obj.list_arrays = MagicMock(return_value=RESP_ARRAYS) - api_obj.list_api_clients = MagicMock(return_value=RESP_AC) - api_obj.list_volume_snapshots = MagicMock(return_value=RESP_VS) - m_ni_api.return_value = api_obj - m_se_api.return_value = api_obj - m_nig_api.return_value = api_obj - m_array_api.return_value = api_obj - m_az_api.return_value = api_obj - m_snapshot_api.return_value = api_obj - m_pg_api.return_value = api_obj - m_vs_api.return_value = api_obj - m_volume_api.return_value = api_obj - m_ts_api.return_value = api_obj - m_ra_api.return_value = api_obj - m_sc_api.return_value = api_obj - m_role_api.return_value = api_obj - m_region_api.return_value = api_obj - m_tenant_api.return_value = api_obj - m_ss_api.return_value = api_obj - m_hw_api.return_value = api_obj - m_hap_api.return_value = api_obj - m_pp_api.return_value = api_obj - m_im_api.return_value = api_obj - m_default_api.return_value = api_obj - - time.tzset() - - set_module_args( - { - "gather_subset": gather_subset, - "app_id": "ABCD1234", - "key_file": "private-key.pem", - } - ) - - with pytest.raises(AnsibleExitJson) as exc: - fusion_info.main() - - assert exc.value.changed is False - - expected_keys = {} - for option in gather_subset: - expected_keys = {*expected_keys, *EXPECTED_KEYS[option]} - - assert exc.value.fusion_info.keys() == expected_keys - - if "hardware_types" in gather_subset or "all" in gather_subset: - api_obj.list_hardware_types.assert_called_with() - assert "hardware_types" in exc.value.fusion_info - assert exc.value.fusion_info["hardware_types"] == { - hw_type.name: { - "array_type": hw_type.array_type, - "display_name": hw_type.display_name, - "media_type": hw_type.media_type, - } - for hw_type in RESP_HT.items - } - elif "minimum" in gather_subset: - api_obj.list_hardware_types.assert_called_with() - assert "default" in exc.value.fusion_info - assert "hardware_types" in exc.value.fusion_info["default"] - assert exc.value.fusion_info["default"]["hardware_types"] == len(RESP_HT.items) - else: - api_obj.list_hardware_types.assert_not_called() - - if "users" in gather_subset or "all" in gather_subset: - api_obj.list_users.assert_called_with() - assert "users" in exc.value.fusion_info - assert exc.value.fusion_info["users"] == { - user.name: { - "display_name": user.display_name, - "email": user.email, - "id": user.id, - } - for user in RESP_LU - } - elif "minimum" in gather_subset: - api_obj.list_users.assert_called_with() - assert "default" in exc.value.fusion_info - assert "users" in exc.value.fusion_info["default"] - assert exc.value.fusion_info["default"]["users"] == len(RESP_LU) - else: - api_obj.list_users.assert_not_called() - - if "availability_zones" in gather_subset or "all" in gather_subset: - api_obj.list_regions.assert_called_with() - api_obj.list_availability_zones.assert_has_calls( - [call(region_name=region.name) for region in RESP_REGIONS.items], - any_order=True, - ) - assert "availability_zones" in exc.value.fusion_info - assert exc.value.fusion_info["availability_zones"] == { - zone.name: { - "display_name": zone.display_name, - "region": zone.region.name, - } - for zone in RESP_AZ.items - } - elif "minimum" in gather_subset: - api_obj.list_regions.assert_called_with() - api_obj.list_availability_zones.assert_has_calls( - [call(region_name=region.name) for region in RESP_REGIONS.items], - any_order=True, - ) - assert "default" in exc.value.fusion_info - assert "availability_zones" in exc.value.fusion_info["default"] - assert exc.value.fusion_info["default"]["availability_zones"] == len( - RESP_REGIONS.items - ) * len(RESP_AZ.items) - - if "roles" in gather_subset or "all" in gather_subset: - api_obj.list_roles.assert_called_with() - api_obj.list_role_assignments.assert_has_calls( - [call(role_name=role.name) for role in RESP_ROLES], - any_order=True, - ) - assert "roles" in exc.value.fusion_info - assert "role_assignments" in exc.value.fusion_info - assert exc.value.fusion_info["roles"] == { - role.name: { - "display_name": role.display_name, - "scopes": role.assignable_scopes, - } - for role in RESP_ROLES - } - assert exc.value.fusion_info["role_assignments"] == { - ra.name: { - "display_name": ra.display_name, - "role": ra.role.name, - "scope": ra.scope.name, - } - for ra in RESP_RA - } - elif "minimum" in gather_subset: - api_obj.list_roles.assert_called_with() - api_obj.list_role_assignments.assert_has_calls( - [call(role_name=role.name) for role in RESP_ROLES], - any_order=True, - ) - assert "default" in exc.value.fusion_info - assert "roles" in exc.value.fusion_info["default"] - assert "role_assignments" in exc.value.fusion_info["default"] - assert exc.value.fusion_info["default"]["roles"] == len(RESP_ROLES) - assert exc.value.fusion_info["default"]["role_assignments"] == len( - RESP_ROLES - ) * len(RESP_RA) - else: - api_obj.list_roles.assert_not_called() - api_obj.list_role_assignments.assert_not_called() - - if "storage_services" in gather_subset or "all" in gather_subset: - api_obj.list_storage_services.assert_called_with() - assert "storage_services" in exc.value.fusion_info - assert exc.value.fusion_info["storage_services"] == { - service.name: { - "display_name": service.display_name, - "hardware_types": [hwtype.name for hwtype in service.hardware_types], - } - for service in RESP_SS.items - } - elif "minimum" in gather_subset: - api_obj.list_storage_services.assert_called_with() - assert "default" in exc.value.fusion_info - assert "storage_services" in exc.value.fusion_info["default"] - assert exc.value.fusion_info["default"]["storage_services"] == len( - RESP_SS.items - ) - - if "volumes" in gather_subset or "all" in gather_subset: - api_obj.list_tenants.assert_called_with() - api_obj.list_tenant_spaces.assert_has_calls( - [call(tenant_name=tenant.name) for tenant in RESP_TENANTS.items], - any_order=True, - ) - api_obj.list_volumes.assert_has_calls( - [ - call( - tenant_name=tenant.name, - tenant_space_name=ts.name, - ) - for ts in RESP_TS.items - for tenant in RESP_TENANTS.items - ], - any_order=True, - ) - assert "volumes" in exc.value.fusion_info - assert exc.value.fusion_info["volumes"] == { - tenant.name - + "/" - + tenant_space.name - + "/" - + volume.name: { - "tenant": tenant.name, - "tenant_space": tenant_space.name, - "name": volume.name, - "size": volume.size, - "display_name": volume.display_name, - "placement_group": volume.placement_group.name, - "source_volume_snapshot": getattr( - volume.source_volume_snapshot, "name", None - ), - "protection_policy": getattr(volume.protection_policy, "name", None), - "storage_class": volume.storage_class.name, - "serial_number": volume.serial_number, - "target": { - "iscsi": { - "addresses": volume.target.iscsi.addresses, - "iqn": volume.target.iscsi.iqn, - }, - "nvme": { - "addresses": None, - "nqn": None, - }, - "fc": { - "addresses": None, - "wwns": None, - }, - }, - "array": volume.array.name, - } - for volume in RESP_VOLUMES.items - for tenant_space in RESP_TS.items - for tenant in RESP_TENANTS.items - } - elif "minimum" in gather_subset: - api_obj.list_tenants.assert_called_with() - api_obj.list_tenant_spaces.assert_has_calls( - [call(tenant_name=tenant.name) for tenant in RESP_TENANTS.items], - any_order=True, - ) - api_obj.list_volumes.assert_has_calls( - [ - call( - tenant_name=tenant.name, - tenant_space_name=ts.name, - ) - for ts in RESP_TS.items - for tenant in RESP_TENANTS.items - ], - any_order=True, - ) - assert "default" in exc.value.fusion_info - assert "volumes" in exc.value.fusion_info["default"] - assert exc.value.fusion_info["default"]["volumes"] == len( - RESP_TENANTS.items - ) * len(RESP_TS.items) * len(RESP_VOLUMES.items) - else: - api_obj.list_volumes.assert_not_called() - - if "protection_policies" in gather_subset or "all" in gather_subset: - api_obj.list_protection_policies.assert_called_with() - assert "protection_policies" in exc.value.fusion_info - assert exc.value.fusion_info["protection_policies"] == { - policy.name: { - "objectives": policy.objectives, - } - for policy in RESP_PP.items - } - elif "minimum" in gather_subset: - api_obj.list_protection_policies.assert_called_with() - assert "default" in exc.value.fusion_info - assert "protection_policies" in exc.value.fusion_info["default"] - assert exc.value.fusion_info["default"]["protection_policies"] == len( - RESP_PP.items - ) - else: - api_obj.list_protection_policies.assert_not_called() - - if "storage_classes" in gather_subset or "all" in gather_subset: - api_obj.list_storage_services.assert_called_with() - api_obj.list_storage_classes.assert_has_calls( - [call(storage_service_name=service.name) for service in RESP_SS.items], - any_order=True, - ) - assert "storage_classes" in exc.value.fusion_info - assert exc.value.fusion_info["storage_classes"] == { - s_class.name: { - "bandwidth_limit": getattr(s_class, "bandwidth_limit", None), - "iops_limit": getattr(s_class, "iops_limit", None), - "size_limit": getattr(s_class, "size_limit", None), - "display_name": s_class.display_name, - "storage_service": service.name, - } - for s_class in RESP_SC.items - for service in RESP_SS.items - } - elif "minimum" in gather_subset: - api_obj.list_storage_services.assert_called_with() - api_obj.list_storage_classes.assert_has_calls( - [call(storage_service_name=service.name) for service in RESP_SS.items], - any_order=True, - ) - assert "default" in exc.value.fusion_info - assert "storage_classes" in exc.value.fusion_info["default"] - assert exc.value.fusion_info["default"]["storage_classes"] == len( - RESP_SC.items - ) * len(RESP_SS.items) - else: - api_obj.list_storage_classes.assert_not_called() - - if "network_interfaces" in gather_subset or "all" in gather_subset: - api_obj.list_regions.assert_called_with() - api_obj.list_availability_zones.assert_has_calls( - [call(region_name=region.name) for region in RESP_REGIONS.items], - any_order=True, - ) - api_obj.list_arrays.assert_has_calls( - [ - call( - availability_zone_name=az.name, - region_name=region.name, - ) - for region in RESP_REGIONS.items - for az in RESP_AZ.items - ], - any_order=True, - ) - api_obj.list_network_interfaces.assert_has_calls( - [ - call( - array_name=array.name, - availability_zone_name=az.name, - region_name=region.name, - ) - for region in RESP_REGIONS.items - for az in RESP_AZ.items - for array in RESP_ARRAYS.items - ], - any_order=True, - ) - assert "network_interfaces" in exc.value.fusion_info - assert exc.value.fusion_info["network_interfaces"] == { - az.name - + "/" - + array.name: { - nic.name: { - "enabled": nic.enabled, - "display_name": nic.display_name, - "interface_type": nic.interface_type, - "services": nic.services, - "max_speed": nic.max_speed, - "vlan": nic.eth.vlan, - "address": nic.eth.address, - "mac_address": nic.eth.mac_address, - "gateway": nic.eth.gateway, - "mtu": nic.eth.mtu, - "network_interface_group": nic.network_interface_group.name, - "availability_zone": nic.availability_zone.name, - } - for nic in RESP_NI.items - } - for region in RESP_REGIONS.items - for az in RESP_AZ.items - for array in RESP_ARRAYS.items - } - elif "minimum" in gather_subset: - api_obj.list_regions.assert_called_with() - api_obj.list_availability_zones.assert_has_calls( - [call(region_name=region.name) for region in RESP_REGIONS.items], - any_order=True, - ) - api_obj.list_arrays.assert_has_calls( - [ - call( - availability_zone_name=az.name, - region_name=region.name, - ) - for region in RESP_REGIONS.items - for az in RESP_AZ.items - ], - any_order=True, - ) - api_obj.list_network_interfaces.assert_has_calls( - [ - call( - array_name=array.name, - availability_zone_name=az.name, - region_name=region.name, - ) - for region in RESP_REGIONS.items - for az in RESP_AZ.items - for array in RESP_ARRAYS.items - ], - any_order=True, - ) - assert "default" in exc.value.fusion_info - assert "network_interfaces" in exc.value.fusion_info["default"] - assert exc.value.fusion_info["default"]["network_interfaces"] == len( - RESP_REGIONS.items - ) * len(RESP_AZ.items) * len(RESP_ARRAYS.items) * len(RESP_NI.items) - else: - api_obj.list_network_interfaces.assert_not_called() - - if "host_access_policies" in gather_subset or "all" in gather_subset: - api_obj.list_host_access_policies.assert_called_with() - assert "host_access_policies" in exc.value.fusion_info - assert exc.value.fusion_info["host_access_policies"] == { - host.name: { - "personality": host.personality, - "display_name": host.display_name, - "iqn": host.iqn, - } - for host in RESP_HAP.items - } - elif "minimum" in gather_subset: - api_obj.list_host_access_policies.assert_called_with() - assert "default" in exc.value.fusion_info - assert "host_access_policies" in exc.value.fusion_info["default"] - assert exc.value.fusion_info["default"]["host_access_policies"] == len( - RESP_HAP.items - ) - else: - api_obj.list_host_access_policies.assert_not_called() - - if "arrays" in gather_subset or "all" in gather_subset: - api_obj.list_regions.assert_called_with() - api_obj.list_availability_zones.assert_has_calls( - [call(region_name=region.name) for region in RESP_REGIONS.items], - any_order=True, - ) - api_obj.list_arrays.assert_has_calls( - [ - call( - availability_zone_name=az.name, - region_name=region.name, - ) - for region in RESP_REGIONS.items - for az in RESP_AZ.items - ], - any_order=True, - ) - api_obj.get_array_space.assert_has_calls( - [ - call( - array_name=array.name, - availability_zone_name=az.name, - region_name=region.name, - ) - for region in RESP_REGIONS.items - for az in RESP_AZ.items - for array in RESP_ARRAYS.items - ], - any_order=True, - ) - api_obj.get_array_performance.assert_has_calls( - [ - call( - array_name=array.name, - availability_zone_name=az.name, - region_name=region.name, - ) - for region in RESP_REGIONS.items - for az in RESP_AZ.items - for array in RESP_ARRAYS.items - ], - any_order=True, - ) - assert "arrays" in exc.value.fusion_info - assert exc.value.fusion_info["arrays"] == { - array.name: { - "region": region.name, - "availability_zone": az.name, - "host_name": array.host_name, - "maintenance_mode": array.maintenance_mode, - "unavailable_mode": array.unavailable_mode, - "display_name": array.display_name, - "hardware_type": array.hardware_type.name, - "appliance_id": array.appliance_id, - "apartment_id": getattr(array, "apartment_id", None), - "space": { - "total_physical_space": RESP_AS.total_physical_space, - }, - "performance": { - "read_bandwidth": RESP_AP.read_bandwidth, - "read_latency_us": RESP_AP.read_latency_us, - "reads_per_sec": RESP_AP.reads_per_sec, - "write_bandwidth": RESP_AP.write_bandwidth, - "write_latency_us": RESP_AP.write_latency_us, - "writes_per_sec": RESP_AP.writes_per_sec, - }, - } - for region in RESP_REGIONS.items - for az in RESP_AZ.items - for array in RESP_ARRAYS.items - } - elif "minimum" in gather_subset: - api_obj.list_regions.assert_called_with() - api_obj.list_availability_zones.assert_has_calls( - [call(region_name=region.name) for region in RESP_REGIONS.items], - any_order=True, - ) - api_obj.list_arrays.assert_has_calls( - [ - call( - availability_zone_name=az.name, - region_name=region.name, - ) - for region in RESP_REGIONS.items - for az in RESP_AZ.items - ], - any_order=True, - ) - api_obj.get_array_space.assert_not_called() - api_obj.get_array_performance.assert_not_called() - assert "default" in exc.value.fusion_info - assert "arrays" in exc.value.fusion_info["default"] - assert exc.value.fusion_info["default"]["arrays"] == len( - RESP_REGIONS.items - ) * len(RESP_AZ.items) * len(RESP_ARRAYS.items) - else: - api_obj.get_array_space.assert_not_called() - api_obj.get_array_performance.assert_not_called() - - if "tenants" in gather_subset or "all" in gather_subset: - api_obj.list_tenants.assert_called_with() - assert "tenants" in exc.value.fusion_info - assert exc.value.fusion_info["tenants"] == { - tenant.name: { - "display_name": tenant.display_name, - } - for tenant in RESP_TENANTS.items - } - elif "minimum" in gather_subset: - api_obj.list_tenants.assert_called_with() - assert "default" in exc.value.fusion_info - assert "tenants" in exc.value.fusion_info["default"] - assert exc.value.fusion_info["default"]["tenants"] == len(RESP_TENANTS.items) - - if "tenant_spaces" in gather_subset or "all" in gather_subset: - api_obj.list_tenants.assert_called_with() - api_obj.list_tenant_spaces.assert_has_calls( - [call(tenant_name=tenant.name) for tenant in RESP_TENANTS.items], - any_order=True, - ) - assert "tenant_spaces" in exc.value.fusion_info - assert exc.value.fusion_info["tenant_spaces"] == { - tenant.name - + "/" - + ts.name: { - "tenant": tenant.name, - "display_name": ts.display_name, - } - for tenant in RESP_TENANTS.items - for ts in RESP_TS.items - } - elif "minimum" in gather_subset: - api_obj.list_tenants.assert_called_with() - api_obj.list_tenant_spaces.assert_has_calls( - [call(tenant_name=tenant.name) for tenant in RESP_TENANTS.items], - any_order=True, - ) - assert "default" in exc.value.fusion_info - assert "tenant_spaces" in exc.value.fusion_info["default"] - assert exc.value.fusion_info["default"]["tenant_spaces"] == len( - RESP_TENANTS.items - ) * len(RESP_TS.items) - - if "storage_endpoints" in gather_subset or "all" in gather_subset: - api_obj.list_regions.assert_called_with() - api_obj.list_availability_zones.assert_has_calls( - [call(region_name=region.name) for region in RESP_REGIONS.items], - any_order=True, - ) - api_obj.list_storage_endpoints.assert_has_calls( - [ - call( - availability_zone_name=az.name, - region_name=region.name, - ) - for region in RESP_REGIONS.items - for az in RESP_AZ.items - ], - any_order=True, - ) - assert "storage_endpoints" in exc.value.fusion_info - assert exc.value.fusion_info["storage_endpoints"] == { - region.name - + "/" - + az.name - + "/" - + endpoint.name: { - "display_name": endpoint.display_name, - "endpoint_type": endpoint.endpoint_type, - "iscsi_interfaces": [ - { - "address": iface.address, - "gateway": iface.gateway, - "mtu": iface.mtu, - "network_interface_groups": [ - nig.name for nig in iface.network_interface_groups - ], - } - for iface in endpoint.iscsi.discovery_interfaces - ], - } - for region in RESP_REGIONS.items - for az in RESP_AZ.items - for endpoint in RESP_SE.items - } - elif "minimum" in gather_subset: - api_obj.list_regions.assert_called_with() - api_obj.list_availability_zones.assert_has_calls( - [call(region_name=region.name) for region in RESP_REGIONS.items], - any_order=True, - ) - api_obj.list_storage_endpoints.assert_has_calls( - [ - call( - availability_zone_name=az.name, - region_name=region.name, - ) - for region in RESP_REGIONS.items - for az in RESP_AZ.items - ], - any_order=True, - ) - assert "default" in exc.value.fusion_info - assert "storage_endpoints" in exc.value.fusion_info["default"] - assert exc.value.fusion_info["default"]["storage_endpoints"] == len( - RESP_REGIONS.items - ) * len(RESP_AZ.items) * len(RESP_SE.items) - else: - api_obj.list_storage_endpoints.assert_not_called() - - if "api_clients" in gather_subset or "all" in gather_subset: - api_obj.list_api_clients.assert_called_with() - assert "api_clients" in exc.value.fusion_info - assert exc.value.fusion_info["api_clients"] == { - client.name: { - "display_name": client.display_name, - "issuer": client.issuer, - "public_key": client.public_key, - "creator_id": client.creator_id, - "last_key_update": "Thu, 18 May 2023 14:46:24 UTC", - "last_used": "Thu, 18 May 2023 14:48:10 UTC", - } - for client in RESP_AC - } - elif "minimum" in gather_subset: - # api_clients is not in default dict - api_obj.list_api_clients.assert_not_called() - assert "default" in exc.value.fusion_info - assert "api_clients" not in exc.value.fusion_info["default"] - else: - api_obj.list_api_clients.assert_not_called() - - if "snapshots" in gather_subset or "all" in gather_subset: - api_obj.list_tenants.assert_called_with() - api_obj.list_tenant_spaces.assert_has_calls( - [call(tenant_name=tenant.name) for tenant in RESP_TENANTS.items], - any_order=True, - ) - api_obj.list_snapshots.assert_has_calls( - [ - call( - tenant_name=tenant.name, - tenant_space_name=ts.name, - ) - for ts in RESP_TS.items - for tenant in RESP_TENANTS.items - ], - any_order=True, - ) - api_obj.list_volume_snapshots.assert_has_calls( - [ - call( - tenant_name=tenant.name, - tenant_space_name=ts.name, - snapshot_name=snap.name, - ) - for snap in RESP_SNAPSHOTS.items - for ts in RESP_TS.items - for tenant in RESP_TENANTS.items - ], - any_order=True, - ) - assert "snapshots" in exc.value.fusion_info - assert "volume_snapshots" in exc.value.fusion_info - assert exc.value.fusion_info["snapshots"] == { - tenant.name - + "/" - + ts.name - + "/" - + snap.name: { - "display_name": snap.display_name, - "protection_policy": snap.protection_policy, - "time_remaining": "0 hours, 0 mins, 23 secs", - "volume_snapshots_link": snap.volume_snapshots_link, - } - for snap in RESP_SNAPSHOTS.items - for ts in RESP_TS.items - for tenant in RESP_TENANTS.items - } - - assert exc.value.fusion_info["volume_snapshots"] == { - tenant.name - + "/" - + ts.name - + "/" - + snap.name - + "/" - + vsnap.name: { - "size": vsnap.size, - "display_name": vsnap.display_name, - "protection_policy": vsnap.protection_policy, - "serial_number": vsnap.serial_number, - "created_at": "Thu, 18 May 2023 14:46:24 UTC", - "time_remaining": "14 hours, 48 mins, 10 secs", - "placement_group": vsnap.placement_group.name, - } - for vsnap in RESP_VS.items - for snap in RESP_SNAPSHOTS.items - for ts in RESP_TS.items - for tenant in RESP_TENANTS.items - } - elif "minimum" in gather_subset: - api_obj.list_tenants.assert_called_with() - api_obj.list_tenant_spaces.assert_has_calls( - [call(tenant_name=tenant.name) for tenant in RESP_TENANTS.items], - any_order=True, - ) - api_obj.list_snapshots.assert_has_calls( - [ - call( - tenant_name=tenant.name, - tenant_space_name=ts.name, - ) - for ts in RESP_TS.items - for tenant in RESP_TENANTS.items - ], - any_order=True, - ) - api_obj.list_volume_snapshots.assert_not_called() - assert "default" in exc.value.fusion_info - assert "snapshots" in exc.value.fusion_info["default"] - assert exc.value.fusion_info["default"]["snapshots"] == len( - RESP_TENANTS.items - ) * len(RESP_TS.items) * len(RESP_SNAPSHOTS.items) - else: - api_obj.list_snapshots.assert_not_called() - api_obj.list_volume_snapshots.assert_not_called() - - if "network_interface_groups" in gather_subset or "all" in gather_subset: - api_obj.list_regions.assert_called_with() - api_obj.list_availability_zones.assert_has_calls( - [call(region_name=region.name) for region in RESP_REGIONS.items], - any_order=True, - ) - api_obj.list_network_interface_groups.assert_has_calls( - [ - call( - availability_zone_name=az.name, - region_name=region.name, - ) - for region in RESP_REGIONS.items - for az in RESP_AZ.items - ], - any_order=True, - ) - assert "network_interface_groups" in exc.value.fusion_info - assert exc.value.fusion_info["network_interface_groups"] == { - region.name - + "/" - + az.name - + "/" - + nig.name: { - "display_name": nig.display_name, - "gateway": nig.eth.gateway, - "prefix": nig.eth.prefix, - "mtu": nig.eth.mtu, - } - for nig in RESP_NIG.items - for region in RESP_REGIONS.items - for az in RESP_AZ.items - } - elif "minimum" in gather_subset: - api_obj.list_regions.assert_called_with() - api_obj.list_availability_zones.assert_has_calls( - [call(region_name=region.name) for region in RESP_REGIONS.items], - any_order=True, - ) - api_obj.list_network_interface_groups.assert_has_calls( - [ - call( - availability_zone_name=az.name, - region_name=region.name, - ) - for region in RESP_REGIONS.items - for az in RESP_AZ.items - ], - any_order=True, - ) - assert "default" in exc.value.fusion_info - assert "network_interface_groups" in exc.value.fusion_info["default"] - assert exc.value.fusion_info["default"]["network_interface_groups"] == len( - RESP_NIG.items - ) * len(RESP_REGIONS.items) * len(RESP_AZ.items) - else: - api_obj.list_network_interface_groups.assert_not_called() - - if "placement_groups" in gather_subset or "all" in gather_subset: - api_obj.list_tenants.assert_called_with() - api_obj.list_tenant_spaces.assert_has_calls( - [call(tenant_name=tenant.name) for tenant in RESP_TENANTS.items], - any_order=True, - ) - api_obj.list_volumes.list_placement_groups( - [ - call( - tenant_name=tenant.name, - tenant_space_name=ts.name, - ) - for ts in RESP_TS.items - for tenant in RESP_TENANTS.items - ], - any_order=True, - ) - assert "placement_groups" in exc.value.fusion_info - assert exc.value.fusion_info["placement_groups"] == { - tenant.name - + "/" - + ts.name - + "/" - + group.name: { - "tenant": group.tenant.name, - "display_name": group.display_name, - "placement_engine": group.placement_engine, - "tenant_space": group.tenant_space.name, - "az": group.availability_zone.name, - "array": getattr(group.array, "name", None), - } - for group in RESP_PG.items - for ts in RESP_TS.items - for tenant in RESP_TENANTS.items - } - elif "minimum" in gather_subset: - api_obj.list_tenants.assert_called_with() - api_obj.list_tenant_spaces.assert_has_calls( - [call(tenant_name=tenant.name) for tenant in RESP_TENANTS.items], - any_order=True, - ) - api_obj.list_volumes.list_placement_groups( - [ - call( - tenant_name=tenant.name, - tenant_space_name=ts.name, - ) - for ts in RESP_TS.items - for tenant in RESP_TENANTS.items - ], - any_order=True, - ) - assert "default" in exc.value.fusion_info - assert "placement_groups" in exc.value.fusion_info["default"] - assert exc.value.fusion_info["default"]["placement_groups"] == len( - RESP_PG.items - ) * len(RESP_TENANTS.items) * len(RESP_TS.items) - else: - api_obj.list_placement_groups.assert_not_called() - - if "regions" in gather_subset or "all" in gather_subset: - api_obj.list_regions.assert_called_with() - assert "regions" in exc.value.fusion_info - assert exc.value.fusion_info["regions"] == { - region.name: { - "display_name": region.display_name, - } - for region in RESP_REGIONS.items - } - elif "minimum" in gather_subset: - api_obj.list_regions.assert_called_with() - assert "default" in exc.value.fusion_info - assert "regions" in exc.value.fusion_info["default"] - assert exc.value.fusion_info["default"]["regions"] == len(RESP_REGIONS.items) - - -@patch("fusion.DefaultApi") -@patch("fusion.IdentityManagerApi") -@patch("fusion.ProtectionPoliciesApi") -@patch("fusion.HostAccessPoliciesApi") -@patch("fusion.HardwareTypesApi") -@patch("fusion.StorageServicesApi") -@patch("fusion.TenantsApi") -@patch("fusion.RegionsApi") -@patch("fusion.RolesApi") -@patch("fusion.StorageClassesApi") -@patch("fusion.RoleAssignmentsApi") -@patch("fusion.TenantSpacesApi") -@patch("fusion.VolumesApi") -@patch("fusion.VolumeSnapshotsApi") -@patch("fusion.PlacementGroupsApi") -@patch("fusion.SnapshotsApi") -@patch("fusion.AvailabilityZonesApi") -@patch("fusion.ArraysApi") -@patch("fusion.NetworkInterfaceGroupsApi") -@patch("fusion.StorageEndpointsApi") -@patch("fusion.NetworkInterfacesApi") -@pytest.mark.parametrize("subset", VALID_SUBSETS) -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, HTTPError), - (ApiExceptionsMockGenerator.create_permission_denied(), AnsibleExitJson), - ], -) -def test_info_exception( - # API mocks - m_ni_api, - m_se_api, - m_nig_api, - m_array_api, - m_az_api, - m_snapshot_api, - m_pg_api, - m_vs_api, - m_volume_api, - m_ts_api, - m_ra_api, - m_sc_api, - m_role_api, - m_region_api, - m_tenant_api, - m_ss_api, - m_hw_api, - m_hap_api, - m_pp_api, - m_im_api, - m_default_api, - # test parameter - subset, - # exceptions - exec_original, - exec_catch, -): - """ - Test that fusion_info propagates exceptions correctly. - """ - # NOTE: here we use the same MagicMock object for all APIs to make the test simpler, this has no harm to the logic of the test - api_obj = MagicMock() - api_obj.get_version = MagicMock( - return_value=RESP_VERSION, side_effect=exec_original - ) - api_obj.get_array_space = MagicMock(return_value=RESP_AS, side_effect=exec_original) - api_obj.get_array_performance = MagicMock( - return_value=RESP_AP, side_effect=exec_original - ) - api_obj.list_users = MagicMock(return_value=RESP_LU, side_effect=exec_original) - api_obj.list_protection_policies = MagicMock( - return_value=RESP_PP, side_effect=exec_original - ) - api_obj.list_host_access_policies = MagicMock( - return_value=RESP_HAP, side_effect=exec_original - ) - api_obj.list_hardware_types = MagicMock( - return_value=RESP_HT, side_effect=exec_original - ) - api_obj.list_storage_services = MagicMock( - return_value=RESP_SS, side_effect=exec_original - ) - api_obj.list_tenants = MagicMock( - return_value=RESP_TENANTS, side_effect=exec_original - ) - api_obj.list_regions = MagicMock( - return_value=RESP_REGIONS, side_effect=exec_original - ) - api_obj.list_roles = MagicMock(return_value=RESP_ROLES, side_effect=exec_original) - api_obj.list_storage_classes = MagicMock( - return_value=RESP_SC, side_effect=exec_original - ) - api_obj.list_role_assignments = MagicMock( - return_value=RESP_RA, side_effect=exec_original - ) - api_obj.list_tenant_spaces = MagicMock( - return_value=RESP_TS, side_effect=exec_original - ) - api_obj.list_volumes = MagicMock( - return_value=RESP_VOLUMES, side_effect=exec_original - ) - api_obj.list_placement_groups = MagicMock( - return_value=RESP_PG, side_effect=exec_original - ) - api_obj.list_snapshots = MagicMock( - return_value=RESP_SNAPSHOTS, side_effect=exec_original - ) - api_obj.list_availability_zones = MagicMock( - return_value=RESP_AZ, side_effect=exec_original - ) - api_obj.list_network_interface_groups = MagicMock( - return_value=RESP_NIG, side_effect=exec_original - ) - api_obj.list_storage_endpoints = MagicMock( - return_value=RESP_SE, side_effect=exec_original - ) - api_obj.list_network_interfaces = MagicMock( - return_value=RESP_NI, side_effect=exec_original - ) - api_obj.list_arrays = MagicMock(return_value=RESP_ARRAYS, side_effect=exec_original) - api_obj.list_api_clients = MagicMock( - return_value=RESP_AC, side_effect=exec_original - ) - api_obj.list_volume_snapshots = MagicMock( - return_value=RESP_VS, side_effect=exec_original - ) - m_ni_api.return_value = api_obj - m_se_api.return_value = api_obj - m_nig_api.return_value = api_obj - m_array_api.return_value = api_obj - m_az_api.return_value = api_obj - m_snapshot_api.return_value = api_obj - m_pg_api.return_value = api_obj - m_vs_api.return_value = api_obj - m_volume_api.return_value = api_obj - m_ts_api.return_value = api_obj - m_ra_api.return_value = api_obj - m_sc_api.return_value = api_obj - m_role_api.return_value = api_obj - m_region_api.return_value = api_obj - m_tenant_api.return_value = api_obj - m_ss_api.return_value = api_obj - m_hw_api.return_value = api_obj - m_hap_api.return_value = api_obj - m_pp_api.return_value = api_obj - m_im_api.return_value = api_obj - m_default_api.return_value = api_obj - - set_module_args( - { - "gather_subset": [subset], - "app_id": "ABCD1234", - "key_file": "private-key.pem", - } - ) - - with pytest.raises(exec_catch) as exc: - fusion_info.main() - - # in case of permission denied error, check correct output - if exec_catch == AnsibleExitJson: - assert exc.value.changed is False - - expected_keys = EXPECTED_KEYS[subset] - assert exc.value.fusion_info.keys() == expected_keys - for key in expected_keys: - if key == "default": - for k in exc.value.fusion_info[key]: - assert exc.value.fusion_info[key][k] is None - else: - assert exc.value.fusion_info[key] is None - - -@patch("fusion.StorageServicesApi") -def test_info_hidden_fields_storage_services(m_ss_api): - set_module_args( - { - "gather_subset": ["storage_services"], - "app_id": "ABCD1234", - "key_file": "private-key.pem", - } - ) - - response = purefusion.StorageServiceList( - count=1, - more_items_remaining=False, - items=[ - purefusion.StorageService( - id="503", - name="ss2", - self_link="self_link_value", - display_name="Storage Service 3", - hardware_types=None, # can be None if not enough permissions - ), - ], - ) - - api_obj = MagicMock() - api_obj.list_storage_services = MagicMock(return_value=response) - m_ss_api.return_value = api_obj - - with pytest.raises(AnsibleExitJson) as exc: - fusion_info.main() - - expected = { - "storage_services": { - service.name: { - "display_name": service.display_name, - "hardware_types": None, - } - for service in response.items - }, - } - assert exc.value.fusion_info == expected - - -@patch("fusion.RegionsApi") -@patch("fusion.AvailabilityZonesApi") -@patch("fusion.StorageEndpointsApi") -def test_info_hidden_fields_storage_endpoints(m_ss_api, m_az_api, m_region_api): - set_module_args( - { - "gather_subset": ["storage_endpoints"], - "app_id": "ABCD1234", - "key_file": "private-key.pem", - } - ) - - response = purefusion.StorageEndpointList( - count=1, - more_items_remaining=False, - items=[ - purefusion.StorageEndpoint( - id="541", - name="se1", - self_link="self_link_value", - display_name="Storage Endpoint 1", - region=purefusion.RegionRef( - id="542", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - availability_zone=purefusion.AvailabilityZoneRef( - id="543", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - endpoint_type="iscsi", - iscsi=purefusion.StorageEndpointIscsi( - discovery_interfaces=[ - purefusion.StorageEndpointIscsiDiscoveryInterface( - address="10.21.200.5/24", - gateway="10.21.200.0", - mtu=2000, - network_interface_groups=None, - ), - ] - ), - ) - ], - ) - - api_obj = MagicMock() - api_obj.list_regions = MagicMock(return_value=RESP_REGIONS) - api_obj.list_availability_zones = MagicMock(return_value=RESP_AZ) - api_obj.list_storage_endpoints = MagicMock(return_value=response) - m_ss_api.return_value = api_obj - m_az_api.return_value = api_obj - m_region_api.return_value = api_obj - - with pytest.raises(AnsibleExitJson) as exc: - fusion_info.main() - - expected = { - "storage_endpoints": { - region.name - + "/" - + az.name - + "/" - + endpoint.name: { - "display_name": endpoint.display_name, - "endpoint_type": endpoint.endpoint_type, - "iscsi_interfaces": [ - { - "address": iface.address, - "gateway": iface.gateway, - "mtu": iface.mtu, - "network_interface_groups": None, - } - for iface in endpoint.iscsi.discovery_interfaces - ], - } - for region in RESP_REGIONS.items - for az in RESP_AZ.items - for endpoint in response.items - }, - } - assert exc.value.fusion_info == expected - - -@patch("fusion.TenantsApi") -@patch("fusion.TenantSpacesApi") -@patch("fusion.VolumesApi") -def test_info_hidden_fields_volumes(m_ss_api, m_az_api, m_region_api): - set_module_args( - { - "gather_subset": ["volumes"], - "app_id": "ABCD1234", - "key_file": "private-key.pem", - } - ) - - response = purefusion.VolumeList( - count=1, - more_items_remaining=False, - items=[ - purefusion.Volume( - id="517", - name="volume1", - self_link="self_link_value", - display_name="Volume 1", - size=4000000, - tenant=purefusion.TenantRef( - id="518", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - tenant_space=purefusion.TenantSpaceRef( - id="519", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - storage_class=purefusion.StorageClassRef( - id="520", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - protection_policy=purefusion.ProtectionPolicyRef( - id="521", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - placement_group=purefusion.PlacementGroupRef( - id="522", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - array=None, - created_at=485743825, - source_volume_snapshot=purefusion.VolumeSnapshotRef( - id="523", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ), - host_access_policies=[ - purefusion.HostAccessPolicyRef( - id="524", - name="res_ref_name", - kind="kind_value", - self_link="self_link_value", - ) - ], - serial_number="123923482034", - target=purefusion.Target( - iscsi=purefusion.Iscsi( - iqn="iqn.2023-05.com.purestorage:420qp2c0222", - addresses=["125.1.2.4"], - ) - ), - time_remaining=1000000, - destroyed=False, - ) - ], - ) - - api_obj = MagicMock() - api_obj.list_tenants = MagicMock(return_value=RESP_TENANTS) - api_obj.list_tenant_spaces = MagicMock(return_value=RESP_TS) - api_obj.list_volumes = MagicMock(return_value=response) - m_ss_api.return_value = api_obj - m_az_api.return_value = api_obj - m_region_api.return_value = api_obj - - with pytest.raises(AnsibleExitJson) as exc: - fusion_info.main() - - expected = { - "volumes": { - tenant.name - + "/" - + tenant_space.name - + "/" - + volume.name: { - "tenant": tenant.name, - "tenant_space": tenant_space.name, - "name": volume.name, - "size": volume.size, - "display_name": volume.display_name, - "placement_group": volume.placement_group.name, - "source_volume_snapshot": getattr( - volume.source_volume_snapshot, "name", None - ), - "protection_policy": getattr(volume.protection_policy, "name", None), - "storage_class": volume.storage_class.name, - "serial_number": volume.serial_number, - "target": { - "iscsi": { - "addresses": volume.target.iscsi.addresses, - "iqn": volume.target.iscsi.iqn, - }, - "nvme": { - "addresses": None, - "nqn": None, - }, - "fc": { - "addresses": None, - "wwns": None, - }, - }, - "array": None, - } - for volume in response.items - for tenant_space in RESP_TS.items - for tenant in RESP_TENANTS.items - } - } - assert exc.value.fusion_info == expected - - -@patch("fusion.DefaultApi") -@patch("fusion.IdentityManagerApi") -@patch("fusion.ProtectionPoliciesApi") -@patch("fusion.HostAccessPoliciesApi") -@patch("fusion.HardwareTypesApi") -@patch("fusion.StorageServicesApi") -@patch("fusion.TenantsApi") -@patch("fusion.RegionsApi") -@patch("fusion.RolesApi") -@patch("fusion.StorageClassesApi") -@patch("fusion.RoleAssignmentsApi") -@patch("fusion.TenantSpacesApi") -@patch("fusion.VolumesApi") -@patch("fusion.VolumeSnapshotsApi") -@patch("fusion.PlacementGroupsApi") -@patch("fusion.SnapshotsApi") -@patch("fusion.AvailabilityZonesApi") -@patch("fusion.ArraysApi") -@patch("fusion.NetworkInterfaceGroupsApi") -@patch("fusion.StorageEndpointsApi") -@patch("fusion.NetworkInterfacesApi") -def test_info_permission_denied_minimum( - m_ni_api, - m_se_api, - m_nig_api, - m_array_api, - m_az_api, - m_snapshot_api, - m_pg_api, - m_vs_api, - m_volume_api, - m_ts_api, - m_ra_api, - m_sc_api, - m_role_api, - m_region_api, - m_tenant_api, - m_ss_api, - m_hw_api, - m_hap_api, - m_pp_api, - m_im_api, - m_default_api, -): - """ - Test that default dict works correctly with permission denied errors. - """ - exec = ApiExceptionsMockGenerator.create_permission_denied() - - api_obj = MagicMock() - api_obj.get_version = MagicMock(return_value=RESP_VERSION, side_effect=exec) - api_obj.get_array_space = MagicMock(return_value=RESP_AS, side_effect=exec) - api_obj.get_array_performance = MagicMock(return_value=RESP_AP, side_effect=exec) - api_obj.list_users = MagicMock(return_value=RESP_LU, side_effect=exec) - api_obj.list_protection_policies = MagicMock(return_value=RESP_PP, side_effect=exec) - api_obj.list_host_access_policies = MagicMock( - return_value=RESP_HAP, side_effect=exec - ) - api_obj.list_hardware_types = MagicMock(return_value=RESP_HT, side_effect=exec) - api_obj.list_storage_services = MagicMock(return_value=RESP_SS, side_effect=exec) - api_obj.list_tenants = MagicMock(return_value=RESP_TENANTS, side_effect=exec) - api_obj.list_regions = MagicMock(return_value=RESP_REGIONS, side_effect=exec) - api_obj.list_roles = MagicMock(return_value=RESP_ROLES, side_effect=exec) - api_obj.list_storage_classes = MagicMock(return_value=RESP_SC, side_effect=exec) - api_obj.list_role_assignments = MagicMock(return_value=RESP_RA, side_effect=exec) - api_obj.list_tenant_spaces = MagicMock(return_value=RESP_TS, side_effect=exec) - api_obj.list_volumes = MagicMock(return_value=RESP_VOLUMES, side_effect=exec) - api_obj.list_placement_groups = MagicMock(return_value=RESP_PG, side_effect=exec) - api_obj.list_snapshots = MagicMock(return_value=RESP_SNAPSHOTS, side_effect=exec) - api_obj.list_availability_zones = MagicMock(return_value=RESP_AZ, side_effect=exec) - api_obj.list_network_interface_groups = MagicMock( - return_value=RESP_NIG, side_effect=exec - ) - api_obj.list_storage_endpoints = MagicMock(return_value=RESP_SE, side_effect=exec) - api_obj.list_network_interfaces = MagicMock(return_value=RESP_NI, side_effect=exec) - api_obj.list_arrays = MagicMock(return_value=RESP_ARRAYS, side_effect=exec) - api_obj.list_api_clients = MagicMock(return_value=RESP_AC, side_effect=exec) - api_obj.list_volume_snapshots = MagicMock(return_value=RESP_VS, side_effect=exec) - m_ni_api.return_value = api_obj - m_se_api.return_value = api_obj - m_nig_api.return_value = api_obj - m_array_api.return_value = api_obj - m_az_api.return_value = api_obj - m_snapshot_api.return_value = api_obj - m_pg_api.return_value = api_obj - m_vs_api.return_value = api_obj - m_volume_api.return_value = api_obj - m_ts_api.return_value = api_obj - m_ra_api.return_value = api_obj - m_sc_api.return_value = api_obj - m_role_api.return_value = api_obj - m_region_api.return_value = api_obj - m_tenant_api.return_value = api_obj - m_ss_api.return_value = api_obj - m_hw_api.return_value = api_obj - m_hap_api.return_value = api_obj - m_pp_api.return_value = api_obj - m_im_api.return_value = api_obj - m_default_api.return_value = api_obj - - set_module_args( - { - "gather_subset": ["minimum"], - "app_id": "ABCD1234", - "key_file": "private-key.pem", - } - ) - - with pytest.raises(AnsibleExitJson) as exc: - fusion_info.main() - - assert exc.value.changed is False - assert "default" in exc.value.fusion_info - assert { - "version": None, - "users": None, - "protection_policies": None, - "host_access_policies": None, - "hardware_types": None, - "storage_services": None, - "tenants": None, - "regions": None, - "storage_classes": None, - "roles": None, - "role_assignments": None, - "tenant_spaces": None, - "volumes": None, - "placement_groups": None, - "snapshots": None, - "availability_zones": None, - "arrays": None, - "network_interfaces": None, - "network_interface_groups": None, - "storage_endpoints": None, - } == exc.value.fusion_info["default"] diff --git a/ansible_collections/purestorage/fusion/tests/functional/test_fusion_nig.py b/ansible_collections/purestorage/fusion/tests/functional/test_fusion_nig.py deleted file mode 100644 index e8a2eb0ac..000000000 --- a/ansible_collections/purestorage/fusion/tests/functional/test_fusion_nig.py +++ /dev/null @@ -1,1244 +0,0 @@ -# -*- coding: utf-8 -*- - -# (c) 2023, Andrej Pajtas (apajtas@purestorage.com) -# GNU General Public License v3.0+ (see COPYING.GPLv3 or https://www.gnu.org/licenses/gpl-3.0.txt) - -from __future__ import absolute_import, division, print_function - -__metaclass__ = type - -from unittest.mock import MagicMock, patch - -import fusion as purefusion -import pytest -from ansible.module_utils import basic -from ansible_collections.purestorage.fusion.plugins.module_utils.errors import ( - OperationException, -) -from ansible_collections.purestorage.fusion.plugins.modules import fusion_nig -from ansible_collections.purestorage.fusion.tests.functional.utils import ( - AnsibleExitJson, - AnsibleFailJson, - FailedOperationMock, - OperationMock, - SuccessfulOperationMock, - FAKE_RESOURCE_ID, - exit_json, - fail_json, - set_module_args, -) -from urllib3.exceptions import HTTPError - -# GLOBAL MOCKS -fusion_nig.setup_fusion = MagicMock(return_value=purefusion.api_client.ApiClient()) -purefusion.api_client.ApiClient.call_api = MagicMock( - side_effect=Exception("API call not mocked!") -) -basic.AnsibleModule.exit_json = exit_json -basic.AnsibleModule.fail_json = fail_json - - -@patch("fusion.OperationsApi") -@patch("fusion.NetworkInterfaceGroupsApi") -@pytest.mark.parametrize( - "module_args", - [ - # required parameter 'name` is missing - { - "state": "present", - "display_name": "Network Interface Group 1", - "availability_zone": "az1", - "region": "region1", - "prefix": "10.21.200.0/24", - "gateway": "10.21.200.1", - "mtu": 1300, - "group_type": "eth", - "app_id": "ABCD1234", - "key_file": "private-key.pem", - }, - # required parameter 'availability_zone` is missing - { - "state": "present", - "name": "nig1", - "display_name": "Network Interface Group 1", - "region": "region1", - "prefix": "10.21.200.0/24", - "gateway": "10.21.200.1", - "mtu": 1300, - "group_type": "eth", - "app_id": "ABCD1234", - "key_file": "private-key.pem", - }, - # required parameter 'region` is missing - { - "state": "present", - "name": "nig1", - "display_name": "Network Interface Group 1", - "availability_zone": "az1", - "prefix": "10.21.200.0/24", - "gateway": "10.21.200.1", - "mtu": 1300, - "group_type": "eth", - "app_id": "ABCD1234", - "key_file": "private-key.pem", - }, - # unknown parameter 'extra' is provided - { - "state": "present", - "name": "nig1", - "display_name": "Network Interface Group 1", - "app_id": "ABCD1234", - "key_file": "private-key.pem", - "extra": "value", - }, - # parameter 'state` has incorrect value - { - "state": "cool", - "name": "nig1", - "display_name": "Network Interface Group 1", - "availability_zone": "az1", - "region": "region1", - "prefix": "10.21.200.0/24", - "gateway": "10.21.200.1", - "mtu": 1300, - "group_type": "eth", - "app_id": "ABCD1234", - "key_file": "private-key.pem", - }, - # parameter 'group_type` has incorrect value - { - "state": "present", - "name": "nig1", - "display_name": "Network Interface Group 1", - "availability_zone": "az1", - "region": "region1", - "prefix": "10.21.200.0/24", - "gateway": "10.21.200.1", - "mtu": 1300, - "group_type": "supergroup", - "app_id": "ABCD1234", - "key_file": "private-key.pem", - }, - ], -) -def test_module_fails_on_wrong_parameters(m_nig_api, m_op_api, module_args): - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_network_interface_group = MagicMock( - side_effect=purefusion.rest.ApiException - ) - api_obj.create_network_interface_group = MagicMock(return_value=OperationMock(1)) - api_obj.update_network_interface_group = MagicMock(return_value=OperationMock(2)) - api_obj.delete_network_interface_group = MagicMock(return_value=OperationMock(3)) - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - m_nig_api.return_value = api_obj - - # run module - with pytest.raises(AnsibleFailJson): - fusion_nig.main() - - # check api was not called at all - api_obj.get_network_interface_group.assert_not_called() - api_obj.create_network_interface_group.assert_not_called() - api_obj.update_network_interface_group.assert_not_called() - api_obj.delete_network_interface_group.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.NetworkInterfaceGroupsApi") -def test_nig_create_fails_on_missing_prefix(m_nig_api, m_op_api): - module_args = { - "state": "present", - "name": "nig1", - "display_name": "Network Interface Group 1", - "availability_zone": "az1", - "region": "region1", - "gateway": "10.21.200.1", - "mtu": 1300, - "group_type": "eth", - "app_id": "ABCD1234", - "key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_network_interface_group = MagicMock( - side_effect=purefusion.rest.ApiException - ) - api_obj.create_network_interface_group = MagicMock(return_value=OperationMock(1)) - api_obj.update_network_interface_group = MagicMock(return_value=OperationMock(2)) - api_obj.delete_network_interface_group = MagicMock(return_value=OperationMock(3)) - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - m_nig_api.return_value = api_obj - - # run module - with pytest.raises(AnsibleFailJson): - fusion_nig.main() - - # check api was not called at all - api_obj.get_network_interface_group.assert_called_once_with( - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - network_interface_group_name=module_args["name"], - ) - api_obj.create_network_interface_group.assert_not_called() - api_obj.update_network_interface_group.assert_not_called() - api_obj.delete_network_interface_group.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.NetworkInterfaceGroupsApi") -def test_nig_create(m_nig_api, m_op_api): - module_args = { - "state": "present", - "name": "nig1", - "display_name": "Network Interface Group 1", - "availability_zone": "az1", - "region": "region1", - "prefix": "10.21.200.0/24", - "gateway": "10.21.200.1", - "mtu": 1300, - "group_type": "eth", - "app_id": "ABCD1234", - "key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_network_interface_group = MagicMock( - side_effect=purefusion.rest.ApiException - ) - api_obj.create_network_interface_group = MagicMock(return_value=OperationMock(1)) - api_obj.update_network_interface_group = MagicMock(return_value=OperationMock(2)) - api_obj.delete_network_interface_group = MagicMock(return_value=OperationMock(3)) - m_nig_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_nig.main() - - assert exc.value.changed is True - assert exc.value.id == FAKE_RESOURCE_ID - - # check api was called correctly - api_obj.get_network_interface_group.assert_called_once_with( - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - network_interface_group_name=module_args["name"], - ) - api_obj.create_network_interface_group.assert_called_once_with( - purefusion.NetworkInterfaceGroupPost( - group_type="eth", - eth=purefusion.NetworkInterfaceGroupEthPost( - prefix=module_args["prefix"], - gateway=module_args["gateway"], - mtu=module_args["mtu"], - ), - name=module_args["name"], - display_name=module_args["display_name"], - ), - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - ) - api_obj.update_network_interface_group.assert_not_called() - api_obj.delete_network_interface_group.assert_not_called() - op_obj.get_operation.assert_called_once_with(1) - - -@patch("fusion.OperationsApi") -@patch("fusion.NetworkInterfaceGroupsApi") -def test_nig_create_without_display_name(m_nig_api, m_op_api): - module_args = { - "state": "present", - "name": "nig1", - "availability_zone": "az1", - "region": "region1", - "prefix": "10.21.200.0/24", - "gateway": "10.21.200.1", - "mtu": 1300, - "group_type": "eth", - "app_id": "ABCD1234", - "key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_network_interface_group = MagicMock( - side_effect=purefusion.rest.ApiException - ) - api_obj.create_network_interface_group = MagicMock(return_value=OperationMock(1)) - api_obj.update_network_interface_group = MagicMock(return_value=OperationMock(2)) - api_obj.delete_network_interface_group = MagicMock(return_value=OperationMock(3)) - m_nig_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_nig.main() - - assert exc.value.changed is True - assert exc.value.id == FAKE_RESOURCE_ID - - # check api was called correctly - api_obj.get_network_interface_group.assert_called_once_with( - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - network_interface_group_name=module_args["name"], - ) - api_obj.create_network_interface_group.assert_called_once_with( - purefusion.NetworkInterfaceGroupPost( - group_type="eth", - eth=purefusion.NetworkInterfaceGroupEthPost( - prefix=module_args["prefix"], - gateway=module_args["gateway"], - mtu=module_args["mtu"], - ), - name=module_args["name"], - display_name=module_args["name"], - ), - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - ) - api_obj.update_network_interface_group.assert_not_called() - api_obj.delete_network_interface_group.assert_not_called() - op_obj.get_operation.assert_called_once_with(1) - - -@patch("fusion.OperationsApi") -@patch("fusion.NetworkInterfaceGroupsApi") -def test_nig_create_without_gateway(m_nig_api, m_op_api): - module_args = { - "state": "present", - "name": "nig1", - "display_name": "Network Interface Group 1", - "availability_zone": "az1", - "region": "region1", - "prefix": "10.21.200.0/24", - "mtu": 1300, - "group_type": "eth", - "app_id": "ABCD1234", - "key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_network_interface_group = MagicMock( - side_effect=purefusion.rest.ApiException - ) - api_obj.create_network_interface_group = MagicMock(return_value=OperationMock(1)) - api_obj.update_network_interface_group = MagicMock(return_value=OperationMock(2)) - api_obj.delete_network_interface_group = MagicMock(return_value=OperationMock(3)) - m_nig_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_nig.main() - - assert exc.value.changed is True - assert exc.value.id == FAKE_RESOURCE_ID - - # check api was called correctly - api_obj.get_network_interface_group.assert_called_once_with( - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - network_interface_group_name=module_args["name"], - ) - api_obj.create_network_interface_group.assert_called_once_with( - purefusion.NetworkInterfaceGroupPost( - group_type="eth", - eth=purefusion.NetworkInterfaceGroupEthPost( - prefix=module_args["prefix"], - mtu=module_args["mtu"], - ), - name=module_args["name"], - display_name=module_args["display_name"], - ), - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - ) - api_obj.update_network_interface_group.assert_not_called() - api_obj.delete_network_interface_group.assert_not_called() - op_obj.get_operation.assert_called_once_with(1) - - -@patch("fusion.OperationsApi") -@patch("fusion.NetworkInterfaceGroupsApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, HTTPError), - ], -) -def test_nig_create_exception(m_nig_api, m_op_api, exec_original, exec_catch): - module_args = { - "state": "present", - "name": "nig1", - "display_name": "Network Interface Group 1", - "availability_zone": "az1", - "region": "region1", - "prefix": "10.21.200.0/24", - "mtu": 1300, - "group_type": "eth", - "app_id": "ABCD1234", - "key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_network_interface_group = MagicMock( - side_effect=purefusion.rest.ApiException - ) - api_obj.create_network_interface_group = MagicMock(side_effect=exec_original) - api_obj.update_network_interface_group = MagicMock(return_value=OperationMock(2)) - api_obj.delete_network_interface_group = MagicMock(return_value=OperationMock(3)) - m_nig_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_nig.main() - - # check api was called correctly - api_obj.get_network_interface_group.assert_called_once_with( - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - network_interface_group_name=module_args["name"], - ) - api_obj.create_network_interface_group.assert_called_once_with( - purefusion.NetworkInterfaceGroupPost( - group_type="eth", - eth=purefusion.NetworkInterfaceGroupEthPost( - prefix=module_args["prefix"], - mtu=module_args["mtu"], - ), - name=module_args["name"], - display_name=module_args["display_name"], - ), - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - ) - api_obj.update_network_interface_group.assert_not_called() - api_obj.delete_network_interface_group.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.NetworkInterfaceGroupsApi") -def test_nig_create_op_fails(m_nig_api, m_op_api): - module_args = { - "state": "present", - "name": "nig1", - "display_name": "Network Interface Group 1", - "availability_zone": "az1", - "region": "region1", - "prefix": "10.21.200.0/24", - "mtu": 1300, - "group_type": "eth", - "app_id": "ABCD1234", - "key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_network_interface_group = MagicMock( - side_effect=purefusion.rest.ApiException - ) - api_obj.create_network_interface_group = MagicMock(return_value=OperationMock(1)) - api_obj.update_network_interface_group = MagicMock(return_value=OperationMock(2)) - api_obj.delete_network_interface_group = MagicMock(return_value=OperationMock(3)) - m_nig_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(OperationException): - fusion_nig.main() - - # check api was called correctly - api_obj.get_network_interface_group.assert_called_once_with( - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - network_interface_group_name=module_args["name"], - ) - api_obj.create_network_interface_group.assert_called_once_with( - purefusion.NetworkInterfaceGroupPost( - group_type="eth", - eth=purefusion.NetworkInterfaceGroupEthPost( - prefix=module_args["prefix"], - mtu=module_args["mtu"], - ), - name=module_args["name"], - display_name=module_args["display_name"], - ), - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - ) - api_obj.update_network_interface_group.assert_not_called() - api_obj.delete_network_interface_group.assert_not_called() - op_obj.get_operation.assert_called_once_with(1) - - -@patch("fusion.OperationsApi") -@patch("fusion.NetworkInterfaceGroupsApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, OperationException), - ], -) -def test_nig_create_op_exception(m_nig_api, m_op_api, exec_original, exec_catch): - module_args = { - "state": "present", - "name": "nig1", - "display_name": "Network Interface Group 1", - "availability_zone": "az1", - "region": "region1", - "prefix": "10.21.200.0/24", - "mtu": 1300, - "group_type": "eth", - "app_id": "ABCD1234", - "key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_network_interface_group = MagicMock( - side_effect=purefusion.rest.ApiException - ) - api_obj.create_network_interface_group = MagicMock(return_value=OperationMock(1)) - api_obj.update_network_interface_group = MagicMock(return_value=OperationMock(2)) - api_obj.delete_network_interface_group = MagicMock(return_value=OperationMock(3)) - m_nig_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(side_effect=exec_original) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_nig.main() - - # check api was called correctly - api_obj.get_network_interface_group.assert_called_once_with( - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - network_interface_group_name=module_args["name"], - ) - api_obj.create_network_interface_group.assert_called_once_with( - purefusion.NetworkInterfaceGroupPost( - group_type="eth", - eth=purefusion.NetworkInterfaceGroupEthPost( - prefix=module_args["prefix"], - mtu=module_args["mtu"], - ), - name=module_args["name"], - display_name=module_args["display_name"], - ), - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - ) - api_obj.update_network_interface_group.assert_not_called() - api_obj.delete_network_interface_group.assert_not_called() - op_obj.get_operation.assert_called_once_with(1) - - -@patch("fusion.OperationsApi") -@patch("fusion.NetworkInterfaceGroupsApi") -def test_nig_update(m_nig_api, m_op_api): - current_nig = purefusion.NetworkInterfaceGroup( - id="1", - self_link="self_link_value", - name="nig1", - display_name=None, - region="region1", - availability_zone="az1", - group_type="eth", - eth=purefusion.NetworkInterfaceGroupEth( - prefix="str", - gateway="str", - vlan=3, - mtu=1300, - ), - ) - module_args = { - "state": "present", - "name": current_nig.name, # must match - "display_name": "New Name", # should be updated - "availability_zone": current_nig.availability_zone, # must match - "region": current_nig.region, # must match - "prefix": "12.19.150.0/23", # should not be updated - "mtu": current_nig.eth.mtu + 100, # should not be updated - "group_type": "eth", - "app_id": "ABCD1234", - "key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_network_interface_group = MagicMock(return_value=current_nig) - api_obj.create_network_interface_group = MagicMock(return_value=OperationMock(1)) - api_obj.update_network_interface_group = MagicMock(return_value=OperationMock(2)) - api_obj.delete_network_interface_group = MagicMock(return_value=OperationMock(3)) - m_nig_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_nig.main() - - assert exc.value.changed is True - assert exc.value.id == current_nig.id - - # check api was called correctly - api_obj.get_network_interface_group.assert_called_once_with( - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - network_interface_group_name=module_args["name"], - ) - api_obj.create_network_interface_group.assert_not_called() - api_obj.update_network_interface_group.assert_called_once_with( - purefusion.NetworkInterfaceGroupPatch( - display_name=purefusion.NullableString(module_args["display_name"]), - ), - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - network_interface_group_name=module_args["name"], - ) - api_obj.delete_network_interface_group.assert_not_called() - op_obj.get_operation.assert_called_once_with(2) - - -@patch("fusion.OperationsApi") -@patch("fusion.NetworkInterfaceGroupsApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, HTTPError), - ], -) -def test_nig_update_exception(m_nig_api, m_op_api, exec_original, exec_catch): - current_nig = purefusion.NetworkInterfaceGroup( - id="1", - self_link="self_link_value", - name="nig1", - display_name=None, - region="region1", - availability_zone="az1", - group_type="eth", - eth=purefusion.NetworkInterfaceGroupEth( - prefix="str", - gateway="str", - vlan=3, - mtu=1300, - ), - ) - module_args = { - "state": "present", - "name": current_nig.name, # must match - "display_name": "New Name", # should be updated - "availability_zone": current_nig.availability_zone, # must match - "region": current_nig.region, # must match - "prefix": "12.19.150.0/23", # should not be updated - "mtu": current_nig.eth.mtu + 100, # should not be updated - "group_type": "eth", - "app_id": "ABCD1234", - "key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_network_interface_group = MagicMock(return_value=current_nig) - api_obj.create_network_interface_group = MagicMock(return_value=OperationMock(1)) - api_obj.update_network_interface_group = MagicMock(side_effect=exec_original) - api_obj.delete_network_interface_group = MagicMock(return_value=OperationMock(3)) - m_nig_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_nig.main() - - # check api was called correctly - api_obj.get_network_interface_group.assert_called_once_with( - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - network_interface_group_name=module_args["name"], - ) - api_obj.create_network_interface_group.assert_not_called() - api_obj.update_network_interface_group.assert_called_once_with( - purefusion.NetworkInterfaceGroupPatch( - display_name=purefusion.NullableString(module_args["display_name"]), - ), - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - network_interface_group_name=module_args["name"], - ) - api_obj.delete_network_interface_group.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.NetworkInterfaceGroupsApi") -def test_nig_update_op_fails(m_nig_api, m_op_api): - current_nig = purefusion.NetworkInterfaceGroup( - id="1", - self_link="self_link_value", - name="nig1", - display_name=None, - region="region1", - availability_zone="az1", - group_type="eth", - eth=purefusion.NetworkInterfaceGroupEth( - prefix="str", - gateway="str", - vlan=3, - mtu=1300, - ), - ) - module_args = { - "state": "present", - "name": current_nig.name, # must match - "display_name": "New Name", # should be updated - "availability_zone": current_nig.availability_zone, # must match - "region": current_nig.region, # must match - "prefix": "12.19.150.0/23", # should not be updated - "mtu": current_nig.eth.mtu + 100, # should not be updated - "group_type": "eth", - "app_id": "ABCD1234", - "key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_network_interface_group = MagicMock(return_value=current_nig) - api_obj.create_network_interface_group = MagicMock(return_value=OperationMock(1)) - api_obj.update_network_interface_group = MagicMock(return_value=OperationMock(2)) - api_obj.delete_network_interface_group = MagicMock(return_value=OperationMock(3)) - m_nig_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(OperationException): - fusion_nig.main() - - # check api was called correctly - api_obj.get_network_interface_group.assert_called_once_with( - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - network_interface_group_name=module_args["name"], - ) - api_obj.create_network_interface_group.assert_not_called() - api_obj.update_network_interface_group.assert_called_once_with( - purefusion.NetworkInterfaceGroupPatch( - display_name=purefusion.NullableString(module_args["display_name"]), - ), - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - network_interface_group_name=module_args["name"], - ) - api_obj.delete_network_interface_group.assert_not_called() - op_obj.get_operation.assert_called_once_with(2) - - -@patch("fusion.OperationsApi") -@patch("fusion.NetworkInterfaceGroupsApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, OperationException), - ], -) -def test_nig_update_op_exception(m_nig_api, m_op_api, exec_original, exec_catch): - current_nig = purefusion.NetworkInterfaceGroup( - id="1", - self_link="self_link_value", - name="nig1", - display_name=None, - region="region1", - availability_zone="az1", - group_type="eth", - eth=purefusion.NetworkInterfaceGroupEth( - prefix="str", - gateway="str", - vlan=3, - mtu=1300, - ), - ) - module_args = { - "state": "present", - "name": current_nig.name, # must match - "display_name": "New Name", # should be updated - "availability_zone": current_nig.availability_zone, # must match - "region": current_nig.region, # must match - "prefix": "12.19.150.0/23", # should not be updated - "mtu": current_nig.eth.mtu + 100, # should not be updated - "group_type": "eth", - "app_id": "ABCD1234", - "key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_network_interface_group = MagicMock(return_value=current_nig) - api_obj.create_network_interface_group = MagicMock(return_value=OperationMock(1)) - api_obj.update_network_interface_group = MagicMock(return_value=OperationMock(2)) - api_obj.delete_network_interface_group = MagicMock(return_value=OperationMock(3)) - m_nig_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(side_effect=exec_original) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_nig.main() - - # check api was called correctly - api_obj.get_network_interface_group.assert_called_once_with( - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - network_interface_group_name=module_args["name"], - ) - api_obj.create_network_interface_group.assert_not_called() - api_obj.update_network_interface_group.assert_called_once_with( - purefusion.NetworkInterfaceGroupPatch( - display_name=purefusion.NullableString(module_args["display_name"]), - ), - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - network_interface_group_name=module_args["name"], - ) - api_obj.delete_network_interface_group.assert_not_called() - op_obj.get_operation.assert_called_once_with(2) - - -@patch("fusion.OperationsApi") -@patch("fusion.NetworkInterfaceGroupsApi") -def test_nig_present_not_changed(m_nig_api, m_op_api): - current_nig = purefusion.NetworkInterfaceGroup( - id="1", - self_link="self_link_value", - name="nig1", - display_name="Display Name", - region="region1", - availability_zone="az1", - group_type="eth", - eth=purefusion.NetworkInterfaceGroupEth( - prefix="str", - gateway="str", - vlan=3, - mtu=1300, - ), - ) - module_args = { - "state": "present", - "name": current_nig.name, # must match - "display_name": current_nig.display_name, # should not be updated - "availability_zone": current_nig.availability_zone, # must match - "region": current_nig.region, # must match - "prefix": "12.19.150.0/23", # should not be updated - "mtu": current_nig.eth.mtu + 100, # should not be updated - "group_type": "eth", - "app_id": "ABCD1234", - "key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_network_interface_group = MagicMock(return_value=current_nig) - api_obj.create_network_interface_group = MagicMock(return_value=OperationMock(1)) - api_obj.update_network_interface_group = MagicMock(return_value=OperationMock(2)) - api_obj.delete_network_interface_group = MagicMock(return_value=OperationMock(3)) - m_nig_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_nig.main() - - assert exc.value.changed is False - - # check api was called correctly - api_obj.get_network_interface_group.assert_called_once_with( - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - network_interface_group_name=module_args["name"], - ) - api_obj.create_network_interface_group.assert_not_called() - api_obj.update_network_interface_group.assert_not_called() - api_obj.delete_network_interface_group.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.NetworkInterfaceGroupsApi") -def test_nig_absent_not_changed(m_nig_api, m_op_api): - module_args = { - "state": "absent", - "name": "nig1", - "display_name": "Network Interface Group 1", - "availability_zone": "az1", - "region": "region1", - "app_id": "ABCD1234", - "key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_network_interface_group = MagicMock( - side_effect=purefusion.rest.ApiException - ) - api_obj.create_network_interface_group = MagicMock(return_value=OperationMock(1)) - api_obj.update_network_interface_group = MagicMock(return_value=OperationMock(2)) - api_obj.delete_network_interface_group = MagicMock(return_value=OperationMock(3)) - m_nig_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_nig.main() - - assert exc.value.changed is False - - # check api was called correctly - api_obj.get_network_interface_group.assert_called_once_with( - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - network_interface_group_name=module_args["name"], - ) - api_obj.create_network_interface_group.assert_not_called() - api_obj.update_network_interface_group.assert_not_called() - api_obj.delete_network_interface_group.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.NetworkInterfaceGroupsApi") -def test_nig_delete(m_nig_api, m_op_api): - current_nig = purefusion.NetworkInterfaceGroup( - id="1", - self_link="self_link_value", - name="nig1", - display_name="Display Name", - region="region1", - availability_zone="az1", - group_type="eth", - eth=purefusion.NetworkInterfaceGroupEth( - prefix="str", - gateway="str", - vlan=3, - mtu=1300, - ), - ) - module_args = { - "state": "absent", - "name": current_nig.name, # must match - "availability_zone": current_nig.availability_zone, # must match - "region": current_nig.region, # must match - "app_id": "ABCD1234", - "key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_network_interface_group = MagicMock(return_value=current_nig) - api_obj.create_network_interface_group = MagicMock(return_value=OperationMock(1)) - api_obj.update_network_interface_group = MagicMock(return_value=OperationMock(2)) - api_obj.delete_network_interface_group = MagicMock(return_value=OperationMock(3)) - m_nig_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_nig.main() - - assert exc.value.changed is True - - # check api was called correctly - api_obj.get_network_interface_group.assert_called_once_with( - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - network_interface_group_name=module_args["name"], - ) - api_obj.create_network_interface_group.assert_not_called() - api_obj.update_network_interface_group.assert_not_called() - api_obj.delete_network_interface_group.assert_called_once_with( - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - network_interface_group_name=module_args["name"], - ) - op_obj.get_operation.assert_called_once_with(3) - - -@patch("fusion.OperationsApi") -@patch("fusion.NetworkInterfaceGroupsApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, HTTPError), - ], -) -def test_nig_delete_exception(m_nig_api, m_op_api, exec_original, exec_catch): - current_nig = purefusion.NetworkInterfaceGroup( - id="1", - self_link="self_link_value", - name="nig1", - display_name="Display Name", - region="region1", - availability_zone="az1", - group_type="eth", - eth=purefusion.NetworkInterfaceGroupEth( - prefix="str", - gateway="str", - vlan=3, - mtu=1300, - ), - ) - module_args = { - "state": "absent", - "name": current_nig.name, # must match - "availability_zone": current_nig.availability_zone, # must match - "region": current_nig.region, # must match - "app_id": "ABCD1234", - "key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_network_interface_group = MagicMock(return_value=current_nig) - api_obj.create_network_interface_group = MagicMock(return_value=OperationMock(1)) - api_obj.update_network_interface_group = MagicMock(return_value=OperationMock(2)) - api_obj.delete_network_interface_group = MagicMock(side_effect=exec_original) - m_nig_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_nig.main() - - # check api was called correctly - api_obj.get_network_interface_group.assert_called_once_with( - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - network_interface_group_name=module_args["name"], - ) - api_obj.create_network_interface_group.assert_not_called() - api_obj.update_network_interface_group.assert_not_called() - api_obj.delete_network_interface_group.assert_called_once_with( - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - network_interface_group_name=module_args["name"], - ) - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.NetworkInterfaceGroupsApi") -def test_nig_delete_op_fails(m_nig_api, m_op_api): - current_nig = purefusion.NetworkInterfaceGroup( - id="1", - self_link="self_link_value", - name="nig1", - display_name="Display Name", - region="region1", - availability_zone="az1", - group_type="eth", - eth=purefusion.NetworkInterfaceGroupEth( - prefix="str", - gateway="str", - vlan=3, - mtu=1300, - ), - ) - module_args = { - "state": "absent", - "name": current_nig.name, # must match - "availability_zone": current_nig.availability_zone, # must match - "region": current_nig.region, # must match - "app_id": "ABCD1234", - "key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_network_interface_group = MagicMock(return_value=current_nig) - api_obj.create_network_interface_group = MagicMock(return_value=OperationMock(1)) - api_obj.update_network_interface_group = MagicMock(return_value=OperationMock(2)) - api_obj.delete_network_interface_group = MagicMock(return_value=OperationMock(3)) - m_nig_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(OperationException): - fusion_nig.main() - - # check api was called correctly - api_obj.get_network_interface_group.assert_called_once_with( - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - network_interface_group_name=module_args["name"], - ) - api_obj.create_network_interface_group.assert_not_called() - api_obj.update_network_interface_group.assert_not_called() - api_obj.delete_network_interface_group.assert_called_once_with( - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - network_interface_group_name=module_args["name"], - ) - op_obj.get_operation.assert_called_once_with(3) - - -@patch("fusion.OperationsApi") -@patch("fusion.NetworkInterfaceGroupsApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, OperationException), - ], -) -def test_nig_delete_op_exception(m_nig_api, m_op_api, exec_original, exec_catch): - current_nig = purefusion.NetworkInterfaceGroup( - id="1", - self_link="self_link_value", - name="nig1", - display_name="Display Name", - region="region1", - availability_zone="az1", - group_type="eth", - eth=purefusion.NetworkInterfaceGroupEth( - prefix="str", - gateway="str", - vlan=3, - mtu=1300, - ), - ) - module_args = { - "state": "absent", - "name": current_nig.name, # must match - "availability_zone": current_nig.availability_zone, # must match - "region": current_nig.region, # must match - "app_id": "ABCD1234", - "key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_network_interface_group = MagicMock(return_value=current_nig) - api_obj.create_network_interface_group = MagicMock(return_value=OperationMock(1)) - api_obj.update_network_interface_group = MagicMock(return_value=OperationMock(2)) - api_obj.delete_network_interface_group = MagicMock(return_value=OperationMock(3)) - m_nig_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(side_effect=exec_original) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_nig.main() - - # check api was called correctly - api_obj.get_network_interface_group.assert_called_once_with( - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - network_interface_group_name=module_args["name"], - ) - api_obj.create_network_interface_group.assert_not_called() - api_obj.update_network_interface_group.assert_not_called() - api_obj.delete_network_interface_group.assert_called_once_with( - availability_zone_name=module_args["availability_zone"], - region_name=module_args["region"], - network_interface_group_name=module_args["name"], - ) - op_obj.get_operation.assert_called_once_with(3) diff --git a/ansible_collections/purestorage/fusion/tests/functional/test_fusion_pg.py b/ansible_collections/purestorage/fusion/tests/functional/test_fusion_pg.py deleted file mode 100644 index 2a9419a8e..000000000 --- a/ansible_collections/purestorage/fusion/tests/functional/test_fusion_pg.py +++ /dev/null @@ -1,1600 +0,0 @@ -# -*- coding: utf-8 -*- - -# (c) 2023 Pure Storage, Inc. -# GNU General Public License v3.0+ (see COPYING.GPLv3 or https://www.gnu.org/licenses/gpl-3.0.txt) - -from __future__ import absolute_import, division, print_function - -__metaclass__ = type - -from unittest.mock import MagicMock, patch, call - -import fusion as purefusion -import pytest -from ansible.module_utils import basic -from ansible_collections.purestorage.fusion.plugins.module_utils.errors import ( - OperationException, -) -from ansible_collections.purestorage.fusion.plugins.modules import fusion_pg -from ansible_collections.purestorage.fusion.tests.functional.utils import ( - AnsibleExitJson, - AnsibleFailJson, - OperationMock, - FAKE_RESOURCE_ID, - exit_json, - fail_json, - set_module_args, - side_effects_with_exceptions, -) -from urllib3.exceptions import HTTPError - -# GLOBAL MOCKS -fusion_pg.setup_fusion = MagicMock(return_value=purefusion.api_client.ApiClient()) -purefusion.api_client.ApiClient.call_api = MagicMock( - side_effect=Exception("API call not mocked!") -) -basic.AnsibleModule.exit_json = exit_json -basic.AnsibleModule.fail_json = fail_json - - -@pytest.fixture -def module_args_present(): - return { - "name": "placement_group1", - "tenant": "tenant1", - "tenant_space": "tenant_space1", - "region": "region1", - "availability_zone": "availability_zone1", - "storage_service": "storage_service1", - "state": "present", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - - -@pytest.fixture -def module_args_absent(): - return { - "name": "placement_group1", - "tenant": "tenant1", - "tenant_space": "tenant_space1", - "state": "absent", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - - -@patch("fusion.OperationsApi") -@patch("fusion.PlacementGroupsApi") -@pytest.mark.parametrize( - ("module_args", "get_not_called"), - [ - # 'name` is missing - ( - { - "tenant": "tenant1", - "tenant_space": "tenant_space1", - "region": "region1", - "availability_zone": "availability_zone1", - "storage_service": "storage_service1", - "state": "present", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - True, - ), - # 'tenant` is missing - ( - { - "name": "placement_group1", - "tenant_space": "tenant_space1", - "region": "region1", - "availability_zone": "availability_zone1", - "storage_service": "storage_service1", - "state": "present", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - True, - ), - # 'tenant space` is missing - ( - { - "name": "placement_group1", - "tenant": "tenant1", - "region": "region1", - "availability_zone": "availability_zone1", - "storage_service": "storage_service1", - "state": "present", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - True, - ), - # 'region` is missing - ( - { - "name": "placement_group1", - "tenant": "tenant1", - "tenant_space": "tenant_space1", - "availability_zone": "availability_zone1", - "storage_service": "storage_service1", - "state": "present", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - False, - ), - # 'availability_zone` is missing - ( - { - "name": "placement_group1", - "tenant": "tenant1", - "tenant_space": "tenant_space1", - "region": "region1", - "storage_service": "storage_service1", - "state": "present", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - False, - ), - # 'storage_service` is missing - ( - { - "name": "placement_group1", - "tenant": "tenant1", - "tenant_space": "tenant_space1", - "region": "region1", - "availability_zone": "availability_zone1", - "state": "present", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - False, - ), - # 'state` is invalid - ( - { - "name": "placement_group1", - "tenant": "tenant1", - "tenant_space": "tenant_space1", - "region": "region1", - "availability_zone": "availability_zone1", - "storage_service": "storage_service1", - "state": "past", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - False, - ), - ], -) -def test_module_args_wrong(pg_api_init, op_api_init, module_args, get_not_called): - set_module_args(module_args) - - pg_mock = MagicMock() - pg_mock.get_placement_group = MagicMock(side_effect=purefusion.rest.ApiException) - pg_mock.create_placement_group = MagicMock(side_effect=NotImplementedError()) - pg_mock.update_placement_group = MagicMock(side_effect=NotImplementedError()) - pg_mock.delete_placement_group = MagicMock(side_effect=NotImplementedError()) - pg_api_init.return_value = pg_mock - - op_mock = MagicMock() - op_mock.get_operation = MagicMock(side_effect=purefusion.rest.ApiException) - op_api_init.return_value = op_mock - - with pytest.raises(AnsibleFailJson): - fusion_pg.main() - - if get_not_called: - pg_mock.get_placement_group.assert_not_called() - elif pg_mock.get_placement_group.called: - pg_mock.get_placement_group.assert_called_with( - tenant_name="tenant1", - tenant_space_name="tenant_space1", - placement_group_name="placement_group1", - ) - pg_mock.create_placement_group.assert_not_called() - pg_mock.update_placement_group.assert_not_called() - pg_mock.delete_placement_group.assert_not_called() - op_mock.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.PlacementGroupsApi") -def test_pg_create_ok(pg_api_init, op_api_init, module_args_present): - module_args = module_args_present - module_args["display_name"] = "some_display_name" - set_module_args(module_args) - - pg_mock = MagicMock() - pg_mock.get_placement_group = MagicMock(side_effect=purefusion.rest.ApiException) - pg_mock.create_placement_group = MagicMock(return_value=OperationMock("op1")) - pg_mock.update_placement_group = MagicMock(side_effect=NotImplementedError()) - pg_mock.delete_placement_group = MagicMock(side_effect=NotImplementedError()) - pg_api_init.return_value = pg_mock - - op_mock = MagicMock() - op_mock.get_operation = MagicMock(return_value=OperationMock("op1", success=True)) - op_api_init.return_value = op_mock - - with pytest.raises(AnsibleExitJson) as excinfo: - fusion_pg.main() - assert excinfo.value.changed - assert excinfo.value.id == FAKE_RESOURCE_ID - - pg_mock.get_placement_group.assert_called_with( - tenant_name="tenant1", - tenant_space_name="tenant_space1", - placement_group_name="placement_group1", - ) - pg_mock.create_placement_group.assert_called_with( - purefusion.PlacementGroupPost( - name="placement_group1", - display_name="some_display_name", - availability_zone="availability_zone1", - region="region1", - storage_service="storage_service1", - ), - tenant_name="tenant1", - tenant_space_name="tenant_space1", - ) - pg_mock.update_placement_group.assert_not_called() - pg_mock.delete_placement_group.assert_not_called() - op_mock.get_operation.assert_called_with("op1") - - -@patch("fusion.OperationsApi") -@patch("fusion.PlacementGroupsApi") -def test_pg_create_without_display_name_ok( - pg_api_init, op_api_init, module_args_present -): - module_args = module_args_present - set_module_args(module_args) - - pg_mock = MagicMock() - pg_mock.get_placement_group = MagicMock(side_effect=purefusion.rest.ApiException) - pg_mock.create_placement_group = MagicMock(return_value=OperationMock("op1")) - pg_mock.update_placement_group = MagicMock(side_effect=NotImplementedError()) - pg_mock.delete_placement_group = MagicMock(side_effect=NotImplementedError()) - pg_api_init.return_value = pg_mock - - op_mock = MagicMock() - op_mock.get_operation = MagicMock(return_value=OperationMock("op1", success=True)) - op_api_init.return_value = op_mock - - with pytest.raises(AnsibleExitJson) as excinfo: - fusion_pg.main() - assert excinfo.value.changed - assert excinfo.value.id == FAKE_RESOURCE_ID - - pg_mock.get_placement_group.assert_called_with( - tenant_name="tenant1", - tenant_space_name="tenant_space1", - placement_group_name="placement_group1", - ) - pg_mock.create_placement_group.assert_called_with( - purefusion.PlacementGroupPost( - name="placement_group1", - display_name="placement_group1", - availability_zone="availability_zone1", - region="region1", - storage_service="storage_service1", - ), - tenant_name="tenant1", - tenant_space_name="tenant_space1", - ) - pg_mock.update_placement_group.assert_not_called() - pg_mock.delete_placement_group.assert_not_called() - op_mock.get_operation.assert_called_with("op1") - - -@patch("fusion.OperationsApi") -@patch("fusion.PlacementGroupsApi") -@pytest.mark.parametrize( - ("raised_exception", "expected_exception"), - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, HTTPError), - ], -) -def test_pg_create_exception( - pg_api_init, op_api_init, raised_exception, expected_exception, module_args_present -): - set_module_args(module_args_present) - - pg_mock = MagicMock() - pg_mock.get_placement_group = MagicMock(side_effect=purefusion.rest.ApiException) - pg_mock.create_placement_group = MagicMock(side_effect=raised_exception) - pg_mock.update_placement_group = MagicMock(side_effect=NotImplementedError()) - pg_mock.delete_placement_group = MagicMock(side_effect=NotImplementedError()) - pg_api_init.return_value = pg_mock - - op_mock = MagicMock() - op_mock.get_operation = MagicMock(side_effect=NotImplementedError()) - op_api_init.return_value = op_mock - - with pytest.raises(expected_exception): - fusion_pg.main() - - pg_mock.get_placement_group.assert_called_with( - tenant_name="tenant1", - tenant_space_name="tenant_space1", - placement_group_name="placement_group1", - ) - pg_mock.create_placement_group.assert_called_with( - purefusion.PlacementGroupPost( - name="placement_group1", - display_name="placement_group1", - availability_zone="availability_zone1", - region="region1", - storage_service="storage_service1", - ), - tenant_name="tenant1", - tenant_space_name="tenant_space1", - ) - pg_mock.delete_placement_group.assert_not_called() - pg_mock.update_placement_group.assert_not_called() - op_mock.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.PlacementGroupsApi") -def test_pg_create_op_fails(pg_api_init, op_api_init, module_args_present): - module_args = module_args_present - set_module_args(module_args) - - pg_mock = MagicMock() - pg_mock.get_placement_group = MagicMock(side_effect=purefusion.rest.ApiException) - pg_mock.create_placement_group = MagicMock(return_value=OperationMock(id="op1")) - pg_mock.update_placement_group = MagicMock(side_effect=NotImplementedError()) - pg_mock.delete_placement_group = MagicMock(side_effect=NotImplementedError()) - pg_api_init.return_value = pg_mock - - op_mock = MagicMock() - op_mock.get_operation = MagicMock(return_value=OperationMock("op1", success=False)) - op_api_init.return_value = op_mock - - with pytest.raises(OperationException): - fusion_pg.main() - - pg_mock.get_placement_group.assert_called_with( - tenant_name="tenant1", - tenant_space_name="tenant_space1", - placement_group_name="placement_group1", - ) - pg_mock.create_placement_group.assert_called_with( - purefusion.PlacementGroupPost( - name="placement_group1", - display_name="placement_group1", - availability_zone="availability_zone1", - region="region1", - storage_service="storage_service1", - ), - tenant_name="tenant1", - tenant_space_name="tenant_space1", - ) - pg_mock.update_placement_group.assert_not_called() - pg_mock.delete_placement_group.assert_not_called() - op_mock.get_operation.assert_called_with("op1") - - -@patch("fusion.OperationsApi") -@patch("fusion.PlacementGroupsApi") -def test_pg_create_triggers_update_ok(pg_api_init, op_api_init): - module_args = { - "name": "placement_group1", - "display_name": "some_display_name", - "tenant": "tenant1", - "tenant_space": "tenant_space1", - "region": "region1", - "availability_zone": "availability_zone1", - "storage_service": "storage_service1", - "array": "array2", - "state": "present", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - set_module_args(module_args) - - get_placement_group_effects = [ - purefusion.rest.ApiException(), - purefusion.PlacementGroup( - id="placement_group1_id", - name="placement_group1", - display_name="some_display_name", - self_link="test_self_link", - tenant=purefusion.TenantRef( - id="tenant1_id", - name="tenant1", - kind="Tenant", - self_link="some_self_link", - ), - tenant_space=purefusion.TenantSpaceRef( - id="tenant_space1_id", - name="tenant_space1", - kind="TenantSpace", - self_link="some_self_link", - ), - availability_zone=purefusion.AvailabilityZoneRef( - id="availability_zone1_id", - name="availability_zone1", - kind="AvailabilityZone", - self_link="some_self_link", - ), - placement_engine="heuristics", - protocols=[], - storage_service=purefusion.StorageServiceRef( - id="storage_service1_id", - name="storage_service", - kind="StorageService", - self_link="some_self_link", - ), - array=purefusion.ArrayRef( - id="array1_id", name="array1", kind="Array", self_link="some_self_link" - ), - ), - ] - - pg_mock = MagicMock() - pg_mock.get_placement_group = MagicMock( - side_effect=side_effects_with_exceptions(get_placement_group_effects) - ) - pg_mock.create_placement_group = MagicMock(return_value=OperationMock("op1")) - pg_mock.update_placement_group = MagicMock(return_value=OperationMock("op2")) - pg_mock.delete_placement_group = MagicMock(side_effect=NotImplementedError()) - pg_api_init.return_value = pg_mock - - op_mock = MagicMock() - op_mock.get_operation = MagicMock(return_value=OperationMock("op1", success=True)) - op_api_init.return_value = op_mock - - with pytest.raises(AnsibleExitJson) as excinfo: - fusion_pg.main() - assert excinfo.value.changed - assert excinfo.value.id == FAKE_RESOURCE_ID - - pg_mock.get_placement_group.assert_has_calls( - [ - call( - tenant_name="tenant1", - tenant_space_name="tenant_space1", - placement_group_name="placement_group1", - ), - call( - tenant_name="tenant1", - tenant_space_name="tenant_space1", - placement_group_name="placement_group1", - ), - ], - any_order=True, - ) - pg_mock.create_placement_group.assert_called_with( - purefusion.PlacementGroupPost( - name="placement_group1", - display_name="some_display_name", - availability_zone="availability_zone1", - region="region1", - storage_service="storage_service1", - ), - tenant_name="tenant1", - tenant_space_name="tenant_space1", - ) - pg_mock.update_placement_group.assert_called_with( - purefusion.PlacementGroupPatch(array=purefusion.NullableString(value="array2")), - tenant_name="tenant1", - tenant_space_name="tenant_space1", - placement_group_name="placement_group1", - ) - pg_mock.delete_placement_group.assert_not_called() - op_mock.get_operation.assert_has_calls([call("op1"), call("op2")], any_order=True) - - -@patch("fusion.OperationsApi") -@patch("fusion.PlacementGroupsApi") -@pytest.mark.parametrize( - ("raised_exception", "expected_exception"), - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, HTTPError), - ], -) -def test_pg_create_triggers_update_exception( - pg_api_init, op_api_init, raised_exception, expected_exception -): - module_args = { - "name": "placement_group1", - "display_name": "some_display_name", - "tenant": "tenant1", - "tenant_space": "tenant_space1", - "region": "region1", - "availability_zone": "availability_zone1", - "storage_service": "storage_service1", - "array": "array2", - "state": "present", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - set_module_args(module_args) - - get_placement_group_effects = [ - purefusion.rest.ApiException(), - purefusion.PlacementGroup( - id="placement_group1_id", - name="placement_group1", - display_name="some_display_name", - self_link="test_self_link", - tenant=purefusion.TenantRef( - id="tenant1_id", - name="tenant1", - kind="Tenant", - self_link="some_self_link", - ), - tenant_space=purefusion.TenantSpaceRef( - id="tenant_space1_id", - name="tenant_space1", - kind="TenantSpace", - self_link="some_self_link", - ), - availability_zone=purefusion.AvailabilityZoneRef( - id="availability_zone1_id", - name="availability_zone1", - kind="AvailabilityZone", - self_link="some_self_link", - ), - placement_engine="heuristics", - protocols=[], - storage_service=purefusion.StorageServiceRef( - id="storage_service1_id", - name="storage_service", - kind="StorageService", - self_link="some_self_link", - ), - array=purefusion.ArrayRef( - id="array1_id", name="array1", kind="Array", self_link="some_self_link" - ), - ), - ] - - pg_mock = MagicMock() - pg_mock.get_placement_group = MagicMock( - side_effect=side_effects_with_exceptions(get_placement_group_effects) - ) - pg_mock.create_placement_group = MagicMock(return_value=OperationMock("op1")) - pg_mock.update_placement_group = MagicMock(side_effect=raised_exception) - pg_mock.delete_placement_group = MagicMock(side_effect=NotImplementedError()) - pg_api_init.return_value = pg_mock - - op_mock = MagicMock() - op_mock.get_operation = MagicMock(return_value=OperationMock("op1", success=True)) - op_api_init.return_value = op_mock - - with pytest.raises(expected_exception): - fusion_pg.main() - - pg_mock.get_placement_group.assert_has_calls( - [ - call( - tenant_name="tenant1", - tenant_space_name="tenant_space1", - placement_group_name="placement_group1", - ), - call( - tenant_name="tenant1", - tenant_space_name="tenant_space1", - placement_group_name="placement_group1", - ), - ], - any_order=True, - ) - pg_mock.create_placement_group.assert_called_with( - purefusion.PlacementGroupPost( - name="placement_group1", - display_name="some_display_name", - availability_zone="availability_zone1", - region="region1", - storage_service="storage_service1", - ), - tenant_name="tenant1", - tenant_space_name="tenant_space1", - ) - pg_mock.update_placement_group.assert_called_with( - purefusion.PlacementGroupPatch(array=purefusion.NullableString(value="array2")), - tenant_name="tenant1", - tenant_space_name="tenant_space1", - placement_group_name="placement_group1", - ) - pg_mock.delete_placement_group.assert_not_called() - op_mock.get_operation.assert_called_with("op1") - - -@patch("fusion.OperationsApi") -@patch("fusion.PlacementGroupsApi") -def test_pg_create_triggers_update_op_fails(pg_api_init, op_api_init): - module_args = { - "name": "placement_group1", - "display_name": "some_display_name", - "tenant": "tenant1", - "tenant_space": "tenant_space1", - "region": "region1", - "availability_zone": "availability_zone1", - "storage_service": "storage_service1", - "array": "array2", - "state": "present", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - set_module_args(module_args) - - get_placement_group_effects = [ - purefusion.rest.ApiException(), - purefusion.PlacementGroup( - id="placement_group1_id", - name="placement_group1", - display_name="some_display_name", - self_link="test_self_link", - tenant=purefusion.TenantRef( - id="tenant1_id", - name="tenant1", - kind="Tenant", - self_link="some_self_link", - ), - tenant_space=purefusion.TenantSpaceRef( - id="tenant_space1_id", - name="tenant_space1", - kind="TenantSpace", - self_link="some_self_link", - ), - availability_zone=purefusion.AvailabilityZoneRef( - id="availability_zone1_id", - name="availability_zone1", - kind="AvailabilityZone", - self_link="some_self_link", - ), - placement_engine="heuristics", - protocols=[], - storage_service=purefusion.StorageServiceRef( - id="storage_service1_id", - name="storage_service", - kind="StorageService", - self_link="some_self_link", - ), - array=purefusion.ArrayRef( - id="array1_id", name="array1", kind="Array", self_link="some_self_link" - ), - ), - ] - - pg_mock = MagicMock() - pg_mock.get_placement_group = MagicMock( - side_effect=side_effects_with_exceptions(get_placement_group_effects) - ) - pg_mock.create_placement_group = MagicMock(return_value=OperationMock("op1")) - pg_mock.update_placement_group = MagicMock(return_value=OperationMock("op2")) - pg_mock.delete_placement_group = MagicMock(side_effect=NotImplementedError()) - pg_api_init.return_value = pg_mock - - op_mock = MagicMock() - op_mock.get_operation = MagicMock( - side_effect=[ - OperationMock("op1", success=True), - OperationMock("op2", success=False), - ] - ) - op_api_init.return_value = op_mock - - with pytest.raises(OperationException): - fusion_pg.main() - - pg_mock.get_placement_group.assert_has_calls( - [ - call( - tenant_name="tenant1", - tenant_space_name="tenant_space1", - placement_group_name="placement_group1", - ), - call( - tenant_name="tenant1", - tenant_space_name="tenant_space1", - placement_group_name="placement_group1", - ), - ], - any_order=True, - ) - pg_mock.create_placement_group.assert_called_with( - purefusion.PlacementGroupPost( - name="placement_group1", - display_name="some_display_name", - availability_zone="availability_zone1", - region="region1", - storage_service="storage_service1", - ), - tenant_name="tenant1", - tenant_space_name="tenant_space1", - ) - pg_mock.update_placement_group.assert_called_with( - purefusion.PlacementGroupPatch(array=purefusion.NullableString(value="array2")), - tenant_name="tenant1", - tenant_space_name="tenant_space1", - placement_group_name="placement_group1", - ) - pg_mock.delete_placement_group.assert_not_called() - op_mock.get_operation.assert_has_calls([call("op1"), call("op2")]) - - -@patch("fusion.OperationsApi") -@patch("fusion.PlacementGroupsApi") -@pytest.mark.parametrize( - "test_case", - [ - # patch 'display_name` - { - "current_state": purefusion.PlacementGroup( - id="placement_group1_id", - name="placement_group1", - display_name="placement_group1_display_name", - self_link="test_self_link", - tenant=purefusion.TenantRef( - id="tenant1_id", - name="tenant1", - kind="Tenant", - self_link="some_self_link", - ), - tenant_space=purefusion.TenantSpaceRef( - id="tenant_space1_id", - name="tenant_space1", - kind="TenantSpace", - self_link="some_self_link", - ), - availability_zone=purefusion.AvailabilityZoneRef( - id="availability_zone1_id", - name="availability_zone1", - kind="AvailabilityZone", - self_link="some_self_link", - ), - placement_engine="heuristics", - protocols=[], - storage_service=purefusion.StorageServiceRef( - id="storage_service1_id", - name="storage_service", - kind="StorageService", - self_link="some_self_link", - ), - array=purefusion.ArrayRef( - id="array1_id", - name="array1", - kind="Array", - self_link="some_self_link", - ), - ), - "module_args": { - "name": "placement_group1", - "display_name": "different_display_name", - "tenant": "tenant1", - "tenant_space": "tenant_space1", - "region": "region1", - "availability_zone": "availability_zone1", - "storage_service": "storage_service1", - "state": "present", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - "patches": [ - purefusion.PlacementGroupPatch( - display_name=purefusion.NullableString( - value="different_display_name" - ), - ), - ], - }, - # patch 'array` - { - "current_state": purefusion.PlacementGroup( - id="placement_group1_id", - name="placement_group1", - display_name="placement_group1", - self_link="test_self_link", - tenant=purefusion.TenantRef( - id="tenant1_id", - name="tenant1", - kind="Tenant", - self_link="some_self_link", - ), - tenant_space=purefusion.TenantSpaceRef( - id="tenant_space1_id", - name="tenant_space1", - kind="TenantSpace", - self_link="some_self_link", - ), - availability_zone=purefusion.AvailabilityZoneRef( - id="availability_zone1_id", - name="availability_zone1", - kind="AvailabilityZone", - self_link="some_self_link", - ), - placement_engine="heuristics", - protocols=[], - storage_service=purefusion.StorageServiceRef( - id="storage_service1_id", - name="storage_service", - kind="StorageService", - self_link="some_self_link", - ), - array=purefusion.ArrayRef( - id="array1_id", - name="array1", - kind="Array", - self_link="some_self_link", - ), - ), - "module_args": { - "name": "placement_group1", - "tenant": "tenant1", - "tenant_space": "tenant_space1", - "region": "region1", - "availability_zone": "availability_zone1", - "storage_service": "storage_service1", - "array": "array2", - "state": "present", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - "patches": [ - purefusion.PlacementGroupPatch( - array=purefusion.NullableString(value="array2"), - ), - ], - }, - # patch all - { - "current_state": purefusion.PlacementGroup( - id="placement_group1_id", - name="placement_group1", - display_name="placement_group1_display_name", - self_link="test_self_link", - tenant=purefusion.TenantRef( - id="tenant1_id", - name="tenant1", - kind="Tenant", - self_link="some_self_link", - ), - tenant_space=purefusion.TenantSpaceRef( - id="tenant_space1_id", - name="tenant_space1", - kind="TenantSpace", - self_link="some_self_link", - ), - availability_zone=purefusion.AvailabilityZoneRef( - id="availability_zone1_id", - name="availability_zone1", - kind="AvailabilityZone", - self_link="some_self_link", - ), - placement_engine="heuristics", - protocols=[], - storage_service=purefusion.StorageServiceRef( - id="storage_service1_id", - name="storage_service", - kind="StorageService", - self_link="some_self_link", - ), - array=purefusion.ArrayRef( - id="array1_id", - name="array1", - kind="Array", - self_link="some_self_link", - ), - ), - "module_args": { - "name": "placement_group1", - "display_name": "different_display_name", - "tenant": "tenant1", - "tenant_space": "tenant_space1", - "region": "region1", - "availability_zone": "availability_zone1", - "storage_service": "storage_service1", - "array": "array2", - "state": "present", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - "patches": [ - purefusion.PlacementGroupPatch( - display_name=purefusion.NullableString( - value="different_display_name" - ), - ), - purefusion.PlacementGroupPatch( - array=purefusion.NullableString(value="array2"), - ), - ], - }, - ], -) -def test_pg_update_ok(pg_api_init, op_api_init, test_case): - module_args = test_case["module_args"] - set_module_args(module_args) - - get_operation_calls = [ - call("op{0}".format(i)) for i in range(len(test_case["patches"])) - ] - update_placement_group_return_vals = [ - OperationMock(id="op{0}".format(i)) for i in range(len(test_case["patches"])) - ] - update_placement_group_calls = [ - call( - p, - tenant_name="tenant1", - tenant_space_name="tenant_space1", - placement_group_name="placement_group1", - ) - for p in test_case["patches"] - ] - - pg_mock = MagicMock() - pg_mock.get_placement_group = MagicMock(return_value=test_case["current_state"]) - pg_mock.create_placement_group = MagicMock(side_effect=NotImplementedError()) - pg_mock.update_placement_group = MagicMock( - side_effect=update_placement_group_return_vals - ) - pg_mock.delete_placement_group = MagicMock(side_effect=NotImplementedError()) - pg_api_init.return_value = pg_mock - - op_mock = MagicMock() - op_mock.get_operation = MagicMock( - side_effect=lambda op_id: OperationMock(id=op_id, success=True) - ) - op_api_init.return_value = op_mock - - with pytest.raises(AnsibleExitJson) as excinfo: - fusion_pg.main() - assert excinfo.value.changed - assert excinfo.value.id == test_case["current_state"].id - - pg_mock.get_placement_group.assert_called_with( - tenant_name="tenant1", - tenant_space_name="tenant_space1", - placement_group_name="placement_group1", - ) - pg_mock.create_placement_group.assert_not_called() - pg_mock.update_placement_group.assert_has_calls( - update_placement_group_calls, any_order=True - ) - pg_mock.delete_placement_group.assert_not_called() - op_mock.get_operation.assert_has_calls(get_operation_calls, any_order=True) - - -@patch("fusion.OperationsApi") -@patch("fusion.PlacementGroupsApi") -@pytest.mark.parametrize("failing_patch", [0, 1]) -@pytest.mark.parametrize( - ("raised_exception", "expected_exception"), - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, HTTPError), - ], -) -def test_pg_update_exception( - pg_api_init, op_api_init, failing_patch, raised_exception, expected_exception -): - module_args = { - "name": "placement_group1", - "display_name": "different_display_name", - "tenant": "tenant1", - "tenant_space": "tenant_space1", - "region": "region1", - "availability_zone": "availability_zone1", - "storage_service": "storage_service1", - "array": "array2", - "state": "present", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - set_module_args(module_args) - - patches = [ - purefusion.PlacementGroupPatch( - display_name=purefusion.NullableString(value="different_display_name"), - ), - purefusion.PlacementGroupPatch( - array=purefusion.NullableString(value="array2"), - ), - ] - - pg_mock = MagicMock() - pg_mock.get_placement_group = MagicMock( - return_value=purefusion.PlacementGroup( - id="placement_group1_id", - name="placement_group1", - display_name="placement_group1_display_name", - self_link="test_self_link", - tenant=purefusion.TenantRef( - id="tenant1_id", - name="tenant1", - kind="Tenant", - self_link="some_self_link", - ), - tenant_space=purefusion.TenantSpaceRef( - id="tenant_space1_id", - name="tenant_space1", - kind="TenantSpace", - self_link="some_self_link", - ), - availability_zone=purefusion.AvailabilityZoneRef( - id="availability_zone1_id", - name="availability_zone1", - kind="AvailabilityZone", - self_link="some_self_link", - ), - placement_engine="heuristics", - protocols=[], - storage_service=purefusion.StorageServiceRef( - id="storage_service1_id", - name="storage_service", - kind="StorageService", - self_link="some_self_link", - ), - array=purefusion.ArrayRef( - id="array1_id", name="array1", kind="Array", self_link="some_self_link" - ), - ) - ) - pg_mock.create_placement_group = MagicMock(side_effect=NotImplementedError()) - pg_mock.update_placement_group = MagicMock( - side_effect=throw_on_specific_patch(patches, failing_patch, raised_exception, 0) - ) - pg_mock.delete_placement_group = MagicMock(side_effect=NotImplementedError()) - pg_api_init.return_value = pg_mock - - op_mock = MagicMock() - op_mock.get_operation = MagicMock( - side_effect=lambda op_id: OperationMock(id=op_id, success=True) - ) - op_api_init.return_value = op_mock - - with pytest.raises(expected_exception): - fusion_pg.main() - - pg_mock.get_placement_group.assert_called_with( - tenant_name="tenant1", - tenant_space_name="tenant_space1", - placement_group_name="placement_group1", - ) - pg_mock.create_placement_group.assert_not_called() - pg_mock.delete_placement_group.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.PlacementGroupsApi") -@pytest.mark.parametrize("failing_patch", [0, 1]) -@pytest.mark.parametrize( - ("raised_exception", "expected_exception"), - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, HTTPError), - ], -) -def test_pg_update_exception( - pg_api_init, op_api_init, failing_patch, raised_exception, expected_exception -): - module_args = { - "name": "placement_group1", - "display_name": "different_display_name", - "tenant": "tenant1", - "tenant_space": "tenant_space1", - "region": "region1", - "availability_zone": "availability_zone1", - "storage_service": "storage_service1", - "array": "array2", - "state": "present", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - set_module_args(module_args) - - patches = [ - purefusion.PlacementGroupPatch( - display_name=purefusion.NullableString(value="different_display_name"), - ), - purefusion.PlacementGroupPatch( - array=purefusion.NullableString(value="array2"), - ), - ] - - pg_mock = MagicMock() - pg_mock.get_placement_group = MagicMock( - return_value=purefusion.PlacementGroup( - id="placement_group1_id", - name="placement_group1", - display_name="placement_group1_display_name", - self_link="test_self_link", - tenant=purefusion.TenantRef( - id="tenant1_id", - name="tenant1", - kind="Tenant", - self_link="some_self_link", - ), - tenant_space=purefusion.TenantSpaceRef( - id="tenant_space1_id", - name="tenant_space1", - kind="TenantSpace", - self_link="some_self_link", - ), - availability_zone=purefusion.AvailabilityZoneRef( - id="availability_zone1_id", - name="availability_zone1", - kind="AvailabilityZone", - self_link="some_self_link", - ), - placement_engine="heuristics", - protocols=[], - storage_service=purefusion.StorageServiceRef( - id="storage_service1_id", - name="storage_service", - kind="StorageService", - self_link="some_self_link", - ), - array=purefusion.ArrayRef( - id="array1_id", name="array1", kind="Array", self_link="some_self_link" - ), - ) - ) - pg_mock.create_placement_group = MagicMock(side_effect=NotImplementedError()) - pg_mock.update_placement_group = MagicMock( - side_effect=throw_on_specific_patch(patches, failing_patch, raised_exception, 0) - ) - pg_mock.delete_placement_group = MagicMock(side_effect=NotImplementedError()) - pg_api_init.return_value = pg_mock - - op_mock = MagicMock() - op_mock.get_operation = MagicMock( - side_effect=lambda op_id: OperationMock(id=op_id, success=True) - ) - op_api_init.return_value = op_mock - - with pytest.raises(expected_exception) as excinfo: - fusion_pg.main() - - pg_mock.get_placement_group.assert_called_with( - tenant_name="tenant1", - tenant_space_name="tenant_space1", - placement_group_name="placement_group1", - ) - pg_mock.create_placement_group.assert_not_called() - pg_mock.delete_placement_group.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.PlacementGroupsApi") -@pytest.mark.parametrize("failing_patch", [0, 1]) -def test_pg_update_op_fails(pg_api_init, op_api_init, failing_patch): - module_args = { - "name": "placement_group1", - "display_name": "different_display_name", - "tenant": "tenant1", - "tenant_space": "tenant_space1", - "region": "region1", - "availability_zone": "availability_zone1", - "storage_service": "storage_service1", - "array": "array2", - "state": "present", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - set_module_args(module_args) - - patches = [ - purefusion.PlacementGroupPatch( - display_name=purefusion.NullableString(value="different_display_name"), - ), - purefusion.PlacementGroupPatch( - array=purefusion.NullableString(value="array2"), - ), - ] - ops = ["op0", "op1"] - - pg_mock = MagicMock() - pg_mock.get_placement_group = MagicMock( - return_value=purefusion.PlacementGroup( - id="placement_group1_id", - name="placement_group1", - display_name="placement_group1_display_name", - self_link="test_self_link", - tenant=purefusion.TenantRef( - id="tenant1_id", - name="tenant1", - kind="Tenant", - self_link="some_self_link", - ), - tenant_space=purefusion.TenantSpaceRef( - id="tenant_space1_id", - name="tenant_space1", - kind="TenantSpace", - self_link="some_self_link", - ), - availability_zone=purefusion.AvailabilityZoneRef( - id="availability_zone1_id", - name="availability_zone1", - kind="AvailabilityZone", - self_link="some_self_link", - ), - placement_engine="heuristics", - protocols=[], - storage_service=purefusion.StorageServiceRef( - id="storage_service1_id", - name="storage_service", - kind="StorageService", - self_link="some_self_link", - ), - array=purefusion.ArrayRef( - id="array1_id", name="array1", kind="Array", self_link="some_self_link" - ), - ) - ) - pg_mock.create_placement_group = MagicMock(side_effect=NotImplementedError()) - pg_mock.update_placement_group = MagicMock( - side_effect=lambda patch, tenant_name, tenant_space_name, placement_group_name: OperationMock( - id="op{0}".format(patches.index(patch)) - ) - ) - pg_mock.delete_placement_group = MagicMock(side_effect=NotImplementedError()) - pg_api_init.return_value = pg_mock - - op_mock = MagicMock() - op_mock.get_operation = MagicMock( - side_effect=lambda id: OperationMock( - id=id, success=ops.index(id) != failing_patch - ) - ) - op_api_init.return_value = op_mock - - with pytest.raises(OperationException): - fusion_pg.main() - - pg_mock.get_placement_group.assert_called_with( - tenant_name="tenant1", - tenant_space_name="tenant_space1", - placement_group_name="placement_group1", - ) - pg_mock.create_placement_group.assert_not_called() - pg_mock.delete_placement_group.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.PlacementGroupsApi") -def test_pg_delete_ok(pg_api_init, op_api_init, module_args_absent): - module_args = module_args_absent - set_module_args(module_args) - - pg_mock = MagicMock() - pg_mock.get_placement_group = MagicMock( - return_value=purefusion.PlacementGroup( - id="placement_group1_id", - name="placement_group1", - display_name="placement_group1_display_name", - self_link="test_self_link", - tenant=purefusion.TenantRef( - id="tenant1_id", - name="tenant1", - kind="Tenant", - self_link="some_self_link", - ), - tenant_space=purefusion.TenantSpaceRef( - id="tenant_space1_id", - name="tenant_space1", - kind="TenantSpace", - self_link="some_self_link", - ), - availability_zone=purefusion.AvailabilityZoneRef( - id="availability_zone1_id", - name="availability_zone1", - kind="AvailabilityZone", - self_link="some_self_link", - ), - placement_engine="heuristics", - protocols=[], - storage_service=purefusion.StorageServiceRef( - id="storage_service1_id", - name="storage_service", - kind="StorageService", - self_link="some_self_link", - ), - array=purefusion.ArrayRef( - id="array1_id", name="array1", kind="Array", self_link="some_self_link" - ), - ) - ) - pg_mock.create_placement_group = MagicMock(side_effect=NotImplementedError()) - pg_mock.update_placement_group = MagicMock(side_effect=NotImplementedError()) - pg_mock.delete_placement_group = MagicMock(return_value=OperationMock(id="op1")) - pg_api_init.return_value = pg_mock - - op_mock = MagicMock() - op_mock.get_operation = MagicMock( - return_value=OperationMock(id="op1", success=True) - ) - op_api_init.return_value = op_mock - - with pytest.raises(AnsibleExitJson) as excinfo: - fusion_pg.main() - assert excinfo.value.changed - - pg_mock.get_placement_group.assert_called_with( - tenant_name="tenant1", - tenant_space_name="tenant_space1", - placement_group_name="placement_group1", - ) - pg_mock.create_placement_group.assert_not_called() - pg_mock.update_placement_group.assert_not_called() - pg_mock.delete_placement_group.assert_called_with( - tenant_name="tenant1", - tenant_space_name="tenant_space1", - placement_group_name="placement_group1", - ) - op_mock.get_operation.assert_called_with("op1") - - -@patch("fusion.OperationsApi") -@patch("fusion.PlacementGroupsApi") -@pytest.mark.parametrize( - ("raised_exception", "expected_exception"), - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, HTTPError), - ], -) -def test_pg_delete_exception( - pg_api_init, op_api_init, raised_exception, expected_exception, module_args_absent -): - module_args = module_args_absent - set_module_args(module_args) - - pg_mock = MagicMock() - pg_mock.get_placement_group = MagicMock( - return_value=purefusion.PlacementGroup( - id="placement_group1_id", - name="placement_group1", - display_name="placement_group1_display_name", - self_link="test_self_link", - tenant=purefusion.TenantRef( - id="tenant1_id", - name="tenant1", - kind="Tenant", - self_link="some_self_link", - ), - tenant_space=purefusion.TenantSpaceRef( - id="tenant_space1_id", - name="tenant_space1", - kind="TenantSpace", - self_link="some_self_link", - ), - availability_zone=purefusion.AvailabilityZoneRef( - id="availability_zone1_id", - name="availability_zone1", - kind="AvailabilityZone", - self_link="some_self_link", - ), - placement_engine="heuristics", - protocols=[], - storage_service=purefusion.StorageServiceRef( - id="storage_service1_id", - name="storage_service", - kind="StorageService", - self_link="some_self_link", - ), - array=purefusion.ArrayRef( - id="array1_id", name="array1", kind="Array", self_link="some_self_link" - ), - ) - ) - pg_mock.create_placement_group = MagicMock(side_effect=NotImplementedError()) - pg_mock.update_placement_group = MagicMock(side_effect=NotImplementedError()) - pg_mock.delete_placement_group = MagicMock(side_effect=raised_exception) - pg_api_init.return_value = pg_mock - - op_mock = MagicMock() - op_mock.get_operation = MagicMock(side_effect=NotImplementedError()) - op_api_init.return_value = op_mock - - with pytest.raises(expected_exception): - fusion_pg.main() - - pg_mock.get_placement_group.assert_called_with( - tenant_name="tenant1", - tenant_space_name="tenant_space1", - placement_group_name="placement_group1", - ) - pg_mock.create_placement_group.assert_not_called() - pg_mock.update_placement_group.assert_not_called() - pg_mock.delete_placement_group.assert_called_with( - tenant_name="tenant1", - tenant_space_name="tenant_space1", - placement_group_name="placement_group1", - ) - op_mock.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.PlacementGroupsApi") -def test_pg_delete_op_fails(pg_api_init, op_api_init, module_args_absent): - module_args = module_args_absent - set_module_args(module_args) - - pg_mock = MagicMock() - pg_mock.get_placement_group = MagicMock( - return_value=purefusion.PlacementGroup( - id="placement_group1_id", - name="placement_group1", - display_name="placement_group1_display_name", - self_link="test_self_link", - tenant=purefusion.TenantRef( - id="tenant1_id", - name="tenant1", - kind="Tenant", - self_link="some_self_link", - ), - tenant_space=purefusion.TenantSpaceRef( - id="tenant_space1_id", - name="tenant_space1", - kind="TenantSpace", - self_link="some_self_link", - ), - availability_zone=purefusion.AvailabilityZoneRef( - id="availability_zone1_id", - name="availability_zone1", - kind="AvailabilityZone", - self_link="some_self_link", - ), - placement_engine="heuristics", - protocols=[], - storage_service=purefusion.StorageServiceRef( - id="storage_service1_id", - name="storage_service", - kind="StorageService", - self_link="some_self_link", - ), - array=purefusion.ArrayRef( - id="array1_id", name="array1", kind="Array", self_link="some_self_link" - ), - ) - ) - pg_mock.create_placement_group = MagicMock(side_effect=NotImplementedError()) - pg_mock.update_placement_group = MagicMock(side_effect=NotImplementedError()) - pg_mock.delete_placement_group = MagicMock(return_value=OperationMock(id="op1")) - pg_api_init.return_value = pg_mock - - op_mock = MagicMock() - op_mock.get_operation = MagicMock( - return_value=OperationMock(id="op1", success=False) - ) - op_api_init.return_value = op_mock - - with pytest.raises(OperationException): - fusion_pg.main() - - pg_mock.get_placement_group.assert_called_with( - tenant_name="tenant1", - tenant_space_name="tenant_space1", - placement_group_name="placement_group1", - ) - pg_mock.create_placement_group.assert_not_called() - pg_mock.update_placement_group.assert_not_called() - pg_mock.delete_placement_group.assert_called_with( - tenant_name="tenant1", - tenant_space_name="tenant_space1", - placement_group_name="placement_group1", - ) - op_mock.get_operation.assert_called_with("op1") - - -@patch("fusion.OperationsApi") -@patch("fusion.PlacementGroupsApi") -def test_pg_present_not_changed(pg_api_init, op_api_init, module_args_present): - module_args = module_args_present - set_module_args(module_args) - - pg_mock = MagicMock() - pg_mock.get_placement_group = MagicMock( - return_value=purefusion.PlacementGroup( - id="placement_group1_id", - name="placement_group1", - display_name="placement_group1_display_name", - self_link="test_self_link", - tenant=purefusion.TenantRef( - id="tenant1_id", - name="tenant1", - kind="Tenant", - self_link="some_self_link", - ), - tenant_space=purefusion.TenantSpaceRef( - id="tenant_space1_id", - name="tenant_space1", - kind="TenantSpace", - self_link="some_self_link", - ), - availability_zone=purefusion.AvailabilityZoneRef( - id="availability_zone1_id", - name="availability_zone1", - kind="AvailabilityZone", - self_link="some_self_link", - ), - placement_engine="heuristics", - protocols=[], - storage_service=purefusion.StorageServiceRef( - id="storage_service1_id", - name="storage_service", - kind="StorageService", - self_link="some_self_link", - ), - array=purefusion.ArrayRef( - id="array1_id", name="array1", kind="Array", self_link="some_self_link" - ), - ) - ) - pg_mock.create_placement_group = MagicMock(side_effect=NotImplementedError()) - pg_mock.update_placement_group = MagicMock(side_effect=NotImplementedError()) - pg_mock.delete_placement_group = MagicMock(side_effect=NotImplementedError()) - pg_api_init.return_value = pg_mock - - op_mock = MagicMock() - op_mock.get_operation = MagicMock(side_effect=NotImplementedError()) - op_api_init.return_value = op_mock - - with pytest.raises(AnsibleExitJson) as excinfo: - fusion_pg.main() - assert not excinfo.value.changed - - pg_mock.get_placement_group.assert_called_with( - tenant_name="tenant1", - tenant_space_name="tenant_space1", - placement_group_name="placement_group1", - ) - pg_mock.create_placement_group.assert_not_called() - pg_mock.update_placement_group.assert_not_called() - pg_mock.delete_placement_group.assert_not_called() - op_mock.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.PlacementGroupsApi") -def test_pg_absent_not_changed(pg_api_init, op_api_init, module_args_absent): - module_args = module_args_absent - set_module_args(module_args) - - pg_mock = MagicMock() - pg_mock.get_placement_group = MagicMock(side_effect=purefusion.rest.ApiException) - pg_mock.create_placement_group = MagicMock(side_effect=NotImplementedError()) - pg_mock.update_placement_group = MagicMock(side_effect=NotImplementedError()) - pg_mock.delete_placement_group = MagicMock(side_effect=NotImplementedError()) - pg_api_init.return_value = pg_mock - - op_mock = MagicMock() - op_mock.get_operation = MagicMock(side_effect=NotImplementedError()) - op_api_init.return_value = op_mock - - with pytest.raises(AnsibleExitJson) as excinfo: - fusion_pg.main() - assert not excinfo.value.changed - - pg_mock.get_placement_group.assert_called_with( - tenant_name="tenant1", - tenant_space_name="tenant_space1", - placement_group_name="placement_group1", - ) - pg_mock.create_placement_group.assert_not_called() - pg_mock.update_placement_group.assert_not_called() - pg_mock.delete_placement_group.assert_not_called() - op_mock.get_operation.assert_not_called() - - -def throw_on_specific_patch(patches, failing_patch_idx, raised_exception, op_offset): - patches = patches.copy() - - def _update_side_effect(patch, **kwargs): - idx = patches.index(patch) - if idx == failing_patch_idx: - raise raised_exception() - return OperationMock(id="op{0}".format(op_offset + idx)) - - return _update_side_effect diff --git a/ansible_collections/purestorage/fusion/tests/functional/test_fusion_pp.py b/ansible_collections/purestorage/fusion/tests/functional/test_fusion_pp.py deleted file mode 100644 index 359d4ca7e..000000000 --- a/ansible_collections/purestorage/fusion/tests/functional/test_fusion_pp.py +++ /dev/null @@ -1,531 +0,0 @@ -# -*- coding: utf-8 -*- - -# (c) 2023 Pure Storage, Inc. -# GNU General Public License v3.0+ (see COPYING.GPLv3 or https://www.gnu.org/licenses/gpl-3.0.txt) - -from __future__ import absolute_import, division, print_function - -__metaclass__ = type - -from unittest.mock import MagicMock, patch - -import fusion as purefusion -import pytest -from ansible.module_utils import basic -from ansible_collections.purestorage.fusion.plugins.module_utils.errors import ( - OperationException, -) -from ansible_collections.purestorage.fusion.plugins.modules import fusion_pp -from ansible_collections.purestorage.fusion.tests.functional.utils import ( - AnsibleExitJson, - AnsibleFailJson, - OperationMock, - FAKE_RESOURCE_ID, - exit_json, - fail_json, - set_module_args, -) -from urllib3.exceptions import HTTPError - -# GLOBAL MOCKS -fusion_pp.setup_fusion = MagicMock(return_value=purefusion.api_client.ApiClient()) -purefusion.api_client.ApiClient.call_api = MagicMock( - side_effect=Exception("API call not mocked!") -) -basic.AnsibleModule.exit_json = exit_json -basic.AnsibleModule.fail_json = fail_json - - -@pytest.fixture -def module_args_present(): - return { - "name": "protection_policy1", - "local_rpo": "1H43M", - "local_retention": "2H", - "state": "present", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - - -@pytest.fixture -def module_args_absent(): - return { - "name": "protection_policy1", - "state": "absent", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - - -@patch("fusion.OperationsApi") -@patch("fusion.ProtectionPoliciesApi") -@pytest.mark.parametrize( - ("module_args", "get_not_called"), - [ - # 'name` is missing - ( - { - "local_rpo": 10, - "local_retention": "10M", - "state": "present", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - True, - ), - # 'local_rpo` is missing - ( - { - "name": "protection_policy1", - "local_retention": "10M", - "state": "present", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - False, - ), - # 'local_retention` is missing - ( - { - "name": "protection_policy1", - "local_rpo": 10, - "state": "present", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - False, - ), - # 'local_rpo` is invalid - ( - { - "name": "protection_policy1", - "local_rpo": 10, - "local_retention": "10yen", - "state": "present", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - False, - ), - # 'local_retention` is invalid - ( - { - "name": "protection_policy1", - "local_rpo": "10bread", - "local_retention": "bre", - "state": "present", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - False, - ), - # 'state` is invalid - ( - { - "name": "protection_policy1", - "local_rpo": 10, - "local_retention": 10, - "state": "past", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - False, - ), - ], -) -def test_module_args_wrong(pp_api_init, op_api_init, module_args, get_not_called): - set_module_args(module_args) - - pp_mock = MagicMock() - pp_mock.get_protection_policy = MagicMock(side_effect=purefusion.rest.ApiException) - pp_mock.create_protection_policy = MagicMock(side_effect=NotImplementedError()) - pp_mock.delete_protection_policy = MagicMock(side_effect=NotImplementedError()) - pp_api_init.return_value = pp_mock - - op_mock = MagicMock() - op_mock.get_operation = MagicMock(side_effect=purefusion.rest.ApiException) - op_api_init.return_value = op_mock - - with pytest.raises(AnsibleFailJson): - fusion_pp.main() - - if get_not_called: - pp_mock.get_protection_policy.assert_not_called() - if pp_mock.get_protection_policy.called: - pp_mock.get_protection_policy.assert_called_with( - protection_policy_name="protection_policy1" - ) - pp_mock.create_protection_policy.assert_not_called() - pp_mock.delete_protection_policy.assert_not_called() - op_mock.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.ProtectionPoliciesApi") -def test_pp_create_ok(pp_api_init, op_api_init, module_args_present): - module_args = module_args_present - module_args["display_name"] = "some_display_name" - - set_module_args(module_args) - - pp_mock = MagicMock() - pp_mock.get_protection_policy = MagicMock(side_effect=purefusion.rest.ApiException) - pp_mock.create_protection_policy = MagicMock(return_value=OperationMock("op1")) - pp_mock.delete_protection_policy = MagicMock(side_effect=NotImplementedError()) - pp_api_init.return_value = pp_mock - - op_mock = MagicMock() - op_mock.get_operation = MagicMock(return_value=OperationMock("op1", success=True)) - op_api_init.return_value = op_mock - - with pytest.raises(AnsibleExitJson) as excinfo: - fusion_pp.main() - assert excinfo.value.changed - assert excinfo.value.id == FAKE_RESOURCE_ID - - pp_mock.get_protection_policy.assert_called_with( - protection_policy_name="protection_policy1" - ) - pp_mock.create_protection_policy.assert_called_with( - purefusion.ProtectionPolicyPost( - name="protection_policy1", - display_name="some_display_name", - objectives=[ - purefusion.RPO(type="RPO", rpo="PT103M"), - purefusion.Retention(type="Retention", after="PT120M"), - ], - ) - ) - pp_mock.delete_protection_policy.assert_not_called() - op_mock.get_operation.assert_called_with("op1") - - -@patch("fusion.OperationsApi") -@patch("fusion.ProtectionPoliciesApi") -def test_pp_create_without_display_name_ok( - pp_api_init, op_api_init, module_args_present -): - module_args = module_args_present - set_module_args(module_args) - - pp_mock = MagicMock() - pp_mock.get_protection_policy = MagicMock(side_effect=purefusion.rest.ApiException) - pp_mock.create_protection_policy = MagicMock(return_value=OperationMock("op1")) - pp_mock.delete_protection_policy = MagicMock(side_effect=NotImplementedError()) - pp_api_init.return_value = pp_mock - - op_mock = MagicMock() - op_mock.get_operation = MagicMock(return_value=OperationMock("op1", success=True)) - op_api_init.return_value = op_mock - - with pytest.raises(AnsibleExitJson) as excinfo: - fusion_pp.main() - assert excinfo.value.changed - assert excinfo.value.id == FAKE_RESOURCE_ID - - pp_mock.get_protection_policy.assert_called_with( - protection_policy_name="protection_policy1" - ) - pp_mock.create_protection_policy.assert_called_with( - purefusion.ProtectionPolicyPost( - name="protection_policy1", - display_name="protection_policy1", - objectives=[ - purefusion.RPO(type="RPO", rpo="PT103M"), - purefusion.Retention(type="Retention", after="PT120M"), - ], - ) - ) - pp_mock.delete_protection_policy.assert_not_called() - op_mock.get_operation.assert_called_with("op1") - - -@patch("fusion.OperationsApi") -@patch("fusion.ProtectionPoliciesApi") -@pytest.mark.parametrize( - ("raised_exception", "expected_exception"), - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, HTTPError), - ], -) -def test_pp_create_exception( - pp_api_init, op_api_init, raised_exception, expected_exception, module_args_present -): - module_args = module_args_present - set_module_args(module_args) - - pp_mock = MagicMock() - pp_mock.get_protection_policy = MagicMock(side_effect=purefusion.rest.ApiException) - pp_mock.create_protection_policy = MagicMock(side_effect=raised_exception) - pp_mock.delete_protection_policy = MagicMock(side_effect=NotImplementedError()) - pp_api_init.return_value = pp_mock - - op_mock = MagicMock() - op_mock.get_operation = MagicMock(side_effect=NotImplementedError()) - op_api_init.return_value = op_mock - - with pytest.raises(expected_exception): - fusion_pp.main() - - pp_mock.get_protection_policy.assert_called_with( - protection_policy_name="protection_policy1" - ) - pp_mock.create_protection_policy.assert_called_with( - purefusion.ProtectionPolicyPost( - name="protection_policy1", - display_name="protection_policy1", - objectives=[ - purefusion.RPO(type="RPO", rpo="PT103M"), - purefusion.Retention(type="Retention", after="PT120M"), - ], - ) - ) - pp_mock.delete_protection_policy.assert_not_called() - op_mock.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.ProtectionPoliciesApi") -def test_pp_create_op_fails(pp_api_init, op_api_init, module_args_present): - module_args = module_args_present - set_module_args(module_args) - - pp_mock = MagicMock() - pp_mock.get_protection_policy = MagicMock(side_effect=purefusion.rest.ApiException) - pp_mock.create_protection_policy = MagicMock(return_value=OperationMock(id="op1")) - pp_mock.delete_protection_policy = MagicMock(side_effect=NotImplementedError()) - pp_api_init.return_value = pp_mock - - op_mock = MagicMock() - op_mock.get_operation = MagicMock(return_value=OperationMock("op1", success=False)) - op_api_init.return_value = op_mock - - with pytest.raises(OperationException): - fusion_pp.main() - - pp_mock.get_protection_policy.assert_called_with( - protection_policy_name="protection_policy1" - ) - pp_mock.create_protection_policy.assert_called_with( - purefusion.ProtectionPolicyPost( - name="protection_policy1", - display_name="protection_policy1", - objectives=[ - purefusion.RPO(type="RPO", rpo="PT103M"), - purefusion.Retention(type="Retention", after="PT120M"), - ], - ) - ) - pp_mock.delete_protection_policy.assert_not_called() - op_mock.get_operation.assert_called_with("op1") - - -@patch("fusion.OperationsApi") -@patch("fusion.ProtectionPoliciesApi") -def test_pp_delete_ok(pp_api_init, op_api_init, module_args_absent): - module_args = module_args_absent - set_module_args(module_args) - - pp_mock = MagicMock() - pp_mock.get_protection_policy = MagicMock( - return_value=purefusion.ProtectionPolicy( - id="protection_policy1_id", - name="protection_policy1", - display_name="protection_policy1_display_name", - self_link="test_self_link", - objectives=[ - purefusion.RPO(type="RPO", rpo="PT103M"), - purefusion.Retention(type="Retention", after="PT120M"), - ], - ) - ) - pp_mock.create_protection_policy = MagicMock(side_effect=NotImplementedError()) - pp_mock.delete_protection_policy = MagicMock(return_value=OperationMock(id="op1")) - pp_api_init.return_value = pp_mock - - op_mock = MagicMock() - op_mock.get_operation = MagicMock( - return_value=OperationMock(id="op1", success=True) - ) - op_api_init.return_value = op_mock - - with pytest.raises(AnsibleExitJson) as excinfo: - fusion_pp.main() - assert excinfo.value.changed - - pp_mock.get_protection_policy.assert_called_with( - protection_policy_name="protection_policy1" - ) - pp_mock.create_protection_policy.assert_not_called() - pp_mock.delete_protection_policy.assert_called_with( - protection_policy_name="protection_policy1" - ) - op_mock.get_operation.assert_called_with("op1") - - -@patch("fusion.OperationsApi") -@patch("fusion.ProtectionPoliciesApi") -@pytest.mark.parametrize( - ("raised_exception", "expected_exception"), - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, HTTPError), - ], -) -def test_pp_delete_exception( - pp_api_init, op_api_init, raised_exception, expected_exception, module_args_absent -): - module_args = module_args_absent - set_module_args(module_args) - - pp_mock = MagicMock() - pp_mock.get_protection_policy = MagicMock( - return_value=purefusion.ProtectionPolicy( - id="protection_policy1_id", - name="protection_policy1", - display_name="protection_policy1_display_name", - self_link="test_self_link", - objectives=[ - purefusion.RPO(type="RPO", rpo="PT103M"), - purefusion.Retention(type="Retention", after="PT120M"), - ], - ) - ) - pp_mock.create_protection_policy = MagicMock(side_effect=NotImplementedError()) - pp_mock.delete_protection_policy = MagicMock(side_effect=raised_exception) - pp_api_init.return_value = pp_mock - - op_mock = MagicMock() - op_mock.get_operation = MagicMock(side_effect=NotImplementedError()) - op_api_init.return_value = op_mock - - with pytest.raises(expected_exception): - fusion_pp.main() - - pp_mock.get_protection_policy.assert_called_with( - protection_policy_name="protection_policy1" - ) - pp_mock.create_protection_policy.assert_not_called() - pp_mock.delete_protection_policy.assert_called_with( - protection_policy_name="protection_policy1" - ) - op_mock.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.ProtectionPoliciesApi") -def test_pp_delete_op_fails(pp_api_init, op_api_init, module_args_absent): - module_args = module_args_absent - set_module_args(module_args) - - pp_mock = MagicMock() - pp_mock.get_protection_policy = MagicMock( - return_value=purefusion.ProtectionPolicy( - id="protection_policy1_id", - name="protection_policy1", - display_name="protection_policy1_display_name", - self_link="test_self_link", - objectives=[ - purefusion.RPO(type="RPO", rpo="PT103M"), - purefusion.Retention(type="Retention", after="PT120M"), - ], - ) - ) - pp_mock.create_protection_policy = MagicMock(side_effect=NotImplementedError()) - pp_mock.delete_protection_policy = MagicMock(return_value=OperationMock(id="op1")) - pp_api_init.return_value = pp_mock - - op_mock = MagicMock() - op_mock.get_operation = MagicMock( - return_value=OperationMock(id="op1", success=False) - ) - op_api_init.return_value = op_mock - - with pytest.raises(OperationException): - fusion_pp.main() - - pp_mock.get_protection_policy.assert_called_with( - protection_policy_name="protection_policy1" - ) - pp_mock.create_protection_policy.assert_not_called() - pp_mock.delete_protection_policy.assert_called_with( - protection_policy_name="protection_policy1" - ) - op_mock.get_operation.assert_called_with("op1") - - -@patch("fusion.OperationsApi") -@patch("fusion.ProtectionPoliciesApi") -def test_pp_present_not_changed(pp_api_init, op_api_init): - module_args = { - "name": "protection_policy1", - "display_name": "some_display_name", - "local_rpo": "43M", - "local_retention": "2H", - "state": "present", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - set_module_args(module_args) - - pp_mock = MagicMock() - pp_mock.get_protection_policy = MagicMock( - return_value=purefusion.ProtectionPolicy( - id="protection_policy1_id", - name="protection_policy1", - display_name="some_display_name", - self_link="test_self_link", - objectives=[ - purefusion.RPO(type="RPO", rpo="PT43M"), - purefusion.Retention(type="Retention", after="PT120M"), - ], - ) - ) - pp_mock.create_protection_policy = MagicMock(side_effect=NotImplementedError()) - pp_mock.delete_protection_policy = MagicMock(side_effect=NotImplementedError()) - pp_api_init.return_value = pp_mock - - op_mock = MagicMock() - op_mock.get_operation = MagicMock(side_effect=NotImplementedError()) - op_api_init.return_value = op_mock - - with pytest.raises(AnsibleExitJson) as excinfo: - fusion_pp.main() - assert not excinfo.value.changed - - pp_mock.get_protection_policy.assert_called_with( - protection_policy_name="protection_policy1" - ) - pp_mock.create_protection_policy.assert_not_called() - pp_mock.delete_protection_policy.assert_not_called() - op_mock.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.ProtectionPoliciesApi") -def test_pp_absent_not_changed(pp_api_init, op_api_init, module_args_absent): - module_args = module_args_absent - set_module_args(module_args) - - pp_mock = MagicMock() - pp_mock.get_protection_policy = MagicMock(side_effect=purefusion.rest.ApiException) - pp_mock.create_protection_policy = MagicMock(side_effect=NotImplementedError()) - pp_mock.delete_protection_policy = MagicMock(side_effect=NotImplementedError()) - pp_api_init.return_value = pp_mock - - op_mock = MagicMock() - op_mock.get_operation = MagicMock(side_effect=NotImplementedError()) - op_api_init.return_value = op_mock - - with pytest.raises(AnsibleExitJson) as excinfo: - fusion_pp.main() - assert not excinfo.value.changed - - pp_mock.get_protection_policy.assert_called_with( - protection_policy_name="protection_policy1" - ) - pp_mock.create_protection_policy.assert_not_called() - pp_mock.delete_protection_policy.assert_not_called() - op_mock.get_operation.assert_not_called() diff --git a/ansible_collections/purestorage/fusion/tests/functional/test_fusion_ra.py b/ansible_collections/purestorage/fusion/tests/functional/test_fusion_ra.py deleted file mode 100644 index d8cac74a5..000000000 --- a/ansible_collections/purestorage/fusion/tests/functional/test_fusion_ra.py +++ /dev/null @@ -1,815 +0,0 @@ -# -*- coding: utf-8 -*- - -# (c) 2023 Pure Storage, Inc. -# GNU General Public License v3.0+ (see COPYING.GPLv3 or https://www.gnu.org/licenses/gpl-3.0.txt) - -from __future__ import absolute_import, division, print_function - -__metaclass__ = type - -from unittest.mock import MagicMock, patch - -import fusion as purefusion -import pytest -from ansible.module_utils import basic -from ansible_collections.purestorage.fusion.plugins.module_utils.errors import ( - OperationException, -) -from ansible_collections.purestorage.fusion.plugins.modules import fusion_ra -from ansible_collections.purestorage.fusion.tests.functional.utils import ( - AnsibleExitJson, - AnsibleFailJson, - OperationMock, - FAKE_RESOURCE_ID, - exit_json, - fail_json, - set_module_args, -) -from urllib3.exceptions import HTTPError - -# GLOBAL MOCKS -fusion_ra.setup_fusion = MagicMock(return_value=purefusion.api_client.ApiClient()) -purefusion.api_client.ApiClient.call_api = MagicMock( - side_effect=Exception("API call not mocked!") -) -basic.AnsibleModule.exit_json = exit_json -basic.AnsibleModule.fail_json = fail_json - - -@pytest.fixture -def module_args_present(): - return { - "state": "present", - "role": "az-admin", - "user": "user1", - "scope": "organization", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - - -@pytest.fixture -def module_args_absent(): - return { - "state": "absent", - "role": "az-admin", - "user": "user1", - "scope": "organization", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - - -@patch("fusion.OperationsApi") -@patch("fusion.IdentityManagerApi") -@patch("fusion.RoleAssignmentsApi") -@pytest.mark.parametrize( - "module_args", - [ - # 'role` is missing - { - "state": "present", - "tenant": "tenant1", - "tenant_space": "tenant_space1", - "user": "user1", - "scope": "tenant_space", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - # 'user` is missing - { - "state": "present", - "role": "tenant-space-admin", - "tenant": "tenant1", - "tenant_space": "tenant_space1", - "scope": "tenant_space", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - # 'scope` is invalid - { - "state": "present", - "role": "tenant-space-admin", - "tenant": "tenant1", - "tenant_space": "tenant_space1", - "user": "user1", - "scope": "bikini_bottom", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - # 'state` is invalid - { - "state": "past", - "role": "tenant-space-admin", - "tenant": "tenant1", - "tenant_space": "tenant_space1", - "user": "user1", - "scope": "tenant_space", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - # 'tenant` is missing #1 - { - "state": "present", - "role": "tenant-space-admin", - "tenant_space": "tenant_space1", - "user": "user1", - "scope": "tenant_space", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - # 'tenant` is missing #2 - { - "state": "present", - "role": "tenant-space-admin", - "tenant_space": "tenant_space1", - "user": "user1", - "scope": "tenant", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - # 'tenant_space` is missing - { - "state": "present", - "role": "tenant-space-admin", - "tenant": "tenant1", - "user": "user1", - "scope": "tenant_space", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - # both 'principal` and `user` are specified - { - "state": "present", - "role": "tenant-space-admin", - "tenant": "tenant1", - "user": "user1", - "principal": "123456", - "scope": "tenant_space", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - # both 'principal` and `api_client_key` are specified - { - "state": "present", - "role": "tenant-space-admin", - "tenant": "tenant1", - "api_client_key": "pure1:apikey:asdf123XYZ", - "principal": "123456", - "scope": "tenant_space", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - ], -) -def test_module_args_wrong(ra_api_init, im_api_init, op_api_init, module_args): - set_module_args(module_args) - - ra_mock = MagicMock() - ra_mock.list_role_assignments = MagicMock(side_effect=NotImplementedError()) - ra_mock.create_role_assignment = MagicMock(side_effect=NotImplementedError()) - ra_mock.delete_role_assignment = MagicMock(side_effect=NotImplementedError()) - ra_api_init.return_value = ra_mock - - im_mock = MagicMock() - im_mock.list_users = MagicMock( - return_value=[ - purefusion.User( - id="principal1", - self_link="test_value", - name="user1", - email="example@example.com", - ) - ] - ) - im_api_init.return_value = im_mock - - op_mock = MagicMock() - op_mock.get_operation = MagicMock(side_effect=purefusion.rest.ApiException) - op_api_init.return_value = op_mock - - with pytest.raises(AnsibleFailJson): - fusion_ra.main() - - ra_mock.list_role_assignments.assert_not_called() - ra_mock.create_role_assignment.assert_not_called() - ra_mock.delete_role_assignment.assert_not_called() - op_mock.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.IdentityManagerApi") -@patch("fusion.RoleAssignmentsApi") -def test_ra_user_does_not_exist( - ra_api_init, im_api_init, op_api_init, module_args_present -): - module_args = module_args_present - set_module_args(module_args) - - ra_mock = MagicMock() - ra_mock.list_role_assignments = MagicMock(side_effect=purefusion.rest.ApiException) - ra_mock.create_role_assignment = MagicMock(side_effect=NotImplementedError()) - ra_mock.delete_role_assignment = MagicMock(side_effect=NotImplementedError()) - ra_api_init.return_value = ra_mock - - im_mock = MagicMock() - im_mock.list_users = MagicMock(return_value=[]) - im_api_init.return_value = im_mock - - op_mock = MagicMock() - op_mock.get_operation = MagicMock(side_effect=purefusion.rest.ApiException) - op_api_init.return_value = op_mock - - with pytest.raises(AnsibleFailJson): - fusion_ra.main() - - ra_mock.list_role_assignments.assert_not_called() - ra_mock.create_role_assignment.assert_not_called() - ra_mock.delete_role_assignment.assert_not_called() - op_mock.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.IdentityManagerApi") -@patch("fusion.RoleAssignmentsApi") -@pytest.mark.parametrize( - "args_and_scope", - [ - # organization scope - ( - { - "state": "present", - "role": "az-admin", - "user": "user1", - "scope": "organization", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - "/", - ), - # tenant scope - ( - { - "state": "present", - "role": "tenant-admin", - "user": "user1", - "scope": "tenant", - "tenant": "tenant1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - "/tenants/tenant1", - ), - # tenant space scope - ( - { - "state": "present", - "role": "tenant-space-admin", - "user": "user1", - "scope": "tenant_space", - "tenant": "tenant1", - "tenant_space": "tenant_space1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - "/tenants/tenant1/tenant-spaces/tenant_space1", - ), - # principal instead of user - ( - { - "state": "present", - "role": "az-admin", - "principal": "principal1", - "scope": "organization", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - "/", - ), - # api_client_key instead of user - ( - { - "state": "present", - "role": "az-admin", - "api_client_key": "pure1:apikey:asdf123XYZ", - "scope": "organization", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - "/", - ), - ], -) -def test_ra_create_ok(ra_api_init, im_api_init, op_api_init, args_and_scope): - module_args = args_and_scope[0] - ra_scope = args_and_scope[1] - set_module_args(module_args) - - ra_mock = MagicMock() - ra_mock.list_role_assignments = MagicMock(return_value=[]) - ra_mock.create_role_assignment = MagicMock(return_value=OperationMock("op1")) - ra_mock.delete_role_assignment = MagicMock(side_effect=NotImplementedError()) - ra_api_init.return_value = ra_mock - - im_mock = MagicMock() - im_mock.list_users = MagicMock( - return_value=[ - purefusion.User( - id="principal1", - self_link="test_value", - name="user1", - email="example@example.com", - ) - ] - ) - im_api_init.return_value = im_mock - - op_mock = MagicMock() - op_mock.get_operation = MagicMock(return_value=OperationMock("op1", success=True)) - op_api_init.return_value = op_mock - - with pytest.raises(AnsibleExitJson) as excinfo: - fusion_ra.main() - assert excinfo.value.changed - assert excinfo.value.id == FAKE_RESOURCE_ID - - ra_mock.list_role_assignments.assert_called_with( - role_name=module_args["role"], principal="principal1" - ) - ra_mock.create_role_assignment.assert_called_with( - purefusion.RoleAssignmentPost(scope=ra_scope, principal="principal1"), - role_name=module_args["role"], - ) - ra_mock.delete_role_assignment.assert_not_called() - op_mock.get_operation.assert_called_with("op1") - - -@patch("fusion.OperationsApi") -@patch("fusion.IdentityManagerApi") -@patch("fusion.RoleAssignmentsApi") -@pytest.mark.parametrize( - ("raised_exception", "expected_exception"), - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, HTTPError), - ], -) -def test_ra_create_exception( - ra_api_init, - im_api_init, - op_api_init, - raised_exception, - expected_exception, - module_args_present, -): - module_args = module_args_present - set_module_args(module_args) - - ra_mock = MagicMock() - ra_mock.list_role_assignments = MagicMock(return_value=[]) - ra_mock.create_role_assignment = MagicMock(side_effect=raised_exception) - ra_mock.delete_role_assignment = MagicMock(side_effect=NotImplementedError()) - ra_api_init.return_value = ra_mock - - im_mock = MagicMock() - im_mock.list_users = MagicMock( - return_value=[ - purefusion.User( - id="principal1", - self_link="test_value", - name="user1", - email="example@example.com", - ) - ] - ) - im_api_init.return_value = im_mock - - op_mock = MagicMock() - op_mock.get_operation = MagicMock(side_effect=NotImplementedError()) - op_api_init.return_value = op_mock - - with pytest.raises(expected_exception): - fusion_ra.main() - - ra_mock.list_role_assignments.assert_called_with( - role_name="az-admin", principal="principal1" - ) - ra_mock.create_role_assignment.assert_called_with( - purefusion.RoleAssignmentPost(scope="/", principal="principal1"), - role_name="az-admin", - ) - ra_mock.delete_role_assignment.assert_not_called() - op_mock.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.IdentityManagerApi") -@patch("fusion.RoleAssignmentsApi") -def test_ra_create_op_fails(ra_api_init, im_api_init, op_api_init, module_args_present): - module_args = module_args_present - set_module_args(module_args) - - ra_mock = MagicMock() - ra_mock.list_role_assignments = MagicMock(return_value=[]) - ra_mock.create_role_assignment = MagicMock(return_value=OperationMock(id="op1")) - ra_mock.delete_role_assignment = MagicMock(side_effect=NotImplementedError()) - ra_api_init.return_value = ra_mock - - im_mock = MagicMock() - im_mock.list_users = MagicMock( - return_value=[ - purefusion.User( - id="principal1", - self_link="test_value", - name="user1", - email="example@example.com", - ) - ] - ) - im_api_init.return_value = im_mock - - op_mock = MagicMock() - op_mock.get_operation = MagicMock(return_value=OperationMock("op1", success=False)) - op_api_init.return_value = op_mock - - with pytest.raises(OperationException): - fusion_ra.main() - - ra_mock.list_role_assignments.assert_called_with( - role_name="az-admin", principal="principal1" - ) - ra_mock.create_role_assignment.assert_called_with( - purefusion.RoleAssignmentPost(scope="/", principal="principal1"), - role_name="az-admin", - ) - ra_mock.delete_role_assignment.assert_not_called() - op_mock.get_operation.assert_called_with("op1") - - -@patch("fusion.OperationsApi") -@patch("fusion.IdentityManagerApi") -@patch("fusion.RoleAssignmentsApi") -@pytest.mark.parametrize( - "args_and_scope", - [ - # organization scope - ( - { - "state": "absent", - "role": "az-admin", - "user": "user1", - "scope": "organization", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - purefusion.ResourceMetadata( - id="org_id", - name="org", - self_link="/", - ), - ), - # tenant scope - ( - { - "state": "absent", - "role": "tenant-admin", - "user": "user1", - "scope": "tenant", - "tenant": "tenant1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - purefusion.ResourceMetadata( - id="tenant1_id", - name="tenant1", - self_link="/tenants/tenant1", - ), - ), - # tenant space scope - ( - { - "state": "absent", - "role": "tenant-space-admin", - "user": "user1", - "scope": "tenant_space", - "tenant": "tenant1", - "tenant_space": "tenant_space1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - purefusion.ResourceMetadata( - id="tenant_space1_id", - name="tenant_space1", - self_link="/tenants/tenant1/tenant-spaces/tenant_space1", - ), - ), - ], -) -def test_ra_delete_ok(ra_api_init, im_api_init, op_api_init, args_and_scope): - module_args = args_and_scope[0] - ra_scope = args_and_scope[1] - set_module_args(module_args) - - ra_mock = MagicMock() - ra_mock.list_role_assignments = MagicMock( - return_value=[ - purefusion.RoleAssignment( - id="ra1_id", - name="ra1", - self_link="test_value", - role=purefusion.RoleRef( - id="role1_id", - name=module_args["role"], - kind="Role", - self_link="test_value", - ), - scope=ra_scope, - principal="principal1", - ) - ] - ) - ra_mock.create_role_assignment = MagicMock(side_effect=NotImplementedError()) - ra_mock.delete_role_assignment = MagicMock(return_value=OperationMock(id="op1")) - ra_api_init.return_value = ra_mock - - im_mock = MagicMock() - im_mock.list_users = MagicMock( - return_value=[ - purefusion.User( - id="principal1", - self_link="test_value", - name="user1", - email="example@example.com", - ) - ] - ) - im_api_init.return_value = im_mock - - op_mock = MagicMock() - op_mock.get_operation = MagicMock( - return_value=OperationMock(id="op1", success=True) - ) - op_api_init.return_value = op_mock - - with pytest.raises(AnsibleExitJson) as excinfo: - fusion_ra.main() - assert excinfo.value.changed - - ra_mock.list_role_assignments.assert_called_with( - role_name=module_args["role"], principal="principal1" - ) - ra_mock.create_role_assignment.assert_not_called() - ra_mock.delete_role_assignment.assert_called_with( - role_name=module_args["role"], role_assignment_name="ra1" - ) - op_mock.get_operation.assert_called_with("op1") - - -@patch("fusion.OperationsApi") -@patch("fusion.IdentityManagerApi") -@patch("fusion.RoleAssignmentsApi") -@pytest.mark.parametrize( - ("raised_exception", "expected_exception"), - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, HTTPError), - ], -) -def test_ra_delete_exception( - ra_api_init, - im_api_init, - op_api_init, - raised_exception, - expected_exception, - module_args_absent, -): - module_args = module_args_absent - set_module_args(module_args) - - ra_mock = MagicMock() - ra_mock.list_role_assignments = MagicMock( - return_value=[ - purefusion.RoleAssignment( - id="ra1_id", - name="ra1", - self_link="test_value", - role=purefusion.RoleRef( - id="role1_id", - name=module_args["role"], - kind="Role", - self_link="test_value", - ), - scope=purefusion.ResourceMetadata( - id="org_id", - name="org", - self_link="/", - ), - principal="principal1", - ) - ] - ) - ra_mock.create_role_assignment = MagicMock(side_effect=NotImplementedError()) - ra_mock.delete_role_assignment = MagicMock(side_effect=raised_exception) - ra_api_init.return_value = ra_mock - - im_mock = MagicMock() - im_mock.list_users = MagicMock( - return_value=[ - purefusion.User( - id="principal1", - self_link="test_value", - name="user1", - email="example@example.com", - ) - ] - ) - im_api_init.return_value = im_mock - - op_mock = MagicMock() - op_mock.get_operation = MagicMock(side_effect=NotImplementedError()) - op_api_init.return_value = op_mock - - with pytest.raises(expected_exception): - fusion_ra.main() - - ra_mock.list_role_assignments.assert_called_with( - role_name=module_args["role"], principal="principal1" - ) - ra_mock.create_role_assignment.assert_not_called() - ra_mock.delete_role_assignment.assert_called_with( - role_name=module_args["role"], role_assignment_name="ra1" - ) - op_mock.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.IdentityManagerApi") -@patch("fusion.RoleAssignmentsApi") -def test_ra_delete_op_fails(ra_api_init, im_api_init, op_api_init, module_args_absent): - module_args = module_args_absent - set_module_args(module_args) - - ra_mock = MagicMock() - ra_mock.list_role_assignments = MagicMock( - return_value=[ - purefusion.RoleAssignment( - id="ra1_id", - name="ra1", - self_link="test_value", - role=purefusion.RoleRef( - id="role1_id", - name=module_args["role"], - kind="Role", - self_link="test_value", - ), - scope=purefusion.ResourceMetadata( - id="org_id", - name="org", - self_link="/", - ), - principal="principal1", - ) - ] - ) - ra_mock.create_role_assignment = MagicMock(side_effect=NotImplementedError()) - ra_mock.delete_role_assignment = MagicMock(return_value=OperationMock(id="op1")) - ra_api_init.return_value = ra_mock - - im_mock = MagicMock() - im_mock.list_users = MagicMock( - return_value=[ - purefusion.User( - id="principal1", - self_link="test_value", - name="user1", - email="example@example.com", - ) - ] - ) - im_api_init.return_value = im_mock - - op_mock = MagicMock() - op_mock.get_operation = MagicMock( - return_value=OperationMock(id="op1", success=False) - ) - op_api_init.return_value = op_mock - - with pytest.raises(OperationException): - fusion_ra.main() - - ra_mock.list_role_assignments.assert_called_with( - role_name=module_args["role"], principal="principal1" - ) - ra_mock.create_role_assignment.assert_not_called() - ra_mock.delete_role_assignment.assert_called_with( - role_name=module_args["role"], role_assignment_name="ra1" - ) - op_mock.get_operation.assert_called_with("op1") - - -@patch("fusion.OperationsApi") -@patch("fusion.IdentityManagerApi") -@patch("fusion.RoleAssignmentsApi") -def test_ra_present_not_changed( - ra_api_init, im_api_init, op_api_init, module_args_present -): - module_args = module_args_present - set_module_args(module_args) - - ra_mock = MagicMock() - ra_mock.list_role_assignments = MagicMock( - return_value=[ - purefusion.RoleAssignment( - id="ra1_id", - name="ra1", - self_link="test_value", - role=purefusion.RoleRef( - id="role1_id", - name=module_args["role"], - kind="Role", - self_link="test_value", - ), - scope=purefusion.ResourceMetadata( - id="org_id", - name="org", - self_link="/", - ), - principal="principal1", - ) - ] - ) - ra_mock.create_role_assignment = MagicMock(side_effect=NotImplementedError()) - ra_mock.delete_role_assignment = MagicMock(side_effect=NotImplementedError()) - ra_api_init.return_value = ra_mock - - im_mock = MagicMock() - im_mock.list_users = MagicMock( - return_value=[ - purefusion.User( - id="principal1", - self_link="test_value", - name="user1", - email="example@example.com", - ) - ] - ) - im_api_init.return_value = im_mock - - op_mock = MagicMock() - op_mock.get_operation = MagicMock(side_effect=NotImplementedError()) - op_api_init.return_value = op_mock - - with pytest.raises(AnsibleExitJson) as excinfo: - fusion_ra.main() - assert not excinfo.value.changed - - ra_mock.list_role_assignments.assert_called_with( - role_name=module_args["role"], principal="principal1" - ) - ra_mock.create_role_assignment.assert_not_called() - ra_mock.delete_role_assignment.assert_not_called() - op_mock.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.IdentityManagerApi") -@patch("fusion.RoleAssignmentsApi") -def test_ra_absent_not_changed( - ra_api_init, im_api_init, op_api_init, module_args_absent -): - module_args = module_args_absent - set_module_args(module_args) - - ra_mock = MagicMock() - ra_mock.list_role_assignments = MagicMock(return_value=[]) - ra_mock.create_role_assignment = MagicMock(side_effect=NotImplementedError()) - ra_mock.delete_role_assignment = MagicMock(side_effect=NotImplementedError()) - ra_api_init.return_value = ra_mock - - im_mock = MagicMock() - im_mock.list_users = MagicMock( - return_value=[ - purefusion.User( - id="principal1", - self_link="test_value", - name="user1", - email="example@example.com", - ) - ] - ) - im_api_init.return_value = im_mock - - op_mock = MagicMock() - op_mock.get_operation = MagicMock(side_effect=NotImplementedError()) - op_api_init.return_value = op_mock - - with pytest.raises(AnsibleExitJson) as excinfo: - fusion_ra.main() - assert not excinfo.value.changed - - ra_mock.list_role_assignments.assert_called_with( - role_name=module_args["role"], principal="principal1" - ) - ra_mock.create_role_assignment.assert_not_called() - ra_mock.delete_role_assignment.assert_not_called() - op_mock.get_operation.assert_not_called() diff --git a/ansible_collections/purestorage/fusion/tests/functional/test_fusion_region.py b/ansible_collections/purestorage/fusion/tests/functional/test_fusion_region.py deleted file mode 100644 index 42d14d56e..000000000 --- a/ansible_collections/purestorage/fusion/tests/functional/test_fusion_region.py +++ /dev/null @@ -1,802 +0,0 @@ -# -*- coding: utf-8 -*- - -# (c) 2023, Andrej Pajtas (apajtas@purestorage.com) -# GNU General Public License v3.0+ (see COPYING.GPLv3 or https://www.gnu.org/licenses/gpl-3.0.txt) - -from __future__ import absolute_import, division, print_function - -__metaclass__ = type - -from unittest.mock import MagicMock, patch - -import fusion as purefusion -import pytest -from ansible.module_utils import basic -from ansible_collections.purestorage.fusion.plugins.module_utils.errors import ( - OperationException, -) -from ansible_collections.purestorage.fusion.plugins.modules import fusion_region -from ansible_collections.purestorage.fusion.tests.functional.utils import ( - AnsibleExitJson, - AnsibleFailJson, - FailedOperationMock, - OperationMock, - SuccessfulOperationMock, - FAKE_RESOURCE_ID, - exit_json, - fail_json, - set_module_args, -) -from urllib3.exceptions import HTTPError - -# GLOBAL MOCKS -fusion_region.setup_fusion = MagicMock(return_value=purefusion.api_client.ApiClient()) -purefusion.api_client.ApiClient.call_api = MagicMock( - side_effect=Exception("API call not mocked!") -) -basic.AnsibleModule.exit_json = exit_json -basic.AnsibleModule.fail_json = fail_json - - -@patch("fusion.OperationsApi") -@patch("fusion.RegionsApi") -@pytest.mark.parametrize( - "module_args", - [ - # required parameter 'name` is missing - { - "state": "present", - "display_name": "Region 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - # unknown parameter 'extra' is provided - { - "state": "present", - "name": "region1", - "display_name": "Region 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - "extra": "value", - }, - # parameter 'state` has incorrect value - { - "state": "cool", - "name": "region1", - "display_name": "Region 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - ], -) -def test_module_fails_on_wrong_parameters(m_region_api, m_op_api, module_args): - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_region = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_region = MagicMock(return_value=OperationMock(1)) - api_obj.update_region = MagicMock(return_value=OperationMock(2)) - api_obj.delete_region = MagicMock(return_value=OperationMock(3)) - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - m_region_api.return_value = api_obj - - # run module - with pytest.raises(AnsibleFailJson): - fusion_region.main() - - # check api was not called at all - api_obj.get_region.assert_not_called() - api_obj.create_region.assert_not_called() - api_obj.update_region.assert_not_called() - api_obj.delete_region.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.RegionsApi") -def test_region_create(m_region_api, m_op_api): - module_args = { - "state": "present", - "name": "region1", - "display_name": "Region 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_region = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_region = MagicMock(return_value=OperationMock(1)) - api_obj.update_region = MagicMock(return_value=OperationMock(2)) - api_obj.delete_region = MagicMock(return_value=OperationMock(3)) - m_region_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_region.main() - - assert exc.value.changed - assert exc.value.id == FAKE_RESOURCE_ID - - # check api was called correctly - api_obj.get_region.assert_called_once_with(region_name=module_args["name"]) - api_obj.create_region.assert_called_once_with( - purefusion.RegionPost( - name=module_args["name"], display_name=module_args["display_name"] - ) - ) - api_obj.update_region.assert_not_called() - api_obj.delete_region.assert_not_called() - op_obj.get_operation.assert_called_once_with(1) - - -@patch("fusion.OperationsApi") -@patch("fusion.RegionsApi") -def test_region_create_without_display_name(m_region_api, m_op_api): - module_args = { - "state": "present", - "name": "region1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_region = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_region = MagicMock(return_value=OperationMock(1)) - api_obj.update_region = MagicMock(return_value=OperationMock(2)) - api_obj.delete_region = MagicMock(return_value=OperationMock(3)) - m_region_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_region.main() - - assert exc.value.changed - assert exc.value.id == FAKE_RESOURCE_ID - - # check api was called correctly - api_obj.get_region.assert_called_once_with(region_name=module_args["name"]) - api_obj.create_region.assert_called_once_with( - purefusion.RegionPost( - name=module_args["name"], display_name=module_args["name"] - ) - ) - api_obj.update_region.assert_not_called() - api_obj.delete_region.assert_not_called() - op_obj.get_operation.assert_called_once_with(1) - - -@patch("fusion.OperationsApi") -@patch("fusion.RegionsApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, HTTPError), - ], -) -def test_region_create_exception(m_region_api, m_op_api, exec_original, exec_catch): - module_args = { - "state": "present", - "name": "region1", - "display_name": "Region 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_region = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_region = MagicMock(side_effect=exec_original) - api_obj.update_region = MagicMock(return_value=OperationMock(2)) - api_obj.delete_region = MagicMock(return_value=OperationMock(3)) - m_region_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_region.main() - - # check api was called correctly - api_obj.get_region.assert_called_once_with(region_name=module_args["name"]) - api_obj.create_region.assert_called_once_with( - purefusion.RegionPost( - name=module_args["name"], display_name=module_args["display_name"] - ) - ) - api_obj.update_region.assert_not_called() - api_obj.delete_region.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.RegionsApi") -def test_region_create_op_fails(m_region_api, m_op_api): - module_args = { - "state": "present", - "name": "region1", - "display_name": "Region 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_region = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_region = MagicMock(return_value=OperationMock(1)) - api_obj.update_region = MagicMock(return_value=OperationMock(2)) - api_obj.delete_region = MagicMock(return_value=OperationMock(3)) - m_region_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(OperationException): - fusion_region.main() - - # check api was called correctly - api_obj.get_region.assert_called_once_with(region_name=module_args["name"]) - api_obj.create_region.assert_called_once_with( - purefusion.RegionPost( - name=module_args["name"], display_name=module_args["display_name"] - ) - ) - api_obj.update_region.assert_not_called() - api_obj.delete_region.assert_not_called() - op_obj.get_operation.assert_called_once_with(1) - - -@patch("fusion.OperationsApi") -@patch("fusion.RegionsApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, OperationException), - ], -) -def test_region_create_op_exception(m_region_api, m_op_api, exec_original, exec_catch): - module_args = { - "state": "present", - "name": "region1", - "display_name": "Region 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_region = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_region = MagicMock(return_value=OperationMock(1)) - api_obj.update_region = MagicMock(return_value=OperationMock(2)) - api_obj.delete_region = MagicMock(return_value=OperationMock(3)) - m_region_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(side_effect=exec_original) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_region.main() - - # check api was called correctly - api_obj.get_region.assert_called_once_with(region_name=module_args["name"]) - api_obj.create_region.assert_called_once_with( - purefusion.RegionPost( - name=module_args["name"], display_name=module_args["display_name"] - ) - ) - api_obj.update_region.assert_not_called() - api_obj.delete_region.assert_not_called() - op_obj.get_operation.assert_called_once_with(1) - - -@patch("fusion.OperationsApi") -@patch("fusion.RegionsApi") -def test_region_update(m_region_api, m_op_api): - module_args = { - "state": "present", - "name": "region1", - "display_name": "Region 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - current_region = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], # name must match - "display_name": None, - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_region = MagicMock(return_value=purefusion.Region(**current_region)) - api_obj.create_region = MagicMock(return_value=OperationMock(1)) - api_obj.update_region = MagicMock(return_value=OperationMock(2)) - api_obj.delete_region = MagicMock(return_value=OperationMock(3)) - m_region_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_region.main() - - assert exc.value.changed - assert exc.value.id == current_region["id"] - - # check api was called correctly - api_obj.get_region.assert_called_once_with(region_name=module_args["name"]) - api_obj.create_region.assert_not_called() - api_obj.update_region.assert_called_once_with( - purefusion.RegionPatch( - display_name=purefusion.NullableString(module_args["display_name"]) - ), - region_name=module_args["name"], - ) - api_obj.delete_region.assert_not_called() - op_obj.get_operation.assert_called_once_with(2) - - -@patch("fusion.OperationsApi") -@patch("fusion.RegionsApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, HTTPError), - ], -) -def test_region_update_exception(m_region_api, m_op_api, exec_original, exec_catch): - module_args = { - "state": "present", - "name": "region1", - "display_name": "Region 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - current_region = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], # name must match - "display_name": None, - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_region = MagicMock(return_value=purefusion.Region(**current_region)) - api_obj.create_region = MagicMock(return_value=OperationMock(1)) - api_obj.update_region = MagicMock(side_effect=exec_original) - api_obj.delete_region = MagicMock(return_value=OperationMock(3)) - m_region_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_region.main() - - # check api was called correctly - api_obj.get_region.assert_called_once_with(region_name=module_args["name"]) - api_obj.create_region.assert_not_called() - api_obj.update_region.assert_called_once_with( - purefusion.RegionPatch( - display_name=purefusion.NullableString(module_args["display_name"]) - ), - region_name=module_args["name"], - ) - api_obj.delete_region.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.RegionsApi") -def test_region_update_op_fails(m_region_api, m_op_api): - module_args = { - "state": "present", - "name": "region1", - "display_name": "Region 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - current_region = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], # name must match - "display_name": None, - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_region = MagicMock(return_value=purefusion.Region(**current_region)) - api_obj.create_region = MagicMock(return_value=OperationMock(1)) - api_obj.update_region = MagicMock(return_value=OperationMock(2)) - api_obj.delete_region = MagicMock(return_value=OperationMock(3)) - m_region_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(OperationException): - fusion_region.main() - - # check api was called correctly - api_obj.get_region.assert_called_once_with(region_name=module_args["name"]) - api_obj.create_region.assert_not_called() - api_obj.update_region.assert_called_once_with( - purefusion.RegionPatch( - display_name=purefusion.NullableString(module_args["display_name"]) - ), - region_name=module_args["name"], - ) - api_obj.delete_region.assert_not_called() - op_obj.get_operation.assert_called_once_with(2) - - -@patch("fusion.OperationsApi") -@patch("fusion.RegionsApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, OperationException), - ], -) -def test_region_update_op_exception(m_region_api, m_op_api, exec_original, exec_catch): - module_args = { - "state": "present", - "name": "region1", - "display_name": "Region 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - current_region = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], # name must match - "display_name": None, - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_region = MagicMock(return_value=purefusion.Region(**current_region)) - api_obj.create_region = MagicMock(return_value=OperationMock(1)) - api_obj.update_region = MagicMock(return_value=OperationMock(2)) - api_obj.delete_region = MagicMock(return_value=OperationMock(3)) - m_region_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(side_effect=exec_original) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_region.main() - - # check api was called correctly - api_obj.get_region.assert_called_once_with(region_name=module_args["name"]) - api_obj.create_region.assert_not_called() - api_obj.update_region.assert_called_once_with( - purefusion.RegionPatch( - display_name=purefusion.NullableString(module_args["display_name"]) - ), - region_name=module_args["name"], - ) - api_obj.delete_region.assert_not_called() - op_obj.get_operation.assert_called_once_with(2) - - -@patch("fusion.OperationsApi") -@patch("fusion.RegionsApi") -def test_region_present_not_changed(m_region_api, m_op_api): - module_args = { - "state": "present", - "name": "region1", - "display_name": "Region 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - current_region = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], # name must match - "display_name": module_args["display_name"], - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_region = MagicMock(return_value=purefusion.Region(**current_region)) - api_obj.create_region = MagicMock(return_value=OperationMock(1)) - api_obj.update_region = MagicMock(return_value=OperationMock(2)) - api_obj.delete_region = MagicMock(return_value=OperationMock(3)) - m_region_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_region.main() - - assert not exc.value.changed - - # check api was called correctly - api_obj.get_region.assert_called_once_with(region_name=module_args["name"]) - api_obj.create_region.assert_not_called() - api_obj.update_region.assert_not_called() - api_obj.delete_region.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.RegionsApi") -def test_region_absent_not_changed(m_region_api, m_op_api): - module_args = { - "state": "absent", - "name": "region1", - "display_name": "Region 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_region = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_region = MagicMock(return_value=OperationMock(1)) - api_obj.update_region = MagicMock(return_value=OperationMock(2)) - api_obj.delete_region = MagicMock(return_value=OperationMock(3)) - m_region_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_region.main() - - assert not exc.value.changed - - # check api was called correctly - api_obj.get_region.assert_called_once_with(region_name=module_args["name"]) - api_obj.create_region.assert_not_called() - api_obj.update_region.assert_not_called() - api_obj.delete_region.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.RegionsApi") -def test_region_delete(m_region_api, m_op_api): - module_args = { - "state": "absent", - "name": "region1", - "display_name": "Region 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - current_region = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], # name must match - "display_name": "different", # display_name doesn't match but UPDATE shouldn't be called - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_region = MagicMock(return_value=purefusion.Region(**current_region)) - api_obj.create_region = MagicMock(return_value=OperationMock(1)) - api_obj.update_region = MagicMock(return_value=OperationMock(2)) - api_obj.delete_region = MagicMock(return_value=OperationMock(3)) - m_region_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_region.main() - - assert exc.value.changed - - # check api was called correctly - api_obj.get_region.assert_called_once_with(region_name=module_args["name"]) - api_obj.create_region.assert_not_called() - api_obj.update_region.assert_not_called() - api_obj.delete_region.assert_called_once_with(region_name=module_args["name"]) - op_obj.get_operation.assert_called_once_with(3) - - -@patch("fusion.OperationsApi") -@patch("fusion.RegionsApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, HTTPError), - ], -) -def test_region_delete_exception(m_region_api, m_op_api, exec_original, exec_catch): - module_args = { - "state": "absent", - "name": "region1", - "display_name": "Region 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - current_region = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], # name must match - "display_name": "different", # display_name doesn't match but UPDATE shouldn't be called - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_region = MagicMock(return_value=purefusion.Region(**current_region)) - api_obj.create_region = MagicMock(return_value=OperationMock(1)) - api_obj.update_region = MagicMock(return_value=OperationMock(2)) - api_obj.delete_region = MagicMock(side_effect=exec_original) - m_region_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_region.main() - - # check api was called correctly - api_obj.get_region.assert_called_once_with(region_name=module_args["name"]) - api_obj.create_region.assert_not_called() - api_obj.update_region.assert_not_called() - api_obj.delete_region.assert_called_once_with(region_name=module_args["name"]) - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.RegionsApi") -def test_region_delete_op_fails(m_region_api, m_op_api): - module_args = { - "state": "absent", - "name": "region1", - "display_name": "Region 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - current_region = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], # name must match - "display_name": "different", # display_name doesn't match but UPDATE shouldn't be called - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_region = MagicMock(return_value=purefusion.Region(**current_region)) - api_obj.create_region = MagicMock(return_value=OperationMock(1)) - api_obj.update_region = MagicMock(return_value=OperationMock(2)) - api_obj.delete_region = MagicMock(return_value=OperationMock(3)) - m_region_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(OperationException): - fusion_region.main() - - # check api was called correctly - api_obj.get_region.assert_called_once_with(region_name=module_args["name"]) - api_obj.create_region.assert_not_called() - api_obj.update_region.assert_not_called() - api_obj.delete_region.assert_called_once_with(region_name=module_args["name"]) - op_obj.get_operation.assert_called_once_with(3) - - -@patch("fusion.OperationsApi") -@patch("fusion.RegionsApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, OperationException), - ], -) -def test_region_delete_op_exception(m_region_api, m_op_api, exec_original, exec_catch): - module_args = { - "state": "absent", - "name": "region1", - "display_name": "Region 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - current_region = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], # name must match - "display_name": "different", # display_name doesn't match but UPDATE shouldn't be called - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_region = MagicMock(return_value=purefusion.Region(**current_region)) - api_obj.create_region = MagicMock(return_value=OperationMock(1)) - api_obj.update_region = MagicMock(return_value=OperationMock(2)) - api_obj.delete_region = MagicMock(return_value=OperationMock(3)) - m_region_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(side_effect=exec_original) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_region.main() - - # check api was called correctly - api_obj.get_region.assert_called_once_with(region_name=module_args["name"]) - api_obj.create_region.assert_not_called() - api_obj.update_region.assert_not_called() - api_obj.delete_region.assert_called_once_with(region_name=module_args["name"]) - op_obj.get_operation.assert_called_once_with(3) diff --git a/ansible_collections/purestorage/fusion/tests/functional/test_fusion_sc.py b/ansible_collections/purestorage/fusion/tests/functional/test_fusion_sc.py deleted file mode 100644 index 4d44e7fcb..000000000 --- a/ansible_collections/purestorage/fusion/tests/functional/test_fusion_sc.py +++ /dev/null @@ -1,1244 +0,0 @@ -# -*- coding: utf-8 -*- - -# (c) 2023, Andrej Pajtas (apajtas@purestorage.com) -# GNU General Public License v3.0+ (see COPYING.GPLv3 or https://www.gnu.org/licenses/gpl-3.0.txt) - -from __future__ import absolute_import, division, print_function - -__metaclass__ = type - -from unittest.mock import MagicMock, patch - -import fusion as purefusion -import pytest -from ansible.module_utils import basic -from ansible_collections.purestorage.fusion.plugins.module_utils.errors import ( - OperationException, -) -from ansible_collections.purestorage.fusion.plugins.modules import fusion_sc -from ansible_collections.purestorage.fusion.tests.functional.utils import ( - AnsibleExitJson, - AnsibleFailJson, - FailedOperationMock, - OperationMock, - SuccessfulOperationMock, - FAKE_RESOURCE_ID, - exit_json, - fail_json, - set_module_args, -) -from urllib3.exceptions import HTTPError - -# GLOBAL MOCKS -fusion_sc.setup_fusion = MagicMock(return_value=purefusion.api_client.ApiClient()) -purefusion.api_client.ApiClient.call_api = MagicMock( - side_effect=Exception("API call not mocked!") -) -basic.AnsibleModule.exit_json = exit_json -basic.AnsibleModule.fail_json = fail_json - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageClassesApi") -@pytest.mark.parametrize( - "module_args", - [ - # required parameter 'name` is missing - { - "state": "present", - "display_name": "Storage Class 1", - "iops_limit": "2000000", - "bw_limit": "256G", - "size_limit": "2P", - "storage_service": "ss1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - # required parameter 'storage_service` is missing - { - "state": "present", - "name": "sc1", - "display_name": "Storage Class 1", - "iops_limit": "2000000", - "bw_limit": "256G", - "size_limit": "2P", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - # unknown parameter 'extra' is provided - { - "state": "present", - "name": "sc1", - "display_name": "Storage Class 1", - "iops_limit": "2000000", - "bw_limit": "256G", - "size_limit": "2P", - "storage_service": "ss1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - "extra": "value", - }, - # parameter 'state` has incorrect value - { - "state": "cool", - "name": "sc1", - "display_name": "Storage Class 1", - "iops_limit": "2000000", - "bw_limit": "256G", - "size_limit": "2P", - "storage_service": "ss1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - ], -) -def test_module_fails_on_wrong_parameters(m_sc_api, m_op_api, module_args): - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_class = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_storage_class = MagicMock(return_value=OperationMock(1)) - api_obj.update_storage_class = MagicMock(return_value=OperationMock(2)) - api_obj.delete_storage_class = MagicMock(return_value=OperationMock(3)) - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - m_sc_api.return_value = api_obj - - # run module - with pytest.raises(AnsibleFailJson): - fusion_sc.main() - - # check api was not called at all - api_obj.get_storage_class.assert_not_called() - api_obj.create_storage_class.assert_not_called() - api_obj.update_storage_class.assert_not_called() - api_obj.delete_storage_class.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageClassesApi") -@pytest.mark.parametrize( - "iops_arg,iops_exp", - [("2000000", 2_000_000), (None, 100_000_000)], -) -@pytest.mark.parametrize( - "bw_arg,bw_exp", - [("256G", 274877906944), (None, 549755813888)], -) -@pytest.mark.parametrize( - "size_arg,size_exp", - [("2P", 2251799813685248), (None, 4503599627370496)], -) -def test_sc_create( - m_sc_api, m_op_api, iops_arg, iops_exp, bw_arg, bw_exp, size_arg, size_exp -): - module_args = { - "state": "present", - "name": "sc1", - "display_name": "Storage Class 1", - "iops_limit": iops_arg, - "bw_limit": bw_arg, - "size_limit": size_arg, - "storage_service": "ss1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_class = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_storage_class = MagicMock(return_value=OperationMock(1)) - api_obj.update_storage_class = MagicMock(return_value=OperationMock(2)) - api_obj.delete_storage_class = MagicMock(return_value=OperationMock(3)) - m_sc_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_sc.main() - - assert exc.value.changed - assert exc.value.id == FAKE_RESOURCE_ID - - # check api was called correctly - api_obj.get_storage_class.assert_called_once_with( - storage_class_name=module_args["name"], - storage_service_name=module_args["storage_service"], - ) - api_obj.create_storage_class.assert_called_once_with( - purefusion.StorageClassPost( - name=module_args["name"], - display_name=module_args["display_name"], - iops_limit=iops_exp, - bandwidth_limit=bw_exp, - size_limit=size_exp, - ), - storage_service_name=module_args["storage_service"], - ) - api_obj.update_storage_class.assert_not_called() - api_obj.delete_storage_class.assert_not_called() - op_obj.get_operation.assert_called_once_with(1) - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageClassesApi") -def test_sc_create_without_display_name(m_sc_api, m_op_api): - module_args = { - "state": "present", - "name": "sc1", - "iops_limit": "2000000", - "bw_limit": "256G", - "size_limit": "2P", - "storage_service": "ss1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - parsed_size = 2251799813685248 - parsed_bandwidth = 274877906944 - parsed_iops = 2000000 - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_class = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_storage_class = MagicMock(return_value=OperationMock(1)) - api_obj.update_storage_class = MagicMock(return_value=OperationMock(2)) - api_obj.delete_storage_class = MagicMock(return_value=OperationMock(3)) - m_sc_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_sc.main() - - assert exc.value.changed - assert exc.value.id == FAKE_RESOURCE_ID - - # check api was called correctly - api_obj.get_storage_class.assert_called_once_with( - storage_class_name=module_args["name"], - storage_service_name=module_args["storage_service"], - ) - api_obj.create_storage_class.assert_called_once_with( - purefusion.StorageClassPost( - name=module_args["name"], - display_name=module_args["name"], - iops_limit=parsed_iops, - bandwidth_limit=parsed_bandwidth, - size_limit=parsed_size, - ), - storage_service_name=module_args["storage_service"], - ) - api_obj.update_storage_class.assert_not_called() - api_obj.delete_storage_class.assert_not_called() - op_obj.get_operation.assert_called_once_with(1) - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageClassesApi") -@pytest.mark.parametrize("iops_arg", [-100, 99, 100_000_001]) -def test_sc_create_iops_out_of_range(m_sc_api, m_op_api, iops_arg): - module_args = { - "state": "present", - "name": "sc1", - "display_name": "Storage Class 1", - "iops_limit": iops_arg, - "bw_limit": "256G", - "size_limit": "2P", - "storage_service": "ss1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_class = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_storage_class = MagicMock(return_value=OperationMock(1)) - api_obj.update_storage_class = MagicMock(return_value=OperationMock(2)) - api_obj.delete_storage_class = MagicMock(return_value=OperationMock(3)) - m_sc_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleFailJson): - fusion_sc.main() - - # check api was called correctly - api_obj.get_storage_class.assert_called_once_with( - storage_class_name=module_args["name"], - storage_service_name=module_args["storage_service"], - ) - api_obj.create_storage_class.assert_not_called() - api_obj.update_storage_class.assert_not_called() - api_obj.delete_storage_class.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageClassesApi") -@pytest.mark.parametrize("bw_arg", ["1023K", "513G"]) -def test_sc_create_bw_out_of_range(m_sc_api, m_op_api, bw_arg): - module_args = { - "state": "present", - "name": "sc1", - "display_name": "Storage Class 1", - "iops_limit": "2000000", - "bw_limit": bw_arg, - "size_limit": "2P", - "storage_service": "ss1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_class = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_storage_class = MagicMock(return_value=OperationMock(1)) - api_obj.update_storage_class = MagicMock(return_value=OperationMock(2)) - api_obj.delete_storage_class = MagicMock(return_value=OperationMock(3)) - m_sc_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleFailJson): - fusion_sc.main() - - # check api was called correctly - api_obj.get_storage_class.assert_called_once_with( - storage_class_name=module_args["name"], - storage_service_name=module_args["storage_service"], - ) - api_obj.create_storage_class.assert_not_called() - api_obj.update_storage_class.assert_not_called() - api_obj.delete_storage_class.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageClassesApi") -@pytest.mark.parametrize("size_arg", ["1023K", "5P"]) -def test_sc_create_size_out_of_range(m_sc_api, m_op_api, size_arg): - module_args = { - "state": "present", - "name": "sc1", - "display_name": "Storage Class 1", - "iops_limit": "2000000", - "bw_limit": "256G", - "size_limit": size_arg, - "storage_service": "ss1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_class = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_storage_class = MagicMock(return_value=OperationMock(1)) - api_obj.update_storage_class = MagicMock(return_value=OperationMock(2)) - api_obj.delete_storage_class = MagicMock(return_value=OperationMock(3)) - m_sc_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleFailJson): - fusion_sc.main() - - # check api was called correctly - api_obj.get_storage_class.assert_called_once_with( - storage_class_name=module_args["name"], - storage_service_name=module_args["storage_service"], - ) - api_obj.create_storage_class.assert_not_called() - api_obj.update_storage_class.assert_not_called() - api_obj.delete_storage_class.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageClassesApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, HTTPError), - ], -) -def test_sc_create_exception(m_sc_api, m_op_api, exec_original, exec_catch): - module_args = { - "state": "present", - "name": "sc1", - "display_name": "Storage Class 1", - "iops_limit": "2000000", - "bw_limit": "256G", - "size_limit": "2P", - "storage_service": "ss1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - parsed_size = 2251799813685248 - parsed_bandwidth = 274877906944 - parsed_iops = 2000000 - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_class = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_storage_class = MagicMock(side_effect=exec_original) - api_obj.update_storage_class = MagicMock(return_value=OperationMock(2)) - api_obj.delete_storage_class = MagicMock(return_value=OperationMock(3)) - m_sc_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_sc.main() - - # check api was called correctly - api_obj.get_storage_class.assert_called_once_with( - storage_class_name=module_args["name"], - storage_service_name=module_args["storage_service"], - ) - api_obj.create_storage_class.assert_called_once_with( - purefusion.StorageClassPost( - name=module_args["name"], - display_name=module_args["display_name"], - iops_limit=parsed_iops, - bandwidth_limit=parsed_bandwidth, - size_limit=parsed_size, - ), - storage_service_name=module_args["storage_service"], - ) - api_obj.update_storage_class.assert_not_called() - api_obj.delete_storage_class.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageClassesApi") -def test_sc_create_op_fails(m_sc_api, m_op_api): - module_args = { - "state": "present", - "name": "sc1", - "display_name": "Storage Class 1", - "iops_limit": "2000000", - "bw_limit": "256G", - "size_limit": "2P", - "storage_service": "ss1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - parsed_size = 2251799813685248 - parsed_bandwidth = 274877906944 - parsed_iops = 2000000 - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_class = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_storage_class = MagicMock(return_value=OperationMock(1)) - api_obj.update_storage_class = MagicMock(return_value=OperationMock(2)) - api_obj.delete_storage_class = MagicMock(return_value=OperationMock(3)) - m_sc_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(OperationException): - fusion_sc.main() - - # check api was called correctly - api_obj.get_storage_class.assert_called_once_with( - storage_class_name=module_args["name"], - storage_service_name=module_args["storage_service"], - ) - api_obj.create_storage_class.assert_called_once_with( - purefusion.StorageClassPost( - name=module_args["name"], - display_name=module_args["display_name"], - iops_limit=parsed_iops, - bandwidth_limit=parsed_bandwidth, - size_limit=parsed_size, - ), - storage_service_name=module_args["storage_service"], - ) - api_obj.update_storage_class.assert_not_called() - api_obj.delete_storage_class.assert_not_called() - op_obj.get_operation.assert_called_once_with(1) - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageClassesApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, OperationException), - ], -) -def test_sc_create_op_exception(m_sc_api, m_op_api, exec_original, exec_catch): - module_args = { - "state": "present", - "name": "sc1", - "display_name": "Storage Class 1", - "iops_limit": "2000000", - "bw_limit": "256G", - "size_limit": "2P", - "storage_service": "ss1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - parsed_size = 2251799813685248 - parsed_bandwidth = 274877906944 - parsed_iops = 2000000 - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_class = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_storage_class = MagicMock(return_value=OperationMock(1)) - api_obj.update_storage_class = MagicMock(return_value=OperationMock(2)) - api_obj.delete_storage_class = MagicMock(return_value=OperationMock(3)) - m_sc_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(side_effect=exec_original) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_sc.main() - - # check api was called correctly - api_obj.get_storage_class.assert_called_once_with( - storage_class_name=module_args["name"], - storage_service_name=module_args["storage_service"], - ) - api_obj.create_storage_class.assert_called_once_with( - purefusion.StorageClassPost( - name=module_args["name"], - display_name=module_args["display_name"], - iops_limit=parsed_iops, - bandwidth_limit=parsed_bandwidth, - size_limit=parsed_size, - ), - storage_service_name=module_args["storage_service"], - ) - api_obj.update_storage_class.assert_not_called() - api_obj.delete_storage_class.assert_not_called() - op_obj.get_operation.assert_called_once_with(1) - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageClassesApi") -def test_sc_update(m_sc_api, m_op_api): - module_args = { - "state": "present", - "name": "sc1", - "display_name": "Storage Class 1", - "iops_limit": "2000000", - "bw_limit": "256G", - "size_limit": "2P", - "storage_service": "ss1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - current_sc = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], # name must match - "display_name": None, - "iops_limit": "2000000", - "bandwidth_limit": "256G", - "size_limit": "2P", - "storage_service": module_args["storage_service"], - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_class = MagicMock( - return_value=purefusion.StorageClass(**current_sc) - ) - api_obj.create_storage_class = MagicMock(return_value=OperationMock(1)) - api_obj.update_storage_class = MagicMock(return_value=OperationMock(2)) - api_obj.delete_storage_class = MagicMock(return_value=OperationMock(3)) - m_sc_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_sc.main() - - assert exc.value.changed - assert exc.value.id == current_sc["id"] - - # check api was called correctly - api_obj.get_storage_class.assert_called_once_with( - storage_class_name=module_args["name"], - storage_service_name=module_args["storage_service"], - ) - api_obj.create_storage_class.assert_not_called() - api_obj.update_storage_class.assert_called_once_with( - purefusion.StorageClassPatch( - display_name=purefusion.NullableString(module_args["display_name"]) - ), - storage_class_name=module_args["name"], - storage_service_name=module_args["storage_service"], - ) - api_obj.delete_storage_class.assert_not_called() - op_obj.get_operation.assert_called_once_with(2) - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageClassesApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, HTTPError), - ], -) -def test_sc_update_exception(m_sc_api, m_op_api, exec_original, exec_catch): - module_args = { - "state": "present", - "name": "sc1", - "display_name": "Storage Class 1", - "iops_limit": "2000000", - "bw_limit": "256G", - "size_limit": "2P", - "storage_service": "ss1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - current_sc = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], # name must match - "display_name": None, - "iops_limit": "2000000", - "bandwidth_limit": "256G", - "size_limit": "2P", - "storage_service": module_args["storage_service"], - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_class = MagicMock( - return_value=purefusion.StorageClass(**current_sc) - ) - api_obj.create_storage_class = MagicMock(return_value=OperationMock(1)) - api_obj.update_storage_class = MagicMock(side_effect=exec_original) - api_obj.delete_storage_class = MagicMock(return_value=OperationMock(3)) - m_sc_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_sc.main() - - # check api was called correctly - api_obj.get_storage_class.assert_called_once_with( - storage_class_name=module_args["name"], - storage_service_name=module_args["storage_service"], - ) - api_obj.create_storage_class.assert_not_called() - api_obj.update_storage_class.assert_called_once_with( - purefusion.StorageClassPatch( - display_name=purefusion.NullableString(module_args["display_name"]) - ), - storage_class_name=module_args["name"], - storage_service_name=module_args["storage_service"], - ) - api_obj.delete_storage_class.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageClassesApi") -def test_sc_update_op_fails(m_sc_api, m_op_api): - module_args = { - "state": "present", - "name": "sc1", - "display_name": "Storage Class 1", - "iops_limit": "2000000", - "bw_limit": "256G", - "size_limit": "2P", - "storage_service": "ss1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - current_sc = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], # name must match - "display_name": None, - "iops_limit": "2000000", - "bandwidth_limit": "256G", - "size_limit": "2P", - "storage_service": module_args["storage_service"], - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_class = MagicMock( - return_value=purefusion.StorageClass(**current_sc) - ) - api_obj.create_storage_class = MagicMock(return_value=OperationMock(1)) - api_obj.update_storage_class = MagicMock(return_value=OperationMock(2)) - api_obj.delete_storage_class = MagicMock(return_value=OperationMock(3)) - m_sc_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(OperationException): - fusion_sc.main() - - # check api was called correctly - api_obj.get_storage_class.assert_called_once_with( - storage_class_name=module_args["name"], - storage_service_name=module_args["storage_service"], - ) - api_obj.create_storage_class.assert_not_called() - api_obj.update_storage_class.assert_called_once_with( - purefusion.StorageClassPatch( - display_name=purefusion.NullableString(module_args["display_name"]) - ), - storage_class_name=module_args["name"], - storage_service_name=module_args["storage_service"], - ) - api_obj.delete_storage_class.assert_not_called() - op_obj.get_operation.assert_called_once_with(2) - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageClassesApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, OperationException), - ], -) -def test_sc_update_op_exception(m_sc_api, m_op_api, exec_original, exec_catch): - module_args = { - "state": "present", - "name": "sc1", - "display_name": "Storage Class 1", - "iops_limit": "2000000", - "bw_limit": "256G", - "size_limit": "2P", - "storage_service": "ss1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - current_sc = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], # name must match - "display_name": None, - "iops_limit": "2000000", - "bandwidth_limit": "256G", - "size_limit": "2P", - "storage_service": module_args["storage_service"], - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_class = MagicMock( - return_value=purefusion.StorageClass(**current_sc) - ) - api_obj.create_storage_class = MagicMock(return_value=OperationMock(1)) - api_obj.update_storage_class = MagicMock(return_value=OperationMock(2)) - api_obj.delete_storage_class = MagicMock(return_value=OperationMock(3)) - m_sc_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(side_effect=exec_original) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_sc.main() - - # check api was called correctly - api_obj.get_storage_class.assert_called_once_with( - storage_class_name=module_args["name"], - storage_service_name=module_args["storage_service"], - ) - api_obj.create_storage_class.assert_not_called() - api_obj.update_storage_class.assert_called_once_with( - purefusion.StorageClassPatch( - display_name=purefusion.NullableString(module_args["display_name"]) - ), - storage_class_name=module_args["name"], - storage_service_name=module_args["storage_service"], - ) - api_obj.delete_storage_class.assert_not_called() - op_obj.get_operation.assert_called_once_with(2) - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageClassesApi") -def test_sc_present_not_changed(m_sc_api, m_op_api): - module_args = { - "state": "present", - "name": "sc1", - "display_name": "Storage Class 1", - "iops_limit": "2000000", - "bw_limit": "256G", - "size_limit": "2P", - "storage_service": "ss1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - current_sc = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], # name must match - "display_name": module_args["display_name"], - "iops_limit": "2000000", - "bandwidth_limit": "256G", - "size_limit": "2P", - "storage_service": module_args["storage_service"], - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_class = MagicMock( - return_value=purefusion.StorageClass(**current_sc) - ) - api_obj.create_storage_class = MagicMock(return_value=OperationMock(1)) - api_obj.update_storage_class = MagicMock(return_value=OperationMock(2)) - api_obj.delete_storage_class = MagicMock(return_value=OperationMock(3)) - m_sc_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_sc.main() - - assert not exc.value.changed - - # check api was called correctly - api_obj.get_storage_class.assert_called_once_with( - storage_class_name=module_args["name"], - storage_service_name=module_args["storage_service"], - ) - api_obj.create_storage_class.assert_not_called() - api_obj.update_storage_class.assert_not_called() - api_obj.delete_storage_class.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageClassesApi") -def test_sc_absent_not_changed(m_sc_api, m_op_api): - module_args = { - "state": "absent", - "name": "sc1", - "display_name": "Storage Class 1", - "iops_limit": "2000000", - "bw_limit": "256G", - "size_limit": "2P", - "storage_service": "ss1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_class = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_storage_class = MagicMock(return_value=OperationMock(1)) - api_obj.update_storage_class = MagicMock(return_value=OperationMock(2)) - api_obj.delete_storage_class = MagicMock(return_value=OperationMock(3)) - m_sc_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_sc.main() - - assert not exc.value.changed - - # check api was called correctly - api_obj.get_storage_class.assert_called_once_with( - storage_class_name=module_args["name"], - storage_service_name=module_args["storage_service"], - ) - api_obj.create_storage_class.assert_not_called() - api_obj.update_storage_class.assert_not_called() - api_obj.delete_storage_class.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageClassesApi") -def test_sc_update_limits_not_changed(m_sc_api, m_op_api): - module_args = { - "state": "present", - "name": "sc1", - "display_name": "Storage Class 1", - "iops_limit": "2000000", - "bw_limit": "256G", - "size_limit": "2P", - "storage_service": "ss1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - current_sc = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], # name must match - "display_name": module_args["display_name"], - "iops_limit": "1500000", # does not match but shouldn't be updated! - "bandwidth_limit": "300G", # does not match but shouldn't be updated! - "size_limit": "1P", # does not match but shouldn't be updated! - "storage_service": module_args["storage_service"], - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_class = MagicMock( - return_value=purefusion.StorageClass(**current_sc) - ) - api_obj.create_storage_class = MagicMock(return_value=OperationMock(1)) - api_obj.update_storage_class = MagicMock(return_value=OperationMock(2)) - api_obj.delete_storage_class = MagicMock(return_value=OperationMock(3)) - m_sc_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_sc.main() - - assert not exc.value.changed - - # check api was called correctly - api_obj.get_storage_class.assert_called_once_with( - storage_class_name=module_args["name"], - storage_service_name=module_args["storage_service"], - ) - api_obj.create_storage_class.assert_not_called() - api_obj.update_storage_class.assert_not_called() - api_obj.delete_storage_class.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageClassesApi") -def test_sc_delete(m_sc_api, m_op_api): - module_args = { - "state": "absent", - "name": "sc1", - "display_name": "Storage Class 1", - "iops_limit": "2000000", - "bw_limit": "256G", - "size_limit": "2P", - "storage_service": "ss1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - current_sc = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], # name must match - "display_name": None, - "iops_limit": "2000000", - "bandwidth_limit": "256G", - "size_limit": "2P", - "storage_service": module_args["storage_service"], - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_class = MagicMock( - return_value=purefusion.StorageClass(**current_sc) - ) - api_obj.create_storage_class = MagicMock(return_value=OperationMock(1)) - api_obj.update_storage_class = MagicMock(return_value=OperationMock(2)) - api_obj.delete_storage_class = MagicMock(return_value=OperationMock(3)) - m_sc_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_sc.main() - - assert exc.value.changed - - # check api was called correctly - api_obj.get_storage_class.assert_called_once_with( - storage_class_name=module_args["name"], - storage_service_name=module_args["storage_service"], - ) - api_obj.create_storage_class.assert_not_called() - api_obj.update_storage_class.assert_not_called() - api_obj.delete_storage_class.assert_called_once_with( - storage_class_name=module_args["name"], - storage_service_name=module_args["storage_service"], - ) - op_obj.get_operation.assert_called_once_with(3) - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageClassesApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, HTTPError), - ], -) -def test_sc_delete_exception(m_sc_api, m_op_api, exec_original, exec_catch): - module_args = { - "state": "absent", - "name": "sc1", - "display_name": "Storage Class 1", - "iops_limit": "2000000", - "bw_limit": "256G", - "size_limit": "2P", - "storage_service": "ss1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - current_sc = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], # name must match - "display_name": None, - "iops_limit": "2000000", - "bandwidth_limit": "256G", - "size_limit": "2P", - "storage_service": module_args["storage_service"], - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_class = MagicMock( - return_value=purefusion.StorageClass(**current_sc) - ) - api_obj.create_storage_class = MagicMock(return_value=OperationMock(1)) - api_obj.update_storage_class = MagicMock(return_value=OperationMock(2)) - api_obj.delete_storage_class = MagicMock(side_effect=exec_original) - m_sc_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_sc.main() - - # check api was called correctly - api_obj.get_storage_class.assert_called_once_with( - storage_class_name=module_args["name"], - storage_service_name=module_args["storage_service"], - ) - api_obj.create_storage_class.assert_not_called() - api_obj.update_storage_class.assert_not_called() - api_obj.delete_storage_class.assert_called_once_with( - storage_class_name=module_args["name"], - storage_service_name=module_args["storage_service"], - ) - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageClassesApi") -def test_sc_delete_op_fails(m_sc_api, m_op_api): - module_args = { - "state": "absent", - "name": "sc1", - "display_name": "Storage Class 1", - "iops_limit": "2000000", - "bw_limit": "256G", - "size_limit": "2P", - "storage_service": "ss1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - current_sc = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], # name must match - "display_name": None, - "iops_limit": "2000000", - "bandwidth_limit": "256G", - "size_limit": "2P", - "storage_service": module_args["storage_service"], - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_class = MagicMock( - return_value=purefusion.StorageClass(**current_sc) - ) - api_obj.create_storage_class = MagicMock(return_value=OperationMock(1)) - api_obj.update_storage_class = MagicMock(return_value=OperationMock(2)) - api_obj.delete_storage_class = MagicMock(return_value=OperationMock(3)) - m_sc_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(OperationException): - fusion_sc.main() - - # check api was called correctly - api_obj.get_storage_class.assert_called_once_with( - storage_class_name=module_args["name"], - storage_service_name=module_args["storage_service"], - ) - api_obj.create_storage_class.assert_not_called() - api_obj.update_storage_class.assert_not_called() - api_obj.delete_storage_class.assert_called_once_with( - storage_class_name=module_args["name"], - storage_service_name=module_args["storage_service"], - ) - op_obj.get_operation.assert_called_once_with(3) - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageClassesApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, OperationException), - ], -) -def test_sc_delete_op_exception(m_sc_api, m_op_api, exec_original, exec_catch): - module_args = { - "state": "absent", - "name": "sc1", - "display_name": "Storage Class 1", - "iops_limit": "2000000", - "bw_limit": "256G", - "size_limit": "2P", - "storage_service": "ss1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - current_sc = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], # name must match - "display_name": None, - "iops_limit": "2000000", - "bandwidth_limit": "256G", - "size_limit": "2P", - "storage_service": module_args["storage_service"], - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_class = MagicMock( - return_value=purefusion.StorageClass(**current_sc) - ) - api_obj.create_storage_class = MagicMock(return_value=OperationMock(1)) - api_obj.update_storage_class = MagicMock(return_value=OperationMock(2)) - api_obj.delete_storage_class = MagicMock(return_value=OperationMock(3)) - m_sc_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(side_effect=exec_original) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_sc.main() - - # check api was called correctly - api_obj.get_storage_class.assert_called_once_with( - storage_class_name=module_args["name"], - storage_service_name=module_args["storage_service"], - ) - api_obj.create_storage_class.assert_not_called() - api_obj.update_storage_class.assert_not_called() - api_obj.delete_storage_class.assert_called_once_with( - storage_class_name=module_args["name"], - storage_service_name=module_args["storage_service"], - ) - op_obj.get_operation.assert_called_once_with(3) diff --git a/ansible_collections/purestorage/fusion/tests/functional/test_fusion_se.py b/ansible_collections/purestorage/fusion/tests/functional/test_fusion_se.py deleted file mode 100644 index 9d9559c12..000000000 --- a/ansible_collections/purestorage/fusion/tests/functional/test_fusion_se.py +++ /dev/null @@ -1,1044 +0,0 @@ -# -*- coding: utf-8 -*- - -# (c) 2023, Andrej Pajtas (apajtas@purestorage.com) -# GNU General Public License v3.0+ (see COPYING.GPLv3 or https://www.gnu.org/licenses/gpl-3.0.txt) - -from __future__ import absolute_import, division, print_function - -__metaclass__ = type - -from unittest.mock import MagicMock, patch - -import fusion as purefusion -import pytest -from ansible.module_utils import basic -from ansible_collections.purestorage.fusion.plugins.module_utils.errors import ( - OperationException, -) -from ansible_collections.purestorage.fusion.plugins.modules import fusion_se -from ansible_collections.purestorage.fusion.tests.functional.utils import ( - AnsibleExitJson, - AnsibleFailJson, - FailedOperationMock, - OperationMock, - SuccessfulOperationMock, - FAKE_RESOURCE_ID, - exit_json, - fail_json, - set_module_args, -) -from urllib3.exceptions import HTTPError - -# GLOBAL MOCKS -fusion_se.setup_fusion = MagicMock(return_value=purefusion.api_client.ApiClient()) -purefusion.api_client.ApiClient.call_api = MagicMock( - side_effect=Exception("API call not mocked!") -) -basic.AnsibleModule.exit_json = exit_json -basic.AnsibleModule.fail_json = fail_json - - -@pytest.fixture -def module_args(): - return { - "state": "present", - "name": "se1", - "display_name": "Storage Endpoint 1", - "region": "region1", - "availability_zone": "az1", - "iscsi": [ - { - "address": "10.21.200.124/24", - "gateway": "10.21.200.1", - "network_interface_groups": ["subnet-0", "subnet-1"], - } - ], - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - - -@pytest.fixture -def current_se(module_args): - return { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], - "display_name": module_args["display_name"], - "region": module_args["region"], - "availability_zone": module_args["availability_zone"], - "endpoint_type": "iscsi", - "iscsi": [ - dict(discovery_interface) for discovery_interface in module_args["iscsi"] - ], - } - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageEndpointsApi") -@pytest.mark.parametrize( - "module_args", - [ - # required parameter 'name` is missing - { - "state": "present", - "display_name": "Storage Endpoint 1", - "region": "region1", - "availability_zone": "az1", - "iscsi": [ - { - "address": "10.21.200.124/24", - "gateway": "10.21.200.1", - "network_interface_groups": ["subnet-0", "subnet-1"], - } - ], - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - # required parameter 'region` is missing - { - "state": "present", - "name": "se1", - "display_name": "Storage Endpoint 1", - "availability_zone": "az1", - "iscsi": [ - { - "address": "10.21.200.124/24", - "gateway": "10.21.200.1", - "network_interface_groups": ["subnet-0", "subnet-1"], - } - ], - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - # required parameter 'availability_zone` is missing - { - "state": "present", - "name": "se1", - "display_name": "Storage Endpoint 1", - "region": "region1", - "iscsi": [ - { - "address": "10.21.200.124/24", - "gateway": "10.21.200.1", - "network_interface_groups": ["subnet-0", "subnet-1"], - } - ], - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - # unknown parameter 'extra' is provided - { - "state": "present", - "name": "se1", - "display_name": "Storage Endpoint 1", - "region": "region1", - "availability_zone": "az1", - "iscsi": [ - { - "address": "10.21.200.124/24", - "gateway": "10.21.200.1", - "network_interface_groups": ["subnet-0", "subnet-1"], - } - ], - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - "extra": "value", - }, - # parameter 'state` has incorrect value - { - "state": "cool", - "name": "se1", - "display_name": "Storage Endpoint 1", - "region": "region1", - "availability_zone": "az1", - "iscsi": [ - { - "address": "10.21.200.124/24", - "gateway": "10.21.200.1", - "network_interface_groups": ["subnet-0", "subnet-1"], - } - ], - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - # parameter 'iscsi` and 'cbs_azure_iscsi' are used at the same time - { - "state": "present", - "name": "se1", - "display_name": "Storage Endpoint 1", - "region": "region1", - "availability_zone": "az1", - "iscsi": [ - { - "address": "10.21.200.124/24", - "gateway": "10.21.200.1", - "network_interface_groups": ["subnet-0", "subnet-1"], - } - ], - "cbs_azure_iscsi": { - "storage_endpoint_collection_identity": "/subscriptions/sub/resourcegroups/sec/providers/ms/userAssignedIdentities/secId", - "load_balancer": "/subscriptions/sub/resourcegroups/sec/providers/ms/loadBalancers/sec-lb", - "load_balancer_addresses": [], - }, - "app_id": "ABCD1234", - "key_file": "private-key.pem", - }, - # parameter 'cbs_azure_iscsi' has invalid address - { - "state": "present", - "name": "se1", - "display_name": "Storage Endpoint 1", - "region": "region1", - "availability_zone": "az1", - "cbs_azure_iscsi": { - "storage_endpoint_collection_identity": "/subscriptions/sub/resourcegroups/sec/providers/ms/userAssignedIdentities/secId", - "load_balancer": "/subscriptions/sub/resourcegroups/sec/providers/ms/loadBalancers/sec-lb", - "load_balancer_addresses": ["not an address"], - }, - "app_id": "ABCD1234", - "key_file": "private-key.pem", - }, - # parameter 'iscsi' has invalid 'gateway' address - { - "state": "present", - "name": "se1", - "display_name": "Storage Endpoint 1", - "region": "region1", - "availability_zone": "az1", - "iscsi": [ - { - "address": "10.21.200.124/24", - "gateway": "not an address", - "network_interface_groups": ["subnet-0", "subnet-1"], - } - ], - "app_id": "ABCD1234", - "key_file": "private-key.pem", - }, - # parameter 'iscsi' has invalid 'address' address - { - "state": "present", - "name": "se1", - "display_name": "Storage Endpoint 1", - "region": "region1", - "availability_zone": "az1", - "iscsi": [ - { - "address": "not an address", - "gateway": "10.21.200.1", - "network_interface_groups": ["subnet-0", "subnet-1"], - } - ], - "app_id": "ABCD1234", - "key_file": "private-key.pem", - }, - ], -) -def test_module_fails_on_wrong_parameters(m_se_api, m_op_api, module_args): - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_endpoint = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_storage_endpoint = MagicMock(return_value=OperationMock(1)) - api_obj.update_storage_endpoint = MagicMock(return_value=OperationMock(2)) - api_obj.delete_storage_endpoint = MagicMock(return_value=OperationMock(3)) - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - m_se_api.return_value = api_obj - - # run module - with pytest.raises(AnsibleFailJson): - fusion_se.main() - - # check api was not called at all - api_obj.get_storage_endpoint.assert_not_called() - api_obj.create_storage_endpoint.assert_not_called() - api_obj.update_storage_endpoint.assert_not_called() - api_obj.delete_storage_endpoint.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageEndpointsApi") -def test_se_create_iscsi(m_se_api, m_op_api, module_args): - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_endpoint = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_storage_endpoint = MagicMock(return_value=OperationMock(1)) - api_obj.update_storage_endpoint = MagicMock(return_value=OperationMock(2)) - api_obj.delete_storage_endpoint = MagicMock(return_value=OperationMock(3)) - m_se_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_se.main() - - assert exc.value.changed - assert exc.value.id == FAKE_RESOURCE_ID - - # check api was called correctly - api_obj.get_storage_endpoint.assert_called_once_with( - region_name=module_args["region"], - storage_endpoint_name=module_args["name"], - availability_zone_name=module_args["availability_zone"], - ) - api_obj.create_storage_endpoint.assert_called_once_with( - purefusion.StorageEndpointPost( - name=module_args["name"], - display_name=module_args["display_name"], - endpoint_type="iscsi", - iscsi=purefusion.StorageEndpointIscsiPost( - discovery_interfaces=[ - purefusion.StorageEndpointIscsiDiscoveryInterfacePost(**endpoint) - for endpoint in module_args["iscsi"] - ] - ), - ), - region_name=module_args["region"], - availability_zone_name=module_args["availability_zone"], - ) - api_obj.update_storage_endpoint.assert_not_called() - api_obj.delete_storage_endpoint.assert_not_called() - op_obj.get_operation.assert_called_once_with(1) - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageEndpointsApi") -def test_se_create_cbs_azure_iscsi(m_se_api, m_op_api, module_args): - del module_args["iscsi"] - module_args["cbs_azure_iscsi"] = { - "storage_endpoint_collection_identity": "/subscriptions/sub/resourcegroups/sec/providers/ms/userAssignedIdentities/secId", - "load_balancer": "/subscriptions/sub/resourcegroups/sec/providers/ms/loadBalancers/sec-lb", - "load_balancer_addresses": ["234.1.2.3"], - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_endpoint = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_storage_endpoint = MagicMock(return_value=OperationMock(1)) - api_obj.update_storage_endpoint = MagicMock(return_value=OperationMock(2)) - api_obj.delete_storage_endpoint = MagicMock(return_value=OperationMock(3)) - m_se_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_se.main() - - assert exc.value.changed is True - assert exc.value.id == FAKE_RESOURCE_ID - - # check api was called correctly - api_obj.get_storage_endpoint.assert_called_once_with( - region_name=module_args["region"], - storage_endpoint_name=module_args["name"], - availability_zone_name=module_args["availability_zone"], - ) - api_obj.create_storage_endpoint.assert_called_once_with( - purefusion.StorageEndpointPost( - name=module_args["name"], - display_name=module_args["display_name"], - endpoint_type="cbs-azure-iscsi", - cbs_azure_iscsi=purefusion.StorageEndpointCbsAzureIscsiPost( - storage_endpoint_collection_identity=module_args["cbs_azure_iscsi"][ - "storage_endpoint_collection_identity" - ], - load_balancer=module_args["cbs_azure_iscsi"]["load_balancer"], - load_balancer_addresses=module_args["cbs_azure_iscsi"][ - "load_balancer_addresses" - ], - ), - ), - region_name=module_args["region"], - availability_zone_name=module_args["availability_zone"], - ) - api_obj.update_storage_endpoint.assert_not_called() - api_obj.delete_storage_endpoint.assert_not_called() - op_obj.get_operation.assert_called_once_with(1) - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageEndpointsApi") -def test_se_create_without_display_name(m_se_api, m_op_api, module_args): - del module_args["display_name"] - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_endpoint = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_storage_endpoint = MagicMock(return_value=OperationMock(1)) - api_obj.update_storage_endpoint = MagicMock(return_value=OperationMock(2)) - api_obj.delete_storage_endpoint = MagicMock(return_value=OperationMock(3)) - m_se_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_se.main() - - assert exc.value.changed - assert exc.value.id == FAKE_RESOURCE_ID - - # check api was called correctly - api_obj.get_storage_endpoint.assert_called_once_with( - region_name=module_args["region"], - storage_endpoint_name=module_args["name"], - availability_zone_name=module_args["availability_zone"], - ) - api_obj.create_storage_endpoint.assert_called_once_with( - purefusion.StorageEndpointPost( - name=module_args["name"], - display_name=module_args["name"], - endpoint_type="iscsi", - iscsi=purefusion.StorageEndpointIscsiPost( - discovery_interfaces=[ - purefusion.StorageEndpointIscsiDiscoveryInterfacePost(**endpoint) - for endpoint in module_args["iscsi"] - ] - ), - ), - region_name=module_args["region"], - availability_zone_name=module_args["availability_zone"], - ) - api_obj.update_storage_endpoint.assert_not_called() - api_obj.delete_storage_endpoint.assert_not_called() - op_obj.get_operation.assert_called_once_with(1) - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageEndpointsApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, HTTPError), - ], -) -def test_se_create_exception( - m_se_api, m_op_api, exec_original, exec_catch, module_args -): - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_endpoint = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_storage_endpoint = MagicMock(side_effect=exec_original) - api_obj.update_storage_endpoint = MagicMock(return_value=OperationMock(2)) - api_obj.delete_storage_endpoint = MagicMock(return_value=OperationMock(3)) - m_se_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_se.main() - - # check api was called correctly - api_obj.get_storage_endpoint.assert_called_once_with( - region_name=module_args["region"], - storage_endpoint_name=module_args["name"], - availability_zone_name=module_args["availability_zone"], - ) - api_obj.create_storage_endpoint.assert_called_once_with( - purefusion.StorageEndpointPost( - name=module_args["name"], - display_name=module_args["display_name"], - endpoint_type="iscsi", - iscsi=purefusion.StorageEndpointIscsiPost( - discovery_interfaces=[ - purefusion.StorageEndpointIscsiDiscoveryInterfacePost(**endpoint) - for endpoint in module_args["iscsi"] - ] - ), - ), - region_name=module_args["region"], - availability_zone_name=module_args["availability_zone"], - ) - api_obj.update_storage_endpoint.assert_not_called() - api_obj.delete_storage_endpoint.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageEndpointsApi") -def test_se_create_op_fails(m_se_api, m_op_api, module_args): - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_endpoint = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_storage_endpoint = MagicMock(return_value=OperationMock(1)) - api_obj.update_storage_endpoint = MagicMock(return_value=OperationMock(2)) - api_obj.delete_storage_endpoint = MagicMock(return_value=OperationMock(3)) - m_se_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(OperationException): - fusion_se.main() - - # check api was called correctly - api_obj.get_storage_endpoint.assert_called_once_with( - region_name=module_args["region"], - storage_endpoint_name=module_args["name"], - availability_zone_name=module_args["availability_zone"], - ) - api_obj.create_storage_endpoint.assert_called_once_with( - purefusion.StorageEndpointPost( - name=module_args["name"], - display_name=module_args["display_name"], - endpoint_type="iscsi", - iscsi=purefusion.StorageEndpointIscsiPost( - discovery_interfaces=[ - purefusion.StorageEndpointIscsiDiscoveryInterfacePost(**endpoint) - for endpoint in module_args["iscsi"] - ] - ), - ), - region_name=module_args["region"], - availability_zone_name=module_args["availability_zone"], - ) - api_obj.update_storage_endpoint.assert_not_called() - api_obj.delete_storage_endpoint.assert_not_called() - op_obj.get_operation.assert_called_once_with(1) - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageEndpointsApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, OperationException), - ], -) -def test_se_create_op_exception( - m_se_api, m_op_api, exec_original, exec_catch, module_args -): - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_endpoint = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_storage_endpoint = MagicMock(return_value=OperationMock(1)) - api_obj.update_storage_endpoint = MagicMock(return_value=OperationMock(2)) - api_obj.delete_storage_endpoint = MagicMock(return_value=OperationMock(3)) - m_se_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(side_effect=exec_original) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_se.main() - - # check api was called correctly - api_obj.get_storage_endpoint.assert_called_once_with( - region_name=module_args["region"], - storage_endpoint_name=module_args["name"], - availability_zone_name=module_args["availability_zone"], - ) - api_obj.create_storage_endpoint.assert_called_once_with( - purefusion.StorageEndpointPost( - name=module_args["name"], - display_name=module_args["display_name"], - endpoint_type="iscsi", - iscsi=purefusion.StorageEndpointIscsiPost( - discovery_interfaces=[ - purefusion.StorageEndpointIscsiDiscoveryInterfacePost(**endpoint) - for endpoint in module_args["iscsi"] - ] - ), - ), - region_name=module_args["region"], - availability_zone_name=module_args["availability_zone"], - ) - api_obj.update_storage_endpoint.assert_not_called() - api_obj.delete_storage_endpoint.assert_not_called() - op_obj.get_operation.assert_called_once_with(1) - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageEndpointsApi") -def test_se_update(m_se_api, m_op_api, module_args, current_se): - current_se["display_name"] = None - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_endpoint = MagicMock( - return_value=purefusion.StorageEndpoint(**current_se) - ) - api_obj.create_storage_endpoint = MagicMock(return_value=OperationMock(1)) - api_obj.update_storage_endpoint = MagicMock(return_value=OperationMock(2)) - api_obj.delete_storage_endpoint = MagicMock(return_value=OperationMock(3)) - m_se_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_se.main() - - assert exc.value.changed - assert exc.value.id == current_se["id"] - - # check api was called correctly - api_obj.get_storage_endpoint.assert_called_once_with( - region_name=module_args["region"], - storage_endpoint_name=module_args["name"], - availability_zone_name=module_args["availability_zone"], - ) - api_obj.create_storage_endpoint.assert_not_called() - api_obj.update_storage_endpoint.assert_called_once_with( - purefusion.StorageEndpointPatch( - display_name=purefusion.NullableString(module_args["display_name"]) - ), - region_name=module_args["region"], - storage_endpoint_name=module_args["name"], - availability_zone_name=module_args["availability_zone"], - ) - api_obj.delete_storage_endpoint.assert_not_called() - op_obj.get_operation.assert_called_once_with(2) - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageEndpointsApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, HTTPError), - ], -) -def test_se_update_exception( - m_se_api, m_op_api, exec_original, exec_catch, module_args, current_se -): - current_se["display_name"] = None - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_endpoint = MagicMock( - return_value=purefusion.StorageEndpoint(**current_se) - ) - api_obj.create_storage_endpoint = MagicMock(return_value=OperationMock(1)) - api_obj.update_storage_endpoint = MagicMock(side_effect=exec_original) - api_obj.delete_storage_endpoint = MagicMock(return_value=OperationMock(3)) - m_se_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_se.main() - - # check api was called correctly - api_obj.get_storage_endpoint.assert_called_once_with( - region_name=module_args["region"], - storage_endpoint_name=module_args["name"], - availability_zone_name=module_args["availability_zone"], - ) - api_obj.create_storage_endpoint.assert_not_called() - api_obj.update_storage_endpoint.assert_called_once_with( - purefusion.StorageEndpointPatch( - display_name=purefusion.NullableString(module_args["display_name"]) - ), - region_name=module_args["region"], - storage_endpoint_name=module_args["name"], - availability_zone_name=module_args["availability_zone"], - ) - api_obj.delete_storage_endpoint.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageEndpointsApi") -def test_se_update_op_fails(m_se_api, m_op_api, module_args, current_se): - current_se["display_name"] = None - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_endpoint = MagicMock( - return_value=purefusion.StorageEndpoint(**current_se) - ) - api_obj.create_storage_endpoint = MagicMock(return_value=OperationMock(1)) - api_obj.update_storage_endpoint = MagicMock(return_value=OperationMock(2)) - api_obj.delete_storage_endpoint = MagicMock(return_value=OperationMock(3)) - m_se_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(OperationException): - fusion_se.main() - - # check api was called correctly - api_obj.get_storage_endpoint.assert_called_once_with( - region_name=module_args["region"], - storage_endpoint_name=module_args["name"], - availability_zone_name=module_args["availability_zone"], - ) - api_obj.create_storage_endpoint.assert_not_called() - api_obj.update_storage_endpoint.assert_called_once_with( - purefusion.StorageEndpointPatch( - display_name=purefusion.NullableString(module_args["display_name"]) - ), - region_name=module_args["region"], - storage_endpoint_name=module_args["name"], - availability_zone_name=module_args["availability_zone"], - ) - api_obj.delete_storage_endpoint.assert_not_called() - op_obj.get_operation.assert_called_once_with(2) - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageEndpointsApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, OperationException), - ], -) -def test_se_update_op_exception( - m_se_api, m_op_api, exec_original, exec_catch, module_args, current_se -): - current_se["display_name"] = None - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_endpoint = MagicMock( - return_value=purefusion.StorageEndpoint(**current_se) - ) - api_obj.create_storage_endpoint = MagicMock(return_value=OperationMock(1)) - api_obj.update_storage_endpoint = MagicMock(return_value=OperationMock(2)) - api_obj.delete_storage_endpoint = MagicMock(return_value=OperationMock(3)) - m_se_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(side_effect=exec_original) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_se.main() - - # check api was called correctly - api_obj.get_storage_endpoint.assert_called_once_with( - region_name=module_args["region"], - storage_endpoint_name=module_args["name"], - availability_zone_name=module_args["availability_zone"], - ) - api_obj.create_storage_endpoint.assert_not_called() - api_obj.update_storage_endpoint.assert_called_once_with( - purefusion.StorageEndpointPatch( - display_name=purefusion.NullableString(module_args["display_name"]) - ), - region_name=module_args["region"], - storage_endpoint_name=module_args["name"], - availability_zone_name=module_args["availability_zone"], - ) - api_obj.delete_storage_endpoint.assert_not_called() - op_obj.get_operation.assert_called_once_with(2) - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageEndpointsApi") -def test_se_present_not_changed(m_se_api, m_op_api, module_args, current_se): - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_endpoint = MagicMock( - return_value=purefusion.StorageEndpoint(**current_se) - ) - api_obj.create_storage_endpoint = MagicMock(return_value=OperationMock(1)) - api_obj.update_storage_endpoint = MagicMock(return_value=OperationMock(2)) - api_obj.delete_storage_endpoint = MagicMock(return_value=OperationMock(3)) - m_se_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_se.main() - - assert not exc.value.changed - - # check api was called correctly - api_obj.get_storage_endpoint.assert_called_once_with( - region_name=module_args["region"], - storage_endpoint_name=module_args["name"], - availability_zone_name=module_args["availability_zone"], - ) - api_obj.create_storage_endpoint.assert_not_called() - api_obj.update_storage_endpoint.assert_not_called() - api_obj.delete_storage_endpoint.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageEndpointsApi") -def test_se_absent_not_changed(m_se_api, m_op_api, module_args, current_se): - module_args["state"] = "absent" - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_endpoint = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_storage_endpoint = MagicMock(return_value=OperationMock(1)) - api_obj.update_storage_endpoint = MagicMock(return_value=OperationMock(2)) - api_obj.delete_storage_endpoint = MagicMock(return_value=OperationMock(3)) - m_se_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_se.main() - - assert not exc.value.changed - - # check api was called correctly - api_obj.get_storage_endpoint.assert_called_once_with( - region_name=module_args["region"], - storage_endpoint_name=module_args["name"], - availability_zone_name=module_args["availability_zone"], - ) - api_obj.create_storage_endpoint.assert_not_called() - api_obj.update_storage_endpoint.assert_not_called() - api_obj.delete_storage_endpoint.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageEndpointsApi") -def test_se_delete(m_se_api, m_op_api, module_args, current_se): - module_args["state"] = "absent" - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_endpoint = MagicMock( - return_value=purefusion.StorageEndpoint(**current_se) - ) - api_obj.create_storage_endpoint = MagicMock(return_value=OperationMock(1)) - api_obj.update_storage_endpoint = MagicMock(return_value=OperationMock(2)) - api_obj.delete_storage_endpoint = MagicMock(return_value=OperationMock(3)) - m_se_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_se.main() - - assert exc.value.changed - - # check api was called correctly - api_obj.get_storage_endpoint.assert_called_once_with( - region_name=module_args["region"], - storage_endpoint_name=module_args["name"], - availability_zone_name=module_args["availability_zone"], - ) - api_obj.create_storage_endpoint.assert_not_called() - api_obj.update_storage_endpoint.assert_not_called() - api_obj.delete_storage_endpoint.assert_called_once_with( - region_name=module_args["region"], - storage_endpoint_name=module_args["name"], - availability_zone_name=module_args["availability_zone"], - ) - op_obj.get_operation.assert_called_once_with(3) - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageEndpointsApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, HTTPError), - ], -) -def test_se_delete_exception( - m_se_api, m_op_api, exec_original, exec_catch, module_args, current_se -): - module_args["state"] = "absent" - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_endpoint = MagicMock( - return_value=purefusion.StorageEndpoint(**current_se) - ) - api_obj.create_storage_endpoint = MagicMock(return_value=OperationMock(1)) - api_obj.update_storage_endpoint = MagicMock(return_value=OperationMock(2)) - api_obj.delete_storage_endpoint = MagicMock(side_effect=exec_original) - m_se_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_se.main() - - # check api was called correctly - api_obj.get_storage_endpoint.assert_called_once_with( - region_name=module_args["region"], - storage_endpoint_name=module_args["name"], - availability_zone_name=module_args["availability_zone"], - ) - api_obj.create_storage_endpoint.assert_not_called() - api_obj.update_storage_endpoint.assert_not_called() - api_obj.delete_storage_endpoint.assert_called_once_with( - region_name=module_args["region"], - storage_endpoint_name=module_args["name"], - availability_zone_name=module_args["availability_zone"], - ) - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageEndpointsApi") -def test_se_delete_op_fails(m_se_api, m_op_api, module_args, current_se): - module_args["state"] = "absent" - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_endpoint = MagicMock( - return_value=purefusion.StorageEndpoint(**current_se) - ) - api_obj.create_storage_endpoint = MagicMock(return_value=OperationMock(1)) - api_obj.update_storage_endpoint = MagicMock(return_value=OperationMock(2)) - api_obj.delete_storage_endpoint = MagicMock(return_value=OperationMock(3)) - m_se_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(OperationException): - fusion_se.main() - - # check api was called correctly - api_obj.get_storage_endpoint.assert_called_once_with( - region_name=module_args["region"], - storage_endpoint_name=module_args["name"], - availability_zone_name=module_args["availability_zone"], - ) - api_obj.create_storage_endpoint.assert_not_called() - api_obj.update_storage_endpoint.assert_not_called() - api_obj.delete_storage_endpoint.assert_called_once_with( - region_name=module_args["region"], - storage_endpoint_name=module_args["name"], - availability_zone_name=module_args["availability_zone"], - ) - op_obj.get_operation.assert_called_once_with(3) - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageEndpointsApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, OperationException), - ], -) -def test_se_delete_op_exception( - m_se_api, m_op_api, exec_original, exec_catch, module_args, current_se -): - module_args["state"] = "absent" - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_endpoint = MagicMock( - return_value=purefusion.StorageEndpoint(**current_se) - ) - api_obj.create_storage_endpoint = MagicMock(return_value=OperationMock(1)) - api_obj.update_storage_endpoint = MagicMock(return_value=OperationMock(2)) - api_obj.delete_storage_endpoint = MagicMock(return_value=OperationMock(3)) - m_se_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(side_effect=exec_original) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_se.main() - - # check api was called correctly - api_obj.get_storage_endpoint.assert_called_once_with( - region_name=module_args["region"], - storage_endpoint_name=module_args["name"], - availability_zone_name=module_args["availability_zone"], - ) - api_obj.create_storage_endpoint.assert_not_called() - api_obj.update_storage_endpoint.assert_not_called() - api_obj.delete_storage_endpoint.assert_called_once_with( - region_name=module_args["region"], - storage_endpoint_name=module_args["name"], - availability_zone_name=module_args["availability_zone"], - ) - op_obj.get_operation.assert_called_once_with(3) diff --git a/ansible_collections/purestorage/fusion/tests/functional/test_fusion_ss.py b/ansible_collections/purestorage/fusion/tests/functional/test_fusion_ss.py deleted file mode 100644 index f1514b8e6..000000000 --- a/ansible_collections/purestorage/fusion/tests/functional/test_fusion_ss.py +++ /dev/null @@ -1,934 +0,0 @@ -# -*- coding: utf-8 -*- - -# (c) 2023, Andrej Pajtas (apajtas@purestorage.com) -# GNU General Public License v3.0+ (see COPYING.GPLv3 or https://www.gnu.org/licenses/gpl-3.0.txt) - -from __future__ import absolute_import, division, print_function - -__metaclass__ = type - -from unittest.mock import MagicMock, patch - -import fusion as purefusion -import pytest -from ansible.module_utils import basic -from ansible_collections.purestorage.fusion.plugins.module_utils.errors import ( - OperationException, -) -from ansible_collections.purestorage.fusion.plugins.modules import fusion_ss -from ansible_collections.purestorage.fusion.tests.functional.utils import ( - AnsibleExitJson, - AnsibleFailJson, - FailedOperationMock, - OperationMock, - SuccessfulOperationMock, - FAKE_RESOURCE_ID, - exit_json, - fail_json, - set_module_args, -) -from urllib3.exceptions import HTTPError - -# GLOBAL MOCKS -fusion_ss.setup_fusion = MagicMock(return_value=purefusion.api_client.ApiClient()) -purefusion.api_client.ApiClient.call_api = MagicMock( - side_effect=Exception("API call not mocked!") -) -basic.AnsibleModule.exit_json = exit_json -basic.AnsibleModule.fail_json = fail_json - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageServicesApi") -@pytest.mark.parametrize( - "module_args", - [ - # required parameter 'name` is missing - { - "state": "present", - "display_name": "Storage Service 1", - "hardware_types": ["flash-array-x"], - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - # unknown parameter 'extra' is provided - { - "state": "present", - "name": "ss1", - "display_name": "Storage Service 1", - "hardware_types": ["flash-array-x"], - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - "extra": "value", - }, - # parameter 'state` has incorrect value - { - "state": "cool", - "name": "ss1", - "display_name": "Storage Service 1", - "hardware_types": ["flash-array-x"], - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - # parameter 'hardware_types` has incorrect value - { - "state": "present", - "name": "ss1", - "display_name": "Storage Service 1", - "hardware_types": ["hdd-array-x"], - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - ], -) -def test_module_fails_on_wrong_parameters(m_ss_api, m_op_api, module_args): - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_service = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_storage_service = MagicMock(return_value=OperationMock(1)) - api_obj.update_storage_service = MagicMock(return_value=OperationMock(2)) - api_obj.delete_storage_service = MagicMock(return_value=OperationMock(3)) - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - m_ss_api.return_value = api_obj - - # run module - with pytest.raises(AnsibleFailJson): - fusion_ss.main() - - # check api was not called at all - api_obj.get_storage_service.assert_not_called() - api_obj.create_storage_service.assert_not_called() - api_obj.update_storage_service.assert_not_called() - api_obj.delete_storage_service.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageServicesApi") -def test_ss_create(m_ss_api, m_op_api): - module_args = { - "state": "present", - "name": "ss1", - "display_name": "Storage Service 1", - "hardware_types": ["flash-array-x"], - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_service = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_storage_service = MagicMock(return_value=OperationMock(1)) - api_obj.update_storage_service = MagicMock(return_value=OperationMock(2)) - api_obj.delete_storage_service = MagicMock(return_value=OperationMock(3)) - m_ss_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_ss.main() - - assert exc.value.changed - assert exc.value.id == FAKE_RESOURCE_ID - - # check api was called correctly - api_obj.get_storage_service.assert_called_once_with( - storage_service_name=module_args["name"] - ) - api_obj.create_storage_service.assert_called_once_with( - purefusion.StorageServicePost( - name=module_args["name"], - display_name=module_args["display_name"], - hardware_types=module_args["hardware_types"], - ) - ) - api_obj.update_storage_service.assert_not_called() - api_obj.delete_storage_service.assert_not_called() - op_obj.get_operation.assert_called_once_with(1) - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageServicesApi") -def test_ss_create_without_display_name(m_ss_api, m_op_api): - module_args = { - "state": "present", - "name": "ss1", - "hardware_types": ["flash-array-x"], - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_service = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_storage_service = MagicMock(return_value=OperationMock(1)) - api_obj.update_storage_service = MagicMock(return_value=OperationMock(2)) - api_obj.delete_storage_service = MagicMock(return_value=OperationMock(3)) - m_ss_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_ss.main() - - assert exc.value.changed - assert exc.value.id == FAKE_RESOURCE_ID - - # check api was called correctly - api_obj.get_storage_service.assert_called_once_with( - storage_service_name=module_args["name"] - ) - api_obj.create_storage_service.assert_called_once_with( - purefusion.StorageServicePost( - name=module_args["name"], - display_name=module_args["name"], - hardware_types=module_args["hardware_types"], - ) - ) - api_obj.update_storage_service.assert_not_called() - api_obj.delete_storage_service.assert_not_called() - op_obj.get_operation.assert_called_once_with(1) - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageServicesApi") -def test_array_create_without_hardware_type(m_ss_api, m_op_api): - module_args = { - "state": "present", - "name": "ss1", - "display_name": "Storage Service 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_service = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_storage_service = MagicMock(return_value=OperationMock(1)) - api_obj.update_storage_service = MagicMock(return_value=OperationMock(2)) - api_obj.delete_storage_service = MagicMock(return_value=OperationMock(3)) - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - m_ss_api.return_value = api_obj - - # run module - with pytest.raises(AnsibleFailJson): - fusion_ss.main() - - # check api was not called at all - api_obj.get_storage_service.assert_called_once_with( - storage_service_name=module_args["name"] - ) - api_obj.create_storage_service.assert_not_called() - api_obj.update_storage_service.assert_not_called() - api_obj.delete_storage_service.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageServicesApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, HTTPError), - ], -) -def test_ss_create_exception(m_ss_api, m_op_api, exec_original, exec_catch): - module_args = { - "state": "present", - "name": "ss1", - "display_name": "Storage Service 1", - "hardware_types": ["flash-array-x"], - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_service = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_storage_service = MagicMock(side_effect=exec_original) - api_obj.update_storage_service = MagicMock(return_value=OperationMock(2)) - api_obj.delete_storage_service = MagicMock(return_value=OperationMock(3)) - m_ss_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_ss.main() - - # check api was called correctly - api_obj.get_storage_service.assert_called_once_with( - storage_service_name=module_args["name"] - ) - api_obj.create_storage_service.assert_called_once_with( - purefusion.StorageServicePost( - name=module_args["name"], - display_name=module_args["display_name"], - hardware_types=module_args["hardware_types"], - ) - ) - api_obj.update_storage_service.assert_not_called() - api_obj.delete_storage_service.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageServicesApi") -def test_ss_create_op_fails(m_ss_api, m_op_api): - module_args = { - "state": "present", - "name": "ss1", - "display_name": "Storage Service 1", - "hardware_types": ["flash-array-x"], - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_service = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_storage_service = MagicMock(return_value=OperationMock(1)) - api_obj.update_storage_service = MagicMock(return_value=OperationMock(2)) - api_obj.delete_storage_service = MagicMock(return_value=OperationMock(3)) - m_ss_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(OperationException): - fusion_ss.main() - - # check api was called correctly - api_obj.get_storage_service.assert_called_once_with( - storage_service_name=module_args["name"] - ) - api_obj.create_storage_service.assert_called_once_with( - purefusion.StorageServicePost( - name=module_args["name"], - display_name=module_args["display_name"], - hardware_types=module_args["hardware_types"], - ) - ) - api_obj.update_storage_service.assert_not_called() - api_obj.delete_storage_service.assert_not_called() - op_obj.get_operation.assert_called_once_with(1) - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageServicesApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, OperationException), - ], -) -def test_ss_create_op_exception(m_ss_api, m_op_api, exec_original, exec_catch): - module_args = { - "state": "present", - "name": "ss1", - "display_name": "Storage Service 1", - "hardware_types": ["flash-array-x"], - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_service = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_storage_service = MagicMock(return_value=OperationMock(1)) - api_obj.update_storage_service = MagicMock(return_value=OperationMock(2)) - api_obj.delete_storage_service = MagicMock(return_value=OperationMock(3)) - m_ss_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(side_effect=exec_original) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_ss.main() - - # check api was called correctly - api_obj.get_storage_service.assert_called_once_with( - storage_service_name=module_args["name"] - ) - api_obj.create_storage_service.assert_called_once_with( - purefusion.StorageServicePost( - name=module_args["name"], - display_name=module_args["display_name"], - hardware_types=module_args["hardware_types"], - ) - ) - api_obj.update_storage_service.assert_not_called() - api_obj.delete_storage_service.assert_not_called() - op_obj.get_operation.assert_called_once_with(1) - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageServicesApi") -def test_ss_update(m_ss_api, m_op_api): - module_args = { - "state": "present", - "name": "ss1", - "display_name": "Storage Service 1", - "hardware_types": ["flash-array-x"], - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - current_ss = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], # name must match - "display_name": None, - "hardware_types": ["flash-array-c"], # is different but shouldn't be patched! - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_service = MagicMock( - return_value=purefusion.StorageService(**current_ss) - ) - api_obj.create_storage_service = MagicMock(return_value=OperationMock(1)) - api_obj.update_storage_service = MagicMock(return_value=OperationMock(2)) - api_obj.delete_storage_service = MagicMock(return_value=OperationMock(3)) - m_ss_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_ss.main() - - assert exc.value.changed - assert exc.value.id == current_ss["id"] - - # check api was called correctly - api_obj.get_storage_service.assert_called_once_with( - storage_service_name=module_args["name"] - ) - api_obj.create_storage_service.assert_not_called() - api_obj.update_storage_service.assert_called_once_with( - purefusion.StorageServicePatch( - display_name=purefusion.NullableString(module_args["display_name"]) - ), - storage_service_name=module_args["name"], - ) - api_obj.delete_storage_service.assert_not_called() - op_obj.get_operation.assert_called_once_with(2) - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageServicesApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, HTTPError), - ], -) -def test_ss_update_exception(m_ss_api, m_op_api, exec_original, exec_catch): - module_args = { - "state": "present", - "name": "ss1", - "display_name": "Storage Service 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - current_ss = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], # name must match - "display_name": None, - "hardware_types": ["flash-array-x"], - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_service = MagicMock( - return_value=purefusion.StorageService(**current_ss) - ) - api_obj.create_storage_service = MagicMock(return_value=OperationMock(1)) - api_obj.update_storage_service = MagicMock(side_effect=exec_original) - api_obj.delete_storage_service = MagicMock(return_value=OperationMock(3)) - m_ss_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_ss.main() - - # check api was called correctly - api_obj.get_storage_service.assert_called_once_with( - storage_service_name=module_args["name"] - ) - api_obj.create_storage_service.assert_not_called() - api_obj.update_storage_service.assert_called_once_with( - purefusion.StorageServicePatch( - display_name=purefusion.NullableString(module_args["display_name"]) - ), - storage_service_name=module_args["name"], - ) - api_obj.delete_storage_service.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageServicesApi") -def test_ss_update_op_fails(m_ss_api, m_op_api): - module_args = { - "state": "present", - "name": "ss1", - "display_name": "Storage Service 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - current_ss = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], # name must match - "display_name": None, - "hardware_types": ["flash-array-x"], - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_service = MagicMock( - return_value=purefusion.StorageService(**current_ss) - ) - api_obj.create_storage_service = MagicMock(return_value=OperationMock(1)) - api_obj.update_storage_service = MagicMock(return_value=OperationMock(2)) - api_obj.delete_storage_service = MagicMock(return_value=OperationMock(3)) - m_ss_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(OperationException): - fusion_ss.main() - - # check api was called correctly - api_obj.get_storage_service.assert_called_once_with( - storage_service_name=module_args["name"] - ) - api_obj.create_storage_service.assert_not_called() - api_obj.update_storage_service.assert_called_once_with( - purefusion.StorageServicePatch( - display_name=purefusion.NullableString(module_args["display_name"]) - ), - storage_service_name=module_args["name"], - ) - api_obj.delete_storage_service.assert_not_called() - op_obj.get_operation.assert_called_once_with(2) - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageServicesApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, OperationException), - ], -) -def test_ss_update_op_exception(m_ss_api, m_op_api, exec_original, exec_catch): - module_args = { - "state": "present", - "name": "ss1", - "display_name": "Storage Service 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - current_ss = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], # name must match - "display_name": None, - "hardware_types": ["flash-array-x"], - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_service = MagicMock( - return_value=purefusion.StorageService(**current_ss) - ) - api_obj.create_storage_service = MagicMock(return_value=OperationMock(1)) - api_obj.update_storage_service = MagicMock(return_value=OperationMock(2)) - api_obj.delete_storage_service = MagicMock(return_value=OperationMock(3)) - m_ss_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(side_effect=exec_original) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_ss.main() - - # check api was called correctly - api_obj.get_storage_service.assert_called_once_with( - storage_service_name=module_args["name"] - ) - api_obj.create_storage_service.assert_not_called() - api_obj.update_storage_service.assert_called_once_with( - purefusion.StorageServicePatch( - display_name=purefusion.NullableString(module_args["display_name"]) - ), - storage_service_name=module_args["name"], - ) - api_obj.delete_storage_service.assert_not_called() - op_obj.get_operation.assert_called_once_with(2) - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageServicesApi") -def test_ss_present_not_changed(m_ss_api, m_op_api): - module_args = { - "state": "present", - "name": "ss1", - "display_name": "Storage Service 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - current_ss = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], # name must match - "display_name": module_args["display_name"], - "hardware_types": ["flash-array-x"], - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_service = MagicMock( - return_value=purefusion.StorageService(**current_ss) - ) - api_obj.create_storage_service = MagicMock(return_value=OperationMock(1)) - api_obj.update_storage_service = MagicMock(return_value=OperationMock(2)) - api_obj.delete_storage_service = MagicMock(return_value=OperationMock(3)) - m_ss_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_ss.main() - - assert not exc.value.changed - - # check api was called correctly - api_obj.get_storage_service.assert_called_once_with( - storage_service_name=module_args["name"] - ) - api_obj.create_storage_service.assert_not_called() - api_obj.update_storage_service.assert_not_called() - api_obj.delete_storage_service.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageServicesApi") -def test_ss_absent_not_changed(m_ss_api, m_op_api): - module_args = { - "state": "absent", - "name": "ss1", - "display_name": "Storage Service 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_service = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_storage_service = MagicMock(return_value=OperationMock(1)) - api_obj.update_storage_service = MagicMock(return_value=OperationMock(2)) - api_obj.delete_storage_service = MagicMock(return_value=OperationMock(3)) - m_ss_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_ss.main() - - assert not exc.value.changed - - # check api was called correctly - api_obj.get_storage_service.assert_called_once_with( - storage_service_name=module_args["name"] - ) - api_obj.create_storage_service.assert_not_called() - api_obj.update_storage_service.assert_not_called() - api_obj.delete_storage_service.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageServicesApi") -def test_ss_delete(m_ss_api, m_op_api): - module_args = { - "state": "absent", - "name": "ss1", - "display_name": "Storage Service 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - current_ss = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], # name must match - "display_name": "different", # display_name doesn't match but UPDATE shouldn't be called - "hardware_types": ["flash-array-x"], - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_service = MagicMock( - return_value=purefusion.StorageService(**current_ss) - ) - api_obj.create_storage_service = MagicMock(return_value=OperationMock(1)) - api_obj.update_storage_service = MagicMock(return_value=OperationMock(2)) - api_obj.delete_storage_service = MagicMock(return_value=OperationMock(3)) - m_ss_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_ss.main() - - assert exc.value.changed - - # check api was called correctly - api_obj.get_storage_service.assert_called_once_with( - storage_service_name=module_args["name"] - ) - api_obj.create_storage_service.assert_not_called() - api_obj.update_storage_service.assert_not_called() - api_obj.delete_storage_service.assert_called_once_with( - storage_service_name=module_args["name"] - ) - op_obj.get_operation.assert_called_once_with(3) - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageServicesApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, HTTPError), - ], -) -def test_ss_delete_exception(m_ss_api, m_op_api, exec_original, exec_catch): - module_args = { - "state": "absent", - "name": "ss1", - "display_name": "Storage Service 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - current_ss = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], # name must match - "display_name": "different", # display_name doesn't match but UPDATE shouldn't be called - "hardware_types": ["flash-array-x"], - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_service = MagicMock( - return_value=purefusion.StorageService(**current_ss) - ) - api_obj.create_storage_service = MagicMock(return_value=OperationMock(1)) - api_obj.update_storage_service = MagicMock(return_value=OperationMock(2)) - api_obj.delete_storage_service = MagicMock(side_effect=exec_original) - m_ss_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_ss.main() - - # check api was called correctly - api_obj.get_storage_service.assert_called_once_with( - storage_service_name=module_args["name"] - ) - api_obj.create_storage_service.assert_not_called() - api_obj.update_storage_service.assert_not_called() - api_obj.delete_storage_service.assert_called_once_with( - storage_service_name=module_args["name"] - ) - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageServicesApi") -def test_ss_delete_op_fails(m_ss_api, m_op_api): - module_args = { - "state": "absent", - "name": "ss1", - "display_name": "Storage Service 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - current_ss = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], # name must match - "display_name": "different", # display_name doesn't match but UPDATE shouldn't be called - "hardware_types": ["flash-array-x"], - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_service = MagicMock( - return_value=purefusion.StorageService(**current_ss) - ) - api_obj.create_storage_service = MagicMock(return_value=OperationMock(1)) - api_obj.update_storage_service = MagicMock(return_value=OperationMock(2)) - api_obj.delete_storage_service = MagicMock(return_value=OperationMock(3)) - m_ss_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(OperationException): - fusion_ss.main() - - # check api was called correctly - api_obj.get_storage_service.assert_called_once_with( - storage_service_name=module_args["name"] - ) - api_obj.create_storage_service.assert_not_called() - api_obj.update_storage_service.assert_not_called() - api_obj.delete_storage_service.assert_called_once_with( - storage_service_name=module_args["name"] - ) - op_obj.get_operation.assert_called_once_with(3) - - -@patch("fusion.OperationsApi") -@patch("fusion.StorageServicesApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, OperationException), - ], -) -def test_ss_delete_op_exception(m_ss_api, m_op_api, exec_original, exec_catch): - module_args = { - "state": "absent", - "name": "ss1", - "display_name": "Storage Service 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - current_ss = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], # name must match - "display_name": "different", # display_name doesn't match but UPDATE shouldn't be called - "hardware_types": ["flash-array-x"], - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_storage_service = MagicMock( - return_value=purefusion.StorageService(**current_ss) - ) - api_obj.create_storage_service = MagicMock(return_value=OperationMock(1)) - api_obj.update_storage_service = MagicMock(return_value=OperationMock(2)) - api_obj.delete_storage_service = MagicMock(return_value=OperationMock(3)) - m_ss_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(side_effect=exec_original) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_ss.main() - - # check api was called correctly - api_obj.get_storage_service.assert_called_once_with( - storage_service_name=module_args["name"] - ) - api_obj.create_storage_service.assert_not_called() - api_obj.update_storage_service.assert_not_called() - api_obj.delete_storage_service.assert_called_once_with( - storage_service_name=module_args["name"] - ) - op_obj.get_operation.assert_called_once_with(3) diff --git a/ansible_collections/purestorage/fusion/tests/functional/test_fusion_tenant.py b/ansible_collections/purestorage/fusion/tests/functional/test_fusion_tenant.py deleted file mode 100644 index 11cd71171..000000000 --- a/ansible_collections/purestorage/fusion/tests/functional/test_fusion_tenant.py +++ /dev/null @@ -1,807 +0,0 @@ -# -*- coding: utf-8 -*- - -# (c) 2023, Andrej Pajtas (apajtas@purestorage.com) -# GNU General Public License v3.0+ (see COPYING.GPLv3 or https://www.gnu.org/licenses/gpl-3.0.txt) - -from __future__ import absolute_import, division, print_function - -__metaclass__ = type - -from unittest.mock import MagicMock, patch - -import fusion as purefusion -import pytest -from ansible.module_utils import basic -from ansible_collections.purestorage.fusion.plugins.module_utils.errors import ( - OperationException, -) -from ansible_collections.purestorage.fusion.plugins.modules import fusion_tenant -from ansible_collections.purestorage.fusion.tests.functional.utils import ( - AnsibleExitJson, - AnsibleFailJson, - FailedOperationMock, - OperationMock, - SuccessfulOperationMock, - FAKE_RESOURCE_ID, - exit_json, - fail_json, - set_module_args, -) -from urllib3.exceptions import HTTPError - -# GLOBAL MOCKS -fusion_tenant.setup_fusion = MagicMock(return_value=purefusion.api_client.ApiClient()) -purefusion.api_client.ApiClient.call_api = MagicMock( - side_effect=Exception("API call not mocked!") -) -basic.AnsibleModule.exit_json = exit_json -basic.AnsibleModule.fail_json = fail_json - - -@patch("fusion.OperationsApi") -@patch("fusion.TenantsApi") -@pytest.mark.parametrize( - "module_args", - [ - # required parameter 'name` is missing - { - "state": "present", - "display_name": "Tenant 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - # unknown parameter 'extra' is provided - { - "state": "present", - "name": "tenant1", - "display_name": "Tenant 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - "extra": "value", - }, - # parameter 'state` has incorrect value - { - "state": "cool", - "name": "tenant1", - "display_name": "Tenant 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - ], -) -def test_module_fails_on_wrong_parameters(m_tenant_api, m_op_api, module_args): - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_tenant = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_tenant = MagicMock(return_value=OperationMock(1)) - api_obj.update_tenant = MagicMock(return_value=OperationMock(2)) - api_obj.delete_tenant = MagicMock(return_value=OperationMock(3)) - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - m_tenant_api.return_value = api_obj - - # run module - with pytest.raises(AnsibleFailJson): - fusion_tenant.main() - - # check api was not called at all - api_obj.get_tenant.assert_not_called() - api_obj.create_tenant.assert_not_called() - api_obj.update_tenant.assert_not_called() - api_obj.delete_tenant.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.TenantsApi") -def test_tenant_create(m_tenant_api, m_op_api): - module_args = { - "state": "present", - "name": "tenant1", - "display_name": "Tenant 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_tenant = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_tenant = MagicMock(return_value=OperationMock(1)) - api_obj.update_tenant = MagicMock(return_value=OperationMock(2)) - api_obj.delete_tenant = MagicMock(return_value=OperationMock(3)) - m_tenant_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_tenant.main() - - assert exc.value.changed - assert exc.value.id == FAKE_RESOURCE_ID - - # check api was called correctly - api_obj.get_tenant.assert_called_once_with(tenant_name=module_args["name"]) - api_obj.create_tenant.assert_called_once_with( - purefusion.TenantPost( - name=module_args["name"], - display_name=module_args["display_name"], - ) - ) - api_obj.update_tenant.assert_not_called() - api_obj.delete_tenant.assert_not_called() - op_obj.get_operation.assert_called_once_with(1) - - -@patch("fusion.OperationsApi") -@patch("fusion.TenantsApi") -def test_tenant_create_without_display_name(m_tenant_api, m_op_api): - module_args = { - "state": "present", - "name": "tenant1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_tenant = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_tenant = MagicMock(return_value=OperationMock(1)) - api_obj.update_tenant = MagicMock(return_value=OperationMock(2)) - api_obj.delete_tenant = MagicMock(return_value=OperationMock(3)) - m_tenant_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_tenant.main() - - assert exc.value.changed - assert exc.value.id == FAKE_RESOURCE_ID - - # check api was called correctly - api_obj.get_tenant.assert_called_once_with(tenant_name=module_args["name"]) - api_obj.create_tenant.assert_called_once_with( - purefusion.TenantPost( - name=module_args["name"], - display_name=module_args["name"], - ) - ) - api_obj.update_tenant.assert_not_called() - api_obj.delete_tenant.assert_not_called() - op_obj.get_operation.assert_called_once_with(1) - - -@patch("fusion.OperationsApi") -@patch("fusion.TenantsApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, HTTPError), - ], -) -def test_tenant_create_exception(m_tenant_api, m_op_api, exec_original, exec_catch): - module_args = { - "state": "present", - "name": "tenant1", - "display_name": "Tenant 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_tenant = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_tenant = MagicMock(side_effect=exec_original) - api_obj.update_tenant = MagicMock(return_value=OperationMock(2)) - api_obj.delete_tenant = MagicMock(return_value=OperationMock(3)) - m_tenant_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_tenant.main() - - # check api was called correctly - api_obj.get_tenant.assert_called_once_with(tenant_name=module_args["name"]) - api_obj.create_tenant.assert_called_once_with( - purefusion.TenantPost( - name=module_args["name"], - display_name=module_args["display_name"], - ) - ) - api_obj.update_tenant.assert_not_called() - api_obj.delete_tenant.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.TenantsApi") -def test_tenant_create_op_fails(m_tenant_api, m_op_api): - module_args = { - "state": "present", - "name": "tenant1", - "display_name": "Tenant 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_tenant = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_tenant = MagicMock(return_value=OperationMock(1)) - api_obj.update_tenant = MagicMock(return_value=OperationMock(2)) - api_obj.delete_tenant = MagicMock(return_value=OperationMock(3)) - m_tenant_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(OperationException): - fusion_tenant.main() - - # check api was called correctly - api_obj.get_tenant.assert_called_once_with(tenant_name=module_args["name"]) - api_obj.create_tenant.assert_called_once_with( - purefusion.TenantPost( - name=module_args["name"], - display_name=module_args["display_name"], - ) - ) - api_obj.update_tenant.assert_not_called() - api_obj.delete_tenant.assert_not_called() - op_obj.get_operation.assert_called_once_with(1) - - -@patch("fusion.OperationsApi") -@patch("fusion.TenantsApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, OperationException), - ], -) -def test_tenant_create_op_exception(m_tenant_api, m_op_api, exec_original, exec_catch): - module_args = { - "state": "present", - "name": "tenant1", - "display_name": "Tenant 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_tenant = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_tenant = MagicMock(return_value=OperationMock(1)) - api_obj.update_tenant = MagicMock(return_value=OperationMock(2)) - api_obj.delete_tenant = MagicMock(return_value=OperationMock(3)) - m_tenant_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(side_effect=exec_original) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_tenant.main() - - # check api was called correctly - api_obj.get_tenant.assert_called_once_with(tenant_name=module_args["name"]) - api_obj.create_tenant.assert_called_once_with( - purefusion.TenantPost( - name=module_args["name"], - display_name=module_args["display_name"], - ) - ) - api_obj.update_tenant.assert_not_called() - api_obj.delete_tenant.assert_not_called() - op_obj.get_operation.assert_called_once_with(1) - - -@patch("fusion.OperationsApi") -@patch("fusion.TenantsApi") -def test_tenant_update(m_tenant_api, m_op_api): - module_args = { - "state": "present", - "name": "tenant1", - "display_name": "Tenant 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - current_tenant = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], # name must match - "display_name": None, - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_tenant = MagicMock(return_value=purefusion.Tenant(**current_tenant)) - api_obj.create_tenant = MagicMock(return_value=OperationMock(1)) - api_obj.update_tenant = MagicMock(return_value=OperationMock(2)) - api_obj.delete_tenant = MagicMock(return_value=OperationMock(3)) - m_tenant_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_tenant.main() - - assert exc.value.changed - assert exc.value.id == current_tenant["id"] - - # check api was called correctly - api_obj.get_tenant.assert_called_once_with(tenant_name=module_args["name"]) - api_obj.create_tenant.assert_not_called() - api_obj.update_tenant.assert_called_once_with( - purefusion.TenantPatch( - display_name=purefusion.NullableString(module_args["display_name"]) - ), - tenant_name=module_args["name"], - ) - api_obj.delete_tenant.assert_not_called() - op_obj.get_operation.assert_called_once_with(2) - - -@patch("fusion.OperationsApi") -@patch("fusion.TenantsApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, HTTPError), - ], -) -def test_tenant_update_exception(m_tenant_api, m_op_api, exec_original, exec_catch): - module_args = { - "state": "present", - "name": "tenant1", - "display_name": "Tenant 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - current_tenant = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], # name must match - "display_name": None, - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_tenant = MagicMock(return_value=purefusion.Tenant(**current_tenant)) - api_obj.create_tenant = MagicMock(return_value=OperationMock(1)) - api_obj.update_tenant = MagicMock(side_effect=exec_original) - api_obj.delete_tenant = MagicMock(return_value=OperationMock(3)) - m_tenant_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_tenant.main() - - # check api was called correctly - api_obj.get_tenant.assert_called_once_with(tenant_name=module_args["name"]) - api_obj.create_tenant.assert_not_called() - api_obj.update_tenant.assert_called_once_with( - purefusion.TenantPatch( - display_name=purefusion.NullableString(module_args["display_name"]) - ), - tenant_name=module_args["name"], - ) - api_obj.delete_tenant.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.TenantsApi") -def test_tenant_update_op_fails(m_tenant_api, m_op_api): - module_args = { - "state": "present", - "name": "tenant1", - "display_name": "Tenant 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - current_tenant = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], # name must match - "display_name": None, - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_tenant = MagicMock(return_value=purefusion.Tenant(**current_tenant)) - api_obj.create_tenant = MagicMock(return_value=OperationMock(1)) - api_obj.update_tenant = MagicMock(return_value=OperationMock(2)) - api_obj.delete_tenant = MagicMock(return_value=OperationMock(3)) - m_tenant_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(OperationException): - fusion_tenant.main() - - # check api was called correctly - api_obj.get_tenant.assert_called_once_with(tenant_name=module_args["name"]) - api_obj.create_tenant.assert_not_called() - api_obj.update_tenant.assert_called_once_with( - purefusion.TenantPatch( - display_name=purefusion.NullableString(module_args["display_name"]) - ), - tenant_name=module_args["name"], - ) - api_obj.delete_tenant.assert_not_called() - op_obj.get_operation.assert_called_once_with(2) - - -@patch("fusion.OperationsApi") -@patch("fusion.TenantsApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, OperationException), - ], -) -def test_tenant_update_op_exception(m_tenant_api, m_op_api, exec_original, exec_catch): - module_args = { - "state": "present", - "name": "tenant1", - "display_name": "Tenant 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - current_tenant = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], # name must match - "display_name": None, - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_tenant = MagicMock(return_value=purefusion.Tenant(**current_tenant)) - api_obj.create_tenant = MagicMock(return_value=OperationMock(1)) - api_obj.update_tenant = MagicMock(return_value=OperationMock(2)) - api_obj.delete_tenant = MagicMock(return_value=OperationMock(3)) - m_tenant_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(side_effect=exec_original) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_tenant.main() - - # check api was called correctly - api_obj.get_tenant.assert_called_once_with(tenant_name=module_args["name"]) - api_obj.create_tenant.assert_not_called() - api_obj.update_tenant.assert_called_once_with( - purefusion.TenantPatch( - display_name=purefusion.NullableString(module_args["display_name"]) - ), - tenant_name=module_args["name"], - ) - api_obj.delete_tenant.assert_not_called() - op_obj.get_operation.assert_called_once_with(2) - - -@patch("fusion.OperationsApi") -@patch("fusion.TenantsApi") -def test_tenant_present_not_changed(m_tenant_api, m_op_api): - module_args = { - "state": "present", - "name": "tenant1", - "display_name": "Tenant 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - current_tenant = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], # name must match - "display_name": module_args["display_name"], - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_tenant = MagicMock(return_value=purefusion.Tenant(**current_tenant)) - api_obj.create_tenant = MagicMock(return_value=OperationMock(1)) - api_obj.update_tenant = MagicMock(return_value=OperationMock(2)) - api_obj.delete_tenant = MagicMock(return_value=OperationMock(3)) - m_tenant_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_tenant.main() - - assert not exc.value.changed - - # check api was called correctly - api_obj.get_tenant.assert_called_once_with(tenant_name=module_args["name"]) - api_obj.create_tenant.assert_not_called() - api_obj.update_tenant.assert_not_called() - api_obj.delete_tenant.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.TenantsApi") -def test_tenant_absent_not_changed(m_tenant_api, m_op_api): - module_args = { - "state": "absent", - "name": "tenant1", - "display_name": "Tenant 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_tenant = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_tenant = MagicMock(return_value=OperationMock(1)) - api_obj.update_tenant = MagicMock(return_value=OperationMock(2)) - api_obj.delete_tenant = MagicMock(return_value=OperationMock(3)) - m_tenant_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_tenant.main() - - assert not exc.value.changed - - # check api was called correctly - api_obj.get_tenant.assert_called_once_with(tenant_name=module_args["name"]) - api_obj.create_tenant.assert_not_called() - api_obj.update_tenant.assert_not_called() - api_obj.delete_tenant.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.TenantsApi") -def test_tenant_delete(m_tenant_api, m_op_api): - module_args = { - "state": "absent", - "name": "tenant1", - "display_name": "Tenant 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - current_tenant = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], # name must match - "display_name": "different", # display_name doesn't match but UPDATE shouldn't be called - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_tenant = MagicMock(return_value=purefusion.Tenant(**current_tenant)) - api_obj.create_tenant = MagicMock(return_value=OperationMock(1)) - api_obj.update_tenant = MagicMock(return_value=OperationMock(2)) - api_obj.delete_tenant = MagicMock(return_value=OperationMock(3)) - m_tenant_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_tenant.main() - - assert exc.value.changed - - # check api was called correctly - api_obj.get_tenant.assert_called_once_with(tenant_name=module_args["name"]) - api_obj.create_tenant.assert_not_called() - api_obj.update_tenant.assert_not_called() - api_obj.delete_tenant.assert_called_once_with(tenant_name=module_args["name"]) - op_obj.get_operation.assert_called_once_with(3) - - -@patch("fusion.OperationsApi") -@patch("fusion.TenantsApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, HTTPError), - ], -) -def test_tenant_delete_exception(m_tenant_api, m_op_api, exec_original, exec_catch): - module_args = { - "state": "absent", - "name": "tenant1", - "display_name": "Tenant 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - current_tenant = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], # name must match - "display_name": "different", # display_name doesn't match but UPDATE shouldn't be called - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_tenant = MagicMock(return_value=purefusion.Tenant(**current_tenant)) - api_obj.create_tenant = MagicMock(return_value=OperationMock(1)) - api_obj.update_tenant = MagicMock(return_value=OperationMock(2)) - api_obj.delete_tenant = MagicMock(side_effect=exec_original) - m_tenant_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_tenant.main() - - # check api was called correctly - api_obj.get_tenant.assert_called_once_with(tenant_name=module_args["name"]) - api_obj.create_tenant.assert_not_called() - api_obj.update_tenant.assert_not_called() - api_obj.delete_tenant.assert_called_once_with(tenant_name=module_args["name"]) - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.TenantsApi") -def test_tenant_delete_op_fails(m_tenant_api, m_op_api): - module_args = { - "state": "absent", - "name": "tenant1", - "display_name": "Tenant 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - current_tenant = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], # name must match - "display_name": "different", # display_name doesn't match but UPDATE shouldn't be called - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_tenant = MagicMock(return_value=purefusion.Tenant(**current_tenant)) - api_obj.create_tenant = MagicMock(return_value=OperationMock(1)) - api_obj.update_tenant = MagicMock(return_value=OperationMock(2)) - api_obj.delete_tenant = MagicMock(return_value=OperationMock(3)) - m_tenant_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(OperationException): - fusion_tenant.main() - - # check api was called correctly - api_obj.get_tenant.assert_called_once_with(tenant_name=module_args["name"]) - api_obj.create_tenant.assert_not_called() - api_obj.update_tenant.assert_not_called() - api_obj.delete_tenant.assert_called_once_with(tenant_name=module_args["name"]) - op_obj.get_operation.assert_called_once_with(3) - - -@patch("fusion.OperationsApi") -@patch("fusion.TenantsApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, OperationException), - ], -) -def test_tenant_delete_op_exception(m_tenant_api, m_op_api, exec_original, exec_catch): - module_args = { - "state": "absent", - "name": "tenant1", - "display_name": "Tenant 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - current_tenant = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], # name must match - "display_name": "different", # display_name doesn't match but UPDATE shouldn't be called - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_tenant = MagicMock(return_value=purefusion.Tenant(**current_tenant)) - api_obj.create_tenant = MagicMock(return_value=OperationMock(1)) - api_obj.update_tenant = MagicMock(return_value=OperationMock(2)) - api_obj.delete_tenant = MagicMock(return_value=OperationMock(3)) - m_tenant_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(side_effect=exec_original) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_tenant.main() - - # check api was called correctly - api_obj.get_tenant.assert_called_once_with(tenant_name=module_args["name"]) - api_obj.create_tenant.assert_not_called() - api_obj.update_tenant.assert_not_called() - api_obj.delete_tenant.assert_called_once_with(tenant_name=module_args["name"]) - op_obj.get_operation.assert_called_once_with(3) diff --git a/ansible_collections/purestorage/fusion/tests/functional/test_fusion_ts.py b/ansible_collections/purestorage/fusion/tests/functional/test_fusion_ts.py deleted file mode 100644 index 0e1260858..000000000 --- a/ansible_collections/purestorage/fusion/tests/functional/test_fusion_ts.py +++ /dev/null @@ -1,926 +0,0 @@ -# -*- coding: utf-8 -*- - -# (c) 2023, Andrej Pajtas (apajtas@purestorage.com) -# GNU General Public License v3.0+ (see COPYING.GPLv3 or https://www.gnu.org/licenses/gpl-3.0.txt) - -from __future__ import absolute_import, division, print_function - -__metaclass__ = type - -from unittest.mock import MagicMock, patch - -import fusion as purefusion -import pytest -from ansible.module_utils import basic -from ansible_collections.purestorage.fusion.plugins.module_utils.errors import ( - OperationException, -) -from ansible_collections.purestorage.fusion.plugins.modules import fusion_ts -from ansible_collections.purestorage.fusion.tests.functional.utils import ( - AnsibleExitJson, - AnsibleFailJson, - FailedOperationMock, - OperationMock, - SuccessfulOperationMock, - FAKE_RESOURCE_ID, - exit_json, - fail_json, - set_module_args, -) -from urllib3.exceptions import HTTPError - -# GLOBAL MOCKS -fusion_ts.setup_fusion = MagicMock(return_value=purefusion.api_client.ApiClient()) -purefusion.api_client.ApiClient.call_api = MagicMock( - side_effect=Exception("API call not mocked!") -) -basic.AnsibleModule.exit_json = exit_json -basic.AnsibleModule.fail_json = fail_json - - -@patch("fusion.OperationsApi") -@patch("fusion.TenantSpacesApi") -@pytest.mark.parametrize( - "module_args", - [ - # required parameter 'name` is missing - { - "state": "present", - "display_name": "Tenanct Space 1", - "tenant": "tenant1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - # required tenant 'name` is missing - { - "state": "present", - "name": "tenantspace1", - "display_name": "Tenanct Space 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - # unknown parameter 'extra' is provided - { - "state": "present", - "name": "tenantspace1", - "display_name": "Tenanct Space 1", - "tenant": "tenant1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - "extra": "value", - }, - # parameter 'state` has incorrect value - { - "state": "cool", - "name": "tenantspace1", - "display_name": "Tenanct Space 1", - "tenant": "tenant1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - }, - ], -) -def test_module_fails_on_wrong_parameters(m_ts_api, m_op_api, module_args): - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_tenant_space = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_tenant_space = MagicMock(return_value=OperationMock(1)) - api_obj.update_tenant_space = MagicMock(return_value=OperationMock(2)) - api_obj.delete_tenant_space = MagicMock(return_value=OperationMock(3)) - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - m_ts_api.return_value = api_obj - - # run module - with pytest.raises(AnsibleFailJson): - fusion_ts.main() - - # check api was not called at all - api_obj.get_tenant_space.assert_not_called() - api_obj.create_tenant_space.assert_not_called() - api_obj.update_tenant_space.assert_not_called() - api_obj.delete_tenant_space.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.TenantSpacesApi") -def test_ts_create(m_ts_api, m_op_api): - module_args = { - "state": "present", - "name": "tenantspace1", - "display_name": "Tenanct Space 1", - "tenant": "tenant1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_tenant_space = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_tenant_space = MagicMock(return_value=OperationMock(1)) - api_obj.update_tenant_space = MagicMock(return_value=OperationMock(2)) - api_obj.delete_tenant_space = MagicMock(return_value=OperationMock(3)) - m_ts_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_ts.main() - - assert exc.value.changed - assert exc.value.id == FAKE_RESOURCE_ID - - # check api was called correctly - api_obj.get_tenant_space.assert_called_once_with( - tenant_name=module_args["tenant"], - tenant_space_name=module_args["name"], - ) - api_obj.create_tenant_space.assert_called_once_with( - purefusion.TenantSpacePost( - name=module_args["name"], - display_name=module_args["display_name"], - ), - tenant_name=module_args["tenant"], - ) - api_obj.update_tenant_space.assert_not_called() - api_obj.delete_tenant_space.assert_not_called() - op_obj.get_operation.assert_called_once_with(1) - - -@patch("fusion.OperationsApi") -@patch("fusion.TenantSpacesApi") -def test_ts_create_without_display_name(m_ts_api, m_op_api): - module_args = { - "state": "present", - "name": "tenantspace1", - "tenant": "tenant1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_tenant_space = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_tenant_space = MagicMock(return_value=OperationMock(1)) - api_obj.update_tenant_space = MagicMock(return_value=OperationMock(2)) - api_obj.delete_tenant_space = MagicMock(return_value=OperationMock(3)) - m_ts_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_ts.main() - - assert exc.value.changed - assert exc.value.id == FAKE_RESOURCE_ID - - # check api was called correctly - api_obj.get_tenant_space.assert_called_once_with( - tenant_name=module_args["tenant"], - tenant_space_name=module_args["name"], - ) - api_obj.create_tenant_space.assert_called_once_with( - purefusion.TenantSpacePost( - name=module_args["name"], - display_name=module_args["name"], - ), - tenant_name=module_args["tenant"], - ) - api_obj.update_tenant_space.assert_not_called() - api_obj.delete_tenant_space.assert_not_called() - op_obj.get_operation.assert_called_once_with(1) - - -@patch("fusion.OperationsApi") -@patch("fusion.TenantSpacesApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, HTTPError), - ], -) -def test_ts_create_exception(m_ts_api, m_op_api, exec_original, exec_catch): - module_args = { - "state": "present", - "name": "tenantspace1", - "display_name": "Tenanct Space 1", - "tenant": "tenant1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_tenant_space = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_tenant_space = MagicMock(side_effect=exec_original) - api_obj.update_tenant_space = MagicMock(return_value=OperationMock(2)) - api_obj.delete_tenant_space = MagicMock(return_value=OperationMock(3)) - m_ts_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_ts.main() - - # check api was called correctly - api_obj.get_tenant_space.assert_called_once_with( - tenant_name=module_args["tenant"], - tenant_space_name=module_args["name"], - ) - api_obj.create_tenant_space.assert_called_once_with( - purefusion.TenantSpacePost( - name=module_args["name"], - display_name=module_args["display_name"], - ), - tenant_name=module_args["tenant"], - ) - api_obj.update_tenant_space.assert_not_called() - api_obj.delete_tenant_space.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.TenantSpacesApi") -def test_ts_create_op_fails(m_ts_api, m_op_api): - module_args = { - "state": "present", - "name": "tenantspace1", - "display_name": "Tenanct Space 1", - "tenant": "tenant1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_tenant_space = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_tenant_space = MagicMock(return_value=OperationMock(1)) - api_obj.update_tenant_space = MagicMock(return_value=OperationMock(2)) - api_obj.delete_tenant_space = MagicMock(return_value=OperationMock(3)) - m_ts_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(OperationException): - fusion_ts.main() - - # check api was called correctly - api_obj.get_tenant_space.assert_called_once_with( - tenant_name=module_args["tenant"], - tenant_space_name=module_args["name"], - ) - api_obj.create_tenant_space.assert_called_once_with( - purefusion.TenantSpacePost( - name=module_args["name"], - display_name=module_args["display_name"], - ), - tenant_name=module_args["tenant"], - ) - api_obj.update_tenant_space.assert_not_called() - api_obj.delete_tenant_space.assert_not_called() - op_obj.get_operation.assert_called_once_with(1) - - -@patch("fusion.OperationsApi") -@patch("fusion.TenantSpacesApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, OperationException), - ], -) -def test_ts_create_op_exception(m_ts_api, m_op_api, exec_original, exec_catch): - module_args = { - "state": "present", - "name": "tenantspace1", - "display_name": "Tenanct Space 1", - "tenant": "tenant1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_tenant_space = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_tenant_space = MagicMock(return_value=OperationMock(1)) - api_obj.update_tenant_space = MagicMock(return_value=OperationMock(2)) - api_obj.delete_tenant_space = MagicMock(return_value=OperationMock(3)) - m_ts_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(side_effect=exec_original) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_ts.main() - - # check api was called correctly - api_obj.get_tenant_space.assert_called_once_with( - tenant_name=module_args["tenant"], - tenant_space_name=module_args["name"], - ) - api_obj.create_tenant_space.assert_called_once_with( - purefusion.TenantSpacePost( - name=module_args["name"], - display_name=module_args["display_name"], - ), - tenant_name=module_args["tenant"], - ) - api_obj.update_tenant_space.assert_not_called() - api_obj.delete_tenant_space.assert_not_called() - op_obj.get_operation.assert_called_once_with(1) - - -@patch("fusion.OperationsApi") -@patch("fusion.TenantSpacesApi") -def test_ts_update(m_ts_api, m_op_api): - module_args = { - "state": "present", - "name": "tenantspace1", - "display_name": "Tenanct Space 1", - "tenant": "tenant1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - current_ts = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], # name must match - "tenant": "tenant1", - "display_name": None, - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_tenant_space = MagicMock( - return_value=purefusion.TenantSpace(**current_ts) - ) - api_obj.create_tenant_space = MagicMock(return_value=OperationMock(1)) - api_obj.update_tenant_space = MagicMock(return_value=OperationMock(2)) - api_obj.delete_tenant_space = MagicMock(return_value=OperationMock(3)) - m_ts_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_ts.main() - - assert exc.value.changed - assert exc.value.id == current_ts["id"] - - # check api was called correctly - api_obj.get_tenant_space.assert_called_once_with( - tenant_name=module_args["tenant"], - tenant_space_name=module_args["name"], - ) - api_obj.create_tenant_space.assert_not_called() - api_obj.update_tenant_space.assert_called_once_with( - purefusion.TenantSpacePatch( - display_name=purefusion.NullableString(module_args["display_name"]) - ), - tenant_name=module_args["tenant"], - tenant_space_name=module_args["name"], - ) - api_obj.delete_tenant_space.assert_not_called() - op_obj.get_operation.assert_called_once_with(2) - - -@patch("fusion.OperationsApi") -@patch("fusion.TenantSpacesApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, HTTPError), - ], -) -def test_ts_update_exception(m_ts_api, m_op_api, exec_original, exec_catch): - module_args = { - "state": "present", - "name": "tenantspace1", - "display_name": "Tenanct Space 1", - "tenant": "tenant1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - current_ts = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], # name must match - "tenant": "tenant1", - "display_name": None, - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_tenant_space = MagicMock( - return_value=purefusion.TenantSpace(**current_ts) - ) - api_obj.create_tenant_space = MagicMock(return_value=OperationMock(1)) - api_obj.update_tenant_space = MagicMock(side_effect=exec_original) - api_obj.delete_tenant_space = MagicMock(return_value=OperationMock(3)) - m_ts_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_ts.main() - - # check api was called correctly - api_obj.get_tenant_space.assert_called_once_with( - tenant_name=module_args["tenant"], - tenant_space_name=module_args["name"], - ) - api_obj.create_tenant_space.assert_not_called() - api_obj.update_tenant_space.assert_called_once_with( - purefusion.TenantSpacePatch( - display_name=purefusion.NullableString(module_args["display_name"]) - ), - tenant_name=module_args["tenant"], - tenant_space_name=module_args["name"], - ) - api_obj.delete_tenant_space.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.TenantSpacesApi") -def test_ts_update_op_fails(m_ts_api, m_op_api): - module_args = { - "state": "present", - "name": "tenantspace1", - "display_name": "Tenanct Space 1", - "tenant": "tenant1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - current_ts = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], # name must match - "tenant": "tenant1", - "display_name": None, - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_tenant_space = MagicMock( - return_value=purefusion.TenantSpace(**current_ts) - ) - api_obj.create_tenant_space = MagicMock(return_value=OperationMock(1)) - api_obj.update_tenant_space = MagicMock(return_value=OperationMock(2)) - api_obj.delete_tenant_space = MagicMock(return_value=OperationMock(3)) - m_ts_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(OperationException): - fusion_ts.main() - - # check api was called correctly - api_obj.get_tenant_space.assert_called_once_with( - tenant_name=module_args["tenant"], - tenant_space_name=module_args["name"], - ) - api_obj.create_tenant_space.assert_not_called() - api_obj.update_tenant_space.assert_called_once_with( - purefusion.TenantSpacePatch( - display_name=purefusion.NullableString(module_args["display_name"]) - ), - tenant_name=module_args["tenant"], - tenant_space_name=module_args["name"], - ) - api_obj.delete_tenant_space.assert_not_called() - op_obj.get_operation.assert_called_once_with(2) - - -@patch("fusion.OperationsApi") -@patch("fusion.TenantSpacesApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, OperationException), - ], -) -def test_ts_update_op_exception(m_ts_api, m_op_api, exec_original, exec_catch): - module_args = { - "state": "present", - "name": "tenantspace1", - "display_name": "Tenanct Space 1", - "tenant": "tenant1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - current_ts = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], # name must match - "tenant": "tenant1", - "display_name": None, - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_tenant_space = MagicMock( - return_value=purefusion.TenantSpace(**current_ts) - ) - api_obj.create_tenant_space = MagicMock(return_value=OperationMock(1)) - api_obj.update_tenant_space = MagicMock(return_value=OperationMock(2)) - api_obj.delete_tenant_space = MagicMock(return_value=OperationMock(3)) - m_ts_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(side_effect=exec_original) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_ts.main() - - # check api was called correctly - api_obj.get_tenant_space.assert_called_once_with( - tenant_name=module_args["tenant"], - tenant_space_name=module_args["name"], - ) - api_obj.create_tenant_space.assert_not_called() - api_obj.update_tenant_space.assert_called_once_with( - purefusion.TenantSpacePatch( - display_name=purefusion.NullableString(module_args["display_name"]) - ), - tenant_name=module_args["tenant"], - tenant_space_name=module_args["name"], - ) - api_obj.delete_tenant_space.assert_not_called() - op_obj.get_operation.assert_called_once_with(2) - - -@patch("fusion.OperationsApi") -@patch("fusion.TenantSpacesApi") -def test_ts_present_not_changed(m_ts_api, m_op_api): - module_args = { - "state": "present", - "name": "tenantspace1", - "display_name": "Tenanct Space 1", - "tenant": "tenant1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - current_ts = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], # name must match - "tenant": "tenant1", - "display_name": module_args["display_name"], - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_tenant_space = MagicMock( - return_value=purefusion.TenantSpace(**current_ts) - ) - api_obj.create_tenant_space = MagicMock(return_value=OperationMock(1)) - api_obj.update_tenant_space = MagicMock(return_value=OperationMock(2)) - api_obj.delete_tenant_space = MagicMock(return_value=OperationMock(3)) - m_ts_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_ts.main() - - assert not exc.value.changed - - # check api was called correctly - api_obj.get_tenant_space.assert_called_once_with( - tenant_name=module_args["tenant"], - tenant_space_name=module_args["name"], - ) - api_obj.create_tenant_space.assert_not_called() - api_obj.update_tenant_space.assert_not_called() - api_obj.delete_tenant_space.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.TenantSpacesApi") -def test_ts_absent_not_changed(m_ts_api, m_op_api): - module_args = { - "state": "absent", - "name": "tenantspace1", - "tenant": "tenant1", - "display_name": "Tenanct Space 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_tenant_space = MagicMock(side_effect=purefusion.rest.ApiException) - api_obj.create_tenant_space = MagicMock(return_value=OperationMock(1)) - api_obj.update_tenant_space = MagicMock(return_value=OperationMock(2)) - api_obj.delete_tenant_space = MagicMock(return_value=OperationMock(3)) - m_ts_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_ts.main() - - assert not exc.value.changed - - # check api was called correctly - api_obj.get_tenant_space.assert_called_once_with( - tenant_name=module_args["tenant"], - tenant_space_name=module_args["name"], - ) - api_obj.create_tenant_space.assert_not_called() - api_obj.update_tenant_space.assert_not_called() - api_obj.delete_tenant_space.assert_not_called() - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.TenantSpacesApi") -def test_ts_delete(m_ts_api, m_op_api): - module_args = { - "state": "absent", - "name": "tenantspace1", - "tenant": "tenant1", - "display_name": "Tenanct Space 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - current_ts = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], # name must match - "tenant": "tenant1", - "display_name": "different", # display_name doesn't match but UPDATE shouldn't be called - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_tenant_space = MagicMock( - return_value=purefusion.TenantSpace(**current_ts) - ) - api_obj.create_tenant_space = MagicMock(return_value=OperationMock(1)) - api_obj.update_tenant_space = MagicMock(return_value=OperationMock(2)) - api_obj.delete_tenant_space = MagicMock(return_value=OperationMock(3)) - m_ts_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=SuccessfulOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(AnsibleExitJson) as exc: - fusion_ts.main() - - assert exc.value.changed - - # check api was called correctly - api_obj.get_tenant_space.assert_called_once_with( - tenant_name=module_args["tenant"], - tenant_space_name=module_args["name"], - ) - api_obj.create_tenant_space.assert_not_called() - api_obj.update_tenant_space.assert_not_called() - api_obj.delete_tenant_space.assert_called_once_with( - tenant_name=module_args["tenant"], - tenant_space_name=module_args["name"], - ) - op_obj.get_operation.assert_called_once_with(3) - - -@patch("fusion.OperationsApi") -@patch("fusion.TenantSpacesApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, HTTPError), - ], -) -def test_ts_delete_exception(m_ts_api, m_op_api, exec_original, exec_catch): - module_args = { - "state": "absent", - "name": "tenantspace1", - "tenant": "tenant1", - "display_name": "Tenanct Space 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - current_ts = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], # name must match - "tenant": "tenant1", - "display_name": "different", # display_name doesn't match but UPDATE shouldn't be called - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_tenant_space = MagicMock( - return_value=purefusion.TenantSpace(**current_ts) - ) - api_obj.create_tenant_space = MagicMock(return_value=OperationMock(1)) - api_obj.update_tenant_space = MagicMock(return_value=OperationMock(2)) - api_obj.delete_tenant_space = MagicMock(side_effect=exec_original) - m_ts_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_ts.main() - - # check api was called correctly - api_obj.get_tenant_space.assert_called_once_with( - tenant_name=module_args["tenant"], - tenant_space_name=module_args["name"], - ) - api_obj.create_tenant_space.assert_not_called() - api_obj.update_tenant_space.assert_not_called() - api_obj.delete_tenant_space.assert_called_once_with( - tenant_name=module_args["tenant"], - tenant_space_name=module_args["name"], - ) - op_obj.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.TenantSpacesApi") -def test_ts_delete_op_fails(m_ts_api, m_op_api): - module_args = { - "state": "absent", - "name": "tenantspace1", - "tenant": "tenant1", - "display_name": "Tenanct Space 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - current_ts = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], # name must match - "tenant": "tenant1", - "display_name": "different", # display_name doesn't match but UPDATE shouldn't be called - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_tenant_space = MagicMock( - return_value=purefusion.TenantSpace(**current_ts) - ) - api_obj.create_tenant_space = MagicMock(return_value=OperationMock(1)) - api_obj.update_tenant_space = MagicMock(return_value=OperationMock(2)) - api_obj.delete_tenant_space = MagicMock(return_value=OperationMock(3)) - m_ts_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(return_value=FailedOperationMock) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(OperationException): - fusion_ts.main() - - # check api was called correctly - api_obj.get_tenant_space.assert_called_once_with( - tenant_name=module_args["tenant"], - tenant_space_name=module_args["name"], - ) - api_obj.create_tenant_space.assert_not_called() - api_obj.update_tenant_space.assert_not_called() - api_obj.delete_tenant_space.assert_called_once_with( - tenant_name=module_args["tenant"], - tenant_space_name=module_args["name"], - ) - op_obj.get_operation.assert_called_once_with(3) - - -@patch("fusion.OperationsApi") -@patch("fusion.TenantSpacesApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, OperationException), - ], -) -def test_ts_delete_op_exception(m_ts_api, m_op_api, exec_original, exec_catch): - module_args = { - "state": "absent", - "name": "tenantspace1", - "tenant": "tenant1", - "display_name": "Tenanct Space 1", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - current_ts = { - "id": 1, - "self_link": "self_link_value", - "name": module_args["name"], # name must match - "tenant": "tenant1", - "display_name": "different", # display_name doesn't match but UPDATE shouldn't be called - } - set_module_args(module_args) - - # mock api responses - api_obj = MagicMock() - api_obj.get_tenant_space = MagicMock( - return_value=purefusion.TenantSpace(**current_ts) - ) - api_obj.create_tenant_space = MagicMock(return_value=OperationMock(1)) - api_obj.update_tenant_space = MagicMock(return_value=OperationMock(2)) - api_obj.delete_tenant_space = MagicMock(return_value=OperationMock(3)) - m_ts_api.return_value = api_obj - - # mock operation results - op_obj = MagicMock() - op_obj.get_operation = MagicMock(side_effect=exec_original) - m_op_api.return_value = op_obj - - # run module - with pytest.raises(exec_catch): - fusion_ts.main() - - # check api was called correctly - api_obj.get_tenant_space.assert_called_once_with( - tenant_name=module_args["tenant"], - tenant_space_name=module_args["name"], - ) - api_obj.create_tenant_space.assert_not_called() - api_obj.update_tenant_space.assert_not_called() - api_obj.delete_tenant_space.assert_called_once_with( - tenant_name=module_args["tenant"], - tenant_space_name=module_args["name"], - ) - op_obj.get_operation.assert_called_once_with(3) diff --git a/ansible_collections/purestorage/fusion/tests/functional/test_fusion_volume.py b/ansible_collections/purestorage/fusion/tests/functional/test_fusion_volume.py deleted file mode 100644 index 43f69666e..000000000 --- a/ansible_collections/purestorage/fusion/tests/functional/test_fusion_volume.py +++ /dev/null @@ -1,861 +0,0 @@ -# -*- coding: utf-8 -*- - -# (c) 2023, Dmitriy Li (dmli@purestorage.com) -# GNU General Public License v3.0+ (see COPYING.GPLv3 or https://www.gnu.org/licenses/gpl-3.0.txt) - -from __future__ import absolute_import, division, print_function - -__metaclass__ = type - -from unittest.mock import MagicMock, call, patch - -import fusion as purefusion -import pytest -from ansible.module_utils import basic -from ansible_collections.purestorage.fusion.plugins.module_utils.errors import ( - OperationException, -) -from ansible_collections.purestorage.fusion.plugins.modules import ( - fusion_volume, -) -from ansible_collections.purestorage.fusion.tests.functional.utils import ( - AnsibleExitJson, - AnsibleFailJson, - OperationMock, - SuccessfulOperationMock, - FAKE_RESOURCE_ID, - exit_json, - fail_json, - set_module_args, -) -from urllib3.exceptions import HTTPError - -# GLOBAL MOCKS -fusion_volume.setup_fusion = MagicMock(return_value=purefusion.api_client.ApiClient()) -purefusion.api_client.ApiClient.call_api = MagicMock( - side_effect=Exception("API call not mocked!") -) -basic.AnsibleModule.exit_json = exit_json -basic.AnsibleModule.fail_json = fail_json - - -@pytest.fixture -def module_args(): - return { - "name": "volume_1", - "state": "present", - "display_name": "Volume 1", - "tenant": "t1", - "tenant_space": "ts1", - "placement_group": "pg1", - "storage_class": "sc1", - "protection_policy": "pp1", - "host_access_policies": ["hap1"], - "eradicate": False, - "size": "1M", - "issuer_id": "ABCD1234", - "private_key_file": "private-key.pem", - } - - -@pytest.fixture -def absent_module_args(module_args): - module_args.update( - {"host_access_policies": [], "eradicate": True, "state": "absent"} - ) - return module_args - - -@pytest.fixture -def volume(): - return { - "name": "volume_1", - "display_name": "Volume 1", - "tenant": "t1", - "tenant_space": "ts1", - "storage_class": purefusion.StorageClassRef( - name="sc1", id="id_1", kind="storage_class", self_link="self_link" - ), - "placement_group": purefusion.PlacementGroupRef( - name="pg1", id="id_1", kind="placement_group", self_link="self_link" - ), - "protection_policy": purefusion.ProtectionPolicyRef( - name="pp1", id="id_1", kind="protection_policy", self_link="self_link" - ), - "host_access_policies": [ - purefusion.HostAccessPolicyRef( - name="hap1", id="id_1", kind="host_access_policy", self_link="self_link" - ) - ], - "serial_number": "sn1", - "destroyed": False, - "size": 1048576, - "id": "id_1", - "self_link": "self_link", - } - - -@pytest.fixture -def destroyed_volume(volume): - volume.update({"host_access_policies": [], "destroyed": True}) - return volume - - -@patch("fusion.VolumesApi") -@pytest.mark.parametrize( - "field,expected_exception_regex", - [ - ( - "name", - "missing required arguments: name", - ), - ( - "tenant", - "missing required arguments: tenant", - ), - ( - "tenant_space", - "missing required arguments: tenant_space", - ), - ( - "storage_class", - "missing parameter\\(s\\) required by 'placement_group': storage_class", - ), - ( - "placement_group", - "missing required arguments: placement_group", - ), - ( - "size", - "Either `size`, `source_volume` or `source_snapshot` parameter is required when creating a volume.", - ), - ], -) -def test_module_fails_on_missing_parameters( - mock_volumes_api, field, expected_exception_regex, module_args -): - volumes_api = purefusion.VolumesApi() - volumes_api.get_volume = MagicMock(side_effect=purefusion.rest.ApiException) - mock_volumes_api.return_value = volumes_api - del module_args[field] - set_module_args(module_args) - # run module - with pytest.raises(AnsibleFailJson) as ansible_error: - fusion_volume.main() - assert ansible_error.match(expected_exception_regex) - - -@patch("fusion.VolumesApi") -@pytest.mark.parametrize( - "dict_update,expected_exception_regex", - [ - ( - {"extra": "value"}, - "Unsupported parameters for.*module: extra", - ), - ( - {"state": "absent"}, - "Volume must have no host access policies when destroyed", - ), - ( - {"eradicate": True}, - "'eradicate: true' cannot be used together with 'state: present'", - ), - ( - {"size": "1K"}, - "Size is not within the required range", - ), - ( - {"source_volume": "vol_name"}, - "parameters are mutually exclusive: source_volume|source_snapshot|size", - ), - ( - {"source_snapshot": "snap_name"}, - "parameters are mutually exclusive: source_volume|source_snapshot|size", - ), - ( - {"source_volume_snapshot": "vol_snap_name"}, - "parameters are required together: source_snapshot, source_volume_snapshot", - ), - ], -) -def test_module_fails_on_incorrect_parameters( - mock_volumes_api, dict_update, expected_exception_regex, module_args -): - volumes_api = purefusion.VolumesApi() - volumes_api.get_volume = MagicMock(side_effect=purefusion.rest.ApiException) - mock_volumes_api.return_value = volumes_api - module_args.update(dict_update) - set_module_args(module_args) - # run module - with pytest.raises(AnsibleFailJson) as ansible_error: - fusion_volume.main() - assert ansible_error.match(expected_exception_regex) - - -@patch("fusion.VolumesApi") -def test_module_not_existent_volume_with_state_absent_not_changed( - mock_volumes_api, module_args -): - volumes_api = purefusion.VolumesApi() - volumes_api.get_volume = MagicMock(side_effect=purefusion.rest.ApiException) - mock_volumes_api.return_value = volumes_api - del module_args["host_access_policies"] - module_args["state"] = "absent" - set_module_args(module_args) - # run module - with pytest.raises(AnsibleExitJson) as exception: - fusion_volume.main() - assert exception.value.changed is False - volumes_api.get_volume.assert_called_once_with( - volume_name=module_args["name"], - tenant_name=module_args["tenant"], - tenant_space_name=module_args["tenant_space"], - ) - - -@patch("fusion.OperationsApi") -@patch("fusion.VolumesApi") -def test_volume_create_successfully(mock_volumes_api, mock_operations_api, module_args): - operations_api = purefusion.OperationsApi() - volumes_api = purefusion.VolumesApi() - volumes_api.get_volume = MagicMock(side_effect=purefusion.rest.ApiException) - volumes_api.create_volume = MagicMock(return_value=OperationMock(1)) - operations_api.get_operation = MagicMock(return_value=SuccessfulOperationMock) - mock_volumes_api.return_value = volumes_api - mock_operations_api.return_value = operations_api - set_module_args(module_args) - # run module - with pytest.raises(AnsibleExitJson) as exception: - fusion_volume.main() - assert exception.value.changed is True - assert exception.value.id == FAKE_RESOURCE_ID - - volumes_api.get_volume.assert_called_with( - volume_name=module_args["name"], - tenant_name=module_args["tenant"], - tenant_space_name=module_args["tenant_space"], - ) - volumes_api.create_volume.assert_called_once_with( - purefusion.VolumePost( - size=1048576, - storage_class=module_args["storage_class"], - placement_group=module_args["placement_group"], - name=module_args["name"], - display_name=module_args["display_name"], - protection_policy=module_args["protection_policy"], - ), - tenant_name=module_args["tenant"], - tenant_space_name=module_args["tenant_space"], - ) - operations_api.get_operation.assert_called_once_with(1) - - -@patch("fusion.OperationsApi") -@patch("fusion.VolumesApi") -def test_volume_create_from_volume_successfully( - mock_volumes_api, mock_operations_api, module_args -): - del module_args["size"] - module_args["source_volume"] = "source_volume_name" - - operations_api = purefusion.OperationsApi() - volumes_api = purefusion.VolumesApi() - volumes_api.get_volume = MagicMock(side_effect=purefusion.rest.ApiException) - volumes_api.create_volume = MagicMock(return_value=OperationMock(1)) - operations_api.get_operation = MagicMock(return_value=SuccessfulOperationMock) - mock_volumes_api.return_value = volumes_api - mock_operations_api.return_value = operations_api - set_module_args(module_args) - # run module - with pytest.raises(AnsibleExitJson) as exception: - fusion_volume.main() - assert exception.value.changed is True - assert exception.value.id == FAKE_RESOURCE_ID - volumes_api.get_volume.assert_called_with( - volume_name=module_args["name"], - tenant_name=module_args["tenant"], - tenant_space_name=module_args["tenant_space"], - ) - volumes_api.create_volume.assert_called_once_with( - purefusion.VolumePost( - source_link=f"/tenants/{module_args['tenant']}/tenant-spaces/{module_args['tenant_space']}/volumes/{module_args['source_volume']}", - storage_class=module_args["storage_class"], - placement_group=module_args["placement_group"], - name=module_args["name"], - display_name=module_args["display_name"], - protection_policy=module_args["protection_policy"], - ), - tenant_name=module_args["tenant"], - tenant_space_name=module_args["tenant_space"], - ) - operations_api.get_operation.assert_called_once_with(1) - - -@patch("fusion.OperationsApi") -@patch("fusion.VolumesApi") -def test_volume_create_from_volume_snapshot_successfully( - mock_volumes_api, mock_operations_api, module_args -): - del module_args["size"] - module_args["source_snapshot"] = "source_snapshot_name" - module_args["source_volume_snapshot"] = "source_volume_snapshot_name" - - operations_api = purefusion.OperationsApi() - volumes_api = purefusion.VolumesApi() - volumes_api.get_volume = MagicMock(side_effect=purefusion.rest.ApiException) - volumes_api.create_volume = MagicMock(return_value=OperationMock(1)) - operations_api.get_operation = MagicMock(return_value=SuccessfulOperationMock) - mock_volumes_api.return_value = volumes_api - mock_operations_api.return_value = operations_api - set_module_args(module_args) - # run module - with pytest.raises(AnsibleExitJson) as exception: - fusion_volume.main() - assert exception.value.changed is True - assert exception.value.id == FAKE_RESOURCE_ID - volumes_api.get_volume.assert_called_with( - volume_name=module_args["name"], - tenant_name=module_args["tenant"], - tenant_space_name=module_args["tenant_space"], - ) - volumes_api.create_volume.assert_called_once_with( - purefusion.VolumePost( - source_link=f"/tenants/{module_args['tenant']}/tenant-spaces/{module_args['tenant_space']}/snapshots/" - f"{module_args['source_snapshot']}/volume-snapshots/{module_args['source_volume_snapshot']}", - storage_class=module_args["storage_class"], - placement_group=module_args["placement_group"], - name=module_args["name"], - display_name=module_args["display_name"], - protection_policy=module_args["protection_policy"], - ), - tenant_name=module_args["tenant"], - tenant_space_name=module_args["tenant_space"], - ) - operations_api.get_operation.assert_called_once_with(1) - - -@patch("fusion.OperationsApi") -@patch("fusion.VolumesApi") -def test_volume_create_without_display_name_successfully( - mock_volumes_api, mock_operations_api, module_args -): - del module_args["display_name"] - operations_api = purefusion.OperationsApi() - volumes_api = purefusion.VolumesApi() - volumes_api.get_volume = MagicMock(side_effect=purefusion.rest.ApiException) - volumes_api.create_volume = MagicMock(return_value=OperationMock(1)) - operations_api.get_operation = MagicMock(return_value=SuccessfulOperationMock) - mock_volumes_api.return_value = volumes_api - mock_operations_api.return_value = operations_api - set_module_args(module_args) - # run module - with pytest.raises(AnsibleExitJson) as exception: - fusion_volume.main() - assert exception.value.changed is True - assert exception.value.id == FAKE_RESOURCE_ID - volumes_api.get_volume.assert_called_with( - volume_name=module_args["name"], - tenant_name=module_args["tenant"], - tenant_space_name=module_args["tenant_space"], - ) - volumes_api.create_volume.assert_called_with( - purefusion.VolumePost( - size=1048576, - storage_class=module_args["storage_class"], - placement_group=module_args["placement_group"], - name=module_args["name"], - display_name=module_args["name"], - protection_policy=module_args["protection_policy"], - ), - tenant_name=module_args["tenant"], - tenant_space_name=module_args["tenant_space"], - ) - operations_api.get_operation.assert_called_once_with(1) - - -@patch("fusion.OperationsApi") -@patch("fusion.VolumesApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, HTTPError), - ], -) -def test_volume_create_throws_exception( - mock_volumes_api, mock_operations_api, exec_original, exec_catch, module_args -): - operations_api = purefusion.OperationsApi() - volumes_api = purefusion.VolumesApi() - volumes_api.get_volume = MagicMock(side_effect=purefusion.rest.ApiException) - volumes_api.create_volume = MagicMock(side_effect=exec_original) - operations_api.get_operation = MagicMock(return_value=SuccessfulOperationMock) - mock_volumes_api.return_value = volumes_api - mock_operations_api.return_value = operations_api - set_module_args(module_args) - # run module - with pytest.raises(exec_catch): - fusion_volume.main() - volumes_api.get_volume.assert_called_with( - volume_name=module_args["name"], - tenant_name=module_args["tenant"], - tenant_space_name=module_args["tenant_space"], - ) - volumes_api.create_volume.assert_called_once_with( - purefusion.VolumePost( - size=1048576, - storage_class=module_args["storage_class"], - placement_group=module_args["placement_group"], - name=module_args["name"], - display_name=module_args["display_name"], - protection_policy=module_args["protection_policy"], - ), - tenant_name=module_args["tenant"], - tenant_space_name=module_args["tenant_space"], - ) - operations_api.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.VolumesApi") -@pytest.mark.parametrize( - "updated_volume,called_with", - [ - ( - {"destroyed": True}, - purefusion.VolumePatch(destroyed=purefusion.NullableBoolean(False)), - ), - ( - {"size": 1000000}, - purefusion.VolumePatch(size=purefusion.NullableSize(1048576)), - ), - ( - { - "protection_policy": purefusion.ProtectionPolicyRef( - name="pp2", - id="id_1", - kind="protection_policy", - self_link="self_link", - ) - }, - purefusion.VolumePatch(protection_policy=purefusion.NullableString("pp1")), - ), - ( - {"display_name": "Volume"}, - purefusion.VolumePatch(display_name=purefusion.NullableString("Volume 1")), - ), - ( - { - "storage_class": purefusion.StorageClassRef( - name="sc2", id="id_1", kind="storage_class", self_link="self_link" - ) - }, - purefusion.VolumePatch(storage_class=purefusion.NullableString("sc1")), - ), - ( - { - "placement_group": purefusion.PlacementGroupRef( - name="pg2", id="id_1", kind="placement_group", self_link="self_link" - ) - }, - purefusion.VolumePatch(placement_group=purefusion.NullableString("pg1")), - ), - ( - { - "host_access_policies": [ - purefusion.HostAccessPolicyRef( - name="hap2", - id="id_1", - kind="host_access_policy", - self_link="self_link", - ) - ] - }, - purefusion.VolumePatch( - host_access_policies=purefusion.NullableString("hap1") - ), - ), - ], -) -def test_volume_update_with_state_present_executed_correctly( - mock_volumes_api, - mock_operations_api, - updated_volume, - called_with, - module_args, - volume, -): - volume.update(updated_volume) - operations_api = purefusion.OperationsApi() - volumes_api = purefusion.VolumesApi() - volumes_api.get_volume = MagicMock(return_value=purefusion.Volume(**volume)) - volumes_api.update_volume = MagicMock(return_value=OperationMock(1)) - operations_api.get_operation = MagicMock(return_value=SuccessfulOperationMock) - mock_volumes_api.return_value = volumes_api - mock_operations_api.return_value = operations_api - set_module_args(module_args) - # run module - with pytest.raises(AnsibleExitJson) as exception: - fusion_volume.main() - assert exception.value.changed is True - assert exception.value.id == volume["id"] - volumes_api.get_volume.assert_called_with( - volume_name=module_args["name"], - tenant_name=module_args["tenant"], - tenant_space_name=module_args["tenant_space"], - ) - volumes_api.update_volume.assert_called_once_with( - called_with, - volume_name=module_args["name"], - tenant_name=module_args["tenant"], - tenant_space_name=module_args["tenant_space"], - ) - operations_api.get_operation.assert_called_once_with(1) - - -@patch("fusion.OperationsApi") -@patch("fusion.VolumesApi") -@pytest.mark.parametrize( - "updated_volume,called_with", - [ - ( - {"destroyed": False, "host_access_policies": []}, - purefusion.VolumePatch(destroyed=purefusion.NullableBoolean(True)), - ) - ], -) -def test_volume_update_with_state_absent_executed_correctly( - mock_volumes_api, - mock_operations_api, - updated_volume, - called_with, - module_args, - volume, -): - module_args["state"] = "absent" - del module_args["host_access_policies"] - volume.update(updated_volume) - operations_api = purefusion.OperationsApi() - volumes_api = purefusion.VolumesApi() - volumes_api.get_volume = MagicMock(return_value=purefusion.Volume(**volume)) - volumes_api.update_volume = MagicMock(return_value=OperationMock(1)) - operations_api.get_operation = MagicMock(return_value=SuccessfulOperationMock) - mock_volumes_api.return_value = volumes_api - mock_operations_api.return_value = operations_api - set_module_args(module_args) - # run module - with pytest.raises(AnsibleExitJson) as exception: - fusion_volume.main() - assert exception.value.changed is True - assert exception.value.id == volume["id"] - volumes_api.get_volume.assert_called_with( - volume_name=module_args["name"], - tenant_name=module_args["tenant"], - tenant_space_name=module_args["tenant_space"], - ) - volumes_api.update_volume.assert_called_once_with( - called_with, - volume_name=module_args["name"], - tenant_name=module_args["tenant"], - tenant_space_name=module_args["tenant_space"], - ) - operations_api.get_operation.assert_called_once_with(1) - - -@patch("fusion.OperationsApi") -@patch("fusion.VolumesApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, HTTPError), - ], -) -def test_volume_update_throws_exception( - mock_volumes_api, - mock_operations_api, - exec_original, - exec_catch, - module_args, - volume, -): - module_args["display_name"] = "volume" - operations_api = purefusion.OperationsApi() - volumes_api = purefusion.VolumesApi() - volumes_api.get_volume = MagicMock(return_value=purefusion.Volume(**volume)) - volumes_api.update_volume = MagicMock(side_effect=exec_original) - operations_api.get_operation = MagicMock(return_value=SuccessfulOperationMock) - mock_volumes_api.return_value = volumes_api - mock_operations_api.return_value = operations_api - set_module_args(module_args) - # run module - with pytest.raises(exec_catch): - fusion_volume.main() - - volumes_api.get_volume.assert_called_with( - volume_name=module_args["name"], - tenant_name=module_args["tenant"], - tenant_space_name=module_args["tenant_space"], - ) - volumes_api.update_volume.assert_called_once_with( - purefusion.VolumePatch( - display_name=purefusion.NullableString(module_args["display_name"]) - ), - volume_name=module_args["name"], - tenant_name=module_args["tenant"], - tenant_space_name=module_args["tenant_space"], - ) - operations_api.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.VolumesApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, OperationException), - ], -) -def test_volume_update_operation_throws_exception( - mock_volumes_api, - mock_operations_api, - exec_original, - exec_catch, - module_args, - volume, -): - module_args["display_name"] = "volume" - operations_api = purefusion.OperationsApi() - volumes_api = purefusion.VolumesApi() - volumes_api.get_volume = MagicMock(return_value=purefusion.Volume(**volume)) - volumes_api.update_volume = MagicMock(return_value=OperationMock(1)) - operations_api.get_operation = MagicMock(side_effect=exec_original) - mock_volumes_api.return_value = volumes_api - mock_operations_api.return_value = operations_api - set_module_args(module_args) - # run module - with pytest.raises(exec_catch): - fusion_volume.main() - - volumes_api.get_volume.assert_called_with( - volume_name=module_args["name"], - tenant_name=module_args["tenant"], - tenant_space_name=module_args["tenant_space"], - ) - volumes_api.update_volume.assert_called_once_with( - purefusion.VolumePatch( - display_name=purefusion.NullableString(module_args["display_name"]) - ), - volume_name=module_args["name"], - tenant_name=module_args["tenant"], - tenant_space_name=module_args["tenant_space"], - ) - operations_api.get_operation.assert_called_once_with(1) - - -@patch("fusion.OperationsApi") -@patch("fusion.VolumesApi") -def test_volume_delete_throws_validation_error( - mock_volumes_api, mock_operations_api, absent_module_args, volume -): - volume["host_access_policies"] = [] - operations_api = purefusion.OperationsApi() - volumes_api = purefusion.VolumesApi() - volumes_api.get_volume = MagicMock(return_value=purefusion.Volume(**volume)) - volumes_api.update_volume = MagicMock(return_value=OperationMock(1)) - volumes_api.delete_volume = MagicMock(return_value=OperationMock(2)) - - operations_api.get_operation = MagicMock(return_value=SuccessfulOperationMock) - mock_volumes_api.return_value = volumes_api - mock_operations_api.return_value = operations_api - set_module_args(absent_module_args) - # run module - with pytest.raises(AnsibleFailJson) as ansible_fail: - fusion_volume.main() - assert ansible_fail.match(regexp="BUG: inconsistent state, eradicate_volume") - volumes_api.get_volume.assert_called_with( - volume_name=absent_module_args["name"], - tenant_name=absent_module_args["tenant"], - tenant_space_name=absent_module_args["tenant_space"], - ) - volumes_api.update_volume.assert_called_once_with( - purefusion.VolumePatch(destroyed=purefusion.NullableBoolean(True)), - volume_name=absent_module_args["name"], - tenant_name=absent_module_args["tenant"], - tenant_space_name=absent_module_args["tenant_space"], - ) - volumes_api.delete_volume.assert_not_called() - operations_api.get_operation.assert_called_once_with(1) - - -@patch("fusion.OperationsApi") -@patch("fusion.VolumesApi") -def test_volume_delete_executed_correctly( - mock_volumes_api, mock_operations_api, absent_module_args, destroyed_volume -): - operations_api = purefusion.OperationsApi() - volumes_api = purefusion.VolumesApi() - volumes_api.get_volume = MagicMock( - return_value=purefusion.Volume(**destroyed_volume) - ) - volumes_api.update_volume = MagicMock(return_value=OperationMock(1)) - volumes_api.delete_volume = MagicMock(return_value=OperationMock(2)) - - operations_api.get_operation = MagicMock(return_value=SuccessfulOperationMock) - mock_volumes_api.return_value = volumes_api - mock_operations_api.return_value = operations_api - set_module_args(absent_module_args) - # run module - with pytest.raises(AnsibleExitJson): - fusion_volume.main() - volumes_api.get_volume.assert_called_with( - volume_name=absent_module_args["name"], - tenant_name=absent_module_args["tenant"], - tenant_space_name=absent_module_args["tenant_space"], - ) - volumes_api.update_volume.assert_not_called() - volumes_api.delete_volume.assert_called_once_with( - volume_name=absent_module_args["name"], - tenant_name=absent_module_args["tenant"], - tenant_space_name=absent_module_args["tenant_space"], - ) - operations_api.get_operation.assert_called_once_with(2) - - -@patch("fusion.OperationsApi") -@patch("fusion.VolumesApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, HTTPError), - ], -) -def test_volume_delete_throws_exception( - mock_volumes_api, - mock_operations_api, - exec_original, - exec_catch, - absent_module_args, - destroyed_volume, -): - operations_api = purefusion.OperationsApi() - volumes_api = purefusion.VolumesApi() - volumes_api.get_volume = MagicMock( - return_value=purefusion.Volume(**destroyed_volume) - ) - volumes_api.update_volume = MagicMock(return_value=OperationMock(1)) - volumes_api.delete_volume = MagicMock(side_effect=exec_original) - - operations_api.get_operation = MagicMock(return_value=SuccessfulOperationMock) - mock_volumes_api.return_value = volumes_api - mock_operations_api.return_value = operations_api - set_module_args(absent_module_args) - # run module - with pytest.raises(exec_catch): - fusion_volume.main() - volumes_api.get_volume.assert_called_with( - volume_name=absent_module_args["name"], - tenant_name=absent_module_args["tenant"], - tenant_space_name=absent_module_args["tenant_space"], - ) - volumes_api.update_volume.assert_not_called() - volumes_api.delete_volume.assert_called_once_with( - volume_name=absent_module_args["name"], - tenant_name=absent_module_args["tenant"], - tenant_space_name=absent_module_args["tenant_space"], - ) - - operations_api.get_operation.assert_not_called() - - -@patch("fusion.OperationsApi") -@patch("fusion.VolumesApi") -@pytest.mark.parametrize( - "exec_original,exec_catch", - [ - (purefusion.rest.ApiException, purefusion.rest.ApiException), - (HTTPError, OperationException), - ], -) -def test_volume_delete_operation_throws_exception( - mock_volumes_api, - mock_operations_api, - exec_original, - exec_catch, - absent_module_args, - destroyed_volume, -): - operations_api = purefusion.OperationsApi() - volumes_api = purefusion.VolumesApi() - volumes_api.get_volume = MagicMock( - return_value=purefusion.Volume(**destroyed_volume) - ) - volumes_api.update_volume = MagicMock(return_value=OperationMock(1)) - volumes_api.delete_volume = MagicMock(return_value=OperationMock(2)) - - operations_api.get_operation = MagicMock(side_effect=exec_original) - mock_volumes_api.return_value = volumes_api - mock_operations_api.return_value = operations_api - set_module_args(absent_module_args) - # run module - with pytest.raises(exec_catch): - fusion_volume.main() - volumes_api.get_volume.assert_called_with( - volume_name=absent_module_args["name"], - tenant_name=absent_module_args["tenant"], - tenant_space_name=absent_module_args["tenant_space"], - ) - volumes_api.update_volume.assert_not_called() - volumes_api.delete_volume.assert_called_once_with( - volume_name=absent_module_args["name"], - tenant_name=absent_module_args["tenant"], - tenant_space_name=absent_module_args["tenant_space"], - ) - operations_api.get_operation.assert_called_once_with(2) - - -@patch("fusion.OperationsApi") -@patch("fusion.VolumesApi") -def test_module_updates_on_empty_array_of_haps( - mock_volumes_api, mock_operations_api, module_args, volume -): - volumes_api = purefusion.VolumesApi() - operations_api = purefusion.OperationsApi() - volumes_api.get_volume = MagicMock(return_value=purefusion.Volume(**volume)) - volumes_api.update_volume = MagicMock(return_value=OperationMock(1)) - operations_api.get_operation = MagicMock(return_value=SuccessfulOperationMock) - mock_operations_api.return_value = operations_api - mock_volumes_api.return_value = volumes_api - module_args.update({"state": "absent", "host_access_policies": []}) - set_module_args(module_args) - # run module - with pytest.raises(AnsibleExitJson) as exception: - fusion_volume.main() - assert exception.value.changed is True - assert exception.value.id == volume["id"] - volumes_api.get_volume.assert_called_with( - volume_name=module_args["name"], - tenant_name=module_args["tenant"], - tenant_space_name=module_args["tenant_space"], - ) - volumes_api.update_volume.assert_has_calls( - [ - call( - purefusion.VolumePatch( - host_access_policies=purefusion.NullableString(",".join([])) - ), - volume_name=volume["name"], - tenant_name=volume["tenant"], - tenant_space_name=volume["tenant_space"], - ), - call( - purefusion.VolumePatch(destroyed=purefusion.NullableBoolean(True)), - volume_name=volume["name"], - tenant_name=volume["tenant"], - tenant_space_name=volume["tenant_space"], - ), - ] - ) diff --git a/ansible_collections/purestorage/fusion/tests/functional/utils.py b/ansible_collections/purestorage/fusion/tests/functional/utils.py deleted file mode 100644 index 53e501bc0..000000000 --- a/ansible_collections/purestorage/fusion/tests/functional/utils.py +++ /dev/null @@ -1,131 +0,0 @@ -from __future__ import absolute_import, division, print_function - -__metaclass__ = type - -import json -from dataclasses import dataclass - -from ansible.module_utils import basic -from ansible.module_utils.common.text.converters import to_bytes -from ansible_collections.purestorage.fusion.tests.helpers import ( - OperationResultsDict, -) - -FAKE_RESOURCE_ID = "fake-id-12345" - - -@dataclass -class OperationMock: - """ - Mock Operation object. This object should be returned by mocked api. - """ - - def __init__(self, id=None, success=None): - if success is None: - self.status = "Pending" - elif success: - self.status = "Succeeded" - self.result = OperationResultsDict( - {"resource": OperationResultsDict({"id": FAKE_RESOURCE_ID})} - ) - else: - self.status = "Failed" - self.id = id - - -class SuccessfulOperationMock: - """ - Mock object for successful operation. This object is returned by mocked Operation API if the operation was successful. - """ - - result = OperationResultsDict( - {"resource": OperationResultsDict({"id": FAKE_RESOURCE_ID})} - ) - status = "Succeeded" - - -class FailedOperationMock: - """ - Mock object for failed operation. This object is returned by mocked Operation API if the operation failed. - """ - - status = "Failed" - - -def set_module_args(args): - """ - Prepare arguments so that they will be picked up during module creation. - Docs: https://docs.ansible.com/ansible/latest/dev_guide/testing_units_modules.html - """ - - args = json.dumps({"ANSIBLE_MODULE_ARGS": args}) - basic._ANSIBLE_ARGS = to_bytes(args) - - -class AnsibleExitJson(Exception): - """ - Exception class to be raised by module.exit_json and caught by the test case - Docs: https://docs.ansible.com/ansible/latest/dev_guide/testing_units_modules.html - """ - - def __init__(self, kwargs): - self.kwargs = kwargs - - @property - def changed(self): - return self.kwargs["changed"] - - @property - def id(self): - return self.kwargs["id"] - - @property - def fusion_info(self): - return self.kwargs["fusion_info"] if "fusion_info" in self.kwargs else None - - -class AnsibleFailJson(Exception): - """ - Exception class to be raised by module.fail_json and caught by the test case - Docs: https://docs.ansible.com/ansible/latest/dev_guide/testing_units_modules.html - """ - - def __init__(self, msg, kwargs): - super().__init__(msg) - self.kwargs = kwargs - - -def exit_json(self, **kwargs): - """ - Function to patch over exit_json; package return data into an exception - Docs: https://docs.ansible.com/ansible/latest/dev_guide/testing_units_modules.html - """ - - if "changed" not in kwargs: - kwargs["changed"] = False - raise AnsibleExitJson(kwargs) - - -def fail_json(self, msg, **kwargs): - """ - Function to patch over fail_json; package return data into an exception - Docs: https://docs.ansible.com/ansible/latest/dev_guide/testing_units_modules.html - """ - kwargs["failed"] = True - raise AnsibleFailJson(msg, kwargs) - - -def side_effects_with_exceptions(side_effects): - """ - Assumes side_effects is a list. Works similarly to `MagicMock(side_effect=side_effects)`, - but if item in the list is instance of an exception, it raises it instead of returning it. - """ - side_effects = side_effects.copy() - - def _pop_side_effect(*args, **kwargs): - i = side_effects.pop(0) - if isinstance(i, Exception): - raise i - return i - - return _pop_side_effect |