mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-22 20:12:00 -06:00
#1843: Allow assignment of VC member interfaces to VC master LAG
This commit is contained in:
parent
2f7f5425d8
commit
1cd629efb3
@ -1706,17 +1706,17 @@ class InterfaceForm(BootstrapMixin, forms.ModelForm, ChainedFieldsMixin):
|
|||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(InterfaceForm, self).__init__(*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:
|
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'])
|
device = Device.objects.get(pk=self.data['device'])
|
||||||
else:
|
|
||||||
self.fields['lag'].queryset = Interface.objects.order_naturally().filter(
|
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
|
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
|
# Limit the queryset for the site to only include the interface's device's site
|
||||||
if device and device.site:
|
if device and device.site:
|
||||||
@ -1832,10 +1832,10 @@ class InterfaceCreateForm(ComponentForm, ChainedFieldsMixin):
|
|||||||
|
|
||||||
super(InterfaceCreateForm, self).__init__(*args, **kwargs)
|
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:
|
if self.parent is not None:
|
||||||
self.fields['lag'].queryset = Interface.objects.order_naturally().filter(
|
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:
|
else:
|
||||||
self.fields['lag'].queryset = Interface.objects.none()
|
self.fields['lag'].queryset = Interface.objects.none()
|
||||||
@ -1935,7 +1935,7 @@ class InterfaceBulkEditForm(BootstrapMixin, BulkEditForm, ChainedFieldsMixin):
|
|||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(InterfaceBulkEditForm, self).__init__(*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
|
device = None
|
||||||
if self.initial.get('device'):
|
if self.initial.get('device'):
|
||||||
try:
|
try:
|
||||||
@ -1945,7 +1945,7 @@ class InterfaceBulkEditForm(BootstrapMixin, BulkEditForm, ChainedFieldsMixin):
|
|||||||
if device is not None:
|
if device is not None:
|
||||||
interface_ordering = device.device_type.interface_ordering
|
interface_ordering = device.device_type.interface_ordering
|
||||||
self.fields['lag'].queryset = Interface.objects.order_naturally(method=interface_ordering).filter(
|
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:
|
else:
|
||||||
self.fields['lag'].choices = []
|
self.fields['lag'].choices = []
|
||||||
|
@ -1070,6 +1070,15 @@ class Device(CreatedUpdatedModel, CustomFieldModel):
|
|||||||
else:
|
else:
|
||||||
return None
|
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
|
@property
|
||||||
def virtual_chassis(self):
|
def virtual_chassis(self):
|
||||||
try:
|
try:
|
||||||
@ -1375,8 +1384,8 @@ class Interface(models.Model):
|
|||||||
"Disconnect the interface or choose a suitable form factor."
|
"Disconnect the interface or choose a suitable form factor."
|
||||||
})
|
})
|
||||||
|
|
||||||
# An interface's LAG must belong to the same device
|
# An interface's LAG must belong to the same device (or VC master)
|
||||||
if self.lag and self.lag.device != self.device:
|
if self.lag and self.lag.device not in [self.device, self.device.get_vc_master()]:
|
||||||
raise ValidationError({
|
raise ValidationError({
|
||||||
'lag': "The selected LAG interface ({}) belongs to a different device ({}).".format(
|
'lag': "The selected LAG interface ({}) belongs to a different device ({}).".format(
|
||||||
self.lag.name, self.lag.device.name
|
self.lag.name, self.lag.device.name
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
<tr class="interface{% if not iface.enabled %} danger{% elif iface.connection and iface.connection.connection_status or iface.circuit_termination %} success{% elif iface.connection and not iface.connection.connection_status %} info{% elif iface.is_virtual %} warning{% endif %}" id="iface_{{ iface.name }}">
|
<tr class="interface{% if not iface.enabled %} danger{% elif iface.connection and iface.connection.connection_status or iface.circuit_termination %} success{% elif iface.connection and not iface.connection.connection_status %} info{% elif iface.is_virtual %} warning{% endif %}" id="iface_{{ iface.name }}">
|
||||||
|
|
||||||
{# Checkbox (exclude VC members) #}
|
{# Checkbox #}
|
||||||
{% if perms.dcim.change_interface or perms.dcim.delete_interface %}
|
{% if perms.dcim.change_interface or perms.dcim.delete_interface %}
|
||||||
<td class="pk">
|
<td class="pk">
|
||||||
{% if iface.parent == device %}
|
<input name="pk" type="checkbox" value="{{ iface.pk }}" />
|
||||||
<input name="pk" type="checkbox" value="{{ iface.pk }}" />
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
</td>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user