diff options
Diffstat (limited to 'dashboard/src/resource_inventory/resource_manager.py')
-rw-r--r-- | dashboard/src/resource_inventory/resource_manager.py | 194 |
1 files changed, 81 insertions, 113 deletions
diff --git a/dashboard/src/resource_inventory/resource_manager.py b/dashboard/src/resource_inventory/resource_manager.py index 812fcd7..652e4e3 100644 --- a/dashboard/src/resource_inventory/resource_manager.py +++ b/dashboard/src/resource_inventory/resource_manager.py @@ -8,16 +8,20 @@ ############################################################################## -from django.template.loader import render_to_string - -import booking from dashboard.exceptions import ( ResourceExistenceException, ResourceAvailabilityException, ResourceProvisioningException, ModelValidationException, ) -from resource_inventory.models import Host, HostConfiguration, ResourceBundle, HostProfile +from resource_inventory.models import ( + Host, + HostConfiguration, + ResourceBundle, + HostProfile, + Network, + Vlan +) class ResourceManager: @@ -38,61 +42,102 @@ class ResourceManager: hostprofileset = HostProfile.objects.filter(host__in=hostset, labs=lab) return set(hostprofileset) + def hostsAvailable(self, grb): + """ + This method will check if the given GenericResourceBundle + is available. No changes to the database + """ + + # count up hosts + profile_count = {} + for host in grb.getHosts(): + if host.profile not in profile_count: + profile_count[host.profile] = 0 + profile_count[host.profile] += 1 + + # check that all required hosts are available + for profile in profile_count.keys(): + available = Host.objects.filter( + booked=False, + lab=grb.lab, + profile=profile + ).count() + needed = profile_count[profile] + if available < needed: + return False + return True + # 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): + def get_vlans(self, genericResourceBundle): + networks = {} + vlan_manager = genericResourceBundle.lab.vlan_manager + for network in genericResourceBundle.networks.all(): + if network.is_public: + public_net = vlan_manager.get_public_vlan() + vlan_manager.reserve_public_vlan(public_net.vlan) + networks[network.name] = public_net.vlan + else: + vlan = vlan_manager.get_vlan() + vlan_manager.reserve_vlans(vlan) + networks[network.name] = vlan + return networks + + def convertResourceBundle(self, genericResourceBundle, 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 - + resource_bundle = ResourceBundle.objects.create(template=genericResourceBundle) + generic_hosts = genericResourceBundle.getHosts() physical_hosts = [] - for host in hosts: + vlan_map = self.get_vlans(genericResourceBundle) + + for generic_host in generic_hosts: host_config = None if config: - host_config = HostConfiguration.objects.get(bundle=config, host=host) + host_config = HostConfiguration.objects.get(bundle=config, host=generic_host) try: - physical_host = self.acquireHost(host, genericResourceBundle.lab.name) + physical_host = self.acquireHost(generic_host, genericResourceBundle.lab.name) except ResourceAvailabilityException: - self.fail_acquire(physical_hosts) + self.fail_acquire(physical_hosts, vlan_map, genericResourceBundle) raise ResourceAvailabilityException("Could not provision hosts, not enough available") try: physical_host.bundle = resource_bundle - physical_host.template = host + physical_host.template = generic_host physical_host.config = host_config physical_hosts.append(physical_host) - self.configureNetworking(physical_host) + self.configureNetworking(physical_host, vlan_map) except Exception: - self.fail_acquire(physical_hosts) + self.fail_acquire(physical_hosts, vlan_map, genericResourceBundle) raise ResourceProvisioningException("Network configuration failed.") try: physical_host.save() except Exception: - self.fail_acquire(physical_hosts) + self.fail_acquire(physical_hosts, vlan_map, genericResourceBundle) raise ModelValidationException("Saving hosts failed") return resource_bundle - def configureNetworking(self, host): + def configureNetworking(self, host, vlan_map): 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) + for connection in generic_interface.connections.all(): + physical_interface.config.add( + Vlan.objects.create( + vlan_id=vlan_map[connection.network.name], + tagged=connection.vlan_is_tagged, + public=connection.network.is_public, + network=connection.network + ) + ) # private interface def acquireHost(self, genericHost, labName): @@ -114,93 +159,16 @@ class ResourceManager: host.booked = False host.save() - def fail_acquire(self, hosts): + def releaseNetworks(self, grb, vlan_manager, vlans): + for net_name, vlan_id in vlans.items(): + net = Network.objects.get(name=net_name, bundle=grb) + 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) 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: - 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 |