Merge "Fixed all Flake8 errors"
[laas.git] / src / workflow / models.py
index 66b1739..7dae279 100644 (file)
@@ -11,6 +11,7 @@
 from django.shortcuts import render
 from django.contrib import messages
 from django.http import HttpResponse
+from django.utils import timezone
 
 import yaml
 import requests
@@ -27,13 +28,11 @@ from booking.models import Booking
 class BookingAuthManager():
     LFN_PROJECTS = ["opnfv"]  # TODO
 
-    def parse_url(self, info_url):
-        """
-        will return the PTL in the INFO file on success, or None
-        """
+    def parse_github_url(self, url):
+        project_leads = []
         try:
-            parts = info_url.split("/")
-            if parts[0].find("http") > -1:  # the url include http(s)://
+            parts = url.split("/")
+            if "http" in parts[0]:  # the url include http(s)://
                 parts = parts[2:]
             if parts[-1] != "INFO.yaml":
                 return None
@@ -48,13 +47,94 @@ class BookingAuthManager():
             info_file = requests.get(url, timeout=15).text
             info_parsed = yaml.load(info_file)
             ptl = info_parsed.get('project_lead')
-            if not ptl:
+            if ptl:
+                project_leads.append(ptl)
+            sub_ptl = info_parsed.get("subproject_lead")
+            if sub_ptl:
+                project_leads.append(sub_ptl)
+
+        except Exception:
+            pass
+
+        return project_leads
+
+    def parse_gerrit_url(self, url):
+        project_leads = []
+        try:
+            halfs = url.split("?")
+            parts = halfs[0].split("/")
+            args = halfs[1].split(";")
+            if "http" in parts[0]:  # the url include http(s)://
+                parts = parts[2:]
+            if "f=INFO.yaml" not in args:
+                return None
+            if "gerrit.opnfv.org" not in parts[0]:
+                return None
+            try:
+                i = args.index("a=blob")
+                args[i] = "a=blob_plain"
+            except ValueError:
+                pass
+            # recreate url
+            halfs[1] = ";".join(args)
+            halfs[0] = "/".join(parts)
+            # now to download and parse file
+            url = "https://" + "?".join(halfs)
+            info_file = requests.get(url, timeout=15).text
+            info_parsed = yaml.load(info_file)
+            ptl = info_parsed.get('project_lead')
+            if ptl:
+                project_leads.append(ptl)
+            sub_ptl = info_parsed.get("subproject_lead")
+            if sub_ptl:
+                project_leads.append(sub_ptl)
+
+        except Exception:
+            return None
+
+        return project_leads
+
+    def parse_opnfv_git_url(self, url):
+        project_leads = []
+        try:
+            parts = url.split("/")
+            if "http" in parts[0]:  # the url include http(s)://
+                parts = parts[2:]
+            if "INFO.yaml" not in parts[-1]:
+                return None
+            if "git.opnfv.org" not in parts[0]:
                 return None
-            return ptl
+            if parts[-2] == "tree":
+                parts[-2] = "plain"
+            # now to download and parse file
+            url = "https://" + "/".join(parts)
+            info_file = requests.get(url, timeout=15).text
+            info_parsed = yaml.load(info_file)
+            ptl = info_parsed.get('project_lead')
+            if ptl:
+                project_leads.append(ptl)
+            sub_ptl = info_parsed.get("subproject_lead")
+            if sub_ptl:
+                project_leads.append(sub_ptl)
 
         except Exception:
             return None
 
+        return project_leads
+
+    def parse_url(self, info_url):
+        """
+        will return the PTL in the INFO file on success, or None
+        """
+        if "github" in info_url:
+            return self.parse_github_url(info_url)
+
+        if "gerrit.opnfv.org" in info_url:
+            return self.parse_gerrit_url(info_url)
+
+        if "git.opnfv.org" in info_url:
+            return self.parse_opnfv_git_url(info_url)
+
     def booking_allowed(self, booking, repo):
         """
         This is the method that will have to change whenever the booking policy changes in the Infra
@@ -68,8 +148,11 @@ class BookingAuthManager():
             return True  # admin override for this user
         if repo.BOOKING_INFO_FILE not in repo.el:
             return False  # INFO file not provided
-        ptl_info = self.parse_url(repo.BOOKING_INFO_FILE)
-        return ptl_info and ptl_info == booking.owner.userprofile.email_addr
+        ptl_info = self.parse_url(repo.el.get(repo.BOOKING_INFO_FILE))
+        for ptl in ptl_info:
+            if ptl['email'] == booking.owner.userprofile.email_addr:
+                return True
+        return False
 
 
 class WorkflowStep(object):
@@ -240,8 +323,8 @@ class Repository():
     SNAPSHOT_DESC = "description of the snapshot"
     BOOKING_INFO_FILE = "the INFO.yaml file for this user's booking"
 
-    #migratory elements of segmented workflow
-    #each of these is the end result of a different workflow.
+    # migratory elements of segmented workflow
+    # each of these is the end result of a different workflow.
     HAS_RESULT = "whether or not workflow has a result"
     RESULT_KEY = "key for target index that result will be put into in parent"
     RESULT = "result object from workflow"
@@ -316,6 +399,8 @@ class Repository():
         if not booking_id:
             return "SNAP, No booking ID provided"
         booking = Booking.objects.get(pk=booking_id)
+        if booking.start > timezone.now() or booking.end < timezone.now():
+            return "Booking is not active"
         name = self.el.get(self.SNAPSHOT_NAME)
         if not name:
             return "SNAP, no name provided"
@@ -331,6 +416,13 @@ class Repository():
         image.owner = owner
         image.host_type = host.profile
         image.save()
+        try:
+            current_image = host.config.image
+            image.os = current_image.os
+            image.save()
+        except Exception:
+            pass
+        JobFactory.makeSnapshotTask(image, booking, host)
 
     def make_generic_resource_bundle(self):
         owner = self.el[self.SESSION_USER]
@@ -366,7 +458,7 @@ class Repository():
                         try:
                             interface.host = interface.host
                             interface.save()
-                        except Exception as e:
+                        except Exception:
                             return "GRB, saving interface " + str(interface) + " failed. CODE:0x0019"
             else:
                 return "GRB, no interface set provided. CODE:0x001a"
@@ -484,6 +576,12 @@ class Repository():
         for collaborator in collaborators:
             booking.collaborators.add(collaborator)
 
+        try:
+            booking.pdf = ResourceManager().makePDF(booking.resource)
+            booking.save()
+        except Exception as e:
+            return "BOOK, failed to create Pod Desriptor File: " + str(e)
+
         try:
             JobFactory.makeCompleteJob(booking)
         except Exception as e: