diff --git a/python/neutron-understack/neutron_understack/ironic.py b/python/neutron-understack/neutron_understack/ironic.py index 14b67547c..ebed76a6b 100644 --- a/python/neutron-understack/neutron_understack/ironic.py +++ b/python/neutron-understack/neutron_understack/ironic.py @@ -21,12 +21,14 @@ def _get_ironic_client(self) -> BaremetalService: session=session, oslo_conf=cfg.CONF, connect_retries=cfg.CONF.http_retries ).baremetal - def baremetal_port_by_mac(self, mac_addr: str) -> BaremetalPort | None: + def baremetal_port_physical_network(self, local_link_info: dict) -> str | None: + port = self._port_by_local_link(local_link_info) + return port.physical_network if port else None + + def _port_by_local_link(self, local_link_info: dict) -> BaremetalPort | None: try: - return next(self.irclient.ports(details=True, address=mac_addr)) + return next( + self.irclient.ports(details=True, local_link_connection=local_link_info) + ) except StopIteration: return None - - def baremetal_port_physical_network(self, mac_addr: str) -> str | None: - port = self.baremetal_port_by_mac(mac_addr) - return port.physical_network if port else None diff --git a/python/neutron-understack/neutron_understack/neutron_understack_mech.py b/python/neutron-understack/neutron_understack/neutron_understack_mech.py index 4f8fb86a1..aca7bdc07 100644 --- a/python/neutron-understack/neutron_understack/neutron_understack_mech.py +++ b/python/neutron-understack/neutron_understack/neutron_understack_mech.py @@ -258,8 +258,16 @@ def _update_port_baremetal(self, context: PortContext) -> None: original_vif_other = context.original_vif_type == portbindings.VIF_TYPE_OTHER current_vif_other = context.vif_type == portbindings.VIF_TYPE_OTHER + if current_vif_unbound and original_vif_other: + local_link_info = utils.local_link_from_binding_profile( + context.original[portbindings.PROFILE] + ) + else: + local_link_info = utils.local_link_from_binding_profile( + context.current[portbindings.PROFILE] + ) vlan_group_name = self.ironic_client.baremetal_port_physical_network( - context.current["mac_address"] + local_link_info ) if current_vif_unbound and original_vif_other: @@ -323,8 +331,11 @@ def _delete_port_baremetal(self, context: PortContext) -> None: # Only clean up provisioning ports. Ports with tenant networks are cleaned # up in _tenant_network_port_cleanup + local_link_info = utils.local_link_from_binding_profile( + context.current[portbindings.PROFILE] + ) vlan_group_name = self.ironic_client.baremetal_port_physical_network( - context.current["mac_address"] + local_link_info ) if vlan_group_name and is_provisioning_network(context.current["network_id"]): @@ -383,8 +394,11 @@ def _bind_port_segment(self, context: PortContext, segment): ) mac_address = context.current["mac_address"] + local_link_info = utils.local_link_from_binding_profile( + context.current[portbindings.PROFILE] + ) vlan_group_name = self.ironic_client.baremetal_port_physical_network( - mac_address + local_link_info ) if not vlan_group_name: diff --git a/python/neutron-understack/neutron_understack/tests/conftest.py b/python/neutron-understack/neutron_understack/tests/conftest.py index 6d6058b1c..6df1f1da3 100644 --- a/python/neutron-understack/neutron_understack/tests/conftest.py +++ b/python/neutron-understack/neutron_understack/tests/conftest.py @@ -219,8 +219,8 @@ def subport_model(vlan_num) -> SubPortModel: @pytest.fixture -def port_model(mac_address) -> PortModel: - return PortModel(mac_address=mac_address) +def port_model(mac_address, port_id) -> PortModel: + return PortModel(mac_address=mac_address, id=str(port_id)) @pytest.fixture diff --git a/python/neutron-understack/neutron_understack/trunk.py b/python/neutron-understack/neutron_understack/trunk.py index f949ff7e0..e3f5aa773 100644 --- a/python/neutron-understack/neutron_understack/trunk.py +++ b/python/neutron-understack/neutron_understack/trunk.py @@ -205,8 +205,9 @@ def _add_subports_networks_to_parent_port_switchport( binding_profile, self.nb ) + local_link_info = utils.local_link_from_binding_profile(binding_profile) vlan_group_name = self.ironic_client.baremetal_port_physical_network( - parent_port.mac_address + local_link_info ) allowed_vlan_ids = self._handle_segment_allocation( subports, vlan_group_name, binding_host @@ -237,8 +238,9 @@ def _clean_parent_port_switchport_config( return binding_profile = parent_port_obj.bindings[0].profile binding_host = parent_port_obj.bindings[0].host + local_link_info = utils.local_link_from_binding_profile(binding_profile) vlan_group_name = self.ironic_client.baremetal_port_physical_network( - parent_port_obj.mac_address + local_link_info ) self._handle_subports_removal( binding_profile=binding_profile, @@ -308,8 +310,10 @@ def subports_added_post(self, resource, event, trunk_plugin, payload): parent_port = utils.fetch_port_object(trunk.port_id) if utils.parent_port_is_bound(parent_port): + binding_profile = parent_port.bindings[0].profile + local_link_info = utils.local_link_from_binding_profile(binding_profile) vlan_group_name = self.ironic_client.baremetal_port_physical_network( - parent_port.mac_address + local_link_info ) LOG.debug("subports_added_post found vlan_group_name=%s", vlan_group_name) self._trigger_undersync(vlan_group_name) diff --git a/python/neutron-understack/neutron_understack/utils.py b/python/neutron-understack/neutron_understack/utils.py index 370fddfd2..48eb9deec 100644 --- a/python/neutron-understack/neutron_understack/utils.py +++ b/python/neutron-understack/neutron_understack/utils.py @@ -195,6 +195,10 @@ def is_dynamic_network_segment(segment_id: str) -> bool: return segment.is_dynamic +def local_link_from_binding_profile(binding_profile: dict) -> dict | None: + return binding_profile.get("local_link_information", [None])[0] + + def fetch_connected_interface_uuid(binding_profile: dict, nautobot: Nautobot) -> str: """Fetches the connected interface UUID from the port's binding profile.