summaryrefslogtreecommitdiffstats
path: root/dashboard/src/booking/views.py
diff options
context:
space:
mode:
Diffstat (limited to 'dashboard/src/booking/views.py')
-rw-r--r--dashboard/src/booking/views.py283
1 files changed, 138 insertions, 145 deletions
diff --git a/dashboard/src/booking/views.py b/dashboard/src/booking/views.py
index 7e35af2..bad7dc9 100644
--- a/dashboard/src/booking/views.py
+++ b/dashboard/src/booking/views.py
@@ -1,5 +1,6 @@
##############################################################################
# Copyright (c) 2016 Max Breitenfeldt and others.
+# Copyright (c) 2018 Parker Berberian, Sawyer Bergeron, and others.
#
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Apache License, Version 2.0
@@ -7,164 +8,74 @@
# http://www.apache.org/licenses/LICENSE-2.0
##############################################################################
-from django.conf import settings
from django.contrib import messages
-from django.contrib.auth.mixins import LoginRequiredMixin
-from django.http import JsonResponse
from django.shortcuts import get_object_or_404
-from django.urls import reverse
+from django.http import JsonResponse, HttpResponse
from django.utils import timezone
from django.views import View
-from django.views.generic import FormView
from django.views.generic import TemplateView
-from jira import JIRAError
-from django.shortcuts import redirect
+from django.shortcuts import redirect, render
+from django.db.models import Q
+from django.urls import reverse
-from account.jira_util import get_jira
-from booking.forms import BookingForm, BookingEditForm
+from resource_inventory.models import ResourceBundle, HostProfile, Image, Host
+from resource_inventory.resource_manager import ResourceManager
+from account.models import Lab
from booking.models import Booking
-from dashboard.models import Resource
-
-def create_jira_ticket(user, booking):
- jira = get_jira(user)
- issue_dict = {
- 'project': 'PHAROS',
- 'summary': str(booking.resource) + ': Access Request',
- 'description': booking.purpose,
- 'issuetype': {'name': 'Task'},
- 'components': [{'name': 'POD Access Request'}],
- 'assignee': {'name': booking.resource.owner.username}
- }
- issue = jira.create_issue(fields=issue_dict)
- jira.add_attachment(issue, user.userprofile.pgp_public_key)
- jira.add_attachment(issue, user.userprofile.ssh_public_key)
- booking.jira_issue_id = issue.id
- booking.save()
+from booking.stats import StatisticsManager
+from booking.forms import HostReImageForm
+from api.models import JobFactory
+from workflow.views import login
+from booking.forms import QuickBookingForm
+from booking.quick_deployer import create_from_form, drop_filter
-class BookingFormView(FormView):
- template_name = "booking/booking_calendar.html"
- form_class = BookingForm
+def quick_create_clear_fields(request):
+ request.session['quick_create_forminfo'] = None
- def dispatch(self, request, *args, **kwargs):
- self.resource = get_object_or_404(Resource, id=self.kwargs['resource_id'])
- return super(BookingFormView, self).dispatch(request, *args, **kwargs)
- def get_context_data(self, **kwargs):
- title = 'Booking: ' + self.resource.name
- context = super(BookingFormView, self).get_context_data(**kwargs)
- context.update({'title': title, 'resource': self.resource})
- #raise PermissionDenied('check')
- return context
+def quick_create(request):
+ if not request.user.is_authenticated:
+ return login(request)
- def get_success_url(self):
- return reverse('booking:create', kwargs=self.kwargs)
-
- def form_valid(self, form):
- if not self.request.user.is_authenticated:
- messages.add_message(self.request, messages.ERROR,
- 'You need to be logged in to book a Pod.')
- return super(BookingFormView, self).form_invalid(form)
-
- user = self.request.user
- booking = Booking(start=form.cleaned_data['start'],
- end=form.cleaned_data['end'],
- purpose=form.cleaned_data['purpose'],
- opsys=form.cleaned_data['opsys'],
- installer=form.cleaned_data['installer'],
- scenario=form.cleaned_data['scenario'],
- resource=self.resource, user=user)
- try:
- booking.save()
- except ValueError as err:
- messages.add_message(self.request, messages.ERROR, err)
- return super(BookingFormView, self).form_invalid(form)
- try:
- if settings.CREATE_JIRA_TICKET:
- create_jira_ticket(user, booking)
- except JIRAError:
- messages.add_message(self.request, messages.ERROR, 'Failed to create Jira Ticket. '
- 'Please check your Jira '
- 'permissions.')
- booking.delete()
- return super(BookingFormView, self).form_invalid(form)
- messages.add_message(self.request, messages.SUCCESS, 'Booking saved')
- return super(BookingFormView, self).form_valid(form)
-
-
-class BookingEditFormView(FormView):
- template_name = "booking/booking_calendar.html"
- form_class = BookingEditForm
-
- def is_valid(self):
- return True
-
- def dispatch(self, request, *args, **kwargs):
- self.resource = get_object_or_404(Resource, id=self.kwargs['resource_id'])
- self.original_booking = get_object_or_404(Booking, id=self.kwargs['booking_id'])
- return super(BookingEditFormView, self).dispatch(request, *args, **kwargs)
+ if request.method == 'GET':
+ context = {}
- def get_context_data(self, **kwargs):
- title = 'Editing Booking on: ' + self.resource.name
- context = super(BookingEditFormView, self).get_context_data(**kwargs)
- context.update({'title': title, 'resource': self.resource})
- return context
+ r_manager = ResourceManager.getInstance()
+ profiles = {}
+ for lab in Lab.objects.all():
+ profiles[str(lab)] = r_manager.getAvailableHostTypes(lab)
+
+ context['lab_profile_map'] = profiles
+
+ context['form'] = QuickBookingForm(default_user=request.user.username, user=request.user)
+
+ context.update(drop_filter(request.user))
+
+ return render(request, 'booking/quick_deploy.html', context)
+ if request.method == 'POST':
+ form = QuickBookingForm(request.POST, user=request.user)
+ context = {}
+ context['lab_profile_map'] = {}
+ context['form'] = form
+
+ if form.is_valid():
+ try:
+ booking = create_from_form(form, request)
+ messages.success(request, "We've processed your request. "
+ "Check Account->My Bookings for the status of your new booking")
+ return redirect(reverse('booking:booking_detail', kwargs={'booking_id': booking.id}))
+ except Exception as e:
+ messages.error(request, "Whoops, an error occurred: " + str(e))
+ return render(request, 'booking/quick_deploy.html', context)
+ else:
+ messages.error(request, "Looks like the form didn't validate. Check that you entered everything correctly")
+ return render(request, 'booking/quick_deploy.html', context)
- def get_form_kwargs(self):
- kwargs = super(BookingEditFormView, self).get_form_kwargs()
- kwargs['purpose'] = self.original_booking.purpose
- kwargs['start'] = self.original_booking.start
- kwargs['end'] = self.original_booking.end
- try:
- kwargs['installer'] = self.original_booking.installer
- except AttributeError:
- pass
- try:
- kwargs['scenario'] = self.original_booking.scenario
- except AttributeError:
- pass
- return kwargs
-
- def get_success_url(self):
- return reverse('booking:create', args=(self.resource.id,))
-
- def form_valid(self, form):
-
- if not self.request.user.is_authenticated:
- messages.add_message(self.request, messages.ERROR,
- 'You need to be logged in to book a Pod.')
- return super(BookingEditFormView, self).form_invalid(form)
-
- if not self.request.user == self.original_booking.user:
- messages.add_message(self.request, messages.ERROR,
- 'You are not the owner of this booking.')
- return super(BookingEditFormView, self).form_invalid(form)
-
- #Do Conflict Checks
- if self.original_booking.start != form.cleaned_data['start']:
- if timezone.now() > form.cleaned_data['start']:
- messages.add_message(self.request, messages.ERROR,
- 'Cannot change start date after it has occurred.')
- return super(BookingEditFormView, self).form_invalid(form)
- self.original_booking.start = form.cleaned_data['start']
- self.original_booking.end = form.cleaned_data['end']
- self.original_booking.purpose = form.cleaned_data['purpose']
- self.original_booking.installer = form.cleaned_data['installer']
- self.original_booking.scenario = form.cleaned_data['scenario']
- self.original_booking.reset = form.cleaned_data['reset']
- try:
- self.original_booking.save()
- except ValueError as err:
- messages.add_message(self.request, messages.ERROR, err)
- return super(BookingEditFormView, self).form_invalid(form)
-
- user = self.request.user
- return super(BookingEditFormView, self).form_valid(form)
class BookingView(TemplateView):
template_name = "booking/booking_detail.html"
-
def get_context_data(self, **kwargs):
booking = get_object_or_404(Booking, id=self.kwargs['booking_id'])
title = 'Booking Details'
@@ -172,6 +83,7 @@ class BookingView(TemplateView):
context.update({'title': title, 'booking': booking})
return context
+
class BookingDeleteView(TemplateView):
template_name = "booking/booking_delete.html"
@@ -182,12 +94,14 @@ class BookingDeleteView(TemplateView):
context.update({'title': title, 'booking': booking})
return context
+
def bookingDelete(request, booking_id):
booking = get_object_or_404(Booking, id=booking_id)
booking.delete()
messages.add_message(request, messages.SUCCESS, 'Booking deleted')
return redirect('../../../../')
+
class BookingListView(TemplateView):
template_name = "booking/booking_list.html"
@@ -201,8 +115,87 @@ class BookingListView(TemplateView):
class ResourceBookingsJSON(View):
def get(self, request, *args, **kwargs):
- resource = get_object_or_404(Resource, id=self.kwargs['resource_id'])
- bookings = resource.booking_set.get_queryset().values('id', 'start', 'end', 'purpose',
- 'jira_issue_status', 'opsys__name',
- 'installer__name', 'scenario__name')
- return JsonResponse({'bookings': list(bookings)}) \ No newline at end of file
+ resource = get_object_or_404(ResourceBundle, id=self.kwargs['resource_id'])
+ bookings = resource.booking_set.get_queryset().values(
+ 'id',
+ 'start',
+ 'end',
+ 'purpose',
+ 'jira_issue_status',
+ 'config_bundle__name'
+ )
+ return JsonResponse({'bookings': list(bookings)})
+
+
+def build_image_mapping(lab, user):
+ mapping = {}
+ for profile in HostProfile.objects.filter(labs=lab):
+ images = Image.objects.filter(
+ from_lab=lab,
+ host_type=profile
+ ).filter(
+ Q(public=True) | Q(owner=user)
+ )
+ mapping[profile.name] = [{"name": image.name, "value": image.id} for image in images]
+ return mapping
+
+
+def booking_detail_view(request, booking_id):
+ user = None
+ if request.user.is_authenticated:
+ user = request.user
+ else:
+ return render(request, "dashboard/login.html", {'title': 'Authentication Required'})
+
+ booking = get_object_or_404(Booking, id=booking_id)
+ allowed_users = set(list(booking.collaborators.all()))
+ allowed_users.add(booking.owner)
+ if user not in allowed_users:
+ return render(request, "dashboard/login.html", {'title': 'This page is private'})
+
+ context = {
+ 'title': 'Booking Details',
+ 'booking': booking,
+ 'pdf': booking.pdf,
+ 'user_id': user.id,
+ 'image_mapping': build_image_mapping(booking.lab, user)
+ }
+
+ return render(
+ request,
+ "booking/booking_detail.html",
+ context
+ )
+
+
+def booking_modify_image(request, booking_id):
+ form = HostReImageForm(request.POST)
+ if form.is_valid():
+ booking = Booking.objects.get(id=booking_id)
+ if request.user != booking.owner:
+ return HttpResponse("unauthorized")
+ if timezone.now() > booking.end:
+ return HttpResponse("unauthorized")
+ new_image = Image.objects.get(id=form.cleaned_data['image_id'])
+ host = Host.objects.get(id=form.cleaned_data['host_id'])
+ host.config.image = new_image
+ host.config.save()
+ JobFactory.reimageHost(new_image, booking, host)
+ return HttpResponse(new_image.name)
+ return HttpResponse("error")
+
+
+def booking_stats_view(request):
+ return render(
+ request,
+ "booking/stats.html",
+ context={"data": StatisticsManager.getContinuousBookingTimeSeries(), "title": "Booking Statistics"}
+ )
+
+
+def booking_stats_json(request):
+ try:
+ span = int(request.GET.get("days", 14))
+ except Exception:
+ span = 14
+ return JsonResponse(StatisticsManager.getContinuousBookingTimeSeries(span), safe=False)