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
4 changes: 3 additions & 1 deletion python/neutron-understack/neutron_understack/nautobot.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,12 +125,14 @@ def make_api_request(
def ucvni_create(
self,
network_id: str,
project_id: str,
ucvni_group: str,
network_name: str,
segment_id: int | None = None,
):
) -> dict:
payload = {
"id": network_id,
"tenant": project_id,
"name": network_name,
"ucvni_group": ucvni_group,
"status": {"name": "Active"},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ def create_network_postcommit(self, context):
network = context.current
network_id = network["id"]
network_name = network["name"]
project_id = network["project_id"]
external = network["router:external"]
provider_type = network.get("provider:network_type")
segmentation_id = network.get("provider:segmentation_id")
Expand All @@ -74,11 +75,22 @@ def create_network_postcommit(self, context):
if provider_type not in [p_const.TYPE_VLAN, p_const.TYPE_VXLAN]:
return
ucvni_group = conf.ucvni_group
self.nb.ucvni_create(network_id, ucvni_group, network_name)
ucvni_response = self.nb.ucvni_create(
network_id=network_id,
project_id=project_id,
ucvni_group=ucvni_group,
network_name=network_name,
)
LOG.info(
"network %(net_id)s has been added on ucvni_group %(ucvni_group)s, "
"physnet %(physnet)s",
{"net_id": network_id, "ucvni_group": ucvni_group, "physnet": physnet},
{
"net_id": network_id,
"nautobot_ucvni_uuid": ucvni_response.get("id"),
"nautobot_tenant_id": ucvni_response.get("tenant", {}).get("id"),
"ucvni_group": ucvni_group,
"physnet": physnet,
},
)
self._create_nautobot_namespace(network_id, external)

Expand Down
64 changes: 60 additions & 4 deletions python/neutron-understack/neutron_understack/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,17 @@
from neutron_understack.nautobot import Nautobot
from neutron_understack.neutron_understack_mech import UnderstackDriver
from neutron_understack.tests.helpers import Ml2PluginNoInit
from neutron_understack.tests.helpers import extend_network_dict
from neutron_understack.tests.helpers import extend_port_dict_with_trunk
from neutron_understack.trunk import UnderStackTrunkDriver
from neutron_understack.undersync import Undersync


@pytest.fixture
def ucvni_group_id() -> uuid.UUID:
return uuid.uuid4()


@pytest.fixture
def network_id() -> uuid.UUID:
return uuid.uuid4()
Expand Down Expand Up @@ -59,6 +65,16 @@ def network_segment_id() -> uuid.UUID:
return uuid.uuid4()


@pytest.fixture
def project_id() -> str:
return uuid.uuid4().hex


@pytest.fixture
def network(project_id, network_id) -> Network:
return Network(id=str(network_id), project_id=project_id, external=None)


@pytest.fixture
def patch_extend_subnet(mocker) -> None:
"""Ml2 Plugin extend subnet patch.
Expand Down Expand Up @@ -86,13 +102,16 @@ def subport(port_id, vlan_num) -> SubPort:


@pytest.fixture
def network_dict(ml2_plugin) -> dict:
return ml2_plugin._make_network_dict(Network(), process_extensions=False)
def network_dict(ml2_plugin, network, network_segment) -> dict:
network_details = ml2_plugin._make_network_dict(network, process_extensions=False)
extend_network_dict(network_details, network)
ml2_plugin.extend_network_dict_with_segment(network_segment, network_details)
return network_details


@pytest.fixture
def network_segment() -> NetworkSegment:
return NetworkSegment(network_type="vxlan")
def network_segment(network) -> NetworkSegment:
return NetworkSegment(network_type="vxlan", network=network)


@pytest.fixture
Expand Down Expand Up @@ -268,3 +287,40 @@ def trunk_payload_metadata(subport) -> dict:
@pytest.fixture
def trunk_payload(trunk_payload_metadata, trunk) -> DBEventPayload:
return DBEventPayload("context", metadata=trunk_payload_metadata, states=[trunk])


@pytest.fixture
def ml2_understack_conf(mocker, ucvni_group_id) -> None:
mocker.patch(
"neutron_understack.neutron_understack_mech.cfg.CONF.ml2_understack.ucvni_group",
str(ucvni_group_id),
)
mocker.patch(
"neutron_understack.neutron_understack_mech.cfg.CONF.ml2_understack.network_node_switchport_uuid",
"a27f7260-a7c5-4f0c-ac70-6258b026d368",
)
mocker.patch(
"neutron_understack.neutron_understack_mech.cfg.CONF.ml2_understack.undersync_dry_run",
False,
)


@pytest.fixture
def ucvni_create_response(ucvni_group_id) -> list[dict]:
return [
{
"id": "63a2da8b-9da5-493a-b5ac-2ae62f663e1a",
"name": "PROV-NET500",
"ucvni_id": 200054,
"ucvni_type": "TENANT",
"ucvni_group": {
"id": str(ucvni_group_id),
},
"tenant": {
"id": "d3c2c85b-dbf2-4ff5-843f-323524b63768",
},
"status": {
"id": "d4bcbafa-3033-433b-b21b-a20acf9d1324",
},
}
]
28 changes: 24 additions & 4 deletions python/neutron-understack/neutron_understack/tests/helpers.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
from neutron.db.external_net_db import External_net_db_mixin
from neutron.db import external_net_db
from neutron.db import segments_db
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
from neutron.plugins.ml2.managers import TypeManager
from neutron.plugins.ml2.plugin import Ml2Plugin
from neutron.services.trunk.plugin import TrunkPlugin

Expand All @@ -13,7 +17,7 @@ class Ml2PluginNoInit(Ml2Plugin):
"""

def __init__(self):
pass
self.type_manager = TypeManager()

def construct_port_dict(self, port: Port) -> dict:
port_dict = self._make_port_dict(port, process_extensions=False)
Expand All @@ -22,14 +26,30 @@ def construct_port_dict(self, port: Port) -> dict:

def construct_subnet_dict(self, subnet: Subnet) -> dict:
base_subnet_dict = self._make_subnet_dict(subnet)
extended_subnet_dict = External_net_db_mixin._extend_subnet_dict_l3(
base_subnet_dict, subnet
extended_subnet_dict = (
external_net_db.External_net_db_mixin._extend_subnet_dict_l3(
base_subnet_dict, subnet
)
)
return extended_subnet_dict

def extend_network_dict_with_segment(
self, segment: NetworkSegment, network_dict: dict
) -> dict:
segment_dict = segments_db._make_segment_dict(segment)
self.type_manager.extend_network_with_provider_segments(
network_dict, [segment_dict]
)
return network_dict


def extend_port_dict_with_trunk(port_dict: dict, port: Port) -> dict:
port_dict["bulk"] = True
TrunkPlugin._extend_port_trunk_details(port_dict, port)
port_dict.pop("bulk")
return port_dict


def extend_network_dict(network_dict: dict, network: Network = None):
external_net_db.External_net_db_mixin._extend_network_dict_l3(network_dict, network)
return network_dict
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import uuid
from unittest.mock import MagicMock
from unittest.mock import patch

Expand Down Expand Up @@ -57,3 +58,26 @@ 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)


def test_ucvni_create(
mocker,
network_id,
ucvni_create_response,
nautobot,
):
mocker.patch.object(
nautobot, "make_api_request", return_value=ucvni_create_response
)
project_id = "d3c2c85bdbf24ff5843f323524b63768"
response = nautobot.ucvni_create(
network_id=network_id.hex,
project_id=project_id,
ucvni_group="f6843091-845d-4195-8132-960125e05f7b",
network_name="PROV-NET500",
)

assert "tenant" in response[0]
tenant_obj = response[0].get("tenant", {})

assert tenant_obj.get("id") == str(uuid.UUID(project_id))
Original file line number Diff line number Diff line change
Expand Up @@ -183,3 +183,28 @@ def test__delete_vlan(self, mocker, vlan_network_segment, understack_driver):
mock_delete = mocker.patch.object(understack_driver.nb, "delete_vlan")
understack_driver._delete_vlan(vlan_network_segment)
mock_delete.assert_called_once_with(vlan_id=vlan_network_segment.get("id"))


class TestCreateNetworkPostCommit:
@pytest.mark.usefixtures("ml2_understack_conf")
def test_vxlan_network(
self,
mocker,
understack_driver,
network_context,
network_id,
ucvni_group_id,
project_id,
):
mocker.patch.object(understack_driver, "_create_nautobot_namespace")
understack_driver.create_network_postcommit(network_context)
understack_driver.nb.ucvni_create.assert_called_once_with(
network_id=str(network_id),
project_id=str(project_id),
ucvni_group=str(ucvni_group_id),
network_name=network_context.current["name"],
)
understack_driver._create_nautobot_namespace.assert_called_once_with(
str(network_id),
network_context.current["router:external"],
)