1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

Closes #8168: Add min/max VID fields to VLANGroup

This commit is contained in:
jeremystretch
2021-12-23 11:13:28 -05:00
parent 083fda3172
commit 544d991e1e
14 changed files with 148 additions and 31 deletions

View File

@@ -46,6 +46,24 @@ class VLANGroup(OrganizationalModel):
ct_field='scope_type',
fk_field='scope_id'
)
min_vid = models.PositiveSmallIntegerField(
verbose_name='Minimum VLAN ID',
default=VLAN_VID_MIN,
validators=(
MinValueValidator(VLAN_VID_MIN),
MaxValueValidator(VLAN_VID_MAX)
),
help_text='Lowest permissible ID of a child VLAN'
)
max_vid = models.PositiveSmallIntegerField(
verbose_name='Maximum VLAN ID',
default=VLAN_VID_MAX,
validators=(
MinValueValidator(VLAN_VID_MIN),
MaxValueValidator(VLAN_VID_MAX)
),
help_text='Highest permissible ID of a child VLAN'
)
description = models.CharField(
max_length=200,
blank=True
@@ -75,24 +93,28 @@ class VLANGroup(OrganizationalModel):
if self.scope_id and not self.scope_type:
raise ValidationError("Cannot set scope_id without scope_type.")
# Validate min/max child VID limits
if self.max_vid < self.min_vid:
raise ValidationError({
'max_vid': "Maximum child VID must be greater than or equal to minimum child VID"
})
def get_available_vids(self):
"""
Return all available VLANs within this group.
"""
available_vlans = {vid for vid in range(VLAN_VID_MIN, VLAN_VID_MAX + 1)}
available_vlans = {vid for vid in range(self.min_vid, self.max_vid + 1)}
available_vlans -= set(VLAN.objects.filter(group=self).values_list('vid', flat=True))
# TODO: Check ordering
return list(available_vlans)
return sorted(available_vlans)
def get_next_available_vid(self):
"""
Return the first available VLAN ID (1-4094) in the group.
"""
vlan_ids = VLAN.objects.filter(group=self).values_list('vid', flat=True)
for i in range(1, 4095):
if i not in vlan_ids:
return i
available_vids = self.get_available_vids()
if available_vids:
return available_vids[0]
return None
@@ -122,7 +144,10 @@ class VLAN(PrimaryModel):
)
vid = models.PositiveSmallIntegerField(
verbose_name='ID',
validators=[MinValueValidator(1), MaxValueValidator(4094)]
validators=(
MinValueValidator(VLAN_VID_MIN),
MaxValueValidator(VLAN_VID_MAX)
)
)
name = models.CharField(
max_length=64
@@ -182,6 +207,13 @@ class VLAN(PrimaryModel):
f"site {self.site}."
})
# Validate group min/max VIDs
if self.group and not self.group.min_vid <= self.vid <= self.group.max_vid:
raise ValidationError({
'vid': f"VID must be between {self.group.min_vid} and {self.group.max_vid} for VLANs in group "
f"{self.group}"
})
def get_status_class(self):
return VLANStatusChoices.colors.get(self.status, 'secondary')