Misc cleanup, add test for VID validation

This commit is contained in:
Jeremy Stretch 2024-07-16 10:33:09 -04:00
parent e2dae0cd1f
commit 965be76aec
2 changed files with 18 additions and 11 deletions

View File

@ -29,7 +29,8 @@ def default_vid_ranges():
class VLANGroup(OrganizationalModel): class VLANGroup(OrganizationalModel):
""" """
A VLAN group is an arbitrary collection of VLANs within which VLAN IDs and names must be unique. A VLAN group is an arbitrary collection of VLANs within which VLAN IDs and names must be unique. Each group must
define one or more ranges of valid VLAN IDs, and may be assigned a specific scope.
""" """
name = models.CharField( name = models.CharField(
verbose_name=_('name'), verbose_name=_('name'),
@ -98,7 +99,6 @@ class VLANGroup(OrganizationalModel):
# Validate VID ranges # Validate VID ranges
if self.vid_ranges and check_ranges_overlap(self.vid_ranges): if self.vid_ranges and check_ranges_overlap(self.vid_ranges):
raise ValidationError({'vid_ranges': _("Ranges cannot overlap.")}) raise ValidationError({'vid_ranges': _("Ranges cannot overlap.")})
for vid_range in self.vid_ranges: for vid_range in self.vid_ranges:
if vid_range.lower >= vid_range.upper: if vid_range.lower >= vid_range.upper:
raise ValidationError({ raise ValidationError({
@ -120,7 +120,9 @@ class VLANGroup(OrganizationalModel):
""" """
available_vlans = set() available_vlans = set()
for vlan_range in self.vid_ranges: for vlan_range in self.vid_ranges:
available_vlans = available_vlans.union({vid for vid in range(vlan_range.lower, vlan_range.upper)}) available_vlans = available_vlans.union({
vid for vid in range(vlan_range.lower, vlan_range.upper)
})
available_vlans -= set(VLAN.objects.filter(group=self).values_list('vid', flat=True)) available_vlans -= set(VLAN.objects.filter(group=self).values_list('vid', flat=True))
return sorted(available_vlans) return sorted(available_vlans)
@ -249,14 +251,9 @@ class VLAN(PrimaryModel):
).format(group=self.group, scope=self.group.scope, site=self.site) ).format(group=self.group, scope=self.group.scope, site=self.site)
) )
# Validate group min/max VIDs # Check that the VLAN ID is permitted in the assigned group (if any)
if self.group and self.group.vid_ranges: if self.group:
in_bounds = False if not any([self.vid in r for r in self.group.vid_ranges]):
for vid_range in self.group.vid_ranges:
if vid_range.lower <= self.vid <= vid_range.upper:
in_bounds = True
if not in_bounds:
raise ValidationError({ raise ValidationError({
'vid': _( 'vid': _(
"VID must be in ranges {ranges} for VLANs in group {group}" "VID must be in ranges {ranges} for VLANs in group {group}"

View File

@ -533,3 +533,13 @@ class TestVLANGroup(TestCase):
VLAN.objects.create(name='VLAN 104', vid=104, group=vlangroup) VLAN.objects.create(name='VLAN 104', vid=104, group=vlangroup)
self.assertEqual(vlangroup.get_next_available_vid(), 105) self.assertEqual(vlangroup.get_next_available_vid(), 105)
def test_vid_validation(self):
vlangroup = VLANGroup.objects.first()
vlan = VLAN(vid=1, name='VLAN 1', group=vlangroup)
with self.assertRaises(ValidationError):
vlan.full_clean()
vlan = VLAN(vid=109, name='VLAN 109', group=vlangroup)
vlan.full_clean()