diff options
-rw-r--r-- | config.env.sample | 2 | ||||
-rw-r--r-- | src/dashboard/views.py | 9 | ||||
-rw-r--r-- | src/laas_dashboard/settings.py | 6 | ||||
-rw-r--r-- | src/liblaas/endpoints.py | 3 | ||||
-rw-r--r-- | src/liblaas/views.py | 17 | ||||
-rw-r--r-- | src/resource_inventory/views.py | 9 | ||||
-rw-r--r-- | src/static/js/workflows/design-a-pod.js | 64 | ||||
-rw-r--r-- | src/templates/anuket/base.html (renamed from src/templates/laas/base.html) | 0 | ||||
-rw-r--r-- | src/templates/anuket/dashboard/landing.html (renamed from src/templates/laas/dashboard/landing.html) | 0 | ||||
-rw-r--r-- | src/templates/anuket/layout.html (renamed from src/templates/laas/layout.html) | 0 | ||||
-rw-r--r-- | src/templates/base/workflow/design_a_pod.html | 20 | ||||
-rw-r--r-- | src/templates/lfedge/base.html | 2 | ||||
-rw-r--r-- | src/templates/lfedge/dashboard/landing.html | 19 | ||||
-rw-r--r-- | src/workflow/views.py | 23 |
14 files changed, 87 insertions, 87 deletions
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://<address>:<port>/ 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 @@ -75,19 +75,8 @@ def flavor_list_flavors(project: str) -> requests.Response: 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<HostConfigBlob>} hostlist + * @param {List<HostConfigBlob>} 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 = ` - <div class="card align-items-center border-0"> - <span class="` + span_class + `" id="resource-count">` + hostlist.length + `/ 8</span> - <button class="btn btn-success add-button p-0" onclick="workflow.onclickAddResource()">+</button> - </div> - ` - host_cards.appendChild(plus_card); + if (max_hosts) { + plus_card.innerHTML = ` + <div class="card align-items-center border-0"> + <span class="${span_class}" id="resource-count">${hostlist.length} / ${max_hosts}</span> + <button class="btn btn-success add-button p-0" onclick="workflow.onclickAddResource()">+</button> + </div> + ` + } else { + plus_card.innerHTML = ` + <div class="card align-items-center border-0"> + <button class="btn btn-success add-button p-0" onclick="workflow.onclickAddResource()">+</button> + </div> + ` + } + + 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 index f980268..f980268 100644 --- a/src/templates/laas/base.html +++ b/src/templates/anuket/base.html diff --git a/src/templates/laas/dashboard/landing.html b/src/templates/anuket/dashboard/landing.html index 12d8924..12d8924 100644 --- a/src/templates/laas/dashboard/landing.html +++ b/src/templates/anuket/dashboard/landing.html diff --git a/src/templates/laas/layout.html b/src/templates/anuket/layout.html index f9b1d99..f9b1d99 100644 --- a/src/templates/laas/layout.html +++ b/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 @@ <script src="/static/js/workflows/design-a-pod.js"></script> {% endblock %} {% block content %} -{% if dashboard == 'laas' %} - <!-- Main Content --> <body> @@ -18,13 +16,13 @@ <div class="arrow arrow-up"></div> </button> </div> - + <div id="next" class="row w-100 m-0"> <button class="btn btn-workflow-nav stretched-link m-0 p-0 mb-3" onclick="workflow.goNext()" id="workflow-next"> <div class="arrow arrow-down"></div> </button> </div> - + <div class="scroll-container w-100 h-100 p-0"> <!-- Select Lab --> @@ -40,18 +38,24 @@ <!-- Add Resources --> <div class="scroll-area pt-5 mx-5" id="add_resources"> <h2 class="mt-4 mb-3">Add Resources<span class="text-danger">*</span></h2> - <p>Add up to 8 configurable resources to your pod, then use the navigation arrows to proceed to the next step.</p> + {% if constraints.max_hosts != "null" %} + <p>Add up to {{constraints.max_hosts}} configurable resources to your pod, then use the navigation arrows to proceed to the next step.</p> + {% else %} + <p>Select a resource bundle that you would like to configure. To change the selected resource bundle, remove all added resources.</p> + {% endif %} <div class="row card-deck align-items-center" id="host_cards"> <div class="col-xl-3 col-md-6 col-12" id="add_resource_plus_card"> <div class="card align-items-center border-0"> - <span class="" id="resource-count">0 / 8</span> + {% if constraints.max_hosts != "null" %} + <span class="" id="resource-count">0 / {{constraints.max_hosts}}</span> + {% endif %} <button class="btn btn-success add-button p-0" onclick="workflow.onclickAddResource()">+</button> </div> </div> </div> </div> - <!-- Add Networks --> + <!-- Add Networks --> <div class="scroll-area pt-5 mx-5" id="add_networks"> <h2 class="mt-4 mb-3">Add Networks<span class="text-danger">*</span></h2> <p>Define networks to use in your pod. A network may be set as public or private.</p> @@ -238,8 +242,8 @@ <script> const user = "{{user}}" + const max_hosts = {{constraints.max_hosts}} const workflow = new DesignWorkflow(); workflow.startWorkflow(); </script> -{% 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 @@ </a> </div> {% endblock logo %} -{% block dropDown %} -{% endblock dropDown %} {% block userDropDownText %} <a class="nav-link p-0 wtext p-2" data-toggle="dropdown" href="#"> {% 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 %} <p>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.</p> <p>To get started, you can request access to a pod at the right.</p> {% endblock about_us %} - -{% block btnGrp %} -<style> -.btnLFEdge { - color: #fff; - background-color: #0049b0; -} -.btnLFEdge:hover{ - color: #fff; - background-color: #001776; -} -</style> -<p>To get started, book a pod below:</p> -<a class="btn btnLFEdge btn-lg d-flex flex-column justify-content-center align-content-center border text-white p-4" href="/booking/quick/">Book a Pod</a> -{% 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 {} + |