diff options
5 files changed, 44 insertions, 5 deletions
diff --git a/ironic/drivers/modules/redfish/management.py b/ironic/drivers/modules/redfish/management.py index a669d09bc..8bd7058a5 100644 --- a/ironic/drivers/modules/redfish/management.py +++ b/ironic/drivers/modules/redfish/management.py @@ -1197,9 +1197,18 @@ class RedfishManagement(base.ManagementInterface): :raises: RedfishError on an error from the Sushy library :returns: A list of MAC addresses for the node """ + system = redfish_utils.get_system(task.node) try: - system = redfish_utils.get_system(task.node) return list(redfish_utils.get_enabled_macs(task, system)) + # NOTE(janders) we should handle MissingAttributeError separately + # from other SushyErrors - some servers (e.g. some Cisco UCSB and UCSX + # blades) are missing EthernetInterfaces attribute yet could be + # provisioned successfully if MAC information is provided manually AND + # this exception is caught and handled accordingly. + except sushy.exceptions.MissingAttributeError as exc: + LOG.warning('Cannot get MAC addresses for node %(node)s: %(exc)s', + {'node': task.node.uuid, 'exc': exc}) + # if the exception is not a MissingAttributeError, raise it except sushy.exceptions.SushyError as exc: msg = (_('Failed to get network interface information on node ' '%(node)s: %(exc)s') diff --git a/ironic/tests/unit/drivers/modules/network/test_common.py b/ironic/tests/unit/drivers/modules/network/test_common.py index 7b907ad22..e58fcaa20 100644 --- a/ironic/tests/unit/drivers/modules/network/test_common.py +++ b/ironic/tests/unit/drivers/modules/network/test_common.py @@ -1065,10 +1065,14 @@ class TestNeutronVifPortIDMixin(db_base.DbTestCase): expected_dhcp_opts = [{'opt_name': '61', 'opt_value': 'fake2'}] self.port.extra = expected_extra self.port.internal_info = expected_ii + what_changed_mock = mock.Mock() + what_changed_mock.return_value = ['extra', 'internal_info'] + self.port.obj_what_changed = what_changed_mock with task_manager.acquire(self.context, self.node.id) as task: self.interface.port_changed(task, self.port) dhcp_update_mock.assert_called_once_with( mock.ANY, 'fake-id', expected_dhcp_opts, context=task.context) + self.assertEqual(2, what_changed_mock.call_count) @mock.patch('ironic.dhcp.neutron.NeutronDHCPApi.update_port_dhcp_opts', autospec=True) @@ -1087,14 +1091,16 @@ class TestNeutronVifPortIDMixin(db_base.DbTestCase): def test_port_changed_client_id_fail(self, dhcp_update_mock): self.port.internal_info = {'tenant_vif_port_id': 'fake-id'} self.port.extra = {'client-id': 'fake3'} - # NOTE(TheJulia): Does not save, because it attempts to figure - # out what has changed as part of the test. + what_changed_mock = mock.Mock() + what_changed_mock.return_value = ['extra'] + self.port.obj_what_changed = what_changed_mock dhcp_update_mock.side_effect = ( exception.FailedToUpdateDHCPOptOnPort(port_id=self.port.uuid)) with task_manager.acquire(self.context, self.node.id) as task: self.assertRaises(exception.FailedToUpdateDHCPOptOnPort, self.interface.port_changed, task, self.port) + self.assertEqual(2, what_changed_mock.call_count) @mock.patch('ironic.dhcp.neutron.NeutronDHCPApi.update_port_dhcp_opts', autospec=True) diff --git a/ironic/tests/unit/drivers/modules/redfish/test_management.py b/ironic/tests/unit/drivers/modules/redfish/test_management.py index f8c82949a..1d752d909 100644 --- a/ironic/tests/unit/drivers/modules/redfish/test_management.py +++ b/ironic/tests/unit/drivers/modules/redfish/test_management.py @@ -1598,3 +1598,13 @@ class RedfishManagementTestCase(db_base.DbTestCase): shared=True) as task: self.assertEqual([], task.driver.management.get_mac_addresses(task)) + + @mock.patch.object(redfish_utils, 'get_enabled_macs', autospec=True) + @mock.patch.object(redfish_utils, 'get_system', autospec=True) + def test_get_mac_addresses_missing_attr(self, mock_get_system, + mock_get_enabled_macs): + redfish_utils.get_enabled_macs.side_effect = (sushy.exceptions. + MissingAttributeError) + with task_manager.acquire(self.context, self.node.uuid, + shared=True) as task: + self.assertIsNone(task.driver.management.get_mac_addresses(task)) diff --git a/releasenotes/notes/handle-missing-ethernetinterfaces-attr-7e52f7259fe66762.yaml b/releasenotes/notes/handle-missing-ethernetinterfaces-attr-7e52f7259fe66762.yaml new file mode 100644 index 000000000..225238506 --- /dev/null +++ b/releasenotes/notes/handle-missing-ethernetinterfaces-attr-7e52f7259fe66762.yaml @@ -0,0 +1,9 @@ +--- +fixes: + - | + Fixes the bug where provisioning a Redfish managed node fails if the BMC + doesn't support EthernetInterfaces attribute, even if MAC address + information is provided manually. This is done by handling of + MissingAttributeError sushy exception in get_mac_addresses() method. + This fix is needed to successfully provision machines such as Cisco UCSB + and UCSX. diff --git a/zuul.d/project.yaml b/zuul.d/project.yaml index 8fbfbb929..cf3a696db 100644 --- a/zuul.d/project.yaml +++ b/zuul.d/project.yaml @@ -13,7 +13,10 @@ - ironic-cross-sushy: voting: false - ironic-tempest-functional-python3 - - ironic-tempest-functional-rbac-scope-enforced + # NOTE(rpittau) moving to non-voting until we fix the tests + # see also https://review.opendev.org/c/openstack/ironic-tempest-plugin/+/882312 + - ironic-tempest-functional-rbac-scope-enforced: + voting: false - ironic-grenade - ironic-standalone - ironic-standalone-redfish @@ -63,7 +66,9 @@ jobs: - ironic-tox-unit-with-driver-libs - ironic-tempest-functional-python3 - - ironic-tempest-functional-rbac-scope-enforced + # NOTE(rpittau) disabled until we fix the tests + # see also https://review.opendev.org/c/openstack/ironic-tempest-plugin/+/882312 + #- ironic-tempest-functional-rbac-scope-enforced - ironic-grenade - ironic-standalone - ironic-standalone-redfish |