From 378a314f2cefed79ad6c5ea1161a1418031826b6 Mon Sep 17 00:00:00 2001 From: Peter Eckel Date: Wed, 18 Mar 2026 17:21:13 +0100 Subject: [PATCH] Modified PoolImportForm so ip_range can be specified using [vrf,]start_address --- netbox_dhcp/forms/pool.py | 27 ++++++++++++++++++++++----- netbox_dhcp/models/pool.py | 3 +++ netbox_dhcp/tests/pool/test_views.py | 16 ++++++++-------- 3 files changed, 33 insertions(+), 13 deletions(-) diff --git a/netbox_dhcp/forms/pool.py b/netbox_dhcp/forms/pool.py index d442833..5f3aaad 100644 --- a/netbox_dhcp/forms/pool.py +++ b/netbox_dhcp/forms/pool.py @@ -15,7 +15,7 @@ ) from utilities.forms import add_blank_choice, get_field_value from utilities.forms.rendering import FieldSet -from ipam.models import IPRange, Prefix +from ipam.models import IPRange, Prefix, VRF from ipam.choices import IPAddressFamilyChoices from netbox_dhcp.models import Pool @@ -192,6 +192,7 @@ class Meta: "description", "weight", *SubnetImportFormMixin.FIELDS, + "vrf", "ip_range", *ClientClassesImportFormMixin.FIELDS, *EvaluateClientClassesImportFormMixin.FIELDS, @@ -200,16 +201,32 @@ class Meta: "tags", ) - # TODO: Specify IP ranges by (start_address,end_address) + vrf = CSVModelChoiceField( + queryset=VRF.objects.all(), + to_field_name="name", + required=False, + label=_("IP Range VRF"), + ) ip_range = CSVModelChoiceField( queryset=IPRange.objects.all(), - required=True, + to_field_name="start_address", + required=False, error_messages={ - "invalid_choice": _("IP range %(value)s not found"), + "invalid_choice": _("IP range with start address %(value)s not found"), }, - label=_("IP Range"), + label=_("IP Range Start Address"), ) + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + self.fields["weight"].required = False + + if self.is_bound and "vrf" in self.data: + self.fields["ip_range"].queryset = self.fields["ip_range"].queryset.filter( + vrf=self.data["vrf"] + ) + class PoolBulkEditForm( SubnetBulkEditFormMixin, diff --git a/netbox_dhcp/models/pool.py b/netbox_dhcp/models/pool.py index d312fb0..61b3ce5 100644 --- a/netbox_dhcp/models/pool.py +++ b/netbox_dhcp/models/pool.py @@ -104,6 +104,9 @@ def dhcp_server(self): return self.subnet.dhcp_server def clean(self): + if self.weight is None: + self.weight = 100 + super().clean() ip_range = self.ip_range.range diff --git a/netbox_dhcp/tests/pool/test_views.py b/netbox_dhcp/tests/pool/test_views.py index 179a546..ad0448f 100644 --- a/netbox_dhcp/tests/pool/test_views.py +++ b/netbox_dhcp/tests/pool/test_views.py @@ -84,14 +84,14 @@ def setUpTestData(cls): cls.csv_data = ( "name,description,weight,subnet,ip_range,client_classes,evaluate_additional_classes", # noqa: E501 - f'test-pool-6,Test Pool 6,100,{ipv4_subnets[0].name},{ipv4_ranges[0].pk},"{client_classes[0].name},{client_classes[1].name}","{client_classes[1].name},{client_classes[2].name}"', # noqa: E501 - f'test-pool-7,Test Pool 7,23,{ipv4_subnets[1].name},{ipv4_ranges[1].pk},"{client_classes[0].name},{client_classes[1].name}","{client_classes[1].name},{client_classes[2].name}"', # noqa: E501 + f'test-pool-6,Test Pool 6,,{ipv4_subnets[0].name},{ipv4_ranges[0].start_address},"{client_classes[0].name},{client_classes[1].name}","{client_classes[1].name},{client_classes[2].name}"', # noqa: E501 + f'test-pool-7,Test Pool 7,23,{ipv4_subnets[1].name},{ipv4_ranges[1].start_address},"{client_classes[0].name},{client_classes[1].name}","{client_classes[1].name},{client_classes[2].name}"', # noqa: E501 ) cls.csv_update_data = ( "id,description,weight,ip_range,client_classes,evaluate_additional_classes", # noqa: E501 - f'{pools[0].pk},Test Pool 1 (updated),42,{ipv4_ranges[0].pk},"{client_classes[0].name},{client_classes[1].name}","{client_classes[1].name},{client_classes[2].name}"', # noqa: E501 - f'{pools[1].pk},Test Pool 2 (updated),23,{ipv4_ranges[1].pk},"{client_classes[0].name},{client_classes[1].name}","{client_classes[1].name},{client_classes[2].name}"', # noqa: E501 + f'{pools[0].pk},Test Pool 1 (updated),42,{ipv4_ranges[0].start_address},"{client_classes[0].name},{client_classes[1].name}","{client_classes[1].name},{client_classes[2].name}"', # noqa: E501 + f'{pools[1].pk},Test Pool 2 (updated),23,{ipv4_ranges[1].start_address},"{client_classes[0].name},{client_classes[1].name}","{client_classes[1].name},{client_classes[2].name}"', # noqa: E501 ) maxDiff = None @@ -177,14 +177,14 @@ def setUpTestData(cls): cls.csv_data = ( "name,description,weight,subnet,ip_range,client_classes,evaluate_additional_classes", # noqa: E501 - f'test-pool-6,Test Pool 6,100,{ipv6_subnets[1].name},{ipv6_ranges[0].pk},"{client_classes[0].name},{client_classes[1].name}","{client_classes[1].name},{client_classes[2].name}"', # noqa: E501 - f'test-pool-7,Test Pool 7,23,{ipv6_subnets[1].name},{ipv6_ranges[1].pk},"{client_classes[0].name},{client_classes[1].name}","{client_classes[1].name},{client_classes[2].name}"', # noqa: E501 + f'test-pool-6,Test Pool 6,100,{ipv6_subnets[1].name},{ipv6_ranges[0].start_address},"{client_classes[0].name},{client_classes[1].name}","{client_classes[1].name},{client_classes[2].name}"', # noqa: E501 + f'test-pool-7,Test Pool 7,23,{ipv6_subnets[1].name},{ipv6_ranges[1].start_address},"{client_classes[0].name},{client_classes[1].name}","{client_classes[1].name},{client_classes[2].name}"', # noqa: E501 ) cls.csv_update_data = ( "id,description,weight,ip_range,client_classes,evaluate_additional_classes", # noqa: E501 - f'{pools[0].pk},Test Pool 1 (updated),42,{ipv6_ranges[0].pk},"{client_classes[0].name},{client_classes[1].name}","{client_classes[1].name},{client_classes[2].name}"', # noqa: E501 - f'{pools[1].pk},Test Pool 2 (updated),23,{ipv6_ranges[1].pk},"{client_classes[0].name},{client_classes[1].name}","{client_classes[1].name},{client_classes[2].name}"', # noqa: E501 + f'{pools[0].pk},Test Pool 1 (updated),42,{ipv6_ranges[0].start_address},"{client_classes[0].name},{client_classes[1].name}","{client_classes[1].name},{client_classes[2].name}"', # noqa: E501 + f'{pools[1].pk},Test Pool 2 (updated),23,{ipv6_ranges[1].start_address},"{client_classes[0].name},{client_classes[1].name}","{client_classes[1].name},{client_classes[2].name}"', # noqa: E501 ) maxDiff = None