From 04b676a8bc7209b8017395dc9bb36086283ac72c Mon Sep 17 00:00:00 2001 From: Sawyer Bergeron Date: Tue, 9 Apr 2019 16:30:57 -0400 Subject: Implement OPNFV workflow This is a counterpart to an update to network models, and allows for configuring baremetal OPNFV and Openstack deploys Change-Id: I0185dbfa6c9105d7e63a7e7d7dd1f5cf228a8877 Signed-off-by: Sawyer Bergeron Signed-off-by: Parker Berberian --- src/resource_inventory/idf_templater.py | 14 +++--- .../migrations/0010_auto_20190430_1405.py | 54 ++++++++++++++++++++++ src/resource_inventory/models.py | 20 +++++++- src/resource_inventory/pdf_templater.py | 34 ++++++++++---- 4 files changed, 105 insertions(+), 17 deletions(-) create mode 100644 src/resource_inventory/migrations/0010_auto_20190430_1405.py (limited to 'src/resource_inventory') diff --git a/src/resource_inventory/idf_templater.py b/src/resource_inventory/idf_templater.py index 7cd13bb..26307e3 100644 --- a/src/resource_inventory/idf_templater.py +++ b/src/resource_inventory/idf_templater.py @@ -12,10 +12,7 @@ from django.template.loader import render_to_string from account.models import PublicNetwork -from resource_inventory.models import ( - OPNFVConfig, - Vlan -) +from resource_inventory.models import Vlan class IDFTemplater: @@ -67,7 +64,7 @@ class IDFTemplater: def get_public_net(self, booking): public = {} - config = OPNFVConfig.objects.get(bundle=booking.config_bundle) + config = booking.opnfv_config 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) @@ -91,7 +88,7 @@ class IDFTemplater: return net def get_single_net_config(self, booking, net_name): - config = OPNFVConfig.objects.get(bundle=booking.config_bundle) + config = booking.opnfv_config role = config.networks.get(name=net_name) vlan = Vlan.objects.filter(network=role.network).first() self.networks[net_name]['vlan'] = vlan.vlan_id @@ -127,7 +124,10 @@ class IDFTemplater: return bridges def get_fuel_nodes(self, booking): - hosts = booking.resource.hosts.exclude(config__opnfvRole__name="jumphost") + jumphost = booking.opnfv_config.host_opnfv_config.get( + role__name__iexact="jumphost" + ) + hosts = booking.resource.hosts.exclude(pk=jumphost.pk) nodes = [] for host in hosts: node = {} diff --git a/src/resource_inventory/migrations/0010_auto_20190430_1405.py b/src/resource_inventory/migrations/0010_auto_20190430_1405.py new file mode 100644 index 0000000..3823eaf --- /dev/null +++ b/src/resource_inventory/migrations/0010_auto_20190430_1405.py @@ -0,0 +1,54 @@ +# Generated by Django 2.1 on 2019-04-30 14:05 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('resource_inventory', '0009_auto_20190315_1757'), + ] + + operations = [ + migrations.CreateModel( + name='HostOPNFVConfig', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ], + ), + migrations.RemoveField( + model_name='hostconfiguration', + name='opnfvRole', + ), + migrations.AddField( + model_name='hostconfiguration', + name='is_head_node', + field=models.BooleanField(default=False), + ), + migrations.AddField( + model_name='opnfvconfig', + name='description', + field=models.CharField(blank=True, default='', max_length=600), + ), + migrations.AddField( + model_name='opnfvconfig', + name='name', + field=models.CharField(blank=True, default='', max_length=300), + ), + migrations.AddField( + model_name='hostopnfvconfig', + name='host_config', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='host_opnfv_config', to='resource_inventory.HostConfiguration'), + ), + migrations.AddField( + model_name='hostopnfvconfig', + name='opnfv_config', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='host_opnfv_config', to='resource_inventory.OPNFVConfig'), + ), + migrations.AddField( + model_name='hostopnfvconfig', + name='role', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='host_opnfv_configs', to='resource_inventory.OPNFVRole'), + ), + ] diff --git a/src/resource_inventory/models.py b/src/resource_inventory/models.py index d3f47d4..b9f2c44 100644 --- a/src/resource_inventory/models.py +++ b/src/resource_inventory/models.py @@ -191,7 +191,7 @@ class ResourceBundle(models.Model): return "instance of " + str(self.template) def get_host(self, role="Jumphost"): - return Host.objects.filter(bundle=self, config__opnfvRole__name=role).first() + return Host.objects.filter(bundle=self, config__is_head_node=True).first() # should only ever be one, but it is not an invariant in the models class GenericInterface(models.Model): @@ -252,6 +252,8 @@ class OPNFVConfig(models.Model): scenario = models.ForeignKey(Scenario, on_delete=models.CASCADE) bundle = models.ForeignKey(ConfigBundle, related_name="opnfv_config", on_delete=models.CASCADE) networks = models.ManyToManyField(NetworkRole) + name = models.CharField(max_length=300, blank=True, default="") + description = models.CharField(max_length=600, blank=True, default="") def __str__(self): return "OPNFV job with " + str(self.installer) + " and " + str(self.scenario) @@ -297,12 +299,18 @@ class HostConfiguration(models.Model): host = models.ForeignKey(GenericHost, related_name="configuration", on_delete=models.CASCADE) image = models.ForeignKey(Image, on_delete=models.PROTECT) bundle = models.ForeignKey(ConfigBundle, related_name="hostConfigurations", null=True, on_delete=models.CASCADE) - opnfvRole = models.ForeignKey(OPNFVRole, on_delete=models.SET(get_sentinal_opnfv_role)) + is_head_node = models.BooleanField(default=False) def __str__(self): return "config with " + str(self.host) + " and image " + str(self.image) +class HostOPNFVConfig(models.Model): + role = models.ForeignKey(OPNFVRole, related_name="host_opnfv_configs", on_delete=models.CASCADE) + host_config = models.ForeignKey(HostConfiguration, related_name="host_opnfv_config", on_delete=models.CASCADE) + opnfv_config = models.ForeignKey(OPNFVConfig, related_name="host_opnfv_config", on_delete=models.CASCADE) + + class RemoteInfo(models.Model): address = models.CharField(max_length=15) mac_address = models.CharField(max_length=17) @@ -353,3 +361,11 @@ class Interface(models.Model): def __str__(self): return self.mac_address + " on host " + str(self.host) + + +class OPNFV_SETTINGS(): + """ + This is a static configuration class + """ + # all the required network types in PDF/IDF spec + NETWORK_ROLES = ["public", "private", "admin", "mgmt"] diff --git a/src/resource_inventory/pdf_templater.py b/src/resource_inventory/pdf_templater.py index 2db2129..d08b303 100644 --- a/src/resource_inventory/pdf_templater.py +++ b/src/resource_inventory/pdf_templater.py @@ -19,15 +19,15 @@ class PDFTemplater: """ @classmethod - def makePDF(cls, resource): + def makePDF(cls, booking): """ fills the pod descriptor file template with info about the resource """ template = "dashboard/pdf.yaml" info = {} - info['details'] = cls.get_pdf_details(resource) - info['jumphost'] = cls.get_pdf_jumphost(resource) - info['nodes'] = cls.get_pdf_nodes(resource) + info['details'] = cls.get_pdf_details(booking.resource) + info['jumphost'] = cls.get_pdf_jumphost(booking) + info['nodes'] = cls.get_pdf_nodes(booking) return render_to_string(template, context=info) @@ -63,22 +63,40 @@ class PDFTemplater: return details @classmethod - def get_pdf_jumphost(cls, resource): + def get_jumphost(cls, booking): + jumphost = None + if booking.opnfv_config: + jumphost_opnfv_config = booking.opnfv_config.host_opnfv_config.get( + role__name__iexact="jumphost" + ) + jumphost = booking.resource.hosts.get(config=jumphost_opnfv_config.host_config) + else: # if there is no opnfv config, use headnode + jumphost = Host.objects.filter( + bundle=booking.resource, + config__is_head_node=True + ).first() + + return jumphost + + @classmethod + def get_pdf_jumphost(cls, booking): """ returns a dict of all the info for the "jumphost" section """ - jumphost = Host.objects.get(bundle=resource, config__opnfvRole__name__iexact="jumphost") + jumphost = cls.get_jumphost(booking) jumphost_info = cls.get_pdf_host(jumphost) jumphost_info['os'] = jumphost.config.image.os.name return jumphost_info @classmethod - def get_pdf_nodes(cls, resource): + def get_pdf_nodes(cls, booking): """ returns a list of all the "nodes" (every host except jumphost) """ pdf_nodes = [] - nodes = Host.objects.filter(bundle=resource).exclude(config__opnfvRole__name__iexact="jumphost") + nodes = set(Host.objects.filter(bundle=booking.resource)) + nodes.discard(cls.get_jumphost(booking)) + for node in nodes: pdf_nodes.append(cls.get_pdf_host(node)) -- cgit 1.2.3-korg