From 530271c247a4ce538e3aa69fd3893481fada44ab Mon Sep 17 00:00:00 2001 From: Sawyer Bergeron Date: Fri, 15 May 2020 14:58:37 -0400 Subject: Merge resource branch This pulls master up to date to include changes to models and surrounding infra that allow for multi-node templates and merging of pods Squashed commit of the following: commit abc8f27d9c6b05fb3afcb9b00dc35c0f2232d1a6 Author: Sawyer Bergeron Date: Thu Apr 2 14:05:26 2020 -0400 Start fixing workflow for model changes Change-Id: I79df975ef45abf2e6e69594d358bbd205938828f Signed-off-by: Sawyer Bergeron Signed-off-by: Sawyer Bergeron commit 7a7e2182acd0ea94e19aba4926c3a12771b30a6d Author: sms1097 Date: Tue Mar 31 15:13:06 2020 -0400 Working on workflow refactoring Change-Id: I4141b6aca98aff7bff9cb78a7d5594e25eb45e98 Signed-off-by: Sean Smith commit c09050ae2814f07af58557b40f9ed3559063d2c7 Merge: 71438d9 b5ccdc4 Author: Parker Berberian Date: Tue Mar 24 20:34:16 2020 +0000 Merge "Able to delete configurations and view lab details" into resource commit b5ccdc4ffbb883c20f2f6f69aeef5002aef5db53 Author: sms1097 Date: Thu Mar 19 17:08:12 2020 -0400 Able to delete configurations and view lab details Change-Id: Ib15c86d84f4cc7e7745551889ce91c89b5de46e2 Signed-off-by: Sean Smith Change-Id: Id6748c6bea67773a861921394d88579730246598 commit 71438d9a35cdb316cece865c9d410aeffb0053d8 Merge: 5460d0d a758223 Author: Parker Berberian Date: Thu Mar 19 18:51:09 2020 +0000 Merge "Add / Fix tests for refactor" into resource commit 5460d0d447b075433a763f9bfa33448b88ec8393 Merge: a9063a3 f55d839 Author: Parker Berberian Date: Wed Mar 18 15:59:37 2020 +0000 Merge "Fixed the quick booking form resource template filtering. Added some more models to the admin page." into resource commit f55d839a029ab1f5ab1273872e71a97fa1d5108b Author: Adam Hassick Date: Tue Mar 17 11:35:40 2020 -0400 Fixed the quick booking form resource template filtering. Added some more models to the admin page. Signed-off-by: Adam Hassick Change-Id: I2d2e7aeb96b10c231804a62f37a476039c954b7b commit a9063a347c4ebef0e53a17f198468bb135772810 Author: Parker Berberian Date: Wed Mar 18 10:29:51 2020 -0400 Fixes Some Issues with Quick Booking Seen in the Akraino lab Signed-off-by: Parker Berberian Change-Id: I2a1e843fbaa7984225f2f80742dad59dc348fbf2 commit a758223f44c6fec595b055d7c9b232b00e9174a0 Author: Parker Berberian Date: Tue Mar 17 11:07:32 2020 -0400 Add / Fix tests for refactor Change-Id: I0526d1942f87707082a4eb1c8c98910f84481c23 Signed-off-by: Parker Berberian Author: Parker Berberian Add "Pod" Column to booking list Signed-off-by: Parker Berberian Change-Id: I270913283bf1e5815cadf622ba2fd5f98bb61675 Author: Parker Berberian Fixes that make the Akraino dashboard work Signed-off-by: Parker Berberian Change-Id: I81746473a4511ef7d46445a7b16809a6e9da100f Signed-off-by: Sawyer Bergeron Change-Id: I4b428e7c8a8d401d7bae95cba01077feb0332a7f Signed-off-by: Sawyer Bergeron --- src/booking/forms.py | 9 +++--- src/booking/quick_deployer.py | 17 ++++++----- src/booking/tests/test_models.py | 48 ++++-------------------------- src/booking/tests/test_quick_booking.py | 52 +++++++++++++-------------------- src/booking/views.py | 23 ++++++--------- 5 files changed, 48 insertions(+), 101 deletions(-) (limited to 'src/booking') diff --git a/src/booking/forms.py b/src/booking/forms.py index b9c9231..886f0f6 100644 --- a/src/booking/forms.py +++ b/src/booking/forms.py @@ -11,8 +11,7 @@ from django.forms.widgets import NumberInput from workflow.forms import ( MultipleSelectFilterField, - MultipleSelectFilterWidget, - FormUtils) + MultipleSelectFilterWidget) from account.models import UserProfile from resource_inventory.models import Image, Installer, Scenario from workflow.forms import SearchableSelectMultipleField @@ -27,7 +26,7 @@ class QuickBookingForm(forms.Form): installer = forms.ModelChoiceField(queryset=Installer.objects.all(), required=False) scenario = forms.ModelChoiceField(queryset=Scenario.objects.all(), required=False) - def __init__(self, data=None, user=None, *args, **kwargs): + def __init__(self, data=None, user=None, lab_data=None, *args, **kwargs): if "default_user" in kwargs: default_user = kwargs.pop("default_user") else: @@ -47,8 +46,6 @@ class QuickBookingForm(forms.Form): **get_user_field_opts() ) - attrs = FormUtils.getLabData() - self.fields['filter_field'] = MultipleSelectFilterField(widget=MultipleSelectFilterWidget(**attrs)) self.fields['length'] = forms.IntegerField( widget=NumberInput( attrs={ @@ -60,6 +57,8 @@ class QuickBookingForm(forms.Form): ) ) + self.fields['filter_field'] = MultipleSelectFilterField(widget=MultipleSelectFilterWidget(**lab_data)) + def build_user_list(self): """ Build list of UserProfiles. diff --git a/src/booking/quick_deployer.py b/src/booking/quick_deployer.py index 951ff47..9cfc465 100644 --- a/src/booking/quick_deployer.py +++ b/src/booking/quick_deployer.py @@ -79,13 +79,14 @@ def update_template(old_template, image, hostname, user): lab=old_template.lab, description=old_template.description, public=False, - temporary=True + temporary=True, + copy_of=old_template ) for old_network in old_template.networks.all(): Network.objects.create( name=old_network.name, - bundle=old_template, + bundle=template, is_public=False ) # We are assuming there is only one opnfv config per public resource template @@ -105,7 +106,8 @@ def update_template(old_template, image, hostname, user): config = ResourceConfiguration.objects.create( profile=old_config.profile, image=image, - template=template + template=template, + is_head_node=old_config.is_head_node ) for old_iface_config in old_config.interface_configs.all(): @@ -127,6 +129,7 @@ def update_template(old_template, image, hostname, user): resource_config=config, opnfv_config=opnfv_config ) + return template def generate_opnfvconfig(scenario, installer, template): @@ -165,7 +168,6 @@ def check_invariants(request, **kwargs): image = kwargs['image'] scenario = kwargs['scenario'] lab = kwargs['lab'] - resource_template = kwargs['resource_template'] length = kwargs['length'] # check that image os is compatible with installer if installer in image.os.sup_installers.all(): @@ -176,8 +178,8 @@ def check_invariants(request, **kwargs): raise ValidationError("The chosen installer does not support the chosen scenario") if image.from_lab != lab: raise ValidationError("The chosen image is not available at the chosen hosting lab") - #TODO - #if image.host_type != host_profile: + # TODO + # if image.host_type != host_profile: # raise ValidationError("The chosen image is not available for the chosen host type") if not image.public and image.owner != request.user: raise ValidationError("You are not the owner of the chosen private image") @@ -217,11 +219,12 @@ def create_from_form(form, request): ResourceManager.getInstance().templateIsReservable(resource_template) - hconf = update_template(resource_template, image, hostname, request.user) + resource_template = update_template(resource_template, image, hostname, request.user) # if no installer provided, just create blank host opnfv_config = None if installer: + hconf = resource_template.getConfigs()[0] opnfv_config = generate_opnfvconfig(scenario, installer, resource_template) generate_hostopnfv(hconf, opnfv_config) diff --git a/src/booking/tests/test_models.py b/src/booking/tests/test_models.py index c8c8ea8..37eb655 100644 --- a/src/booking/tests/test_models.py +++ b/src/booking/tests/test_models.py @@ -11,13 +11,12 @@ from datetime import timedelta -from django.contrib.auth.models import Permission, User +from django.contrib.auth.models import User from django.test import TestCase from django.utils import timezone -# from booking.models import * from booking.models import Booking -from resource_inventory.models import ResourceBundle, GenericResourceBundle, ConfigBundle +from dashboard.testing_utils import make_resource_template, make_user class BookingModelTestCase(TestCase): @@ -27,8 +26,6 @@ class BookingModelTestCase(TestCase): Creates all the scafolding needed and tests the Booking model """ - count = 0 - def setUp(self): """ Prepare for Booking model tests. @@ -36,29 +33,9 @@ class BookingModelTestCase(TestCase): Creates all the needed models, such as users, resources, and configurations """ self.owner = User.objects.create(username='owner') - - self.res1 = ResourceBundle.objects.create( - template=GenericResourceBundle.objects.create( - name="gbundle" + str(self.count) - ) - ) - self.count += 1 - self.res2 = ResourceBundle.objects.create( - template=GenericResourceBundle.objects.create( - name="gbundle2" + str(self.count) - ) - ) - self.count += 1 - self.user1 = User.objects.create(username='user1') - - self.add_booking_perm = Permission.objects.get(codename='add_booking') - self.user1.user_permissions.add(self.add_booking_perm) - - self.user1 = User.objects.get(pk=self.user1.id) - self.config_bundle = ConfigBundle.objects.create( - owner=self.user1, - name="test config" - ) + self.res1 = make_resource_template(name="Test template 1") + self.res2 = make_resource_template(name="Test template 2") + self.user1 = make_user(username='user1') def test_start_end(self): """ @@ -76,7 +53,6 @@ class BookingModelTestCase(TestCase): end=end, resource=self.res1, owner=self.user1, - config_bundle=self.config_bundle ) end = start self.assertRaises( @@ -86,7 +62,6 @@ class BookingModelTestCase(TestCase): end=end, resource=self.res1, owner=self.user1, - config_bundle=self.config_bundle ) def test_conflicts(self): @@ -105,7 +80,6 @@ class BookingModelTestCase(TestCase): end=end, owner=self.user1, resource=self.res1, - config_bundle=self.config_bundle ) ) @@ -116,7 +90,6 @@ class BookingModelTestCase(TestCase): end=end, resource=self.res1, owner=self.user1, - config_bundle=self.config_bundle ) self.assertRaises( @@ -126,7 +99,6 @@ class BookingModelTestCase(TestCase): end=end - timedelta(days=1), resource=self.res1, owner=self.user1, - config_bundle=self.config_bundle ) self.assertRaises( @@ -136,7 +108,6 @@ class BookingModelTestCase(TestCase): end=end, resource=self.res1, owner=self.user1, - config_bundle=self.config_bundle ) self.assertRaises( @@ -146,7 +117,6 @@ class BookingModelTestCase(TestCase): end=end - timedelta(days=1), resource=self.res1, owner=self.user1, - config_bundle=self.config_bundle ) self.assertRaises( @@ -156,7 +126,6 @@ class BookingModelTestCase(TestCase): end=end + timedelta(days=1), resource=self.res1, owner=self.user1, - config_bundle=self.config_bundle ) self.assertRaises( @@ -166,7 +135,6 @@ class BookingModelTestCase(TestCase): end=end + timedelta(days=1), resource=self.res1, owner=self.user1, - config_bundle=self.config_bundle ) self.assertTrue( @@ -175,7 +143,6 @@ class BookingModelTestCase(TestCase): end=start, owner=self.user1, resource=self.res1, - config_bundle=self.config_bundle ) ) @@ -185,7 +152,6 @@ class BookingModelTestCase(TestCase): end=end + timedelta(days=1), owner=self.user1, resource=self.res1, - config_bundle=self.config_bundle ) ) @@ -195,7 +161,6 @@ class BookingModelTestCase(TestCase): end=start - timedelta(days=1), owner=self.user1, resource=self.res1, - config_bundle=self.config_bundle ) ) @@ -205,7 +170,6 @@ class BookingModelTestCase(TestCase): end=end + timedelta(days=2), owner=self.user1, resource=self.res1, - config_bundle=self.config_bundle ) ) @@ -215,7 +179,6 @@ class BookingModelTestCase(TestCase): end=end, owner=self.user1, resource=self.res2, - config_bundle=self.config_bundle ) ) @@ -234,7 +197,6 @@ class BookingModelTestCase(TestCase): end=end, owner=self.user1, resource=self.res1, - config_bundle=self.config_bundle ) ) diff --git a/src/booking/tests/test_quick_booking.py b/src/booking/tests/test_quick_booking.py index 5ba1744..f405047 100644 --- a/src/booking/tests/test_quick_booking.py +++ b/src/booking/tests/test_quick_booking.py @@ -14,17 +14,15 @@ from django.test import TestCase, Client from booking.models import Booking from dashboard.testing_utils import ( - make_host, make_user, make_user_profile, make_lab, - make_installer, make_image, - make_scenario, make_os, - make_complete_host_profile, make_opnfv_role, make_public_net, + make_resource_template, + make_server ) @@ -36,15 +34,13 @@ class QuickBookingValidFormTestCase(TestCase): cls.user.save() make_user_profile(cls.user, True) - lab_user = make_user(True) - cls.lab = make_lab(lab_user) + cls.lab = make_lab() - cls.host_profile = make_complete_host_profile(cls.lab) - cls.scenario = make_scenario() - cls.installer = make_installer([cls.scenario]) - os = make_os([cls.installer]) - cls.image = make_image(cls.lab, 1, cls.user, os, cls.host_profile) - cls.host = make_host(cls.host_profile, cls.lab) + cls.res_template = make_resource_template(owner=cls.user, lab=cls.lab) + cls.res_profile = cls.res_template.getConfigs()[0].profile + os = make_os() + cls.image = make_image(cls.res_profile, lab=cls.lab, owner=cls.user, os=os) + cls.server = make_server(cls.res_profile, cls.lab) cls.role = make_opnfv_role() cls.pubnet = make_public_net(10, cls.lab) @@ -55,10 +51,10 @@ class QuickBookingValidFormTestCase(TestCase): def build_post_data(cls): return { 'filter_field': json.dumps({ - "host": { - "host_" + str(cls.host_profile.id): { + "resource": { + "resource_" + str(cls.res_profile.id): { "selected": True, - "id": cls.host_profile.id + "id": cls.res_template.id } }, "lab": { @@ -75,8 +71,6 @@ class QuickBookingValidFormTestCase(TestCase): 'users': '', 'hostname': 'my_host', 'image': str(cls.image.id), - 'installer': str(cls.installer.id), - 'scenario': str(cls.scenario.id) } def post(self, changed_fields={}): @@ -97,15 +91,10 @@ class QuickBookingValidFormTestCase(TestCase): self.assertLess(delta, datetime.timedelta(minutes=1)) resource_bundle = booking.resource - config_bundle = booking.config_bundle - opnfv_config = config_bundle.opnfv_config.first() - self.assertEqual(self.installer, opnfv_config.installer) - self.assertEqual(self.scenario, opnfv_config.scenario) - - host = resource_bundle.hosts.first() - self.assertEqual(host.profile, self.host_profile) - self.assertEqual(host.template.resource.name, 'my_host') + host = resource_bundle.get_resources()[0] + self.assertEqual(host.profile, self.res_profile) + self.assertEqual(host.name, 'my_host') def test_with_too_long_length(self): response = self.post({'length': '22'}) @@ -133,10 +122,10 @@ class QuickBookingValidFormTestCase(TestCase): def test_with_invalid_host_id(self): response = self.post({'filter_field': json.dumps({ - "host": { - "host_" + str(self.host_profile.id + 100): { + "resource": { + "resource_" + str(self.res_profile.id + 100): { "selected": True, - "id": self.host_profile.id + 100 + "id": self.res_profile.id + 100 } }, "lab": { @@ -151,12 +140,11 @@ class QuickBookingValidFormTestCase(TestCase): self.assertIsNone(Booking.objects.first()) def test_with_invalid_lab_id(self): - response = self.post({'filter_field': '{"hosts":[{"host_' + str(self.host_profile.id) + '":"true"}], "labs": [{"lab_' + str(self.lab.lab_user.id + 100) + '":"true"}]}'}) response = self.post({'filter_field': json.dumps({ - "host": { - "host_" + str(self.host_profile.id): { + "resource": { + "resource_" + str(self.res_profile.id): { "selected": True, - "id": self.host_profile.id + "id": self.res_profile.id } }, "lab": { diff --git a/src/booking/views.py b/src/booking/views.py index daaf026..3c95e07 100644 --- a/src/booking/views.py +++ b/src/booking/views.py @@ -19,11 +19,11 @@ from django.db.models import Q from django.urls import reverse from resource_inventory.models import ResourceBundle, ResourceProfile, Image, ResourceQuery -from resource_inventory.resource_manager import ResourceManager -from account.models import Lab, Downtime +from account.models import Downtime from booking.models import Booking from booking.stats import StatisticsManager from booking.forms import HostReImageForm +from workflow.forms import FormUtils from api.models import JobFactory from workflow.views import login from booking.forms import QuickBookingForm @@ -40,21 +40,16 @@ def quick_create(request): if request.method == 'GET': context = {} - - r_manager = ResourceManager.getInstance() - templates = {} - for lab in Lab.objects.all(): - templates[str(lab)] = r_manager.getAvailableResourceTemplates(lab, request.user) - - context['lab_profile_map'] = templates - - context['form'] = QuickBookingForm(default_user=request.user.username, user=request.user) - + attrs = FormUtils.getLabData(user=request.user) + context['form'] = QuickBookingForm(lab_data=attrs, default_user=request.user.username, user=request.user) + context['lab_profile_map'] = {} context.update(drop_filter(request.user)) - return render(request, 'booking/quick_deploy.html', context) + if request.method == 'POST': - form = QuickBookingForm(request.POST, user=request.user) + attrs = FormUtils.getLabData(user=request.user) + form = QuickBookingForm(request.POST, lab_data=attrs, user=request.user) + context = {} context['lab_profile_map'] = {} context['form'] = form -- cgit 1.2.3-korg