1 ##############################################################################
2 # Copyright (c) 2018 Parker Berberian, Sawyer Bergeron, and others.
4 # All rights reserved. This program and the accompanying materials
5 # are made available under the terms of the Apache License, Version 2.0
6 # which accompanies this distribution, and is available at
7 # http://www.apache.org/licenses/LICENSE-2.0
8 ##############################################################################
11 from dashboard.exceptions import (
12 ResourceExistenceException,
13 ResourceAvailabilityException,
14 ResourceProvisioningException,
15 ModelValidationException,
17 from resource_inventory.models import Host, HostConfiguration, ResourceBundle, HostProfile
20 class ResourceManager:
29 if ResourceManager.instance is None:
30 ResourceManager.instance = ResourceManager()
31 return ResourceManager.instance
33 def getAvailableHostTypes(self, lab):
34 hostset = Host.objects.filter(lab=lab).filter(booked=False).filter(working=True)
35 hostprofileset = HostProfile.objects.filter(host__in=hostset, labs=lab)
36 return set(hostprofileset)
38 def hostsAvailable(self, grb):
40 This method will check if the given GenericResourceBundle
41 is available. No changes to the database
46 for host in grb.getHosts():
47 if host.profile not in profile_count:
48 profile_count[host.profile] = 0
49 profile_count[host.profile] += 1
51 # check that all required hosts are available
52 for profile in profile_count.keys():
53 available = Host.objects.filter(
58 needed = profile_count[profile]
59 if available < needed:
64 def deleteResourceBundle(self, resourceBundle):
65 for host in Host.objects.filter(bundle=resourceBundle):
66 self.releaseHost(host)
67 resourceBundle.delete()
69 def convertResourceBundle(self, genericResourceBundle, lab=None, config=None):
71 Takes in a GenericResourceBundle and 'converts' it into a ResourceBundle
73 resource_bundle = ResourceBundle()
74 resource_bundle.template = genericResourceBundle
75 resource_bundle.save()
77 hosts = genericResourceBundle.getHosts()
79 # current supported case: user creating new booking
80 # currently unsupported: editing existing booking
87 host_config = HostConfiguration.objects.get(bundle=config, host=host)
89 physical_host = self.acquireHost(host, genericResourceBundle.lab.name)
90 except ResourceAvailabilityException:
91 self.fail_acquire(physical_hosts)
92 raise ResourceAvailabilityException("Could not provision hosts, not enough available")
94 physical_host.bundle = resource_bundle
95 physical_host.template = host
96 physical_host.config = host_config
97 physical_hosts.append(physical_host)
99 self.configureNetworking(physical_host)
101 self.fail_acquire(physical_hosts)
102 raise ResourceProvisioningException("Network configuration failed.")
106 self.fail_acquire(physical_hosts)
107 raise ModelValidationException("Saving hosts failed")
109 return resource_bundle
111 def configureNetworking(self, host):
112 generic_interfaces = list(host.template.generic_interfaces.all())
113 for int_num, physical_interface in enumerate(host.interfaces.all()):
114 generic_interface = generic_interfaces[int_num]
115 physical_interface.config.clear()
116 for vlan in generic_interface.vlans.all():
117 physical_interface.config.add(vlan)
120 def acquireHost(self, genericHost, labName):
121 host_full_set = Host.objects.filter(lab__name__exact=labName, profile=genericHost.profile)
122 if not host_full_set.first():
123 raise ResourceExistenceException("No matching servers found")
124 host_set = host_full_set.filter(booked=False)
125 if not host_set.first():
126 raise ResourceAvailabilityException("No unbooked hosts match requested hosts")
127 host = host_set.first()
129 host.template = genericHost
133 def releaseHost(self, host):
139 def fail_acquire(self, hosts):
141 self.releaseHost(host)