aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJacob Hodgdon <jhodgdon@iol.unh.edu>2021-07-22 16:49:26 -0400
committerSawyer Bergeron <sbergeron@iol.unh.edu>2021-08-04 15:01:12 -0400
commitaa06cf305172854a47d61387c4df4f893dd00839 (patch)
tree8533c8498ed6cdcab396de609d566208c2301b85
parent68e660d74131f92337a37362014056e6390d350f (diff)
added /api/labs endpoint and tracebacks
Change-Id: I59d06d19806e892daed007689b0dab139eae3160 Signed-off-by: Jacob Hodgdon <jhodgdon@iol.unh.edu> Signed-off-by: Sawyer Bergeron <sbergeron@iol.unh.edu>
-rw-r--r--src/api/urls.py1
-rw-r--r--src/api/views.py33
-rw-r--r--src/resource_inventory/resource_manager.py32
3 files changed, 51 insertions, 15 deletions
diff --git a/src/api/urls.py b/src/api/urls.py
index 3d78ed6..1878d9c 100644
--- a/src/api/urls.py
+++ b/src/api/urls.py
@@ -82,6 +82,7 @@ urlpatterns = [
path('resource_inventory/<int:template_id>/images', images_for_template),
path('users', all_users),
+ path('labs', all_labs),
url(r'^token$', GenerateTokenView.as_view(), name='generate_token'),
]
diff --git a/src/api/views.py b/src/api/views.py
index 3c8445d..84085b4 100644
--- a/src/api/views.py
+++ b/src/api/views.py
@@ -10,6 +10,7 @@
import json
import math
+import traceback
from datetime import timedelta
from django.contrib.auth.decorators import login_required
@@ -362,7 +363,8 @@ def make_booking(request):
try:
booking = create_from_API(request.body, token.user)
except Exception as e:
- return HttpResponse(str(e), status=400)
+ exc_type, exc_value, exc_traceback = sys.exc_info()
+ return HttpResponse(str(traceback.format_exception(exc_type, exc_value, exc_traceback)), status=400)
sbooking = AutomationAPIManager.serialize_booking(booking)
return JsonResponse(sbooking, safe=False)
@@ -383,7 +385,7 @@ def available_templates(request):
# mirrors MultipleSelectFilter Widget
avt = []
for lab in Lab.objects.all():
- for template in ResourceTemplate.objects.filter(lab=lab, owner=token.user, public=True):
+ for template in ResourceTemplate.objects.filter(Q(lab=lab), Q(owner=token.user) | Q(public=True)):
available_resources = lab.get_available_resources()
required_resources = template.get_required_resources()
least_available = 100
@@ -417,7 +419,7 @@ def images_for_template(request, template_id=""):
"""
User API Views
"""
-
+lab_info
def all_users(request):
token = auth_and_log(request, 'users')
@@ -429,3 +431,28 @@ def all_users(request):
for up in UserProfile.objects.exclude(user=token.user)]
return JsonResponse(users, safe=False)
+
+
+"""
+Lab API Views
+"""
+
+
+def all_labs():
+ lab_list=[]
+ for lab in Lab.objects.all():
+ lab_info = {
+ 'name':lab.name,
+ 'username':lab.lab_user.username,
+ 'status':lab.status,
+ 'project':lab.project,
+ 'description':lab.description,
+ 'location':lab.location,
+ 'info':lab.lab_info_link,
+ 'email':lab.contact_email,
+ 'phone':lab.contact_phone
+ }
+ lab_list.append(lab_info)
+
+ return JsonResponse(lab_list, safe=False)
+
diff --git a/src/resource_inventory/resource_manager.py b/src/resource_inventory/resource_manager.py
index 9406977..1935e0c 100644
--- a/src/resource_inventory/resource_manager.py
+++ b/src/resource_inventory/resource_manager.py
@@ -7,6 +7,8 @@
# http://www.apache.org/licenses/LICENSE-2.0
##############################################################################
import re
+import typing
+from typing import Optional
from django.db.models import Q
from dashboard.exceptions import ResourceAvailabilityException
@@ -14,6 +16,7 @@ from dashboard.exceptions import ResourceAvailabilityException
from resource_inventory.models import (
ResourceBundle,
ResourceTemplate,
+ ResourceConfiguration,
Network,
Vlan,
PhysicalNetwork,
@@ -29,19 +32,19 @@ class ResourceManager:
pass
@staticmethod
- def getInstance():
+ def getInstance() -> ResourceManager:
if ResourceManager.instance is None:
ResourceManager.instance = ResourceManager()
return ResourceManager.instance
- def getAvailableResourceTemplates(self, lab, user=None):
+ def getAvailableResourceTemplates(self, lab: Lab, user: Optional[User] = None) -> list[ResourceTemplate]:
filter = Q(public=True)
if user:
filter = filter | Q(owner=user)
filter = filter & Q(temporary=False) & Q(lab=lab)
return ResourceTemplate.objects.filter(filter)
- def templateIsReservable(self, resource_template):
+ def templateIsReservable(self, resource_template: ResourceTemplate):
"""
Check if the required resources to reserve this template is available.
@@ -63,13 +66,16 @@ class ResourceManager:
return True
# public interface
- def deleteResourceBundle(self, resourceBundle):
+ def deleteResourceBundle(self, resourceBundle: ResourceBundle):
raise NotImplementedError("Resource Bundle Deletion Not Implemented")
- def releaseResourceBundle(self, resourceBundle):
+ def releaseResourceBundle(self, resourceBundle: ResourceBundle):
resourceBundle.release()
- def get_vlans(self, resourceTemplate):
+ def get_vlans(self, resourceTemplate: ResourceTemplate) -> dict[str, int]:
+ """
+ returns: dict from network name to the associated vlan number (backend vlan id)
+ """
networks = {}
vlan_manager = resourceTemplate.lab.vlan_manager
for network in resourceTemplate.networks.all():
@@ -84,7 +90,7 @@ class ResourceManager:
networks[network.name] = vlans[0]
return networks
- def instantiateTemplate(self, resource_template):
+ def instantiateTemplate(self, resource_template: ResourceTemplate):
"""
Convert a ResourceTemplate into a ResourceBundle.
@@ -113,16 +119,18 @@ class ResourceManager:
return resource_bundle
- def configureNetworking(self, resource_bundle, resource, vlan_map):
+ def configureNetworking(self, resource_bundle: ResourceBundle, resource: Resource, vlan_map: dict[str, int]):
+ """
+ @vlan_map: dict from network name to the associated vlan number (backend vlan id)
+ """
for physical_interface in resource.interfaces.all():
- # assign interface configs
- iface_configs = InterfaceConfiguration.objects.filter(
+ # assign interface configs
+ iface_config = InterfaceConfiguration.objects.get(
profile=physical_interface.profile,
resource_config=resource.config
)
- iface_config = iface_configs.first()
physical_interface.acts_as = iface_config
physical_interface.acts_as.save()
@@ -143,7 +151,7 @@ class ResourceManager:
)
# private interface
- def acquireHost(self, resource_config):
+ def acquireHost(self, resource_config: ResourceConfiguration) -> Resource:
resources = resource_config.profile.get_resources(
lab=resource_config.template.lab,
unreserved=True