Fixes #18878: Automatically assign a designated primary MAC address upon creation of a new interface (#20457)

This commit is contained in:
Jeremy Stretch 2025-09-30 14:26:52 -04:00 committed by GitHub
parent ba1c0d6d84
commit 28cc8e5c89
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 23 additions and 3 deletions

View File

@ -632,10 +632,17 @@ class BaseInterface(models.Model):
}) })
# Check that the primary MAC address (if any) is assigned to this interface # Check that the primary MAC address (if any) is assigned to this interface
if self.primary_mac_address and self.primary_mac_address.assigned_object != self: if (
self.primary_mac_address and
self.primary_mac_address.assigned_object is not None and
self.primary_mac_address.assigned_object != self
):
raise ValidationError({ raise ValidationError({
'primary_mac_address': _("MAC address {mac_address} is not assigned to this interface.").format( 'primary_mac_address': _(
mac_address=self.primary_mac_address "MAC address {mac_address} is assigned to a different interface ({interface})."
).format(
mac_address=self.primary_mac_address,
interface=self.primary_mac_address.assigned_object,
) )
}) })

View File

@ -4,6 +4,7 @@ from django.db.models.signals import post_save, post_delete, pre_delete
from django.dispatch import receiver from django.dispatch import receiver
from dcim.choices import CableEndChoices, LinkStatusChoices from dcim.choices import CableEndChoices, LinkStatusChoices
from virtualization.models import VMInterface
from .models import ( from .models import (
Cable, CablePath, CableTermination, ConsolePort, ConsoleServerPort, Device, DeviceBay, FrontPort, Interface, Cable, CablePath, CableTermination, ConsolePort, ConsoleServerPort, Device, DeviceBay, FrontPort, Interface,
InventoryItem, ModuleBay, PathEndpoint, PowerOutlet, PowerPanel, PowerPort, Rack, RearPort, Location, InventoryItem, ModuleBay, PathEndpoint, PowerOutlet, PowerPanel, PowerPort, Rack, RearPort, Location,
@ -170,3 +171,15 @@ def extend_rearport_cable_paths(instance, created, raw, **kwargs):
rearport = instance.rear_port rearport = instance.rear_port
for cablepath in CablePath.objects.filter(_nodes__contains=rearport): for cablepath in CablePath.objects.filter(_nodes__contains=rearport):
cablepath.retrace() cablepath.retrace()
@receiver(post_save, sender=Interface)
@receiver(post_save, sender=VMInterface)
def update_mac_address_interface(instance, created, raw, **kwargs):
"""
When creating a new Interface or VMInterface, check whether a MACAddress has been designated as its primary. If so,
assign the MACAddress to the interface.
"""
if created and not raw and instance.primary_mac_address:
instance.primary_mac_address.assigned_object = instance
instance.primary_mac_address.save()