aboutsummaryrefslogtreecommitdiffstats
path: root/src/resource_inventory
diff options
context:
space:
mode:
authorGergely Csatari <gergely.csatari@nokia.com>2023-10-26 10:33:28 +0300
committerGergely Csatari <gergely.csatari@nokia.com>2023-10-26 10:34:28 +0300
commit2ec0d7b9f5c1354977b821c6b06c24a3ffa13142 (patch)
tree6e449d92ddfc880ed007e9d8a8f25bda8fc7cb0f /src/resource_inventory
parent0d3dd290aa6e7f39e7b0b3cbe448b6622f924240 (diff)
Removing project content and adding a noteHEADmaster
that the development continues in GitHub Change-Id: I25c58a679dbf92b2367d826429b7cda936bf9f0e Signed-off-by: Gergely Csatari <gergely.csatari@nokia.com>
Diffstat (limited to 'src/resource_inventory')
-rw-r--r--src/resource_inventory/__init__.py8
-rw-r--r--src/resource_inventory/admin.py70
-rw-r--r--src/resource_inventory/apps.py14
-rw-r--r--src/resource_inventory/forms.py31
-rw-r--r--src/resource_inventory/idf_templater.py148
-rw-r--r--src/resource_inventory/migrations/0001_initial.py328
-rw-r--r--src/resource_inventory/migrations/0002_auto_20180919_1459.py18
-rw-r--r--src/resource_inventory/migrations/0003_vlan_public.py18
-rw-r--r--src/resource_inventory/migrations/0004_auto_20181017_1532.py28
-rw-r--r--src/resource_inventory/migrations/0005_image_os.py19
-rw-r--r--src/resource_inventory/migrations/0006_auto_20190124_1700.py76
-rw-r--r--src/resource_inventory/migrations/0007_auto_20190306_1616.py31
-rw-r--r--src/resource_inventory/migrations/0008_host_remote_management.py19
-rw-r--r--src/resource_inventory/migrations/0009_auto_20190315_1757.py73
-rw-r--r--src/resource_inventory/migrations/0010_auto_20190430_1405.py54
-rw-r--r--src/resource_inventory/migrations/0011_auto_20191106_2024.py33
-rw-r--r--src/resource_inventory/migrations/0012_auto_20200103_1850.py59
-rw-r--r--src/resource_inventory/migrations/0012_manual_20200218_1536.py25
-rw-r--r--src/resource_inventory/migrations/0013_auto_20200218_1536.py407
-rw-r--r--src/resource_inventory/migrations/0014_auto_20200305_1415.py18
-rw-r--r--src/resource_inventory/migrations/0015_resourcetemplate_copy_of.py19
-rw-r--r--src/resource_inventory/migrations/0016_auto_20201109_1947.py59
-rw-r--r--src/resource_inventory/migrations/0017_auto_20201218_1516.py18
-rw-r--r--src/resource_inventory/migrations/0018_auto_20210630_1629.py101
-rw-r--r--src/resource_inventory/migrations/0019_auto_20210701_1947.py43
-rw-r--r--src/resource_inventory/migrations/0020_cloudinitfile.py21
-rw-r--r--src/resource_inventory/migrations/0021_resourceconfiguration_cloud_init_files.py18
-rw-r--r--src/resource_inventory/migrations/0022_auto_20210925_2028.py23
-rw-r--r--src/resource_inventory/migrations/0023_cloudinitfile_generated.py18
-rw-r--r--src/resource_inventory/migrations/__init__.py0
-rw-r--r--src/resource_inventory/models.py705
-rw-r--r--src/resource_inventory/pdf_templater.py176
-rw-r--r--src/resource_inventory/resource_manager.py197
-rw-r--r--src/resource_inventory/tests/test_managers.py301
-rw-r--r--src/resource_inventory/tests/test_models.py173
-rw-r--r--src/resource_inventory/urls.py36
-rw-r--r--src/resource_inventory/views.py38
37 files changed, 0 insertions, 3423 deletions
diff --git a/src/resource_inventory/__init__.py b/src/resource_inventory/__init__.py
deleted file mode 100644
index f903394..0000000
--- a/src/resource_inventory/__init__.py
+++ /dev/null
@@ -1,8 +0,0 @@
-##############################################################################
-# Copyright (c) 2018 Sawyer Bergeron, Parker Berberian, 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
-##############################################################################
diff --git a/src/resource_inventory/admin.py b/src/resource_inventory/admin.py
deleted file mode 100644
index 2444a98..0000000
--- a/src/resource_inventory/admin.py
+++ /dev/null
@@ -1,70 +0,0 @@
-##############################################################################
-# Copyright (c) 2016 Max Breitenfeldt 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.contrib import admin
-
-from resource_inventory.forms import InterfaceConfigurationForm
-
-from resource_inventory.models import (
- ResourceProfile,
- InterfaceProfile,
- DiskProfile,
- CpuProfile,
- RamProfile,
- ResourceTemplate,
- ResourceConfiguration,
- InterfaceConfiguration,
- Server,
- Interface,
- Network,
- Vlan,
- ResourceBundle,
- Scenario,
- Installer,
- Opsys,
- OPNFVConfig,
- OPNFVRole,
- Image,
- RemoteInfo,
- PhysicalNetwork,
- NetworkConnection,
-)
-
-
-admin.site.register([
- ResourceProfile,
- InterfaceProfile,
- DiskProfile,
- CpuProfile,
- RamProfile,
- ResourceTemplate,
- ResourceConfiguration,
- Server,
- Interface,
- Network,
- Vlan,
- ResourceBundle,
- Scenario,
- Installer,
- Opsys,
- OPNFVConfig,
- OPNFVRole,
- Image,
- PhysicalNetwork,
- NetworkConnection,
- RemoteInfo]
-)
-
-
-class InterfaceConfigurationAdmin(admin.ModelAdmin):
- form = InterfaceConfigurationForm
-
-
-admin.site.register(InterfaceConfiguration, InterfaceConfigurationAdmin)
diff --git a/src/resource_inventory/apps.py b/src/resource_inventory/apps.py
deleted file mode 100644
index 79768a7..0000000
--- a/src/resource_inventory/apps.py
+++ /dev/null
@@ -1,14 +0,0 @@
-##############################################################################
-# Copyright (c) 2016 Max Breitenfeldt 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.apps import AppConfig
-
-
-class ResourcesConfig(AppConfig):
- name = 'hwresource'
diff --git a/src/resource_inventory/forms.py b/src/resource_inventory/forms.py
deleted file mode 100644
index fb8c102..0000000
--- a/src/resource_inventory/forms.py
+++ /dev/null
@@ -1,31 +0,0 @@
-##############################################################################
-# Copyright (c) 2020 Sawyer Bergeron, Sean Smith, 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.core.exceptions import ValidationError
-from django import forms
-
-from resource_inventory.models import Network, InterfaceConfiguration
-
-
-class InterfaceConfigurationForm(forms.ModelForm):
- class Meta:
- model = InterfaceConfiguration
- fields = ['profile', 'resource_config', 'connections']
-
- def clean(self):
- connections = self.cleaned_data.get('connections')
- resource_config = self.cleaned_data.get('resource_config')
-
- valid_nets = set(Network.objects.filter(bundle=resource_config.template))
- curr_nets = set([conn.network for conn in connections])
-
- if not curr_nets.issubset(valid_nets):
- raise ValidationError("Cannot have network connection to network outside pod")
-
- return self.cleaned_data
diff --git a/src/resource_inventory/idf_templater.py b/src/resource_inventory/idf_templater.py
deleted file mode 100644
index 8f0f924..0000000
--- a/src/resource_inventory/idf_templater.py
+++ /dev/null
@@ -1,148 +0,0 @@
-##############################################################################
-# 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 Vlan
-
-
-class IDFTemplater:
- """Utility class to create a full Installer Descriptor File (IDF) yaml file."""
-
- net_names = ["admin", "mgmt", "private", "public"]
- bridge_names = {
- "admin": "br-admin",
- "mgmt": "br-mgmt",
- "private": "br-private",
- "public": "br-public"
- }
-
- def __init__(self):
- 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):
- """Fill the IDF 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 = 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)
- 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 = 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
- 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):
- return self.bridge_names
-
- def get_fuel_nodes(self, booking):
- 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 = {}
- 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/src/resource_inventory/migrations/0001_initial.py b/src/resource_inventory/migrations/0001_initial.py
deleted file mode 100644
index d01e8e7..0000000
--- a/src/resource_inventory/migrations/0001_initial.py
+++ /dev/null
@@ -1,328 +0,0 @@
-# Generated by Django 2.1 on 2018-09-14 14:48
-
-from django.conf import settings
-import django.core.validators
-from django.db import migrations, models
-import django.db.models.deletion
-
-
-class Migration(migrations.Migration):
-
- initial = True
-
- dependencies = [
- migrations.swappable_dependency(settings.AUTH_USER_MODEL),
- ('account', '0001_initial'),
- ]
-
- operations = [
- migrations.CreateModel(
- name='ConfigBundle',
- fields=[
- ('id', models.AutoField(primary_key=True, serialize=False)),
- ('name', models.CharField(max_length=200, unique=True)),
- ('description', models.CharField(default='', max_length=1000)),
- ],
- ),
- migrations.CreateModel(
- name='CpuProfile',
- fields=[
- ('id', models.AutoField(primary_key=True, serialize=False)),
- ('cores', models.IntegerField()),
- ('architecture', models.CharField(choices=[('x86_64', 'x86_64'), ('aarch64', 'aarch64')], max_length=50)),
- ('cpus', models.IntegerField()),
- ('cflags', models.TextField(null=True)),
- ],
- ),
- migrations.CreateModel(
- name='DiskProfile',
- fields=[
- ('id', models.AutoField(primary_key=True, serialize=False)),
- ('size', models.IntegerField()),
- ('media_type', models.CharField(choices=[('SSD', 'SSD'), ('HDD', 'HDD')], max_length=50)),
- ('name', models.CharField(max_length=50)),
- ('rotation', models.IntegerField(default=0)),
- ('interface', models.CharField(choices=[('sata', 'sata'), ('sas', 'sas'), ('ssd', 'ssd'), ('nvme', 'nvme'), ('scsi', 'scsi'), ('iscsi', 'iscsi')], default='sata', max_length=50)),
- ],
- ),
- migrations.CreateModel(
- name='GenericHost',
- fields=[
- ('id', models.AutoField(primary_key=True, serialize=False)),
- ],
- ),
- migrations.CreateModel(
- name='GenericInterface',
- fields=[
- ('id', models.AutoField(primary_key=True, serialize=False)),
- ('host', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='generic_interfaces', to='resource_inventory.GenericHost')),
- ],
- ),
- migrations.CreateModel(
- name='GenericResource',
- fields=[
- ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('name', models.CharField(max_length=200, validators=[django.core.validators.RegexValidator(message='Enter a valid hostname. Full domain name may be 1-253 characters, each hostname 1-63 characters (including suffixed dot), and valid characters for hostnames are A-Z, a-z, 0-9, hyphen (-), and underscore (_)', regex='(?=^.{1,253}$)(?=(^([A-Za-z0-9\\-\\_]{1,62}\\.)*[A-Za-z0-9\\-\\_]{1,63}$))')])),
- ],
- ),
- migrations.CreateModel(
- name='GenericResourceBundle',
- fields=[
- ('id', models.AutoField(primary_key=True, serialize=False)),
- ('name', models.CharField(max_length=300, unique=True)),
- ('xml', models.TextField()),
- ('description', models.CharField(default='', max_length=1000)),
- ('lab', models.ForeignKey(null=True, on_delete=django.db.models.deletion.DO_NOTHING, to='account.Lab')),
- ('owner', models.ForeignKey(null=True, on_delete=django.db.models.deletion.DO_NOTHING, to=settings.AUTH_USER_MODEL)),
- ],
- ),
- migrations.CreateModel(
- name='Host',
- fields=[
- ('id', models.AutoField(primary_key=True, serialize=False)),
- ('booked', models.BooleanField(default=False)),
- ('name', models.CharField(max_length=200, unique=True)),
- ('labid', models.CharField(default='default_id', max_length=200)),
- ('working', models.BooleanField(default=True)),
- ('vendor', models.CharField(default='unknown', max_length=100)),
- ('model', models.CharField(default='unknown', max_length=150)),
- ],
- ),
- migrations.CreateModel(
- name='HostConfiguration',
- fields=[
- ('id', models.AutoField(primary_key=True, serialize=False)),
- ('bundle', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='hostConfigurations', to='resource_inventory.ConfigBundle')),
- ('host', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='configuration', to='resource_inventory.GenericHost')),
- ],
- ),
- migrations.CreateModel(
- name='HostProfile',
- fields=[
- ('id', models.AutoField(primary_key=True, serialize=False)),
- ('host_type', models.PositiveSmallIntegerField()),
- ('name', models.CharField(max_length=200, unique=True)),
- ('description', models.TextField()),
- ('labs', models.ManyToManyField(related_name='hostprofiles', to='account.Lab')),
- ],
- ),
- migrations.CreateModel(
- name='Image',
- fields=[
- ('id', models.AutoField(primary_key=True, serialize=False)),
- ('lab_id', models.IntegerField()),
- ('name', models.CharField(max_length=200)),
- ('public', models.BooleanField(default=True)),
- ('description', models.TextField()),
- ('from_lab', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='account.Lab')),
- ('host_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='resource_inventory.HostProfile')),
- ('owner', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)),
- ],
- ),
- migrations.CreateModel(
- name='Installer',
- fields=[
- ('id', models.AutoField(primary_key=True, serialize=False)),
- ('name', models.CharField(max_length=200)),
- ],
- ),
- migrations.CreateModel(
- name='Interface',
- fields=[
- ('id', models.AutoField(primary_key=True, serialize=False)),
- ('mac_address', models.CharField(max_length=17)),
- ('bus_address', models.CharField(max_length=50)),
- ('name', models.CharField(default='eth0', max_length=100)),
- ],
- ),
- migrations.CreateModel(
- name='InterfaceProfile',
- fields=[
- ('id', models.AutoField(primary_key=True, serialize=False)),
- ('speed', models.IntegerField()),
- ('name', models.CharField(max_length=100)),
- ('nic_type', models.CharField(choices=[('onboard', 'onboard'), ('pcie', 'pcie')], default='onboard', max_length=50)),
- ('host', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='interfaceprofile', to='resource_inventory.HostProfile')),
- ],
- ),
- migrations.CreateModel(
- name='Network',
- fields=[
- ('id', models.AutoField(primary_key=True, serialize=False)),
- ('vlan_id', models.IntegerField()),
- ('name', models.CharField(max_length=100)),
- ],
- ),
- migrations.CreateModel(
- name='OPNFVConfig',
- fields=[
- ('id', models.AutoField(primary_key=True, serialize=False)),
- ('bundle', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='opnfv_config', to='resource_inventory.ConfigBundle')),
- ('installer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='resource_inventory.Installer')),
- ],
- ),
- migrations.CreateModel(
- name='OPNFVRole',
- fields=[
- ('id', models.AutoField(primary_key=True, serialize=False)),
- ('name', models.CharField(max_length=200)),
- ('description', models.TextField()),
- ],
- ),
- migrations.CreateModel(
- name='Opsys',
- fields=[
- ('id', models.AutoField(primary_key=True, serialize=False)),
- ('name', models.CharField(max_length=100)),
- ('sup_installers', models.ManyToManyField(blank=True, to='resource_inventory.Installer')),
- ],
- ),
- migrations.CreateModel(
- name='RamProfile',
- fields=[
- ('id', models.AutoField(primary_key=True, serialize=False)),
- ('amount', models.IntegerField()),
- ('channels', models.IntegerField()),
- ('host', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='ramprofile', to='resource_inventory.HostProfile')),
- ],
- ),
- migrations.CreateModel(
- name='ResourceBundle',
- fields=[
- ('id', models.AutoField(primary_key=True, serialize=False)),
- ('template', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='resource_inventory.GenericResourceBundle')),
- ],
- ),
- migrations.CreateModel(
- name='Scenario',
- fields=[
- ('id', models.AutoField(primary_key=True, serialize=False)),
- ('name', models.CharField(max_length=300)),
- ],
- ),
- migrations.CreateModel(
- name='Vlan',
- fields=[
- ('id', models.AutoField(primary_key=True, serialize=False)),
- ('vlan_id', models.IntegerField()),
- ('tagged', models.BooleanField()),
- ],
- ),
- migrations.CreateModel(
- name='GenericPod',
- fields=[
- ('genericresource_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='resource_inventory.GenericResource')),
- ],
- bases=('resource_inventory.genericresource',),
- ),
- migrations.AddField(
- model_name='opnfvconfig',
- name='scenario',
- field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='resource_inventory.Scenario'),
- ),
- migrations.AddField(
- model_name='interface',
- name='config',
- field=models.ManyToManyField(to='resource_inventory.Vlan'),
- ),
- migrations.AddField(
- model_name='interface',
- name='host',
- field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='interfaces', to='resource_inventory.Host'),
- ),
- migrations.AddField(
- model_name='installer',
- name='sup_scenarios',
- field=models.ManyToManyField(blank=True, to='resource_inventory.Scenario'),
- ),
- migrations.AddField(
- model_name='hostconfiguration',
- name='image',
- field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='resource_inventory.Image'),
- ),
- migrations.AddField(
- model_name='hostconfiguration',
- name='opnfvRole',
- field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='resource_inventory.OPNFVRole'),
- ),
- migrations.AddField(
- model_name='host',
- name='bundle',
- field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='hosts', to='resource_inventory.ResourceBundle'),
- ),
- migrations.AddField(
- model_name='host',
- name='config',
- field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='configuration', to='resource_inventory.HostConfiguration'),
- ),
- migrations.AddField(
- model_name='host',
- name='lab',
- field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='account.Lab'),
- ),
- migrations.AddField(
- model_name='host',
- name='profile',
- field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='resource_inventory.HostProfile'),
- ),
- migrations.AddField(
- model_name='host',
- name='template',
- field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='resource_inventory.GenericHost'),
- ),
- migrations.AddField(
- model_name='genericresource',
- name='bundle',
- field=models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='generic_resources', to='resource_inventory.GenericResourceBundle'),
- ),
- migrations.AddField(
- model_name='genericinterface',
- name='profile',
- field=models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='resource_inventory.InterfaceProfile'),
- ),
- migrations.AddField(
- model_name='genericinterface',
- name='vlans',
- field=models.ManyToManyField(to='resource_inventory.Vlan'),
- ),
- migrations.AddField(
- model_name='generichost',
- name='profile',
- field=models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='resource_inventory.HostProfile'),
- ),
- migrations.AddField(
- model_name='generichost',
- name='resource',
- field=models.OneToOneField(on_delete=django.db.models.deletion.DO_NOTHING, related_name='generic_host', to='resource_inventory.GenericResource'),
- ),
- migrations.AddField(
- model_name='diskprofile',
- name='host',
- field=models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='storageprofile', to='resource_inventory.HostProfile'),
- ),
- migrations.AddField(
- model_name='cpuprofile',
- name='host',
- field=models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='cpuprofile', to='resource_inventory.HostProfile'),
- ),
- migrations.AddField(
- model_name='configbundle',
- name='bundle',
- field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='resource_inventory.GenericResourceBundle'),
- ),
- migrations.AddField(
- model_name='configbundle',
- name='owner',
- field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
- ),
- migrations.AddField(
- model_name='genericpod',
- name='hosts',
- field=models.ManyToManyField(to='resource_inventory.GenericHost'),
- ),
- migrations.AddField(
- model_name='genericpod',
- name='networks',
- field=models.ManyToManyField(to='resource_inventory.Network'),
- ),
- ]
diff --git a/src/resource_inventory/migrations/0002_auto_20180919_1459.py b/src/resource_inventory/migrations/0002_auto_20180919_1459.py
deleted file mode 100644
index 80c9e6f..0000000
--- a/src/resource_inventory/migrations/0002_auto_20180919_1459.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Generated by Django 2.1 on 2018-09-19 14:59
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('resource_inventory', '0001_initial'),
- ]
-
- operations = [
- migrations.AlterField(
- model_name='hostprofile',
- name='host_type',
- field=models.PositiveSmallIntegerField(default=0),
- ),
- ]
diff --git a/src/resource_inventory/migrations/0003_vlan_public.py b/src/resource_inventory/migrations/0003_vlan_public.py
deleted file mode 100644
index 07dc647..0000000
--- a/src/resource_inventory/migrations/0003_vlan_public.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Generated by Django 2.1 on 2018-09-26 14:41
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('resource_inventory', '0002_auto_20180919_1459'),
- ]
-
- operations = [
- migrations.AddField(
- model_name='vlan',
- name='public',
- field=models.BooleanField(default=False),
- ),
- ]
diff --git a/src/resource_inventory/migrations/0004_auto_20181017_1532.py b/src/resource_inventory/migrations/0004_auto_20181017_1532.py
deleted file mode 100644
index 3a7475c..0000000
--- a/src/resource_inventory/migrations/0004_auto_20181017_1532.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# Generated by Django 2.1 on 2018-10-17 15:32
-
-from django.db import migrations
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('resource_inventory', '0003_vlan_public'),
- ]
-
- operations = [
- migrations.RemoveField(
- model_name='genericpod',
- name='genericresource_ptr',
- ),
- migrations.RemoveField(
- model_name='genericpod',
- name='hosts',
- ),
- migrations.RemoveField(
- model_name='genericpod',
- name='networks',
- ),
- migrations.DeleteModel(
- name='GenericPod',
- ),
- ]
diff --git a/src/resource_inventory/migrations/0005_image_os.py b/src/resource_inventory/migrations/0005_image_os.py
deleted file mode 100644
index ede008e..0000000
--- a/src/resource_inventory/migrations/0005_image_os.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# Generated by Django 2.1 on 2019-01-10 16:18
-
-from django.db import migrations, models
-import django.db.models.deletion
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('resource_inventory', '0004_auto_20181017_1532'),
- ]
-
- operations = [
- migrations.AddField(
- model_name='image',
- name='os',
- field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='resource_inventory.Opsys'),
- ),
- ]
diff --git a/src/resource_inventory/migrations/0006_auto_20190124_1700.py b/src/resource_inventory/migrations/0006_auto_20190124_1700.py
deleted file mode 100644
index a5a972f..0000000
--- a/src/resource_inventory/migrations/0006_auto_20190124_1700.py
+++ /dev/null
@@ -1,76 +0,0 @@
-# Generated by Django 2.1 on 2019-01-24 17:00
-
-from django.conf import settings
-from django.db import migrations, models
-import django.db.models.deletion
-import resource_inventory.models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('resource_inventory', '0005_image_os'),
- ]
-
- operations = [
- migrations.AlterField(
- model_name='cpuprofile',
- name='host',
- field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='cpuprofile', to='resource_inventory.HostProfile'),
- ),
- migrations.AlterField(
- model_name='diskprofile',
- name='host',
- field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='storageprofile', to='resource_inventory.HostProfile'),
- ),
- migrations.AlterField(
- model_name='generichost',
- name='profile',
- field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='resource_inventory.HostProfile'),
- ),
- migrations.AlterField(
- model_name='generichost',
- name='resource',
- field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='generic_host', to='resource_inventory.GenericResource'),
- ),
- migrations.AlterField(
- model_name='genericinterface',
- name='host',
- field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='generic_interfaces', to='resource_inventory.GenericHost'),
- ),
- migrations.AlterField(
- model_name='genericresource',
- name='bundle',
- field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='generic_resources', to='resource_inventory.GenericResourceBundle'),
- ),
- migrations.AlterField(
- model_name='genericresourcebundle',
- name='lab',
- field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='account.Lab'),
- ),
- migrations.AlterField(
- model_name='genericresourcebundle',
- name='owner',
- field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL),
- ),
- migrations.AlterField(
- model_name='hostconfiguration',
- name='opnfvRole',
- field=models.ForeignKey(on_delete=models.SET(resource_inventory.models.get_sentinal_opnfv_role), to='resource_inventory.OPNFVRole'),
- ),
- migrations.AlterField(
- model_name='interfaceprofile',
- name='host',
- field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='interfaceprofile', to='resource_inventory.HostProfile'),
- ),
- migrations.AlterField(
- model_name='ramprofile',
- name='host',
- field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='ramprofile', to='resource_inventory.HostProfile'),
- ),
- migrations.AlterField(
- model_name='resourcebundle',
- name='template',
- field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='resource_inventory.GenericResourceBundle'),
- ),
- ]
diff --git a/src/resource_inventory/migrations/0007_auto_20190306_1616.py b/src/resource_inventory/migrations/0007_auto_20190306_1616.py
deleted file mode 100644
index 19a49c5..0000000
--- a/src/resource_inventory/migrations/0007_auto_20190306_1616.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# Generated by Django 2.1 on 2019-03-06 16:16
-
-from django.db import migrations, models
-import django.db.models.deletion
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('resource_inventory', '0006_auto_20190124_1700'),
- ]
-
- operations = [
- migrations.CreateModel(
- name='RemoteInfo',
- fields=[
- ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('address', models.CharField(max_length=15)),
- ('mac_address', models.CharField(max_length=17)),
- ('password', models.CharField(max_length=100)),
- ('user', models.CharField(max_length=100)),
- ('management_type', models.CharField(default='ipmi', max_length=50)),
- ('versions', models.CharField(max_length=100)),
- ],
- ),
- migrations.AlterField(
- model_name='genericinterface',
- name='profile',
- field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='resource_inventory.InterfaceProfile'),
- ),
- ]
diff --git a/src/resource_inventory/migrations/0008_host_remote_management.py b/src/resource_inventory/migrations/0008_host_remote_management.py
deleted file mode 100644
index f74a535..0000000
--- a/src/resource_inventory/migrations/0008_host_remote_management.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# Generated by Django 2.1 on 2019-03-06 16:42
-
-from django.db import migrations, models
-import resource_inventory.models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('resource_inventory', '0007_auto_20190306_1616'),
- ]
-
- operations = [
- migrations.AddField(
- model_name='host',
- name='remote_management',
- field=models.ForeignKey(default=resource_inventory.models.get_default_remote_info, on_delete=models.SET(resource_inventory.models.get_default_remote_info), to='resource_inventory.RemoteInfo'),
- ),
- ]
diff --git a/src/resource_inventory/migrations/0009_auto_20190315_1757.py b/src/resource_inventory/migrations/0009_auto_20190315_1757.py
deleted file mode 100644
index 92ed0e9..0000000
--- a/src/resource_inventory/migrations/0009_auto_20190315_1757.py
+++ /dev/null
@@ -1,73 +0,0 @@
-# Generated by Django 2.1 on 2019-03-15 17:57
-
-from django.db import migrations, models
-import django.db.models.deletion
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('resource_inventory', '0008_host_remote_management'),
- ]
-
- operations = [
- migrations.CreateModel(
- name='NetworkConnection',
- fields=[
- ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('vlan_is_tagged', models.BooleanField()),
- ],
- ),
- migrations.CreateModel(
- name='NetworkRole',
- fields=[
- ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('name', models.CharField(max_length=100)),
- ],
- ),
- migrations.RemoveField(
- model_name='genericinterface',
- name='vlans',
- ),
- migrations.RemoveField(
- model_name='network',
- name='vlan_id',
- ),
- migrations.AddField(
- model_name='network',
- name='bundle',
- field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, related_name='networks', to='resource_inventory.GenericResourceBundle'),
- preserve_default=False,
- ),
- migrations.AddField(
- model_name='network',
- name='is_public',
- field=models.BooleanField(default=False),
- preserve_default=False,
- ),
- migrations.AddField(
- model_name='vlan',
- name='network',
- field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.DO_NOTHING, to='resource_inventory.Network'),
- ),
- migrations.AddField(
- model_name='networkrole',
- name='network',
- field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='resource_inventory.Network'),
- ),
- migrations.AddField(
- model_name='networkconnection',
- name='network',
- field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='resource_inventory.Network'),
- ),
- migrations.AddField(
- model_name='genericinterface',
- name='connections',
- field=models.ManyToManyField(to='resource_inventory.NetworkConnection'),
- ),
- migrations.AddField(
- model_name='opnfvconfig',
- name='networks',
- field=models.ManyToManyField(to='resource_inventory.NetworkRole'),
- ),
- ]
diff --git a/src/resource_inventory/migrations/0010_auto_20190430_1405.py b/src/resource_inventory/migrations/0010_auto_20190430_1405.py
deleted file mode 100644
index 3823eaf..0000000
--- a/src/resource_inventory/migrations/0010_auto_20190430_1405.py
+++ /dev/null
@@ -1,54 +0,0 @@
-# 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/migrations/0011_auto_20191106_2024.py b/src/resource_inventory/migrations/0011_auto_20191106_2024.py
deleted file mode 100644
index bde9f9d..0000000
--- a/src/resource_inventory/migrations/0011_auto_20191106_2024.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# Generated by Django 2.2 on 2019-11-06 20:24
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('resource_inventory', '0010_auto_20190430_1405'),
- ]
-
- operations = [
- migrations.AddField(
- model_name='configbundle',
- name='hidden',
- field=models.BooleanField(default=False),
- ),
- migrations.AddField(
- model_name='configbundle',
- name='public',
- field=models.BooleanField(default=False),
- ),
- migrations.AddField(
- model_name='genericresourcebundle',
- name='hidden',
- field=models.BooleanField(default=False),
- ),
- migrations.AddField(
- model_name='genericresourcebundle',
- name='public',
- field=models.BooleanField(default=False),
- ),
- ]
diff --git a/src/resource_inventory/migrations/0012_auto_20200103_1850.py b/src/resource_inventory/migrations/0012_auto_20200103_1850.py
deleted file mode 100644
index 65d8f85..0000000
--- a/src/resource_inventory/migrations/0012_auto_20200103_1850.py
+++ /dev/null
@@ -1,59 +0,0 @@
-# Generated by Django 2.2 on 2020-01-03 18:50
-
-from django.db import migrations, models
-import django.db.models.deletion
-
-
-def pairVlanPhysicalNetworks(apps, editor):
- PhysicalNetwork = apps.get_model("resource_inventory", "PhysicalNetwork")
- Vlan = apps.get_model("resource_inventory", "Vlan")
- for vlan in Vlan.objects.filter(network__isnull=False):
- if PhysicalNetwork.objects.filter(id=vlan.network.id).exists():
- continue
- PhysicalNetwork.objects.create(id=vlan.network.id, vlan_id=vlan.vlan_id, generic_network=vlan.network)
-
-
-def deletePhysicalNetworks(apps, editor):
- Vlan = apps.get_model("resource_inventory", "Vlan")
- for vlan in Vlan.objects.all():
- vlan.network = None
- PhysicalNetwork = apps.get_model("resource_inventory", "PhysicalNetwork")
- PhysicalNetwork.objects.all().delete()
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('resource_inventory', '0011_auto_20191106_2024'),
- ]
-
- operations = [
- migrations.CreateModel(
- name='PhysicalNetwork',
- fields=[
- ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('vlan_id', models.IntegerField()),
- ('generic_network', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='resource_inventory.Network')),
- ],
- options={
- 'abstract': False,
- },
- ),
- migrations.AlterField(
- model_name='host',
- name='id',
- field=models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
- ),
- migrations.AlterField(
- model_name='resourcebundle',
- name='id',
- field=models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
- ),
- migrations.RunPython(pairVlanPhysicalNetworks, deletePhysicalNetworks),
- migrations.AlterField(
- model_name='vlan',
- name='network',
- field=models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING,
- to='resource_inventory.PhysicalNetwork', null=True),
- ),
- ]
diff --git a/src/resource_inventory/migrations/0012_manual_20200218_1536.py b/src/resource_inventory/migrations/0012_manual_20200218_1536.py
deleted file mode 100644
index 378bdc3..0000000
--- a/src/resource_inventory/migrations/0012_manual_20200218_1536.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# Generated by Django 2.2 on 2020-02-18 15:36
-
-from django.conf import settings
-from django.db import migrations
-
-
-def clear_networks(apps, schema_editor):
- Network = apps.get_model('resource_inventory', 'Network')
- Vlan = apps.get_model('resource_inventory', 'Vlan')
- for vlan in Vlan.objects.all():
- vlan.delete()
- for net in Network.objects.all():
- net.delete()
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- migrations.swappable_dependency(settings.AUTH_USER_MODEL),
- ('resource_inventory', '0012_auto_20200103_1850'),
- ]
-
- operations = [
- migrations.RunPython(clear_networks)
- ]
diff --git a/src/resource_inventory/migrations/0013_auto_20200218_1536.py b/src/resource_inventory/migrations/0013_auto_20200218_1536.py
deleted file mode 100644
index 053453b..0000000
--- a/src/resource_inventory/migrations/0013_auto_20200218_1536.py
+++ /dev/null
@@ -1,407 +0,0 @@
-# Generated by Django 2.2 on 2020-02-18 15:36
-
-from django.conf import settings
-from django.db import migrations, models
-import django.db.models.deletion
-import resource_inventory.models
-
-
-def clear_resource_bundles(apps, schema_editor):
- ResourceBundle = apps.get_model('resource_inventory', 'ResourceBundle')
- for rb in ResourceBundle.objects.all():
- rb.template = None
- rb.save()
-
-
-def create_default_template(apps, schema_editor):
- ResourceTemplate = apps.get_model('resource_inventory', 'ResourceTemplate')
- ResourceTemplate.objects.create(name="Default Template", hidden=True)
-
-
-def populate_servers(apps, schema_editor):
- """Convert old Host models to Server Resources."""
- Host = apps.get_model('resource_inventory', 'Host')
- Server = apps.get_model('resource_inventory', 'Server')
- ResourceProfile = apps.get_model('resource_inventory', 'ResourceProfile')
- for h in Host.objects.all():
- rp = ResourceProfile.objects.get(id=h.profile.id)
- server = Server.objects.create(
- working=h.working,
- vendor=h.vendor,
- labid=h.labid,
- booked=h.booked,
- name=h.labid,
- lab=h.lab,
- profile=rp
- )
-
- for iface in h.interfaces.all():
- server.interfaces.add(iface)
-
-
-def populate_resource_templates(apps, schema_editor):
- """
- Convert old GenericResourceBundles to ResourceTemplate.
-
- This will be kept blank for now. If, during testing, we realize
- we want to implement this, we will. For now, it seems
- fine to let the old models just die and create
- new ones as needed.
- """
- pass
-
-
-def populate_resource_profiles(apps, schema_editor):
- """
- Convert old HostProfile models to ResourceProfiles.
-
- Also updates all the foreign keys pointed to the old
- host profile. This change was basically only a name change.
- """
- HostProfile = apps.get_model('resource_inventory', 'HostProfile')
- ResourceProfile = apps.get_model('resource_inventory', 'ResourceProfile')
- for hp in HostProfile.objects.all():
- rp = ResourceProfile.objects.create(id=hp.id, name=hp.name, description=hp.description)
- rp.labs.add(*list(hp.labs.all()))
- """
- TODO: link these models together
- rp.interfaceprofile = hp.interfaceprofile
- rp.storageprofile = hp.storageprofile
- rp.cpuprofile = hp.cpuprofile
- rp.ramprofile = hp.ramprofile
- rp.save()
- hp.interfaceprofile.host = rp
- rp.storageprofile.host = rp
- rp.cpuprofile.host = rp
- rp.ramprofile.host = rp
- rp.interfaceprofile.save()
- rp.storageprofile.save()
- rp.cpuprofile.save()
- rp.ramprofile.save()
- """
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- migrations.swappable_dependency(settings.AUTH_USER_MODEL),
- ('booking', '0007_remove_booking_config_bundle'),
- ('account', '0004_downtime'),
- ('api', '0013_manual_20200218_1536'),
- ('resource_inventory', '0012_manual_20200218_1536'),
- ]
-
- operations = [
- migrations.CreateModel(
- name='InterfaceConfiguration',
- fields=[
- ('id', models.AutoField(primary_key=True, serialize=False)),
- ('connections', models.ManyToManyField(to='resource_inventory.NetworkConnection')),
- ],
- ),
- migrations.CreateModel(
- name='ResourceConfiguration',
- fields=[
- ('id', models.AutoField(primary_key=True, serialize=False)),
- ('is_head_node', models.BooleanField(default=False)),
- ],
- ),
- migrations.CreateModel(
- name='ResourceOPNFVConfig',
- fields=[
- ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ],
- ),
- migrations.CreateModel(
- name='ResourceProfile',
- fields=[
- ('id', models.AutoField(primary_key=True, serialize=False)),
- ('name', models.CharField(max_length=200, unique=True)),
- ('description', models.TextField()),
- ('labs', models.ManyToManyField(related_name='resourceprofiles', to='account.Lab')),
- ],
- ),
- migrations.RunPython(populate_resource_profiles),
- migrations.CreateModel(
- name='ResourceTemplate',
- fields=[
- ('id', models.AutoField(primary_key=True, serialize=False)),
- ('name', models.CharField(max_length=300, unique=True)),
- ('xml', models.TextField()),
- ('description', models.CharField(default='', max_length=1000)),
- ('public', models.BooleanField(default=False)),
- ('hidden', models.BooleanField(default=False)),
- ('lab', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='resourcetemplates', to='account.Lab')),
- ('owner', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)),
- ],
- ),
- migrations.RunPython(populate_resource_templates),
- migrations.CreateModel(
- name='Server',
- fields=[
- ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('working', models.BooleanField(default=True)),
- ('vendor', models.CharField(default='unknown', max_length=100)),
- ('model', models.CharField(default='unknown', max_length=150)),
- ('labid', models.CharField(default='default_id', max_length=200, unique=True)),
- ('booked', models.BooleanField(default=False)),
- ('name', models.CharField(max_length=200, unique=True)),
- ],
- options={
- 'abstract': False,
- },
- ),
- migrations.AddField(
- model_name='server',
- name='bundle',
- field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='resource_inventory.ResourceBundle'),
- ),
- migrations.AddField(
- model_name='server',
- name='config',
- field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='resource_inventory.ResourceConfiguration'),
- ),
- migrations.AddField(
- model_name='server',
- name='interfaces',
- field=models.ManyToManyField(to='resource_inventory.Interface'),
- ),
- migrations.AddField(
- model_name='server',
- name='lab',
- field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='account.Lab'),
- ),
- migrations.AddField(
- model_name='server',
- name='profile',
- field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='resource_inventory.ResourceProfile'),
- ),
- migrations.AddField(
- model_name='server',
- name='remote_management',
- field=models.ForeignKey(default=resource_inventory.models.get_default_remote_info, on_delete=models.SET(resource_inventory.models.get_default_remote_info), to='resource_inventory.RemoteInfo'),
- ),
- migrations.RunPython(populate_servers),
- migrations.RemoveField(
- model_name='generichost',
- name='profile',
- ),
- migrations.RemoveField(
- model_name='generichost',
- name='resource',
- ),
- migrations.RemoveField(
- model_name='genericinterface',
- name='connections',
- ),
- migrations.RemoveField(
- model_name='genericinterface',
- name='host',
- ),
- migrations.RemoveField(
- model_name='genericinterface',
- name='profile',
- ),
- migrations.RemoveField(
- model_name='genericresource',
- name='bundle',
- ),
- migrations.RemoveField(
- model_name='genericresourcebundle',
- name='lab',
- ),
- migrations.RemoveField(
- model_name='genericresourcebundle',
- name='owner',
- ),
- migrations.RemoveField(
- model_name='host',
- name='bundle',
- ),
- migrations.RemoveField(
- model_name='host',
- name='config',
- ),
- migrations.RemoveField(
- model_name='host',
- name='lab',
- ),
- migrations.RemoveField(
- model_name='host',
- name='profile',
- ),
- migrations.RemoveField(
- model_name='host',
- name='remote_management',
- ),
- migrations.RemoveField(
- model_name='host',
- name='template',
- ),
- migrations.RemoveField(
- model_name='hostconfiguration',
- name='bundle',
- ),
- migrations.RemoveField(
- model_name='hostconfiguration',
- name='host',
- ),
- migrations.RemoveField(
- model_name='hostconfiguration',
- name='image',
- ),
- migrations.RemoveField(
- model_name='hostopnfvconfig',
- name='host_config',
- ),
- migrations.RemoveField(
- model_name='hostopnfvconfig',
- name='opnfv_config',
- ),
- migrations.RemoveField(
- model_name='hostopnfvconfig',
- name='role',
- ),
- migrations.RemoveField(
- model_name='hostprofile',
- name='labs',
- ),
- migrations.RemoveField(
- model_name='interface',
- name='host',
- ),
- migrations.RemoveField(
- model_name='interface',
- name='name',
- ),
- migrations.RemoveField(
- model_name='opnfvconfig',
- name='bundle',
- ),
- migrations.AddField(
- model_name='interface',
- name='profile',
- field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='resource_inventory.InterfaceProfile'),
- preserve_default=False,
- ),
- migrations.AddField(
- model_name='interfaceprofile',
- name='order',
- field=models.IntegerField(default=-1),
- ),
- migrations.AlterField(
- model_name='cpuprofile',
- name='host',
- field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='cpuprofile', to='resource_inventory.ResourceProfile'),
- ),
- migrations.AlterField(
- model_name='diskprofile',
- name='host',
- field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='storageprofile', to='resource_inventory.ResourceProfile'),
- ),
- migrations.AlterField(
- model_name='image',
- name='host_type',
- field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='resource_inventory.ResourceProfile'),
- ),
- migrations.AlterField(
- model_name='interfaceprofile',
- name='host',
- field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='interfaceprofile', to='resource_inventory.ResourceProfile'),
- ),
- migrations.AlterField(
- model_name='network',
- name='bundle',
- field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='networks', to='resource_inventory.ResourceTemplate'),
- ),
- migrations.AlterField(
- model_name='ramprofile',
- name='host',
- field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='ramprofile', to='resource_inventory.ResourceProfile'),
- ),
- migrations.RunPython(clear_resource_bundles),
- migrations.AlterField(
- model_name='resourcebundle',
- name='template',
- field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='resource_inventory.ResourceTemplate'),
- ),
- migrations.DeleteModel(
- name='ConfigBundle',
- ),
- migrations.DeleteModel(
- name='GenericHost',
- ),
- migrations.DeleteModel(
- name='GenericInterface',
- ),
- migrations.DeleteModel(
- name='GenericResource',
- ),
- migrations.DeleteModel(
- name='GenericResourceBundle',
- ),
- migrations.DeleteModel(
- name='HostConfiguration',
- ),
- migrations.DeleteModel(
- name='HostOPNFVConfig',
- ),
- migrations.DeleteModel(
- name='HostProfile',
- ),
- migrations.DeleteModel(
- name='Host',
- ),
- migrations.AddField(
- model_name='resourceopnfvconfig',
- name='opnfv_config',
- field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='resource_opnfv_config', to='resource_inventory.OPNFVConfig'),
- ),
- migrations.AddField(
- model_name='resourceopnfvconfig',
- name='resource_config',
- field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='resource_opnfv_config', to='resource_inventory.ResourceConfiguration'),
- ),
- migrations.AddField(
- model_name='resourceopnfvconfig',
- name='role',
- field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='resource_opnfv_configs', to='resource_inventory.OPNFVRole'),
- ),
- migrations.AddField(
- model_name='resourceconfiguration',
- name='image',
- field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='resource_inventory.Image'),
- ),
- migrations.AddField(
- model_name='resourceconfiguration',
- name='profile',
- field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='resource_inventory.ResourceProfile'),
- ),
- migrations.AddField(
- model_name='resourceconfiguration',
- name='template',
- field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='resourceConfigurations', to='resource_inventory.ResourceTemplate'),
- ),
- migrations.AddField(
- model_name='interfaceconfiguration',
- name='profile',
- field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='resource_inventory.InterfaceProfile'),
- ),
- migrations.AddField(
- model_name='interfaceconfiguration',
- name='resource_config',
- field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='interface_configs', to='resource_inventory.ResourceConfiguration'),
- ),
- migrations.AddField(
- model_name='interface',
- name='acts_as',
- field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.SET_NULL, to='resource_inventory.InterfaceConfiguration'),
- ),
- migrations.RunPython(create_default_template),
- migrations.AddField(
- model_name='opnfvconfig',
- name='template',
- field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, related_name='opnfv_config', to='resource_inventory.ResourceTemplate'),
- preserve_default=False,
- ),
- ]
diff --git a/src/resource_inventory/migrations/0014_auto_20200305_1415.py b/src/resource_inventory/migrations/0014_auto_20200305_1415.py
deleted file mode 100644
index 6fcf4a6..0000000
--- a/src/resource_inventory/migrations/0014_auto_20200305_1415.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Generated by Django 2.2 on 2020-03-05 14:15
-
-from django.db import migrations
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('resource_inventory', '0013_auto_20200218_1536'),
- ]
-
- operations = [
- migrations.RenameField(
- model_name='resourcetemplate',
- old_name='hidden',
- new_name='temporary',
- ),
- ]
diff --git a/src/resource_inventory/migrations/0015_resourcetemplate_copy_of.py b/src/resource_inventory/migrations/0015_resourcetemplate_copy_of.py
deleted file mode 100644
index 322dc00..0000000
--- a/src/resource_inventory/migrations/0015_resourcetemplate_copy_of.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# Generated by Django 2.2 on 2020-04-13 13:56
-
-from django.db import migrations, models
-import django.db.models.deletion
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('resource_inventory', '0014_auto_20200305_1415'),
- ]
-
- operations = [
- migrations.AddField(
- model_name='resourcetemplate',
- name='copy_of',
- field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='resource_inventory.ResourceTemplate'),
- ),
- ]
diff --git a/src/resource_inventory/migrations/0016_auto_20201109_1947.py b/src/resource_inventory/migrations/0016_auto_20201109_1947.py
deleted file mode 100644
index d145f06..0000000
--- a/src/resource_inventory/migrations/0016_auto_20201109_1947.py
+++ /dev/null
@@ -1,59 +0,0 @@
-# Generated by Django 2.2 on 2020-11-09 19:47
-
-from django.db import migrations, models
-import django.db.models.deletion
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('resource_inventory', '0015_resourcetemplate_copy_of'),
- ]
-
- operations = [
- migrations.AddField(
- model_name='physicalnetwork',
- name='bundle',
- field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='resource_inventory.ResourceBundle'),
- ),
- migrations.AddField(
- model_name='resourceconfiguration',
- name='name',
- field=models.CharField(default='<Hostname>', max_length=3000),
- ),
- migrations.AlterField(
- model_name='cpuprofile',
- name='cflags',
- field=models.TextField(blank=True, null=True),
- ),
- migrations.AlterField(
- model_name='interface',
- name='acts_as',
- field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='resource_inventory.InterfaceConfiguration'),
- ),
- migrations.AlterField(
- model_name='interfaceconfiguration',
- name='connections',
- field=models.ManyToManyField(blank=True, to='resource_inventory.NetworkConnection'),
- ),
- migrations.AlterField(
- model_name='resourcetemplate',
- name='copy_of',
- field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='resource_inventory.ResourceTemplate'),
- ),
- migrations.AlterField(
- model_name='resourcetemplate',
- name='name',
- field=models.CharField(max_length=300),
- ),
- migrations.AlterField(
- model_name='server',
- name='bundle',
- field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='resource_inventory.ResourceBundle'),
- ),
- migrations.AlterField(
- model_name='server',
- name='config',
- field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='resource_inventory.ResourceConfiguration'),
- ),
- ]
diff --git a/src/resource_inventory/migrations/0017_auto_20201218_1516.py b/src/resource_inventory/migrations/0017_auto_20201218_1516.py
deleted file mode 100644
index d4884de..0000000
--- a/src/resource_inventory/migrations/0017_auto_20201218_1516.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Generated by Django 2.2 on 2020-12-18 15:16
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('resource_inventory', '0016_auto_20201109_1947'),
- ]
-
- operations = [
- migrations.AlterField(
- model_name='resourceconfiguration',
- name='name',
- field=models.CharField(default='opnfv_host', max_length=3000),
- ),
- ]
diff --git a/src/resource_inventory/migrations/0018_auto_20210630_1629.py b/src/resource_inventory/migrations/0018_auto_20210630_1629.py
deleted file mode 100644
index 19e53e4..0000000
--- a/src/resource_inventory/migrations/0018_auto_20210630_1629.py
+++ /dev/null
@@ -1,101 +0,0 @@
-# Generated by Django 2.2 on 2021-06-30 16:29
-
-from django.db import migrations, models
-import django.db.models.deletion
-from account.models import Lab
-
-
-def set_availability(apps, schema_editor):
- models = [apps.get_model('resource_inventory', 'Image'), apps.get_model('resource_inventory', 'Opsys')]
-
- for model in models:
- for obj in model.objects.all():
- obj.available = False
- obj.obsolete = True
- obj.save()
-
-
-def set_rconfig_arch(apps, schema_editor):
- rprofs = apps.get_model('resource_inventory', 'ResourceProfile')
-
- for rprof in rprofs.objects.all():
- rprof.architecture = rprof.cpuprofile.first().architecture
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('account', '0009_auto_20210324_2107'),
- ('resource_inventory', '0017_auto_20201218_1516'),
- ]
-
- operations = [
- migrations.RemoveField(
- model_name='image',
- name='host_type',
- ),
- migrations.AlterField(
- model_name='image',
- name='lab_id',
- field=models.CharField(default='none (retired)', max_length=100),
- preserve_default=True,
- ),
- migrations.RemoveField(
- model_name='opsys',
- name='sup_installers',
- ),
-
- migrations.AddField(
- model_name='image',
- name='architecture',
- field=models.CharField(choices=[('x86_64', 'x86_64'), ('aarch64', 'aarch64'), ('unknown', 'unknown')], default='unknown', max_length=50),
- preserve_default=False,
- ),
-
- migrations.AddField(
- model_name='image',
- name='available',
- field=models.BooleanField(default=True),
- ),
- migrations.AddField(
- model_name='image',
- name='obsolete',
- field=models.BooleanField(default=False),
- ),
-
- migrations.AddField(
- model_name='opsys',
- name='available',
- field=models.BooleanField(default=False),
- ),
- migrations.AddField(
- model_name='opsys',
- name='obsolete',
- field=models.BooleanField(default=True),
- ),
-
- migrations.RunPython(set_availability),
-
- migrations.AddField(
- model_name='opsys',
- name='lab_id',
- field=models.CharField(default="none (retired)", max_length=100),
- preserve_default=False,
- ),
-
- migrations.AddField(
- model_name='opsys',
- name='from_lab',
- field=models.ForeignKey(default=Lab.objects.first, on_delete=django.db.models.deletion.CASCADE, to='account.Lab'),
- preserve_default=False,
- ),
-
- migrations.AddField(
- model_name='resourceprofile',
- name='architecture',
- field=models.CharField(choices=[('x86_64', 'x86_64'), ('aarch64', 'aarch64'), ('unknown', 'unknown')], default='unknown', max_length=50),
- preserve_default=False,
- ),
-
- migrations.RunPython(set_rconfig_arch),
- ]
diff --git a/src/resource_inventory/migrations/0019_auto_20210701_1947.py b/src/resource_inventory/migrations/0019_auto_20210701_1947.py
deleted file mode 100644
index e64d174..0000000
--- a/src/resource_inventory/migrations/0019_auto_20210701_1947.py
+++ /dev/null
@@ -1,43 +0,0 @@
-# Generated by Django 2.2 on 2021-07-01 19:47
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('resource_inventory', '0018_auto_20210630_1629'),
- ]
-
- operations = [
- migrations.AlterField(
- model_name='image',
- name='lab_id',
- field=models.CharField(max_length=100),
- ),
- migrations.AlterField(
- model_name='image',
- name='name',
- field=models.CharField(max_length=100),
- ),
- migrations.AlterField(
- model_name='network',
- name='name',
- field=models.CharField(max_length=200),
- ),
- migrations.AlterField(
- model_name='opsys',
- name='available',
- field=models.BooleanField(default=True),
- ),
- migrations.AlterField(
- model_name='opsys',
- name='obsolete',
- field=models.BooleanField(default=False),
- ),
- migrations.AlterField(
- model_name='resourceprofile',
- name='architecture',
- field=models.CharField(choices=[('x86_64', 'x86_64'), ('aarch64', 'aarch64')], max_length=50),
- ),
- ]
diff --git a/src/resource_inventory/migrations/0020_cloudinitfile.py b/src/resource_inventory/migrations/0020_cloudinitfile.py
deleted file mode 100644
index 198181c..0000000
--- a/src/resource_inventory/migrations/0020_cloudinitfile.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# Generated by Django 2.2 on 2021-09-07 14:48
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('resource_inventory', '0019_auto_20210701_1947'),
- ]
-
- operations = [
- migrations.CreateModel(
- name='CloudInitFile',
- fields=[
- ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('text', models.TextField()),
- ('priority', models.IntegerField()),
- ],
- ),
- ]
diff --git a/src/resource_inventory/migrations/0021_resourceconfiguration_cloud_init_files.py b/src/resource_inventory/migrations/0021_resourceconfiguration_cloud_init_files.py
deleted file mode 100644
index 6b0befc..0000000
--- a/src/resource_inventory/migrations/0021_resourceconfiguration_cloud_init_files.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Generated by Django 2.2 on 2021-09-10 18:10
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('resource_inventory', '0020_cloudinitfile'),
- ]
-
- operations = [
- migrations.AddField(
- model_name='resourceconfiguration',
- name='cloud_init_files',
- field=models.ManyToManyField(blank=True, to='resource_inventory.CloudInitFile'),
- ),
- ]
diff --git a/src/resource_inventory/migrations/0022_auto_20210925_2028.py b/src/resource_inventory/migrations/0022_auto_20210925_2028.py
deleted file mode 100644
index 2b0b902..0000000
--- a/src/resource_inventory/migrations/0022_auto_20210925_2028.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# Generated by Django 2.2 on 2021-09-25 20:28
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('resource_inventory', '0021_resourceconfiguration_cloud_init_files'),
- ]
-
- operations = [
- migrations.AddField(
- model_name='resourcetemplate',
- name='private_vlan_pool',
- field=models.TextField(default=''),
- ),
- migrations.AddField(
- model_name='resourcetemplate',
- name='public_vlan_pool',
- field=models.TextField(default=''),
- ),
- ]
diff --git a/src/resource_inventory/migrations/0023_cloudinitfile_generated.py b/src/resource_inventory/migrations/0023_cloudinitfile_generated.py
deleted file mode 100644
index b309753..0000000
--- a/src/resource_inventory/migrations/0023_cloudinitfile_generated.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Generated by Django 2.2 on 2021-12-17 18:54
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('resource_inventory', '0022_auto_20210925_2028'),
- ]
-
- operations = [
- migrations.AddField(
- model_name='cloudinitfile',
- name='generated',
- field=models.BooleanField(default=False),
- ),
- ]
diff --git a/src/resource_inventory/migrations/__init__.py b/src/resource_inventory/migrations/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/src/resource_inventory/migrations/__init__.py
+++ /dev/null
diff --git a/src/resource_inventory/models.py b/src/resource_inventory/models.py
deleted file mode 100644
index 5d87430..0000000
--- a/src/resource_inventory/models.py
+++ /dev/null
@@ -1,705 +0,0 @@
-##############################################################################
-# Copyright (c) 2018 Sawyer Bergeron, Parker Berberian, and others.
-# Copyright (c) 2020 Sawyer Bergeron, Sean Smith, 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.contrib.auth.models import User
-
-from django.core.exceptions import ValidationError
-from django.db import models
-from django.db.models import Q
-import traceback
-import json
-
-import re
-from collections import Counter
-
-from account.models import Lab
-from dashboard.utils import AbstractModelQuery
-
-"""
-Profiles of resources hosted by labs.
-
-These describe hardware attributes of the different Resources a lab hosts.
-A single Resource subclass (e.g. Server) may have instances that point to different
-Profile models (e.g. an x86 server profile and armv8 server profile.
-"""
-
-
-class ResourceProfile(models.Model):
- id = models.AutoField(primary_key=True)
- name = models.CharField(max_length=200, unique=True)
- architecture = models.CharField(max_length=50, choices=[
- ("x86_64", "x86_64"),
- ("aarch64", "aarch64")
- ])
- description = models.TextField()
- labs = models.ManyToManyField(Lab, related_name="resourceprofiles")
-
- def validate(self):
- validname = re.compile(r"^[A-Za-z0-9\-\_\.\/\, ]+$")
- if not validname.match(self.name):
- return "Invalid host profile name given. Name must only use A-Z, a-z, 0-9, hyphens, underscores, dots, commas, or spaces."
- else:
- return None
-
- def __str__(self):
- return self.name
-
- def get_resources(self, lab=None, working=True, unreserved=False):
- """
- Return a list of Resource objects which have this profile.
-
- If lab is provided, only resources at that lab will be returned.
- If working=True, will only return working hosts
- """
- resources = []
- query = Q(profile=self)
- if lab:
- query = query & Q(lab=lab)
- if working:
- query = query & Q(working=True)
-
- resources = ResourceQuery.filter(query)
-
- if unreserved:
- resources = [r for r in resources if not r.is_reserved()]
-
- return resources
-
-
-class InterfaceProfile(models.Model):
- id = models.AutoField(primary_key=True)
- speed = models.IntegerField()
- name = models.CharField(max_length=100)
- host = models.ForeignKey(ResourceProfile, on_delete=models.CASCADE, related_name='interfaceprofile')
- nic_type = models.CharField(
- max_length=50,
- choices=[
- ("onboard", "onboard"),
- ("pcie", "pcie")
- ],
- default="onboard"
- )
- order = models.IntegerField(default=-1)
-
- def __str__(self):
- return self.name + " for " + str(self.host)
-
-
-class DiskProfile(models.Model):
- id = models.AutoField(primary_key=True)
- size = models.IntegerField()
- media_type = models.CharField(max_length=50, choices=[
- ("SSD", "SSD"),
- ("HDD", "HDD")
- ])
- name = models.CharField(max_length=50)
- host = models.ForeignKey(ResourceProfile, on_delete=models.CASCADE, related_name='storageprofile')
- rotation = models.IntegerField(default=0)
- interface = models.CharField(
- max_length=50,
- choices=[
- ("sata", "sata"),
- ("sas", "sas"),
- ("ssd", "ssd"),
- ("nvme", "nvme"),
- ("scsi", "scsi"),
- ("iscsi", "iscsi"),
- ],
- default="sata"
- )
-
- def __str__(self):
- return self.name + " for " + str(self.host)
-
-
-class CpuProfile(models.Model):
- id = models.AutoField(primary_key=True)
- cores = models.IntegerField()
- architecture = models.CharField(max_length=50, choices=[
- ("x86_64", "x86_64"),
- ("aarch64", "aarch64")
- ])
- cpus = models.IntegerField()
- host = models.ForeignKey(ResourceProfile, on_delete=models.CASCADE, related_name='cpuprofile')
- cflags = models.TextField(null=True, blank=True)
-
- def __str__(self):
- return str(self.architecture) + " " + str(self.cpus) + "S" + str(self.cores) + " C for " + str(self.host)
-
-
-class RamProfile(models.Model):
- id = models.AutoField(primary_key=True)
- amount = models.IntegerField()
- channels = models.IntegerField()
- host = models.ForeignKey(ResourceProfile, on_delete=models.CASCADE, related_name='ramprofile')
-
- def __str__(self):
- return str(self.amount) + "G for " + str(self.host)
-
-
-"""
-Resource Models
-
-These models represent actual hardware resources
-with varying degrees of abstraction.
-"""
-
-
-class CloudInitFile(models.Model):
- text = models.TextField()
-
- # higher priority is applied later, so "on top" of existing files
- priority = models.IntegerField()
- generated = models.BooleanField(default=False)
-
- @classmethod
- def merge_strategy(cls):
- return [
- {'name': 'list', 'settings': ['append']},
- {'name': 'dict', 'settings': ['recurse_list', 'replace']},
- ]
-
- @classmethod
- def create(cls, text="", priority=0):
- return CloudInitFile.objects.create(priority=priority, text=text)
-
-
-class ResourceTemplate(models.Model):
- """
- Models a "template" of a complete, configured collection of resources that can be booked.
-
- For example, this may represent a Pharos POD. This model is a template of the actual
- resources that will be booked. This model can be "instantiated" into real resource models
- across multiple different bookings.
- """
-
- # TODO: template might not be a good name because this is a collection of lots of configured resources
- id = models.AutoField(primary_key=True)
- name = models.CharField(max_length=300)
- xml = models.TextField()
- owner = models.ForeignKey(User, null=True, on_delete=models.SET_NULL)
- lab = models.ForeignKey(Lab, null=True, on_delete=models.SET_NULL, related_name="resourcetemplates")
- description = models.CharField(max_length=1000, default="")
- public = models.BooleanField(default=False)
- temporary = models.BooleanField(default=False)
- copy_of = models.ForeignKey("ResourceTemplate", blank=True, null=True, on_delete=models.SET_NULL)
-
- # if these fields are empty ("") then they are implicitly "every vlan",
- # otherwise we filter any allocations we try to instantiate against this list
- # they should be represented as a json list of integers
- private_vlan_pool = models.TextField(default="")
- public_vlan_pool = models.TextField(default="")
-
- def private_vlan_pool_set(self):
- if self.private_vlan_pool != "":
- return set(json.loads(self.private_vlan_pool))
- else:
- return None
-
- def public_vlan_pool_set(self):
- if self.private_vlan_pool != "":
- return set(json.loads(self.public_vlan_pool))
- else:
- return None
-
- def getConfigs(self):
- configs = self.resourceConfigurations.all()
- return list(configs)
-
- def get_required_resources(self):
- profiles = Counter([str(config.profile) for config in self.getConfigs()])
- return dict(profiles)
-
- def __str__(self):
- return self.name
-
-
-class ResourceBundle(models.Model):
- """
- Collection of Resource objects.
-
- This is just a way of aggregating all the resources in a booking into a single model.
- """
-
- template = models.ForeignKey(ResourceTemplate, on_delete=models.SET_NULL, null=True)
-
- def __str__(self):
- if self.template is None:
- return "Resource bundle " + str(self.id) + " with no template"
- return "instance of " + str(self.template)
-
- def get_resources(self):
- return ResourceQuery.filter(bundle=self)
-
- def get_resource_with_role(self, role):
- # TODO
- pass
-
- def release(self):
- for pn in PhysicalNetwork.objects.filter(bundle=self).all():
- try:
- pn.release()
- except Exception as e:
- print("Exception occurred while trying to release resource ", pn.vlan_id)
- print(e)
- traceback.print_exc()
-
- for resource in self.get_resources():
- try:
- resource.release()
- except Exception as e:
- print("Exception occurred while trying to release resource ", resource)
- print(e)
- traceback.print_exc()
-
- def get_template_name(self):
- if not self.template:
- return ""
- if not self.template.temporary:
- return self.template.name
- return self.template.copy_of.name
-
-
-class ResourceConfiguration(models.Model):
- """Model to represent a complete configuration for a single physical Resource."""
-
- id = models.AutoField(primary_key=True)
- profile = models.ForeignKey(ResourceProfile, on_delete=models.CASCADE)
- image = models.ForeignKey("Image", on_delete=models.PROTECT)
- template = models.ForeignKey(ResourceTemplate, related_name="resourceConfigurations", null=True, on_delete=models.CASCADE)
- is_head_node = models.BooleanField(default=False)
- name = models.CharField(max_length=3000, default="opnfv_host")
-
- cloud_init_files = models.ManyToManyField(CloudInitFile, blank=True)
-
- def __str__(self):
- return str(self.name)
-
- def ci_file_list(self):
- return list(self.cloud_init_files.order_by("priority").all())
-
-
-def get_default_remote_info():
- return RemoteInfo.objects.get_or_create(
- address="default",
- mac_address="default",
- password="default",
- user="default",
- management_type="default",
- versions="[default]"
- )[0].pk
-
-
-class Resource(models.Model):
- """
- Super class for all hardware resource models.
-
- Defines methods that must be implemented and common database fields.
- Any new kind of Resource a lab wants to host (White box switch, traffic generator, etc)
- should inherit from this class and fulfill the functional interface
- """
-
- class Meta:
- abstract = True
-
- bundle = models.ForeignKey(ResourceBundle, on_delete=models.SET_NULL, blank=True, null=True)
- profile = models.ForeignKey(ResourceProfile, on_delete=models.CASCADE)
- config = models.ForeignKey(ResourceConfiguration, on_delete=models.SET_NULL, blank=True, null=True)
- working = models.BooleanField(default=True)
- vendor = models.CharField(max_length=100, default="unknown")
- model = models.CharField(max_length=150, default="unknown")
- interfaces = models.ManyToManyField("Interface")
- remote_management = models.ForeignKey("RemoteInfo", default=get_default_remote_info, on_delete=models.SET(get_default_remote_info))
- labid = models.CharField(max_length=200, default="default_id", unique=True)
- lab = models.ForeignKey(Lab, on_delete=models.CASCADE)
-
- def get_configuration(self, state):
- """
- Get configuration of Resource.
-
- Returns the desired configuration for this host as a
- JSON object as defined in the rest api spec.
- state is a ConfigState
- """
- raise NotImplementedError("Must implement in concrete Resource classes")
-
- def reserve(self):
- """Reserve this resource for its currently assigned booking."""
- raise NotImplementedError("Must implement in concrete Resource classes")
-
- def release(self):
- """Make this resource available again for new boookings."""
- raise NotImplementedError("Must implement in concrete Resource classes")
-
- def get_interfaces(self):
- """
- Return a list of interfaces on this resource.
-
- The ordering of interfaces should be consistent.
- """
- raise NotImplementedError("Must implement in concrete Resource classes")
-
- def is_reserved(self):
- """Return True if this Resource is reserved."""
- raise NotImplementedError("Must implement in concrete Resource classes")
-
- def same_instance(self, other):
- """Return True if this Resource is the same instance as other."""
- raise NotImplementedError("Must implement in concrete Resource classes")
-
- def save(self, *args, **kwargs):
- """Assert that labid is unique across all Resource models."""
- res = ResourceQuery.filter(labid=self.labid)
- if len(res) > 1:
- raise ValidationError("Too many resources with labid " + str(self.labid))
-
- if len(res) == 1:
- if not self.same_instance(res[0]):
- raise ValidationError("Too many resources with labid " + str(self.labid))
- super().save(*args, **kwargs)
-
-
-class RemoteInfo(models.Model):
- address = models.CharField(max_length=15)
- mac_address = models.CharField(max_length=17)
- password = models.CharField(max_length=100)
- user = models.CharField(max_length=100)
- management_type = models.CharField(max_length=50, default="ipmi")
- versions = models.CharField(max_length=100) # json serialized list of floats
-
-
-class Server(Resource):
- """Resource subclass - a basic baremetal server."""
-
- booked = models.BooleanField(default=False)
- name = models.CharField(max_length=200, unique=True)
-
- def __str__(self):
- return self.name
-
- def get_configuration(self, state):
- ipmi = state == ConfigState.NEW
- power = "off" if state == ConfigState.CLEAN else "on"
- image = self.config.image.lab_id if self.config else "unknown"
-
- return {
- "id": self.labid,
- "image": image,
- "hostname": self.config.name,
- "power": power,
- "ipmi_create": str(ipmi)
- }
-
- def get_interfaces(self):
- return list(self.interfaces.all().order_by('bus_address'))
-
- def release(self):
- self.bundle = None
- self.booked = False
- self.save()
-
- def reserve(self):
- self.booked = True
- self.save()
-
- def is_reserved(self):
- return self.booked
-
- def same_instance(self, other):
- return isinstance(other, Server) and other.name == self.name
-
-
-def is_serializable(data):
- try:
- json.dumps(data)
- return True
- except Exception:
- return False
-
-
-class Opsys(models.Model):
- id = models.AutoField(primary_key=True)
- name = models.CharField(max_length=100)
- lab_id = models.CharField(max_length=100)
- obsolete = models.BooleanField(default=False)
- available = models.BooleanField(default=True) # marked true by Cobbler if it exists there
- from_lab = models.ForeignKey(Lab, on_delete=models.CASCADE)
-
- indexes = [
- models.Index(fields=['cobbler_id'])
- ]
-
- def new_from_data(data):
- opsys = Opsys()
- opsys.update(data)
- return opsys
-
- def serialize(self):
- d = {}
- for field in vars(self):
- attr = getattr(self, field)
- if is_serializable(attr):
- d[field] = attr
- return d
-
- def update(self, data):
- for field in vars(self):
- if field in data:
- setattr(self, field, data[field] if data[field] else getattr(self, field))
-
- def __str__(self):
- return self.name
-
-
-class Image(models.Model):
- """Model for representing OS images / snapshots of hosts."""
-
- id = models.AutoField(primary_key=True)
- from_lab = models.ForeignKey(Lab, on_delete=models.CASCADE)
- architecture = models.CharField(max_length=50, choices=[
- ("x86_64", "x86_64"),
- ("aarch64", "aarch64"),
- ("unknown", "unknown"),
- ])
- lab_id = models.CharField(max_length=100)
- name = models.CharField(max_length=100)
- owner = models.ForeignKey(User, null=True, on_delete=models.SET_NULL)
- public = models.BooleanField(default=True)
- description = models.TextField()
- os = models.ForeignKey(Opsys, null=True, on_delete=models.CASCADE)
-
- available = models.BooleanField(default=True) # marked True by cobbler if it exists there
- obsolete = models.BooleanField(default=False)
-
- indexes = [
- models.Index(fields=['architecture']),
- models.Index(fields=['cobbler_id'])
- ]
-
- def __str__(self):
- return self.name
-
- def is_obsolete(self):
- return self.obsolete or self.os.obsolete
-
- def serialize(self):
- d = {}
- for field in vars(self):
- attr = getattr(self, field)
- if is_serializable(attr):
- d[field] = attr
- return d
-
- def update(self, data):
- for field in vars(self):
- if field in data:
- setattr(self, field, data[field] if data[field] else getattr(self, field))
-
- def new_from_data(data):
- img = Image()
- img.update(data)
- return img
-
- def in_use(self):
- for resource in ResourceQuery.filter(config__image=self):
- if resource.is_reserved():
- return True
-
- return False
-
-
-"""
-Networking configuration models
-"""
-
-
-class Network(models.Model):
- id = models.AutoField(primary_key=True)
- name = models.CharField(max_length=200)
- bundle = models.ForeignKey(ResourceTemplate, on_delete=models.CASCADE, related_name="networks")
- is_public = models.BooleanField()
-
- def __str__(self):
- return self.name
-
-
-class PhysicalNetwork(models.Model):
- vlan_id = models.IntegerField()
- generic_network = models.ForeignKey(Network, on_delete=models.CASCADE)
- bundle = models.ForeignKey(ResourceBundle, null=True, blank=True, on_delete=models.CASCADE)
-
- def get_configuration(self, state):
- """
- Get the network configuration.
-
- Collects info about each attached network interface and vlan, etc
- """
- return {}
-
- def reserve(self):
- """Reserve vlan(s) associated with this network."""
- return False
-
- def release(self):
- from booking.models import Booking
-
- booking = Booking.objects.get(resource=self.bundle)
- lab = booking.lab
- vlan_manager = lab.vlan_manager
-
- if self.generic_network.is_public:
- vlan_manager.release_public_vlan(self.vlan_id)
- else:
- vlan_manager.release_vlans([self.vlan_id])
- return False
-
- def __str__(self):
- return 'Physical Network for ' + self.generic_network.name
-
-
-class NetworkConnection(models.Model):
- network = models.ForeignKey(Network, on_delete=models.CASCADE)
- vlan_is_tagged = models.BooleanField()
-
- def __str__(self):
- return 'Connection to ' + self.network.name
-
-
-class Vlan(models.Model):
- id = models.AutoField(primary_key=True)
- vlan_id = models.IntegerField()
- tagged = models.BooleanField()
- public = models.BooleanField(default=False)
- network = models.ForeignKey(PhysicalNetwork, on_delete=models.DO_NOTHING, null=True)
-
- def __str__(self):
- return str(self.vlan_id) + ("_T" if self.tagged else "")
-
-
-class InterfaceConfiguration(models.Model):
- id = models.AutoField(primary_key=True)
- profile = models.ForeignKey(InterfaceProfile, on_delete=models.CASCADE)
- resource_config = models.ForeignKey(ResourceConfiguration, on_delete=models.CASCADE, related_name='interface_configs')
- connections = models.ManyToManyField(NetworkConnection, blank=True)
-
- def __str__(self):
- return "type " + str(self.profile) + " on host " + str(self.resource_config)
-
-
-"""
-OPNFV / Software configuration models
-"""
-
-
-class Scenario(models.Model):
- id = models.AutoField(primary_key=True)
- name = models.CharField(max_length=300)
-
- def __str__(self):
- return self.name
-
-
-class Installer(models.Model):
- id = models.AutoField(primary_key=True)
- name = models.CharField(max_length=200)
- sup_scenarios = models.ManyToManyField(Scenario, blank=True)
-
- def __str__(self):
- return self.name
-
-
-class NetworkRole(models.Model):
- name = models.CharField(max_length=100)
- network = models.ForeignKey(Network, on_delete=models.CASCADE)
-
-
-def create_resource_ref_string(for_hosts: [str]) -> str:
- # need to sort the list, then do dump
- for_hosts.sort()
-
- return json.dumps(for_hosts)
-
-
-class OPNFVConfig(models.Model):
- id = models.AutoField(primary_key=True)
- installer = models.ForeignKey(Installer, on_delete=models.CASCADE)
- scenario = models.ForeignKey(Scenario, on_delete=models.CASCADE)
- template = models.ForeignKey(ResourceTemplate, 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)
-
-
-class OPNFVRole(models.Model):
- id = models.AutoField(primary_key=True)
- name = models.CharField(max_length=200)
- description = models.TextField()
-
- def __str__(self):
- return self.name
-
-
-def get_sentinal_opnfv_role():
- return OPNFVRole.objects.get_or_create(name="deleted", description="Role was deleted.")
-
-
-class ResourceOPNFVConfig(models.Model):
- role = models.ForeignKey(OPNFVRole, related_name="resource_opnfv_configs", on_delete=models.CASCADE)
- resource_config = models.ForeignKey(ResourceConfiguration, related_name="resource_opnfv_config", on_delete=models.CASCADE)
- opnfv_config = models.ForeignKey(OPNFVConfig, related_name="resource_opnfv_config", on_delete=models.CASCADE)
-
-
-class Interface(models.Model):
- id = models.AutoField(primary_key=True)
- mac_address = models.CharField(max_length=17)
- bus_address = models.CharField(max_length=50)
- config = models.ManyToManyField(Vlan)
- acts_as = models.OneToOneField(InterfaceConfiguration, blank=True, null=True, on_delete=models.CASCADE)
- profile = models.ForeignKey(InterfaceProfile, on_delete=models.CASCADE)
-
- def __str__(self):
- return self.mac_address + " on host " + str(self.profile.host.name)
-
- def clean(self, *args, **kwargs):
- if self.acts_as and self.acts_as.profile != self.profile:
- raise ValidationError("Interface Configuration's Interface Profile does not match Interface Profile chosen for Interface.")
- super().clean(*args, **kwargs)
-
- def save(self, *args, **kwargs):
- self.full_clean()
- super().save(*args, **kwargs)
-
-
-"""
-Some Enums for dealing with global constants.
-"""
-
-
-class OPNFV_SETTINGS():
- """This is a static configuration class."""
-
- # all the required network types in PDF/IDF spec
- NETWORK_ROLES = ["public", "private", "admin", "mgmt"]
-
-
-class ConfigState:
- NEW = 0
- RESET = 100
- CLEAN = 200
-
-
-RESOURCE_TYPES = [Server]
-
-
-class ResourceQuery(AbstractModelQuery):
- model_list = [Server]
diff --git a/src/resource_inventory/pdf_templater.py b/src/resource_inventory/pdf_templater.py
deleted file mode 100644
index c4b22fe..0000000
--- a/src/resource_inventory/pdf_templater.py
+++ /dev/null
@@ -1,176 +0,0 @@
-##############################################################################
-# Copyright (c) 2018 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
-import booking
-from resource_inventory.models import Server
-
-
-class PDFTemplater:
- """Utility class to create a full PDF yaml file."""
-
- @classmethod
- def makePDF(cls, booking):
- """Fill the pod descriptor file template with info about the resource."""
- template = "dashboard/pdf.yaml"
- info = {}
- info['details'] = cls.get_pdf_details(booking.resource)
- try:
- info['jumphost'] = cls.get_pdf_jumphost(booking)
- except Exception:
- # filling in jumphost info can be optional in some cases, this shouldn't be a hard error
- info['jumphost'] = {}
- info['nodes'] = cls.get_pdf_nodes(booking)
-
- return render_to_string(template, context=info)
-
- @classmethod
- def get_pdf_details(cls, resource):
- """Info for the "details" section."""
- details = {}
- owner = "Anon"
- email = "email@mail.com"
- resource_lab = resource.template.lab
- lab = resource_lab.name
- location = resource_lab.location
- pod_type = "development"
- link = resource_lab.lab_info_link
-
- 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['contact'] = email
- details['lab'] = lab
- details['link'] = link
- details['owner'] = owner
- details['location'] = location
- details['type'] = pod_type
-
- return details
-
- @classmethod
- def get_jumphost(cls, booking):
- """Return the host designated as the Jumphost for the 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 = Server.objects.filter(
- bundle=booking.resource,
- config__is_head_node=True
- ).first()
-
- return jumphost
-
- @classmethod
- def get_pdf_jumphost(cls, booking):
- """Return a dict of all the info for the "jumphost" section."""
- 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, booking):
- """Return a list of all the "nodes" (every host except jumphost)."""
- pdf_nodes = []
- nodes = set(Server.objects.filter(bundle=booking.resource))
- nodes.discard(cls.get_jumphost(booking))
-
- for node in nodes:
- pdf_nodes.append(cls.get_pdf_host(node))
-
- return pdf_nodes
-
- @classmethod
- def get_pdf_host(cls, host):
- """
- Gather all needed info about a host.
-
- returns a dictionary
- """
- host_info = {}
- host_info['name'] = host.name
- host_info['node'] = cls.get_pdf_host_node(host)
- host_info['disks'] = []
- for disk in host.profile.storageprofile.all():
- host_info['disks'].append(cls.get_pdf_host_disk(disk))
-
- host_info['interfaces'] = []
- for interface in host.interfaces.all():
- host_info['interfaces'].append(cls.get_pdf_host_iface(interface))
-
- host_info['remote'] = cls.get_pdf_host_remote_management(host)
-
- return host_info
-
- @classmethod
- def get_pdf_host_node(cls, host):
- """Return "node" info for a given host."""
- d = {}
- d['type'] = "baremetal"
- d['vendor'] = host.vendor
- d['model'] = host.model
- d['memory'] = str(host.profile.ramprofile.first().amount) + "G"
-
- cpu = host.profile.cpuprofile.first()
- d['arch'] = cpu.architecture
- d['cpus'] = cpu.cpus
- d['cores'] = cpu.cores
- cflags = cpu.cflags
- if cflags and cflags.strip():
- d['cpu_cflags'] = cflags
- else:
- d['cpu_cflags'] = "none"
-
- return d
-
- @classmethod
- def get_pdf_host_disk(cls, disk):
- """Return a dict describing the given disk."""
- 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
- return disk_info
-
- @classmethod
- def get_pdf_host_iface(cls, interface):
- """Return a dict describing given interface."""
- iface_info = {}
- iface_info['features'] = "none"
- iface_info['mac_address'] = interface.mac_address
- iface_info['name'] = interface.profile.name
- speed = str(int(interface.profile.speed / 1000)) + "gb"
- iface_info['speed'] = speed
- return iface_info
-
- @classmethod
- def get_pdf_host_remote_management(cls, host):
- """Get the remote params of the host."""
- man = host.remote_management
- mgmt = {}
- 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/src/resource_inventory/resource_manager.py b/src/resource_inventory/resource_manager.py
deleted file mode 100644
index 16c106e..0000000
--- a/src/resource_inventory/resource_manager.py
+++ /dev/null
@@ -1,197 +0,0 @@
-##############################################################################
-# Copyright (c) 2018 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 __future__ import annotations # noqa: F407
-
-import re
-from typing import Optional
-from django.db.models import Q
-
-from dashboard.exceptions import ResourceAvailabilityException
-
-from resource_inventory.models import (
- Resource,
- ResourceBundle,
- ResourceTemplate,
- ResourceConfiguration,
- Network,
- Vlan,
- PhysicalNetwork,
- InterfaceConfiguration,
-)
-
-from account.models import Lab
-from django.contrib.auth.models import User
-
-
-class ResourceManager:
-
- instance = None
-
- def __init__(self):
- pass
-
- @staticmethod
- def getInstance() -> ResourceManager:
- if ResourceManager.instance is None:
- ResourceManager.instance = ResourceManager()
- return ResourceManager.instance
-
- def getAvailableResourceTemplates(self, lab: Lab, user: Optional[User] = None) -> list[ResourceTemplate]:
- filter = Q(public=True)
- if user:
- filter = filter | Q(owner=user)
- filter = filter & Q(temporary=False) & Q(lab=lab)
- return ResourceTemplate.objects.filter(filter)
-
- def templateIsReservable(self, resource_template: ResourceTemplate):
- """
- Check if the required resources to reserve this template is available.
-
- No changes to the database
- """
- # count up hosts
- profile_count = {}
- 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 = len(profile.get_resources(lab=resource_template.lab, unreserved=True))
- needed = profile_count[profile]
- if available < needed:
- return False
- return True
-
- # public interface
- def deleteResourceBundle(self, resourceBundle: ResourceBundle):
- raise NotImplementedError("Resource Bundle Deletion Not Implemented")
-
- def releaseResourceBundle(self, resourceBundle: ResourceBundle):
- resourceBundle.release()
-
- def get_vlans(self, resourceTemplate: ResourceTemplate) -> dict[str, int]:
- """
- returns: dict from network name to the associated vlan number (backend vlan id)
- """
- networks = {}
- vlan_manager = resourceTemplate.lab.vlan_manager
- for network in resourceTemplate.networks.all():
- if network.is_public:
- # already throws if can't get requested count, so can always expect public_net to be Some
- public_net = vlan_manager.get_public_vlan(within=resourceTemplate.public_vlan_pool_set())
- vlan_manager.reserve_public_vlan(public_net.vlan)
- networks[network.name] = public_net.vlan
- else:
- # already throws if can't get requested count, so can always index in @ 0
- vlans = vlan_manager.get_vlans(count=1, within=resourceTemplate.private_vlan_pool_set())
- vlan_manager.reserve_vlans(vlans[0])
- networks[network.name] = vlans[0]
- return networks
-
- def instantiateTemplate(self, resource_template: ResourceTemplate):
- """
- Convert a ResourceTemplate into a ResourceBundle.
-
- Takes in a ResourceTemplate and reserves all the
- Resources needed and returns a completed ResourceBundle.
- """
- resource_bundle = ResourceBundle.objects.create(template=resource_template)
- res_configs = resource_template.getConfigs()
- resources = []
-
- vlan_map = self.get_vlans(resource_template)
-
- for config in res_configs:
- try:
- phys_res = self.acquireHost(config)
- phys_res.bundle = resource_bundle
- phys_res.config = config
- resources.append(phys_res)
-
- self.configureNetworking(resource_bundle, phys_res, vlan_map)
- phys_res.save()
-
- except Exception as e:
- self.fail_acquire(resources, vlan_map, resource_template)
- raise e
-
- return resource_bundle
-
- def configureNetworking(self, resource_bundle: ResourceBundle, resource: Resource, vlan_map: dict[str, int]):
- """
- @vlan_map: dict from network name to the associated vlan number (backend vlan id)
- """
- for physical_interface in resource.interfaces.all():
-
- # assign interface configs
- iface_config = InterfaceConfiguration.objects.get(
- profile=physical_interface.profile,
- resource_config=resource.config
- )
-
- physical_interface.acts_as = iface_config
- physical_interface.acts_as.save()
-
- physical_interface.config.clear()
- for connection in iface_config.connections.all():
- physicalNetwork = PhysicalNetwork.objects.create(
- vlan_id=vlan_map[connection.network.name],
- generic_network=connection.network,
- bundle=resource_bundle,
- )
- 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=physicalNetwork
- )
- )
-
- # private interface
- def acquireHost(self, resource_config: ResourceConfiguration) -> Resource:
- resources = resource_config.profile.get_resources(
- lab=resource_config.template.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=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, template):
- self.releaseNetworks(template, vlans)
- for host in hosts:
- host.release()
-
-
-class HostNameValidator(object):
- regex = r'^[A-Za-z0-9][A-Za-z0-9-]*$'
- message = "Hostnames can only contain alphanumeric characters and hyphens (-). Hostnames must start with a letter"
- pattern = re.compile(regex)
-
- @classmethod
- def is_valid_hostname(cls, hostname):
- return len(hostname) < 65 and cls.pattern.fullmatch(hostname) is not None
diff --git a/src/resource_inventory/tests/test_managers.py b/src/resource_inventory/tests/test_managers.py
deleted file mode 100644
index 46cee5a..0000000
--- a/src/resource_inventory/tests/test_managers.py
+++ /dev/null
@@ -1,301 +0,0 @@
-##############################################################################
-# Copyright (c) 2018 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.test import TestCase
-from django.contrib.auth.models import User
-
-from resource.inventory_manager import InventoryManager
-from resource.resource_manager import ResourceManager, HostNameValidator
-from account.models import Lab
-from resource.models import (
- Host,
- Vlan,
- Interface,
- ResourceBundle,
- GenericHost,
- GenericResourceBundle,
- CpuProfile,
- RamProfile,
- DiskProfile,
- HostProfile,
- InterfaceProfile
-)
-
-
-class InventoryManagerTestCase(TestCase):
-
- def test_singleton(self):
- instance = InventoryManager.getInstance()
- self.assertTrue(isinstance(instance, InventoryManager))
- self.assertTrue(instance is InventoryManager.getInstance())
-
- def setUp(self):
- # setup
- # create lab and give it resources
- user = User.objects.create(username="username")
- self.lab = Lab.objects.create(
- lab_user=user,
- name='test lab',
- contact_email='someone@email.com',
- contact_phone='dont call me'
- )
-
- # create hostProfile
- hostProfile = HostProfile.objects.create(
- host_type=0,
- name='Test profile',
- description='a test profile'
- )
- InterfaceProfile.objects.create(
- speed=1000,
- name='eno3',
- host=hostProfile
- )
- DiskProfile.objects.create(
- size=1000,
- media_type="SSD",
- name='/dev/sda',
- host=hostProfile
- )
- CpuProfile.objects.create(
- cores=96,
- architecture="x86_64",
- cpus=2,
- host=hostProfile
- )
- RamProfile.objects.create(
- amount=256,
- channels=4,
- host=hostProfile
- )
-
- # create GenericResourceBundle
- genericBundle = GenericResourceBundle.objects.create()
-
- self.gHost1 = GenericHost.objects.create(
- bundle=genericBundle,
- name='generic host 1',
- profile=hostProfile
- )
- self.gHost2 = GenericHost.objects.create(
- bundle=genericBundle,
- name='generic host 2',
- profile=hostProfile
- )
-
- # actual resource bundle
- bundle = ResourceBundle.objects.create(template=genericBundle)
-
- self.host1 = Host.objects.create(
- template=self.gHost1,
- booked=True,
- name='host1',
- bundle=bundle,
- profile=hostProfile,
- lab=self.lab
- )
-
- self.host2 = Host.objects.create(
- template=self.gHost2,
- booked=True,
- name='host2',
- bundle=bundle,
- profile=hostProfile,
- lab=self.lab
- )
-
- vlan1 = Vlan.objects.create(vlan_id=300, tagged=False)
- vlan2 = Vlan.objects.create(vlan_id=300, tagged=False)
-
- Interface.objects.create(
- mac_address='00:11:22:33:44:55',
- bus_address='some bus address',
- switch_name='switch1',
- port_name='port10',
- config=vlan1,
- host=self.host1
- )
- Interface.objects.create(
- mac_address='00:11:22:33:44:56',
- bus_address='some bus address',
- switch_name='switch1',
- port_name='port12',
- config=vlan2,
- host=self.host2
- )
-
- def test_acquire_host(self):
- host = InventoryManager.getInstance().acquireHost(self.gHost1, self.lab.name)
- self.assertNotEquals(host, None)
- self.assertTrue(host.booked)
- self.assertEqual(host.template, self.gHost1)
-
- def test_release_host(self):
- host = InventoryManager.getInstance().acquireHost(self.gHost1, self.lab.name)
- self.assertTrue(host.booked)
- InventoryManager.getInstance().releaseHost(host)
- self.assertFalse(host.booked)
-
-
-class ResourceManagerTestCase(TestCase):
- def test_singleton(self):
- instance = ResourceManager.getInstance()
- self.assertTrue(isinstance(instance, ResourceManager))
- self.assertTrue(instance is ResourceManager.getInstance())
-
- def setUp(self):
- # setup
- # create lab and give it resources
- user = User.objects.create(username="username")
- self.lab = Lab.objects.create(
- lab_user=user,
- name='test lab',
- contact_email='someone@email.com',
- contact_phone='dont call me'
- )
-
- # create hostProfile
- hostProfile = HostProfile.objects.create(
- host_type=0,
- name='Test profile',
- description='a test profile'
- )
- InterfaceProfile.objects.create(
- speed=1000,
- name='eno3',
- host=hostProfile
- )
- DiskProfile.objects.create(
- size=1000,
- media_type="SSD",
- name='/dev/sda',
- host=hostProfile
- )
- CpuProfile.objects.create(
- cores=96,
- architecture="x86_64",
- cpus=2,
- host=hostProfile
- )
- RamProfile.objects.create(
- amount=256,
- channels=4,
- host=hostProfile
- )
-
- # create GenericResourceBundle
- genericBundle = GenericResourceBundle.objects.create()
-
- self.gHost1 = GenericHost.objects.create(
- bundle=genericBundle,
- name='generic host 1',
- profile=hostProfile
- )
- self.gHost2 = GenericHost.objects.create(
- bundle=genericBundle,
- name='generic host 2',
- profile=hostProfile
- )
-
- # actual resource bundle
- bundle = ResourceBundle.objects.create(template=genericBundle)
-
- self.host1 = Host.objects.create(
- template=self.gHost1,
- booked=True,
- name='host1',
- bundle=bundle,
- profile=hostProfile,
- lab=self.lab
- )
-
- self.host2 = Host.objects.create(
- template=self.gHost2,
- booked=True,
- name='host2',
- bundle=bundle,
- profile=hostProfile,
- lab=self.lab
- )
-
- vlan1 = Vlan.objects.create(vlan_id=300, tagged=False)
- vlan2 = Vlan.objects.create(vlan_id=300, tagged=False)
-
- Interface.objects.create(
- mac_address='00:11:22:33:44:55',
- bus_address='some bus address',
- switch_name='switch1',
- port_name='port10',
- config=vlan1,
- host=self.host1
- )
- Interface.objects.create(
- mac_address='00:11:22:33:44:56',
- bus_address='some bus address',
- switch_name='switch1',
- port_name='port12',
- config=vlan2,
- host=self.host2
- )
-
- def test_convert_bundle(self):
- ResourceManager.getInstance().convertResoureBundle(self.genericBundle, self.lab.name)
- # verify bundle configuration
-
-
-class HostNameValidatorTestCase(TestCase):
-
- def test_valid_hostnames(self):
- self.assertTrue(HostNameValidator.is_valid_hostname("localhost"))
- self.assertTrue(HostNameValidator.is_valid_hostname("Localhost"))
- self.assertTrue(HostNameValidator.is_valid_hostname("localHost"))
- self.assertTrue(HostNameValidator.is_valid_hostname("LOCALHOST"))
- self.assertTrue(HostNameValidator.is_valid_hostname("f"))
- self.assertTrue(HostNameValidator.is_valid_hostname("abc123doreyme"))
- self.assertTrue(HostNameValidator.is_valid_hostname("F9999999"))
- self.assertTrue(HostNameValidator.is_valid_hostname("my-host"))
- self.assertTrue(HostNameValidator.is_valid_hostname("My-Host"))
- self.assertTrue(HostNameValidator.is_valid_hostname("MY-HOST"))
- self.assertTrue(HostNameValidator.is_valid_hostname("a-long-name-for-my-host"))
-
- def test_invalid_hostnames(self):
- self.assertFalse(HostNameValidator.is_valid_hostname("-long-name-for-my-host"))
- self.assertFalse(HostNameValidator.is_valid_hostname("546"))
- self.assertFalse(HostNameValidator.is_valid_hostname("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"))
-
- def test_invalid_chars(self):
- self.assertFalse(HostNameValidator.is_valid_hostname("contains!char"))
- self.assertFalse(HostNameValidator.is_valid_hostname("contains@char"))
- self.assertFalse(HostNameValidator.is_valid_hostname("contains#char"))
- self.assertFalse(HostNameValidator.is_valid_hostname("contains$char"))
- self.assertFalse(HostNameValidator.is_valid_hostname("contains%char"))
- self.assertFalse(HostNameValidator.is_valid_hostname("contains^char"))
- self.assertFalse(HostNameValidator.is_valid_hostname("contains&char"))
- self.assertFalse(HostNameValidator.is_valid_hostname("contains*char"))
- self.assertFalse(HostNameValidator.is_valid_hostname("contains(char"))
- self.assertFalse(HostNameValidator.is_valid_hostname("contains)char"))
- self.assertFalse(HostNameValidator.is_valid_hostname("contains_char"))
- self.assertFalse(HostNameValidator.is_valid_hostname("contains=char"))
- self.assertFalse(HostNameValidator.is_valid_hostname("contains+char"))
- self.assertFalse(HostNameValidator.is_valid_hostname("contains|char"))
- self.assertFalse(HostNameValidator.is_valid_hostname("contains\\char"))
- self.assertFalse(HostNameValidator.is_valid_hostname("contains[char"))
- self.assertFalse(HostNameValidator.is_valid_hostname("contains]char"))
- self.assertFalse(HostNameValidator.is_valid_hostname("contains;char"))
- self.assertFalse(HostNameValidator.is_valid_hostname("contains:char"))
- self.assertFalse(HostNameValidator.is_valid_hostname("contains'char"))
- self.assertFalse(HostNameValidator.is_valid_hostname('contains"char'))
- self.assertFalse(HostNameValidator.is_valid_hostname("contains'char"))
- self.assertFalse(HostNameValidator.is_valid_hostname("contains<char"))
- self.assertFalse(HostNameValidator.is_valid_hostname("contains>char"))
- self.assertFalse(HostNameValidator.is_valid_hostname("contains,char"))
- self.assertFalse(HostNameValidator.is_valid_hostname("contains?char"))
- self.assertFalse(HostNameValidator.is_valid_hostname("contains/char"))
- self.assertFalse(HostNameValidator.is_valid_hostname("contains`char"))
- self.assertFalse(HostNameValidator.is_valid_hostname("contains~char"))
diff --git a/src/resource_inventory/tests/test_models.py b/src/resource_inventory/tests/test_models.py
deleted file mode 100644
index 3f2d1d8..0000000
--- a/src/resource_inventory/tests/test_models.py
+++ /dev/null
@@ -1,173 +0,0 @@
-##############################################################################
-# Copyright (c) 2018 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.test import TestCase
-from django.contrib.auth.models import User
-from account.models import Lab
-from resource_inventory.models import (
- Scenario,
- Installer,
- Opsys,
- ConfigBundle,
- OPNFVConfig,
- OPNFVRole,
- Image,
- HostProfile,
- GenericResourceBundle,
- GenericResource,
- GenericHost,
- HostConfiguration
-)
-
-
-class ConfigUtil():
- count = 0
-
- @staticmethod
- def makeScenario():
- return Scenario.objects.create(name="testScenario")
-
- @staticmethod
- def makeInstaller():
- inst = Installer.objects.create(name="testInstaller")
- inst.sup_scenarios = [ConfigUtil.makeScenario()]
- return inst
-
- @staticmethod
- def makeOpsys():
- os = Opsys.objects.create(name="test Operating System")
- os.sup_installers = [ConfigUtil.makeInstaller()]
- return os
-
- @staticmethod
- def makeConfigBundle():
- user = User.objects.create(username="test_user" + str(ConfigUtil.count))
- ConfigUtil.count += 1
- return ConfigBundle.objects.create(owner=user)
-
- @staticmethod
- def makeOPNFVConfig():
- installer = ConfigUtil.makeInstaller()
- scenario = ConfigUtil.makeScenario()
- bundle = ConfigUtil.makeConfigBundle()
- return OPNFVConfig.objects.create(
- installer=installer,
- scenario=scenario,
- bundle=bundle
- )
-
- @staticmethod
- def makeOPNFVRole():
- return OPNFVRole.objects.create(
- name="Test role",
- description="This is a test role"
- )
-
- @staticmethod
- def makeImage():
- owner = User.objects.create(username="another test user")
- lab_user = User.objects.create(username="labUserForTests")
- lab = Lab.objects.create(
- lab_user=lab_user,
- name="this is lab for testing",
- contact_email="email@mail.com",
- contact_phone="123-4567"
- )
-
- return Image.objects.create(
- cobbler_id="profile1",
- from_lab=lab,
- name="an image for testing",
- owner=owner
- )
-
- @staticmethod
- def makeGenericHost():
- profile = HostProfile.objects.create(
- host_type=0,
- name="test lab for config bundle",
- description="this is a test profile"
- )
- user = User.objects.create(username="test sample user 12")
- bundle = GenericResourceBundle.objects.create(
- name="Generic bundle for config tests",
- xml="",
- owner=user,
- description=""
- )
-
- resource = GenericResource.objects.create(
- bundle=bundle,
- name="a test generic resource"
- )
-
- return GenericHost.objects.create(
- profile=profile,
- resource=resource
- )
-
- @staticmethod
- def makeHostConfiguration():
- host = ConfigUtil.makeGenericHost()
- image = ConfigUtil.makeImage()
- bundle = ConfigUtil.makeConfigBundle()
- opnfvRole = ConfigUtil.makeOPNFVRole()
- return HostConfiguration.objects.create(
- host=host,
- image=image,
- bundle=bundle,
- opnfvRole=opnfvRole
- )
-
-
-class ScenarioTestCase(TestCase):
-
- def test_save(self):
- self.assertTrue(ConfigUtil.makeScenario())
-
-
-class InstallerTestCase(TestCase):
-
- def test_save(self):
- self.assertTrue(ConfigUtil.makeInstaller())
-
-
-class OperatingSystemTestCase(TestCase):
-
- def test_save(self):
- self.assertTrue(ConfigUtil.makeOpsys())
-
-
-class ConfigBundleTestCase(TestCase):
-
- def test_save(self):
- self.assertTrue(ConfigUtil.makeConfigBundle())
-
-
-class OPNFVConfigTestCase(TestCase):
-
- def test_save(self):
- self.assertTrue(ConfigUtil.makeOPNFVConfig())
-
-
-class OPNFVRoleTestCase(TestCase):
-
- def test_save(self):
- self.assertTrue(ConfigUtil.makeOPNFVRole())
-
-
-class HostConfigurationTestCase(TestCase):
-
- def test_save(self):
- self.assertTrue(ConfigUtil.makeHostConfiguration())
-
-
-class ImageTestCase(TestCase):
-
- def test_save(self):
- self.assertTrue(ConfigUtil.makeImage())
diff --git a/src/resource_inventory/urls.py b/src/resource_inventory/urls.py
deleted file mode 100644
index a9a4d43..0000000
--- a/src/resource_inventory/urls.py
+++ /dev/null
@@ -1,36 +0,0 @@
-##############################################################################
-# Copyright (c) 2016 Max Breitenfeldt and others.
-# Copyright (c) 2018 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
-##############################################################################
-
-
-"""
-laas_dashboard URL Configuration.
-
-The `urlpatterns` list routes URLs to views. For more information please see:
- https://docs.djangoproject.com/en/1.10/topics/http/urls/
-Examples:
-Function views
- 1. Add an import: from my_app import views
- 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home')
-Class-based views
- 1. Add an import: from other_app.views import Home
- 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home')
-Including another URLconf
- 1. Import the include() function: from django.conf.urls import url, include
- 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
-"""
-from django.conf.urls import url
-from resource_inventory.views import HostView, hostprofile_detail_view
-
-
-app_name = 'resource'
-urlpatterns = [
- url(r'^hosts$', HostView.as_view(), name='hosts'),
- url(r'^profiles/(?P<hostprofile_id>.+)/$', hostprofile_detail_view, name='host_detail'),
-]
diff --git a/src/resource_inventory/views.py b/src/resource_inventory/views.py
deleted file mode 100644
index 52f8c75..0000000
--- a/src/resource_inventory/views.py
+++ /dev/null
@@ -1,38 +0,0 @@
-##############################################################################
-# Copyright (c) 2018 Sawyer Bergeron, Parker Berberian, 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.views.generic import TemplateView
-from django.shortcuts import get_object_or_404
-from django.shortcuts import render
-
-from resource_inventory.models import ResourceProfile, ResourceQuery
-
-
-class HostView(TemplateView):
- template_name = "resource/hosts.html"
-
- def get_context_data(self, **kwargs):
- context = super(HostView, self).get_context_data(**kwargs)
- hosts = ResourceQuery.filter(working=True)
- context.update({'hosts': hosts, 'title': "Hardware Resources"})
- return context
-
-
-def hostprofile_detail_view(request, hostprofile_id):
- hostprofile = get_object_or_404(ResourceProfile, id=hostprofile_id)
-
- return render(
- request,
- "resource/hostprofile_detail.html",
- {
- 'title': "Host Type: " + str(hostprofile.name),
- 'hostprofile': hostprofile
- }
- )