openwisp-ipam
openwisp-ipam copied to clipboard
[model/api] Get next available subnet
Add a way to get the next available subnet via a model method and API, similar to how we already can get the next available IP.
Hi ! I will be working on this issue.
@nemesifier I wrote this function in /openwisp_ipam/base/models.py:
def get_next_available_subnet(self):
target_prefix = self.subnet.prefixlen
if self.master_subnet:
parent_subnet = ip_network(self.master_subnet.subnet)
else:
user_subnet = ip_network(self.subnet)
new_prefix = max(user_subnet.prefixlen - 4, 0)
parent_subnet = ip_network((int(user_subnet.network_address), new_prefix))
existing_subnets = {
sub.subnet
for sub in self._meta.model.objects.all()
if ip_network(sub.subnet).subnet_of(parent_subnet)
}
for candidate_subnet in parent_subnet.subnets(new_prefix=target_prefix):
if any(candidate_subnet.overlaps(existing) for existing in existing_subnets):
continue
try:
self.subnet = candidate_subnet
self._validate_multitenant_uniqueness()
self._validate_multitenant_master_subnet()
self._validate_multitenant_unique_child_subnet()
self._validate_overlapping_subnets()
self._validate_master_subnet_consistency()
return str(candidate_subnet)
except ValidationError:
continue
return None
And I call it as follows:
def clean(self):
if not self.subnet:
return
try:
self._validate_multitenant_uniqueness()
self._validate_multitenant_master_subnet()
self._validate_multitenant_unique_child_subnet()
self._validate_overlapping_subnets()
self._validate_master_subnet_consistency()
except ValidationError as e:
# Try getting next available subnet
next_subnet = self.get_next_available_subnet()
if next_subnet:
self.subnet = next_subnet
else:
raise e
So if 10.0.0.0/24 exists in DB.
- It will work for 10.0.0.0/0-23 (All parent subnets)
- It will work for exact match /24
- It works for up to 2 children subnets /25 and /26. Because I hardcoded the parent subnet.
And currenty it directly saves the next available subnet instead of autofilling and then prompting the user like in add IP address. Which can be fixed after the core logic is decided.
I would like to discuss this further. Especially ideas on how to not hardcode the parent subnet.