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 (
27 class ResourceManager:
36 if ResourceManager.instance is None:
37 ResourceManager.instance = ResourceManager()
38 return ResourceManager.instance
40 def getAvailableHostTypes(self, lab):
41 hostset = Host.objects.filter(lab=lab).filter(booked=False).filter(working=True)
42 hostprofileset = HostProfile.objects.filter(host__in=hostset, labs=lab)
43 return set(hostprofileset)
45 def hostsAvailable(self, grb):
47 This method will check if the given GenericResourceBundle
48 is available. No changes to the database
53 for host in grb.getHosts():
54 if host.profile not in profile_count:
55 profile_count[host.profile] = 0
56 profile_count[host.profile] += 1
58 # check that all required hosts are available
59 for profile in profile_count.keys():
60 available = Host.objects.filter(
65 needed = profile_count[profile]
66 if available < needed:
71 def deleteResourceBundle(self, resourceBundle):
72 for host in Host.objects.filter(bundle=resourceBundle):
73 self.releaseHost(host)
74 resourceBundle.delete()
76 def get_vlans(self, genericResourceBundle):
78 vlan_manager = genericResourceBundle.lab.vlan_manager
79 for network in genericResourceBundle.networks.all():
81 public_net = vlan_manager.get_public_vlan()
82 vlan_manager.reserve_public_vlan(public_net.vlan)
83 networks[network.name] = public_net.vlan
85 vlan = vlan_manager.get_vlan()
86 vlan_manager.reserve_vlans(vlan)
87 networks[network.name] = vlan
90 def convertResourceBundle(self, genericResourceBundle, config=None):
92 Takes in a GenericResourceBundle and 'converts' it into a ResourceBundle
94 resource_bundle = ResourceBundle.objects.create(template=genericResourceBundle)
95 generic_hosts = genericResourceBundle.getHosts()
98 vlan_map = self.get_vlans(genericResourceBundle)
100 for generic_host in generic_hosts:
103 host_config = HostConfiguration.objects.get(bundle=config, host=generic_host)
105 physical_host = self.acquireHost(generic_host, genericResourceBundle.lab.name)
106 except ResourceAvailabilityException:
107 self.fail_acquire(physical_hosts, vlan_map)
108 raise ResourceAvailabilityException("Could not provision hosts, not enough available")
110 physical_host.bundle = resource_bundle
111 physical_host.template = generic_host
112 physical_host.config = host_config
113 physical_hosts.append(physical_host)
115 self.configureNetworking(physical_host, vlan_map)
117 self.fail_acquire(physical_hosts, vlan_map)
118 raise ResourceProvisioningException("Network configuration failed.")
122 self.fail_acquire(physical_hosts)
123 raise ModelValidationException("Saving hosts failed")
125 return resource_bundle
127 def configureNetworking(self, host, vlan_map):
128 generic_interfaces = list(host.template.generic_interfaces.all())
129 for int_num, physical_interface in enumerate(host.interfaces.all()):
130 generic_interface = generic_interfaces[int_num]
131 physical_interface.config.clear()
132 for connection in generic_interface.connections.all():
133 physical_interface.config.add(
135 vlan_id=vlan_map[connection.network.name],
136 tagged=connection.vlan_is_tagged,
137 public=connection.network.is_public,
138 network=connection.network
143 def acquireHost(self, genericHost, labName):
144 host_full_set = Host.objects.filter(lab__name__exact=labName, profile=genericHost.profile)
145 if not host_full_set.first():
146 raise ResourceExistenceException("No matching servers found")
147 host_set = host_full_set.filter(booked=False)
148 if not host_set.first():
149 raise ResourceAvailabilityException("No unbooked hosts match requested hosts")
150 host = host_set.first()
152 host.template = genericHost
156 def releaseHost(self, host):
162 def releaseNetworks(self, grb, vlan_manager, vlans):
163 for net_name, vlan_id in vlans.items():
164 net = Network.objects.get(name=net_name, bundle=grb)
166 vlan_manager.release_public_vlan(vlan_id)
168 vlan_manager.release_vlans(vlan_id)
170 def fail_acquire(self, hosts, vlans):
171 grb = hosts[0].template.resource.bundle
172 vlan_manager = hosts[0].lab.vlan_manager
173 self.releaseNetworks(grb, vlan_manager, vlans)
175 self.releaseHost(host)