summaryrefslogtreecommitdiffstats
path: root/src/account/models.py
diff options
context:
space:
mode:
authorParker Berberian <pberberian@iol.unh.edu>2019-12-19 12:39:01 -0500
committerParker Berberian <pberberian@iol.unh.edu>2020-01-28 16:09:35 -0500
commit77377d5e9362bd35a3b300df231e82ee974675e1 (patch)
tree5e3799768eb887a0259c8c21ed61123cdde2d608 /src/account/models.py
parent899e1a4baa95d0bc6f0eef34de66f0e257174878 (diff)
Comments and Documentation
This change adds a ton of comments and documentation across all the code. Change-Id: Ifee0a2f534e8584f14b0f13af4dda8dc70eb7553 Signed-off-by: Parker Berberian <pberberian@iol.unh.edu>
Diffstat (limited to 'src/account/models.py')
-rw-r--r--src/account/models.py67
1 files changed, 65 insertions, 2 deletions
diff --git a/src/account/models.py b/src/account/models.py
index 4862231..294e109 100644
--- a/src/account/models.py
+++ b/src/account/models.py
@@ -15,6 +15,14 @@ import random
class LabStatus(object):
+ """
+ A Poor man's enum for the status of a lab.
+
+ If everything is working fine at a lab, it is UP.
+ If it is down temporarily e.g. for maintenance, it is TEMP_DOWN
+ If its broken, its DOWN
+ """
+
UP = 0
TEMP_DOWN = 100
DOWN = 200
@@ -25,6 +33,8 @@ def upload_to(object, filename):
class UserProfile(models.Model):
+ """Extend the Django User model."""
+
user = models.OneToOneField(User, on_delete=models.CASCADE)
timezone = models.CharField(max_length=100, blank=False, default='UTC')
ssh_public_key = models.FileField(upload_to=upload_to, null=True, blank=True)
@@ -47,14 +57,31 @@ class UserProfile(models.Model):
class VlanManager(models.Model):
+ """
+ Keeps track of the vlans for a lab.
+
+ Vlans are represented as indexes into a 4096 element list.
+ This list is serialized to JSON for storing in the DB.
+ """
+
# list of length 4096 containing either 0 (not available) or 1 (available)
vlans = models.TextField()
+ # list of length 4096 containing either 0 (not reserved) or 1 (reserved)
+ reserved_vlans = models.TextField()
+
block_size = models.IntegerField()
+
+ # True if the lab allows two different users to have the same private vlans
+ # if they use QinQ or a vxlan overlay, for example
allow_overlapping = models.BooleanField()
- # list of length 4096 containing either 0 (not rexerved) or 1 (reserved)
- reserved_vlans = models.TextField()
def get_vlan(self, count=1):
+ """
+ Return the ID of available vlans, but does not reserve them.
+
+ Will throw index exception if not enough vlans are available.
+ If count == 1, the return value is an int. Otherwise, it is a list of ints.
+ """
allocated = []
vlans = json.loads(self.vlans)
for i in range(count):
@@ -66,24 +93,35 @@ class VlanManager(models.Model):
return allocated
def get_public_vlan(self):
+ """Return reference to an available public network without reserving it."""
return PublicNetwork.objects.filter(lab=self.lab_set.first(), in_use=False).first()
def reserve_public_vlan(self, vlan):
+ """Reserves the Public Network that has the given vlan."""
net = PublicNetwork.objects.get(lab=self.lab_set.first(), vlan=vlan, in_use=False)
net.in_use = True
net.save()
def release_public_vlan(self, vlan):
+ """Un-reserves a public network with the given vlan."""
net = PublicNetwork.objects.get(lab=self.lab_set.first(), vlan=vlan, in_use=True)
net.in_use = False
net.save()
def public_vlan_is_available(self, vlan):
+ """
+ Whether the public vlan is available.
+
+ returns true if the network with the given vlan is free to use,
+ False otherwise
+ """
net = PublicNetwork.objects.get(lab=self.lab_set.first(), vlan=vlan)
return not net.in_use
def is_available(self, vlans):
"""
+ If the vlans are available.
+
'vlans' is either a single vlan id integer or a list of integers
will return true (available) or false
"""
@@ -104,6 +142,8 @@ class VlanManager(models.Model):
def release_vlans(self, vlans):
"""
+ Make the vlans available for another booking.
+
'vlans' is either a single vlan id integer or a list of integers
will make the vlans available
doesnt return a value
@@ -121,6 +161,11 @@ class VlanManager(models.Model):
self.save()
def reserve_vlans(self, vlans):
+ """
+ Reserves all given vlans or throws a ValueError.
+
+ vlans can be an integer or a list of integers.
+ """
my_vlans = json.loads(self.vlans)
try:
@@ -140,6 +185,13 @@ class VlanManager(models.Model):
class Lab(models.Model):
+ """
+ Model representing a Hosting Lab.
+
+ Anybody that wants to host resources for LaaS needs to have a Lab model
+ We associate hardware with Labs so we know what is available and where.
+ """
+
lab_user = models.OneToOneField(User, on_delete=models.CASCADE)
name = models.CharField(max_length=200, primary_key=True, unique=True, null=False, blank=False)
contact_email = models.EmailField(max_length=200, null=True, blank=True)
@@ -147,11 +199,13 @@ class Lab(models.Model):
status = models.IntegerField(default=LabStatus.UP)
vlan_manager = models.ForeignKey(VlanManager, on_delete=models.CASCADE, null=True)
location = models.TextField(default="unknown")
+ # This token must apear in API requests from this lab
api_token = models.CharField(max_length=50)
description = models.CharField(max_length=240)
@staticmethod
def make_api_token():
+ """Generate random 45 character string for API token."""
alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
key = ""
for i in range(45):
@@ -163,6 +217,8 @@ class Lab(models.Model):
class PublicNetwork(models.Model):
+ """L2/L3 network that can reach the internet."""
+
vlan = models.IntegerField()
lab = models.ForeignKey(Lab, on_delete=models.CASCADE)
in_use = models.BooleanField(default=False)
@@ -171,6 +227,13 @@ class PublicNetwork(models.Model):
class Downtime(models.Model):
+ """
+ A Downtime event.
+
+ Labs can create Downtime objects so the dashboard can
+ alert users that the lab is down, etc
+ """
+
start = models.DateTimeField()
end = models.DateTimeField()
lab = models.ForeignKey(Lab, on_delete=models.CASCADE)