Browse Source

Refactor the generation and check of IP endpoints for VPN

Baptiste Jonglez 11 years ago
parent
commit
654188a891
1 changed files with 29 additions and 11 deletions
  1. 29 11
      coin/vpn/models.py

+ 29 - 11
coin/vpn/models.py

@@ -88,29 +88,47 @@ class VPNSubscription(CoinLdapSyncModel):
     def delete_from_ldap(self):
         LdapVPNConfig.objects.get(pk=self.login).delete()
 
-    def clean(self):
-        # Hash password if needed
-        self.password = utils.ldap_hash(self.password)
-        # TODO: this should be factored for other technologies (DSL, etc)
+    def generate_endpoints(self, v4=True, v6=True):
+        """Generate IP endpoints in one of the attributed IP subnets.  If there is
+        no available subnet for a given address family, then no endpoint
+        is generated for this address family.  If there already is an
+        endpoint, do nothing.
+
+        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:
+        if v4 and self.ipv4_endpoint 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 and len(subnets_v4) > 0:
+            if len(subnets_v4) > 0:
                 self.ipv4_endpoint = subnets_v4[0].inet.ip
-            if self.ipv6_endpoint is None and len(subnets_v6) > 0:
+        if v6 and self.ipv6_endpoint is None:
+            subnets_v6 = [s for s in subnets if s.inet.version == 6]
+            if len(subnets_v6) > 0:
                 # 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
+
+    def check_endpoints(self):
+        """Check that the IP endpoints are included in one of the attributed IP
+        subnets.
+        """
+        subnets = self.administrative_subscription.ip_subnet.all()
         for endpoint in [self.ipv4_endpoint, self.ipv6_endpoint]:
             if endpoint:
                 if not any([endpoint in subnet.inet for subnet in subnets]):
                     raise ValidationError("Endpoint {} is not in an attributed range".format(endpoint))
 
+    def clean(self):
+        # Hash password if needed
+        self.password = utils.ldap_hash(self.password)
+        # If saving for the first time and IP endpoints are not specified,
+        # generate them automatically.
+        if self.pk is None:
+            self.generate_endpoints()
+        self.check_endpoints()
+
     def __unicode__(self):
         return 'VPN ' + self.login