|
@@ -4,18 +4,8 @@ from __future__ import unicode_literals
|
|
|
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
|
|
|
-
|
|
|
-
|
|
|
-def validate_subnet(cidr):
|
|
|
- """Checks that a CIDR object is indeed a subnet, i.e. the host bits are
|
|
|
- all set to zero."""
|
|
|
- if not isinstance(cidr, IPNetwork):
|
|
|
- raise ValidationError("Erreur, objet IPNetwork attendu.")
|
|
|
- if cidr.ip != cidr.network:
|
|
|
- raise ValidationError("{} n'est pas un sous-réseau valide, voulez-vous dire {} ?".format(cidr, cidr.cidr))
|
|
|
+from netaddr import IPSet
|
|
|
|
|
|
|
|
|
class IPPool(models.Model):
|
|
@@ -27,8 +17,7 @@ class IPPool(models.Model):
|
|
|
verbose_name='taille de sous-réseau par défaut',
|
|
|
help_text='Taille par défaut du sous-réseau à allouer aux abonnés dans ce pool',
|
|
|
validators=[MaxValueValidator(64)])
|
|
|
- inet = CidrAddressField(validators=[validate_subnet],
|
|
|
- verbose_name='réseau',
|
|
|
+ inet = CidrAddressField(verbose_name='réseau',
|
|
|
help_text="Bloc d'adresses IP du pool")
|
|
|
objects = NetManager()
|
|
|
|
|
@@ -55,7 +44,7 @@ class IPPool(models.Model):
|
|
|
|
|
|
|
|
|
class IPSubnet(models.Model):
|
|
|
- inet = CidrAddressField(blank=True, validators=[validate_subnet],
|
|
|
+ inet = CidrAddressField(blank=True,
|
|
|
unique=True, verbose_name="sous-réseau",
|
|
|
help_text="Laisser vide pour allouer automatiquement")
|
|
|
objects = NetManager()
|
|
@@ -95,9 +84,18 @@ class IPSubnet(models.Model):
|
|
|
if not self.inet in self.ip_pool.inet:
|
|
|
raise ValidationError("Le sous-réseau doit être inclus dans le bloc d'IP.")
|
|
|
# Check that we don't conflict with existing subnets.
|
|
|
- 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:
|
|
|
+
|
|
|
+ # The optimal request would be the following commented request, but
|
|
|
+ # django-netfields 0.4.x seems buggy with Q-expressions. For now use
|
|
|
+ # two requests, but the optimal solution will have to be retried once
|
|
|
+ # we use django-netfields>=0.7
|
|
|
+
|
|
|
+ #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)
|
|
|
+ conflicting_contained = self.ip_pool.ipsubnet_set.filter(inet__net_contained_or_equal=self.inet).exclude(id=self.id)
|
|
|
+ conflicting_containing = self.ip_pool.ipsubnet_set.filter(inet__net_contains_or_equals=self.inet).exclude(id=self.id)
|
|
|
+ if conflicting_contained or conflicting_containing:
|
|
|
+ conflicting = conflicting_contained if conflicting_contained else conflicting_containing
|
|
|
raise ValidationError("Le sous-réseau est en conflit avec des sous-réseaux existants: {}.".format(conflicting))
|
|
|
|
|
|
def validate_reverse_dns(self):
|