From f5cdab1569b26df0c7ffc3df1529f095116fd13a Mon Sep 17 00:00:00 2001 From: Parker Berberian Date: Thu, 6 Feb 2020 12:59:51 -0500 Subject: Modifies Resource Models for ongoing refactor Change-Id: Ice88f53135f57aca8e2de4d69274e7d490f981a4 Signed-off-by: Parker Berberian --- src/api/models.py | 185 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 106 insertions(+), 79 deletions(-) (limited to 'src/api') diff --git a/src/api/models.py b/src/api/models.py index 1e5a2da..de73a7a 100644 --- a/src/api/models.py +++ b/src/api/models.py @@ -10,8 +10,9 @@ from django.contrib.auth.models import User from django.db import models -from django.core.exceptions import PermissionDenied +from django.core.exceptions import PermissionDenied, ValidationError from django.shortcuts import get_object_or_404 +from django.http import HttpResponseNotFound from django.urls import reverse from django.utils import timezone @@ -21,18 +22,19 @@ import uuid from booking.models import Booking from resource_inventory.models import ( Lab, - HostProfile, - Host, + ResourceProfile, Image, Interface, - HostOPNFVConfig, + ResourceOPNFVConfig, RemoteInfo, OPNFVConfig, - ConfigState + ConfigState, + ResourceQuery ) from resource_inventory.idf_templater import IDFTemplater from resource_inventory.pdf_templater import PDFTemplater from account.models import Downtime +from dashboard.utils import AbstractModelQuery class JobStatus(object): @@ -115,8 +117,11 @@ class LabManager(object): ) return self.get_downtime_json() - def update_host_remote_info(self, data, host_id): - host = get_object_or_404(Host, labid=host_id, lab=self.lab) + def update_host_remote_info(self, data, res_id): + resource = ResourceQuery.filter(labid=res_id, lab=self.lab) + if len(resource) != 1: + return HttpResponseNotFound("Could not find single host with id " + str(res_id)) + resource = resource[0] info = {} try: info['address'] = data['address'] @@ -127,7 +132,7 @@ class LabManager(object): info['versions'] = json.dumps(data['versions']) except Exception as e: return {"error": "invalid arguement: " + str(e)} - remote_info = host.remote_management + remote_info = resource.remote_management if "default" in remote_info.mac_address: remote_info = RemoteInfo() remote_info.address = info['address'] @@ -137,9 +142,9 @@ class LabManager(object): remote_info.type = info['type'] remote_info.versions = info['versions'] remote_info.save() - host.remote_management = remote_info - host.save() - booking = Booking.objects.get(resource=host.bundle) + resource.remote_management = remote_info + resource.save() + booking = Booking.objects.get(resource=resource.bundle) self.update_xdf(booking) return {"status": "success"} @@ -163,41 +168,42 @@ class LabManager(object): "phone": self.lab.contact_phone, "email": self.lab.contact_email } - prof['host_count'] = [] - for host in HostProfile.objects.filter(labs=self.lab): - count = Host.objects.filter(profile=host, lab=self.lab).count() - prof['host_count'].append( - { - "type": host.name, - "count": count - } - ) + prof['host_count'] = [{ + "type": profile.name, + "count": len(profile.get_resources(lab=self.lab))} + for profile in ResourceProfile.objects.filter(labs=self.lab)] return prof def get_inventory(self): inventory = {} - hosts = Host.objects.filter(lab=self.lab) + resources = ResourceQuery.filter(lab=self.lab) images = Image.objects.filter(from_lab=self.lab) - profiles = HostProfile.objects.filter(labs=self.lab) - inventory['hosts'] = self.serialize_hosts(hosts) + profiles = ResourceProfile.objects.filter(labs=self.lab) + inventory['resources'] = self.serialize_resources(resources) inventory['images'] = self.serialize_images(images) inventory['host_types'] = self.serialize_host_profiles(profiles) return inventory def get_host(self, hostname): - host = get_object_or_404(Host, labid=hostname, lab=self.lab) + resource = ResourceQuery.filter(labid=hostname, lab=self.lab) + if len(resource) != 1: + return HttpResponseNotFound("Could not find single host with id " + str(hostname)) + resource = resource[0] return { - "booked": host.booked, - "working": host.working, - "type": host.profile.name + "booked": resource.booked, + "working": resource.working, + "type": resource.profile.name } def update_host(self, hostname, data): - host = get_object_or_404(Host, labid=hostname, lab=self.lab) + resource = ResourceQuery.filter(labid=hostname, lab=self.lab) + if len(resource) != 1: + return HttpResponseNotFound("Could not find single host with id " + str(hostname)) + resource = resource[0] if "working" in data: working = data['working'] == "true" - host.working = working - host.save() + resource.working = working + resource.save() return self.get_host(hostname) def get_status(self): @@ -237,20 +243,22 @@ class LabManager(object): return job_ser - def serialize_hosts(self, hosts): + def serialize_resources(self, resources): + # TODO: rewrite for Resource model host_ser = [] - for host in hosts: - h = {} - h['interfaces'] = [] - h['hostname'] = host.name - h['host_type'] = host.profile.name - for iface in host.interfaces.all(): - eth = {} - eth['mac'] = iface.mac_address - eth['busaddr'] = iface.bus_address - eth['name'] = iface.name - eth['switchport'] = {"switch_name": iface.switch_name, "port_name": iface.port_name} - h['interfaces'].append(eth) + for res in resources: + r = { + 'interfaces': [], + 'hostname': res.name, + 'host_type': res.profile.name + } + for iface in res.get_interfaces(): + r['interfaces'].append({ + 'mac': iface.mac_address, + 'busaddr': iface.bus_address, + 'name': iface.name, + 'switchport': {"switch_name": iface.switch_name, "port_name": iface.port_name} + }) return host_ser def serialize_images(self, images): @@ -265,7 +273,7 @@ class LabManager(object): ) return images_ser - def serialize_host_profiles(self, profiles): + def serialize_resource_profiles(self, profiles): profile_ser = [] for profile in profiles: p = {} @@ -323,21 +331,9 @@ class Job(models.Model): return {"id": self.id, "payload": d} def get_tasklist(self, status="all"): - tasklist = [] - clist = [ - HostHardwareRelation, - AccessRelation, - HostNetworkRelation, - SoftwareRelation, - SnapshotRelation - ] if status == "all": - for cls in clist: - tasklist += list(cls.objects.filter(job=self)) - else: - for cls in clist: - tasklist += list(cls.objects.filter(job=self).filter(status=status)) - return tasklist + return JobTaskQuery.filter(job=self, status=status) + return JobTaskQuery.filter(job=self) def is_fulfilled(self): """ @@ -435,7 +431,7 @@ class OpnfvApiConfig(models.Model): installer = models.CharField(max_length=200) scenario = models.CharField(max_length=300) - roles = models.ManyToManyField(Host) + roles = models.ManyToManyField(ResourceOPNFVConfig) # pdf and idf are url endpoints, not the actual file pdf = models.CharField(max_length=100) idf = models.CharField(max_length=100) @@ -632,6 +628,8 @@ class NetworkConfig(TaskConfig): for interface in self.interfaces.all(): d[hid][interface.mac_address] = [] for vlan in interface.config.all(): + # TODO: should this come from the interface? + # e.g. will different interfaces for different resources need different configs? d[hid][interface.mac_address].append({"vlan_id": vlan.vlan_id, "tagged": vlan.tagged}) return d @@ -665,7 +663,7 @@ class NetworkConfig(TaskConfig): class SnapshotConfig(TaskConfig): - host = models.ForeignKey(Host, null=True, on_delete=models.DO_NOTHING) + resource_id = models.CharField(max_length=200, default="default_id") image = models.IntegerField(null=True) dashboard_id = models.IntegerField() delta = models.TextField(default="{}") @@ -718,6 +716,11 @@ class SnapshotConfig(TaskConfig): d['dashboard_id'] = self.dashboard_id self.delta = json.dumps(d) + def save(self, *args, **kwargs): + if len(ResourceQuery.filter(labid=self.resource_id)) != 1: + raise ValidationError("resource_id " + str(self.resource_id) + " does not refer to a single resource") + super().save(*args, **kwargs) + def get_task(task_id): for taskclass in [AccessRelation, SoftwareRelation, HostHardwareRelation, HostNetworkRelation, SnapshotRelation]: @@ -787,7 +790,7 @@ class SoftwareRelation(TaskRelation): class HostHardwareRelation(TaskRelation): - host = models.ForeignKey(Host, on_delete=models.CASCADE) + resource_id = models.CharField(max_length=200, default="default_id") config = models.OneToOneField(HardwareConfig, on_delete=models.CASCADE) job_key = "hardware" @@ -801,9 +804,14 @@ class HostHardwareRelation(TaskRelation): self.config.delete() return super(self.__class__, self).delete(*args, **kwargs) + def save(self, *args, **kwargs): + if len(ResourceQuery.filter(labid=self.resource_id)) != 1: + raise ValidationError("resource_id " + str(self.resource_id) + " does not refer to a single resource") + super().save(*args, **kwargs) + class HostNetworkRelation(TaskRelation): - host = models.ForeignKey(Host, on_delete=models.CASCADE) + resource_id = models.CharField(max_length=200, default="default_id") config = models.OneToOneField(NetworkConfig, on_delete=models.CASCADE) job_key = "network" @@ -814,6 +822,11 @@ class HostNetworkRelation(TaskRelation): self.config.delete() return super(self.__class__, self).delete(*args, **kwargs) + def save(self, *args, **kwargs): + if len(ResourceQuery.filter(labid=self.resource_id)) != 1: + raise ValidationError("resource_id " + str(self.resource_id) + " does not refer to a single resource") + super().save(*args, **kwargs) + class SnapshotRelation(TaskRelation): snapshot = models.ForeignKey(Image, on_delete=models.CASCADE) @@ -876,18 +889,18 @@ class JobFactory(object): @classmethod def makeCompleteJob(cls, booking): """Create everything that is needed to fulfill the given booking.""" - hosts = Host.objects.filter(bundle=booking.resource) + resources = booking.resource.get_resources() job = None try: job = Job.objects.get(booking=booking) except Exception: job = Job.objects.create(status=JobStatus.NEW, booking=booking) cls.makeHardwareConfigs( - hosts=hosts, + resources=resources, job=job ) cls.makeNetworkConfigs( - hosts=hosts, + resources=resources, job=job ) cls.makeSoftware( @@ -911,29 +924,29 @@ class JobFactory(object): job=job, context={ "key": user.userprofile.ssh_public_key.open().read().decode(encoding="UTF-8"), - "hosts": [host.labid for host in hosts] + "hosts": [r.labid for r in resources] } ) except Exception: continue @classmethod - def makeHardwareConfigs(cls, hosts=[], job=Job()): + def makeHardwareConfigs(cls, resources=[], job=Job()): """ Create and save HardwareConfig. Helper function to create the tasks related to configuring the hardware """ - for host in hosts: + for res in resources: hardware_config = None try: - hardware_config = HardwareConfig.objects.get(relation__host=host) + hardware_config = HardwareConfig.objects.get(relation__host=res) except Exception: hardware_config = HardwareConfig() relation = HostHardwareRelation() - relation.host = host + relation.resource_id = res.labid relation.job = job relation.config = hardware_config relation.config.save() @@ -969,29 +982,30 @@ class JobFactory(object): config.save() @classmethod - def makeNetworkConfigs(cls, hosts=[], job=Job()): + def makeNetworkConfigs(cls, resources=[], job=Job()): """ Create and save NetworkConfig. Helper function to create the tasks related to configuring the networking """ - for host in hosts: + for res in resources: network_config = None try: - network_config = NetworkConfig.objects.get(relation__host=host) + network_config = NetworkConfig.objects.get(relation__host=res) except Exception: network_config = NetworkConfig.objects.create() relation = HostNetworkRelation() - relation.host = host + relation.resource_id = res.labid relation.job = job network_config.save() relation.config = network_config relation.save() network_config.clear_delta() - for interface in host.interfaces.all(): + # TODO: use get_interfaces() on resource + for interface in res.interfaces.all(): network_config.add_interface(interface) network_config.save() @@ -1000,13 +1014,13 @@ class JobFactory(object): if booking.resource.hosts.count() < 2: return None try: - jumphost_config = HostOPNFVConfig.objects.filter( + jumphost_config = ResourceOPNFVConfig.objects.filter( role__name__iexact="jumphost" ) - jumphost = Host.objects.get( + jumphost = ResourceQuery.filter( bundle=booking.resource, - config=jumphost_config.host_config - ) + config=jumphost_config.resource_config + )[0] except Exception: return None br_config = BridgeConfig.objects.create(opnfv_config=booking.opnfv_config) @@ -1040,3 +1054,16 @@ class JobFactory(object): software_config = SoftwareConfig.objects.create(opnfv=opnfv_api_config) software_relation = SoftwareRelation.objects.create(job=job, config=software_config) return software_relation + + +JOB_TASK_CLASSLIST = [ + HostHardwareRelation, + AccessRelation, + HostNetworkRelation, + SoftwareRelation, + SnapshotRelation +] + + +class JobTaskQuery(AbstractModelQuery): + model_list = JOB_TASK_CLASSLIST -- cgit 1.2.3-korg From 8c012f8a9bc64add11920688abcd6981278cb0ea Mon Sep 17 00:00:00 2001 From: Parker Berberian Date: Thu, 13 Feb 2020 14:25:24 -0500 Subject: Fix Imports Fixes stale import statements. The dashboard can now come up and we can run our unit tests Change-Id: I7189afb2cd37aaa2492de065c236b6aa9a35de5b Signed-off-by: Parker Berberian --- src/account/views.py | 10 +++---- src/api/serializers/booking_serializer.py | 4 +-- src/booking/quick_deployer.py | 20 ++++++------- src/booking/views.py | 6 ++-- src/dashboard/utils.py | 18 ++++++++++++ src/dashboard/views.py | 4 +-- src/resource_inventory/admin.py | 47 ++++++++++++++++--------------- src/resource_inventory/models.py | 1 + src/resource_inventory/views.py | 6 ++-- src/workflow/booking_workflow.py | 7 ++--- src/workflow/models.py | 4 +-- src/workflow/opnfv_workflow.py | 4 +-- src/workflow/resource_bundle_workflow.py | 30 +++++++++----------- src/workflow/snapshot_workflow.py | 4 +-- src/workflow/sw_bundle_workflow.py | 12 ++++---- src/workflow/workflow_manager.py | 13 ++++----- 16 files changed, 104 insertions(+), 86 deletions(-) (limited to 'src/api') diff --git a/src/account/views.py b/src/account/views.py index ccc4c8d..a8bb02b 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 +from resource_inventory.models import ResourceTemplate, Image @method_decorator(login_required, name='dispatch') @@ -177,7 +177,7 @@ def account_resource_view(request): if not request.user.is_authenticated: return render(request, "dashboard/login.html", {'title': 'Authentication Required'}) template = "account/resource_list.html" - resources = GenericResourceBundle.objects.filter( + resources = ResourceTemplate.objects.filter( owner=request.user).prefetch_related("configbundle_set") mapping = {} resource_list = [] @@ -218,7 +218,7 @@ def account_configuration_view(request): if not request.user.is_authenticated: return render(request, "dashboard/login.html", {'title': 'Authentication Required'}) template = "account/configuration_list.html" - configs = list(ConfigBundle.objects.filter(owner=request.user)) + configs = list(ResourceTemplate.objects.filter(owner=request.user)) context = {"title": "Configuration List", "configurations": configs} return render(request, template, context=context) @@ -245,7 +245,7 @@ def account_images_view(request): def resource_delete_view(request, resource_id=None): if not request.user.is_authenticated: return HttpResponse('no') # 403? - grb = get_object_or_404(GenericResourceBundle, pk=resource_id) + grb = get_object_or_404(ResourceTemplate, pk=resource_id) if not request.user.id == grb.owner.id: return HttpResponse('no') # 403? if Booking.objects.filter(resource__template=grb, end__gt=timezone.now()).exists(): @@ -257,7 +257,7 @@ def resource_delete_view(request, resource_id=None): def configuration_delete_view(request, config_id=None): if not request.user.is_authenticated: return HttpResponse('no') # 403? - config = get_object_or_404(ConfigBundle, pk=config_id) + config = get_object_or_404(ResourceTemplate, pk=config_id) if not request.user.id == config.owner.id: return HttpResponse('no') # 403? if Booking.objects.filter(config_bundle=config, end__gt=timezone.now()).exists(): diff --git a/src/api/serializers/booking_serializer.py b/src/api/serializers/booking_serializer.py index 46a2348..993eb22 100644 --- a/src/api/serializers/booking_serializer.py +++ b/src/api/serializers/booking_serializer.py @@ -11,7 +11,7 @@ from rest_framework import serializers from resource_inventory.models import ( - HostConfiguration, + ResourceConfiguration, CpuProfile, DiskProfile, InterfaceProfile, @@ -35,7 +35,7 @@ class BookingField(serializers.Field): host_configs = {} # mapping hostname -> config networks = {} # mapping vlan id -> network_hosts for host in booking.resource.hosts.all(): - host_configs[host.name] = HostConfiguration.objects.get(host=host.template) + host_configs[host.name] = ResourceConfiguration.objects.get(host=host.template) if "jumphost" not in ser and host_configs[host.name].opnfvRole.name.lower() == "jumphost": ser['jumphost'] = host.name # host is a Host model diff --git a/src/booking/quick_deployer.py b/src/booking/quick_deployer.py index 94ad14d..917f578 100644 --- a/src/booking/quick_deployer.py +++ b/src/booking/quick_deployer.py @@ -12,7 +12,7 @@ import json from django.db.models import Q from datetime import timedelta from django.utils import timezone -from django.form import ValidationException +from django.core.exceptions import ValidationError from account.models import Lab from resource_inventory.models import ( @@ -21,7 +21,7 @@ from resource_inventory.models import ( Image, OPNFVRole, OPNFVConfig, - HostOPNFVConfig, + ResourceOPNFVConfig, ) from resource_inventory.resource_manager import ResourceManager from resource_inventory.pdf_templater import PDFTemplater @@ -49,9 +49,9 @@ def parse_resource_field(resource_json): template = ResourceTemplate.objects.get(pk=resource_info['id']) if lab is None: - raise ValidationException("No lab was selected") + raise ValidationError("No lab was selected") if template is None: - raise ValidationException("No Host was selected") + raise ValidationError("No Host was selected") return lab, template @@ -82,7 +82,7 @@ def generate_hostopnfv(hostconfig, opnfvconfig): name="Jumphost", description="Single server jumphost role" ) - return HostOPNFVConfig.objects.create( + return ResourceOPNFVConfig.objects.create( role=role, host_config=hostconfig, opnfv_config=opnfvconfig @@ -107,15 +107,15 @@ def check_invariants(request, **kwargs): if installer in image.os.sup_installers.all(): # if installer not here, we can omit that and not check for scenario if not scenario: - raise ValidationException("An OPNFV Installer needs a scenario to be chosen to work properly") + raise ValidationError("An OPNFV Installer needs a scenario to be chosen to work properly") if scenario not in installer.sup_scenarios.all(): - raise ValidationException("The chosen installer does not support the chosen scenario") + raise ValidationError("The chosen installer does not support the chosen scenario") if image.from_lab != lab: - raise ValidationException("The chosen image is not available at the chosen hosting lab") + raise ValidationError("The chosen image is not available at the chosen hosting lab") if image.host_type != host_profile: - raise ValidationException("The chosen image is not available for the chosen host type") + raise ValidationError("The chosen image is not available for the chosen host type") if not image.public and image.owner != request.user: - raise ValidationException("You are not the owner of the chosen private image") + raise ValidationError("You are not the owner of the chosen private image") if length < 1 or length > 21: raise BookingLengthException("Booking must be between 1 and 21 days long") diff --git a/src/booking/views.py b/src/booking/views.py index 8e25952..39b24a7 100644 --- a/src/booking/views.py +++ b/src/booking/views.py @@ -18,7 +18,7 @@ from django.shortcuts import redirect, render from django.db.models import Q from django.urls import reverse -from resource_inventory.models import ResourceBundle, HostProfile, Image, Host +from resource_inventory.models import ResourceBundle, ResourceProfile, Image, ResourceQuery from resource_inventory.resource_manager import ResourceManager from account.models import Lab, Downtime from booking.models import Booking @@ -130,7 +130,7 @@ class ResourceBookingsJSON(View): def build_image_mapping(lab, user): mapping = {} - for profile in HostProfile.objects.filter(labs=lab): + for profile in ResourceProfile.objects.filter(labs=lab): images = Image.objects.filter( from_lab=lab, host_type=profile @@ -178,7 +178,7 @@ def booking_modify_image(request, booking_id): if timezone.now() > booking.end: return HttpResponse("unauthorized") new_image = Image.objects.get(id=form.cleaned_data['image_id']) - host = Host.objects.get(id=form.cleaned_data['host_id']) + host = ResourceQuery.get(labid=form.cleaned_data['host_id']) host.config.image = new_image host.config.save() JobFactory.reimageHost(new_image, booking, host) diff --git a/src/dashboard/utils.py b/src/dashboard/utils.py index af2461e..3d63366 100644 --- a/src/dashboard/utils.py +++ b/src/dashboard/utils.py @@ -1,3 +1,14 @@ +############################################################################## +# Copyright (c) 2020 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.core.exceptions import ObjectDoesNotExist + class AbstractModelQuery(): """ @@ -22,3 +33,10 @@ class AbstractModelQuery(): result = [] for model in cls.model_list: result += list(model.objects.filter(*args, **kwargs)) + + @classmethod + def get(cls, *args, **kwargs): + try: + return cls.filter(*args, **kwargs)[0] + except IndexError: + raise ObjectDoesNotExist() diff --git a/src/dashboard/views.py b/src/dashboard/views.py index 2f37774..498bd9d 100644 --- a/src/dashboard/views.py +++ b/src/dashboard/views.py @@ -15,7 +15,7 @@ from django.shortcuts import render from account.models import Lab -from resource_inventory.models import Image, HostProfile +from resource_inventory.models import Image, ResourceProfile from workflow.workflow_manager import ManagerTracker @@ -80,7 +80,7 @@ class LandingView(TemplateView): hosts = [] - for host_profile in HostProfile.objects.all(): + for host_profile in ResourceProfile.objects.all(): name = host_profile.name description = host_profile.description in_labs = host_profile.labs diff --git a/src/resource_inventory/admin.py b/src/resource_inventory/admin.py index ab21dd1..13afd99 100644 --- a/src/resource_inventory/admin.py +++ b/src/resource_inventory/admin.py @@ -16,11 +16,10 @@ from resource_inventory.models import ( DiskProfile, CpuProfile, RamProfile, - GenericResourceBundle, - GenericResource, - GenericHost, - GenericInterface, - Host, + ResourceTemplate, + ResourceConfiguration, + InterfaceConfiguration, + Server, Interface, Network, Vlan, @@ -28,26 +27,30 @@ from resource_inventory.models import ( Scenario, Installer, Opsys, - ConfigBundle, OPNFVConfig, OPNFVRole, Image, - ResourceConfiguration, RemoteInfo ) -profiles = [HostProfile, InterfaceProfile, DiskProfile, CpuProfile, RamProfile] - -admin.site.register(profiles) - -generics = [GenericResourceBundle, GenericResource, GenericHost, GenericInterface] - -admin.site.register(generics) - -physical = [Host, Interface, Network, Vlan, ResourceBundle] - -admin.site.register(physical) - -config = [Scenario, Installer, Opsys, ConfigBundle, OPNFVConfig, OPNFVRole, Image, HostConfiguration, RemoteInfo] - -admin.site.register(config) +admin.site.register([ + ResourceProfile, + InterfaceProfile, + DiskProfile, + CpuProfile, + RamProfile, + ResourceTemplate, + ResourceConfiguration, + InterfaceConfiguration, + Server, + Interface, + Network, + Vlan, + ResourceBundle, + Scenario, + Installer, + Opsys, + OPNFVConfig, + OPNFVRole, + Image, + RemoteInfo]) diff --git a/src/resource_inventory/models.py b/src/resource_inventory/models.py index 20e080b..eec009a 100644 --- a/src/resource_inventory/models.py +++ b/src/resource_inventory/models.py @@ -200,6 +200,7 @@ class ResourceConfiguration(models.Model): 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? def __str__(self): return "config with " + str(self.template) + " and image " + str(self.image) diff --git a/src/resource_inventory/views.py b/src/resource_inventory/views.py index 8c3d899..52f8c75 100644 --- a/src/resource_inventory/views.py +++ b/src/resource_inventory/views.py @@ -12,7 +12,7 @@ from django.views.generic import TemplateView from django.shortcuts import get_object_or_404 from django.shortcuts import render -from resource_inventory.models import HostProfile, Host +from resource_inventory.models import ResourceProfile, ResourceQuery class HostView(TemplateView): @@ -20,13 +20,13 @@ class HostView(TemplateView): def get_context_data(self, **kwargs): context = super(HostView, self).get_context_data(**kwargs) - hosts = Host.objects.filter(working=True) + 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(HostProfile, id=hostprofile_id) + hostprofile = get_object_or_404(ResourceProfile, id=hostprofile_id) return render( request, diff --git a/src/workflow/booking_workflow.py b/src/workflow/booking_workflow.py index c96e1b9..00fa0f9 100644 --- a/src/workflow/booking_workflow.py +++ b/src/workflow/booking_workflow.py @@ -14,7 +14,7 @@ from datetime import timedelta from booking.models import Booking from workflow.models import WorkflowStep, AbstractSelectOrCreate from workflow.forms import ResourceSelectorForm, SWConfigSelectorForm, BookingMetaForm, OPNFVSelectForm -from resource_inventory.models import GenericResourceBundle, ConfigBundle, OPNFVConfig +from resource_inventory.models import OPNFVConfig, ResourceTemplate from django.db.models import Q @@ -44,8 +44,7 @@ class Abstract_Resource_Select(AbstractSelectOrCreate): def get_form_queryset(self): user = self.repo_get(self.repo.SESSION_USER) - qs = GenericResourceBundle.objects.filter(Q(hidden=False) & (Q(owner=user) | Q(public=True))) - return qs + return ResourceTemplate.objects.filter(Q(hidden=False) & (Q(owner=user) | Q(public=True))) def get_page_context(self): return { @@ -83,7 +82,7 @@ class SWConfig_Select(AbstractSelectOrCreate): def get_form_queryset(self): user = self.repo_get(self.repo.SESSION_USER) grb = self.repo_get(self.repo.SELECTED_GRESOURCE_BUNDLE) - qs = ConfigBundle.objects.filter(Q(hidden=False) & (Q(owner=user) | Q(public=True))).filter(bundle=grb) + qs = ResourceTemplate.objects.filter(Q(hidden=False) & (Q(owner=user) | Q(public=True))).filter(bundle=grb) return qs def put_confirm_info(self, bundle): diff --git a/src/workflow/models.py b/src/workflow/models.py index 4d32869..df00d21 100644 --- a/src/workflow/models.py +++ b/src/workflow/models.py @@ -18,7 +18,7 @@ import requests from workflow.forms import ConfirmationForm from api.models import JobFactory from dashboard.exceptions import ResourceAvailabilityException, ModelValidationException -from resource_inventory.models import Image, InterfaceProfile, OPNFVConfig, ResourceOPNFVConfig, NetworkRole +from resource_inventory.models import Image, InterfaceConfiguration, OPNFVConfig, ResourceOPNFVConfig, NetworkRole from resource_inventory.resource_manager import ResourceManager from resource_inventory.pdf_templater import PDFTemplater from notifier.manager import NotificationHandler @@ -725,7 +725,7 @@ class Repository(): config = config_bundle.hostConfigurations.get( host__resource__name=host_role['host_name'] ) - HostOPNFVConfig.objects.create( + ResourceOPNFVConfig.objects.create( role=host_role['role'], host_config=config, opnfv_config=opnfv_config diff --git a/src/workflow/opnfv_workflow.py b/src/workflow/opnfv_workflow.py index 0cac48e..6ffc91d 100644 --- a/src/workflow/opnfv_workflow.py +++ b/src/workflow/opnfv_workflow.py @@ -11,7 +11,7 @@ from django.forms import formset_factory from workflow.models import WorkflowStep, AbstractSelectOrCreate -from resource_inventory.models import ConfigBundle, OPNFV_SETTINGS +from resource_inventory.models import ResourceTemplate, OPNFV_SETTINGS from workflow.forms import OPNFVSelectionForm, OPNFVNetworkRoleForm, OPNFVHostRoleForm, SWConfigSelectorForm, BasicMetaForm @@ -27,7 +27,7 @@ class OPNFV_Resource_Select(AbstractSelectOrCreate): def get_form_queryset(self): user = self.repo_get(self.repo.SESSION_USER) - qs = ConfigBundle.objects.filter(owner=user) + qs = ResourceTemplate.objects.filter(owner=user) return qs def put_confirm_info(self, bundle): diff --git a/src/workflow/resource_bundle_workflow.py b/src/workflow/resource_bundle_workflow.py index f57476b..89baae7 100644 --- a/src/workflow/resource_bundle_workflow.py +++ b/src/workflow/resource_bundle_workflow.py @@ -22,11 +22,10 @@ from workflow.forms import ( ResourceMetaForm, ) from resource_inventory.models import ( - GenericResourceBundle, - GenericInterface, - GenericHost, - GenericResource, - HostProfile, + ResourceProfile, + ResourceTemplate, + ResourceConfiguration, + InterfaceConfiguration, Network, NetworkConnection ) @@ -64,12 +63,12 @@ class Define_Hardware(WorkflowStep): models['hosts'] = [] # This will always clear existing data when this step changes models['interfaces'] = {} if "bundle" not in models: - models['bundle'] = GenericResourceBundle(owner=self.repo_get(self.repo.SESSION_USER)) + models['bundle'] = ResourceTemplate(owner=self.repo_get(self.repo.SESSION_USER)) host_data = data['host'] names = {} for host_profile_dict in host_data.values(): id = host_profile_dict['id'] - profile = HostProfile.objects.get(id=id) + profile = ResourceProfile.objects.get(id=id) # instantiate genericHost and store in repo for name in host_profile_dict['values'].values(): if not re.match(r"(?=^.{1,253}$)(^([A-Za-z0-9-_]{1,62}\.)*[A-Za-z0-9-_]{1,63})", name): @@ -77,14 +76,13 @@ class Define_Hardware(WorkflowStep): if name in names: raise NonUniqueHostnameException("All hosts must have unique names") names[name] = True - genericResource = GenericResource(bundle=models['bundle'], name=name) - genericHost = GenericHost(profile=profile, resource=genericResource) - models['hosts'].append(genericHost) + resourceConfig = ResourceConfiguration(profile=profile, template=models['bundle']) + models['hosts'].append(resourceConfig) for interface_profile in profile.interfaceprofile.all(): - genericInterface = GenericInterface(profile=interface_profile, host=genericHost) - if genericHost.resource.name not in models['interfaces']: - models['interfaces'][genericHost.resource.name] = [] - models['interfaces'][genericHost.resource.name].append(genericInterface) + genericInterface = InterfaceConfiguration(profile=interface_profile, resource_config=resourceConfig) + if resourceConfig.name not in models['interfaces']: + models['interfaces'][resourceConfig.name] = [] + models['interfaces'][resourceConfig.name].append(genericInterface) # add selected lab to models for lab_dict in data['lab'].values(): @@ -226,7 +224,7 @@ class Define_Nets(WorkflowStep): for host in existing_host_list: existing_hosts[host.resource.name] = host - bundle = models.get("bundle", GenericResourceBundle(owner=self.repo_get(self.repo.SESSION_USER))) + bundle = models.get("bundle", ResourceTemplate(owner=self.repo_get(self.repo.SESSION_USER))) for net_id, net in networks.items(): network = Network() @@ -381,7 +379,7 @@ class Resource_Meta_Info(WorkflowStep): models = self.repo_get(self.repo.GRESOURCE_BUNDLE_MODELS, {}) name = form.cleaned_data['bundle_name'] desc = form.cleaned_data['bundle_description'] - bundle = models.get("bundle", GenericResourceBundle(owner=self.repo_get(self.repo.SESSION_USER))) + bundle = models.get("bundle", ResourceTemplate(owner=self.repo_get(self.repo.SESSION_USER))) bundle.name = name bundle.description = desc models['bundle'] = bundle diff --git a/src/workflow/snapshot_workflow.py b/src/workflow/snapshot_workflow.py index c2f4cd6..c0e2052 100644 --- a/src/workflow/snapshot_workflow.py +++ b/src/workflow/snapshot_workflow.py @@ -12,7 +12,7 @@ from django.utils import timezone import json from booking.models import Booking -from resource_inventory.models import Host, Image +from resource_inventory.models import ResourceQuery, Image from workflow.models import WorkflowStep from workflow.forms import BasicMetaForm, SnapshotHostSelectForm @@ -61,7 +61,7 @@ class Select_Host_Step(WorkflowStep): name = host['name'] booking_id = host['booking'] booking = Booking.objects.get(pk=booking_id) - host = Host.objects.get(bundle=booking.resource, template__resource__name=name) + host = ResourceQuery.get(bundle=booking.resource, template__resource__name=name) models = self.repo_get(self.repo.SNAPSHOT_MODELS, {}) if "host" not in models: models['host'] = host diff --git a/src/workflow/sw_bundle_workflow.py b/src/workflow/sw_bundle_workflow.py index ebd8c86..686f46f 100644 --- a/src/workflow/sw_bundle_workflow.py +++ b/src/workflow/sw_bundle_workflow.py @@ -13,7 +13,7 @@ from django.forms import formset_factory from workflow.models import WorkflowStep from workflow.forms import BasicMetaForm, HostSoftwareDefinitionForm from workflow.booking_workflow import Abstract_Resource_Select -from resource_inventory.models import Image, GenericHost, ConfigBundle, HostConfiguration +from resource_inventory.models import Image, ResourceConfiguration, ResourceTemplate class SWConf_Resource_Select(Abstract_Resource_Select): @@ -38,7 +38,7 @@ class Define_Software(WorkflowStep): user = self.repo_get(self.repo.SESSION_USER) lab = self.repo_get(self.repo.SELECTED_GRESOURCE_BUNDLE).lab for i, host_data in enumerate(hosts_data): - host = GenericHost.objects.get(pk=host_data['host_id']) + host = ResourceConfiguration.objects.get(pk=host_data['host_id']) wrong_owner = Image.objects.exclude(owner=user).exclude(public=True) wrong_host = Image.objects.exclude(host_type=host.profile) wrong_lab = Image.objects.exclude(from_lab=lab) @@ -86,7 +86,7 @@ class Define_Software(WorkflowStep): if not grb: return [] if grb.id: - return GenericHost.objects.filter(resource__bundle=grb) + return ResourceConfiguration.objects.filter(resource__bundle=grb) generic_hosts = self.repo_get(self.repo.GRESOURCE_BUNDLE_MODELS, {}).get("hosts", []) return generic_hosts @@ -109,7 +109,7 @@ class Define_Software(WorkflowStep): def post(self, post_data, user): models = self.repo_get(self.repo.CONFIG_MODELS, {}) if "bundle" not in models: - models['bundle'] = ConfigBundle(owner=self.repo_get(self.repo.SESSION_USER)) + models['bundle'] = ResourceTemplate(owner=self.repo_get(self.repo.SESSION_USER)) confirm = self.repo_get(self.repo.CONFIRMATION, {}) @@ -127,7 +127,7 @@ class Define_Software(WorkflowStep): if headnode: has_headnode = True bundle = models['bundle'] - hostConfig = HostConfiguration( + hostConfig = ResourceConfiguration( host=host, image=image, bundle=bundle, @@ -175,7 +175,7 @@ class Config_Software(WorkflowStep): def post(self, post_data, user): models = self.repo_get(self.repo.CONFIG_MODELS, {}) if "bundle" not in models: - models['bundle'] = ConfigBundle(owner=self.repo_get(self.repo.SESSION_USER)) + models['bundle'] = ResourceTemplate(owner=self.repo_get(self.repo.SESSION_USER)) confirm = self.repo_get(self.repo.CONFIRMATION, {}) if "configuration" not in confirm: diff --git a/src/workflow/workflow_manager.py b/src/workflow/workflow_manager.py index fda105e..e31e14c 100644 --- a/src/workflow/workflow_manager.py +++ b/src/workflow/workflow_manager.py @@ -16,9 +16,8 @@ from booking.models import Booking from workflow.workflow_factory import WorkflowFactory from workflow.models import Repository from resource_inventory.models import ( - GenericResourceBundle, - ConfigBundle, - HostConfiguration, + ResourceTemplate, + ResourceConfiguration, OPNFVConfig ) from workflow.forms import ManagerForm @@ -154,10 +153,10 @@ class SessionManager(): edit_object = Booking.objects.get(pk=target_id) self.prefill_booking(edit_object) elif workflow_type == 1: - edit_object = GenericResourceBundle.objects.get(pk=target_id) + edit_object = ResourceTemplate.objects.get(pk=target_id) self.prefill_resource(edit_object) elif workflow_type == 2: - edit_object = ConfigBundle.objects.get(pk=target_id) + edit_object = ResourceTemplate.objects.get(pk=target_id) self.prefill_config(edit_object) def prefill_booking(self, booking): @@ -213,7 +212,7 @@ class SessionManager(): models = self.active_workflow().repository.el.get(self.active_workflow().repository.CONFIG_MODELS, {}) models['bundle'] = config models['host_configs'] = [] - for host_conf in HostConfiguration.objects.filter(bundle=config): + for host_conf in ResourceConfiguration.objects.filter(bundle=config): models['host_configs'].append(host_conf) models['opnfv'] = OPNFVConfig.objects.filter(bundle=config).last() return models @@ -227,7 +226,7 @@ class SessionManager(): opnfv = OPNFVConfig.objects.filter(bundle=config).last() confirm['configuration']['installer'] = opnfv.installer.name confirm['configuration']['scenario'] = opnfv.scenario.name - for host_conf in HostConfiguration.objects.filter(bundle=config): + for host_conf in ResourceConfiguration.objects.filter(bundle=config): h = {"name": host_conf.host.resource.name, "image": host_conf.image.name, "role": host_conf.opnfvRole.name} confirm['configuration']['hosts'].append(h) return confirm -- cgit 1.2.3-korg From d73588dfe1066f85bb83df0e3c0881ff42c25e04 Mon Sep 17 00:00:00 2001 From: Parker Berberian Date: Tue, 18 Feb 2020 13:17:10 -0500 Subject: Add Migration Files Adds migration files with some custom logic to accompany the refactoring in resource_inventory. Change-Id: Id3b3e46913c1f9a102426a5c33d7a282f46e8b28 Signed-off-by: Parker Berberian --- src/api/migrations/0011_auto_20200218_1536.py | 54 +++ src/api/migrations/0012_manual_20200220.py | 18 + .../0007_remove_booking_config_bundle.py | 17 + .../migrations/0013_auto_20200218_1536.py | 449 +++++++++++++++++++++ 4 files changed, 538 insertions(+) create mode 100644 src/api/migrations/0011_auto_20200218_1536.py create mode 100644 src/api/migrations/0012_manual_20200220.py create mode 100644 src/booking/migrations/0007_remove_booking_config_bundle.py create mode 100644 src/resource_inventory/migrations/0013_auto_20200218_1536.py (limited to 'src/api') diff --git a/src/api/migrations/0011_auto_20200218_1536.py b/src/api/migrations/0011_auto_20200218_1536.py new file mode 100644 index 0000000..a399495 --- /dev/null +++ b/src/api/migrations/0011_auto_20200218_1536.py @@ -0,0 +1,54 @@ +# Generated by Django 2.2 on 2020-02-18 15:36 + +from django.db import migrations, models + + +def set_resource_id(apps, schema_editor): + for cls in ["HardwareConfig", "NetworkConfig", "SnapshotConfig"]: + model = apps.get_model('api', cls) + for m in model.objects.all(): + m.resource_id = m.host.labid + m.save() + + +class Migration(migrations.Migration): + + dependencies = [ + ('api', '0010_auto_20191219_2004'), + # ('resource_inventory', '0013_auto_20200218_1536') + ] + + operations = [ + migrations.AddField( + model_name='hosthardwarerelation', + name='resource_id', + field=models.CharField(default='default_id', max_length=200), + ), + migrations.AddField( + model_name='hostnetworkrelation', + name='resource_id', + field=models.CharField(default='default_id', max_length=200), + ), + migrations.AddField( + model_name='snapshotconfig', + name='resource_id', + field=models.CharField(default='default_id', max_length=200), + ), + migrations.RunPython(set_resource_id), + migrations.RemoveField( + model_name='hosthardwarerelation', + name='host', + ), + migrations.RemoveField( + model_name='hostnetworkrelation', + name='host', + ), + migrations.RemoveField( + model_name='snapshotconfig', + name='host', + ), + migrations.RemoveField( + model_name='opnfvapiconfig', + name='roles', + ), + ] diff --git a/src/api/migrations/0012_manual_20200220.py b/src/api/migrations/0012_manual_20200220.py new file mode 100644 index 0000000..40f7e79 --- /dev/null +++ b/src/api/migrations/0012_manual_20200220.py @@ -0,0 +1,18 @@ + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('api', '0011_auto_20200218_1536'), + ('resource_inventory', '0013_auto_20200218_1536') + ] + + operations = [ + migrations.AddField( + model_name='opnfvapiconfig', + name='roles', + field=models.ManyToManyField(to='resource_inventory.ResourceOPNFVConfig'), + ), + ] diff --git a/src/booking/migrations/0007_remove_booking_config_bundle.py b/src/booking/migrations/0007_remove_booking_config_bundle.py new file mode 100644 index 0000000..dcd2e1c --- /dev/null +++ b/src/booking/migrations/0007_remove_booking_config_bundle.py @@ -0,0 +1,17 @@ +# Generated by Django 2.2 on 2020-02-18 15:36 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('booking', '0006_booking_opnfv_config'), + ] + + operations = [ + migrations.RemoveField( + model_name='booking', + name='config_bundle', + ), + ] diff --git a/src/resource_inventory/migrations/0013_auto_20200218_1536.py b/src/resource_inventory/migrations/0013_auto_20200218_1536.py new file mode 100644 index 0000000..3049dc7 --- /dev/null +++ b/src/resource_inventory/migrations/0013_auto_20200218_1536.py @@ -0,0 +1,449 @@ +# 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 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') + for h in Host.objects.all(): + Server.objects.create( + working=h.working, + vendor=h.vendor, + labid=h.labid, + booked=h.booked, + name=h.labid + ) + + +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(name=hp.name, description=hp.description) + rp.labs.add(*list(hp.labs.all())) + rp.interfaceprofile = hp.interfaceprofile + rp.storageprofile = hp.storageprofile + rp.cpuprofile = hp.cpuprofile + rp.ramprofile = hp.ramprofile + rp.save() + rp.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): + """TODO: Creation of the following models. + + - Server + - ResourceTemplate + - ResourceProfile + - ResourceConfiguration (?) + - InterfaceConfiguration (?) + + And set the correct defaults for the following fields: + - Interface.profile + - OpnfvConfig.template (?) + - physicalnetwork.lab + - physicalnetwork.profile + """ + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('booking', '0007_remove_booking_config_bundle'), + ('account', '0004_downtime'), + ('api', '0011_auto_20200218_1536'), + ('resource_inventory', '0012_auto_20200103_1850'), + ] + + 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.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.AddField( + model_name='physicalnetwork', + name='bundle', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='resource_inventory.ResourceBundle'), + ), + migrations.AddField( + model_name='physicalnetwork', + name='interfaces', + field=models.ManyToManyField(to='resource_inventory.Interface'), + ), + migrations.AddField( + model_name='physicalnetwork', + name='lab', + field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='account.Lab'), + preserve_default=False, + ), + migrations.AddField( + model_name='physicalnetwork', + name='labid', + field=models.CharField(default='default_id', max_length=200, unique=True), + ), + migrations.AddField( + model_name='physicalnetwork', + name='model', + field=models.CharField(default='unknown', max_length=150), + ), + migrations.AddField( + model_name='physicalnetwork', + 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.AddField( + model_name='physicalnetwork', + name='vendor', + field=models.CharField(default='unknown', max_length=100), + ), + migrations.AddField( + model_name='physicalnetwork', + name='working', + field=models.BooleanField(default=True), + ), + 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.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='Host', + ), + migrations.DeleteModel( + name='HostConfiguration', + ), + migrations.DeleteModel( + name='HostOPNFVConfig', + ), + migrations.DeleteModel( + name='HostProfile', + ), + 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.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.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, + ), + migrations.AddField( + model_name='physicalnetwork', + name='config', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='resource_inventory.ResourceConfiguration'), + ), + migrations.AddField( + model_name='physicalnetwork', + name='profile', + field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='resource_inventory.ResourceProfile'), + preserve_default=False, + ), + ] -- cgit 1.2.3-korg From 4940cda1806aa13591485b996264ddc887202d35 Mon Sep 17 00:00:00 2001 From: Parker Berberian Date: Thu, 27 Feb 2020 16:26:47 -0500 Subject: Improve Data Migration Improved migration files so that they preserve data Change-Id: I53283fd3fd207ed3f9773beea7b1ce2062b5bd9f Signed-off-by: Parker Berberian --- src/api/migrations/0011_auto_20200218_1536.py | 25 ---- src/api/migrations/0012_manual_20200218_1536.py | 22 +++ src/api/migrations/0012_manual_20200220.py | 18 --- src/api/migrations/0013_manual_20200218_1536.py | 29 ++++ src/api/migrations/0014_manual_20200220.py | 18 +++ .../migrations/0012_auto_20200103_1850.py | 37 ++--- .../migrations/0012_manual_20200218_1536.py | 25 ++++ .../migrations/0013_auto_20200218_1536.py | 161 ++++++++------------- src/resource_inventory/models.py | 2 +- 9 files changed, 163 insertions(+), 174 deletions(-) create mode 100644 src/api/migrations/0012_manual_20200218_1536.py delete mode 100644 src/api/migrations/0012_manual_20200220.py create mode 100644 src/api/migrations/0013_manual_20200218_1536.py create mode 100644 src/api/migrations/0014_manual_20200220.py create mode 100644 src/resource_inventory/migrations/0012_manual_20200218_1536.py (limited to 'src/api') diff --git a/src/api/migrations/0011_auto_20200218_1536.py b/src/api/migrations/0011_auto_20200218_1536.py index a399495..0fd7029 100644 --- a/src/api/migrations/0011_auto_20200218_1536.py +++ b/src/api/migrations/0011_auto_20200218_1536.py @@ -3,14 +3,6 @@ from django.db import migrations, models -def set_resource_id(apps, schema_editor): - for cls in ["HardwareConfig", "NetworkConfig", "SnapshotConfig"]: - model = apps.get_model('api', cls) - for m in model.objects.all(): - m.resource_id = m.host.labid - m.save() - - class Migration(migrations.Migration): dependencies = [ @@ -34,21 +26,4 @@ class Migration(migrations.Migration): name='resource_id', field=models.CharField(default='default_id', max_length=200), ), - migrations.RunPython(set_resource_id), - migrations.RemoveField( - model_name='hosthardwarerelation', - name='host', - ), - migrations.RemoveField( - model_name='hostnetworkrelation', - name='host', - ), - migrations.RemoveField( - model_name='snapshotconfig', - name='host', - ), - migrations.RemoveField( - model_name='opnfvapiconfig', - name='roles', - ), ] diff --git a/src/api/migrations/0012_manual_20200218_1536.py b/src/api/migrations/0012_manual_20200218_1536.py new file mode 100644 index 0000000..55befbd --- /dev/null +++ b/src/api/migrations/0012_manual_20200218_1536.py @@ -0,0 +1,22 @@ +# Generated by Django 2.2 on 2020-02-18 15:36 + +from django.db import migrations + + +def set_resource_id(apps, schema_editor): + for cls in ["HostHardwareRelation", "HostNetworkRelation", "SnapshotConfig"]: + model = apps.get_model('api', cls) + for m in model.objects.all(): + m.resource_id = m.host.labid + m.save() + + +class Migration(migrations.Migration): + + dependencies = [ + ('api', '0011_auto_20200218_1536'), + ] + + operations = [ + migrations.RunPython(set_resource_id), + ] diff --git a/src/api/migrations/0012_manual_20200220.py b/src/api/migrations/0012_manual_20200220.py deleted file mode 100644 index 40f7e79..0000000 --- a/src/api/migrations/0012_manual_20200220.py +++ /dev/null @@ -1,18 +0,0 @@ - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('api', '0011_auto_20200218_1536'), - ('resource_inventory', '0013_auto_20200218_1536') - ] - - operations = [ - migrations.AddField( - model_name='opnfvapiconfig', - name='roles', - field=models.ManyToManyField(to='resource_inventory.ResourceOPNFVConfig'), - ), - ] diff --git a/src/api/migrations/0013_manual_20200218_1536.py b/src/api/migrations/0013_manual_20200218_1536.py new file mode 100644 index 0000000..0b76e84 --- /dev/null +++ b/src/api/migrations/0013_manual_20200218_1536.py @@ -0,0 +1,29 @@ +# Generated by Django 2.2 on 2020-02-18 15:36 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('api', '0012_manual_20200218_1536'), + ] + + operations = [ + migrations.RemoveField( + model_name='hosthardwarerelation', + name='host', + ), + migrations.RemoveField( + model_name='hostnetworkrelation', + name='host', + ), + migrations.RemoveField( + model_name='snapshotconfig', + name='host', + ), + migrations.RemoveField( + model_name='opnfvapiconfig', + name='roles', + ), + ] diff --git a/src/api/migrations/0014_manual_20200220.py b/src/api/migrations/0014_manual_20200220.py new file mode 100644 index 0000000..2e2cd58 --- /dev/null +++ b/src/api/migrations/0014_manual_20200220.py @@ -0,0 +1,18 @@ + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('api', '0013_manual_20200218_1536'), + ('resource_inventory', '0013_auto_20200218_1536') + ] + + operations = [ + migrations.AddField( + model_name='opnfvapiconfig', + name='roles', + field=models.ManyToManyField(to='resource_inventory.ResourceOPNFVConfig'), + ), + ] diff --git a/src/resource_inventory/migrations/0012_auto_20200103_1850.py b/src/resource_inventory/migrations/0012_auto_20200103_1850.py index 2bb203e..569e433 100644 --- a/src/resource_inventory/migrations/0012_auto_20200103_1850.py +++ b/src/resource_inventory/migrations/0012_auto_20200103_1850.py @@ -4,30 +4,23 @@ from django.db import migrations, models import django.db.models.deletion -def genTempVlanNetwork(apps, editor): +def pairVlanPhysicalNetworks(apps, editor): + PhysicalNetwork = apps.get_model("resource_inventory", "PhysicalNetwork") 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) + 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 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): + 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 = [ @@ -56,21 +49,11 @@ class Migration(migrations.Migration): 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.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), ), - migrations.RunPython(pairVlanPhysicalNetworks, deletePhysicalNetworks), - migrations.DeleteModel("tempVlanNetwork") ] diff --git a/src/resource_inventory/migrations/0012_manual_20200218_1536.py b/src/resource_inventory/migrations/0012_manual_20200218_1536.py new file mode 100644 index 0000000..378bdc3 --- /dev/null +++ b/src/resource_inventory/migrations/0012_manual_20200218_1536.py @@ -0,0 +1,25 @@ +# 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 index 3049dc7..014cb2f 100644 --- a/src/resource_inventory/migrations/0013_auto_20200218_1536.py +++ b/src/resource_inventory/migrations/0013_auto_20200218_1536.py @@ -6,17 +6,33 @@ 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(id=1, name="Default Template") + + 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.objects.create( working=h.working, vendor=h.vendor, labid=h.labid, booked=h.booked, - name=h.labid + name=h.labid, + lab=h.lab, + profile=rp ) @@ -42,14 +58,16 @@ def populate_resource_profiles(apps, schema_editor): HostProfile = apps.get_model('resource_inventory', 'HostProfile') ResourceProfile = apps.get_model('resource_inventory', 'ResourceProfile') for hp in HostProfile.objects.all(): - rp = ResourceProfile.objects.create(name=hp.name, description=hp.description) + 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() - rp.interfaceprofile.host = rp + hp.interfaceprofile.host = rp rp.storageprofile.host = rp rp.cpuprofile.host = rp rp.ramprofile.host = rp @@ -57,30 +75,17 @@ def populate_resource_profiles(apps, schema_editor): rp.storageprofile.save() rp.cpuprofile.save() rp.ramprofile.save() + """ class Migration(migrations.Migration): - """TODO: Creation of the following models. - - - Server - - ResourceTemplate - - ResourceProfile - - ResourceConfiguration (?) - - InterfaceConfiguration (?) - - And set the correct defaults for the following fields: - - Interface.profile - - OpnfvConfig.template (?) - - physicalnetwork.lab - - physicalnetwork.profile - """ dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), ('booking', '0007_remove_booking_config_bundle'), ('account', '0004_downtime'), - ('api', '0011_auto_20200218_1536'), - ('resource_inventory', '0012_auto_20200103_1850'), + ('api', '0013_manual_20200218_1536'), + ('resource_inventory', '0012_manual_20200218_1536'), ] operations = [ @@ -143,6 +148,36 @@ class Migration(migrations.Migration): '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', @@ -251,47 +286,6 @@ class Migration(migrations.Migration): name='order', field=models.IntegerField(default=-1), ), - migrations.AddField( - model_name='physicalnetwork', - name='bundle', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='resource_inventory.ResourceBundle'), - ), - migrations.AddField( - model_name='physicalnetwork', - name='interfaces', - field=models.ManyToManyField(to='resource_inventory.Interface'), - ), - migrations.AddField( - model_name='physicalnetwork', - name='lab', - field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='account.Lab'), - preserve_default=False, - ), - migrations.AddField( - model_name='physicalnetwork', - name='labid', - field=models.CharField(default='default_id', max_length=200, unique=True), - ), - migrations.AddField( - model_name='physicalnetwork', - name='model', - field=models.CharField(default='unknown', max_length=150), - ), - migrations.AddField( - model_name='physicalnetwork', - 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.AddField( - model_name='physicalnetwork', - name='vendor', - field=models.CharField(default='unknown', max_length=100), - ), - migrations.AddField( - model_name='physicalnetwork', - name='working', - field=models.BooleanField(default=True), - ), migrations.AlterField( model_name='cpuprofile', name='host', @@ -322,6 +316,7 @@ class Migration(migrations.Migration): 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', @@ -342,9 +337,6 @@ class Migration(migrations.Migration): migrations.DeleteModel( name='GenericResourceBundle', ), - migrations.DeleteModel( - name='Host', - ), migrations.DeleteModel( name='HostConfiguration', ), @@ -354,35 +346,8 @@ class Migration(migrations.Migration): migrations.DeleteModel( name='HostProfile', ), - 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.DeleteModel( + name='Host', ), migrations.AddField( model_name='resourceopnfvconfig', @@ -429,21 +394,11 @@ class Migration(migrations.Migration): 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, ), - migrations.AddField( - model_name='physicalnetwork', - name='config', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='resource_inventory.ResourceConfiguration'), - ), - migrations.AddField( - model_name='physicalnetwork', - name='profile', - field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='resource_inventory.ResourceProfile'), - preserve_default=False, - ), ] diff --git a/src/resource_inventory/models.py b/src/resource_inventory/models.py index eec009a..d11f71b 100644 --- a/src/resource_inventory/models.py +++ b/src/resource_inventory/models.py @@ -382,7 +382,7 @@ class Network(models.Model): return self.name -class PhysicalNetwork(Resource): +class PhysicalNetwork(models.Model): vlan_id = models.IntegerField() generic_network = models.ForeignKey(Network, on_delete=models.CASCADE) -- cgit 1.2.3-korg