diff --git a/argo-workflows/trigger-undersync/workflowtemplates/undersync-device.yaml b/argo-workflows/trigger-undersync/workflowtemplates/undersync-device.yaml index c24b6317c..490eca648 100644 --- a/argo-workflows/trigger-undersync/workflowtemplates/undersync-device.yaml +++ b/argo-workflows/trigger-undersync/workflowtemplates/undersync-device.yaml @@ -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 @@ -34,7 +34,7 @@ spec: readOnly: true inputs: parameters: - - name: interface_uuid + - name: interface_mac - name: device_uuid - name: network_name - name: force diff --git a/python/neutron-understack/neutron_understack/neutron_understack_mech.py b/python/neutron-understack/neutron_understack/neutron_understack_mech.py index ad699fd7c..ae2890120 100644 --- a/python/neutron-understack/neutron_understack/neutron_understack_mech.py +++ b/python/neutron-understack/neutron_understack/neutron_understack_mech.py @@ -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, diff --git a/python/understack-workflows/understack_workflows/main/undersync_device.py b/python/understack-workflows/understack_workflows/main/undersync_device.py index f4fb5fdda..449754a62 100644 --- a/python/understack-workflows/understack_workflows/main/undersync_device.py +++ b/python/understack-workflows/understack_workflows/main/undersync_device.py @@ -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 @@ -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}") @@ -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" diff --git a/python/understack-workflows/understack_workflows/nautobot.py b/python/understack-workflows/understack_workflows/nautobot.py index 8e841f8e6..c8377eb3f 100644 --- a/python/understack-workflows/understack_workflows/nautobot.py +++ b/python/understack-workflows/understack_workflows/nautobot.py @@ -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) @@ -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()