Closes #19273: Enable selection of VLANs scoped to a Device's Cluster or Cluster Group (#22715)

This commit is contained in:
Martin Hauser 2026-07-20 17:18:56 +02:00 committed by GitHub
parent 80f6da084e
commit 15d2cc35e0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 33 additions and 1 deletions

View File

@ -1070,7 +1070,7 @@ class VLANFilterSet(PrimaryModelFilterSet, TenancyFilterSet):
method='get_for_site'
)
available_on_device = django_filters.ModelChoiceFilter(
queryset=Device.objects.all(),
queryset=Device.objects.select_related('cluster'),
method='get_for_device'
)
available_on_virtualmachine = django_filters.ModelChoiceFilter(

View File

@ -298,6 +298,18 @@ class VLANQuerySet(RestrictedQuerySet):
# Find all relevant VLANGroups
q = Q()
if device.cluster_id:
# The Device's physical scope is evaluated below. For valid assignments,
# the Cluster's physical scope is already represented by that hierarchy.
q |= Q(
scope_type=ContentType.objects.get_by_natural_key('virtualization', 'cluster'),
scope_id=device.cluster_id
)
if device.cluster.group_id:
q |= Q(
scope_type=ContentType.objects.get_by_natural_key('virtualization', 'clustergroup'),
scope_id=device.cluster.group_id
)
if device.site.region:
q |= Q(
scope_type=ContentType.objects.get_by_natural_key('dcim', 'region'),

View File

@ -2188,6 +2188,26 @@ class VLANTestCase(TestCase, ChangeLoggedFilterSetTests):
params = {'available_on_device': device_id}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 7) # 5 scoped + 1 global group + 1 global
def test_available_on_device_cluster_scopes(self):
device = Device.objects.get(name='Device 1')
device.cluster = Cluster.objects.get(name='Cluster 1')
device.save(update_fields=('cluster',))
params = {'available_on_device': device.pk}
vlans = self.filterset(params, self.queryset).qs
# VLANs from groups scoped to the assigned cluster or its cluster group
self.assertIn(VLAN.objects.get(name='Cluster 1'), vlans)
self.assertIn(VLAN.objects.get(name='Cluster Group 1'), vlans)
# VLANs from groups scoped to unrelated clusters or cluster groups
self.assertNotIn(VLAN.objects.get(name='Cluster 2'), vlans)
self.assertNotIn(VLAN.objects.get(name='Cluster Group 2'), vlans)
# Site, location, rack and global availability is unchanged
self.assertEqual(
set(vlans.values_list('vid', flat=True)),
{1, 4, 7, 10, 13, 16, 19, 500, 1000}
)
def test_available_on_virtualmachine(self):
vm_id = VirtualMachine.objects.first().pk
params = {'available_on_virtualmachine': vm_id}