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 ##############################################################################
10 from django.contrib import messages
11 from django.shortcuts import render
12 from django.contrib.auth.models import User
13 from django.utils import timezone
16 from datetime import timedelta
18 from booking.models import Booking
19 from workflow.models import WorkflowStep
20 from workflow.forms import ResourceSelectorForm, SWConfigSelectorForm, BookingMetaForm
21 from resource_inventory.models import GenericResourceBundle, ResourceBundle, ConfigBundle
24 class Resource_Select(WorkflowStep):
25 template = 'booking/steps/resource_select.html'
26 title = "Select Resource"
27 description = "Select a resource template to use for your deployment"
28 short_title = "pod select"
30 def __init__(self, *args, **kwargs):
31 super(Resource_Select, self).__init__(*args, **kwargs)
32 self.repo_key = self.repo.SELECTED_GRESOURCE_BUNDLE
33 self.repo_check_key = False
34 self.confirm_key = "booking"
36 def get_default_entry(self):
39 def get_context(self):
40 context = super(Resource_Select, self).get_context()
43 default_bundle = self.get_default_entry()
45 context['disabled'] = True
46 chosen_bundle = default_bundle
48 default.append(chosen_bundle.id)
50 default.append("repo bundle")
52 chosen_bundle = self.repo_get(self.repo_key, False)
55 default.append(chosen_bundle.id)
57 default.append("repo bundle")
59 bundle = default_bundle
61 bundle = chosen_bundle
62 edit = self.repo_get(self.repo.EDIT, False)
63 user = self.repo_get(self.repo.SESSION_USER)
64 context['form'] = ResourceSelectorForm(
66 chosen_resource=default,
72 def post_render(self, request):
73 form = ResourceSelectorForm(request.POST)
74 context = self.get_context()
76 data = form.cleaned_data['generic_resource_bundle']
79 self.metastep.set_invalid("Please select a valid bundle")
80 return render(request, self.template, context)
81 selected_bundle = json.loads(data)
82 selected_id = selected_bundle[0]['id']
83 gresource_bundle = None
85 selected_id = int(selected_id)
86 gresource_bundle = GenericResourceBundle.objects.get(id=selected_id)
88 # we want the bundle in the repo
89 gresource_bundle = self.repo_get(
90 self.repo.GRESOURCE_BUNDLE_MODELS,
92 ).get("bundle", GenericResourceBundle())
97 confirm = self.repo_get(self.repo.CONFIRMATION)
98 if self.confirm_key not in confirm:
99 confirm[self.confirm_key] = {}
100 confirm[self.confirm_key]["resource name"] = gresource_bundle.name
101 self.repo_put(self.repo.CONFIRMATION, confirm)
102 messages.add_message(request, messages.SUCCESS, 'Form Validated Successfully', fail_silently=True)
103 self.metastep.set_valid("Step Completed")
104 return render(request, self.template, context)
106 messages.add_message(request, messages.ERROR, "Form Didn't Validate", fail_silently=True)
107 self.metastep.set_invalid("Please complete the fields highlighted in red to continue")
108 return render(request, self.template, context)
111 class Booking_Resource_Select(Resource_Select):
113 def __init__(self, *args, **kwargs):
114 super(Booking_Resource_Select, self).__init__(*args, **kwargs)
115 self.repo_key = self.repo.BOOKING_SELECTED_GRB
116 self.confirm_key = "booking"
118 def get_default_entry(self):
119 default = self.repo_get(self.repo.GRESOURCE_BUNDLE_MODELS, {}).get("bundle")
120 mine = self.repo_get(self.repo_key)
124 config_bundle = self.repo_get(self.repo.BOOKING_MODELS)['booking'].config_bundle
126 return default # select created grb, even if preselected config bundle
127 return config_bundle.bundle
132 def get_context(self):
133 context = super(Booking_Resource_Select, self).get_context()
136 def post_render(self, request):
137 response = super(Booking_Resource_Select, self).post_render(request)
138 models = self.repo_get(self.repo.BOOKING_MODELS, {})
139 if "booking" not in models:
140 models['booking'] = Booking()
141 booking = models['booking']
142 resource = self.repo_get(self.repo_key, False)
145 booking.resource.template = resource
147 booking.resource = ResourceBundle(template=resource)
148 models['booking'] = booking
149 self.repo_put(self.repo.BOOKING_MODELS, models)
153 class SWConfig_Select(WorkflowStep):
154 template = 'booking/steps/swconfig_select.html'
155 title = "Select Software Configuration"
156 description = "Choose the software and related configurations you want to have used for your deployment"
157 short_title = "pod config"
159 def post_render(self, request):
160 form = SWConfigSelectorForm(request.POST)
163 bundle_json = form.cleaned_data['software_bundle']
164 bundle_json = bundle_json[2:-2] # Stupid django string bug
166 self.metastep.set_invalid("Please select a valid config")
167 return self.render(request)
168 bundle_json = json.loads(bundle_json)
171 id = int(bundle_json[0]['id'])
172 bundle = ConfigBundle.objects.get(id=id)
174 bundle = self.repo_get(self.repo.CONFIG_MODELS).get("bundle")
176 models = self.repo_get(self.repo.BOOKING_MODELS, {})
177 if "booking" not in models:
178 models['booking'] = Booking()
179 models['booking'].config_bundle = bundle
180 self.repo_put(self.repo.BOOKING_MODELS, models)
181 confirm = self.repo_get(self.repo.CONFIRMATION)
182 if "booking" not in confirm:
183 confirm['booking'] = {}
184 confirm['booking']["configuration name"] = bundle.name
185 self.repo_put(self.repo.CONFIRMATION, confirm)
186 self.metastep.set_valid("Step Completed")
187 messages.add_message(request, messages.SUCCESS, 'Form Validated Successfully', fail_silently=True)
189 self.metastep.set_invalid("Please select or create a valid config")
190 messages.add_message(request, messages.ERROR, "Form Didn't Validate", fail_silently=True)
192 return self.render(request)
194 def get_context(self):
195 context = super(SWConfig_Select, self).get_context()
199 created_bundle = self.repo_get(self.repo.CONFIG_MODELS, {}).get("bundle", False)
200 booking = self.repo_get(self.repo.BOOKING_MODELS, {}).get("booking", False)
202 chosen_bundle = booking.config_bundle
203 default.append(chosen_bundle.id)
204 bundle = chosen_bundle
207 default.append("repo bundle")
208 bundle = created_bundle
209 context['disabled'] = True
210 edit = self.repo_get(self.repo.EDIT, False)
211 grb = self.repo_get(self.repo.BOOKING_SELECTED_GRB)
212 context['form'] = SWConfigSelectorForm(chosen_software=default, bundle=bundle, edit=edit, resource=grb)
216 class Booking_Meta(WorkflowStep):
217 template = 'booking/steps/booking_meta.html'
219 description = "Tell us how long you want your booking, what it is for, and who else should have access to it"
220 short_title = "booking info"
222 def get_context(self):
223 context = super(Booking_Meta, self).get_context()
227 models = self.repo_get(self.repo.BOOKING_MODELS, {})
228 booking = models.get("booking")
230 initial['purpose'] = booking.purpose
231 initial['project'] = booking.project
232 initial['length'] = (booking.end - booking.start).days
233 info = self.repo_get(self.repo.BOOKING_INFO_FILE, False)
235 initial['info_file'] = info
236 users = models.get("collaborators", [])
238 default.append(user.id)
242 default_user = self.repo_get(self.repo.SESSION_USER)
243 if default_user is None:
247 default_user = default_user.username
249 context['form'] = BookingMetaForm(initial=initial, chosen_users=default, default_user=default_user)
252 def post_render(self, request):
253 form = BookingMetaForm(data=request.POST)
254 context = self.get_context()
256 forms = self.repo_get(self.repo.BOOKING_FORMS, {})
258 forms["meta_form"] = form
259 self.repo_put(self.repo.BOOKING_FORMS, forms)
262 models = self.repo_get(self.repo.BOOKING_MODELS, {})
263 if "booking" not in models:
264 models['booking'] = Booking()
265 models['collaborators'] = []
266 confirm = self.repo_get(self.repo.CONFIRMATION)
267 if "booking" not in confirm:
268 confirm['booking'] = {}
270 models['booking'].start = timezone.now()
271 models['booking'].end = timezone.now() + timedelta(days=int(form.cleaned_data['length']))
272 models['booking'].purpose = form.cleaned_data['purpose']
273 models['booking'].project = form.cleaned_data['project']
274 for key in ['length', 'project', 'purpose']:
275 confirm['booking'][key] = form.cleaned_data[key]
277 user_data = form.cleaned_data['users']
278 confirm['booking']['collaborators'] = []
279 user_data = user_data[2:-2] # fixes malformed string from querydict
281 form_users = json.loads(user_data)
282 for user_json in form_users:
283 user = User.objects.get(pk=user_json['id'])
284 models['collaborators'].append(user)
285 confirm['booking']['collaborators'].append(user.username)
287 info_file = form.cleaned_data.get("info_file", False)
289 self.repo_put(self.repo.BOOKING_INFO_FILE, info_file)
291 self.repo_put(self.repo.BOOKING_MODELS, models)
292 self.repo_put(self.repo.CONFIRMATION, confirm)
293 messages.add_message(request, messages.SUCCESS, 'Form Validated', fail_silently=True)
294 self.metastep.set_valid("Step Completed")
296 messages.add_message(request, messages.ERROR, "Form didn't validate", fail_silently=True)
297 self.metastep.set_invalid("Please complete the fields highlighted in red to continue")
298 context['form'] = form # TODO: store this form
299 return render(request, self.template, context)