Skip to content

Commit 9a58823

Browse files
committed
Fixes #6289: Fix assignment of VC member interfaces to LAG interfaces
1 parent f408ad1 commit 9a58823

File tree

8 files changed

+20
-12
lines changed

8 files changed

+20
-12
lines changed

docs/release-notes/version-2.11.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
* [#6254](https://github.com/netbox-community/netbox/issues/6254) - Disable ordering of space column in racks table
1818
* [#6258](https://github.com/netbox-community/netbox/issues/6258) - Fix parent assignment for SiteGroup API serializer
1919
* [#6267](https://github.com/netbox-community/netbox/issues/6267) - Fix cable tracing API endpoint for circuit terminations
20+
* [#6289](https://github.com/netbox-community/netbox/issues/6289) - Fix assignment of VC member interfaces to LAG interfaces
2021

2122
---
2223

netbox/dcim/filters.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -984,7 +984,7 @@ def filter_device(self, queryset, name, value):
984984
devices = Device.objects.filter(**{'{}__in'.format(name): value})
985985
vc_interface_ids = []
986986
for device in devices:
987-
vc_interface_ids.extend(device.vc_interfaces.values_list('id', flat=True))
987+
vc_interface_ids.extend(device.vc_interfaces().values_list('id', flat=True))
988988
return queryset.filter(pk__in=vc_interface_ids)
989989
except Device.DoesNotExist:
990990
return queryset.none()
@@ -995,7 +995,7 @@ def filter_device_id(self, queryset, name, id_list):
995995
try:
996996
devices = Device.objects.filter(pk__in=id_list)
997997
for device in devices:
998-
vc_interface_ids += device.vc_interfaces.values_list('id', flat=True)
998+
vc_interface_ids += device.vc_interfaces().values_list('id', flat=True)
999999
return queryset.filter(pk__in=vc_interface_ids)
10001000
except Device.DoesNotExist:
10011001
return queryset.none()

netbox/dcim/forms.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2153,7 +2153,7 @@ def __init__(self, *args, **kwargs):
21532153
ip_choices = [(None, '---------')]
21542154

21552155
# Gather PKs of all interfaces belonging to this Device or a peer VirtualChassis member
2156-
interface_ids = self.instance.vc_interfaces.values_list('pk', flat=True)
2156+
interface_ids = self.instance.vc_interfaces().values_list('pk', flat=True)
21572157

21582158
# Collect interface IPs
21592159
interface_ips = IPAddress.objects.filter(

netbox/dcim/models/devices.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -716,7 +716,7 @@ def clean(self):
716716
pass
717717

718718
# Validate primary IP addresses
719-
vc_interfaces = self.vc_interfaces.all()
719+
vc_interfaces = self.vc_interfaces()
720720
if self.primary_ip4:
721721
if self.primary_ip4.family != 4:
722722
raise ValidationError({
@@ -854,20 +854,27 @@ def primary_ip(self):
854854
else:
855855
return None
856856

857+
@property
858+
def interfaces_count(self):
859+
if self.virtual_chassis and self.virtual_chassis.master == self:
860+
return self.vc_interfaces().count()
861+
return self.interfaces.count()
862+
857863
def get_vc_master(self):
858864
"""
859865
If this Device is a VirtualChassis member, return the VC master. Otherwise, return None.
860866
"""
861867
return self.virtual_chassis.master if self.virtual_chassis else None
862868

863-
@property
864-
def vc_interfaces(self):
869+
def vc_interfaces(self, if_master=False):
865870
"""
866871
Return a QuerySet matching all Interfaces assigned to this Device or, if this Device is a VC master, to another
867872
Device belonging to the same VirtualChassis.
873+
874+
:param if_master: If True, return VC member interfaces only if this Device is the VC master.
868875
"""
869876
filter = Q(device=self)
870-
if self.virtual_chassis and self.virtual_chassis.master == self:
877+
if self.virtual_chassis and (not if_master or self.virtual_chassis.master == self):
871878
filter |= Q(device__virtual_chassis=self.virtual_chassis, mgmt_only=False)
872879
return Interface.objects.filter(filter)
873880

netbox/dcim/views.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1405,7 +1405,7 @@ class DeviceInterfacesView(generic.ObjectView):
14051405
template_name = 'dcim/device/interfaces.html'
14061406

14071407
def get_extra_context(self, request, instance):
1408-
interfaces = instance.vc_interfaces.restrict(request.user, 'view').prefetch_related(
1408+
interfaces = instance.vc_interfaces(if_master=True).restrict(request.user, 'view').prefetch_related(
14091409
Prefetch('ip_addresses', queryset=IPAddress.objects.restrict(request.user)),
14101410
Prefetch('member_interfaces', queryset=Interface.objects.restrict(request.user)),
14111411
'lag', 'cable', '_path__destination', 'tags',
@@ -1527,7 +1527,7 @@ class DeviceLLDPNeighborsView(generic.ObjectView):
15271527
template_name = 'dcim/device/lldp_neighbors.html'
15281528

15291529
def get_extra_context(self, request, instance):
1530-
interfaces = instance.vc_interfaces.restrict(request.user, 'view').prefetch_related(
1530+
interfaces = instance.vc_interfaces(if_master=True).restrict(request.user, 'view').prefetch_related(
15311531
'_path__destination'
15321532
).exclude(
15331533
type__in=NONCONNECTABLE_IFACE_TYPES

netbox/ipam/filters.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,7 @@ def filter_device(self, queryset, name, value):
515515
return queryset.none()
516516
interface_ids = []
517517
for device in devices:
518-
interface_ids.extend(device.vc_interfaces.values_list('id', flat=True))
518+
interface_ids.extend(device.vc_interfaces().values_list('id', flat=True))
519519
return queryset.filter(
520520
interface__in=interface_ids
521521
)

netbox/ipam/forms.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1561,7 +1561,7 @@ def __init__(self, *args, **kwargs):
15611561
# Limit IP address choices to those assigned to interfaces of the parent device/VM
15621562
if self.instance.device:
15631563
self.fields['ipaddresses'].queryset = IPAddress.objects.filter(
1564-
interface__in=self.instance.device.vc_interfaces.values_list('id', flat=True)
1564+
interface__in=self.instance.device.vc_interfaces().values_list('id', flat=True)
15651565
)
15661566
elif self.instance.virtual_machine:
15671567
self.fields['ipaddresses'].queryset = IPAddress.objects.filter(

netbox/templates/dcim/device/base.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@
6868
<li role="presentation" {% if active_tab == 'device' %} class="active"{% endif %}>
6969
<a href="{% url 'dcim:device' pk=object.pk %}">Device</a>
7070
</li>
71-
{% with interface_count=object.vc_interfaces.count %}
71+
{% with interface_count=object.interfaces_count %}
7272
{% if interface_count %}
7373
<li role="presentation" {% if active_tab == 'interfaces' %} class="active"{% endif %}>
7474
<a href="{% url 'dcim:device_interfaces' pk=object.pk %}">Interfaces {% badge interface_count %}</a>

0 commit comments

Comments
 (0)