3 from django.db import models
4 from core.models import PlCoreBase, Site, Slice, Sliver
5 from django.contrib.contenttypes.models import ContentType
6 from django.contrib.contenttypes import generic
8 # Create your models here.
10 SUBNET_BASE = "10.0.0.0"
11 SUBNET_NODE_BITS = 12 # enough for 4096 bits per subnet
12 SUBNET_SUBNET_BITS = 12 # enough for 4096 private networks
15 return int(socket.inet_aton(ip).encode('hex'),16)
18 return socket.inet_ntoa(hex(i)[2:].zfill(8).decode('hex'))
20 def find_unused_subnet(base, subnet_bits, node_bits, existing_subnets):
21 # enumerate possible subnets until we find one that isn't used
24 subnet_i = ip_to_int(base) | (i<<node_bits)
25 subnet = int_to_ip(subnet_i) + "/" + str(32-node_bits)
26 if (subnet not in existing_subnets):
29 # TODO: we could run out...
31 def find_unused_address(subnet, existingAddresses):
32 # enumerate possible addresses until we find one that isn't used
33 (network, bits) = subnet.split("/")
34 network_i = ip_to_int(network)
35 max_addr = 1<<(32-int(bits))
39 raise ValueError("No more ips available")
40 ip = int_to_ip(network_i | i)
41 if not (ip in existingAddresses):
45 class NetworkTemplate(PlCoreBase):
46 VISIBILITY_CHOICES = (('public', 'public'), ('private', 'private'))
48 name = models.CharField(max_length=32)
49 guaranteedBandwidth = models.IntegerField(default=0)
50 visibility = models.CharField(max_length=30, choices=VISIBILITY_CHOICES, default="private")
52 def __unicode__(self): return u'%s' % (self.name)
54 class Network(PlCoreBase):
55 name = models.CharField(max_length=32)
56 template = models.ForeignKey(NetworkTemplate)
57 subnet = models.CharField(max_length=32, blank=True, null=True)
58 ports = models.CharField(max_length=1024)
59 labels = models.CharField(max_length=1024)
60 slice = models.ForeignKey(Slice, related_name="networks")
62 guaranteedBandwidth = models.IntegerField(default=0)
63 permittedSlices = models.ManyToManyField(Slice, blank=True, related_name="permittedNetworks")
64 slivers = models.ManyToManyField(Sliver, blank=True, related_name="boundNetworks", through="NetworkSliver")
66 def __unicode__(self): return u'%s' % (self.name)
68 def allocateSubnet(self):
69 existingSubnets = [x.subnet for x in Network.objects.all()]
70 return find_unused_subnet(SUBNET_BASE, SUBNET_SUBNET_BITS, SUBNET_NODE_BITS, existingSubnets)
72 def allocateAddress(self):
73 existingAddresses = [x.ip for x in self.networksliver_set.all()]
74 return find_unused_address(self.subnet, existingAddresses)
76 def save(self, *args, **kwds):
78 self.subnet = self.allocateSubnet()
79 super(Network, self).save(*args, **kwds)
81 class NetworkSliver(PlCoreBase):
82 network = models.ForeignKey(Network)
83 sliver = models.ForeignKey(Sliver)
84 ip = models.GenericIPAddressField(help_text="Sliver ip address", blank=True, null=True)
86 def save(self, *args, **kwds):
88 self.ip = self.network.allocateAddress()
89 super(NetworkSliver, self).save(*args, **kwds)
91 def __unicode__(self): return u'foo!'
93 class Router(PlCoreBase):
94 name = models.CharField(max_length=32)
95 owner = models.ForeignKey(Slice, related_name="routers")
96 networks = models.ManyToManyField(Network, blank=True, related_name="routers")
98 def __unicode__(self): return u'%s' % (self.name)
100 class NetworkParameterType(PlCoreBase):
101 name = models.SlugField(help_text="The name of this tag", max_length=128)
103 def __unicode__(self): return u'%s' % (self.name)
105 class NetworkParameter(PlCoreBase):
106 networkParameterType = models.ForeignKey(NetworkParameterType, related_name="parameters", help_text="The name of the parameter")
107 value = models.CharField(help_text="The value of this parameter", max_length=1024)
109 # The required fields to do a ObjectType lookup, and object_id assignment
110 content_type = models.ForeignKey(ContentType)
111 object_id = models.PositiveIntegerField()
112 content_object = generic.GenericForeignKey('content_type', 'object_id')
114 def __unicode__(self):
115 return self.networkParameterType.name