From 77377d5e9362bd35a3b300df231e82ee974675e1 Mon Sep 17 00:00:00 2001 From: Parker Berberian Date: Thu, 19 Dec 2019 12:39:01 -0500 Subject: Comments and Documentation This change adds a ton of comments and documentation across all the code. Change-Id: Ifee0a2f534e8584f14b0f13af4dda8dc70eb7553 Signed-off-by: Parker Berberian --- src/api/models.py | 86 ++++++++++++++++++++++++------- src/api/serializers/booking_serializer.py | 10 ++-- src/api/tests/test_models_unittest.py | 3 +- src/api/urls.py | 3 +- src/api/views.py | 12 +++++ 5 files changed, 86 insertions(+), 28 deletions(-) (limited to 'src/api') diff --git a/src/api/models.py b/src/api/models.py index 520e747..1e5a2da 100644 --- a/src/api/models.py +++ b/src/api/models.py @@ -36,6 +36,14 @@ from account.models import Downtime class JobStatus(object): + """ + A poor man's enum for a job's status. + + A job is NEW if it has not been started or recognized by the Lab + A job is CURRENT if it has been started by the lab but it is not yet completed + a job is DONE if all the tasks are complete and the booking is ready to use + """ + NEW = 0 CURRENT = 100 DONE = 200 @@ -47,8 +55,11 @@ class LabManagerTracker(object): @classmethod def get(cls, lab_name, token): """ + Get a LabManager. + Takes in a lab name (from a url path) returns a lab manager instance for that lab, if it exists + Also checks that the given API token is correct """ try: lab = Lab.objects.get(name=lab_name) @@ -61,8 +72,8 @@ class LabManagerTracker(object): class LabManager(object): """ - This is the class that will ultimately handle all REST calls to - lab endpoints. + Handles all lab REST calls. + handles jobs, inventory, status, etc may need to create helper classes """ @@ -86,7 +97,9 @@ class LabManager(object): def create_downtime(self, form): """ - takes in a dictionary that describes the model. + Create a downtime event. + + Takes in a dictionary that describes the model. { "start": utc timestamp "end": utc timestamp @@ -287,8 +300,15 @@ class LabManager(object): class Job(models.Model): """ + A Job to be performed by the Lab. + + The API uses Jobs and Tasks to communicate actions that need to be taken to the Lab + that is hosting a booking. A booking from a user has an associated Job which tells + the lab how to configure the hardware, networking, etc to fulfill the booking + for the user. This is the class that is serialized and put into the api """ + booking = models.OneToOneField(Booking, on_delete=models.CASCADE, null=True) status = models.IntegerField(default=JobStatus.NEW) complete = models.BooleanField(default=False) @@ -321,6 +341,8 @@ class Job(models.Model): def is_fulfilled(self): """ + If a job has been completed by the lab. + This method should return true if all of the job's tasks are done, and false otherwise """ @@ -383,10 +405,8 @@ class TaskConfig(models.Model): class BridgeConfig(models.Model): - """ - Displays mapping between jumphost interfaces and - bridges - """ + """Displays mapping between jumphost interfaces and bridges.""" + interfaces = models.ManyToManyField(Interface) opnfv_config = models.ForeignKey(OPNFVConfig, on_delete=models.CASCADE) @@ -554,9 +574,8 @@ class AccessConfig(TaskConfig): class SoftwareConfig(TaskConfig): - """ - handled opnfv installations, etc - """ + """Handles software installations, such as OPNFV or ONAP.""" + opnfv = models.ForeignKey(OpnfvApiConfig, on_delete=models.CASCADE) def to_dict(self): @@ -584,9 +603,8 @@ class SoftwareConfig(TaskConfig): class HardwareConfig(TaskConfig): - """ - handles imaging, user accounts, etc - """ + """Describes the desired configuration of the hardware.""" + image = models.CharField(max_length=100, default="defimage") power = models.CharField(max_length=100, default="off") hostname = models.CharField(max_length=100, default="hostname") @@ -602,9 +620,8 @@ class HardwareConfig(TaskConfig): class NetworkConfig(TaskConfig): - """ - handles network configuration - """ + """Handles network configuration.""" + interfaces = models.ManyToManyField(Interface) delta = models.TextField() @@ -718,6 +735,13 @@ def get_task_uuid(): class TaskRelation(models.Model): + """ + Relates a Job to a TaskConfig. + + superclass that relates a Job to tasks anc maintains information + like status and messages from the lab + """ + status = models.IntegerField(default=JobStatus.NEW) job = models.ForeignKey(Job, on_delete=models.CASCADE) config = models.OneToOneField(TaskConfig, on_delete=models.CASCADE) @@ -808,13 +832,11 @@ class SnapshotRelation(TaskRelation): class JobFactory(object): + """This class creates all the API models (jobs, tasks, etc) needed to fulfill a booking.""" @classmethod def reimageHost(cls, new_image, booking, host): - """ - This method will make all necessary changes to make a lab - reimage a host. - """ + """Modify an existing job to reimage the given host.""" job = Job.objects.get(booking=booking) # make hardware task new hardware_relation = HostHardwareRelation.objects.get(host=host, job=job) @@ -853,6 +875,7 @@ class JobFactory(object): @classmethod def makeCompleteJob(cls, booking): + """Create everything that is needed to fulfill the given booking.""" hosts = Host.objects.filter(bundle=booking.resource) job = None try: @@ -896,6 +919,12 @@ class JobFactory(object): @classmethod def makeHardwareConfigs(cls, hosts=[], job=Job()): + """ + Create and save HardwareConfig. + + Helper function to create the tasks related to + configuring the hardware + """ for host in hosts: hardware_config = None try: @@ -916,6 +945,12 @@ class JobFactory(object): @classmethod def makeAccessConfig(cls, users, access_type, revoke=False, job=Job(), context=False): + """ + Create and save AccessConfig. + + Helper function to create the tasks related to + configuring the VPN, SSH, etc access for users + """ for user in users: relation = AccessRelation() relation.job = job @@ -935,6 +970,12 @@ class JobFactory(object): @classmethod def makeNetworkConfigs(cls, hosts=[], job=Job()): + """ + Create and save NetworkConfig. + + Helper function to create the tasks related to + configuring the networking + """ for host in hosts: network_config = None try: @@ -975,7 +1016,12 @@ class JobFactory(object): @classmethod def makeSoftware(cls, booking=None, job=Job()): + """ + Create and save SoftwareConfig. + Helper function to create the tasks related to + configuring the desired software, e.g. an OPNFV deployment + """ if not booking.opnfv_config: return None diff --git a/src/api/serializers/booking_serializer.py b/src/api/serializers/booking_serializer.py index 9b5c059..46a2348 100644 --- a/src/api/serializers/booking_serializer.py +++ b/src/api/serializers/booking_serializer.py @@ -25,7 +25,8 @@ class BookingField(serializers.Field): def to_representation(self, booking): """ - Takes in a booking object. + Take in a booking object. + Returns a dictionary of primitives representing that booking """ ser = {} @@ -75,8 +76,7 @@ class BookingField(serializers.Field): def to_internal_value(self, data): """ - Takes in a dictionary of primitives - Returns a booking object + Take in a dictionary of primitives, and return a booking object. This is not going to be implemented or allowed. If someone needs to create a booking through the api, @@ -146,9 +146,7 @@ class InterfaceField(serializers.Field): pass def to_internal_value(self, data): - """ - takes in a serialized interface and creates an Interface model - """ + """Take in a serialized interface and creates an Interface model.""" mac = data['mac'] bus_address = data['busaddr'] switch_name = data['switchport']['switch_name'] diff --git a/src/api/tests/test_models_unittest.py b/src/api/tests/test_models_unittest.py index 2ecbe42..2a6fa0b 100644 --- a/src/api/tests/test_models_unittest.py +++ b/src/api/tests/test_models_unittest.py @@ -108,7 +108,8 @@ class ValidBookingCreatesValidJob(TestCase): def make_networks(self, hostprofile, nets): """ - distributes nets accross hostprofile's interfaces + Distribute nets accross hostprofile's interfaces. + returns a 2D array """ network_struct = [] diff --git a/src/api/urls.py b/src/api/urls.py index 0e84a6a..39f07df 100644 --- a/src/api/urls.py +++ b/src/api/urls.py @@ -9,7 +9,8 @@ ############################################################################## -"""laas_dashboard URL Configuration +""" +laas_dashboard URL Configuration. The `urlpatterns` list routes URLs to views. For more information please see: https://docs.djangoproject.com/en/1.10/topics/http/urls/ diff --git a/src/api/views.py b/src/api/views.py index a5153d7..bc01562 100644 --- a/src/api/views.py +++ b/src/api/views.py @@ -27,6 +27,18 @@ from booking.models import Booking from api.models import LabManagerTracker, get_task from notifier.manager import NotificationHandler +""" +API views. + +All functions return a Json blob +Most functions that deal with info from a specific lab (tasks, host info) +requires the Lab auth token. + for example, curl -H auth-token:mylabsauthtoken url + +Most functions let you GET or POST to the same endpoint, and +the correct thing will happen +""" + class BookingViewSet(viewsets.ModelViewSet): queryset = Booking.objects.all() -- cgit 1.2.3-korg