Merge "Limit total number of active bookings per user"
authorParker Berberian <pberberian@iol.unh.edu>
Tue, 16 Apr 2019 16:53:08 +0000 (16:53 +0000)
committerGerrit Code Review <gerrit@opnfv.org>
Tue, 16 Apr 2019 16:53:08 +0000 (16:53 +0000)
1  2 
src/booking/quick_deployer.py
src/workflow/models.py

@@@ -22,6 -22,7 +22,6 @@@ from resource_inventory.models import 
      Image,
      GenericResourceBundle,
      ConfigBundle,
 -    Vlan,
      Host,
      HostProfile,
      HostConfiguration,
      GenericHost,
      GenericInterface,
      OPNFVRole,
 -    OPNFVConfig
 +    OPNFVConfig,
 +    Network,
 +    NetworkConnection,
 +    NetworkRole
  )
  from resource_inventory.resource_manager import ResourceManager
  from resource_inventory.pdf_templater import PDFTemplater
@@@ -92,6 -90,10 +92,10 @@@ class NoRemainingPublicNetwork(Exceptio
      pass
  
  
+ class BookingPermissionException(Exception):
+     pass
  def parse_host_field(host_field_contents):
      host_json = json.loads(host_field_contents)
      lab_dict = host_json['labs'][0]
@@@ -228,20 -230,6 +232,20 @@@ def check_invariants(request, **kwargs)
          raise BookingLengthException("Booking must be between 1 and 21 days long")
  
  
 +def configure_networking(grb, config):
 +    # create network
 +    net = Network.objects.create(name="public", bundle=grb, is_public=True)
 +    # connect network to generic host
 +    grb.getHosts()[0].generic_interfaces.first().connections.add(
 +        NetworkConnection.objects.create(network=net, vlan_is_tagged=False)
 +    )
 +    # asign network role
 +    role = NetworkRole.objects.create(name="public", network=net)
 +    opnfv_config = config.opnfv_config.first()
 +    if opnfv_config:
 +        opnfv_config.networks.add(role)
 +
 +
  def create_from_form(form, request):
      quick_booking_id = str(uuid.uuid4())
  
      data['host_profile'] = host_profile
      check_invariants(request, **data)
  
+     # check booking privileges
+     if Booking.objects.filter(owner=request.user, end__gt=timezone.now()).count() >= 3 and not request.user.userprofile.booking_privledge:
+         raise BookingPermissionException("You do not have permission to have more than 3 bookings at a time.")
      check_available_matching_host(lab, host_profile)  # requires cleanup if failure after this point
  
      grbundle = generate_grb(request.user, lab, quick_booking_id)
          generic_interface = GenericInterface.objects.create(profile=interface_profile, host=ghost)
          generic_interface.save()
  
 -    # get vlan, assign to first interface
 -    publicnetwork = lab.vlan_manager.get_public_vlan()
 -    if not publicnetwork:
 -        raise NoRemainingPublicNetwork("No public networks were available for your pod")
 -    publicvlan = publicnetwork.vlan
 -    lab.vlan_manager.reserve_public_vlan(publicvlan)
 -
 -    vlan = Vlan.objects.create(vlan_id=publicvlan, tagged=False, public=True)
 -    vlan.save()
 -
 -    ghost.generic_interfaces.first().vlans.add(vlan)
 -    ghost.generic_interfaces.first().save()
 +    configure_networking(grbundle, cbundle)
  
      # generate resource bundle
      resource_bundle = generate_resource_bundle(grbundle, cbundle)
diff --combined src/workflow/models.py
@@@ -143,10 -143,12 +143,12 @@@ class BookingAuthManager()
          currently checks if the booking uses multiple servers. if it does, then the owner must be a PTL,
          which is checked using the provided info file
          """
-         if len(booking.resource.template.getHosts()) < 2:
-             return True  # if they only have one server, we dont care
          if booking.owner.userprofile.booking_privledge:
              return True  # admin override for this user
+         if Booking.objects.filter(owner=booking.owner, end__gt=timezone.now()).count() >= 3:
+             return False
+         if len(booking.resource.template.getHosts()) < 2:
+             return True  # if they only have one server, we dont care
          if repo.BOOKING_INFO_FILE not in repo.el:
              return False  # INFO file not provided
          ptl_info = self.parse_url(repo.el.get(repo.BOOKING_INFO_FILE))
@@@ -203,6 -205,27 +205,6 @@@ class Confirmation_Step(WorkflowStep)
      title = "Confirm Changes"
      description = "Does this all look right?"
  
 -    def get_vlan_warning(self):
 -        grb = self.repo_get(self.repo.SELECTED_GRESOURCE_BUNDLE, False)
 -        if not grb:
 -            return 0
 -        if self.repo.BOOKING_MODELS not in self.repo.el:
 -            return 0
 -        vlan_manager = grb.lab.vlan_manager
 -        if vlan_manager is None:
 -            return 0
 -        hosts = grb.getHosts()
 -        for host in hosts:
 -            for interface in host.generic_interfaces.all():
 -                for vlan in interface.vlans.all():
 -                    if vlan.public:
 -                        if not vlan_manager.public_vlan_is_available(vlan.vlan_id):
 -                            return 1
 -                    else:
 -                        if not vlan_manager.is_available(vlan.vlan_id):
 -                            return 1  # There is a problem with these vlans
 -        return 0
 -
      def get_context(self):
          context = super(Confirmation_Step, self).get_context()
          context['form'] = ConfirmationForm()
              self.repo_get(self.repo.CONFIRMATION),
              default_flow_style=False
          ).strip()
 -        context['vlan_warning'] = self.get_vlan_warning()
  
          return context
  
                  pass
  
          else:
 -            if "vlan_input" in request.POST:
 -                if request.POST.get("vlan_input") == "True":
 -                    self.translate_vlans()
 -                    return self.render(request)
              pass
  
 -    def translate_vlans(self):
 -        grb = self.repo_get(self.repo.SELECTED_GRESOURCE_BUNDLE, False)
 -        if not grb:
 -            return 0
 -        vlan_manager = grb.lab.vlan_manager
 -        if vlan_manager is None:
 -            return 0
 -        hosts = grb.getHosts()
 -        for host in hosts:
 -            for interface in host.generic_interfaces.all():
 -                for vlan in interface.vlans.all():
 -                    if not vlan.public:
 -                        if not vlan_manager.is_available(vlan.vlan_id):
 -                            vlan.vlan_id = vlan_manager.get_vlan()
 -                            vlan.save()
 -                    else:
 -                        if not vlan_manager.public_vlan_is_available(vlan.vlan_id):
 -                            pub_vlan = vlan_manager.get_public_vlan()
 -                            vlan.vlan_id = pub_vlan.vlan
 -                            vlan.save()
 -
  
  class Workflow():
  
@@@ -406,11 -455,6 +408,11 @@@ class Repository()
              except Exception as e:
                  return "GRB, saving hosts generated exception: " + str(e) + " CODE:0x0005"
  
 +            if 'networks' in models:
 +                for net in models['networks'].values():
 +                    net.bundle = bundle
 +                    net.save()
 +
              if 'interfaces' in models:
                  for interface_set in models['interfaces'].values():
                      for interface in interface_set:
              else:
                  return "GRB, no interface set provided. CODE:0x001a"
  
 -            if 'vlans' in models:
 -                for resource_name, mapping in models['vlans'].items():
 -                    for profile_name, vlan_set in mapping.items():
 +            if 'connections' in models:
 +                for resource_name, mapping in models['connections'].items():
 +                    for profile_name, connection_set in mapping.items():
                          interface = GenericInterface.objects.get(
                              profile__name=profile_name,
                              host__resource__name=resource_name,
                              host__resource__bundle=models['bundle']
                          )
 -                        for vlan in vlan_set:
 +                        for connection in connection_set:
                              try:
 -                                vlan.save()
 -                                interface.vlans.add(vlan)
 +                                connection.network = connection.network
 +                                connection.save()
 +                                interface.connections.add(connection)
                              except Exception as e:
 -                                return "GRB, saving vlan " + str(vlan) + " failed. Exception: " + str(e) + ". CODE:0x0017"
 +                                return "GRB, saving vlan " + str(connection) + " failed. Exception: " + str(e) + ". CODE:0x0017"
              else:
                  return "GRB, no vlan set provided. CODE:0x0018"
  
          else:
              return "BOOK, no selected resource. CODE:0x000e"
  
 -        if not self.reserve_vlans(selected_grb):
 -            return "BOOK, vlans not available"
 -
          if 'booking' in models:
              booking = models['booking']
          else:
          except Exception as e:
              return "BOOK, saving booking generated exception: " + str(e) + " CODE:0x0016"
  
 -    def reserve_vlans(self, grb):
 -        """
 -        True is success
 -        """
 -        vlans = []
 -        public_vlan = None
 -        vlan_manager = grb.lab.vlan_manager
 -        if vlan_manager is None:
 -            return True
 -        for host in grb.getHosts():
 -            for interface in host.generic_interfaces.all():
 -                for vlan in interface.vlans.all():
 -                    if vlan.public:
 -                        public_vlan = vlan
 -                    else:
 -                        vlans.append(vlan.vlan_id)
 -
 -        try:
 -            vlan_manager.reserve_vlans(vlans)
 -            vlan_manager.reserve_public_vlan(public_vlan.vlan_id)
 -            return True
 -        except Exception:
 -            return False
 -
      def __init__(self):
          self.el = {}
          self.el[self.CONFIRMATION] = {}