From 55e3848795073aae82db862d73d00a6c9d0de147 Mon Sep 17 00:00:00 2001 From: haseeb <184114777+haseebsyed12@users.noreply.github.com> Date: Tue, 25 Mar 2025 01:15:41 +0530 Subject: [PATCH 1/2] PUC-765: use segmentation_id generated by neutron as ucvni_id in nautobot --- .../neutron_understack/nautobot.py | 13 +++--- .../neutron_understack_mech.py | 1 + .../neutron_understack/tests/conftest.py | 2 +- .../neutron_understack/tests/test_nautobot.py | 43 ++++++++----------- .../tests/test_neutron_understack_mech.py | 1 + 5 files changed, 27 insertions(+), 33 deletions(-) diff --git a/python/neutron-understack/neutron_understack/nautobot.py b/python/neutron-understack/neutron_understack/nautobot.py index cb4adec4c..5aec287c4 100644 --- a/python/neutron-understack/neutron_understack/nautobot.py +++ b/python/neutron-understack/neutron_understack/nautobot.py @@ -128,7 +128,7 @@ def ucvni_create( project_id: str, ucvni_group: str, network_name: str, - segment_id: int | None = None, + segmentation_id: int, ) -> dict: payload = { "id": network_id, @@ -136,14 +136,13 @@ def ucvni_create( "name": network_name, "ucvni_group": ucvni_group, "status": {"name": "Active"}, + "ucvni_id": segmentation_id, } - if segment_id: - payload["ucvni_id"] = segment_id - payload["ucvni_type"] = "INFRA" - - url = "/api/plugins/undercloud-vni/ucvnis/" - return self.make_api_request("POST", url, payload) + ucvni: pynautobot.core.response.Record = ( + self.api.plugins.undercloud_vni.ucvnis.create(payload) + ) + return dict(ucvni) def ucvni_delete(self, network_id): url = f"/api/plugins/undercloud-vni/ucvnis/{network_id}/" diff --git a/python/neutron-understack/neutron_understack/neutron_understack_mech.py b/python/neutron-understack/neutron_understack/neutron_understack_mech.py index b2848705a..b16759c4d 100644 --- a/python/neutron-understack/neutron_understack/neutron_understack_mech.py +++ b/python/neutron-understack/neutron_understack/neutron_understack_mech.py @@ -80,6 +80,7 @@ def create_network_postcommit(self, context): project_id=project_id, ucvni_group=ucvni_group, network_name=network_name, + segmentation_id=segmentation_id, ) LOG.info( "network %(net_id)s has been added on ucvni_group %(ucvni_group)s, " diff --git a/python/neutron-understack/neutron_understack/tests/conftest.py b/python/neutron-understack/neutron_understack/tests/conftest.py index 682ab0a99..37168b3f7 100644 --- a/python/neutron-understack/neutron_understack/tests/conftest.py +++ b/python/neutron-understack/neutron_understack/tests/conftest.py @@ -111,7 +111,7 @@ def network_dict(ml2_plugin, network, network_segment) -> dict: @pytest.fixture def network_segment(network) -> NetworkSegment: - return NetworkSegment(network_type="vxlan", network=network) + return NetworkSegment(network_type="vxlan", network=network, segmentation_id=100) @pytest.fixture diff --git a/python/neutron-understack/neutron_understack/tests/test_nautobot.py b/python/neutron-understack/neutron_understack/tests/test_nautobot.py index 2f77a05e1..af74fde4c 100644 --- a/python/neutron-understack/neutron_understack/tests/test_nautobot.py +++ b/python/neutron-understack/neutron_understack/tests/test_nautobot.py @@ -1,4 +1,3 @@ -import uuid from unittest.mock import MagicMock from unittest.mock import patch @@ -11,13 +10,17 @@ @pytest.fixture def mock_pynautobot_api(): with patch("neutron_understack.nautobot.pynautobot.api") as mock_api: - mock_ipam = MagicMock() - mock_ipam.vlans.delete = MagicMock() - mock_ipam.vlans.create = MagicMock() + mock_api_instance = MagicMock() - mock_api.return_value.ipam = mock_ipam + # Setup mock structure + mock_api_instance.ipam.vlans.delete = MagicMock() + mock_api_instance.ipam.vlans.create = MagicMock() - yield mock_api, mock_ipam + mock_api_instance.plugins.undercloud_vni.ucvnis.create = MagicMock() + + mock_api.return_value = mock_api_instance + + yield mock_api, mock_api_instance @pytest.fixture @@ -26,16 +29,16 @@ def nautobot(mock_pynautobot_api): def test_delete_vlan(nautobot, mock_pynautobot_api): - _, mock_ipam = mock_pynautobot_api + _, mock_api_instance = mock_pynautobot_api vlan_id = "123" nautobot.delete_vlan(vlan_id) - mock_ipam.vlans.delete.assert_called_once_with([vlan_id]) + mock_api_instance.ipam.vlans.delete.assert_called_once_with([vlan_id]) def test_create_vlan_and_associate_vlan_to_ucvni(nautobot, mock_pynautobot_api): - _, mock_ipam = mock_pynautobot_api + _, mock_api_instance = mock_pynautobot_api payload = VlanPayload( id="vlan-123", @@ -57,27 +60,17 @@ def test_create_vlan_and_associate_vlan_to_ucvni(nautobot, mock_pynautobot_api): nautobot.create_vlan_and_associate_vlan_to_ucvni(payload) - mock_ipam.vlans.create.assert_called_once_with(expected_payload_dict) + mock_api_instance.ipam.vlans.create.assert_called_once_with(expected_payload_dict) -def test_ucvni_create( - mocker, - network_id, - ucvni_create_response, - nautobot, -): - mocker.patch.object( - nautobot, "make_api_request", return_value=ucvni_create_response - ) +def test_ucvni_create(network_id, ucvni_create_response, nautobot, mock_pynautobot_api): + _, mock_ucvni = mock_pynautobot_api project_id = "d3c2c85bdbf24ff5843f323524b63768" - response = nautobot.ucvni_create( + nautobot.ucvni_create( network_id=network_id.hex, project_id=project_id, ucvni_group="f6843091-845d-4195-8132-960125e05f7b", network_name="PROV-NET500", + segmentation_id=2010, ) - - assert "tenant" in response[0] - tenant_obj = response[0].get("tenant", {}) - - assert tenant_obj.get("id") == str(uuid.UUID(project_id)) + mock_ucvni.plugins.undercloud_vni.ucvnis.create.assert_called_once() 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 c7f1af4fd..f4f51920e 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 @@ -202,6 +202,7 @@ def test_vxlan_network( network_id=str(network_id), project_id=str(project_id), ucvni_group=str(ucvni_group_id), + segmentation_id=network_context.current["provider:segmentation_id"], network_name=network_context.current["name"], ) understack_driver._create_nautobot_namespace.assert_called_once_with( From d03ce63d51033e6025ede4162c57de65a0627840 Mon Sep 17 00:00:00 2001 From: haseeb <184114777+haseebsyed12@users.noreply.github.com> Date: Tue, 25 Mar 2025 17:40:47 +0530 Subject: [PATCH 2/2] Since we want to use only VXLAN type networks, removing code related to other network types --- .../neutron_understack_mech.py | 37 ++----------------- 1 file changed, 4 insertions(+), 33 deletions(-) diff --git a/python/neutron-understack/neutron_understack/neutron_understack_mech.py b/python/neutron-understack/neutron_understack/neutron_understack_mech.py index b16759c4d..1f7a7750a 100644 --- a/python/neutron-understack/neutron_understack/neutron_understack_mech.py +++ b/python/neutron-understack/neutron_understack/neutron_understack_mech.py @@ -95,20 +95,6 @@ def create_network_postcommit(self, context): ) self._create_nautobot_namespace(network_id, external) - if provider_type != p_const.TYPE_VLAN: - return - - vlan_group_id_and_vlan_tag = self.nb.prep_switch_interface( - connected_interface_id=conf.network_node_switchport_uuid, - ucvni_uuid=network_id, - modify_native_vlan=False, - vlan_tag=int(segmentation_id), - ) - self.undersync.sync_devices( - vlan_group_uuids=str(vlan_group_id_and_vlan_tag["vlan_group_id"]), - dry_run=cfg.CONF.ml2_understack.undersync_dry_run, - ) - def update_network_precommit(self, context): pass @@ -128,21 +114,10 @@ def delete_network_postcommit(self, context): conf = cfg.CONF.ml2_understack ucvni_group = conf.ucvni_group - if provider_type == p_const.TYPE_VLAN: - vlan_group_id = self.nb.detach_port( - connected_interface_id=conf.network_node_switchport_uuid, - ucvni_uuid=network_id, - ) - self.nb.ucvni_delete(network_id) - self.undersync.sync_devices( - vlan_group_uuids=str(vlan_group_id), - dry_run=cfg.CONF.ml2_understack.undersync_dry_run, - ) - elif provider_type == p_const.TYPE_VXLAN: - self.nb.ucvni_delete(network_id) - else: + if provider_type != p_const.TYPE_VXLAN: return + self.nb.ucvni_delete(network_id) LOG.info( "network %(net_id)s has been deleted from ucvni_group %(ucvni_group)s, " "physnet %(physnet)s", @@ -296,19 +271,15 @@ def delete_port_postcommit(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 = utils.fetch_connected_interface_uuid( context.current["binding:profile"], LOG ) 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 + network_id, connected_interface_uuid, None ) self.undersync.sync_devices(