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 account.models import UserProfile
19 from booking.models import Booking
20 from workflow.models import WorkflowStep
21 from workflow.forms import ResourceSelectorForm, SWConfigSelectorForm, BookingMetaForm, ConfirmationForm
22 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(self.repo.GRESOURCE_BUNDLE_MODELS,{}).get("bundle", GenericResourceBundle())
94 confirm = self.repo_get(self.repo.CONFIRMATION)
95 if self.confirm_key not in confirm:
96 confirm[self.confirm_key] = {}
97 confirm[self.confirm_key]["resource name"] = gresource_bundle.name
98 self.repo_put(self.repo.CONFIRMATION, confirm)
99 messages.add_message(request, messages.SUCCESS, 'Form Validated Successfully', fail_silently=True)
100 self.metastep.set_valid("Step Completed")
101 return render(request, self.template, context)
103 messages.add_message(request, messages.ERROR, "Form Didn't Validate", fail_silently=True)
104 self.metastep.set_invalid("Please complete the fields highlighted in red to continue")
105 return render(request, self.template, context)
107 class Booking_Resource_Select(Resource_Select):
109 def __init__(self, *args, **kwargs):
110 super(Booking_Resource_Select, self).__init__(*args, **kwargs)
111 self.repo_key = self.repo.BOOKING_SELECTED_GRB
112 self.confirm_key = "booking"
114 def get_default_entry(self):
115 default = self.repo_get(self.repo.GRESOURCE_BUNDLE_MODELS, {}).get("bundle")
116 mine = self.repo_get(self.repo_key)
120 config_bundle = self.repo_get(self.repo.BOOKING_MODELS)['booking'].config_bundle
122 return default # select created grb, even if preselected config bundle
123 return config_bundle.bundle
128 def get_context(self):
129 context = super(Booking_Resource_Select, self).get_context()
132 def post_render(self, request):
133 response = super(Booking_Resource_Select, self).post_render(request)
134 models = self.repo_get(self.repo.BOOKING_MODELS, {})
135 if "booking" not in models:
136 models['booking'] = Booking()
137 booking = models['booking']
138 resource = self.repo_get(self.repo_key, False)
141 booking.resource.template = resource
143 booking.resource = ResourceBundle(template=resource)
144 models['booking'] = booking
145 self.repo_put(self.repo.BOOKING_MODELS, models)
148 class SWConfig_Select(WorkflowStep):
149 template = 'booking/steps/swconfig_select.html'
150 title = "Select Software Configuration"
151 description = "Choose the software and related configurations you want to have used for your deployment"
152 short_title = "pod config"
154 def post_render(self, request):
155 form = SWConfigSelectorForm(request.POST)
158 bundle_json = form.cleaned_data['software_bundle']
159 bundle_json = bundle_json[2:-2] # Stupid django string bug
161 self.metastep.set_invalid("Please select a valid config")
162 return self.render(request)
163 bundle_json = json.loads(bundle_json)
166 id = int(bundle_json[0]['id'])
167 bundle = ConfigBundle.objects.get(id=id)
169 bundle = self.repo_get(self.repo.CONFIG_MODELS).get("bundle")
171 models = self.repo_get(self.repo.BOOKING_MODELS, {})
172 if "booking" not in models:
173 models['booking'] = Booking()
174 models['booking'].config_bundle = bundle
175 self.repo_put(self.repo.BOOKING_MODELS, models)
176 confirm = self.repo_get(self.repo.CONFIRMATION)
177 if "booking" not in confirm:
178 confirm['booking'] = {}
179 confirm['booking']["configuration name"] = bundle.name
180 self.repo_put(self.repo.CONFIRMATION, confirm)
181 self.metastep.set_valid("Step Completed")
182 messages.add_message(request, messages.SUCCESS, 'Form Validated Successfully', fail_silently=True)
184 self.metastep.set_invalid("Please select or create a valid config")
185 messages.add_message(request, messages.ERROR, "Form Didn't Validate", fail_silently=True)
187 return self.render(request)
190 def get_context(self):
191 context = super(SWConfig_Select, self).get_context()
195 created_bundle = self.repo_get(self.repo.CONFIG_MODELS, {}).get("bundle", False)
196 booking = self.repo_get(self.repo.BOOKING_MODELS, {}).get("booking", False)
198 chosen_bundle = booking.config_bundle
199 default.append(chosen_bundle.id)
203 default.append("repo bundle")
204 bundle = created_bundle
205 context['disabled'] = True
206 edit = self.repo_get(self.repo.EDIT, False)
207 grb = self.repo_get(self.repo.BOOKING_SELECTED_GRB)
208 context['form'] = SWConfigSelectorForm(chosen_software=default, bundle=bundle, edit=edit, resource=grb)
211 class Booking_Meta(WorkflowStep):
212 template = 'booking/steps/booking_meta.html'
214 description = "Tell us how long you want your booking, what it is for, and who else should have access to it"
215 short_title = "booking info"
217 def get_context(self):
218 context = super(Booking_Meta, self).get_context()
222 models = self.repo_get(self.repo.BOOKING_MODELS, {})
223 booking = models.get("booking")
225 initial['purpose'] = booking.purpose
226 initial['project'] = booking.project
227 initial['length'] = (booking.end - booking.start).days
228 info = self.repo_get(self.repo.BOOKING_INFO_FILE, False)
230 initial['info_file'] = info
231 users = models.get("collaborators", [])
233 default.append(user.id)
234 except Exception as e:
237 default_user = self.repo_get(self.repo.SESSION_USER)
238 if default_user is None:
242 default_user = default_user.username
244 context['form'] = BookingMetaForm(initial=initial, chosen_users=default, default_user=default_user)
247 def post_render(self, request):
248 form = BookingMetaForm(data=request.POST)
249 context = self.get_context()
251 forms = self.repo_get(self.repo.BOOKING_FORMS, {})
253 forms["meta_form"] = form
254 self.repo_put(self.repo.BOOKING_FORMS, forms)
257 models = self.repo_get(self.repo.BOOKING_MODELS, {})
258 if "booking" not in models:
259 models['booking'] = Booking()
260 models['collaborators'] = []
261 confirm = self.repo_get(self.repo.CONFIRMATION)
262 if "booking" not in confirm:
263 confirm['booking'] = {}
265 models['booking'].start = timezone.now()
266 models['booking'].end = timezone.now() + timedelta(days=int(form.cleaned_data['length']))
267 models['booking'].purpose = form.cleaned_data['purpose']
268 models['booking'].project = form.cleaned_data['project']
269 for key in ['length', 'project', 'purpose']:
270 confirm['booking'][key] = form.cleaned_data[key]
272 user_data = form.cleaned_data['users']
273 confirm['booking']['collaborators'] = []
274 user_data = user_data[2:-2] #fixes malformed string from querydict
276 form_users = json.loads(user_data)
277 for user_json in form_users:
278 user = User.objects.get(pk=user_json['id'])
279 models['collaborators'].append(user)
280 confirm['booking']['collaborators'].append(user.username)
282 info_file = form.cleaned_data.get("info_file", False)
284 self.repo_put(self.repo.BOOKING_INFO_FILE, info_file)
286 self.repo_put(self.repo.BOOKING_MODELS, models)
287 self.repo_put(self.repo.CONFIRMATION, confirm)
288 messages.add_message(request, messages.SUCCESS, 'Form Validated', fail_silently=True)
289 self.metastep.set_valid("Step Completed")
291 messages.add_message(request, messages.ERROR, "Form didn't validate", fail_silently=True)
292 self.metastep.set_invalid("Please complete the fields highlighted in red to continue")
293 context['form'] = form # TODO: store this form
294 return render(request, self.template, context)