Merge "pass along physical_network to neutron from the baremetal port"

This commit is contained in:
Zuul
2025-11-21 23:28:05 +00:00
committed by Gerrit Code Review
5 changed files with 123 additions and 0 deletions
+4
View File
@@ -371,6 +371,10 @@ def add_ports_to_network(task, network_uuid, security_groups=None):
binding_profile['vtep-logical-switch'] = vtep_logical_switch
binding_profile['vtep-physical-switch'] = vtep_physical_switch
# Include physical_network if available
if ironic_port.physical_network:
binding_profile['physical_network'] = ironic_port.physical_network
update_port_attrs['binding:profile'] = binding_profile
if not ironic_port.pxe_enabled:
+5
View File
@@ -272,6 +272,11 @@ def plug_port_to_tenant_network(task, port_like_obj, client=None):
binding_profile = {'local_link_information': local_link_info}
if local_group_info:
binding_profile['local_group_information'] = local_group_info
# Include physical_network if available
if port_like_obj.physical_network:
binding_profile['physical_network'] = port_like_obj.physical_network
port_attrs['binding:profile'] = binding_profile
if client_id_opt:
+38
View File
@@ -329,6 +329,44 @@ class TestNeutronNetworkActions(db_base.DbTestCase):
self._test_add_ports_to_network(is_client_id=False,
security_groups=sg_ids)
@mock.patch.object(neutron, 'update_neutron_port', autospec=True)
def test_add_ports_to_network_with_physical_network(self, update_mock):
# Test that physical_network is included in binding:profile
self.node.network_interface = 'neutron'
self.node.save()
port = self.ports[0]
port.physical_network = 'physnet1'
port.save()
expected_create_attrs = {
'network_id': self.network_uuid,
'admin_state_up': True,
'binding:vnic_type': 'baremetal',
'device_id': self.node.uuid
}
expected_update_attrs = {
'device_owner': 'baremetal:none',
'binding:host_id': self.node.uuid,
'mac_address': port.address,
'binding:profile': {
'local_link_information': [port.local_link_connection],
'physical_network': 'physnet1'
}
}
self.client_mock.create_port.return_value = self.neutron_port
update_mock.return_value = self.neutron_port
expected = {port.uuid: self.neutron_port['id']}
with task_manager.acquire(self.context, self.node.uuid) as task:
ports = neutron.add_ports_to_network(task, self.network_uuid)
self.assertEqual(expected, ports)
self.client_mock.create_port.assert_called_once_with(
**expected_create_attrs)
update_mock.assert_called_once_with(
self.context, self.neutron_port['id'],
expected_update_attrs)
@mock.patch.object(neutron, 'update_neutron_port', autospec=True)
def test__add_ip_addresses_for_ipv6_stateful(self, mock_update):
subnet_id = uuidutils.generate_uuid()
@@ -492,6 +492,76 @@ class TestCommonFunctions(db_base.DbTestCase):
nclient, self.vif_id, 'ACTIVE', fail_on_binding_failure=True)
self.assertTrue(mock_update.called)
@mock.patch.object(neutron_common, 'update_neutron_port', autospec=True)
@mock.patch.object(neutron_common, 'wait_for_port_status', autospec=True)
@mock.patch.object(neutron_common, 'get_client', autospec=True)
def test_plug_port_to_tenant_network_with_physical_network(
self, mock_gc, wait_mock_status, mock_update):
# Test that physical_network is included in binding:profile for port
nclient = mock.MagicMock()
mock_gc.return_value = nclient
self.port.internal_info = {common.TENANT_VIF_KEY: self.vif_id}
self.port.physical_network = 'physnet1'
self.port.save()
expected_attrs = {
'binding:vnic_type': neutron_common.VNIC_BAREMETAL,
'binding:host_id': self.node.uuid,
'mac_address': self.port.address,
'binding:profile': {
'local_link_information': [self.port.local_link_connection],
'physical_network': 'physnet1'
}
}
with task_manager.acquire(self.context, self.node.id) as task:
common.plug_port_to_tenant_network(task, self.port)
mock_update.assert_called_once_with(
task.context, self.vif_id, expected_attrs)
@mock.patch.object(neutron_common, 'update_neutron_port', autospec=True)
@mock.patch.object(neutron_common, 'wait_for_port_status', autospec=True)
@mock.patch.object(neutron_common, 'get_client', autospec=True)
def test_plug_portgroup_to_tenant_network_with_physical_network(
self, mock_gc, wait_mock_status, mock_update):
# Test that physical_network is included in binding:profile for
# a portgroup
nclient = mock.MagicMock()
mock_gc.return_value = nclient
pg = obj_utils.create_test_portgroup(
self.context, node_id=self.node.id, address='00:54:00:cf:2d:01',
physical_network='physnet1')
port1 = obj_utils.create_test_port(
self.context, node_id=self.node.id, address='52:54:00:cf:2d:01',
portgroup_id=pg.id, uuid=uuidutils.generate_uuid())
port2 = obj_utils.create_test_port(
self.context, node_id=self.node.id, address='52:54:00:cf:2d:02',
portgroup_id=pg.id, uuid=uuidutils.generate_uuid())
pg.internal_info = {common.TENANT_VIF_KEY: self.vif_id}
pg.save()
expected_attrs = {
'binding:vnic_type': neutron_common.VNIC_BAREMETAL,
'binding:host_id': self.node.uuid,
'mac_address': pg.address,
'binding:profile': {
'local_link_information': [port1.local_link_connection,
port2.local_link_connection],
'local_group_information': {
'id': pg.uuid,
'name': pg.name,
'bond_mode': pg.mode,
'bond_properties': {}
},
'physical_network': 'physnet1'
}
}
with task_manager.acquire(self.context, self.node.id) as task:
common.plug_port_to_tenant_network(task, pg)
mock_update.assert_called_once_with(
task.context, self.vif_id, expected_attrs)
class TestVifPortIDMixin(db_base.DbTestCase):
@@ -0,0 +1,6 @@
---
features:
- |
When plugging a baremetal port in using the 'neutron' interface, send
the 'physical_network' value of the baremetal port to Neutron as part of the
binding_profile for the port.