From 71edcc3758b022643668be145e95031b58db56f0 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Fri, 2 Dec 2022 13:07:40 +0000 Subject: [PATCH] Use SDK for remaining network operations We would like nova not to use ironicclient, but instead to invoke the ironic API directly through an openstacksdk connection. In this change, we migrate the remaining network-related operations. Change-Id: Iebf3f4352083755c9e93b10a87ca58e90ed35500 Signed-off-by: Stephen Finucane --- nova/tests/unit/virt/ironic/test_driver.py | 57 ++++++++++---------- nova/virt/ironic/driver.py | 60 ++++++++++++++-------- 2 files changed, 70 insertions(+), 47 deletions(-) diff --git a/nova/tests/unit/virt/ironic/test_driver.py b/nova/tests/unit/virt/ironic/test_driver.py index e0a9beb1da..a8da85a0b2 100644 --- a/nova/tests/unit/virt/ironic/test_driver.py +++ b/nova/tests/unit/virt/ironic/test_driver.py @@ -2296,8 +2296,7 @@ class IronicDriverTestCase(test.NoDBTestCase): host_id = self.driver.network_binding_host_id(self.ctx, instance) self.assertIsNone(host_id) - @mock.patch.object(FAKE_CLIENT, 'node') - def test_get_volume_connector(self, mock_node): + def test_get_volume_connector(self): node_uuid = uuids.node_uuid node_props = {'cpu_arch': 'x86_64'} node = ironic_utils.get_test_node(uuid=node_uuid, @@ -2327,23 +2326,25 @@ class IronicDriverTestCase(test.NoDBTestCase): 'os_type': 'baremetal', 'platform': 'x86_64'} - mock_node.get.return_value = node - mock_node.list_volume_connectors.return_value = connectors + self.mock_conn.get_node.return_value = node + self.mock_conn.volume_connectors.return_value = connectors instance = fake_instance.fake_instance_obj(self.ctx, node=node_uuid) props = self.driver.get_volume_connector(instance) self.assertEqual(expected_props, props) - mock_node.get.assert_called_once_with(node_uuid) - mock_node.list_volume_connectors.assert_called_once_with( - node_uuid, detail=True) + self.mock_conn.get_node.assert_called_once_with(node_uuid) + self.mock_conn.volume_connectors.assert_called_once_with( + node=node_uuid, details=True, + ) @mock.patch.object(objects.instance.Instance, 'get_network_info') - @mock.patch.object(FAKE_CLIENT, 'node') - @mock.patch.object(FAKE_CLIENT.port, 'list') - @mock.patch.object(FAKE_CLIENT.portgroup, 'list') def _test_get_volume_connector_no_ip( - self, mac_specified, mock_pgroup, mock_port, mock_node, - mock_nw_info, portgroup_exist=False, no_fixed_ip=False): + self, + mac_specified, + mock_nw_info, + portgroup_exist=False, + no_fixed_ip=False, + ): node_uuid = uuids.node_uuid node_props = {'cpu_arch': 'x86_64'} node = ironic_utils.get_test_node(uuid=node_uuid, @@ -2368,13 +2369,13 @@ class IronicDriverTestCase(test.NoDBTestCase): 'os_type': 'baremetal', 'platform': 'x86_64'} - mock_node.get.return_value = node - mock_node.list_volume_connectors.return_value = connectors + self.mock_conn.get_node.return_value = node + self.mock_conn.volume_connectors.return_value = connectors instance = fake_instance.fake_instance_obj(self.ctx, node=node_uuid) port = ironic_utils.get_test_port( node_uuid=node_uuid, address='11:22:33:44:55:66', internal_info={'tenant_vif_port_id': vif['id']}) - mock_port.return_value = [port] + self.mock_conn.ports.return_value = [port] if no_fixed_ip: mock_nw_info.return_value = [] expected_props.pop('ip') @@ -2385,26 +2386,28 @@ class IronicDriverTestCase(test.NoDBTestCase): portgroup = ironic_utils.get_test_portgroup( node_uuid=node_uuid, address='11:22:33:44:55:66', extra={'vif_port_id': vif['id']}) - mock_pgroup.return_value = [portgroup] + self.mock_conn.port_groups.return_value = [portgroup] else: - mock_pgroup.return_value = [] + self.mock_conn.port_groups.return_value = [] props = self.driver.get_volume_connector(instance) self.assertEqual(expected_props, props) - mock_node.get.assert_called_once_with(node_uuid) - mock_node.list_volume_connectors.assert_called_once_with( - node_uuid, detail=True) + self.mock_conn.get_node.assert_called_once_with(node_uuid) + self.mock_conn.volume_connectors.assert_called_once_with( + node=node_uuid, details=True, + ) if mac_specified: - mock_pgroup.assert_called_once_with( - node=node_uuid, address='11:22:33:44:55:66', detail=True) + self.mock_conn.port_groups.assert_called_once_with( + node=node_uuid, address='11:22:33:44:55:66', details=True) if not portgroup_exist: - mock_port.assert_called_once_with( - node=node_uuid, address='11:22:33:44:55:66', detail=True) + self.mock_conn.ports.assert_called_once_with( + node=node_uuid, address='11:22:33:44:55:66', details=True, + ) else: - mock_port.assert_not_called() + self.mock_conn.ports.assert_not_called() else: - mock_pgroup.assert_not_called() - mock_port.assert_not_called() + self.mock_conn.port_groups.assert_not_called() + self.mock_conn.ports.assert_not_called() def test_get_volume_connector_no_ip_with_mac(self): self._test_get_volume_connector_no_ip(True) diff --git a/nova/virt/ironic/driver.py b/nova/virt/ironic/driver.py index 1046649a46..a31eba8e87 100644 --- a/nova/virt/ironic/driver.py +++ b/nova/virt/ironic/driver.py @@ -2003,10 +2003,12 @@ class IronicDriver(virt_driver.ComputeDriver): :param instance: nova instance :return: A connector information dictionary """ - node = self.ironicclient.call("node.get", instance.node) + node = self.ironic_connection.get_node(instance.node) properties = self._parse_node_properties(node) - connectors = self.ironicclient.call("node.list_volume_connectors", - instance.node, detail=True) + connectors = self.ironic_connection.volume_connectors( + details=True, + node=instance.node, + ) values = {} for conn in connectors: values.setdefault(conn.type, []).append(conn.connector_id) @@ -2071,24 +2073,42 @@ class IronicDriver(virt_driver.ComputeDriver): :param instance: nova instance, used for logging. :return: A UUID of a VIF assigned to one of the MAC addresses. """ + def _get_vif(ports): + for p in ports: + vif_id = (p.internal_info.get('tenant_vif_port_id') or + p.extra.get('vif_port_id')) + if vif_id: + LOG.debug( + 'VIF %(vif)s for volume connector is ' + 'retrieved with MAC %(mac)s of node %(node)s', + { + 'vif': vif_id, + 'mac': mac, + 'node': node.uuid, + }, + instance=instance, + ) + return vif_id + for mac in macs: - for method in ['portgroup.list', 'port.list']: - ports = self.ironicclient.call(method, - node=node.uuid, - address=mac, - detail=True) - for p in ports: - vif_id = (p.internal_info.get('tenant_vif_port_id') or - p.extra.get('vif_port_id')) - if vif_id: - LOG.debug('VIF %(vif)s for volume connector is ' - 'retrieved with MAC %(mac)s of node ' - '%(node)s', - {'vif': vif_id, - 'mac': mac, - 'node': node.uuid}, - instance=instance) - return vif_id + port_groups = self.ironic_connection.port_groups( + node=node.uuid, + address=mac, + details=True, + ) + vif_id = _get_vif(port_groups) + if vif_id: + return vif_id + + ports = self.ironic_connection.ports( + node=node.uuid, + address=mac, + details=True, + ) + vif_id = _get_vif(ports) + if vif_id: + return vif_id + return None def _can_send_version(self, min_version=None, max_version=None):