From 123753a55af1ffa7530a3986eaf3ae17e26632e3 Mon Sep 17 00:00:00 2001 From: Anatole Denis Date: Thu, 11 Sep 2025 11:57:25 +0200 Subject: [PATCH 1/2] Normalize MAC addresses from netbox to lowercase Both tools used to gather MAC addresses from devices (ethtool and /sys/class/net) return mac addresses as lowercase, but netbox normalizes them as uppercase, causing spurious MAC delete/re-creates when updating servers as the macs don't compare equal --- netbox_agent/network.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/netbox_agent/network.py b/netbox_agent/network.py index c2706108..0135ef67 100644 --- a/netbox_agent/network.py +++ b/netbox_agent/network.py @@ -294,12 +294,12 @@ def update_interface_macs(self, nic, macs): nb_macs = list(self.nb_net.mac_addresses.filter(interface_id=nic.id)) # Clean for nb_mac in nb_macs: - if nb_mac.mac_address not in macs: + if nb_mac.mac_address.lower() not in macs: logging.debug("Deleting extra MAC {mac} from {nic}".format(mac=nb_mac, nic=nic)) nb_mac.delete() # Add missing for mac in macs: - if mac not in {nb_mac.mac_address for nb_mac in nb_macs}: + if mac not in {nb_mac.mac_address.lower() for nb_mac in nb_macs}: logging.debug("Adding MAC {mac} to {nic}".format(mac=mac, nic=nic)) self.nb_net.mac_addresses.create( { @@ -542,7 +542,7 @@ def batched(it, n): if nic["mac"]: self.update_interface_macs(interface, [nic["mac"]]) - if nic["mac"] and nic["mac"] != interface.mac_address: + if nic["mac"] and nic["mac"] != interface.mac_address.lower(): logging.info( "Updating interface {interface} mac to: {mac}".format( interface=interface, mac=nic["mac"] From 780282daa576dc006e9c90a188f19833d62fe1ec Mon Sep 17 00:00:00 2001 From: Anatole Denis Date: Thu, 11 Sep 2025 12:05:41 +0200 Subject: [PATCH 2/2] Specify interface when assigning primary MAC address MAC address objects are not necessarily unique in netbox, so when assigning the primary_interface_field match on the parent object to ensure uniqueness (example usecase: when using virtual VLAN interfaces on a physical interface, the children interface may use the same MAC. Then this update fails with an HTTP 400 because there are multiple netbox MAC address objects with the same MAC) --- netbox_agent/network.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/netbox_agent/network.py b/netbox_agent/network.py index 0135ef67..6f870950 100644 --- a/netbox_agent/network.py +++ b/netbox_agent/network.py @@ -551,7 +551,12 @@ def batched(it, n): if version.parse(nb.version) < version.parse("4.2"): interface.mac_address = nic["mac"] else: - interface.primary_mac_address = {"mac_address": nic["mac"]} + interface.primary_mac_address = { + "mac_address": nic["mac"], + "interface": { + "id": interface.id, + }, + } nic_update += 1 if hasattr(interface, "mtu"):