Update utilized/reserved logic for Prefix and IPRange

This commit is contained in:
Jeremy Stretch 2025-04-02 09:35:21 -04:00
parent 67615368b2
commit 5f548725ee

View File

@ -407,15 +407,16 @@ 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.
""" """
if self.mark_utilized: # TODO: Add mark_reserved
return netaddr.IPSet()
prefix = netaddr.IPSet(self.prefix) prefix = netaddr.IPSet(self.prefix)
child_ips = netaddr.IPSet([ip.address.ip for ip in self.get_child_ips()]) child_ips = netaddr.IPSet([
child_ranges = [] ip.address.ip for ip in self.get_child_ips()
for iprange in self.get_child_ranges(): ])
child_ranges.append(iprange.range) child_ranges = netaddr.IPSet([
available_ips = prefix - child_ips - netaddr.IPSet(child_ranges) iprange.range for iprange in self.get_child_ranges().filter(mark_reserved=True)
])
available_ips = prefix - child_ips - child_ranges
# IPv6 /127's, pool, or IPv4 /31-/32 sets are fully usable # IPv6 /127's, pool, or IPv4 /31-/32 sets are fully usable
if (self.family == 6 and self.prefix.prefixlen >= 127) or self.is_pool or ( if (self.family == 6 and self.prefix.prefixlen >= 127) or self.is_pool or (
@ -433,6 +434,7 @@ class Prefix(ContactsMixin, GetAvailablePrefixesMixin, CachedScopeMixin, Primary
# For IPv6 prefixes, omit the Subnet-Router anycast address # For IPv6 prefixes, omit the Subnet-Router anycast address
# per RFC 4291 # per RFC 4291
available_ips -= netaddr.IPSet([netaddr.IPAddress(self.prefix.first)]) available_ips -= netaddr.IPSet([netaddr.IPAddress(self.prefix.first)])
return available_ips return available_ips
def get_first_available_ip(self): def get_first_available_ip(self):
@ -461,9 +463,11 @@ class Prefix(ContactsMixin, GetAvailablePrefixesMixin, CachedScopeMixin, Primary
utilization = float(child_prefixes.size) / self.prefix.size * 100 utilization = float(child_prefixes.size) / self.prefix.size * 100
else: else:
# Compile an IPSet to avoid counting duplicate IPs # Compile an IPSet to avoid counting duplicate IPs
child_ips = netaddr.IPSet( child_ips = netaddr.IPSet()
[_.range for _ in self.get_child_ranges()] + [_.address.ip for _ in self.get_child_ips()] for iprange in self.get_child_ranges().filter(mark_utilized=True):
) child_ips.add(iprange.range)
for ip in self.get_child_ips():
child_ips.add(ip.address.ip)
prefix_size = self.prefix.size prefix_size = self.prefix.size
if self.prefix.version == 4 and self.prefix.prefixlen < 31 and not self.is_pool: if self.prefix.version == 4 and self.prefix.prefixlen < 31 and not self.is_pool:
@ -668,6 +672,9 @@ class IPRange(ContactsMixin, PrimaryModel):
""" """
Return all available IPs within this range as an IPSet. Return all available IPs within this range as an IPSet.
""" """
if self.mark_reserved:
return netaddr.IPSet()
range = netaddr.IPRange(self.start_address.ip, self.end_address.ip) range = netaddr.IPRange(self.start_address.ip, self.end_address.ip)
child_ips = netaddr.IPSet([ip.address.ip for ip in self.get_child_ips()]) child_ips = netaddr.IPSet([ip.address.ip for ip in self.get_child_ips()])