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:
@@ -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')
|
||||
|
||||
|
Reference in New Issue
Block a user