Browse Source

Automatically generate IP endpoints for VPN

Baptiste Jonglez 11 years ago
parent
commit
0ec09f9038
1 changed files with 21 additions and 1 deletions
  1. 21 1
      coin/vpn/models.py

+ 21 - 1
coin/vpn/models.py

@@ -1,4 +1,5 @@
 from django.db import models
+from django.core.exceptions import ValidationError
 from netfields import InetAddressField, NetManager
 from netaddr import IPAddress
 
@@ -24,11 +25,30 @@ class VPNSubscription(models.Model):
     objects = NetManager()
 
     def clean(self):
+        # TODO: this should be factored for other technologies (DSL, etc)
         subnets = self.administrative_subscription.ip_subnet.all()
+        # If saving for the first time and IP endpoints are not specified,
+        # generate them automatically.
+        if self.pk is None:
+            subnets_v4 = [s for s in subnets if s.inet.version == 4]
+            subnets_v6 = [s for s in subnets if s.inet.version == 6]
+            if self.ipv4_endpoint is None:
+                if len(subnets_v4) == 0:
+                    # TODO: should we fail silently instead?
+                    raise ValidationError('No IPv4 subnet defined, needed to choose an endpoint from')
+                self.ipv4_endpoint = subnets_v4[0].inet.ip
+            if self.ipv6_endpoint is None:
+                if len(subnets_v6) == 0:
+                    # TODO: should we fail silently instead?
+                    raise ValidationError('No IPv6 subnet defined, needed to choose an endpoint from')
+                # With v6, we choose the second host of the subnet (cafe::1)
+                gen = subnets_v6[0].inet.iter_hosts()
+                gen.next()
+                self.ipv6_endpoint = gen.next()
         # Check that the endpoints are included in one of the routed subnets
         for endpoint in [self.ipv4_endpoint, self.ipv6_endpoint]:
             if endpoint:
-                if not any([endpoint in subnet for subnet in subnets]):
+                if not any([endpoint in subnet.inet for subnet in subnets]):
                     raise ValidationError("Endpoint {} is not in an attributed range".format(endpoint))
 
     def __unicode__(self):