Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add logging for original port context #519

Merged
merged 3 commits into from
Nov 28, 2024
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
17 changes: 17 additions & 0 deletions python/neutron-understack/neutron_understack/nautobot.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,23 @@ def prep_switch_interface(

return resp_data["vlan_group_id"]

def detach_port(self, connected_interface_id: str, ucvni_uuid: str) -> str:
"""Runs a Nautobot Job to cleanup a switch interface.

The nautobot job will find a VLAN that is bound to the UCVNI, remove it
from the Interface and if the VLAN is unused it will delete it.

The vlan group ID is returned.
"""
url = "/api/plugins/undercloud-vni/detach_port"
payload = {
"ucvni_uuid": str(ucvni_uuid),
"connected_interface_id": str(connected_interface_id),
}
resp_data = self.make_api_request(url, "post", payload)

return resp_data["vlan_group_id"]

def configure_port_status(self, interface_uuid: str, status: str) -> dict:
url = f"/api/dcim/interfaces/{interface_uuid}/"
payload = {"status": {"name": status}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,13 +210,15 @@ def update_port_precommit(self, context):
def update_port_postcommit(self, context):
log_call("update_port_postcommit", context)

self._delete_tenant_port_on_unbound(context)

vif_type = context.current["binding:vif_type"]

if vif_type != portbindings.VIF_TYPE_OTHER:
return

network_id = context.current["network_id"]
connected_interface_uuid = self.fetch_connected_interface_uuid(context)
connected_interface_uuid = self.fetch_connected_interface_uuid(context.current)
nb_vlan_group_id = self.update_nautobot(network_id, connected_interface_uuid)

self.undersync.sync_devices(
Expand All @@ -230,6 +232,23 @@ def delete_port_precommit(self, context):
def delete_port_postcommit(self, context):
log_call("delete_port_postcommit", context)

network_id = context.current["network_id"]

if network_id == cfg.CONF.ml2_type_understack.provisioning_network:
connected_interface_uuid = self.fetch_connected_interface_uuid(
context.current
)
port_status = "Active"
mfencik marked this conversation as resolved.
Show resolved Hide resolved
configure_port_status_data = self.nb.configure_port_status(
connected_interface_uuid, port_status
)
switch_uuid = configure_port_status_data.get("device", {}).get("id")
nb_vlan_group_id = UUID(self.nb.fetch_vlan_group_uuid(switch_uuid))
self.undersync.sync_devices(
vlan_group_uuids=str(nb_vlan_group_id),
dry_run=cfg.CONF.ml2_understack.undersync_dry_run,
)
mfencik marked this conversation as resolved.
Show resolved Hide resolved

def bind_port(self, context):
log_call("bind_port", context)
for segment in context.network.network_segments:
Expand Down Expand Up @@ -273,16 +292,14 @@ def check_segment(self, segment):
def check_vlan_transparency(self, context):
log_call("check_vlan_transparency", context)

def fetch_connected_interface_uuid(self, context: PortContext) -> str:
def fetch_connected_interface_uuid(self, context: dict) -> str:
"""Fetches the connected interface UUID from the port context.

:param context: The context of the port.
:return: The connected interface UUID.
"""
connected_interface_uuid = (
context.current["binding:profile"]
.get("local_link_information")[0]
.get("port_id")
context["binding:profile"].get("local_link_information")[0].get("port_id")
)
try:
UUID(str(connected_interface_uuid))
Expand Down Expand Up @@ -319,3 +336,31 @@ def update_nautobot(self, network_id: str, connected_interface_uuid: str) -> UUI
return UUID(
self.nb.prep_switch_interface(connected_interface_uuid, network_id)
)

def _delete_tenant_port_on_unbound(self, context):
"""Tenant network port cleanup in the UnderCloud infrastructure.

This is triggered in the update_port_postcommit call as in the
delete_port_postcommit call there is no binding profile information
anymore, hence there is no way for us to identify which baremetal port
needs cleanup.

Only in the update_port_postcommit we have access to the original context,
from which we can access the binding information.
"""
if (
context.current["binding:vnic_type"] == "baremetal"
and context.vif_type == portbindings.VIF_TYPE_UNBOUND
and context.original_vif_type == portbindings.VIF_TYPE_OTHER
):
connected_interface_uuid = self.fetch_connected_interface_uuid(
context.original
)
network_id = context.current["network_id"]
nb_vlan_group_id = UUID(
self.nb.detach_port(connected_interface_uuid, network_id)
)
self.undersync.sync_devices(
vlan_group_uuids=str(nb_vlan_group_id),
dry_run=cfg.CONF.ml2_understack.undersync_dry_run,
)
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def undersync_client() -> Undersync:


def test_fetch_connected_interface_uuid(context):
result = driver.fetch_connected_interface_uuid(context)
result = driver.fetch_connected_interface_uuid(context.current)
assert result == "03921f8d-b4de-412e-a733-f8eade4c6268"


Expand Down