summaryrefslogtreecommitdiffstats
path: root/dashboard/src/workflow/sw_bundle_workflow.py
diff options
context:
space:
mode:
Diffstat (limited to 'dashboard/src/workflow/sw_bundle_workflow.py')
-rw-r--r--dashboard/src/workflow/sw_bundle_workflow.py198
1 files changed, 198 insertions, 0 deletions
diff --git a/dashboard/src/workflow/sw_bundle_workflow.py b/dashboard/src/workflow/sw_bundle_workflow.py
new file mode 100644
index 0000000..0c558fc
--- /dev/null
+++ b/dashboard/src/workflow/sw_bundle_workflow.py
@@ -0,0 +1,198 @@
+##############################################################################
+# Copyright (c) 2018 Sawyer Bergeron, Parker Berberian, and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+
+from django.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
+
+
+class SWConf_Resource_Select(Abstract_Resource_Select):
+ workflow_type = "configuration"
+
+
+class Define_Software(WorkflowStep):
+ template = 'config_bundle/steps/define_software.html'
+ title = "Pick Software"
+ description = "Choose the opnfv and image of your machines"
+ short_title = "host config"
+
+ 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:
+ 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:
+ hosts_initial.append({
+ 'host_id': host.id,
+ 'host_name': host.resource.name
+ })
+
+ HostFormset = formset_factory(HostSoftwareDefinitionForm, extra=0)
+ filter_data = self.build_filter_data(hosts_initial)
+
+ 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
+
+ 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.SELECTED_GRESOURCE_BUNDLE, False)
+ if not grb:
+ return []
+ if grb.id:
+ return GenericHost.objects.filter(resource__bundle=grb)
+ generic_hosts = self.repo_get(self.repo.GRESOURCE_BUNDLE_MODELS, {}).get("hosts", [])
+ return generic_hosts
+
+ def get_context(self):
+ context = super(Define_Software, self).get_context()
+
+ grb = self.repo_get(self.repo.SELECTED_GRESOURCE_BUNDLE, False)
+
+ if grb:
+ context["grb"] = grb
+ formset = self.create_hostformset(self.get_host_list(grb))
+ context["formset"] = formset
+ context['headnode'] = self.repo_get(self.repo.CONFIG_MODELS, {}).get("headnode_index", 1)
+ else:
+ context["error"] = "Please select a resource first"
+ self.set_invalid("Step requires information that is not yet provided by previous step")
+
+ return context
+
+ def post_render(self, request):
+ 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, {})
+
+ 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'] = []
+ confirm_hosts = []
+ for i, form in enumerate(formset):
+ host = hosts[i]
+ image = form.cleaned_data['image']
+ headnode = form.cleaned_data['headnode']
+ if headnode:
+ has_headnode = True
+ bundle = models['bundle']
+ hostConfig = HostConfiguration(
+ host=host,
+ image=image,
+ bundle=bundle,
+ is_head_node=headnode
+ )
+ models['host_configs'].append(hostConfig)
+ 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.set_valid("Completed")
+ else:
+ self.set_invalid("Please complete all fields")
+
+ return self.render(request)
+
+
+class Config_Software(WorkflowStep):
+ template = 'config_bundle/steps/config_software.html'
+ title = "Other Info"
+ description = "Give your software config a name, description, and other stuff"
+ short_title = "config info"
+
+ def get_context(self):
+ context = super(Config_Software, self).get_context()
+
+ initial = {}
+ models = self.repo_get(self.repo.CONFIG_MODELS, {})
+ bundle = models.get("bundle", False)
+ if bundle:
+ initial['name'] = bundle.name
+ initial['description'] = bundle.description
+ context["form"] = BasicMetaForm(initial=initial)
+ return context
+
+ def post_render(self, request):
+ 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'] = {}
+
+ form = BasicMetaForm(request.POST)
+ if form.is_valid():
+ models['bundle'].name = form.cleaned_data['name']
+ models['bundle'].description = form.cleaned_data['description']
+
+ 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)
+
+ return self.render(request)