diff options
Diffstat (limited to 'src/resource_inventory/resource_manager.py')
-rw-r--r-- | src/resource_inventory/resource_manager.py | 126 |
1 files changed, 51 insertions, 75 deletions
diff --git a/src/resource_inventory/resource_manager.py b/src/resource_inventory/resource_manager.py index 242d21a..c8b2b05 100644 --- a/src/resource_inventory/resource_manager.py +++ b/src/resource_inventory/resource_manager.py @@ -7,18 +7,13 @@ # http://www.apache.org/licenses/LICENSE-2.0 ############################################################################## import re +from django.db.models import Q + +from dashboard.exceptions import ResourceAvailabilityException -from dashboard.exceptions import ( - ResourceExistenceException, - ResourceAvailabilityException, - ResourceProvisioningException, - ModelValidationException, -) from resource_inventory.models import ( - Host, - HostConfiguration, ResourceBundle, - HostProfile, + ResourceTemplate, Network, Vlan, PhysicalNetwork, @@ -38,32 +33,27 @@ class ResourceManager: ResourceManager.instance = ResourceManager() return ResourceManager.instance - def getAvailableHostTypes(self, lab): - hostset = Host.objects.filter(lab=lab).filter(booked=False).filter(working=True) - hostprofileset = HostProfile.objects.filter(host__in=hostset, labs=lab) - return set(hostprofileset) + def getAvailableResourceTemplates(self, lab, user): + templates = ResourceTemplate.objects.filter(lab=lab) + templates.filter(Q(owner=user) | Q(public=True)) + return templates - def hostsAvailable(self, grb): + def templateIsReservable(self, resource_template): """ - Check if the given GenericResourceBundle is available. + Check if the required resources to reserve this template is available. No changes to the database """ # count up hosts profile_count = {} - for host in grb.getResources(): - if host.profile not in profile_count: - profile_count[host.profile] = 0 - profile_count[host.profile] += 1 + for config in resource_template.getConfigs(): + if config.profile not in profile_count: + profile_count[config.profile] = 0 + profile_count[config.profile] += 1 # check that all required hosts are available for profile in profile_count.keys(): - available = Host.objects.filter( - booked=False, - working=True, - lab=grb.lab, - profile=profile - ).count() + available = len(profile.get_resources(lab=resource_template.lab, unreserved=True)) needed = profile_count[profile] if available < needed: return False @@ -71,8 +61,8 @@ class ResourceManager: # public interface def deleteResourceBundle(self, resourceBundle): - for host in Host.objects.filter(bundle=resourceBundle): - host.release() + for resource in resourceBundle.get_resources(): + resource.release() resourceBundle.delete() def get_vlans(self, genericResourceBundle): @@ -89,43 +79,32 @@ class ResourceManager: networks[network.name] = vlan return networks - def convertResourceBundle(self, genericResourceBundle, config=None): + def instantiateTemplate(self, resource_template, config=None): """ - Convert a GenericResourceBundle into a ResourceBundle. + Convert a ResourceTemplate into a ResourceBundle. - Takes in a genericResourceBundle and reserves all the + Takes in a ResourceTemplate and reserves all the Resources needed and returns a completed ResourceBundle. """ - resource_bundle = ResourceBundle.objects.create(template=genericResourceBundle) - generic_hosts = genericResourceBundle.getResources() - physical_hosts = [] + resource_bundle = ResourceBundle.objects.create(template=resource_template) + res_configs = resource_template.getConfigs() + resources = [] - vlan_map = self.get_vlans(genericResourceBundle) + vlan_map = self.get_vlans(resource_template) - for generic_host in generic_hosts: - host_config = None - if config: - host_config = HostConfiguration.objects.get(bundle=config, host=generic_host) - try: - physical_host = self.acquireHost(generic_host, genericResourceBundle.lab.name) - except ResourceAvailabilityException: - self.fail_acquire(physical_hosts, vlan_map, genericResourceBundle) - raise ResourceAvailabilityException("Could not provision hosts, not enough available") + for config in res_configs: try: - physical_host.bundle = resource_bundle - physical_host.template = generic_host - physical_host.config = host_config - physical_hosts.append(physical_host) - - self.configureNetworking(physical_host, vlan_map) - except Exception: - self.fail_acquire(physical_hosts, vlan_map, genericResourceBundle) - raise ResourceProvisioningException("Network configuration failed.") - try: - physical_host.save() - except Exception: - self.fail_acquire(physical_hosts, vlan_map, genericResourceBundle) - raise ModelValidationException("Saving hosts failed") + phys_res = self.acquireHost(config) + phys_res.bundle = resource_bundle + phys_res.config = config + resources.append(phys_res) + + self.configureNetworking(phys_res, vlan_map) + phys_res.save() + + except Exception as e: + self.fail_acquire(resources, vlan_map, resource_template) + raise e return resource_bundle @@ -149,30 +128,27 @@ class ResourceManager: ) # 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, working=True) - 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 releaseNetworks(self, grb, vlan_manager, vlans): + def acquireHost(self, resource_config): + resources = resource_config.profile.get_resources(lab=resource_config.lab, unreserved=True) + try: + resource = resources[0] # TODO: should we randomize and 'load balance' the servers? + resource.config = resource_config + resource.reserve() + return resource + except IndexError: + raise ResourceAvailabilityException("No available resources of requested type") + + def releaseNetworks(self, template, vlans): + vlan_manager = template.lab.vlan_manager for net_name, vlan_id in vlans.items(): - net = Network.objects.get(name=net_name, bundle=grb) + net = Network.objects.get(name=net_name, bundle=template) if(net.is_public): vlan_manager.release_public_vlan(vlan_id) else: vlan_manager.release_vlans(vlan_id) - def fail_acquire(self, hosts, vlans, grb): - vlan_manager = grb.lab.vlan_manager - self.releaseNetworks(grb, vlan_manager, vlans) + def fail_acquire(self, hosts, vlans, template): + self.releaseNetworks(template, vlans) for host in hosts: host.release() |