diff options
author | Vanou Ishii <ishii.vanou@fujitsu.com> | 2022-06-01 15:25:25 +0900 |
---|---|---|
committer | Vanou Ishii <ishii.vanou@fujitsu.com> | 2022-09-18 12:28:29 +0900 |
commit | 37a9a95e7703f612e107a617700e189abea977e5 (patch) | |
tree | 7b3d58df8a88691b83dfc81999e21e52966cbebd /ironic/tests/unit | |
parent | 7d47ee3344c6a8fc81c039fe21cc83645d3c63d9 (diff) | |
download | ironic-37a9a95e7703f612e107a617700e189abea977e5.tar.gz |
Fix iRMC driver to use certification file in HTTPS
This patch modifies iRMC driver to use certification file
when it connects to iRMC via HTTPS
Conflicts:
doc/source/admin/drivers/irmc.rst
driver-requirements.txt
ironic/drivers/modules/irmc/common.py
ironic/drivers/modules/irmc/raid.py
ironic/tests/unit/drivers/modules/irmc/test_common.py
ironic/tests/unit/drivers/modules/irmc/test_power.py
lower-constraints.txt
releasenotes/notes/irmc-add-certification-file-option-34e7a0062c768e58.yaml
Change-Id: If69ce1cf2789d9d60fb8e544596cf7d29eab514d
Co-authored-by: Kobayashi Daisuke <kobayashi.da-06@fujitsu.com>
Co-authored-by: Song Shukun <song.shukun@jp.fujitsu.com>
Story: 2009801
Task: 44345
(cherry picked from commit 64d7a7f3077bc000a18c4a0c56f122941b262483)
(cherry picked from commit 6c0152afa141d05ee28cba81178622021574ae17)
(cherry picked from commit 931f13d3c547928d57052eeae1d8d2fb8c6bd194)
(cherry picked from commit 6177b244a55a1a92dddc6a6763137db608c6c59e)
Diffstat (limited to 'ironic/tests/unit')
4 files changed, 306 insertions, 31 deletions
diff --git a/ironic/tests/unit/drivers/modules/irmc/test_boot.py b/ironic/tests/unit/drivers/modules/irmc/test_boot.py index 1e0ad8317..59649bc85 100644 --- a/ironic/tests/unit/drivers/modules/irmc/test_boot.py +++ b/ironic/tests/unit/drivers/modules/irmc/test_boot.py @@ -63,6 +63,7 @@ PARSED_IFNO = { 'irmc_snmp_version': 'v2c', 'irmc_snmp_security': None, 'irmc_sensor_method': 'ipmitool', + 'irmc_verify_ca': True, } diff --git a/ironic/tests/unit/drivers/modules/irmc/test_common.py b/ironic/tests/unit/drivers/modules/irmc/test_common.py index 3f0c3d94a..becfdf98f 100644 --- a/ironic/tests/unit/drivers/modules/irmc/test_common.py +++ b/ironic/tests/unit/drivers/modules/irmc/test_common.py @@ -16,6 +16,7 @@ Test class for common methods used by iRMC modules. """ +import os from unittest import mock from oslo_config import cfg @@ -68,6 +69,7 @@ class IRMCValidateParametersTestCase(BaseIRMCTest): self.assertEqual(161, info['irmc_snmp_port']) self.assertEqual('public', info['irmc_snmp_community']) self.assertFalse(info['irmc_snmp_security']) + self.assertTrue(info['irmc_verify_ca']) def test_parse_driver_option_default(self): self.node.driver_info = { @@ -81,6 +83,7 @@ class IRMCValidateParametersTestCase(BaseIRMCTest): self.assertEqual(443, info['irmc_port']) self.assertEqual(60, info['irmc_client_timeout']) self.assertEqual('ipmitool', info['irmc_sensor_method']) + self.assertEqual(True, info['irmc_verify_ca']) def test_parse_driver_info_missing_address(self): del self.node.driver_info['irmc_address'] @@ -153,25 +156,176 @@ class IRMCValidateParametersTestCase(BaseIRMCTest): self.assertRaises(exception.InvalidParameterValue, irmc_common.parse_driver_info, self.node) + @mock.patch.object(os.path, 'isabs', return_value=True, autospec=True) + @mock.patch.object(os.path, 'isdir', return_value=True, autospec=True) + def test_parse_driver_info_dir_path_verify_ca(self, mock_isdir, + mock_isabs): + fake_path = 'absolute/path/to/a/valid/CA' + self.node.driver_info['irmc_verify_ca'] = fake_path + info = irmc_common.parse_driver_info(self.node) + self.assertEqual(fake_path, info['irmc_verify_ca']) + mock_isdir.assert_called_once_with(fake_path) + mock_isabs.assert_called_once_with(fake_path) + + @mock.patch.object(os.path, 'isabs', return_value=True, autospec=True) + @mock.patch.object(os.path, 'isfile', return_value=True, autospec=True) + def test_parse_driver_info_file_path_verify_ca(self, mock_isfile, + mock_isabs): + fake_path = 'absolute/path/to/a/valid/ca.pem' + self.node.driver_info['irmc_verify_ca'] = fake_path + info = irmc_common.parse_driver_info(self.node) + self.assertEqual(fake_path, info['irmc_verify_ca']) + mock_isfile.assert_called_once_with(fake_path) + mock_isabs.assert_called_once_with(fake_path) + + def test_parse_driver_info_string_bool_verify_ca(self): + self.node.driver_info['irmc_verify_ca'] = "False" + info = irmc_common.parse_driver_info(self.node) + self.assertFalse(info['irmc_verify_ca']) + + def test_parse_driver_info_invalid_verify_ca(self): + self.node.driver_info['irmc_verify_ca'] = "1234" + self.assertRaises(exception.InvalidParameterValue, + irmc_common.parse_driver_info, self.node) + self.node.driver_info['irmc_verify_ca'] = 1234 + self.assertRaises(exception.InvalidParameterValue, + irmc_common.parse_driver_info, self.node) + class IRMCCommonMethodsTestCase(BaseIRMCTest): + @mock.patch.object(irmc_common, 'LOG', autospec=True) + @mock.patch.object(irmc_common, 'scci_mod', spec_set=['__version__']) + @mock.patch.object(irmc_common, 'scci', + spec_set=mock_specs.SCCICLIENT_IRMC_SCCI_SPEC) + def test_get_irmc_client_cert_support_http(self, mock_scci, + mock_scciclient, mock_LOG): + scci_version_list = ['0.8.2', '0.8.3.1', '0.9.5', '0.10.1', '0.10.2', + '0.11.3', '0.11.4', '0.12.0', '0.12.1'] + for ver in scci_version_list: + mock_scciclient.__version__ = ver + self.info['irmc_port'] = 80 + self.info['irmc_auth_method'] = 'digest' + self.info['irmc_client_timeout'] = 60 + self.info['irmc_verify_ca'] = True + mock_scci.get_client.return_value = 'get_client' + returned_mock_scci_get_client = irmc_common.get_irmc_client( + self.node) + mock_scci.get_client.assert_called_with( + self.info['irmc_address'], + self.info['irmc_username'], + self.info['irmc_password'], + port=self.info['irmc_port'], + auth_method=self.info['irmc_auth_method'], + verify=self.info['irmc_verify_ca'], + client_timeout=self.info['irmc_client_timeout']) + self.assertEqual('get_client', returned_mock_scci_get_client) + mock_LOG.warning.assert_not_called() + mock_scci.reset_mock() + mock_LOG.warning.reset_mock() + + @mock.patch.object(irmc_common, 'LOG', autospec=True) + @mock.patch.object(irmc_common, 'scci_mod', spec_set=['__version__']) @mock.patch.object(irmc_common, 'scci', spec_set=mock_specs.SCCICLIENT_IRMC_SCCI_SPEC) - def test_get_irmc_client(self, mock_scci): - self.info['irmc_port'] = 80 - self.info['irmc_auth_method'] = 'digest' - self.info['irmc_client_timeout'] = 60 - mock_scci.get_client.return_value = 'get_client' - returned_mock_scci_get_client = irmc_common.get_irmc_client(self.node) - mock_scci.get_client.assert_called_with( - self.info['irmc_address'], - self.info['irmc_username'], - self.info['irmc_password'], - port=self.info['irmc_port'], - auth_method=self.info['irmc_auth_method'], - client_timeout=self.info['irmc_client_timeout']) - self.assertEqual('get_client', returned_mock_scci_get_client) + def test_get_irmc_client_cert_support_https(self, mock_scci, + mock_scciclient, mock_LOG): + scci_version_list = ['0.8.2', '0.8.3.1', '0.9.5', '0.10.1', '0.10.2', + '0.11.3', '0.11.4', '0.12.0', '0.12.1'] + self.node.driver_info = { + "irmc_address": "1.2.3.4", + "irmc_username": "admin0", + "irmc_password": "fake0", + "irmc_port": "443", + "irmc_auth_method": "digest", + } + + for ver in scci_version_list: + mock_scciclient.__version__ = ver + self.info['irmc_port'] = 443 + self.info['irmc_auth_method'] = 'digest' + self.info['irmc_client_timeout'] = 60 + self.info['irmc_verify_ca'] = True + mock_scci.get_client.return_value = 'get_client' + returned_mock_scci_get_client = irmc_common.get_irmc_client( + self.node) + mock_scci.get_client.assert_called_with( + self.info['irmc_address'], + self.info['irmc_username'], + self.info['irmc_password'], + port=self.info['irmc_port'], + auth_method=self.info['irmc_auth_method'], + verify=self.info['irmc_verify_ca'], + client_timeout=self.info['irmc_client_timeout']) + self.assertEqual('get_client', returned_mock_scci_get_client) + mock_LOG.warning.assert_not_called() + mock_scci.reset_mock() + mock_LOG.warning.reset_mock() + + @mock.patch.object(irmc_common, 'LOG', autospec=True) + @mock.patch.object(irmc_common, 'scci_mod', spec_set=['__version__']) + @mock.patch.object(irmc_common, 'scci', + spec_set=mock_specs.SCCICLIENT_IRMC_SCCI_SPEC) + def test_get_irmc_client_no_cert_support_http(self, mock_scci, + mock_scciclient, mock_LOG): + scci_version_list = ['0.8.0', '0.8.1', '0.9.0', '0.9.4', '0.10.0', + '0.11.2'] + + for ver in scci_version_list: + mock_scciclient.__version__ = ver + self.info['irmc_port'] = 80 + self.info['irmc_auth_method'] = 'digest' + self.info['irmc_client_timeout'] = 60 + mock_scci.get_client.return_value = 'get_client' + returned_mock_scci_get_client = irmc_common.get_irmc_client( + self.node) + mock_scci.get_client.assert_called_with( + self.info['irmc_address'], + self.info['irmc_username'], + self.info['irmc_password'], + port=self.info['irmc_port'], + auth_method=self.info['irmc_auth_method'], + client_timeout=self.info['irmc_client_timeout']) + self.assertEqual('get_client', returned_mock_scci_get_client) + mock_LOG.warning.assert_not_called() + mock_scci.reset_mock() + mock_LOG.warning.reset_mock() + + @mock.patch.object(irmc_common, 'LOG', autospec=True) + @mock.patch.object(irmc_common, 'scci_mod', spec_set=['__version__']) + @mock.patch.object(irmc_common, 'scci', + spec_set=mock_specs.SCCICLIENT_IRMC_SCCI_SPEC) + def test_get_irmc_client_no_cert_support_https(self, mock_scci, + mock_scciclient, mock_LOG): + scci_version_list = ['0.8.0', '0.8.1', '0.9.0', '0.9.4', '0.10.0', + '0.11.2'] + self.node.driver_info = { + "irmc_address": "1.2.3.4", + "irmc_username": "admin0", + "irmc_password": "fake0", + "irmc_port": "443", + "irmc_auth_method": "digest", + } + + for ver in scci_version_list: + mock_scciclient.__version__ = ver + self.info['irmc_port'] = 443 + self.info['irmc_auth_method'] = 'digest' + self.info['irmc_client_timeout'] = 60 + mock_scci.get_client.return_value = 'get_client' + returned_mock_scci_get_client = irmc_common.get_irmc_client( + self.node) + mock_scci.get_client.assert_called_with( + self.info['irmc_address'], + self.info['irmc_username'], + self.info['irmc_password'], + port=self.info['irmc_port'], + auth_method=self.info['irmc_auth_method'], + client_timeout=self.info['irmc_client_timeout']) + self.assertEqual('get_client', returned_mock_scci_get_client) + mock_LOG.warning.assert_called_once() + mock_scci.reset_mock() + mock_LOG.warning.reset_mock() def test_update_ipmi_properties(self): with task_manager.acquire(self.context, self.node.uuid, @@ -187,22 +341,139 @@ class IRMCCommonMethodsTestCase(BaseIRMCTest): expected_info = dict(self.info, **ipmi_info) self.assertEqual(expected_info, actual_info) + @mock.patch.object(irmc_common, 'LOG', autospec=True) + @mock.patch.object(irmc_common, 'scci_mod', spec_set=['__version__']) + @mock.patch.object(irmc_common, 'scci', + spec_set=mock_specs.SCCICLIENT_IRMC_SCCI_SPEC) + def test_get_irmc_report_cert_support_http(self, mock_scci, + mock_scciclient, mock_LOG): + scci_version_list = ['0.8.2', '0.8.3.1', '0.9.5', '0.10.1', '0.10.2', + '0.11.3', '0.11.4', '0.12.0', '0.12.1'] + + for ver in scci_version_list: + mock_scciclient.__version__ = ver + self.info['irmc_port'] = 80 + self.info['irmc_auth_method'] = 'digest' + self.info['irmc_client_timeout'] = 60 + self.info['irmc_verify_ca'] = True + mock_scci.get_report.return_value = 'get_report' + returned_mock_scci_get_report = irmc_common.get_irmc_report( + self.node) + mock_scci.get_report.assert_called_with( + self.info['irmc_address'], + self.info['irmc_username'], + self.info['irmc_password'], + port=self.info['irmc_port'], + auth_method=self.info['irmc_auth_method'], + verify=self.info['irmc_verify_ca'], + client_timeout=self.info['irmc_client_timeout']) + self.assertEqual('get_report', returned_mock_scci_get_report) + mock_LOG.warning.assert_not_called() + mock_scci.reset_mock() + mock_LOG.warning.reset_mock() + + @mock.patch.object(irmc_common, 'LOG', autospec=True) + @mock.patch.object(irmc_common, 'scci_mod', spec_set=['__version__']) @mock.patch.object(irmc_common, 'scci', spec_set=mock_specs.SCCICLIENT_IRMC_SCCI_SPEC) - def test_get_irmc_report(self, mock_scci): - self.info['irmc_port'] = 80 - self.info['irmc_auth_method'] = 'digest' - self.info['irmc_client_timeout'] = 60 - mock_scci.get_report.return_value = 'get_report' - returned_mock_scci_get_report = irmc_common.get_irmc_report(self.node) - mock_scci.get_report.assert_called_with( - self.info['irmc_address'], - self.info['irmc_username'], - self.info['irmc_password'], - port=self.info['irmc_port'], - auth_method=self.info['irmc_auth_method'], - client_timeout=self.info['irmc_client_timeout']) - self.assertEqual('get_report', returned_mock_scci_get_report) + def test_get_irmc_report_cert_support_https(self, mock_scci, + mock_scciclient, mock_LOG): + scci_version_list = ['0.8.2', '0.8.3.1', '0.9.5', '0.10.1', '0.10.2', + '0.11.3', '0.11.4', '0.12.0', '0.12.1'] + self.node.driver_info = { + "irmc_address": "1.2.3.4", + "irmc_username": "admin0", + "irmc_password": "fake0", + "irmc_port": "443", + "irmc_auth_method": "digest", + } + + for ver in scci_version_list: + mock_scciclient.__version__ = ver + self.info['irmc_port'] = 443 + self.info['irmc_auth_method'] = 'digest' + self.info['irmc_client_timeout'] = 60 + self.info['irmc_verify_ca'] = True + mock_scci.get_report.return_value = 'get_report' + returned_mock_scci_get_report = irmc_common.get_irmc_report( + self.node) + mock_scci.get_report.assert_called_with( + self.info['irmc_address'], + self.info['irmc_username'], + self.info['irmc_password'], + port=self.info['irmc_port'], + auth_method=self.info['irmc_auth_method'], + verify=self.info['irmc_verify_ca'], + client_timeout=self.info['irmc_client_timeout']) + self.assertEqual('get_report', returned_mock_scci_get_report) + mock_LOG.warning.assert_not_called() + mock_scci.reset_mock() + mock_LOG.warning.reset_mock() + + @mock.patch.object(irmc_common, 'LOG', autospec=True) + @mock.patch.object(irmc_common, 'scci_mod', spec_set=['__version__']) + @mock.patch.object(irmc_common, 'scci', + spec_set=mock_specs.SCCICLIENT_IRMC_SCCI_SPEC) + def test_get_irmc_report_no_cert_support_http(self, mock_scci, + mock_scciclient, mock_LOG): + scci_version_list = ['0.8.0', '0.8.1', '0.9.0', '0.9.4', '0.10.0', + '0.11.2'] + + for ver in scci_version_list: + mock_scciclient.__version__ = ver + self.info['irmc_port'] = 80 + self.info['irmc_auth_method'] = 'digest' + self.info['irmc_client_timeout'] = 60 + mock_scci.get_report.return_value = 'get_report' + returned_mock_scci_get_report = irmc_common.get_irmc_report( + self.node) + mock_scci.get_report.assert_called_with( + self.info['irmc_address'], + self.info['irmc_username'], + self.info['irmc_password'], + port=self.info['irmc_port'], + auth_method=self.info['irmc_auth_method'], + client_timeout=self.info['irmc_client_timeout']) + self.assertEqual('get_report', returned_mock_scci_get_report) + mock_LOG.warning.assert_not_called() + mock_scci.reset_mock() + mock_LOG.warning.reset_mock() + + @mock.patch.object(irmc_common, 'LOG', autospec=True) + @mock.patch.object(irmc_common, 'scci_mod', spec_set=['__version__']) + @mock.patch.object(irmc_common, 'scci', + spec_set=mock_specs.SCCICLIENT_IRMC_SCCI_SPEC) + def test_get_irmc_report_no_cert_support_https(self, mock_scci, + mock_scciclient, mock_LOG): + scci_version_list = ['0.8.0', '0.8.1', '0.9.0', '0.9.4', '0.10.0', + '0.11.2'] + self.node.driver_info = { + "irmc_address": "1.2.3.4", + "irmc_username": "admin0", + "irmc_password": "fake0", + "irmc_port": "443", + "irmc_auth_method": "digest", + } + + for ver in scci_version_list: + mock_scciclient.__version__ = ver + self.info['irmc_port'] = 443 + self.info['irmc_auth_method'] = 'digest' + self.info['irmc_client_timeout'] = 60 + mock_scci.get_report.return_value = 'get_report' + returned_mock_scci_get_report = irmc_common.get_irmc_report( + self.node) + mock_scci.get_report.assert_called_with( + self.info['irmc_address'], + self.info['irmc_username'], + self.info['irmc_password'], + port=self.info['irmc_port'], + auth_method=self.info['irmc_auth_method'], + client_timeout=self.info['irmc_client_timeout']) + self.assertEqual('get_report', returned_mock_scci_get_report) + mock_LOG.warning.assert_called_once() + mock_scci.reset_mock() + mock_LOG.warning.reset_mock() def test_out_range_port(self): self.assertRaises(ValueError, cfg.CONF.set_override, diff --git a/ironic/tests/unit/drivers/modules/irmc/test_power.py b/ironic/tests/unit/drivers/modules/irmc/test_power.py index c4142202c..1449bc8ad 100644 --- a/ironic/tests/unit/drivers/modules/irmc/test_power.py +++ b/ironic/tests/unit/drivers/modules/irmc/test_power.py @@ -211,6 +211,7 @@ class IRMCPowerInternalMethodsTestCase(test_common.BaseIRMCTest): _wait_power_state_mock.assert_called_once_with(task, target_state, timeout=None) + @mock.patch.object(irmc_common, 'scci_mod', spec_set=['__version__']) @mock.patch.object(irmc_power, '_wait_power_state', spec_set=True, autospec=True) @mock.patch.object(irmc_boot, 'attach_boot_iso_if_needed', @@ -218,7 +219,8 @@ class IRMCPowerInternalMethodsTestCase(test_common.BaseIRMCTest): def test__set_power_state_invalid_target_state( self, attach_boot_iso_if_needed_mock, - _wait_power_state_mock): + _wait_power_state_mock, mock_scciclient): + mock_scciclient.__version__ = '0.8.2' with task_manager.acquire(self.context, self.node.uuid, shared=True) as task: self.assertRaises(exception.InvalidParameterValue, diff --git a/ironic/tests/unit/drivers/modules/irmc/test_raid.py b/ironic/tests/unit/drivers/modules/irmc/test_raid.py index d95f09d16..203bb820d 100644 --- a/ironic/tests/unit/drivers/modules/irmc/test_raid.py +++ b/ironic/tests/unit/drivers/modules/irmc/test_raid.py @@ -20,6 +20,7 @@ from unittest import mock from ironic.common import exception from ironic.conductor import task_manager +from ironic.drivers.modules.irmc import common as irmc_common from ironic.drivers.modules.irmc import raid from ironic.tests.unit.drivers.modules.irmc import test_common @@ -694,8 +695,8 @@ class IRMCRaidConfigurationInternalMethodsTestCase(test_common.BaseIRMCTest): with task_manager.acquire(self.context, self.node.uuid, shared=True) as task: raid._commit_raid_config(task) - get_raid_adapter_mock.assert_called_once_with( - task.node.driver_info) + irmc_info = irmc_common.parse_driver_info(task.node) + get_raid_adapter_mock.assert_called_once_with(irmc_info) update_raid_info_mock.assert_called_once_with( task.node, task.node.raid_config) self.assertEqual(task.node.raid_config['logical_disks'], |