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
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 Image, GenericHost, ConfigBundle, HostConfiguration, Installer, OPNFVConfig
19 # resource selection step is reused from Booking workflow
20 class SWConf_Resource_Select(Resource_Select):
21 def __init__(self, *args, **kwargs):
22 super(SWConf_Resource_Select, self).__init__(*args, **kwargs)
23 self.repo_key = self.repo.SELECTED_GRESOURCE_BUNDLE
24 self.confirm_key = "configuration"
26 def post_render(self, request):
27 response = super(SWConf_Resource_Select, self).post_render(request)
28 models = self.repo_get(self.repo.CONFIG_MODELS, {})
29 bundle = models.get("bundle", ConfigBundle(owner=self.repo_get(self.repo.SESSION_USER)))
30 bundle.bundle = self.repo_get(self.repo_key) # super put grb here
31 models['bundle'] = bundle
32 self.repo_put(self.repo.CONFIG_MODELS, models)
36 class Define_Software(WorkflowStep):
37 template = 'config_bundle/steps/define_software.html'
38 title = "Pick Software"
39 description = "Choose the opnfv and image of your machines"
40 short_title = "host config"
42 def create_hostformset(self, hostlist):
44 host_configs = self.repo_get(self.repo.CONFIG_MODELS, {}).get("host_configs", False)
46 for config in host_configs:
47 host_initial = {'host_id': config.host.id, 'host_name': config.host.resource.name}
48 host_initial['role'] = config.opnfvRole
49 host_initial['image'] = config.image
50 hosts_initial.append(host_initial)
54 host_initial = {'host_id': host.id, 'host_name': host.resource.name}
56 hosts_initial.append(host_initial)
58 HostFormset = formset_factory(HostSoftwareDefinitionForm, extra=0)
59 host_formset = HostFormset(initial=hosts_initial)
62 user = self.repo_get(self.repo.SESSION_USER)
64 for host_data in hosts_initial:
67 host = GenericHost.objects.get(pk=host_data['host_id'])
68 host_profile = host.profile
71 if host.resource.name == host_data['host_name']:
72 host_profile = host.profile
74 excluded_images = Image.objects.exclude(owner=user).exclude(public=True)
75 excluded_images = excluded_images | Image.objects.exclude(host_type=host.profile)
76 lab = self.repo_get(self.repo.SELECTED_GRESOURCE_BUNDLE).lab
77 excluded_images = excluded_images | Image.objects.exclude(from_lab=lab)
78 filter_data["id_form-" + str(i) + "-image"] = []
79 for image in excluded_images:
80 filter_data["id_form-" + str(i) + "-image"].append(image.name)
83 return host_formset, filter_data
85 def get_host_list(self, grb=None):
87 grb = self.repo_get(self.repo.SELECTED_GRESOURCE_BUNDLE, False)
91 return GenericHost.objects.filter(resource__bundle=grb)
92 generic_hosts = self.repo_get(self.repo.GRESOURCE_BUNDLE_MODELS, {}).get("hosts", [])
95 def get_context(self):
96 context = super(Define_Software, self).get_context()
98 grb = self.repo_get(self.repo.SELECTED_GRESOURCE_BUNDLE, False)
102 formset, filter_data = self.create_hostformset(self.get_host_list(grb))
103 context["formset"] = formset
104 context["filter_data"] = filter_data
106 context["error"] = "Please select a resource first"
107 self.metastep.set_invalid("Step requires information that is not yet provided by previous step")
111 def post_render(self, request):
112 models = self.repo_get(self.repo.CONFIG_MODELS, {})
113 if "bundle" not in models:
114 models['bundle'] = ConfigBundle(owner=self.repo_get(self.repo.SESSION_USER))
116 confirm = self.repo_get(self.repo.CONFIRMATION, {})
118 HostFormset = formset_factory(HostSoftwareDefinitionForm, extra=0)
119 formset = HostFormset(request.POST)
120 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.SELECTED_GRESOURCE_BUNDLE)
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 if "jumphost" in role.name.lower():
146 bundle = models['bundle']
147 hostConfig = HostConfiguration(
153 models['host_configs'].append(hostConfig)
154 confirm_host = {"name": host.resource.name, "image": image.name, "role": role.name}
155 confirm_hosts.append(confirm_host)
158 self.metastep.set_invalid('Must have at least one "Jumphost" per POD')
159 return self.render(request)
161 self.repo_put(self.repo.CONFIG_MODELS, models)
162 if "configuration" not in confirm:
163 confirm['configuration'] = {}
164 confirm['configuration']['hosts'] = confirm_hosts
165 self.repo_put(self.repo.CONFIRMATION, confirm)
166 self.metastep.set_valid("Completed")
168 self.metastep.set_invalid("Please complete all fields")
170 return self.render(request)
173 class Config_Software(WorkflowStep):
174 template = 'config_bundle/steps/config_software.html'
175 form = SoftwareConfigurationForm
176 context = {'workspace_form': form}
178 description = "Give your software config a name, description, and other stuff"
179 short_title = "config info"
181 def get_context(self):
182 context = super(Config_Software, self).get_context()
185 models = self.repo_get(self.repo.CONFIG_MODELS, {})
186 bundle = models.get("bundle", False)
188 initial['name'] = bundle.name
189 initial['description'] = bundle.description
190 opnfv = models.get("opnfv", False)
192 initial['installer'] = opnfv.installer
193 initial['scenario'] = opnfv.scenario
195 initial['opnfv'] = False
197 for installer in Installer.objects.all():
198 supported[str(installer)] = []
199 for scenario in installer.sup_scenarios.all():
200 supported[str(installer)].append(str(scenario))
202 context["form"] = SoftwareConfigurationForm(initial=initial)
203 context['supported'] = supported
207 def post_render(self, request):
209 models = self.repo_get(self.repo.CONFIG_MODELS, {})
210 if "bundle" not in models:
211 models['bundle'] = ConfigBundle(owner=self.repo_get(self.repo.SESSION_USER))
213 confirm = self.repo_get(self.repo.CONFIRMATION, {})
214 if "configuration" not in confirm:
215 confirm['configuration'] = {}
217 form = self.form(request.POST)
219 models['bundle'].name = form.cleaned_data['name']
220 models['bundle'].description = form.cleaned_data['description']
221 if form.cleaned_data['opnfv']:
222 installer = form.cleaned_data['installer']
223 scenario = form.cleaned_data['scenario']
225 bundle=models['bundle'],
229 models['opnfv'] = opnfv
230 confirm['configuration']['installer'] = form.cleaned_data['installer'].name
231 confirm['configuration']['scenario'] = form.cleaned_data['scenario'].name
233 confirm['configuration']['name'] = form.cleaned_data['name']
234 confirm['configuration']['description'] = form.cleaned_data['description']
235 self.metastep.set_valid("Complete")
237 self.metastep.set_invalid("Please correct the errors shown below")
239 self.repo_put(self.repo.CONFIG_MODELS, models)
240 self.repo_put(self.repo.CONFIRMATION, confirm)
244 return self.render(request)