1 ##############################################################################
2 # Copyright (c) 2018 Sawyer Bergeron, Parker Berberian, and others.
4 # All rights reserved. This program and the accompanying materials
5 # are made available under the terms of the Apache License, Version 2.0
6 # which accompanies this distribution, and is available at
7 # http://www.apache.org/licenses/LICENSE-2.0
8 ##############################################################################
11 from django.forms import formset_factory, modelformset_factory
13 from workflow.models import WorkflowStep
14 from workflow.forms import SoftwareConfigurationForm, HostSoftwareDefinitionForm
15 from workflow.booking_workflow import Resource_Select
16 from resource_inventory.models import *
19 #resource selection step is reused from Booking workflow
21 #TODO: change this: too hacky, just for presentation
23 class SWConf_Resource_Select(Resource_Select):
24 def __init__(self, *args, **kwargs):
25 super(SWConf_Resource_Select, self).__init__(*args, **kwargs)
26 self.repo_key = self.repo.SWCONF_SELECTED_GRB
27 self.confirm_key = "configuration"
29 def get_default_entry(self):
30 booking_grb = self.repo_get(self.repo.BOOKING_SELECTED_GRB)
33 created_grb = self.repo_get(self.repo.GRESOURCE_BUNDLE_MODELS, {}).get("bundle", None)
36 def post_render(self, request):
37 response = super(SWConf_Resource_Select, self).post_render(request)
38 models = self.repo_get(self.repo.CONFIG_MODELS, {})
39 bundle = models.get("bundle", ConfigBundle(owner=self.repo_get(self.repo.SESSION_USER)))
40 bundle.bundle = self.repo_get(self.repo_key) # super put grb here
41 models['bundle'] = bundle
42 self.repo_put(self.repo.CONFIG_MODELS, models)
45 class Define_Software(WorkflowStep):
46 template = 'config_bundle/steps/define_software.html'
47 title = "Pick Software"
48 description = "Choose the opnfv and image of your machines"
49 short_title = "host config"
51 def create_hostformset(self, hostlist):
53 host_configs = self.repo_get(self.repo.CONFIG_MODELS, {}).get("host_configs", False)
55 for config in host_configs:
56 host_initial = {'host_id': config.host.id, 'host_name': config.host.resource.name}
57 host_initial['role'] = config.opnfvRole
58 host_initial['image'] = config.image
59 hosts_initial.append(host_initial)
63 host_initial = {'host_id': host.id, 'host_name': host.resource.name}
65 hosts_initial.append(host_initial)
67 HostFormset = formset_factory(HostSoftwareDefinitionForm, extra=0)
68 host_formset = HostFormset(initial=hosts_initial)
71 user = self.repo_get(self.repo.SESSION_USER)
73 for host_data in hosts_initial:
74 host = GenericHost.objects.get(pk=host_data['host_id'])
75 excluded_images = Image.objects.exclude(owner=user).exclude(public=True)
76 excluded_images = excluded_images | Image.objects.exclude(host_type=host.profile)
77 lab = self.repo_get(self.repo.SWCONF_SELECTED_GRB).lab
78 excluded_images = excluded_images | Image.objects.exclude(from_lab=lab)
79 filter_data["id_form-" + str(i) + "-image"] = []
80 for image in excluded_images:
81 filter_data["id_form-" + str(i) + "-image"].append(image.name)
84 return host_formset, filter_data
86 def get_host_list(self, grb=None):
88 grb = self.repo_get(self.repo.SWCONF_SELECTED_GRB, False)
92 return GenericHost.objects.filter(resource__bundle=grb)
93 generic_hosts = self.repo_get(self.repo.GRESOURCE_BUNDLE_MODELS, {}).get("hosts", [])
96 def get_context(self):
97 context = super(Define_Software, self).get_context()
99 grb = self.repo_get(self.repo.SWCONF_SELECTED_GRB, False)
103 formset, filter_data = self.create_hostformset(self.get_host_list(grb))
104 context["formset"] = formset
105 context["filter_data"] = filter_data
107 context["error"] = "Please select a resource first"
108 self.metastep.set_invalid("Step requires information that is not yet provided by previous step")
112 def post_render(self, request):
113 models = self.repo_get(self.repo.CONFIG_MODELS, {})
114 if "bundle" not in models:
115 models['bundle'] = ConfigBundle(owner=self.repo_get(self.repo.SESSION_USER))
117 confirm = self.repo_get(self.repo.CONFIRMATION, {})
119 HostFormset = formset_factory(HostSoftwareDefinitionForm, extra=0)
120 formset = HostFormset(request.POST)
121 hosts = self.get_host_list()
122 if formset.is_valid():
123 models['host_configs'] = []
129 image = form.cleaned_data['image']
130 # checks image compatability
131 grb = self.repo_get(self.repo.SWCONF_SELECTED_GRB)
136 owner = self.repo_get(self.repo.SESSION_USER)
137 q = Image.objects.filter(owner=owner) | Image.objects.filter(public=True)
138 q.filter(host_type=host.profile)
139 q.filter(from_lab=lab)
140 q.get(id=image.id) # will throw exception if image is not in q
142 self.metastep.set_invalid("Image " + image.name + " is not compatible with host " + host.resource.name)
143 role = form.cleaned_data['role']
144 bundle = models['bundle']
145 hostConfig = HostConfiguration(
151 models['host_configs'].append(hostConfig)
152 confirm_host = {"name": host.resource.name, "image": image.name, "role": role.name}
153 confirm_hosts.append(confirm_host)
155 self.repo_put(self.repo.CONFIG_MODELS, models)
156 if "configuration" not in confirm:
157 confirm['configuration'] = {}
158 confirm['configuration']['hosts'] = confirm_hosts
159 self.repo_put(self.repo.CONFIRMATION, confirm)
160 self.metastep.set_valid("Completed")
162 self.metastep.set_invalid("Please complete all fields")
164 return self.render(request)
166 class Config_Software(WorkflowStep):
167 template = 'config_bundle/steps/config_software.html'
168 form = SoftwareConfigurationForm
169 context = {'workspace_form':form}
171 description = "Give your software config a name, description, and other stuff"
172 short_title = "config info"
174 def get_context(self):
175 context = super(Config_Software, self).get_context()
178 models = self.repo_get(self.repo.CONFIG_MODELS, {})
179 bundle = models.get("bundle", False)
181 initial['name'] = bundle.name
182 initial['description'] = bundle.description
183 opnfv = models.get("opnfv", False)
185 initial['installer'] = opnfv.installer
186 initial['scenario'] = opnfv.scenario
188 initial['opnfv'] = False
190 for installer in Installer.objects.all():
191 supported[str(installer)] = []
192 for scenario in installer.sup_scenarios.all():
193 supported[str(installer)].append(str(scenario))
195 context["form"] = SoftwareConfigurationForm(initial=initial)
196 context['supported'] = supported
200 def post_render(self, request):
202 models = self.repo_get(self.repo.CONFIG_MODELS, {})
203 if "bundle" not in models:
204 models['bundle'] = ConfigBundle(owner=self.repo_get(self.repo.SESSION_USER))
207 confirm = self.repo_get(self.repo.CONFIRMATION, {})
208 if "configuration" not in confirm:
209 confirm['configuration'] = {}
211 form = self.form(request.POST)
213 models['bundle'].name = form.cleaned_data['name']
214 models['bundle'].description = form.cleaned_data['description']
215 if form.cleaned_data['opnfv']:
216 installer = form.cleaned_data['installer']
217 scenario = form.cleaned_data['scenario']
219 bundle=models['bundle'],
223 models['opnfv'] = opnfv
224 confirm['configuration']['installer'] = form.cleaned_data['installer'].name
225 confirm['configuration']['scenario'] = form.cleaned_data['scenario'].name
227 confirm['configuration']['name'] = form.cleaned_data['name']
228 confirm['configuration']['description'] = form.cleaned_data['description']
229 self.metastep.set_valid("Complete")
231 self.metastep.set_invalid("Please correct the errors shown below")
233 self.repo_put(self.repo.CONFIG_MODELS, models)
234 self.repo_put(self.repo.CONFIRMATION, confirm)
236 except Exception as e:
238 return self.render(request)