From e3389d42758feef5dad48e0bbcd5a0a3f6af4206 Mon Sep 17 00:00:00 2001 From: Parker Berberian Date: Mon, 1 Jul 2019 12:55:19 -0400 Subject: Refactor Workflow Manager Refactors wf manager according to: https://jira.opnfv.org/browse/LAAS-31 Change-Id: I72b4b0b808bb77846f44787fdd146f1053c047b5 Signed-off-by: Parker Berberian Signed-off-by: Sawyer Bergeron --- src/pharos_dashboard/urls.py | 2 +- src/workflow/forms.py | 19 ++++++++++++++ src/workflow/urls.py | 7 ++--- src/workflow/views.py | 57 ++++++++++++++-------------------------- src/workflow/workflow_manager.py | 52 ++++++++++++++++++++++-------------- 5 files changed, 76 insertions(+), 61 deletions(-) (limited to 'src') diff --git a/src/pharos_dashboard/urls.py b/src/pharos_dashboard/urls.py index 8535bed..fd791c3 100644 --- a/src/pharos_dashboard/urls.py +++ b/src/pharos_dashboard/urls.py @@ -32,7 +32,7 @@ from django.contrib import admin urlpatterns = [ - url(r'^wf/', include('workflow.urls', namespace='workflow')), + url(r'^workflow/', include('workflow.urls', namespace='workflow')), url(r'^', include('dashboard.urls', namespace='dashboard')), url(r'^booking/', include('booking.urls', namespace='booking')), url(r'^accounts/', include('account.urls', namespace='account')), diff --git a/src/workflow/forms.py b/src/workflow/forms.py index ee44ecd..a2746f9 100644 --- a/src/workflow/forms.py +++ b/src/workflow/forms.py @@ -15,6 +15,7 @@ from django.template.loader import render_to_string from django.forms.widgets import NumberInput import json +import urllib from account.models import Lab from account.models import UserProfile @@ -428,6 +429,24 @@ class ConfirmationForm(forms.Form): ) +def validate_step(value): + if value not in ["prev", "next", "current"]: + raise ValidationError(str(value) + " is not allowed") + + +def validate_step_form(value): + try: + urllib.parse.unquote_plus(value) + except Exception: + raise ValidationError("Value is not url encoded data") + + +class ManagerForm(forms.Form): + step = forms.CharField(widget=forms.widgets.HiddenInput, validators=[validate_step]) + step_form = forms.CharField(widget=forms.widgets.HiddenInput, validators=[validate_step_form]) + # other fields? + + class OPNFVSelectionForm(forms.Form): installer = forms.ModelChoiceField(queryset=Installer.objects.all(), required=True) scenario = forms.ModelChoiceField(queryset=Scenario.objects.all(), required=True) diff --git a/src/workflow/urls.py b/src/workflow/urls.py index 5a97904..ae620d0 100644 --- a/src/workflow/urls.py +++ b/src/workflow/urls.py @@ -11,7 +11,7 @@ from django.conf.urls import url from django.conf import settings -from workflow.views import step_view, delete_session, manager_view, viewport_view +from workflow.views import delete_session, manager_view, viewport_view, add_workflow, cancel_workflow from workflow.models import Repository from workflow.resource_bundle_workflow import Define_Hardware, Define_Nets, Resource_Meta_Info from workflow.booking_workflow import SWConfig_Select, Booking_Resource_Select, Booking_Meta @@ -19,9 +19,10 @@ from workflow.booking_workflow import SWConfig_Select, Booking_Resource_Select, app_name = 'workflow' urlpatterns = [ - url(r'^workflow/$', step_view, name='workflow'), - url(r'^workflow/finish/$', delete_session, name='delete_session'), + url(r'^finish/$', delete_session, name='delete_session'), url(r'^manager/$', manager_view, name='manager'), + url(r'^add/$', add_workflow, name='add_workflow'), + url(r'^cancel/$', cancel_workflow, name='cancel_workflow'), url(r'^$', viewport_view, name='viewport') ] diff --git a/src/workflow/views.py b/src/workflow/views.py index 7ed9031..47241e2 100644 --- a/src/workflow/views.py +++ b/src/workflow/views.py @@ -8,7 +8,7 @@ ############################################################################## -from django.http import HttpResponseGone, JsonResponse +from django.http import HttpResponse, JsonResponse from django.shortcuts import render from django.urls import reverse @@ -49,7 +49,7 @@ def delete_session(request): manager = attempt_auth(request) if not manager: - return HttpResponseGone("No session found that relates to current request") + return no_workflow(request) not_last_workflow, result = manager.pop_workflow() @@ -60,48 +60,34 @@ def delete_session(request): return JsonResponse(get_redirect_response(result)) -def step_view(request): +def add_workflow(request): manager = attempt_auth(request) if not manager: - # no manager found, redirect to "lost" page return no_workflow(request) - if request.GET.get('step') is not None: - if request.GET.get('step') == 'next': - manager.go_next() - elif request.GET.get('step') == 'prev': - manager.go_prev() - else: - raise Exception("requested action for new step had malformed contents: " + request.GET.get('step')) - return manager.render(request) + try: + workflow_type = int(request.POST.get('workflow_type')) + except ValueError: + return HttpResponse(status=400) + manager.add_workflow(workflow_type=workflow_type) + return manager.render(request) # do we want this? -def manager_view(request): - manager = attempt_auth(request) +def cancel_workflow(request): + manager = attempt_auth(request) if not manager: - return HttpResponseGone("No session found that relates to current request") + return no_workflow(request) - if request.method == 'GET': - # no need for this statement if only intercepting post requests + if not manager.pop_workflow(): + del ManagerTracker.managers[request.session['manager_session']] - # return general context for viewport page - return manager.status(request) - if request.method == 'POST': - if request.POST.get('add') is not None: - logger.debug("add found") - target_id = None - if 'target' in request.POST: - target_id = int(request.POST.get('target')) - manager.add_workflow(workflow_type=int(request.POST.get('add')), target_id=target_id) - elif request.POST.get('edit') is not None and request.POST.get('edit_id') is not None: - logger.debug("edit found") - manager.add_workflow(workflow_type=request.POST.get('edit'), edit_object=int(request.POST.get('edit_id'))) - elif request.POST.get('cancel') is not None: - if not manager.pop_workflow(): - del ManagerTracker.managers[request.session['manager_session']] +def manager_view(request): + manager = attempt_auth(request) + if not manager: + return no_workflow(request) - return manager.status(request) + return manager.handle_request(request) def viewport_view(request): @@ -129,10 +115,7 @@ def create_session(wf_type, request): def no_workflow(request): - - logger.debug("There is no active workflow") - - return render(request, 'workflow/no_workflow.html', {'title': "Not Found"}) + return render(request, 'workflow/no_workflow.html', {'title': "Not Found"}, status=404) def login(request): diff --git a/src/workflow/workflow_manager.py b/src/workflow/workflow_manager.py index 80b8a67..605eee7 100644 --- a/src/workflow/workflow_manager.py +++ b/src/workflow/workflow_manager.py @@ -9,6 +9,7 @@ from django.http import JsonResponse +from django.http.request import QueryDict from booking.models import Booking from workflow.workflow_factory import WorkflowFactory @@ -19,6 +20,7 @@ from resource_inventory.models import ( HostConfiguration, OPNFVConfig ) +from workflow.forms import ManagerForm import logging logger = logging.getLogger(__name__) @@ -45,10 +47,7 @@ class SessionManager(): else: step.disable() - def add_workflow(self, workflow_type=None, target_id=None, **kwargs): - if target_id is not None: - self.prefill_repo(target_id, workflow_type) - + def add_workflow(self, workflow_type=None, **kwargs): repo = Repository() if(len(self.workflows) >= 1): defaults = self.workflows[-1].repository.get_child_defaults() @@ -75,24 +74,37 @@ class SessionManager(): return (multiple_wfs, current_repo.el[current_repo.RESULT]) def status(self, request): - try: - meta_json = [] - for step in self.active_workflow().steps: - meta_json.append(step.to_json()) - responsejson = {} - responsejson["steps"] = meta_json - responsejson["active"] = self.active_workflow().repository.el['active_step'] - responsejson["workflow_count"] = len(self.workflows) - return JsonResponse(responsejson, safe=False) - except Exception: - pass + return { + "steps": [step.to_json() for step in self.active_workflow().steps], + "active": self.active_workflow().repository.el['active_step'], + "workflow_count": len(self.workflows) + } + + def handle_post(self, request): + form = ManagerForm(request.POST) + if form.is_valid: + self.get_active_step().post( + QueryDict(form.cleaned_data['step_form']), + user=request.user + ) + # change step + if form.cleaned_data['step'] == 'prev': + self.go_prev() + if form.cleaned_data['step'] == 'next': + self.go_next() + else: + pass # Exception? + + def handle_request(self, request): + if request.method == 'POST': + self.handle_post(request) + return self.render() def render(self, request, **kwargs): - # filter out when a step needs to handle post/form data - # if 'workflow' in post data, this post request was meant for me, not step - if request.method == 'POST' and request.POST.get('workflow', None) is None: - return self.active_workflow().steps[self.active_workflow().active_index].post_render(request) - return self.active_workflow().steps[self.active_workflow().active_index].render(request) + return JsonResponse({ + "meta": self.status(), + "content": self.get_active_step().render_to_string(request) + }) def post_render(self, request): return self.active_workflow().steps[self.active_workflow().active_index].post_render(request) -- cgit 1.2.3-korg