diff --git a/python/neutron-understack/neutron_understack/neutron_understack_mech.py b/python/neutron-understack/neutron_understack/neutron_understack_mech.py index 2adf0d4fb..789ed37f8 100644 --- a/python/neutron-understack/neutron_understack/neutron_understack_mech.py +++ b/python/neutron-understack/neutron_understack/neutron_understack_mech.py @@ -2,6 +2,7 @@ from uuid import UUID import neutron_lib.api.definitions.portbindings as portbindings +from neutron.plugins.ml2.driver_context import PortContext from neutron_lib import constants as p_const from neutron_lib.plugins.ml2 import api from neutron_lib.plugins.ml2.api import MechanismDriver @@ -223,31 +224,6 @@ def _configure_trunk( def update_port_postcommit(self, context): self._delete_tenant_port_on_unbound(context) - vif_type = context.current["binding:vif_type"] - - if vif_type != portbindings.VIF_TYPE_OTHER: - return - - trunk_details = context.current.get("trunk_details", {}) - network_id = context.current["network_id"] - network_type = context.network.current.get("provider:network_type") - connected_interface_uuid = self.fetch_connected_interface_uuid(context.current) - - if trunk_details: - self._configure_trunk(trunk_details, connected_interface_uuid) - if network_type == p_const.TYPE_VLAN: - vlan_tag = int(context.network.current.get("provider:segmentation_id")) - else: - vlan_tag = None - nb_vlan_group_id = self.update_nautobot( - network_id, connected_interface_uuid, vlan_tag - ) - - self.undersync.sync_devices( - vlan_group_uuids=str(nb_vlan_group_id), - dry_run=cfg.CONF.ml2_understack.undersync_dry_run, - ) - def delete_port_precommit(self, context): pass @@ -273,7 +249,28 @@ def delete_port_postcommit(self, context): dry_run=cfg.CONF.ml2_understack.undersync_dry_run, ) - def bind_port(self, context): + def _configure_switchport_on_bind(self, context: PortContext) -> None: + trunk_details = context.current.get("trunk_details", {}) + network_id = context.current["network_id"] + network_type = context.network.current.get("provider:network_type") + connected_interface_uuid = self.fetch_connected_interface_uuid(context.current) + + if trunk_details: + self._configure_trunk(trunk_details, connected_interface_uuid) + if network_type == p_const.TYPE_VLAN: + vlan_tag = int(context.network.current.get("provider:segmentation_id")) + else: + vlan_tag = None + nb_vlan_group_id = self.update_nautobot( + network_id, connected_interface_uuid, vlan_tag + ) + + self.undersync.sync_devices( + vlan_group_uuids=str(nb_vlan_group_id), + dry_run=cfg.CONF.ml2_understack.undersync_dry_run, + ) + + def bind_port(self, context: PortContext) -> None: for segment in context.network.network_segments: if self.check_segment(segment): context.set_binding( @@ -283,6 +280,7 @@ def bind_port(self, context): status=p_const.PORT_STATUS_ACTIVE, ) LOG.debug("Bound segment: %s", segment) + self._configure_switchport_on_bind(context) return else: LOG.debug( diff --git a/python/neutron-understack/neutron_understack/tests/conftest.py b/python/neutron-understack/neutron_understack/tests/conftest.py index 31a2d6dfd..ce6644e7d 100644 --- a/python/neutron-understack/neutron_understack/tests/conftest.py +++ b/python/neutron-understack/neutron_understack/tests/conftest.py @@ -3,6 +3,7 @@ import uuid import pytest +from neutron.db.models.segment import NetworkSegment from neutron.db.models_v2 import Network from neutron.db.models_v2 import Port from neutron.db.models_v2 import Subnet @@ -73,12 +74,17 @@ def network_dict(ml2_plugin) -> dict: @pytest.fixture -def network_context(ml2_plugin, network_dict) -> NetworkContext: +def network_segment() -> NetworkSegment: + return NetworkSegment(network_type="vxlan") + + +@pytest.fixture +def network_context(ml2_plugin, network_dict, network_segment) -> NetworkContext: return NetworkContext( ml2_plugin, "plugin_context", network_dict, - segments=[], + segments=[network_segment], ) diff --git a/python/neutron-understack/neutron_understack/tests/test_neutron_understack_mech.py b/python/neutron-understack/neutron_understack/tests/test_neutron_understack_mech.py index 7c2ac2156..01c7b7a09 100644 --- a/python/neutron-understack/neutron_understack/tests/test_neutron_understack_mech.py +++ b/python/neutron-understack/neutron_understack/tests/test_neutron_understack_mech.py @@ -45,19 +45,7 @@ def test_for_provisioning_network(self, mocker, understack_driver, vlan_group_id understack_driver.nb.fetch_vlan_group_uuid.assert_called_once_with("444") -@pytest.mark.usefixtures("update_nautobot_patch") class TestUpdatePortPostcommit: - def test_vif_type_other_no_trunk(self, mocker, port_context, understack_driver): - mocker.patch.object(understack_driver, "_configure_trunk") - mocker.patch.object(understack_driver, "fetch_connected_interface_uuid") - - understack_driver.update_port_postcommit(port_context) - - understack_driver.update_nautobot.assert_called_once() - understack_driver._configure_trunk.assert_not_called() - understack_driver.fetch_connected_interface_uuid.assert_called_once() - understack_driver.undersync.sync_devices.assert_called_once() - @pytest.mark.parametrize( "port_dict", [{"vif_type": portbindings.VIF_TYPE_UNBOUND}], indirect=True ) @@ -70,13 +58,27 @@ def test_vif_type_unbound(self, mocker, understack_driver, port_context): spy_delete_tenant_port.assert_called_once() assert result is None + +@pytest.mark.usefixtures("update_nautobot_patch") +class TestBindPort: + def test_with_no_trunk(self, mocker, port_context, understack_driver): + mocker.patch.object(understack_driver, "_configure_trunk") + mocker.patch.object(understack_driver, "fetch_connected_interface_uuid") + + understack_driver.bind_port(port_context) + + understack_driver.update_nautobot.assert_called_once() + understack_driver._configure_trunk.assert_not_called() + understack_driver.fetch_connected_interface_uuid.assert_called_once() + understack_driver.undersync.sync_devices.assert_called_once() + @pytest.mark.parametrize("port_dict", [{"trunk": True}], indirect=True) def test_with_trunk_details(self, mocker, understack_driver, port_context, port_id): mocker.patch( "neutron_understack.utils.fetch_subport_network_id", return_value="112233" ) - understack_driver.update_port_postcommit(port_context) + understack_driver.bind_port(port_context) understack_driver.nb.prep_switch_interface.assert_called_once_with( connected_interface_id=str(port_id), ucvni_uuid="112233",