aboutsummaryrefslogtreecommitdiffstats
path: root/src/booking
diff options
context:
space:
mode:
Diffstat (limited to 'src/booking')
-rw-r--r--src/booking/forms.py12
-rw-r--r--src/booking/migrations/0005_booking_idf.py18
-rw-r--r--src/booking/migrations/0006_booking_opnfv_config.py20
-rw-r--r--src/booking/models.py4
-rw-r--r--src/booking/quick_deployer.py103
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)