Fixes: #19645 - Correct Interface selection for Cable add when VC master is the selected device

This commit is contained in:
Daniel Sheppard 2025-08-06 21:16:19 -05:00
parent e828ca5cb4
commit 1025c227ce
2 changed files with 21 additions and 3 deletions

View File

@ -1885,6 +1885,16 @@ class InterfaceFilterSet(
PathEndpointFilterSet, PathEndpointFilterSet,
CommonInterfaceFilterSet CommonInterfaceFilterSet
): ):
virtual_chassis_member_or_master = MultiValueCharFilter(
method='filter_virtual_chassis_member_or_master',
field_name='name',
label=_('Virtual Chassis Interfaces for Device')
)
virtual_chassis_member_or_master_id = MultiValueNumberFilter(
method='filter_virtual_chassis_member_or_master',
field_name='pk',
label=_('Virtual Chassis Interfaces for Device (ID)')
)
virtual_chassis_member = MultiValueCharFilter( virtual_chassis_member = MultiValueCharFilter(
method='filter_virtual_chassis_member', method='filter_virtual_chassis_member',
field_name='name', field_name='name',
@ -1995,11 +2005,14 @@ class InterfaceFilterSet(
'cable_id', 'cable_end', 'cable_id', 'cable_end',
) )
def filter_virtual_chassis_member(self, queryset, name, value): def filter_virtual_chassis_member_or_master(self, queryset, name, value):
return self.filter_virtual_chassis_member(queryset, name, value, if_master=True)
def filter_virtual_chassis_member(self, queryset, name, value, if_master=False):
try: try:
vc_interface_ids = [] vc_interface_ids = []
for device in Device.objects.filter(**{f'{name}__in': value}): for device in Device.objects.filter(**{f'{name}__in': value}):
vc_interface_ids.extend(device.vc_interfaces(if_master=False).values_list('id', flat=True)) vc_interface_ids.extend(device.vc_interfaces(if_master=if_master).values_list('id', flat=True))
return queryset.filter(pk__in=vc_interface_ids) return queryset.filter(pk__in=vc_interface_ids)
except Device.DoesNotExist: except Device.DoesNotExist:
return queryset.none() return queryset.none()

View File

@ -19,6 +19,11 @@ def get_cable_form(a_type, b_type):
# Device component # Device component
if hasattr(term_cls, 'device'): if hasattr(term_cls, 'device'):
# Dynamically change the param field for interfaces to use virtual_chassis filter
query_param_device_field = 'device_id'
if term_cls == Interface:
query_param_device_field = 'virtual_chassis_member_or_master_id'
attrs[f'termination_{cable_end}_device'] = DynamicModelMultipleChoiceField( attrs[f'termination_{cable_end}_device'] = DynamicModelMultipleChoiceField(
queryset=Device.objects.all(), queryset=Device.objects.all(),
label=_('Device'), label=_('Device'),
@ -36,7 +41,7 @@ def get_cable_form(a_type, b_type):
'parent': 'device', 'parent': 'device',
}, },
query_params={ query_params={
'device_id': f'$termination_{cable_end}_device', query_param_device_field: f'$termination_{cable_end}_device',
'kind': 'physical', # Exclude virtual interfaces 'kind': 'physical', # Exclude virtual interfaces
} }
) )