|
@@ -2,6 +2,7 @@
|
|
|
from django.db import models
|
|
|
from django.core.exceptions import ValidationError
|
|
|
from django.core.validators import MaxValueValidator
|
|
|
+from django.db.models import Q
|
|
|
from netfields import CidrAddressField, NetManager
|
|
|
from netaddr import IPNetwork, IPSet
|
|
|
|
|
@@ -73,12 +74,10 @@ class IPSubnet(models.Model):
|
|
|
if not self.inet in self.ip_pool.inet:
|
|
|
raise ValidationError('Subnet must be included in the IP pool.')
|
|
|
# Check that we don't conflict with existing subnets.
|
|
|
- # TODO: use precise database query instead of querying all
|
|
|
- # subnets and filtering in Python.
|
|
|
- existing = IPSet((s.inet for s in self.ip_pool.ipsubnet_set.all()))
|
|
|
- intersection = IPSet([self.inet]).intersection(existing)
|
|
|
- if intersection.size:
|
|
|
- raise ValidationError('Subnet must not intersect with existing subnets.\nIntersected subnets: {}.'.format([str(p) for p in intersection.iter_cidrs()]))
|
|
|
+ conflicting = self.ip_pool.ipsubnet_set.filter(Q(inet__net_contained_or_equal=self.inet) |
|
|
|
+ Q(inet__net_contains_or_equals=self.inet)).exclude(id=self.id)
|
|
|
+ if conflicting:
|
|
|
+ raise ValidationError('Subnet must not intersect with existing subnets.\nIntersected subnets: {}.'.format(conflicting))
|
|
|
|
|
|
def __unicode__(self):
|
|
|
return str(self.inet)
|