mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-07-23 13:20:23 -07:00
Migrating DellEMC collections from community.general collections (#1699)
* migration modification for dellemc collections * removing dellemc collections * Update changelogs/fragments/948-dellemc-migration-removal.yml Co-authored-by: Felix Fontein <felix@fontein.de> * Update 948-dellemc-migration-removal.yml * Update 948-dellemc-migration-removal.yml * Update runtime.yml * Update meta/runtime.yml Co-authored-by: Felix Fontein <felix@fontein.de> * Update runtime.yml * deleted symlink entries * Update 948-dellemc-migration-removal.yml * Update changelogs/fragments/948-dellemc-migration-removal.yml Co-authored-by: Felix Fontein <felix@fontein.de> * Update changelogs/fragments/948-dellemc-migration-removal.yml Co-authored-by: Felix Fontein <felix@fontein.de>
This commit is contained in:
parent
6af3c96d8e
commit
8afdd23be4
19 changed files with 23 additions and 1433 deletions
|
@ -1,79 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
#
|
||||
# Dell EMC OpenManage Ansible Modules
|
||||
# Version 2.0
|
||||
# Copyright (C) 2019 Dell Inc.
|
||||
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# All rights reserved. Dell, EMC, and other trademarks are trademarks of Dell Inc. or its subsidiaries.
|
||||
# Other trademarks may be trademarks of their respective owners.
|
||||
#
|
||||
|
||||
from __future__ import (absolute_import, division, print_function)
|
||||
__metaclass__ = type
|
||||
|
||||
import pytest
|
||||
from ansible.module_utils.urls import ConnectionError, SSLValidationError
|
||||
from ansible.module_utils.six.moves.urllib.error import URLError, HTTPError
|
||||
from ansible_collections.community.general.plugins.module_utils.remote_management.dellemc.ome import RestOME
|
||||
from ansible_collections.community.general.tests.unit.compat.mock import MagicMock
|
||||
import json
|
||||
|
||||
|
||||
class TestRestOME(object):
|
||||
@pytest.fixture
|
||||
def mock_response(self):
|
||||
mock_response = MagicMock()
|
||||
mock_response.getcode.return_value = 200
|
||||
mock_response.headers = mock_response.getheaders.return_value = {'X-Auth-Token': 'token_id'}
|
||||
mock_response.read.return_value = json.dumps({"value": "data"})
|
||||
return mock_response
|
||||
|
||||
def test_invoke_request_with_session(self, mock_response, mocker):
|
||||
mocker.patch('ansible_collections.community.general.plugins.module_utils.remote_management.dellemc.ome.open_url',
|
||||
return_value=mock_response)
|
||||
module_params = {'hostname': '192.168.0.1', 'username': 'username',
|
||||
'password': 'password', "port": 443}
|
||||
req_session = True
|
||||
with RestOME(module_params, req_session) as obj:
|
||||
response = obj.invoke_request("/testpath", "GET")
|
||||
assert response.status_code == 200
|
||||
assert response.json_data == {"value": "data"}
|
||||
assert response.success is True
|
||||
|
||||
def test_invoke_request_without_session(self, mock_response, mocker):
|
||||
mocker.patch('ansible_collections.community.general.plugins.module_utils.remote_management.dellemc.ome.open_url',
|
||||
return_value=mock_response)
|
||||
module_params = {'hostname': '192.168.0.1', 'username': 'username',
|
||||
'password': 'password', "port": 443}
|
||||
req_session = False
|
||||
with RestOME(module_params, req_session) as obj:
|
||||
response = obj.invoke_request("/testpath", "GET")
|
||||
assert response.status_code == 200
|
||||
assert response.json_data == {"value": "data"}
|
||||
assert response.success is True
|
||||
|
||||
@pytest.mark.parametrize("exc", [URLError, SSLValidationError, ConnectionError])
|
||||
def test_invoke_request_error_case_handling(self, exc, mock_response, mocker):
|
||||
open_url_mock = mocker.patch('ansible_collections.community.general.plugins.module_utils.remote_management.dellemc.ome.open_url',
|
||||
return_value=mock_response)
|
||||
open_url_mock.side_effect = exc("test")
|
||||
module_params = {'hostname': '192.168.0.1', 'username': 'username',
|
||||
'password': 'password', "port": 443}
|
||||
req_session = False
|
||||
with pytest.raises(exc) as e:
|
||||
with RestOME(module_params, req_session) as obj:
|
||||
obj.invoke_request("/testpath", "GET")
|
||||
|
||||
def test_invoke_request_http_error_handling(self, mock_response, mocker):
|
||||
open_url_mock = mocker.patch('ansible_collections.community.general.plugins.module_utils.remote_management.dellemc.ome.open_url',
|
||||
return_value=mock_response)
|
||||
open_url_mock.side_effect = HTTPError('http://testhost.com/', 400,
|
||||
'Bad Request Error', {}, None)
|
||||
module_params = {'hostname': '192.168.0.1', 'username': 'username',
|
||||
'password': 'password', "port": 443}
|
||||
req_session = False
|
||||
with pytest.raises(HTTPError) as e:
|
||||
with RestOME(module_params, req_session) as obj:
|
||||
obj.invoke_request("/testpath", "GET")
|
|
@ -1,196 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
#
|
||||
# Dell EMC OpenManage Ansible Modules
|
||||
# Version 2.0
|
||||
# Copyright (C) 2019 Dell Inc.
|
||||
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# All rights reserved. Dell, EMC, and other trademarks are trademarks of Dell Inc. or its subsidiaries.
|
||||
# Other trademarks may be trademarks of their respective owners.
|
||||
#
|
||||
|
||||
from __future__ import (absolute_import, division, print_function)
|
||||
__metaclass__ = type
|
||||
|
||||
import pytest
|
||||
from ansible_collections.community.general.tests.unit.plugins.modules.utils import set_module_args, exit_json, \
|
||||
fail_json, AnsibleFailJson, AnsibleExitJson
|
||||
from ansible.module_utils import basic
|
||||
from ansible_collections.community.general.plugins.modules.remote_management.dellemc import ome_device_info
|
||||
from ansible.module_utils.six.moves.urllib.error import HTTPError
|
||||
|
||||
default_args = {'hostname': '192.168.0.1', 'username': 'username', 'password': 'password'}
|
||||
resource_basic_inventory = {"basic_inventory": "DeviceService/Devices"}
|
||||
resource_detailed_inventory = {"detailed_inventory:": {"device_id": {1234: None},
|
||||
"device_service_tag": {1345: "MXL1234"}}}
|
||||
|
||||
|
||||
class TestOmeDeviceInfo(object):
|
||||
module = ome_device_info
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def module_mock(self, mocker):
|
||||
return mocker.patch.multiple(basic.AnsibleModule, exit_json=exit_json, fail_json=fail_json)
|
||||
|
||||
@pytest.fixture
|
||||
def connection_mock(self, mocker):
|
||||
connection_class_mock = mocker.patch('ansible_collections.community.general.plugins.modules.remote_management.dellemc.ome_device_info.RestOME')
|
||||
return connection_class_mock.return_value
|
||||
|
||||
@pytest.fixture
|
||||
def response_mock(self, mocker):
|
||||
response_class_mock = mocker.patch('ansible_collections.community.general.plugins.module_utils.remote_management.dellemc.ome.OpenURLResponse')
|
||||
return response_class_mock
|
||||
|
||||
@pytest.fixture
|
||||
def validate_inputs_mock(self, mocker):
|
||||
response_class_mock = mocker.patch('ansible_collections.community.general.plugins.modules.remote_management.dellemc.ome_device_info._validate_inputs')
|
||||
response_class_mock.return_value = None
|
||||
|
||||
@pytest.fixture
|
||||
def get_device_identifier_map_mock(self, mocker):
|
||||
response_class_mock = mocker.patch(
|
||||
'ansible_collections.community.general.plugins.modules.remote_management.dellemc.ome_device_info._get_device_identifier_map'
|
||||
)
|
||||
response_class_mock.return_value = resource_detailed_inventory
|
||||
return response_class_mock.return_value
|
||||
|
||||
@pytest.fixture
|
||||
def get_resource_parameters_mock(self, mocker):
|
||||
response_class_mock = mocker.patch(
|
||||
'ansible_collections.community.general.plugins.modules.remote_management.dellemc.ome_device_info._get_resource_parameters'
|
||||
)
|
||||
return response_class_mock
|
||||
|
||||
def test_main_basic_inventory_success_case(self, module_mock, validate_inputs_mock, connection_mock, get_resource_parameters_mock, response_mock):
|
||||
get_resource_parameters_mock.return_value = resource_basic_inventory
|
||||
connection_mock.__enter__.return_value = connection_mock
|
||||
connection_mock.invoke_request.return_value = response_mock
|
||||
response_mock.json_data = {"value": [{"device_id1": "details", "device_id2": "details"}]}
|
||||
response_mock.status_code = 200
|
||||
result = self._run_module(default_args)
|
||||
assert result['changed'] is False
|
||||
assert 'device_info' in result
|
||||
|
||||
def test_main_basic_inventory_failure_case(self, module_mock, validate_inputs_mock, connection_mock, get_resource_parameters_mock, response_mock):
|
||||
get_resource_parameters_mock.return_value = resource_basic_inventory
|
||||
connection_mock.__enter__.return_value = connection_mock
|
||||
connection_mock.invoke_request.return_value = response_mock
|
||||
response_mock.status_code = 500
|
||||
result = self._run_module_with_fail_json(default_args)
|
||||
assert result['msg'] == 'Failed to fetch the device information'
|
||||
|
||||
def test_main_detailed_inventory_success_case(self, module_mock, validate_inputs_mock, connection_mock, get_resource_parameters_mock, response_mock):
|
||||
default_args.update({"fact_subset": "detailed_inventory", "system_query_options": {"device_id": [1234], "device_service_tag": ["MXL1234"]}})
|
||||
detailed_inventory = {"detailed_inventory:": {"device_id": {1234: "DeviceService/Devices(1234)/InventoryDetails"},
|
||||
"device_service_tag": {"MXL1234": "DeviceService/Devices(4321)/InventoryDetails"}}}
|
||||
get_resource_parameters_mock.return_value = detailed_inventory
|
||||
connection_mock.__enter__.return_value = connection_mock
|
||||
connection_mock.invoke_request.return_value = response_mock
|
||||
response_mock.json_data = {"value": [{"device_id": {"1234": "details"}}, {"device_service_tag": {"MXL1234": "details"}}]}
|
||||
response_mock.status_code = 200
|
||||
result = self._run_module(default_args)
|
||||
assert result['changed'] is False
|
||||
assert 'device_info' in result
|
||||
|
||||
def test_main_HTTPError_error_case(self, module_mock, validate_inputs_mock, connection_mock, get_resource_parameters_mock, response_mock):
|
||||
get_resource_parameters_mock.return_value = resource_basic_inventory
|
||||
connection_mock.__enter__.return_value = connection_mock
|
||||
connection_mock.invoke_request.side_effect = HTTPError('http://testhost.com', 400, '', {}, None)
|
||||
response_mock.json_data = {"value": [{"device_id1": "details", "device_id2": "details"}]}
|
||||
response_mock.status_code = 400
|
||||
result = self._run_module_with_fail_json(default_args)
|
||||
assert 'device_info' not in result
|
||||
assert result['failed'] is True
|
||||
|
||||
@pytest.mark.parametrize("fact_subset, mutually_exclusive_call", [("basic_inventory", False), ("detailed_inventory", True)])
|
||||
def test_validate_inputs(self, fact_subset, mutually_exclusive_call, mocker):
|
||||
module_params = {"fact_subset": fact_subset}
|
||||
check_mutually_inclusive_arguments_mock = mocker.patch(
|
||||
'ansible_collections.community.general.plugins.modules.remote_management.dellemc.ome_device_info._check_mutually_inclusive_arguments')
|
||||
check_mutually_inclusive_arguments_mock.return_value = None
|
||||
self.module._validate_inputs(module_params)
|
||||
if mutually_exclusive_call:
|
||||
check_mutually_inclusive_arguments_mock.assert_called()
|
||||
else:
|
||||
check_mutually_inclusive_arguments_mock.assert_not_called()
|
||||
check_mutually_inclusive_arguments_mock.reset_mock()
|
||||
|
||||
system_query_options_params = [{"system_query_options": None}, {"system_query_options": {"device_id": None}},
|
||||
{"system_query_options": {"device_service_tag": None}}]
|
||||
|
||||
@pytest.mark.parametrize("system_query_options_params", system_query_options_params)
|
||||
def test_check_mutually_inclusive_arguments(self, system_query_options_params):
|
||||
module_params = {"fact_subset": "subsystem_health"}
|
||||
required_args = ["device_id", "device_service_tag"]
|
||||
module_params.update(system_query_options_params)
|
||||
with pytest.raises(ValueError) as ex:
|
||||
self.module._check_mutually_inclusive_arguments(module_params["fact_subset"], module_params, ["device_id", "device_service_tag"])
|
||||
assert "One of the following {0} is required for {1}".format(required_args, module_params["fact_subset"]) == str(ex.value)
|
||||
|
||||
params = [{"fact_subset": "basic_inventory", "system_query_options": {"device_id": [1234]}},
|
||||
{"fact_subset": "subsystem_health", "system_query_options": {"device_service_tag": ["MXL1234"]}},
|
||||
{"fact_subset": "detailed_inventory", "system_query_options": {"device_id": [1234], "inventory_type": "serverDeviceCards"}}]
|
||||
|
||||
@pytest.mark.parametrize("module_params", params)
|
||||
def test_get_resource_parameters(self, module_params, connection_mock):
|
||||
self.module._get_resource_parameters(module_params, connection_mock)
|
||||
|
||||
@pytest.mark.parametrize("module_params,data", [({"system_query_options": None}, None), ({"system_query_options": {"fileter": None}}, None),
|
||||
({"system_query_options": {"filter": "abc"}}, "$filter")])
|
||||
def test_get_query_parameters(self, module_params, data):
|
||||
res = self.module._get_query_parameters(module_params)
|
||||
if data is not None:
|
||||
assert data in res
|
||||
else:
|
||||
assert res is None
|
||||
|
||||
@pytest.mark.parametrize("module_params", params)
|
||||
def test_get_device_identifier_map(self, module_params, connection_mock, mocker):
|
||||
get_device_id_from_service_tags_mock = mocker.patch(
|
||||
'ansible_collections.community.general.plugins.modules.remote_management.dellemc.ome_device_info._get_device_id_from_service_tags'
|
||||
)
|
||||
get_device_id_from_service_tags_mock.return_value = None
|
||||
res = self.module._get_device_identifier_map(module_params, connection_mock)
|
||||
assert isinstance(res, dict)
|
||||
|
||||
def test_check_duplicate_device_id(self):
|
||||
self.module._check_duplicate_device_id([1234], {1234: "MX1234"})
|
||||
assert self.module.device_fact_error_report["MX1234"] == "Duplicate report of device_id: 1234"
|
||||
|
||||
@pytest.mark.parametrize("val,expected_res", [(123, True), ("abc", False)])
|
||||
def test_is_int(self, val, expected_res):
|
||||
actual_res = self.module.is_int(val)
|
||||
assert actual_res == expected_res
|
||||
|
||||
def test_get_device_id_from_service_tags(self, connection_mock, response_mock):
|
||||
connection_mock.__enter__.return_value = connection_mock
|
||||
connection_mock.invoke_request.return_value = response_mock
|
||||
response_mock.json_data = {"value": [{"DeviceServiceTag": "MX1234", "Id": 1234}]}
|
||||
response_mock.status_code = 200
|
||||
response_mock.success = True
|
||||
self.module._get_device_id_from_service_tags(["MX1234", "INVALID"], connection_mock)
|
||||
|
||||
def test_get_device_id_from_service_tags_error_case(self, connection_mock, response_mock):
|
||||
connection_mock.__enter__.return_value = connection_mock
|
||||
connection_mock.invoke_request.side_effect = HTTPError('http://testhost.com',
|
||||
400, '', {}, None)
|
||||
response_mock.json_data = {"value": [{"DeviceServiceTag": "MX1234", "Id": 1234}]}
|
||||
response_mock.status_code = 200
|
||||
response_mock.success = True
|
||||
with pytest.raises(HTTPError) as ex:
|
||||
self.module._get_device_id_from_service_tags(["INVALID"], connection_mock)
|
||||
|
||||
def _run_module(self, module_args):
|
||||
set_module_args(module_args)
|
||||
with pytest.raises(AnsibleExitJson) as ex:
|
||||
self.module.main()
|
||||
return ex.value.args[0]
|
||||
|
||||
def _run_module_with_fail_json(self, module_args):
|
||||
set_module_args(module_args)
|
||||
with pytest.raises(AnsibleFailJson) as exc:
|
||||
self.module.main()
|
||||
result = exc.value.args[0]
|
||||
return result
|
Loading…
Add table
Add a link
Reference in a new issue