From f509ca4e5ea3d01f23a62f5f45e4cc9c1b6bff36 Mon Sep 17 00:00:00 2001 From: Arthur Hanson Date: Fri, 21 Jun 2024 14:14:42 -0700 Subject: [PATCH] 9627 test fixes --- netbox/ipam/forms/bulk_edit.py | 4 +++- netbox/ipam/forms/bulk_import.py | 4 +++- netbox/ipam/forms/filtersets.py | 1 - .../0070_vlangroup_vlan_id_ranges.py | 8 ++++++- netbox/ipam/models/vlans.py | 24 ++++++++++++++----- netbox/ipam/tests/test_api.py | 4 ++-- netbox/ipam/tests/test_models.py | 4 ++-- netbox/ipam/tests/test_views.py | 4 ++-- netbox/utilities/data.py | 1 + netbox/utilities/forms/fields/array.py | 1 - 10 files changed, 38 insertions(+), 17 deletions(-) diff --git a/netbox/ipam/forms/bulk_edit.py b/netbox/ipam/forms/bulk_edit.py index 745a54d6d..e543beea4 100644 --- a/netbox/ipam/forms/bulk_edit.py +++ b/netbox/ipam/forms/bulk_edit.py @@ -472,7 +472,9 @@ class VLANGroupBulkEditForm(NetBoxModelBulkEditForm): 'group_id': '$clustergroup', } ) - vlan_id_ranges = NumericRangeArrayField() + vlan_id_ranges = NumericRangeArrayField( + required=False, + ) model = VLANGroup fieldsets = ( diff --git a/netbox/ipam/forms/bulk_import.py b/netbox/ipam/forms/bulk_import.py index e2362c4ed..c50f194e8 100644 --- a/netbox/ipam/forms/bulk_import.py +++ b/netbox/ipam/forms/bulk_import.py @@ -412,7 +412,9 @@ class VLANGroupImportForm(NetBoxModelImportForm): required=False, label=_('Scope type (app & model)') ) - vlan_id_ranges = NumericRangeArrayField() + vlan_id_ranges = NumericRangeArrayField( + required=False, + ) class Meta: model = VLANGroup diff --git a/netbox/ipam/forms/filtersets.py b/netbox/ipam/forms/filtersets.py index 36aae3774..6016d8506 100644 --- a/netbox/ipam/forms/filtersets.py +++ b/netbox/ipam/forms/filtersets.py @@ -413,7 +413,6 @@ class VLANGroupFilterForm(NetBoxModelFilterSetForm): FieldSet('q', 'filter_id', 'tag'), FieldSet('region', 'sitegroup', 'site', 'location', 'rack', name=_('Location')), FieldSet('cluster_group', 'cluster', name=_('Cluster')), - # FieldSet('min_vid', 'max_vid', name=_('VLAN ID')), ) model = VLANGroup region = DynamicModelMultipleChoiceField( diff --git a/netbox/ipam/migrations/0070_vlangroup_vlan_id_ranges.py b/netbox/ipam/migrations/0070_vlangroup_vlan_id_ranges.py index 65bf1db18..b251e1693 100644 --- a/netbox/ipam/migrations/0070_vlangroup_vlan_id_ranges.py +++ b/netbox/ipam/migrations/0070_vlangroup_vlan_id_ranges.py @@ -4,6 +4,8 @@ import django.contrib.postgres.fields import django.contrib.postgres.fields.ranges from django.db import migrations, models from django.db.backends.postgresql.psycopg_any import NumericRange +from ipam.constants import VLAN_VID_MIN, VLAN_VID_MAX +import ipam.models.vlans def move_min_max(apps, schema_editor): @@ -29,7 +31,11 @@ class Migration(migrations.Migration): migrations.AddField( model_name='vlangroup', name='vlan_id_ranges', - field=django.contrib.postgres.fields.ArrayField(base_field=django.contrib.postgres.fields.ranges.BigIntegerRangeField(), blank=True, null=True, size=None), + field=django.contrib.postgres.fields.ArrayField( + base_field=django.contrib.postgres.fields.ranges.BigIntegerRangeField(), + blank=True, null=True, size=None, + default=ipam.models.vlans.get_default_vlan_ids, + ), ), migrations.AddField( model_name='vlangroup', diff --git a/netbox/ipam/models/vlans.py b/netbox/ipam/models/vlans.py index 7acbf8064..44d81ecef 100644 --- a/netbox/ipam/models/vlans.py +++ b/netbox/ipam/models/vlans.py @@ -3,6 +3,7 @@ from django.contrib.postgres.fields import ArrayField, BigIntegerRangeField from django.core.exceptions import ValidationError from django.core.validators import MaxValueValidator, MinValueValidator from django.db import models +from django.db.backends.postgresql.psycopg_any import NumericRange from django.urls import reverse from django.utils.translation import gettext_lazy as _ @@ -20,6 +21,10 @@ __all__ = ( ) +def get_default_vlan_ids(): + return [NumericRange(VLAN_VID_MIN, VLAN_VID_MAX)] + + class VLANGroup(OrganizationalModel): """ A VLAN group is an arbitrary collection of VLANs within which VLAN IDs and names must be unique. @@ -50,6 +55,7 @@ class VLANGroup(OrganizationalModel): vlan_id_ranges = ArrayField( BigIntegerRangeField(), verbose_name=_('min/max VLAN IDs'), + default=get_default_vlan_ids, help_text=_('Ranges of Minimum, maximum VLAN IDs'), blank=True, null=True @@ -237,12 +243,18 @@ class VLAN(PrimaryModel): ) # Validate group min/max VIDs - if self.group and not self.group.min_vid <= self.vid <= self.group.max_vid: - raise ValidationError({ - 'vid': _( - "VID must be between {minimum} and {maximum} for VLANs in group {group}" - ).format(minimum=self.group.min_vid, maximum=self.group.max_vid, group=self.group) - }) + if self.group and self.group.vlan_id_ranges: + in_bounds = False + for ranges in self.group.vlan_id_ranges: + if ranges.lower <= self.vid <= ranges.upper: + in_bounds = True + + if not in_bounds: + raise ValidationError({ + 'vid': _( + "VID must be in ranges {ranges} for VLANs in group {group}" + ).format(ranges=ranges_to_string(self.group.vlan_id_ranges), group=self.group) + }) def get_status_color(self): return VLANStatusChoices.colors.get(self.status) diff --git a/netbox/ipam/tests/test_api.py b/netbox/ipam/tests/test_api.py index 2cf7a2f1c..b6bc0e5e8 100644 --- a/netbox/ipam/tests/test_api.py +++ b/netbox/ipam/tests/test_api.py @@ -8,6 +8,7 @@ from dcim.models import Device, DeviceRole, DeviceType, Interface, Manufacturer, from ipam.choices import * from ipam.models import * from tenancy.models import Tenant +from utilities.data import string_to_range_array from utilities.testing import APITestCase, APIViewTestCases, create_test_device, disable_warnings @@ -882,8 +883,7 @@ class VLANGroupTest(APIViewTestCases.APIViewTestCase): vlangroup = VLANGroup.objects.create( name='VLAN Group X', slug='vlan-group-x', - min_vid=MIN_VID, - max_vid=MAX_VID + vlan_range_ids=string_to_range_array(f"{MIN_VID}-{MAX_VID}") ) # Create a set of VLANs within the group diff --git a/netbox/ipam/tests/test_models.py b/netbox/ipam/tests/test_models.py index d0f42e8a6..0d2a147d3 100644 --- a/netbox/ipam/tests/test_models.py +++ b/netbox/ipam/tests/test_models.py @@ -1,6 +1,7 @@ from django.core.exceptions import ValidationError from django.test import TestCase, override_settings from netaddr import IPNetwork, IPSet +from utilities.data import string_to_range_array from ipam.choices import * from ipam.models import * @@ -509,8 +510,7 @@ class TestVLANGroup(TestCase): vlangroup = VLANGroup.objects.create( name='VLAN Group 1', slug='vlan-group-1', - min_vid=100, - max_vid=199 + vlan_range_ids=string_to_range_array('100-199'), ) VLAN.objects.bulk_create(( VLAN(name='VLAN 100', vid=100, group=vlangroup), diff --git a/netbox/ipam/tests/test_views.py b/netbox/ipam/tests/test_views.py index bc42341ba..bd5a19c2f 100644 --- a/netbox/ipam/tests/test_views.py +++ b/netbox/ipam/tests/test_views.py @@ -9,6 +9,7 @@ from dcim.models import Device, DeviceRole, DeviceType, Manufacturer, Site, Inte from ipam.choices import * from ipam.models import * from tenancy.models import Tenant +from utilities.data import string_to_range_array from utilities.testing import ViewTestCases, create_tags @@ -764,8 +765,7 @@ class VLANGroupTestCase(ViewTestCases.OrganizationalObjectViewTestCase): cls.form_data = { 'name': 'VLAN Group X', 'slug': 'vlan-group-x', - 'min_vid': 1, - 'max_vid': 4094, + 'vlan_range_ids': string_to_range_array('100-4094'), 'description': 'A new VLAN group', 'tags': [t.pk for t in tags], } diff --git a/netbox/utilities/data.py b/netbox/utilities/data.py index d6f4a0275..04d6c8210 100644 --- a/netbox/utilities/data.py +++ b/netbox/utilities/data.py @@ -1,4 +1,5 @@ import decimal +from django.db.backends.postgresql.psycopg_any import NumericRange from itertools import count, groupby __all__ = ( diff --git a/netbox/utilities/forms/fields/array.py b/netbox/utilities/forms/fields/array.py index cb56dfb2c..d7a0fece2 100644 --- a/netbox/utilities/forms/fields/array.py +++ b/netbox/utilities/forms/fields/array.py @@ -1,6 +1,5 @@ from django import forms from django.contrib.postgres.forms import SimpleArrayField -from django.db.backends.postgresql.psycopg_any import NumericRange from django.utils.translation import gettext_lazy as _ from utilities.data import ranges_to_string, string_to_range_array