diff options
Diffstat (limited to 'dashboard/src/workflow/sw_bundle_workflow.py')
-rw-r--r-- | dashboard/src/workflow/sw_bundle_workflow.py | 224 |
1 files changed, 89 insertions, 135 deletions
diff --git a/dashboard/src/workflow/sw_bundle_workflow.py b/dashboard/src/workflow/sw_bundle_workflow.py index 26ade22..0c558fc 100644 --- a/dashboard/src/workflow/sw_bundle_workflow.py +++ b/dashboard/src/workflow/sw_bundle_workflow.py @@ -11,33 +11,13 @@ from django.forms import formset_factory from workflow.models import WorkflowStep -from workflow.forms import SoftwareConfigurationForm, HostSoftwareDefinitionForm -from workflow.booking_workflow import Resource_Select -from resource_inventory.models import Image, GenericHost, ConfigBundle, HostConfiguration, Installer, OPNFVConfig +from workflow.forms import BasicMetaForm, HostSoftwareDefinitionForm +from workflow.booking_workflow import Abstract_Resource_Select +from resource_inventory.models import Image, GenericHost, ConfigBundle, HostConfiguration -# resource selection step is reused from Booking workflow -class SWConf_Resource_Select(Resource_Select): - def __init__(self, *args, **kwargs): - super(SWConf_Resource_Select, self).__init__(*args, **kwargs) - self.repo_key = self.repo.SWCONF_SELECTED_GRB - self.confirm_key = "configuration" - - def get_default_entry(self): - booking_grb = self.repo_get(self.repo.BOOKING_SELECTED_GRB) - if booking_grb: - return booking_grb - created_grb = self.repo_get(self.repo.GRESOURCE_BUNDLE_MODELS, {}).get("bundle", None) - return created_grb - - def post_render(self, request): - response = super(SWConf_Resource_Select, self).post_render(request) - models = self.repo_get(self.repo.CONFIG_MODELS, {}) - bundle = models.get("bundle", ConfigBundle(owner=self.repo_get(self.repo.SESSION_USER))) - bundle.bundle = self.repo_get(self.repo_key) # super put grb here - models['bundle'] = bundle - self.repo_put(self.repo.CONFIG_MODELS, models) - return response +class SWConf_Resource_Select(Abstract_Resource_Select): + workflow_type = "configuration" class Define_Software(WorkflowStep): @@ -46,52 +26,61 @@ class Define_Software(WorkflowStep): description = "Choose the opnfv and image of your machines" short_title = "host config" - def create_hostformset(self, hostlist): + def build_filter_data(self, hosts_data): + """ + returns a 2D array of images to exclude + based on the ordering of the passed + hosts_data + """ + filter_data = [] + 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']) + 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) + excluded_images = wrong_owner | wrong_host | wrong_lab + filter_data.append([]) + for image in excluded_images: + filter_data[i].append(image.pk) + return filter_data + + def create_hostformset(self, hostlist, data=None): hosts_initial = [] host_configs = self.repo_get(self.repo.CONFIG_MODELS, {}).get("host_configs", False) if host_configs: for config in host_configs: - host_initial = {'host_id': config.host.id, 'host_name': config.host.resource.name} - host_initial['role'] = config.opnfvRole - host_initial['image'] = config.image - hosts_initial.append(host_initial) - + hosts_initial.append({ + 'host_id': config.host.id, + 'host_name': config.host.resource.name, + 'headnode': config.is_head_node, + 'image': config.image + }) else: for host in hostlist: - host_initial = {'host_id': host.id, 'host_name': host.resource.name} - - hosts_initial.append(host_initial) + hosts_initial.append({ + 'host_id': host.id, + 'host_name': host.resource.name + }) HostFormset = formset_factory(HostSoftwareDefinitionForm, extra=0) - host_formset = HostFormset(initial=hosts_initial) + filter_data = self.build_filter_data(hosts_initial) - filter_data = {} - user = self.repo_get(self.repo.SESSION_USER) - i = 0 - for host_data in hosts_initial: - host_profile = None - try: - host = GenericHost.objects.get(pk=host_data['host_id']) - host_profile = host.profile - except Exception: - for host in hostlist: - if host.resource.name == host_data['host_name']: - host_profile = host.profile - break - excluded_images = Image.objects.exclude(owner=user).exclude(public=True) - excluded_images = excluded_images | Image.objects.exclude(host_type=host.profile) - lab = self.repo_get(self.repo.SWCONF_SELECTED_GRB).lab - excluded_images = excluded_images | Image.objects.exclude(from_lab=lab) - filter_data["id_form-" + str(i) + "-image"] = [] - for image in excluded_images: - filter_data["id_form-" + str(i) + "-image"].append(image.name) - i += 1 + class SpecialHostFormset(HostFormset): + def get_form_kwargs(self, index): + kwargs = super(SpecialHostFormset, self).get_form_kwargs(index) + if index is not None: + kwargs['imageQS'] = Image.objects.exclude(pk__in=filter_data[index]) + return kwargs - return host_formset, filter_data + if data: + return SpecialHostFormset(data, initial=hosts_initial) + return SpecialHostFormset(initial=hosts_initial) def get_host_list(self, grb=None): if grb is None: - grb = self.repo_get(self.repo.SWCONF_SELECTED_GRB, False) + grb = self.repo_get(self.repo.SELECTED_GRESOURCE_BUNDLE, False) if not grb: return [] if grb.id: @@ -102,16 +91,16 @@ class Define_Software(WorkflowStep): def get_context(self): context = super(Define_Software, self).get_context() - grb = self.repo_get(self.repo.SWCONF_SELECTED_GRB, False) + grb = self.repo_get(self.repo.SELECTED_GRESOURCE_BUNDLE, False) if grb: context["grb"] = grb - formset, filter_data = self.create_hostformset(self.get_host_list(grb)) + formset = self.create_hostformset(self.get_host_list(grb)) context["formset"] = formset - context["filter_data"] = filter_data + context['headnode'] = self.repo_get(self.repo.CONFIG_MODELS, {}).get("headnode_index", 1) else: context["error"] = "Please select a resource first" - self.metastep.set_invalid("Step requires information that is not yet provided by previous step") + self.set_invalid("Step requires information that is not yet provided by previous step") return context @@ -122,58 +111,51 @@ class Define_Software(WorkflowStep): confirm = self.repo_get(self.repo.CONFIRMATION, {}) - HostFormset = formset_factory(HostSoftwareDefinitionForm, extra=0) - formset = HostFormset(request.POST) hosts = self.get_host_list() + models['headnode_index'] = request.POST.get("headnode", 1) + formset = self.create_hostformset(hosts, data=request.POST) + has_headnode = False if formset.is_valid(): models['host_configs'] = [] - i = 0 confirm_hosts = [] - for form in formset: + for i, form in enumerate(formset): host = hosts[i] - i += 1 image = form.cleaned_data['image'] - # checks image compatability - grb = self.repo_get(self.repo.SWCONF_SELECTED_GRB) - lab = None - if grb: - lab = grb.lab - try: - owner = self.repo_get(self.repo.SESSION_USER) - q = Image.objects.filter(owner=owner) | Image.objects.filter(public=True) - q.filter(host_type=host.profile) - q.filter(from_lab=lab) - q.get(id=image.id) # will throw exception if image is not in q - except: - self.metastep.set_invalid("Image " + image.name + " is not compatible with host " + host.resource.name) - role = form.cleaned_data['role'] + headnode = form.cleaned_data['headnode'] + if headnode: + has_headnode = True bundle = models['bundle'] hostConfig = HostConfiguration( host=host, image=image, bundle=bundle, - opnfvRole=role + is_head_node=headnode ) models['host_configs'].append(hostConfig) - confirm_host = {"name": host.resource.name, "image": image.name, "role": role.name} - confirm_hosts.append(confirm_host) + confirm_hosts.append({ + "name": host.resource.name, + "image": image.name, + "headnode": headnode + }) + + if not has_headnode: + self.set_invalid('Must have one "Headnode" per POD') + return self.render(request) self.repo_put(self.repo.CONFIG_MODELS, models) if "configuration" not in confirm: confirm['configuration'] = {} confirm['configuration']['hosts'] = confirm_hosts self.repo_put(self.repo.CONFIRMATION, confirm) - self.metastep.set_valid("Completed") + self.set_valid("Completed") else: - self.metastep.set_invalid("Please complete all fields") + self.set_invalid("Please complete all fields") return self.render(request) class Config_Software(WorkflowStep): template = 'config_bundle/steps/config_software.html' - form = SoftwareConfigurationForm - context = {'workspace_form': form} title = "Other Info" description = "Give your software config a name, description, and other stuff" short_title = "config info" @@ -187,58 +169,30 @@ class Config_Software(WorkflowStep): if bundle: initial['name'] = bundle.name initial['description'] = bundle.description - opnfv = models.get("opnfv", False) - if opnfv: - initial['installer'] = opnfv.installer - initial['scenario'] = opnfv.scenario - else: - initial['opnfv'] = False - supported = {} - for installer in Installer.objects.all(): - supported[str(installer)] = [] - for scenario in installer.sup_scenarios.all(): - supported[str(installer)].append(str(scenario)) - - context["form"] = SoftwareConfigurationForm(initial=initial) - context['supported'] = supported - + context["form"] = BasicMetaForm(initial=initial) return context def post_render(self, request): - try: - 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 = self.repo_get(self.repo.CONFIG_MODELS, {}) + if "bundle" not in models: + models['bundle'] = ConfigBundle(owner=self.repo_get(self.repo.SESSION_USER)) - confirm = self.repo_get(self.repo.CONFIRMATION, {}) - if "configuration" not in confirm: - confirm['configuration'] = {} + confirm = self.repo_get(self.repo.CONFIRMATION, {}) + if "configuration" not in confirm: + confirm['configuration'] = {} - form = self.form(request.POST) - if form.is_valid(): - models['bundle'].name = form.cleaned_data['name'] - models['bundle'].description = form.cleaned_data['description'] - if form.cleaned_data['opnfv']: - installer = form.cleaned_data['installer'] - scenario = form.cleaned_data['scenario'] - opnfv = OPNFVConfig( - bundle=models['bundle'], - installer=installer, - scenario=scenario - ) - models['opnfv'] = opnfv - confirm['configuration']['installer'] = form.cleaned_data['installer'].name - confirm['configuration']['scenario'] = form.cleaned_data['scenario'].name - - confirm['configuration']['name'] = form.cleaned_data['name'] - confirm['configuration']['description'] = form.cleaned_data['description'] - self.metastep.set_valid("Complete") - else: - self.metastep.set_invalid("Please correct the errors shown below") + form = BasicMetaForm(request.POST) + if form.is_valid(): + models['bundle'].name = form.cleaned_data['name'] + models['bundle'].description = form.cleaned_data['description'] - self.repo_put(self.repo.CONFIG_MODELS, models) - self.repo_put(self.repo.CONFIRMATION, confirm) + confirm['configuration']['name'] = form.cleaned_data['name'] + confirm['configuration']['description'] = form.cleaned_data['description'] + self.set_valid("Complete") + else: + self.set_invalid("Please correct the errors shown below") + + self.repo_put(self.repo.CONFIG_MODELS, models) + self.repo_put(self.repo.CONFIRMATION, confirm) - except Exception: - pass return self.render(request) |