From: Justin Choquette Date: Mon, 23 Oct 2023 20:24:13 +0000 (-0400) Subject: Single Template Selection For Compatible Dashboards X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=commitdiff_plain;h=refs%2Fchanges%2F32%2F74232%2F3;p=laas.git Single Template Selection For Compatible Dashboards Change-Id: I0a795c2c49fdbe0427182a8789d622003997efcd Signed-off-by: Justin Choquette --- diff --git a/config.env.sample b/config.env.sample index cf32c73..002cb7a 100644 --- a/config.env.sample +++ b/config.env.sample @@ -63,7 +63,7 @@ JENKINS_URL=https://build.opnfv.org/ci BOOKING_EXPIRE_TIME=30 BOOKING_MAXIMUM_NUMBER=10 -TEMPLATE_OVERRIDE_DIR=laas +PROJECT=anuket LIBLAAS_BASE_URL=http://
:/ diff --git a/src/dashboard/views.py b/src/dashboard/views.py index 2a8b43f..55be8fb 100644 --- a/src/dashboard/views.py +++ b/src/dashboard/views.py @@ -20,6 +20,7 @@ from django.http import HttpResponse from account.models import Lab, UserProfile from booking.models import Booking from laas_dashboard import settings +from laas_dashboard.settings import PROJECT from liblaas.utils import get_ipa_status from liblaas.views import flavor_list_flavors, flavor_list_hosts @@ -38,15 +39,13 @@ def lab_detail_view(request, lab_name): user = request.user lab = get_object_or_404(Lab, name=lab_name) - origin = "anuket" if os.environ.get("TEMPLATE_OVERRIDE_DIR") == 'laas' else "lfedge" - - flavors_list = flavor_list_flavors(origin) - host_list = flavor_list_hosts(origin) + flavors_list = flavor_list_flavors(PROJECT) + host_list = flavor_list_hosts(PROJECT) flavor_map = {} for flavor in flavors_list: flavor_map[flavor['flavor_id']] = flavor['name'] - + # Apparently Django Templating lacks many features that regular Jinja offers, so I need to get creative for host in host_list: diff --git a/src/laas_dashboard/settings.py b/src/laas_dashboard/settings.py index a56265e..22f33ef 100644 --- a/src/laas_dashboard/settings.py +++ b/src/laas_dashboard/settings.py @@ -87,15 +87,15 @@ if os.environ.get('EXPECT_HOST_FORWARDING') == 'True': ROOT_URLCONF = 'laas_dashboard.urls' -TEMPLATE_OVERRIDE = os.environ.get("TEMPLATE_OVERRIDE_DIR", "") # the user's custom template dir +PROJECT = os.environ.get("PROJECT", "") # the project for the current deployment (i.e. anuket or lfedge) TEMPLATE_DIRS = ["base"] # where all the base templates are # If the user has a custom template directory, # We should search that first. Then we search the # root template directory so that we can extend the base # templates within the custom template dir. -if TEMPLATE_OVERRIDE: - TEMPLATE_DIRS = [TEMPLATE_OVERRIDE, ""] + TEMPLATE_DIRS +if PROJECT: + TEMPLATE_DIRS = [PROJECT, ""] + TEMPLATE_DIRS # all template dirs are relative to /project_root/templates/ dirs = [os.path.join(BASE_DIR, "templates", d) for d in TEMPLATE_DIRS] diff --git a/src/liblaas/endpoints.py b/src/liblaas/endpoints.py index 64e5126..55611f3 100644 --- a/src/liblaas/endpoints.py +++ b/src/liblaas/endpoints.py @@ -18,6 +18,7 @@ from booking.models import Booking from account.models import Lab from django.utils import timezone from datetime import timedelta +from laas_dashboard.settings import PROJECT def request_list_flavors(request) -> HttpResponse: data = json.loads(request.body.decode('utf-8')) @@ -90,7 +91,7 @@ def request_create_booking(request) -> HttpResponse: "project": data["metadata"]["project"], "length": int(data["metadata"]["length"]) }, - "origin": "anuket" if os.environ.get("TEMPLATE_OVERRIDE_DIR") == 'laas' else "lfedge" # todo - refactor + "origin": PROJECT } # Create booking in dashboard diff --git a/src/liblaas/views.py b/src/liblaas/views.py index 5edc727..8eb1dd0 100644 --- a/src/liblaas/views.py +++ b/src/liblaas/views.py @@ -74,20 +74,9 @@ def flavor_list_flavors(project: str) -> requests.Response: print(f"Error at {url}") return None -# GET -def flavor_get_flavor_by_id(flavor_id: str) -> requests.Response: - endpoint = f'flavor/name/{flavor_id}/' - url = f'{base}{endpoint}' - try: - response = requests.get(url) - return response.json() - except: - print(f"Error at {url}") - return None - # GET def flavor_list_hosts(project: str) -> requests.Response: - endpoint = f'flavor/hosts/{project}' + endpoint = f'flavor/hosts/{project}' #todo - support project in liblaas url = f'{base}{endpoint}' try: response = requests.get(url) @@ -100,7 +89,7 @@ def flavor_list_hosts(project: str) -> requests.Response: # GET def template_list_templates(uid: str) -> requests.Response: - endpoint = f'template/list/{uid}' + endpoint = f'template/list/{uid}' # todo - templates need to be restricted by project url = f'{base}{endpoint}' try: response = requests.get(url) @@ -122,7 +111,7 @@ def template_delete_template(template_id: str) -> requests.Response: #POST def template_make_template(template_blob: dict) -> requests.Response: - endpoint = f'template/create' + endpoint = f'template/create' # todo - needs to be restricted by project url = f'{base}{endpoint}' try: response = requests.post(url, data=json.dumps(template_blob), headers=post_headers) diff --git a/src/resource_inventory/views.py b/src/resource_inventory/views.py index b9e3490..e23326b 100644 --- a/src/resource_inventory/views.py +++ b/src/resource_inventory/views.py @@ -11,17 +11,16 @@ import json import os from django.shortcuts import render from django.http import HttpResponse +from laas_dashboard.settings import PROJECT from liblaas.views import flavor_list_hosts, flavor_list_flavors -origin = "anuket" if os.environ.get("TEMPLATE_OVERRIDE_DIR") == 'laas' else "lfedge" - def host_list_view(request): if request.method != "GET": return HttpResponse(status=405) - host_list = flavor_list_hosts(origin) - flavor_list = flavor_list_flavors(origin) + host_list = flavor_list_hosts(PROJECT) + flavor_list = flavor_list_flavors(PROJECT) flavor_map = {} for flavor in flavor_list: @@ -46,7 +45,7 @@ def profile_view(request, resource_id): if request.method != "GET": return HttpResponse(status=405) - flavor_list = flavor_list_flavors(origin) + flavor_list = flavor_list_flavors(PROJECT) selected_flavor = {} for flavor in flavor_list: if flavor["flavor_id"] == resource_id: diff --git a/src/static/js/workflows/design-a-pod.js b/src/static/js/workflows/design-a-pod.js index efec093..3c8652e 100644 --- a/src/static/js/workflows/design-a-pod.js +++ b/src/static/js/workflows/design-a-pod.js @@ -113,8 +113,8 @@ class DesignWorkflow extends Workflow { return; } - if (this.templateBlob.host_list.length >= 8) { - showError("You may not add more than 8 hosts to a single pod.", -1) + if (max_hosts && this.templateBlob.host_list.length >= max_hosts) { + showError(`You may not add more than ${max_hosts} hosts to a single pod.`, -1) return; } @@ -246,7 +246,7 @@ class DesignWorkflow extends Workflow { for (const [index, host] of this.resourceBuilder.user_configs.entries()) { const new_host = new HostConfigBlob(host); this.templateBlob.host_list.push(new_host); - this.labFlavors.get(host.flavor).available_count-- + this.labFlavors.get(host.flavor).available_count-- } // Add networks @@ -256,17 +256,17 @@ class DesignWorkflow extends Workflow { } } - // We are done - GUI.refreshHostStep(this.templateBlob.host_list, this.labFlavors, this.labImages); - GUI.refreshNetworkStep(this.templateBlob.networks); - GUI.refreshConnectionStep(this.templateBlob.host_list); - GUI.refreshPodSummaryHosts(this.templateBlob.host_list, this.labFlavors, this.labImages) - $('#resource_modal').modal('hide') + // We are done + GUI.refreshHostStep(this.templateBlob.host_list, this.labFlavors, this.labImages); + GUI.refreshNetworkStep(this.templateBlob.networks); + GUI.refreshConnectionStep(this.templateBlob.host_list); + GUI.refreshPodSummaryHosts(this.templateBlob.host_list, this.labFlavors, this.labImages) + $('#resource_modal').modal('hide') } /** * Takes a hostname, looks for the matching HostConfigBlob in the TemplateBlob, removes it from the list, and refreshes the appropriate views - * @param {String} hostname + * @param {String} hostname */ onclickDeleteHost(hostname) { this.goTo(steps.ADD_RESOURCES); @@ -536,9 +536,9 @@ class DesignWorkflow extends Workflow { passed = false; message = "Please select a lab"; step = steps.SELECT_LAB; - } else if (this.templateBlob.host_list.length < 1 || this.templateBlob.host_list.length > 8) { + } else if (this.templateBlob.host_list.length < 1 || (max_hosts && this.templateBlob.host_list.length > max_hosts)) { passed = false; - message = "Pods must contain 1 to 8 hosts"; + message = "Pod contains invalid number of resources."; step = steps.ADD_RESOURCES; } else if (this.templateBlob.networks.length < 1) { passed = false; @@ -817,7 +817,7 @@ class GUI { /** * Refreshes the step and creates a card for each host in the hostlist - * @param {List} hostlist + * @param {List} hostlist */ static refreshHostStep(hostlist, flavors, images) { const host_cards = document.getElementById('host_cards'); @@ -827,27 +827,41 @@ class GUI { } let span_class = '' - if (hostlist.length == 8) { - span_class = 'text-primary' - } else if (hostlist.length > 8) { - span_class = 'text-danger' + if (max_hosts) { + if (hostlist.length == max_hosts) { + span_class = 'text-primary' + } else if (hostlist.length > max_hosts) { + span_class = 'text-danger' + } } + const plus_card = document.createElement("div"); plus_card.classList.add("col-xl-3", "col-md-6", "col-12"); plus_card.id = "add_resource_plus_card"; - plus_card.innerHTML = ` -
- ` + hostlist.length + `/ 8 - -
- ` - host_cards.appendChild(plus_card); + if (max_hosts) { + plus_card.innerHTML = ` +
+ ${hostlist.length} / ${max_hosts} + +
+ ` + } else { + plus_card.innerHTML = ` +
+ +
+ ` + } + + if (max_hosts || hostlist.length == 0) { + host_cards.appendChild(plus_card); + } } /** * Makes a host card element for a given host and returns a reference to the card - * @param {HostConfigBlob} host + * @param {HostConfigBlob} host */ static makeHostCard(host, flavors, images) { const new_card = document.createElement("div"); diff --git a/src/templates/laas/base.html b/src/templates/anuket/base.html similarity index 100% rename from src/templates/laas/base.html rename to src/templates/anuket/base.html diff --git a/src/templates/laas/dashboard/landing.html b/src/templates/anuket/dashboard/landing.html similarity index 100% rename from src/templates/laas/dashboard/landing.html rename to src/templates/anuket/dashboard/landing.html diff --git a/src/templates/laas/layout.html b/src/templates/anuket/layout.html similarity index 100% rename from src/templates/laas/layout.html rename to src/templates/anuket/layout.html diff --git a/src/templates/base/workflow/design_a_pod.html b/src/templates/base/workflow/design_a_pod.html index c23e5a8..4804792 100644 --- a/src/templates/base/workflow/design_a_pod.html +++ b/src/templates/base/workflow/design_a_pod.html @@ -7,8 +7,6 @@ {% endblock %} {% block content %} -{% if dashboard == 'laas' %} - @@ -18,13 +16,13 @@
- + - +
@@ -40,18 +38,24 @@

Add Resources*

-

Add up to 8 configurable resources to your pod, then use the navigation arrows to proceed to the next step.

+ {% if constraints.max_hosts != "null" %} +

Add up to {{constraints.max_hosts}} configurable resources to your pod, then use the navigation arrows to proceed to the next step.

+ {% else %} +

Select a resource bundle that you would like to configure. To change the selected resource bundle, remove all added resources.

+ {% endif %}
- 0 / 8 + {% if constraints.max_hosts != "null" %} + 0 / {{constraints.max_hosts}} + {% endif %}
- +

Add Networks*

Define networks to use in your pod. A network may be set as public or private.

@@ -238,8 +242,8 @@ -{% endif %} {% endblock %} diff --git a/src/templates/lfedge/base.html b/src/templates/lfedge/base.html index 4413340..b8ed8c8 100644 --- a/src/templates/lfedge/base.html +++ b/src/templates/lfedge/base.html @@ -17,8 +17,6 @@
{% endblock logo %} -{% block dropDown %} -{% endblock dropDown %} {% block userDropDownText %} {% if request.user.username %} diff --git a/src/templates/lfedge/dashboard/landing.html b/src/templates/lfedge/dashboard/landing.html index 9a776dc..f04ed4d 100644 --- a/src/templates/lfedge/dashboard/landing.html +++ b/src/templates/lfedge/dashboard/landing.html @@ -1,23 +1,6 @@ {% extends "base/dashboard/landing.html" %} + {% block about_us %}

The Shared Community Lab at the IOL aims to help development and testing of LF Edge projects by hosting hardware and providing access to the community.

To get started, you can request access to a pod at the right.

{% endblock about_us %} - -{% block btnGrp %} - -

To get started, book a pod below:

-
Book a Pod -{% endblock btnGrp %} - -{% block returningUsers %} -{% endblock returningUsers %} diff --git a/src/workflow/views.py b/src/workflow/views.py index a85ac09..947c177 100644 --- a/src/workflow/views.py +++ b/src/workflow/views.py @@ -7,9 +7,8 @@ # http://www.apache.org/licenses/LICENSE-2.0 ############################################################################## -import json from django.shortcuts import render, redirect -from laas_dashboard.settings import TEMPLATE_OVERRIDE +from laas_dashboard.settings import PROJECT from django.http import HttpResponse from liblaas.views import user_get_user from workflow.forms import BookingMetaForm @@ -31,9 +30,10 @@ def design_a_pod_view(request): if (not profile or profile.ipa_username == None): return redirect("dashboard:index") + constraints = get_workflow_contraints(PROJECT) template = "workflow/design_a_pod.html" context = { - "dashboard": str(TEMPLATE_OVERRIDE) + "constraints": constraints, } return render(request, template, context) @@ -51,7 +51,7 @@ def book_a_pod_view(request): return redirect("dashboard:index") vpn_user = user_get_user(profile.ipa_username) - + # These booleans need to be represented as strings, due to the way jinja interprets them prereqs = { "company": "true" if ("ou" in vpn_user and vpn_user["ou"] != "") else "false", @@ -60,10 +60,23 @@ def book_a_pod_view(request): template = "workflow/book_a_pod.html" context = { - "dashboard": str(TEMPLATE_OVERRIDE), "form": BookingMetaForm(initial={}, user_initial=[], owner=request.user), "prereqs": prereqs } return render(request, template, context) +def get_workflow_contraints(project: str) -> dict: + + if project == 'anuket': + return { + "max_hosts": 8, + } + + if project == 'lfedge': + return { + "max_hosts": "null", + } + + return {} +