From 9bf761c88c3c320bc93b235070033ad1b6ba2b17 Mon Sep 17 00:00:00 2001 From: Nicolas Froger <nico@cri.epita.fr> Date: Tue, 26 Sep 2023 00:15:03 +0200 Subject: [PATCH] fleet: make DHCP pools togglable Signed-off-by: Nicolas Froger <nico@cri.epita.fr> --- fleet/admin.py | 1 + fleet/migrations/0016_auto_20230926_0014.py | 32 ++++++++ fleet/models/__init__.py | 85 +++++++++++++++------ fleet/views.py | 20 +++-- 4 files changed, 109 insertions(+), 29 deletions(-) create mode 100644 fleet/migrations/0016_auto_20230926_0014.py diff --git a/fleet/admin.py b/fleet/admin.py index 7a1496d..50131be 100644 --- a/fleet/admin.py +++ b/fleet/admin.py @@ -29,6 +29,7 @@ class DhcpSubnetAdmin(admin.ModelAdmin): list_display = ("subnet", "router", "allocation_pool_start", "allocation_pool_end") list_display_links = list_display search_fields = list_display + list_filter = ("enable_pool",) class ExtraTxtRecordRoomInline(admin.TabularInline): diff --git a/fleet/migrations/0016_auto_20230926_0014.py b/fleet/migrations/0016_auto_20230926_0014.py new file mode 100644 index 0000000..351bf81 --- /dev/null +++ b/fleet/migrations/0016_auto_20230926_0014.py @@ -0,0 +1,32 @@ +# Generated by Django 3.2.19 on 2023-09-25 22:14 + +from django.db import migrations, models +import netfields.fields + + +class Migration(migrations.Migration): + dependencies = [ + ("fleet", "0015_extratxtrecordroom_extratxtrecordsite"), + ] + + operations = [ + migrations.AddField( + model_name="dhcpsubnet", + name="enable_pool", + field=models.BooleanField(default=False), + ), + migrations.AlterField( + model_name="dhcpsubnet", + name="allocation_pool_end", + field=netfields.fields.InetAddressField( + blank=True, max_length=39, null=True + ), + ), + migrations.AlterField( + model_name="dhcpsubnet", + name="allocation_pool_start", + field=netfields.fields.InetAddressField( + blank=True, max_length=39, null=True + ), + ), + ] diff --git a/fleet/models/__init__.py b/fleet/models/__init__.py index 8105c78..d8d8bda 100644 --- a/fleet/models/__init__.py +++ b/fleet/models/__init__.py @@ -35,8 +35,14 @@ class DhcpSubnet(models.Model): router = InetAddressField(store_prefix_length=False) - allocation_pool_start = InetAddressField(store_prefix_length=False) - allocation_pool_end = InetAddressField(store_prefix_length=False) + allocation_pool_start = InetAddressField( + store_prefix_length=False, blank=True, null=True + ) + allocation_pool_end = InetAddressField( + store_prefix_length=False, blank=True, null=True + ) + + enable_pool = models.BooleanField(default=False) objects = NetManager() @@ -44,34 +50,69 @@ class DhcpSubnet(models.Model): return str(self.subnet) def clean(self): - if ( - not self.allocation_pool_start # pylint:disable=unneeded-not # noqa: E501 - < self.allocation_pool_end - ): - raise ValidationError( - { - "allocation_pool_start": "allocation_pool_start should be before allocation_pool_end", # noqa: E501 - "allocation_pool_end": "allocation_pool_end should be after allocation_pool_start", # noqa: E501 - } - ) - if ( - self.allocation_pool_start - not in self.subnet # pylint:disable=unsupported-membership-test # noqa: E501 - ): + if self.allocation_pool_start and not self.allocation_pool_end: raise ValidationError( { - "allocation_pool_start": f"allocation_pool_start should be in subnet {self.subnet}", # noqa: E501 + "allocation_pool_end": "allocation_pool_end must be set if allocation_pool_start is set" } ) - if ( - self.allocation_pool_end - not in self.subnet # pylint:disable=unsupported-membership-test # noqa: E501 - ): + if not self.allocation_pool_start and self.allocation_pool_end: raise ValidationError( { - "allocation_pool_end": f"allocation_pool_end should be in subnet {self.subnet}", # noqa: E501 + "allocation_pool_start": "allocation_pool_start must be set if allocation_pool_end is set" } ) + + if self.enable_pool: + if not self.allocation_pool_start and not self.allocation_pool_end: + raise ValidationError( + { + "allocation_pool_start": "allocation_pool_start must be set if enable_pool is True", + "allocation_pool_end": "allocation_pool_end must be set if enable_pool is True", + } + ) + if not self.allocation_pool_start: + raise ValidationError( + { + "allocation_pool_start": "allocation_pool_start must be set if enable_pool is True", + } + ) + if not self.allocation_pool_end: + raise ValidationError( + { + "allocation_pool_end": "allocation_pool_end must be set if enable_pool is True", + } + ) + + if self.allocation_pool_start and self.allocation_pool_end: + if ( + not self.allocation_pool_start # pylint:disable=unneeded-not # noqa: E501 + < self.allocation_pool_end + ): + raise ValidationError( + { + "allocation_pool_start": "allocation_pool_start should be before allocation_pool_end", # noqa: E501 + "allocation_pool_end": "allocation_pool_end should be after allocation_pool_start", # noqa: E501 + } + ) + if ( + self.allocation_pool_start + not in self.subnet # pylint:disable=unsupported-membership-test # noqa: E501 + ): + raise ValidationError( + { + "allocation_pool_start": f"allocation_pool_start should be in subnet {self.subnet}", # noqa: E501 + } + ) + if ( + self.allocation_pool_end + not in self.subnet # pylint:disable=unsupported-membership-test # noqa: E501 + ): + raise ValidationError( + { + "allocation_pool_end": f"allocation_pool_end should be in subnet {self.subnet}", # noqa: E501 + } + ) if ( self.router not in self.subnet # pylint:disable=unsupported-membership-test # noqa: E501 diff --git a/fleet/views.py b/fleet/views.py index c86a940..b71805e 100644 --- a/fleet/views.py +++ b/fleet/views.py @@ -143,12 +143,6 @@ class DhcpConfigDiscovery(View): lambda subnet: { "id": subnet.id, "subnet": str(subnet.subnet), - "pools": [ - { - "pool": f"{subnet.allocation_pool_start} - {subnet.allocation_pool_end}" - # noqa: E501 - } - ], "option-data": [ { "name": "domain-name", @@ -176,7 +170,19 @@ class DhcpConfigDiscovery(View): ).select_related("machine") if hasattr(workstation, "machine") ], - }, + } + | ( + { + "pools": [ + { + "pool": f"{subnet.allocation_pool_start} - {subnet.allocation_pool_end}" + # noqa: E501 + } + ], + } + if subnet.enable_pool + else {} + ), DhcpSubnet.objects.all(), ) ), -- GitLab