aboutsummaryrefslogtreecommitdiffstats
path: root/src/resource_inventory/resource_manager.py
diff options
context:
space:
mode:
authorParker Berberian <pberberian@iol.unh.edu>2018-10-10 16:06:47 -0400
committerParker Berberian <pberberian@iol.unh.edu>2018-10-15 13:16:11 -0400
commit1f3a770d2547848590f39e9d9b9bdffeb94eec14 (patch)
tree97222e5facd1a242d951c38482315057b5790d51 /src/resource_inventory/resource_manager.py
parent6d4019e59eda897384e9c00d1daf8b2ce87d128f (diff)
Lab as a Service 2.0
See changes here: https://wiki.opnfv.org/display/INF/Pharos+Laas Change-Id: I59ada5f98e70a28d7f8c14eab3239597e236ca26 Signed-off-by: Sawyer Bergeron <sbergeron@iol.unh.edu> Signed-off-by: Parker Berberian <pberberian@iol.unh.edu>
Diffstat (limited to 'src/resource_inventory/resource_manager.py')
-rw-r--r--src/resource_inventory/resource_manager.py197
1 files changed, 197 insertions, 0 deletions
diff --git a/src/resource_inventory/resource_manager.py b/src/resource_inventory/resource_manager.py
new file mode 100644
index 0000000..cd70867
--- /dev/null
+++ b/src/resource_inventory/resource_manager.py
@@ -0,0 +1,197 @@
+##############################################################################
+# Copyright (c) 2018 Parker Berberian, Sawyer Bergeron, and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+
+from django.core.exceptions import *
+from django.template.loader import render_to_string
+
+import booking
+from dashboard.exceptions import *
+from resource_inventory.models import *
+
+class ResourceManager:
+
+ instance = None
+
+ def __init__(self):
+ pass
+
+ @staticmethod
+ def getInstance():
+ if ResourceManager.instance is None:
+ ResourceManager.instance = ResourceManager()
+ return ResourceManager.instance
+
+ #public interface
+ def deleteResourceBundle(self, resourceBundle):
+ for host in Host.objects.filter(bundle=resourceBundle):
+ self.releaseHost(host)
+ resourceBundle.delete()
+
+ def convertResourceBundle(self, genericResourceBundle, lab=None, config=None):
+ """
+ Takes in a GenericResourceBundle and 'converts' it into a ResourceBundle
+ """
+ resource_bundle = ResourceBundle()
+ resource_bundle.template = genericResourceBundle
+ resource_bundle.save()
+
+ hosts = genericResourceBundle.getHosts()
+
+ #current supported case: user creating new booking
+ #currently unsupported: editing existing booking
+
+ physical_hosts = []
+
+ for host in hosts:
+ host_config=None
+ if config:
+ host_config = HostConfiguration.objects.get(bundle=config, host=host)
+ try:
+ physical_host = self.acquireHost(host, genericResourceBundle.lab.name)
+ except ResourceAvailabilityException:
+ self.fail_acquire(physical_hosts)
+ raise ResourceAvailabilityException("Could not provision hosts, not enough available")
+ try:
+ physical_host.bundle = resource_bundle
+ physical_host.template = host
+ physical_host.config = host_config
+ physical_hosts.append(physical_host)
+
+ self.configureNetworking(physical_host)
+ except:
+ self.fail_acquire(physical_hosts)
+ raise ResourceProvisioningException("Network configuration failed.")
+ try:
+ physical_host.save()
+ except:
+ self.fail_acquire(physical_hosts)
+ raise ModelValidationException("Saving hosts failed")
+
+ return resource_bundle
+
+ def configureNetworking(self, host):
+ generic_interfaces = list(host.template.generic_interfaces.all())
+ for int_num, physical_interface in enumerate(host.interfaces.all()):
+ generic_interface = generic_interfaces[int_num]
+ physical_interface.config.clear()
+ for vlan in generic_interface.vlans.all():
+ physical_interface.config.add(vlan)
+
+ #private interface
+ def acquireHost(self, genericHost, labName):
+ host_full_set = Host.objects.filter(lab__name__exact=labName, profile=genericHost.profile)
+ if not host_full_set.first():
+ raise ResourceExistenceException("No matching servers found")
+ host_set = host_full_set.filter(booked=False)
+ if not host_set.first():
+ raise ResourceAvailabilityException("No unbooked hosts match requested hosts")
+ host = host_set.first()
+ host.booked = True
+ host.template = genericHost
+ host.save()
+ return host
+
+ def releaseHost(self, host):
+ host.template = None
+ host.bundle = None
+ host.booked = False
+ host.save()
+
+ def fail_acquire(self, hosts):
+ for host in hosts:
+ self.releaseHost(host)
+
+ def makePDF(self, resource):
+ """
+ fills the pod descriptor file template with info about the resource
+ """
+ template = "dashboard/pdf.yaml"
+ info = {}
+ info['details'] = self.get_pdf_details(resource)
+ info['jumphost'] = self.get_pdf_jumphost(resource)
+ info['nodes'] = self.get_pdf_nodes(resource)
+
+ return render_to_string(template, context=info)
+
+ def get_pdf_details(self, resource):
+ details = {}
+ owner = "Anon"
+ email = "email@mail.com"
+ resource_lab = resource.template.lab
+ lab = resource_lab.name
+ location = resource_lab.location
+ pod_type = "development"
+ link = "https://wiki.opnfv.org/display/INF/Pharos+Laas"
+
+ try:
+ # try to get more specific info that may fail, we dont care if it does
+ booking_owner = booking.models.Booking.objects.get(resource=resource).owner
+ owner = booking_owner.username
+ email = booking_owner.userprofile.email_addr
+ except Exception as e:
+ pass
+
+ details['owner'] = owner
+ details['email'] = email
+ details['lab'] = lab
+ details['location'] = location
+ details['type'] = pod_type
+ details['link'] = link
+
+ return details
+
+ def get_pdf_jumphost(self, resource):
+ jumphost = Host.objects.get(bundle=resource, config__opnfvRole__name__iexact="jumphost")
+ return self.get_pdf_host(jumphost)
+
+ def get_pdf_nodes(self, resource):
+ pdf_nodes = []
+ nodes = Host.objects.filter(bundle=resource).exclude(config__opnfvRole__name__iexact="jumphost")
+ for node in nodes:
+ pdf_nodes.append(self.get_pdf_host(node))
+
+ return pdf_nodes
+
+
+ def get_pdf_host(self, host):
+ host_info = {}
+ host_info['name'] = host.template.resource.name
+ host_info['node'] = {}
+ host_info['node']['type'] = "baremetal"
+ host_info['node']['vendor'] = host.vendor
+ host_info['node']['model'] = host.model
+ host_info['node']['arch'] = host.profile.cpuprofile.first().architecture
+ host_info['node']['cpus'] = host.profile.cpuprofile.first().cpus
+ host_info['node']['cores'] = host.profile.cpuprofile.first().cores
+ cflags = host.profile.cpuprofile.first().cflags
+ if cflags and cflags.strip():
+ host_info['node']['cpu_cflags'] = cflags
+ host_info['node']['memory'] = str(host.profile.ramprofile.first().amount) + "G"
+ host_info['disks'] = []
+ for disk in host.profile.storageprofile.all():
+ disk_info = {}
+ disk_info['name'] = disk.name
+ disk_info['capacity'] = str(disk.size) + "G"
+ disk_info['type'] = disk.media_type
+ disk_info['interface'] = disk.interface
+ disk_info['rotation'] = disk.rotation
+ host_info['disks'].append(disk_info)
+
+ host_info['interfaces'] = []
+ for interface in host.interfaces.all():
+ iface_info = {}
+ iface_info['name'] = interface.name
+ iface_info['address'] = "unknown"
+ iface_info['mac_address'] = interface.mac_address
+ vlans = "|".join([str(vlan.vlan_id) for vlan in interface.config.all()])
+ iface_info['vlans'] = vlans
+ host_info['interfaces'].append(iface_info)
+
+ return host_info