diff --git a/ironic/drivers/modules/irmc/common.py b/ironic/drivers/modules/irmc/common.py index c437f62e24..e808fff0b3 100644 --- a/ironic/drivers/modules/irmc/common.py +++ b/ironic/drivers/modules/irmc/common.py @@ -33,6 +33,14 @@ elcm = importutils.try_import('scciclient.irmc.elcm') scci_mod = importutils.try_import('scciclient') LOG = logging.getLogger(__name__) + + +# List of xxx_interface & implementation pair which uses SNMP internally +# and iRMC driver supports +INTERFACE_IMPL_LIST_WITH_SNMP = { + 'inspect_interface': {'irmc', }, + 'power_interface': {'irmc', }} + REQUIRED_PROPERTIES = { 'irmc_address': _("IP address or hostname of the iRMC. Required."), 'irmc_username': _("Username for the iRMC with administrator privileges. " @@ -239,6 +247,12 @@ def _parse_snmp_driver_info(node, info): "v2c": snmp.SNMP_V2C, "v3": snmp.SNMP_V3} + for int_name, impl_list in INTERFACE_IMPL_LIST_WITH_SNMP.items(): + if getattr(node, int_name) in impl_list: + break + else: + return snmp_info + if snmp_info['irmc_snmp_version'].lower() not in valid_versions: raise exception.InvalidParameterValue(_( "Value '%s' is not supported for 'irmc_snmp_version'.") % diff --git a/ironic/tests/unit/drivers/modules/irmc/test_common.py b/ironic/tests/unit/drivers/modules/irmc/test_common.py index 74b9dc35c4..e9373096cb 100644 --- a/ironic/tests/unit/drivers/modules/irmc/test_common.py +++ b/ironic/tests/unit/drivers/modules/irmc/test_common.py @@ -37,6 +37,8 @@ from ironic.tests.unit.objects import utils as obj_utils class BaseIRMCTest(db_base.DbTestCase): boot_interface = 'irmc-pxe' + inspect_interface = 'irmc' + power_interface = 'irmc' def setUp(self): super(BaseIRMCTest, self).setUp() @@ -51,6 +53,8 @@ class BaseIRMCTest(db_base.DbTestCase): self.context, driver='irmc', boot_interface=self.boot_interface, + inspect_interface=self.inspect_interface, + power_interface=self.power_interface, driver_info=self.info, uuid=uuidutils.generate_uuid()) @@ -75,6 +79,44 @@ class IRMCValidateParametersTestCase(BaseIRMCTest): self.assertFalse(info['irmc_snmp_security']) self.assertTrue(info['irmc_verify_ca']) + @mock.patch.object(utils, 'is_fips_enabled', + return_value=False, autospec=True) + def test_parse_snmp_driver_info_with_snmp(self, mock_check_fips): + test_list = [{'interfaces': [{'interface': 'inspect_interface', + 'impl': 'irmc'}, + {'interface': 'power_interface', + 'impl': 'irmc'}], + 'snmp': True}, + {'interfaces': [{'interface': 'inspect_interface', + 'impl': 'inspector'}, + {'interface': 'power_interface', + 'impl': 'irmc'}], + 'snmp': True}, + {'interfaces': [{'interface': 'inspect_interface', + 'impl': 'irmc'}, + {'interface': 'power_interface', + 'impl': 'ipmitool'}], + 'snmp': True}, + {'interfaces': [{'interface': 'inspect_interface', + 'impl': 'inspector'}, + {'interface': 'power_interface', + 'impl': 'ipmitool'}], + 'snmp': False} + ] + + for t_conf in test_list: + with self.subTest(t_conf=t_conf): + for int_conf in t_conf['interfaces']: + setattr(self.node, int_conf['interface'], int_conf['impl']) + irmc_common.parse_driver_info(self.node) + + if t_conf['snmp']: + mock_check_fips.assert_called() + else: + mock_check_fips.assert_not_called() + + mock_check_fips.reset_mock() + @mock.patch.object(irmc_common, 'scci_mod', spec_set=['__version__']) def test_parse_driver_info_snmpv3_support_auth(self, mock_scci_module): self.node.driver_info['irmc_snmp_version'] = 'v3' diff --git a/releasenotes/notes/fix-irmc-enforcing-snmpv3-with-fips-e45971d363925ec3.yaml b/releasenotes/notes/fix-irmc-enforcing-snmpv3-with-fips-e45971d363925ec3.yaml new file mode 100644 index 0000000000..8b6be9982b --- /dev/null +++ b/releasenotes/notes/fix-irmc-enforcing-snmpv3-with-fips-e45971d363925ec3.yaml @@ -0,0 +1,6 @@ +--- +fixes: + - | + Fixes bug of iRMC driver in parse_driver_info where, if FIPS is enabled, + SNMP version is always required to be version 3 even though iRMC driver's + xxx_interface doesn't use SNMP actually.