Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand All @@ -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(
Expand All @@ -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(
Expand Down
10 changes: 8 additions & 2 deletions python/neutron-understack/neutron_understack/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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],
)


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
)
Expand All @@ -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",
Expand Down