From 1aad8a8ad965b9a20224b2ae094ce776c992a601 Mon Sep 17 00:00:00 2001 From: Parker Berberian Date: Fri, 12 Apr 2019 12:24:34 -0400 Subject: Fixes the idf and pdf templates so that we can deploy opnfv Change-Id: I0091629f8f0af423210b2e81210d65239e9662b4 Signed-off-by: Parker Berberian --- dashboard/src/api/models.py | 9 ++ .../src/booking/migrations/0005_booking_idf.py | 18 +++ dashboard/src/booking/models.py | 1 + dashboard/src/resource_inventory/admin.py | 5 +- dashboard/src/resource_inventory/idf_templater.py | 148 +++++++++++++++++++++ dashboard/src/resource_inventory/pdf_templater.py | 19 ++- dashboard/src/templates/dashboard/idf.yaml | 26 ++-- 7 files changed, 197 insertions(+), 29 deletions(-) create mode 100644 dashboard/src/booking/migrations/0005_booking_idf.py create mode 100644 dashboard/src/resource_inventory/idf_templater.py diff --git a/dashboard/src/api/models.py b/dashboard/src/api/models.py index f8b8f89..4ce8c3e 100644 --- a/dashboard/src/api/models.py +++ b/dashboard/src/api/models.py @@ -25,6 +25,8 @@ from resource_inventory.models import ( Interface, RemoteInfo ) +from resource_inventory.idf_templater import IDFTemplater +from resource_inventory.pdf_templater import PDFTemplater class JobStatus(object): @@ -86,8 +88,15 @@ class LabManager(object): remote_info.save() host.remote_management = remote_info host.save() + booking = Booking.objects.get(resource=host.bundle) + self.update_xdf(booking) return {"status": "success"} + def update_xdf(self, booking): + booking.pdf = PDFTemplater.makePDF(booking.resource) + booking.idf = IDFTemplater().makeIDF(booking) + booking.save() + def get_profile(self): prof = {} prof['name'] = self.lab.name diff --git a/dashboard/src/booking/migrations/0005_booking_idf.py b/dashboard/src/booking/migrations/0005_booking_idf.py new file mode 100644 index 0000000..31e9170 --- /dev/null +++ b/dashboard/src/booking/migrations/0005_booking_idf.py @@ -0,0 +1,18 @@ +# Generated by Django 2.1 on 2019-04-12 19:27 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('booking', '0004_auto_20190124_1700'), + ] + + operations = [ + migrations.AddField( + model_name='booking', + name='idf', + field=models.TextField(blank=True, default=''), + ), + ] diff --git a/dashboard/src/booking/models.py b/dashboard/src/booking/models.py index 8612abd..02e03cc 100644 --- a/dashboard/src/booking/models.py +++ b/dashboard/src/booking/models.py @@ -32,6 +32,7 @@ class Booking(models.Model): project = models.CharField(max_length=100, default="", blank=True, null=True) lab = models.ForeignKey(Lab, null=True, on_delete=models.SET_NULL) pdf = models.TextField(blank=True, default="") + idf = models.TextField(blank=True, default="") class Meta: db_table = 'booking' diff --git a/dashboard/src/resource_inventory/admin.py b/dashboard/src/resource_inventory/admin.py index e063cc0..7ff510b 100644 --- a/dashboard/src/resource_inventory/admin.py +++ b/dashboard/src/resource_inventory/admin.py @@ -32,7 +32,8 @@ from resource_inventory.models import ( OPNFVConfig, OPNFVRole, Image, - HostConfiguration + HostConfiguration, + RemoteInfo ) profiles = [HostProfile, InterfaceProfile, DiskProfile, CpuProfile, RamProfile] @@ -47,6 +48,6 @@ physical = [Host, Interface, Network, Vlan, ResourceBundle] admin.site.register(physical) -config = [Scenario, Installer, Opsys, ConfigBundle, OPNFVConfig, OPNFVRole, Image, HostConfiguration] +config = [Scenario, Installer, Opsys, ConfigBundle, OPNFVConfig, OPNFVRole, Image, HostConfiguration, RemoteInfo] admin.site.register(config) diff --git a/dashboard/src/resource_inventory/idf_templater.py b/dashboard/src/resource_inventory/idf_templater.py new file mode 100644 index 0000000..7cd13bb --- /dev/null +++ b/dashboard/src/resource_inventory/idf_templater.py @@ -0,0 +1,148 @@ +############################################################################## +# Copyright (c) 2019 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.template.loader import render_to_string + +from account.models import PublicNetwork + +from resource_inventory.models import ( + OPNFVConfig, + Vlan +) + + +class IDFTemplater: + """ + Utility class to create a full IDF yaml file + """ + def __init__(self): + self.net_names = ["admin", "mgmt", "private", "public"] + self.networks = {} + for i, name in enumerate(self.net_names): + self.networks[name] = { + "name": name, + "vlan": -1, + "interface": i, + "ip": "10.250." + str(i) + ".0", + "netmask": 24 + } + + def makeIDF(self, booking): + """ + fills the installer descriptor file template with info about the resource + """ + template = "dashboard/idf.yaml" + info = {} + info['version'] = "0.1" + info['net_config'] = self.get_net_config(booking) + info['fuel'] = self.get_fuel_config(booking) + + return render_to_string(template, context=info) + + def get_net_config(self, booking): + net_config = {} + try: + net_config['oob'] = self.get_oob_net(booking) + except Exception: + net_config['oob'] = {} + try: + net_config['public'] = self.get_public_net(booking) + except Exception: + net_config['public'] = {} + + for net in [net for net in self.net_names if net != "public"]: + try: + net_config[net] = self.get_single_net_config(booking, net) + except Exception: + net_config[net] = {} + + return net_config + + def get_public_net(self, booking): + public = {} + config = OPNFVConfig.objects.get(bundle=booking.config_bundle) + public_role = config.networks.get(name="public") + public_vlan = Vlan.objects.filter(network=public_role.network).first() + public_network = PublicNetwork.objects.get(vlan=public_vlan.vlan_id, lab=booking.lab) + self.networks['public']['vlan'] = public_vlan.vlan_id + public['interface'] = self.networks['public']['interface'] + public['vlan'] = public_network.vlan # untagged?? + public['network'] = public_network.cidr.split("/")[0] + public['mask'] = public_network.cidr.split("/")[1] + # public['ip_range'] = 4 # necesary? + public['gateway'] = public_network.gateway + public['dns'] = ["1.1.1.1", "8.8.8.8"] + + return public + + def get_oob_net(self, booking): + net = {} + hosts = booking.resource.hosts.all() + addrs = [host.remote_management.address for host in hosts] + net['ip_range'] = ",".join(addrs) + net['vlan'] = "native" + return net + + def get_single_net_config(self, booking, net_name): + config = OPNFVConfig.objects.get(bundle=booking.config_bundle) + role = config.networks.get(name=net_name) + vlan = Vlan.objects.filter(network=role.network).first() + self.networks[net_name]['vlan'] = vlan.vlan_id + net = {} + net['interface'] = self.networks[net_name]['interface'] + net['vlan'] = vlan.vlan_id + net['network'] = self.networks[net_name]['ip'] + net['mask'] = self.networks[net_name]['netmask'] + + return net + + def get_fuel_config(self, booking): + fuel = {} + fuel['jumphost'] = {} + try: + fuel['jumphost']['bridges'] = self.get_fuel_bridges() + except Exception: + fuel['jumphost']['bridges'] = {} + + fuel['network'] = {} + try: + fuel['network']['nodes'] = self.get_fuel_nodes(booking) + except Exception: + fuel['network']['nodes'] = {} + + return fuel + + def get_fuel_bridges(self): + bridges = {} + for net in self.net_names: + bridges[net] = "br-" + net + + return bridges + + def get_fuel_nodes(self, booking): + hosts = booking.resource.hosts.exclude(config__opnfvRole__name="jumphost") + nodes = [] + for host in hosts: + node = {} + ordered_interfaces = self.get_node_interfaces(host) + node['interfaces'] = [iface['name'] for iface in ordered_interfaces] + node['bus_addrs'] = [iface['bus'] for iface in ordered_interfaces] + nodes.append(node) + + return nodes + + def get_node_interfaces(self, node): + # TODO: this should sync with pdf ordering + interfaces = [] + + for iface in node.interfaces.all(): + interfaces.append({"name": iface.name, "bus": iface.bus_address}) + + return interfaces diff --git a/dashboard/src/resource_inventory/pdf_templater.py b/dashboard/src/resource_inventory/pdf_templater.py index 9f7e7f1..2db2129 100644 --- a/dashboard/src/resource_inventory/pdf_templater.py +++ b/dashboard/src/resource_inventory/pdf_templater.py @@ -69,10 +69,6 @@ class PDFTemplater: """ jumphost = Host.objects.get(bundle=resource, config__opnfvRole__name__iexact="jumphost") jumphost_info = cls.get_pdf_host(jumphost) - remote_params = jumphost_info['remote_management'] # jumphost has extra block not in normal hosts - remote_params.pop("address") - remote_params.pop("mac_address") - jumphost_info['remote_params'] = remote_params jumphost_info['os'] = jumphost.config.image.os.name return jumphost_info @@ -105,7 +101,7 @@ class PDFTemplater: for interface in host.interfaces.all(): host_info['interfaces'].append(cls.get_pdf_host_iface(interface)) - host_info['remote_management'] = cls.get_pdf_host_remote_management(host) + host_info['remote'] = cls.get_pdf_host_remote_management(host) return host_info @@ -163,11 +159,12 @@ class PDFTemplater: """ gives the remote params of the host """ + man = host.remote_management mgmt = {} - mgmt['address'] = "I dunno" - mgmt['mac_address'] = "I dunno" - mgmt['pass'] = "I dunno" - mgmt['type'] = "I dunno" - mgmt['user'] = "I dunno" - mgmt['versions'] = ["I dunno"] + mgmt['address'] = man.address + mgmt['mac_address'] = man.mac_address + mgmt['pass'] = man.password + mgmt['type'] = man.management_type + mgmt['user'] = man.user + mgmt['versions'] = [man.versions] return mgmt diff --git a/dashboard/src/templates/dashboard/idf.yaml b/dashboard/src/templates/dashboard/idf.yaml index 5da20c4..9e0cc26 100644 --- a/dashboard/src/templates/dashboard/idf.yaml +++ b/dashboard/src/templates/dashboard/idf.yaml @@ -1,8 +1,9 @@ +--- idf: version: {{version|default:"0.1"}} net_config: oob: - ip-range: {{net_config.oob.ip-range}} + ip-range: {{net_config.oob.ip_range}} vlan: {{net_config.oob.vlan}} admin: interface: {{net_config.admin.interface}} @@ -24,13 +25,11 @@ idf: vlan: {{net_config.public.vlan}} network: {{net_config.public.network}} mask: {{net_config.public.mask}} - ip-range: {{net_config.public.ip-range}} + ip-range: {{net_config.public.ip_range}} mask: {{net_config.public.mask}} gateway: {{net_config.public.gateway}} - dns: - {% for serv in net_config.public.dns %} - - {{serv}} - {% endfor %} + dns: {% for serv in net_config.public.dns %} + - {{serv}}{% endfor %} fuel: jumphost: bridges: @@ -38,15 +37,10 @@ idf: mgmt: {{fuel.jumphost.bridges.mgmt}} private: {{fuel.jumphost.bridges.private}} public: {{fuel.jumphost.bridges.public}} - network: - {% for node in fuel.network.nodes %} + network: {% for node in fuel.network.nodes %} node: - - interfaces: - {% for iface in node.interfaces %} - - {{ iface }} - {% endfor %} - - busaddr: - {% for addr in node.bus_addrs %} - - {{addr}} - {% endfor %} + - interfaces: {% for iface in node.interfaces %} + - {{ iface }}{% endfor %} + - busaddr: {% for addr in node.bus_addrs %} + - {{addr}}{% endfor %} {% endfor %} -- cgit 1.2.3-korg