Skip to content

Commit

Permalink
Identify interface by MAC address instead of UUID
Browse files Browse the repository at this point in the history
The UUID in Nautobot is not the same as the UUID in ironic/nova so use the MAC
address to find the required switch port.

In the earlier milestones we should not encounter LAGs but this is something to
watch out for in future: - it is not clear exactly what the rules are with
interface in Nautobot but when interfaces belong to a LAG.  Nautobot seems to
report that the LAG and its members all share a MAC address.  This means the
MAC address is no longer guaranteed to uniquely identify an interface.

We have also been talking about how to sync/store the various UUID values in
nautobot, so perhaps this will eventually be solved that way.
  • Loading branch information
Steve Keay authored and cardoe committed Sep 4, 2024
1 parent d7a6f82 commit e729fc1
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ spec:
command:
- undersync-device
args:
- --interface-id
- "{{workflow.parameters.interface_uuid}}"
- --interface-mac
- "{{workflow.parameters.interface_mac}}"
- --device-id
- "{{workflow.parameters.device_uuid}}"
- --network-name
Expand All @@ -34,7 +34,7 @@ spec:
readOnly: true
inputs:
parameters:
- name: interface_uuid
- name: interface_mac
- name: device_uuid
- name: network_name
- name: force
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -263,16 +263,16 @@ def __network_name(self, network_id: str):
return "tenant"

def _move_to_network(self, context):
interface_uuid = context.current["id"]
interface_mac = context.current["mac_address"]
device_uuid = context.current["binding:host_id"]
network_name = self.__network_name(context.current["network_id"])
LOG.debug(f"Selected {network_name=} for {device_uuid=} {interface_id=}")
LOG.debug(f"Selected {network_name=} for {device_uuid=} {interface_mac=}")

result = argo_client.submit(
template_name="undersync-device",
entrypoint="trigger-undersync",
parameters={
"interface_uuid": interface_uuid,
"interface_mac": interface_mac,
"device_uuid": device_uuid,
"network_name": network_name,
"dry_run": cfg.CONF.ml2_type_understack.argo_dry_run,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

def update_nautobot(args) -> UUID:
device_id = args.device_id
interface_id = args.interface_id
interface_mac = args.interface_mac
network_name = args.network_name

nb_url = args.nautobot_url
Expand All @@ -28,9 +28,9 @@ def update_nautobot(args) -> UUID:
new_status = network_name_status[args.network_name]

nautobot = Nautobot(nb_url, nb_token, logger=logger)
logger.info(f"Updating Nautobot {device_id=!s} {interface_id=!s} {network_name=}")
interface = nautobot.update_switch_interface_status(interface_id, new_status)
logger.info(f"Updated Nautobot {device_id=!s} {interface_id=!s} {network_name=}")
logger.info(f"Updating Nautobot {device_id=!s} {interface_mac=!s} {network_name=}")
interface = nautobot.update_switch_interface_status(device_id, interface_mac, new_status)
logger.info(f"Updated Nautobot {device_id=!s} {interface_mac=!s} {network_name=}")

switch_id = interface.device.id
logger.info(f"Interface connected to switch {switch_id!s}")
Expand All @@ -57,7 +57,7 @@ def argument_parser():
description="Trigger undersync run for a device",
)
parser.add_argument(
"--interface-id", type=UUID, required=True, help="Nautobot interface UUID"
"--interface-mac", type=str, required=True, help="Interface MAC address"
)
parser.add_argument(
"--device-id", type=UUID, required=False, help="Nautobot device UUID"
Expand Down
40 changes: 36 additions & 4 deletions python/understack-workflows/understack_workflows/nautobot.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,17 @@ def interface_by_id(self, interface_id: UUID) -> NautobotInterface:
self.exit_with_error(f"Interface {interface_id!s} not found in Nautobot")
return interface

def non_lag_interface_by_mac(self, device_id: UUID, mac_address: str) -> list[NautobotInterface]:
interfaces = self.session.dcim.interfaces.filter(
device_id=device_id,
mac_address=mac_address,
type__n = "lag",
)
if not interfaces:
self.exit_with_error(
f"Interface with {device_id=} and {mac_address=} not found in Nautobot"
)
return interfaces[0]

def device_interfaces(self, device_id: UUID):
return self.session.dcim.interfaces.filter(device_id=device_id)
Expand All @@ -127,13 +138,34 @@ def update_cf(self, device_id: UUID, field_name: str, field_value: str):
self.logger.info(f"save result: {response}")
return response

def update_switch_interface_status(self, server_interface_id: UUID, new_status: str) -> NautobotInterface:
server_interface = self.interface_by_id(server_interface_id)
def update_switch_interface_status(
self, device_id: UUID, server_interface_mac: str, new_status: str
) -> NautobotInterface:
"""Change the Interface Status in Nautobot for interfaces
The device_id and interface MAC address parameters identify one or more
server interfaces.
Nautobot Interfaces that are selected that match the device UUID and MAC
address, but excluding any parent LAG interfaces - only the member
interfaces are considered.
We then update ONE of the connected switch ports to the appropriate status.
The interface is returned.
"""
server_interface = self.non_lag_interface_by_mac(device_id, server_interface_mac)

connected_endpoint = server_interface.connected_endpoint
if not connected_endpoint:
raise Exception("Interface {server_interface_id} not connected in Nautobot")
raise Exception(
f"Interface {server_interface_mac} {server_interface.type} not connected in Nautobot"
)
switch_interface_id = connected_endpoint.id
self.logger.debug(f"Int {server_interface_id} connects to {switch_interface_id}")
self.logger.debug(
f"Interface {server_interface_mac} connects to {switch_interface_id}"
)

switch_interface = self.interface_by_id(switch_interface_id)
switch_interface.status = new_status
result = switch_interface.save()
Expand Down

0 comments on commit e729fc1

Please sign in to comment.