From 1cd629efb3c21e9dc0206a52fe8ca069c45cfb97 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Tue, 30 Jan 2018 16:34:42 -0500 Subject: [PATCH] #1843: Allow assignment of VC member interfaces to VC master LAG --- netbox/dcim/forms.py | 20 ++++++++++---------- netbox/dcim/models.py | 13 +++++++++++-- netbox/templates/dcim/inc/interface.html | 6 ++---- 3 files changed, 23 insertions(+), 16 deletions(-) diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 2f5f66750..54719ccf3 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -1706,17 +1706,17 @@ class InterfaceForm(BootstrapMixin, forms.ModelForm, ChainedFieldsMixin): def __init__(self, *args, **kwargs): super(InterfaceForm, self).__init__(*args, **kwargs) - # Limit LAG choices to interfaces belonging to this device + # Limit LAG choices to interfaces belonging to this device (or VC master) if self.is_bound: - self.fields['lag'].queryset = Interface.objects.order_naturally().filter( - device_id=self.data['device'], form_factor=IFACE_FF_LAG - ) device = Device.objects.get(pk=self.data['device']) - else: self.fields['lag'].queryset = Interface.objects.order_naturally().filter( - device=self.instance.device, form_factor=IFACE_FF_LAG + device__in=[device, device.get_vc_master()], form_factor=IFACE_FF_LAG ) + else: device = self.instance.device + self.fields['lag'].queryset = Interface.objects.order_naturally().filter( + device__in=[self.instance.device, self.instance.device.get_vc_master()], form_factor=IFACE_FF_LAG + ) # Limit the queryset for the site to only include the interface's device's site if device and device.site: @@ -1832,10 +1832,10 @@ class InterfaceCreateForm(ComponentForm, ChainedFieldsMixin): super(InterfaceCreateForm, self).__init__(*args, **kwargs) - # Limit LAG choices to interfaces belonging to this device + # Limit LAG choices to interfaces belonging to this device (or its VC master) if self.parent is not None: self.fields['lag'].queryset = Interface.objects.order_naturally().filter( - device=self.parent, form_factor=IFACE_FF_LAG + device__in=[self.parent, self.parent.get_vc_master()], form_factor=IFACE_FF_LAG ) else: self.fields['lag'].queryset = Interface.objects.none() @@ -1935,7 +1935,7 @@ class InterfaceBulkEditForm(BootstrapMixin, BulkEditForm, ChainedFieldsMixin): def __init__(self, *args, **kwargs): super(InterfaceBulkEditForm, self).__init__(*args, **kwargs) - # Limit LAG choices to interfaces which belong to the parent device. + # Limit LAG choices to interfaces which belong to the parent device (or VC master) device = None if self.initial.get('device'): try: @@ -1945,7 +1945,7 @@ class InterfaceBulkEditForm(BootstrapMixin, BulkEditForm, ChainedFieldsMixin): if device is not None: interface_ordering = device.device_type.interface_ordering self.fields['lag'].queryset = Interface.objects.order_naturally(method=interface_ordering).filter( - device=device, form_factor=IFACE_FF_LAG + device__in=[device, device.get_vc_master()], form_factor=IFACE_FF_LAG ) else: self.fields['lag'].choices = [] diff --git a/netbox/dcim/models.py b/netbox/dcim/models.py index 5e270b187..ea39b80aa 100644 --- a/netbox/dcim/models.py +++ b/netbox/dcim/models.py @@ -1070,6 +1070,15 @@ class Device(CreatedUpdatedModel, CustomFieldModel): else: return None + def get_vc_master(self): + """ + If this Device is a VirtualChassis member, return the VC master. Otherwise, return None. + """ + if hasattr(self, 'vc_membership'): + return self.vc_membership.virtual_chassis.master + else: + return None + @property def virtual_chassis(self): try: @@ -1375,8 +1384,8 @@ class Interface(models.Model): "Disconnect the interface or choose a suitable form factor." }) - # An interface's LAG must belong to the same device - if self.lag and self.lag.device != self.device: + # An interface's LAG must belong to the same device (or VC master) + if self.lag and self.lag.device not in [self.device, self.device.get_vc_master()]: raise ValidationError({ 'lag': "The selected LAG interface ({}) belongs to a different device ({}).".format( self.lag.name, self.lag.device.name diff --git a/netbox/templates/dcim/inc/interface.html b/netbox/templates/dcim/inc/interface.html index b9101a965..783a56460 100644 --- a/netbox/templates/dcim/inc/interface.html +++ b/netbox/templates/dcim/inc/interface.html @@ -1,11 +1,9 @@ - {# Checkbox (exclude VC members) #} + {# Checkbox #} {% if perms.dcim.change_interface or perms.dcim.delete_interface %} - {% if iface.parent == device %} - - {% endif %} + {% endif %}