From f35814ccf48e0f90e54d55377c90ff80bfb340cc Mon Sep 17 00:00:00 2001 From: Scott Baker Date: Fri, 26 Jul 2013 18:15:42 -0700 Subject: [PATCH] allocate subnets and networks automatically --- planetstack/core/models/network.py | 37 ++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/planetstack/core/models/network.py b/planetstack/core/models/network.py index 1ea7115..8819179 100644 --- a/planetstack/core/models/network.py +++ b/planetstack/core/models/network.py @@ -11,17 +11,37 @@ SUBNET_BASE = "10.0.0.0" SUBNET_NODE_BITS = 12 # enough for 4096 bits per subnet SUBNET_SUBNET_BITS = 12 # enough for 4096 private networks +def ip_to_int(ip): + return int(socket.inet_aton(ip).encode('hex'),16) + +def int_to_ip(i): + return socket.inet_ntoa(hex(i)[2:].zfill(8).decode('hex')) + def find_unused_subnet(base, subnet_bits, node_bits, existing_subnets): - # start at the first allocatable subnet + # enumerate possible subnets until we find one that isn't used i=1 while True: - subnet_i = int(socket.inet_aton(base).encode('hex'),16) | (i<=max_addr: + raise ValueError("No more ips available") + ip = int_to_ip(network_i | i) + if not (ip in existingAddresses): + return ip + i=i+1 + class NetworkTemplate(PlCoreBase): VISIBILITY_CHOICES = (('public', 'public'), ('private', 'private')) @@ -41,7 +61,7 @@ class Network(PlCoreBase): guaranteedBandwidth = models.IntegerField(default=0) permittedSlices = models.ManyToManyField(Slice, blank=True, related_name="permittedNetworks") - boundSlivers = models.ManyToManyField(Sliver, blank=True, related_name="boundNetworks", through="NetworkSliver") + slivers = models.ManyToManyField(Sliver, blank=True, related_name="boundNetworks", through="NetworkSliver") def __unicode__(self): return u'%s' % (self.name) @@ -49,6 +69,10 @@ class Network(PlCoreBase): existingSubnets = [x.subnet for x in Network.objects.all()] return find_unused_subnet(SUBNET_BASE, SUBNET_SUBNET_BITS, SUBNET_NODE_BITS, existingSubnets) + def allocateAddress(self): + existingAddresses = [x.ip for x in self.networksliver_set.all()] + return find_unused_address(self.subnet, existingAddresses) + def save(self, *args, **kwds): if not self.subnet: self.subnet = self.allocateSubnet() @@ -59,6 +83,11 @@ class NetworkSliver(PlCoreBase): sliver = models.ForeignKey(Sliver) ip = models.GenericIPAddressField(help_text="Sliver ip address", blank=True, null=True) + def save(self, *args, **kwds): + if not self.ip: + self.ip = self.network.allocateAddress() + super(NetworkSliver, self).save(*args, **kwds) + def __unicode__(self): return u'foo!' class Router(PlCoreBase): -- 2.43.0