aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustin Choquette <jchoquette@iol.unh.edu>2023-10-23 16:24:13 -0400
committerJustin Choquette <jchoquette@iol.unh.edu>2023-10-25 16:26:17 -0400
commita4ba880252b2bad72df3f16dd11fdf2206825335 (patch)
tree3d2852284728814ba546ae2719f47fe641b0f544
parentaff53e072502d63d8002d9c83213ce7f9d12c352 (diff)
Single Template Selection For Compatible Dashboardsliblaas-mvp
Change-Id: I0a795c2c49fdbe0427182a8789d622003997efcd Signed-off-by: Justin Choquette <jchoquette@iol.unh.edu>
-rw-r--r--config.env.sample2
-rw-r--r--src/dashboard/views.py9
-rw-r--r--src/laas_dashboard/settings.py6
-rw-r--r--src/liblaas/endpoints.py3
-rw-r--r--src/liblaas/views.py17
-rw-r--r--src/resource_inventory/views.py9
-rw-r--r--src/static/js/workflows/design-a-pod.js64
-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.html20
-rw-r--r--src/templates/lfedge/base.html2
-rw-r--r--src/templates/lfedge/dashboard/landing.html19
-rw-r--r--src/workflow/views.py23
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 {}
+