Prohibit creating an IP address within a populated range

This commit is contained in:
Jeremy Stretch 2025-04-02 15:01:20 -04:00
parent 5fd229bd1d
commit 70f5914469
2 changed files with 35 additions and 2 deletions

View File

@ -408,8 +408,6 @@ class Prefix(ContactsMixin, GetAvailablePrefixesMixin, CachedScopeMixin, Primary
""" """
Return all available IPs within this prefix as an IPSet. Return all available IPs within this prefix as an IPSet.
""" """
# TODO: Add mark_populated
prefix = netaddr.IPSet(self.prefix) prefix = netaddr.IPSet(self.prefix)
child_ips = netaddr.IPSet([ child_ips = netaddr.IPSet([
ip.address.ip for ip in self.get_child_ips() ip.address.ip for ip in self.get_child_ips()
@ -889,6 +887,20 @@ class IPAddress(ContactsMixin, PrimaryModel):
) )
}) })
# Disallow the creation of IPAddresses within an IPRange with mark_populated=True
parent_range = IPRange.objects.filter(
start_address__lte=self.address,
end_address__gte=self.address,
vrf=self.vrf,
mark_populated=True
).first()
if parent_range:
raise ValidationError({
'address': _(
"Cannot create IP address {ip} inside range {range}."
).format(ip=self.address, range=parent_range)
})
if self._original_assigned_object_id and self._original_assigned_object_type_id: if self._original_assigned_object_id and self._original_assigned_object_type_id:
parent = getattr(self.assigned_object, 'parent_object', None) parent = getattr(self.assigned_object, 'parent_object', None)
ct = ObjectType.objects.get_for_id(self._original_assigned_object_type_id) ct = ObjectType.objects.get_for_id(self._original_assigned_object_type_id)

View File

@ -582,6 +582,27 @@ class TestIPAddress(TestCase):
IPAddress.objects.create(address=IPNetwork('192.0.2.1/24'), role=IPAddressRoleChoices.ROLE_VIP) IPAddress.objects.create(address=IPNetwork('192.0.2.1/24'), role=IPAddressRoleChoices.ROLE_VIP)
IPAddress.objects.create(address=IPNetwork('192.0.2.1/24'), role=IPAddressRoleChoices.ROLE_VIP) IPAddress.objects.create(address=IPNetwork('192.0.2.1/24'), role=IPAddressRoleChoices.ROLE_VIP)
#
# Range validation
#
def test_create_ip_in_unpopulated_range(self):
IPRange.objects.create(
start_address=IPNetwork('192.0.2.1/24'),
end_address=IPNetwork('192.0.2.100/24')
)
ip = IPAddress(address=IPNetwork('192.0.2.10/24'))
ip.full_clean()
def test_create_ip_in_populated_range(self):
IPRange.objects.create(
start_address=IPNetwork('192.0.2.1/24'),
end_address=IPNetwork('192.0.2.100/24'),
mark_populated=True
)
ip = IPAddress(address=IPNetwork('192.0.2.10/24'))
self.assertRaises(ValidationError, ip.full_clean)
class TestVLANGroup(TestCase): class TestVLANGroup(TestCase):