diff options
Diffstat (limited to 'src/booking')
-rw-r--r-- | src/booking/forms.py | 12 | ||||
-rw-r--r-- | src/booking/migrations/0005_booking_idf.py | 18 | ||||
-rw-r--r-- | src/booking/migrations/0006_booking_opnfv_config.py | 20 | ||||
-rw-r--r-- | src/booking/models.py | 4 | ||||
-rw-r--r-- | src/booking/quick_deployer.py | 103 |
5 files changed, 110 insertions, 47 deletions
diff --git a/src/booking/forms.py b/src/booking/forms.py index 7ba5af0..de427ab 100644 --- a/src/booking/forms.py +++ b/src/booking/forms.py @@ -8,7 +8,6 @@ ############################################################################## import django.forms as forms from django.forms.widgets import NumberInput -from django.db.models import Q from workflow.forms import ( SearchableSelectMultipleWidget, @@ -22,7 +21,6 @@ from resource_inventory.models import Image, Installer, Scenario class QuickBookingForm(forms.Form): purpose = forms.CharField(max_length=1000) project = forms.CharField(max_length=400) - image = forms.ModelChoiceField(queryset=Image.objects.all()) hostname = forms.CharField(max_length=400) installer = forms.ModelChoiceField(queryset=Installer.objects.all(), required=False) @@ -40,14 +38,12 @@ class QuickBookingForm(forms.Form): elif data and "users" in data: chosen_users = data.getlist("users") - if user: - self.image = forms.ModelChoiceField(queryset=Image.objects.filter( - Q(public=True) | Q(owner=user)), required=False) - else: - self.image = forms.ModelChoiceField(queryset=Image.objects.all(), required=False) - super(QuickBookingForm, self).__init__(data=data, **kwargs) + self.fields["image"] = forms.ModelChoiceField( + Image.objects.filter(public=True) | Image.objects.filter(owner=user) + ) + self.fields['users'] = forms.CharField( widget=SearchableSelectMultipleWidget( attrs=self.build_search_widget_attrs(chosen_users, default_user=default_user) diff --git a/src/booking/migrations/0005_booking_idf.py b/src/booking/migrations/0005_booking_idf.py new file mode 100644 index 0000000..31e9170 --- /dev/null +++ b/src/booking/migrations/0005_booking_idf.py @@ -0,0 +1,18 @@ +# Generated by Django 2.1 on 2019-04-12 19:27 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('booking', '0004_auto_20190124_1700'), + ] + + operations = [ + migrations.AddField( + model_name='booking', + name='idf', + field=models.TextField(blank=True, default=''), + ), + ] diff --git a/src/booking/migrations/0006_booking_opnfv_config.py b/src/booking/migrations/0006_booking_opnfv_config.py new file mode 100644 index 0000000..e5ffc71 --- /dev/null +++ b/src/booking/migrations/0006_booking_opnfv_config.py @@ -0,0 +1,20 @@ +# Generated by Django 2.1 on 2019-05-01 18:02 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('resource_inventory', '0010_auto_20190430_1405'), + ('booking', '0005_booking_idf'), + ] + + operations = [ + migrations.AddField( + model_name='booking', + name='opnfv_config', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='resource_inventory.OPNFVConfig'), + ), + ] diff --git a/src/booking/models.py b/src/booking/models.py index 8612abd..9836730 100644 --- a/src/booking/models.py +++ b/src/booking/models.py @@ -9,7 +9,7 @@ ############################################################################## -from resource_inventory.models import ResourceBundle, ConfigBundle +from resource_inventory.models import ResourceBundle, ConfigBundle, OPNFVConfig from account.models import Lab from django.contrib.auth.models import User from django.db import models @@ -29,9 +29,11 @@ class Booking(models.Model): ext_count = models.IntegerField(default=2) resource = models.ForeignKey(ResourceBundle, on_delete=models.SET_NULL, null=True) config_bundle = models.ForeignKey(ConfigBundle, on_delete=models.SET_NULL, null=True) + opnfv_config = models.ForeignKey(OPNFVConfig, on_delete=models.SET_NULL, null=True) project = models.CharField(max_length=100, default="", blank=True, null=True) lab = models.ForeignKey(Lab, null=True, on_delete=models.SET_NULL) pdf = models.TextField(blank=True, default="") + idf = models.TextField(blank=True, default="") class Meta: db_table = 'booking' diff --git a/src/booking/quick_deployer.py b/src/booking/quick_deployer.py index f076a2e..763c8a0 100644 --- a/src/booking/quick_deployer.py +++ b/src/booking/quick_deployer.py @@ -22,7 +22,6 @@ from resource_inventory.models import ( Image, GenericResourceBundle, ConfigBundle, - Vlan, Host, HostProfile, HostConfiguration, @@ -30,7 +29,11 @@ from resource_inventory.models import ( GenericHost, GenericInterface, OPNFVRole, - OPNFVConfig + OPNFVConfig, + Network, + NetworkConnection, + NetworkRole, + HostOPNFVConfig, ) from resource_inventory.resource_manager import ResourceManager from resource_inventory.pdf_templater import PDFTemplater @@ -90,6 +93,10 @@ class NoRemainingPublicNetwork(Exception): 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] @@ -179,18 +186,30 @@ def generate_hostconfig(generic_host, image, config_bundle): hconf = HostConfiguration() hconf.host = generic_host hconf.image = image - - opnfvrole = OPNFVRole.objects.get(name="Jumphost") - if not opnfvrole: - raise OPNFVRoleDNE("No jumphost role was found.") - - hconf.opnfvRole = opnfvrole hconf.bundle = config_bundle + hconf.is_head_node = True hconf.save() return hconf +def generate_hostopnfv(hostconfig, opnfvconfig): + config = HostOPNFVConfig() + role = None + try: + role = OPNFVRole.objects.get(name="Jumphost") + except Exception: + role = OPNFVRole.objects.create( + name="Jumphost", + description="Single server jumphost role" + ) + config.role = role + config.host_config = hostconfig + config.opnfv_config = opnfvconfig + config.save() + return config + + def generate_resource_bundle(generic_resource_bundle, config_bundle): # warning: requires cleanup try: resource_manager = ResourceManager.getInstance() @@ -226,6 +245,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()) @@ -246,62 +279,56 @@ def create_from_form(form, request): 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) - gresource = generate_gresource(grbundle, hostname) - ghost = generate_ghost(gresource, host_profile) - cbundle = generate_config_bundle(request.user, quick_booking_id, grbundle) + hconf = generate_hostconfig(ghost, image, cbundle) # if no installer provided, just create blank host + opnfv_config = None if installer: - generate_opnfvconfig(scenario, installer, cbundle) - - generate_hostconfig(ghost, image, cbundle) + opnfv_config = generate_opnfvconfig(scenario, installer, cbundle) + generate_hostopnfv(hconf, opnfv_config) # construct generic interfaces for interface_profile in host_profile.interfaceprofile.all(): 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) # generate booking - booking = Booking() - booking.purpose = purpose_field - booking.project = project_field - booking.lab = lab - booking.owner = request.user - booking.start = timezone.now() - booking.end = timezone.now() + timedelta(days=int(length)) - booking.resource = resource_bundle - booking.pdf = PDFTemplater.makePDF(booking.resource) - booking.config_bundle = cbundle - booking.save() + booking = Booking.objects.create( + purpose=purpose_field, + project=project_field, + lab=lab, + owner=request.user, + start=timezone.now(), + end=timezone.now() + timedelta(days=int(length)), + resource=resource_bundle, + config_bundle=cbundle, + opnfv_config=opnfv_config + ) + booking.pdf = PDFTemplater.makePDF(booking) + users_field = users_field[2:-2] if users_field: # may be empty after split, if no collaborators entered users_field = json.loads(users_field) for collaborator in users_field: user = User.objects.get(id=collaborator['id']) booking.collaborators.add(user) - booking.save() + + booking.save() # generate job JobFactory.makeCompleteJob(booking) |