import os
+import socket
from django.db import models
from core.models import PlCoreBase, Site, Slice, Sliver
from django.contrib.contenttypes.models import ContentType
# Create your models here.
+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 find_unused_subnet(base, subnet_bits, node_bits, existing_subnets):
+ i=0
+ while True:
+ subnet_i = (i<<node_bits) | int(socket.inet_aton(base).encode('hex'),16)
+ subnet = socket.inet_ntoa(hex(subnet_i)[2:].zfill(8).decode('hex')) + "/" + str(32-node_bits)
+ if (subnet not in existing_subnets):
+ return subnet
+ i=i+1
+
class NetworkTemplate(PlCoreBase):
VISIBILITY_CHOICES = (('public', 'public'), ('private', 'private'))
class Network(PlCoreBase):
name = models.CharField(max_length=32)
template = models.ForeignKey(NetworkTemplate)
- subnet = models.CharField(max_length=32)
+ subnet = models.CharField(max_length=32, blank=True, null=True)
ports = models.CharField(max_length=1024)
labels = models.CharField(max_length=1024)
slice = models.ForeignKey(Slice, related_name="networks")
def __unicode__(self): return u'%s' % (self.name)
+ def allocateSubnet(self):
+ existingSubnets = [x.subnet for x in Network.objects.all()]
+ return find_unused_subnet(SUBNET_BASE, SUBNET_SUBNET_BITS, SUBNET_NODE_BITS, existingSubnets)
+
+ def save(self, *args, **kwds):
+ if not self.subnet:
+ self.subnet = self.allocateSubnet()
+ super(Network, self).save(*args, **kwds)
+
class NetworkSliver(PlCoreBase):
network = models.ForeignKey(Network)
sliver = models.ForeignKey(Sliver)