aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/account/views.py6
-rw-r--r--src/api/migrations/0010_auto_20191219_2004.py23
-rw-r--r--src/api/models.py161
-rw-r--r--src/api/tests/test_models_unittest.py11
-rw-r--r--src/booking/quick_deployer.py2
-rw-r--r--src/dashboard/tasks.py2
-rw-r--r--src/resource_inventory/migrations/0012_auto_20200103_1850.py76
-rw-r--r--src/resource_inventory/models.py90
-rw-r--r--src/resource_inventory/resource_manager.py14
-rw-r--r--src/workflow/models.py2
-rw-r--r--src/workflow/opnfv_workflow.py2
-rw-r--r--src/workflow/snapshot_workflow.py2
-rw-r--r--src/workflow/workflow_manager.py4
13 files changed, 253 insertions, 142 deletions
diff --git a/src/account/views.py b/src/account/views.py
index 2b4eccb..5b91550 100644
--- a/src/account/views.py
+++ b/src/account/views.py
@@ -33,7 +33,7 @@ from account.forms import AccountSettingsForm
from account.jira_util import SignatureMethod_RSA_SHA1
from account.models import UserProfile
from booking.models import Booking
-from resource_inventory.models import GenericResourceBundle, ConfigBundle, Image, Host
+from resource_inventory.models import GenericResourceBundle, ConfigBundle, Image
@method_decorator(login_required, name='dispatch')
@@ -229,7 +229,7 @@ def account_images_view(request):
public_images = Image.objects.filter(public=True)
used_images = {}
for image in my_images:
- if Host.objects.filter(booked=True, config__image=image).exists():
+ if image.in_use():
used_images[image.id] = "true"
context = {
"title": "Images",
@@ -286,7 +286,7 @@ def image_delete_view(request, image_id=None):
if image.public or image.owner.id != request.user.id:
return HttpResponse('no') # 403?
# check if used in booking
- if Host.objects.filter(booked=True, config__image=image).exists():
+ if image.in_use():
return HttpResponse('no') # 403?
image.delete()
return HttpResponse('')
diff --git a/src/api/migrations/0010_auto_20191219_2004.py b/src/api/migrations/0010_auto_20191219_2004.py
new file mode 100644
index 0000000..ec48584
--- /dev/null
+++ b/src/api/migrations/0010_auto_20191219_2004.py
@@ -0,0 +1,23 @@
+# Generated by Django 2.2 on 2019-12-19 20:04
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('api', '0009_merge_20190508_1317'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='taskconfig',
+ name='delta_keys_list',
+ field=models.CharField(default='[]', max_length=200),
+ ),
+ migrations.AddField(
+ model_name='taskconfig',
+ name='state',
+ field=models.IntegerField(default=200),
+ ),
+ ]
diff --git a/src/api/models.py b/src/api/models.py
index 682785b..520e747 100644
--- a/src/api/models.py
+++ b/src/api/models.py
@@ -27,7 +27,8 @@ from resource_inventory.models import (
Interface,
HostOPNFVConfig,
RemoteInfo,
- OPNFVConfig
+ OPNFVConfig,
+ ConfigState
)
from resource_inventory.idf_templater import IDFTemplater
from resource_inventory.pdf_templater import PDFTemplater
@@ -294,32 +295,12 @@ class Job(models.Model):
def to_dict(self):
d = {}
- j = {}
- j['id'] = self.id
- for relation in AccessRelation.objects.filter(job=self):
- if 'access' not in d:
- d['access'] = {}
- d['access'][relation.task_id] = relation.config.to_dict()
- for relation in SoftwareRelation.objects.filter(job=self):
- if 'software' not in d:
- d['software'] = {}
- d['software'][relation.task_id] = relation.config.to_dict()
- for relation in HostHardwareRelation.objects.filter(job=self):
- if 'hardware' not in d:
- d['hardware'] = {}
- d['hardware'][relation.task_id] = relation.config.to_dict()
- for relation in HostNetworkRelation.objects.filter(job=self):
- if 'network' not in d:
- d['network'] = {}
- d['network'][relation.task_id] = relation.config.to_dict()
- for relation in SnapshotRelation.objects.filter(job=self):
- if 'snapshot' not in d:
- d['snapshot'] = {}
- d['snapshot'][relation.task_id] = relation.config.to_dict()
-
- j['payload'] = d
-
- return j
+ for relation in self.get_tasklist():
+ if relation.job_key not in d:
+ d[relation.job_key] = {}
+ d[relation.job_key][relation.task_id] = relation.config.to_dict()
+
+ return {"id": self.id, "payload": d}
def get_tasklist(self, status="all"):
tasklist = []
@@ -351,48 +332,54 @@ class Job(models.Model):
def get_delta(self, status):
d = {}
- j = {}
- j['id'] = self.id
- for relation in AccessRelation.objects.filter(job=self).filter(status=status):
- if 'access' not in d:
- d['access'] = {}
- d['access'][relation.task_id] = relation.config.get_delta()
- for relation in SoftwareRelation.objects.filter(job=self).filter(status=status):
- if 'software' not in d:
- d['software'] = {}
- d['software'][relation.task_id] = relation.config.get_delta()
- for relation in HostHardwareRelation.objects.filter(job=self).filter(status=status):
- if 'hardware' not in d:
- d['hardware'] = {}
- d['hardware'][relation.task_id] = relation.config.get_delta()
- for relation in HostNetworkRelation.objects.filter(job=self).filter(status=status):
- if 'network' not in d:
- d['network'] = {}
- d['network'][relation.task_id] = relation.config.get_delta()
- for relation in SnapshotRelation.objects.filter(job=self).filter(status=status):
- if 'snapshot' not in d:
- d['snapshot'] = {}
- d['snapshot'][relation.task_id] = relation.config.get_delta()
-
- j['payload'] = d
- return j
+ for relation in self.get_tasklist(status=status):
+ if relation.job_key not in d:
+ d[relation.job_key] = {}
+ d[relation.job_key][relation.task_id] = relation.config.get_delta()
+
+ return {"id": self.id, "payload": d}
def to_json(self):
return json.dumps(self.to_dict())
class TaskConfig(models.Model):
+ state = models.IntegerField(default=ConfigState.CLEAN)
+
+ keys = set() # TODO: This needs to be an instance variable, not a class variable
+ delta_keys_list = models.CharField(max_length=200, default="[]")
+
+ @property
+ def delta_keys(self):
+ return list(set(json.loads(self.delta_keys_list)))
+
+ @delta_keys.setter
+ def delta_keys(self, keylist):
+ self.delta_keys_list = json.dumps(keylist)
+
def to_dict(self):
- pass
+ raise NotImplementedError
def get_delta(self):
- pass
+ raise NotImplementedError
+
+ def format_delta(self, config, token):
+ delta = {k: config[k] for k in self.delta_keys}
+ delta['lab_token'] = token
+ return delta
def to_json(self):
return json.dumps(self.to_dict())
def clear_delta(self):
- self.delta = '{}'
+ self.delta_keys = []
+
+ def set(self, *args):
+ dkeys = self.delta_keys
+ for arg in args:
+ if arg in self.keys:
+ dkeys.append(arg)
+ self.delta_keys = dkeys
class BridgeConfig(models.Model):
@@ -606,55 +593,12 @@ class HardwareConfig(TaskConfig):
ipmi_create = models.BooleanField(default=False)
delta = models.TextField()
- def to_dict(self):
- d = {}
- d['image'] = self.image
- d['power'] = self.power
- d['hostname'] = self.hostname
- d['ipmi_create'] = str(self.ipmi_create)
- d['id'] = self.hosthardwarerelation.host.labid
- return d
-
- def to_json(self):
- return json.dumps(self.to_dict())
+ keys = set(["id", "image", "power", "hostname", "ipmi_create"])
def get_delta(self):
- if not self.delta:
- self.delta = self.to_json()
- self.save()
- d = json.loads(self.delta)
- d['lab_token'] = self.hosthardwarerelation.lab_token
- return d
-
- def clear_delta(self):
- d = {}
- d["id"] = self.hosthardwarerelation.host.labid
- d["lab_token"] = self.hosthardwarerelation.lab_token
- self.delta = json.dumps(d)
-
- def set_image(self, image):
- self.image = image
- d = json.loads(self.delta)
- d['image'] = self.image
- self.delta = json.dumps(d)
-
- def set_power(self, power):
- self.power = power
- d = json.loads(self.delta)
- d['power'] = power
- self.delta = json.dumps(d)
-
- def set_hostname(self, hostname):
- self.hostname = hostname
- d = json.loads(self.delta)
- d['hostname'] = hostname
- self.delta = json.dumps(d)
-
- def set_ipmi_create(self, ipmi_create):
- self.ipmi_create = ipmi_create
- d = json.loads(self.delta)
- d['ipmi_create'] = ipmi_create
- self.delta = json.dumps(d)
+ return self.format_delta(
+ self.hosthardwarerelation.host.get_configuration(self.state),
+ self.hosthardwarerelation.lab_token)
class NetworkConfig(TaskConfig):
@@ -781,6 +725,8 @@ class TaskRelation(models.Model):
lab_token = models.CharField(default="null", max_length=50)
message = models.TextField(default="")
+ job_key = None
+
def delete(self, *args, **kwargs):
self.config.delete()
return super(self.__class__, self).delete(*args, **kwargs)
@@ -794,6 +740,7 @@ class TaskRelation(models.Model):
class AccessRelation(TaskRelation):
config = models.OneToOneField(AccessConfig, on_delete=models.CASCADE)
+ job_key = "access"
def type_str(self):
return "Access Task"
@@ -805,6 +752,7 @@ class AccessRelation(TaskRelation):
class SoftwareRelation(TaskRelation):
config = models.OneToOneField(SoftwareConfig, on_delete=models.CASCADE)
+ job_key = "software"
def type_str(self):
return "Software Configuration Task"
@@ -817,6 +765,7 @@ class SoftwareRelation(TaskRelation):
class HostHardwareRelation(TaskRelation):
host = models.ForeignKey(Host, on_delete=models.CASCADE)
config = models.OneToOneField(HardwareConfig, on_delete=models.CASCADE)
+ job_key = "hardware"
def type_str(self):
return "Hardware Configuration Task"
@@ -832,6 +781,7 @@ class HostHardwareRelation(TaskRelation):
class HostNetworkRelation(TaskRelation):
host = models.ForeignKey(Host, on_delete=models.CASCADE)
config = models.OneToOneField(NetworkConfig, on_delete=models.CASCADE)
+ job_key = "network"
def type_str(self):
return "Network Configuration Task"
@@ -844,6 +794,7 @@ class HostNetworkRelation(TaskRelation):
class SnapshotRelation(TaskRelation):
snapshot = models.ForeignKey(Image, on_delete=models.CASCADE)
config = models.OneToOneField(SnapshotConfig, on_delete=models.CASCADE)
+ job_key = "snapshot"
def type_str(self):
return "Snapshot Task"
@@ -960,11 +911,7 @@ class JobFactory(object):
relation.config = relation.config
relation.save()
- hardware_config.clear_delta()
- hardware_config.set_image(host.config.image.lab_id)
- hardware_config.set_hostname(host.template.resource.name)
- hardware_config.set_power("on")
- hardware_config.set_ipmi_create(True)
+ hardware_config.set("image", "hostname", "power", "ipmi_create")
hardware_config.save()
@classmethod
diff --git a/src/api/tests/test_models_unittest.py b/src/api/tests/test_models_unittest.py
index e6f97a6..2ecbe42 100644
--- a/src/api/tests/test_models_unittest.py
+++ b/src/api/tests/test_models_unittest.py
@@ -1,4 +1,3 @@
-##############################################################################
# Copyright (c) 2019 Sawyer Bergeron, Parker Berberian, and others.
#
# All rights reserved. This program and the accompanying materials
@@ -21,6 +20,7 @@ from api.models import (
from resource_inventory.models import (
OPNFVRole,
HostProfile,
+ ConfigState,
)
from django.test import TestCase, Client
@@ -201,7 +201,7 @@ class ValidBookingCreatesValidJob(TestCase):
self.assertEqual(relation.status, JobStatus.NEW)
config = relation.config
host = relation.host
- self.assertEqual(config.hostname, host.template.resource.name)
+ self.assertEqual(config.get_delta()["hostname"], host.template.resource.name)
def test_complete_job_makes_software_configs(self):
JobFactory.makeCompleteJob(self.booking)
@@ -261,9 +261,10 @@ class ValidBookingCreatesValidJob(TestCase):
host_set.remove(relation.host.id)
except KeyError:
self.fail("Hardware Relation/Config not created for host " + str(relation.host))
-
- self.assertEqual(relation.config.power, "on")
- self.assertTrue(relation.config.ipmi_create)
+ # TODO: ConfigState needs to be fixed in factory methods
+ relation.config.state = ConfigState.NEW
+ self.assertEqual(relation.config.get_delta()["power"], "on")
+ self.assertTrue(relation.config.get_delta()["ipmi_create"])
# TODO: the rest of hwconf attrs
self.assertEqual(len(host_set), 0)
diff --git a/src/booking/quick_deployer.py b/src/booking/quick_deployer.py
index 0e0cc5a..4ec488e 100644
--- a/src/booking/quick_deployer.py
+++ b/src/booking/quick_deployer.py
@@ -245,7 +245,7 @@ def configure_networking(grb, config):
# create network
net = Network.objects.create(name="public", bundle=grb, is_public=True)
# connect network to generic host
- grb.getHosts()[0].generic_interfaces.first().connections.add(
+ grb.getResources()[0].generic_interfaces.first().connections.add(
NetworkConnection.objects.create(network=net, vlan_is_tagged=False)
)
# asign network role
diff --git a/src/dashboard/tasks.py b/src/dashboard/tasks.py
index 597629f..71afed2 100644
--- a/src/dashboard/tasks.py
+++ b/src/dashboard/tasks.py
@@ -23,7 +23,7 @@ def booking_poll():
for hostrelation in qs:
config = hostrelation.config
config.clear_delta()
- config.set_power("off")
+ config.power = "off"
config.save()
hostrelation.status = JobStatus.NEW
hostrelation.save()
diff --git a/src/resource_inventory/migrations/0012_auto_20200103_1850.py b/src/resource_inventory/migrations/0012_auto_20200103_1850.py
new file mode 100644
index 0000000..2bb203e
--- /dev/null
+++ b/src/resource_inventory/migrations/0012_auto_20200103_1850.py
@@ -0,0 +1,76 @@
+# Generated by Django 2.2 on 2020-01-03 18:50
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+def genTempVlanNetwork(apps, editor):
+ Vlan = apps.get_model("resource_inventory", "Vlan")
+ Network = apps.get_model("resource_inventory", "Network")
+ tempVlanNetwork = apps.get_model("resource_inventory", "tempVlanNetwork")
+ for vlan in Vlan.objects.filter(network__isnull=False):
+ tempVlanNetwork.objects.create(network=vlan.network, vlan=vlan)
+
+def deleteTempVlanNetworks(apps, editor):
+ tempVlanNetwork = apps.get_model("resource_inventory", "tempVlanNetwork")
+ tempVlanNetwork.objects.all().delete()
+
+
+def pairVlanPhysicalNetworks(apps, editor):
+ PhysicalNetwork = apps.get_model("resource_inventory", "PhysicalNetwork")
+ tempVlanPair = apps.get_model("resource_inventory", "tempVlanNetwork")
+ for pair in tempVlanPair.objects.all():
+ physicalNetwork = PhysicalNetwork.objects.create(vlan_id=vlan.vlan_id,
+ generic_network=pair.network)
+ pair.vlan.network = physicalNetwork
+
+def deletePhysicalNetworks(apps, editor):
+ 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.CreateModel(
+ name='tempVlanNetwork',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('vlan', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='resource_inventory.vlan')),
+ ('network', models.ForeignKey(null=True, to='resource_inventory.network', on_delete=django.db.models.deletion.CASCADE)),
+ ]
+ ),
+ migrations.RunPython(genTempVlanNetwork, deleteTempVlanNetworks),
+ migrations.AlterField(
+ model_name='vlan',
+ name='network',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING,
+ to='resource_inventory.PhysicalNetwork', null=True),
+ ),
+ migrations.RunPython(pairVlanPhysicalNetworks, deletePhysicalNetworks),
+ migrations.DeleteModel("tempVlanNetwork")
+ ]
diff --git a/src/resource_inventory/models.py b/src/resource_inventory/models.py
index 031ccce..d152698 100644
--- a/src/resource_inventory/models.py
+++ b/src/resource_inventory/models.py
@@ -105,6 +105,33 @@ class RamProfile(models.Model):
return str(self.amount) + "G for " + str(self.host)
+class Resource(models.Model):
+ class Meta:
+ abstract = True
+
+ def get_configuration(self, state):
+ """
+ Returns the desired configuration for this host as a
+ JSON object as defined in the rest api spec.
+ state is a ConfigState
+ TODO: single method, or different methods for hw, network, snapshot, etc?
+ """
+ raise NotImplementedError("Must implement in concrete Resource classes")
+
+ def reserve(self):
+ """
+ Reserves this resource for its currently
+ assigned booking.
+ """
+ raise NotImplementedError("Must implement in concrete Resource classes")
+
+ def release(self):
+ """
+ Makes this resource available again for new boookings
+ """
+ raise NotImplementedError("Must implement in concrete Resource classes")
+
+
# Generic resource templates
class GenericResourceBundle(models.Model):
id = models.AutoField(primary_key=True)
@@ -116,12 +143,12 @@ class GenericResourceBundle(models.Model):
public = models.BooleanField(default=False)
hidden = models.BooleanField(default=False)
- def getHosts(self):
- return_hosts = []
+ def getResources(self):
+ my_resources = []
for genericResource in self.generic_resources.all():
- return_hosts.append(genericResource.getHost())
+ my_resources.append(genericResource.getResource())
- return return_hosts
+ return my_resources
def __str__(self):
return self.name
@@ -137,6 +164,29 @@ class Network(models.Model):
return self.name
+class PhysicalNetwork(Resource):
+ vlan_id = models.IntegerField()
+ generic_network = models.ForeignKey(Network, on_delete=models.CASCADE)
+
+ def get_configuration(self, state):
+ """
+ Returns the network configuration
+ Collects info about each attached network interface and vlan, etc
+ """
+ return {}
+
+ def reserve(self):
+ """
+ Reserves vlan(s) associated with this network
+ """
+ # vlan_manager = self.bundle.lab.vlan_manager
+ return False
+
+ def release(self):
+ # vlan_manager = self.bundle.lab.vlan_manager
+ return False
+
+
class NetworkConnection(models.Model):
network = models.ForeignKey(Network, on_delete=models.CASCADE)
vlan_is_tagged = models.BooleanField()
@@ -147,18 +197,25 @@ class Vlan(models.Model):
vlan_id = models.IntegerField()
tagged = models.BooleanField()
public = models.BooleanField(default=False)
- network = models.ForeignKey(Network, on_delete=models.DO_NOTHING, null=True)
+ 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 ConfigState:
+ NEW = 0
+ RESET = 100
+ CLEAN = 200
+
+
class GenericResource(models.Model):
bundle = models.ForeignKey(GenericResourceBundle, related_name='generic_resources', on_delete=models.CASCADE)
hostname_validchars = RegexValidator(regex=r'(?=^.{1,253}$)(?=(^([A-Za-z0-9\-\_]{1,62}\.)*[A-Za-z0-9\-\_]{1,63}$))', 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 (_)")
name = models.CharField(max_length=200, validators=[hostname_validchars])
- def getHost(self):
+ def getResource(self):
+ # TODO: This will have to be dealt with
return self.generic_host
def __str__(self):
@@ -183,8 +240,7 @@ class GenericHost(models.Model):
# Physical, actual resources
-class ResourceBundle(models.Model):
- id = models.AutoField(primary_key=True)
+class ResourceBundle(Resource):
template = models.ForeignKey(GenericResourceBundle, on_delete=models.SET_NULL, null=True)
def __str__(self):
@@ -289,6 +345,9 @@ class Image(models.Model):
def __str__(self):
return self.name
+ def in_use(self):
+ return Host.objects.filter(booked=True, config__image=self).exists()
+
def get_sentinal_opnfv_role():
return OPNFVRole.objects.get_or_create(name="deleted", description="Role was deleted.")
@@ -336,8 +395,7 @@ def get_default_remote_info():
# Concrete host, actual machine in a lab
-class Host(models.Model):
- id = models.AutoField(primary_key=True)
+class Host(Resource):
template = models.ForeignKey(GenericHost, on_delete=models.SET_NULL, null=True)
booked = models.BooleanField(default=False)
name = models.CharField(max_length=200, unique=True)
@@ -354,6 +412,18 @@ class Host(models.Model):
def __str__(self):
return self.name
+ def get_configuration(self, state):
+ ipmi = state == ConfigState.NEW
+ power = "off" if state == ConfigState.CLEAN else "on"
+
+ return {
+ "id": self.labid,
+ "image": self.config.image.lab_id,
+ "hostname": self.template.resource.name,
+ "power": power,
+ "ipmi_create": str(ipmi)
+ }
+
class Interface(models.Model):
id = models.AutoField(primary_key=True)
diff --git a/src/resource_inventory/resource_manager.py b/src/resource_inventory/resource_manager.py
index e94b4ec..7df4263 100644
--- a/src/resource_inventory/resource_manager.py
+++ b/src/resource_inventory/resource_manager.py
@@ -50,7 +50,7 @@ class ResourceManager:
# count up hosts
profile_count = {}
- for host in grb.getHosts():
+ for host in grb.getResources():
if host.profile not in profile_count:
profile_count[host.profile] = 0
profile_count[host.profile] += 1
@@ -71,7 +71,7 @@ class ResourceManager:
# public interface
def deleteResourceBundle(self, resourceBundle):
for host in Host.objects.filter(bundle=resourceBundle):
- self.releaseHost(host)
+ host.release()
resourceBundle.delete()
def get_vlans(self, genericResourceBundle):
@@ -93,7 +93,7 @@ class ResourceManager:
Takes in a GenericResourceBundle and 'converts' it into a ResourceBundle
"""
resource_bundle = ResourceBundle.objects.create(template=genericResourceBundle)
- generic_hosts = genericResourceBundle.getHosts()
+ generic_hosts = genericResourceBundle.getResources()
physical_hosts = []
vlan_map = self.get_vlans(genericResourceBundle)
@@ -154,12 +154,6 @@ class ResourceManager:
host.save()
return host
- def releaseHost(self, host):
- host.template = None
- host.bundle = None
- host.booked = False
- host.save()
-
def releaseNetworks(self, grb, vlan_manager, vlans):
for net_name, vlan_id in vlans.items():
net = Network.objects.get(name=net_name, bundle=grb)
@@ -172,7 +166,7 @@ class ResourceManager:
vlan_manager = grb.lab.vlan_manager
self.releaseNetworks(grb, vlan_manager, vlans)
for host in hosts:
- self.releaseHost(host)
+ host.release()
class HostNameValidator(object):
diff --git a/src/workflow/models.py b/src/workflow/models.py
index 9d1fac2..99608f6 100644
--- a/src/workflow/models.py
+++ b/src/workflow/models.py
@@ -146,7 +146,7 @@ class BookingAuthManager():
return True # admin override for this user
if Booking.objects.filter(owner=booking.owner, end__gt=timezone.now()).count() >= 3:
return False
- if len(booking.resource.template.getHosts()) < 2:
+ if len(booking.resource.template.getResources()) < 2:
return True # if they only have one server, we dont care
if repo.BOOKING_INFO_FILE not in repo.el:
return False # INFO file not provided
diff --git a/src/workflow/opnfv_workflow.py b/src/workflow/opnfv_workflow.py
index a192d6e..0cac48e 100644
--- a/src/workflow/opnfv_workflow.py
+++ b/src/workflow/opnfv_workflow.py
@@ -202,7 +202,7 @@ class Assign_Host_Roles(WorkflowStep): # taken verbatim from Define_Software in
if config is None:
context['error'] = "Please select a Configuration on the first step"
- formset = self.create_host_role_formset(hostlist=config.bundle.getHosts())
+ formset = self.create_host_role_formset(hostlist=config.bundle.getResources())
context['formset'] = formset
return context
diff --git a/src/workflow/snapshot_workflow.py b/src/workflow/snapshot_workflow.py
index 4266587..c2f4cd6 100644
--- a/src/workflow/snapshot_workflow.py
+++ b/src/workflow/snapshot_workflow.py
@@ -36,7 +36,7 @@ class Select_Host_Step(WorkflowStep):
booking_hosts[booking.id]['start'] = booking.start.strftime("%Y-%m-%d")
booking_hosts[booking.id]['end'] = booking.end.strftime("%Y-%m-%d")
booking_hosts[booking.id]['hosts'] = []
- for genericHost in booking.resource.template.getHosts():
+ for genericHost in booking.resource.template.getResources():
booking_hosts[booking.id]['hosts'].append({"name": genericHost.resource.name})
context['booking_hosts'] = booking_hosts
diff --git a/src/workflow/workflow_manager.py b/src/workflow/workflow_manager.py
index 4677829..fda105e 100644
--- a/src/workflow/workflow_manager.py
+++ b/src/workflow/workflow_manager.py
@@ -189,7 +189,7 @@ class SessionManager():
models['bundle'] = resource
models['interfaces'] = {}
models['vlans'] = {}
- for host in resource.getHosts():
+ for host in resource.getResources():
models['hosts'].append(host)
models['interfaces'][host.resource.name] = []
models['vlans'][host.resource.name] = {}
@@ -205,7 +205,7 @@ class SessionManager():
confirm['resource'] = {}
confirm['resource']['hosts'] = []
confirm['resource']['lab'] = resource.lab.lab_user.username
- for host in resource.getHosts():
+ for host in resource.getResources():
confirm['resource']['hosts'].append({"name": host.resource.name, "profile": host.profile.name})
return confirm