diff options
-rw-r--r-- | src/pharos_dashboard/urls.py | 2 | ||||
-rw-r--r-- | src/templates/booking/steps/booking_meta.html | 12 | ||||
-rw-r--r-- | src/templates/config_bundle/steps/config_software.html | 12 | ||||
-rw-r--r-- | src/templates/config_bundle/steps/define_software.html | 9 | ||||
-rw-r--r-- | src/templates/config_bundle/steps/pick_installer.html | 12 | ||||
-rw-r--r-- | src/templates/config_bundle/steps/table_formset.html | 13 | ||||
-rw-r--r-- | src/templates/resource/steps/define_hardware.html | 10 | ||||
-rw-r--r-- | src/templates/resource/steps/host_info.html | 11 | ||||
-rw-r--r-- | src/templates/resource/steps/meta_info.html | 12 | ||||
-rw-r--r-- | src/templates/resource/steps/pod_definition.html | 2 | ||||
-rw-r--r-- | src/templates/snapshot_workflow/steps/meta.html | 12 | ||||
-rw-r--r-- | src/templates/snapshot_workflow/steps/select_host.html | 12 | ||||
-rw-r--r-- | src/workflow/forms.py | 19 | ||||
-rw-r--r-- | src/workflow/urls.py | 7 | ||||
-rw-r--r-- | src/workflow/views.py | 57 | ||||
-rw-r--r-- | src/workflow/workflow_manager.py | 52 |
16 files changed, 86 insertions, 168 deletions
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/templates/booking/steps/booking_meta.html b/src/templates/booking/steps/booking_meta.html index a7bb8b9..f12496e 100644 --- a/src/templates/booking/steps/booking_meta.html +++ b/src/templates/booking/steps/booking_meta.html @@ -6,7 +6,7 @@ {% block content %} {% bootstrap_form_errors form type='non_fields' %} -<form id="booking_meta_form" action="/wf/workflow/" method="POST" class="form"> +<form id="step_form" method="POST" class="form"> {% csrf_token %} <div id="form_div" class="container-fluid"> <div class="row"> @@ -36,13 +36,3 @@ </div> </form> {% endblock content %} - -{% block onleave %} -var ajaxForm = $("#booking_meta_form"); -var formData = ajaxForm.serialize(); -req = new XMLHttpRequest(); -req.open("POST", "/wf/workflow/", false); -req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); -req.onerror = function() { alert("problem submitting form"); } -req.send(formData); -{% endblock %} diff --git a/src/templates/config_bundle/steps/config_software.html b/src/templates/config_bundle/steps/config_software.html index 68417bc..6fe0ac1 100644 --- a/src/templates/config_bundle/steps/config_software.html +++ b/src/templates/config_bundle/steps/config_software.html @@ -5,7 +5,7 @@ {% block content %} -<form action="/wf/workflow/" method="POST" id="software_config_form" class="form"> +<form method="POST" id="step_form" class="form"> {% csrf_token %} <p>Give it a name:</p> {% bootstrap_field form.name %} @@ -16,13 +16,3 @@ {% endblock content %} - -{% block onleave %} -var ajaxForm = $("#software_config_form"); -var formData = ajaxForm.serialize(); -req = new XMLHttpRequest(); -req.open("POST", "/wf/workflow/", false); -req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); -req.onerror = function() { alert("problem submitting form"); } -req.send(formData); -{% endblock %} diff --git a/src/templates/config_bundle/steps/define_software.html b/src/templates/config_bundle/steps/define_software.html index 87e5997..7c47569 100644 --- a/src/templates/config_bundle/steps/define_software.html +++ b/src/templates/config_bundle/steps/define_software.html @@ -44,12 +44,3 @@ for(var i=0; i<parents.length; i++){ checkbox.value = "True"; } } - -var form = $("#table_formset"); -var formData = form.serialize(); -var req = new XMLHttpRequest(); -req.open("POST", "/wf/workflow/", false); -req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); -req.onerror = function() { alert("problem with form submission"); } -req.send(formData); -{% endblock onleave %} diff --git a/src/templates/config_bundle/steps/pick_installer.html b/src/templates/config_bundle/steps/pick_installer.html index 31a06de..c3b505d 100644 --- a/src/templates/config_bundle/steps/pick_installer.html +++ b/src/templates/config_bundle/steps/pick_installer.html @@ -9,7 +9,7 @@ <h1>Please choose a config bundle first</h1> {% else %} -<form id="installer_form" action="/wf/workflow/" method="POST" id="installer_config_form" class="form"> +<form id="step_form" method="POST" class="form"> {% csrf_token %} <p>Choose your installer:</p> {% bootstrap_field form.installer %} @@ -20,13 +20,3 @@ {% endif %} {% endblock content %} - -{% block onleave %} -var form = $("#installer_form"); -var formData = form.serialize(); -var req = new XMLHttpRequest(); -req.open("POST", "/wf/workflow/", false); -req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); -req.onerror = function() { alert("problem with form submission"); } -req.send(formData); -{% endblock %} diff --git a/src/templates/config_bundle/steps/table_formset.html b/src/templates/config_bundle/steps/table_formset.html index e19f3df..d25621e 100644 --- a/src/templates/config_bundle/steps/table_formset.html +++ b/src/templates/config_bundle/steps/table_formset.html @@ -18,7 +18,7 @@ <h1 class="text-center">{{ error }}</h1> {% else %} <div class="p-2"> - <form method="post" action="" class="form" id="table_formset"> + <form method="post" class="form" id="step_form"> <!-- formset, requires special consideration --> {% csrf_token %} <div class="row"> @@ -51,14 +51,3 @@ {% block tablejs %} {% endblock tablejs %} {% endblock extrajs %} - - -{% block onleave %} -var form = $("#table_formset"); -var formData = form.serialize(); -var req = new XMLHttpRequest(); -req.open("POST", "/wf/workflow/", false); -req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); -req.onerror = function() { alert("problem with form submission"); } -req.send(formData); -{% endblock %} diff --git a/src/templates/resource/steps/define_hardware.html b/src/templates/resource/steps/define_hardware.html index 57078e9..33a7d8e 100644 --- a/src/templates/resource/steps/define_hardware.html +++ b/src/templates/resource/steps/define_hardware.html @@ -9,16 +9,8 @@ As you make your selections, labs and hosts that are not compatible with your current configuration will become unavailable.</p> <h4>NOTE: Only PTL's are able to create multi-node PODs. See <a href="https://google.com">here</a> for more details</h4> -<form id="define_hardware_form" action="/wf/workflow/" method="post"> +<form id="step_form" method="post"> {% csrf_token %} {{form.filter_field|default:"<p>No Form</p>"}} </form> {% endblock content %} -{% block onleave %} -multi_filter_widget.finish(); -var formData = $("#define_hardware_form").serialize(); -req = new XMLHttpRequest(); -req.open('POST', '/wf/workflow/', false); -req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); -req.send(formData); -{% endblock %} diff --git a/src/templates/resource/steps/host_info.html b/src/templates/resource/steps/host_info.html index bbbafdc..3230d8f 100644 --- a/src/templates/resource/steps/host_info.html +++ b/src/templates/resource/steps/host_info.html @@ -10,7 +10,7 @@ {% else %} -<form id="host_meta_form" method="post" action="/wf/workflow/"> +<form id="step_form" method="post"> {% csrf_token %} <table> <thead> @@ -32,12 +32,3 @@ </form> {% endif %} {% endblock content %} - -{% block onleave %} -var formData = $("#host_meta_form").serialize(); -var req = new XMLHttpRequest(); -req.open("POST", "/wf/workflow/", false); -req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); -req.onerror = function() { alert("There was a problem submitting the form"); } -req.send(formData); -{% endblock %} diff --git a/src/templates/resource/steps/meta_info.html b/src/templates/resource/steps/meta_info.html index 62230dc..b6a17a9 100644 --- a/src/templates/resource/steps/meta_info.html +++ b/src/templates/resource/steps/meta_info.html @@ -5,20 +5,10 @@ {% block content %} -<form id="resource_meta_form" method="post" action="/wf/workflow/"> +<form id="step_form" method="post"> {% csrf_token %} <table class="px-4"> {% bootstrap_form form field_class="px-4" label_class="px-4 mt-2" %} </table> </form> {% endblock content %} - -{% block onleave %} -var ajaxForm = $("#resource_meta_form"); -var formData = ajaxForm.serialize(); -req = new XMLHttpRequest(); -req.open("POST", "/wf/workflow/", false); -req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); -req.onerror = function() { alert("problem submitting form"); } -req.send(formData); -{% endblock %} diff --git a/src/templates/resource/steps/pod_definition.html b/src/templates/resource/steps/pod_definition.html index bd0a539..4392dbd 100644 --- a/src/templates/resource/steps/pod_definition.html +++ b/src/templates/resource/steps/pod_definition.html @@ -37,7 +37,7 @@ <button type="button" class="d-none" onclick="network_step.submitForm();">Submit</button> </div> </div> - <form id="xml_form" method="post" action="/wf/workflow/"> + <form id="step_form" method="post"> {% csrf_token %} <input type="hidden" id="hidden_xml_input" name="xml" /> </form> diff --git a/src/templates/snapshot_workflow/steps/meta.html b/src/templates/snapshot_workflow/steps/meta.html index 7c3e98b..88136d2 100644 --- a/src/templates/snapshot_workflow/steps/meta.html +++ b/src/templates/snapshot_workflow/steps/meta.html @@ -6,7 +6,7 @@ {% block content %} {% bootstrap_form_errors form type='non_fields' %} <div class="p-4"> - <form id="meta_form" action="/wf/workflow/" method="POST" class="form"> + <form id="step_form" method="POST" class="form"> {% csrf_token %} <div class="form-group"> {% bootstrap_field form.name %} @@ -15,13 +15,3 @@ </form> </div> {% endblock content %} - -{% block onleave %} -var ajaxForm = $("#meta_form"); -var formData = ajaxForm.serialize(); -req = new XMLHttpRequest(); -req.open("POST", "/wf/workflow/", false); -req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); -req.onerror = function() { alert("problem submitting form"); } -req.send(formData); -{% endblock %} diff --git a/src/templates/snapshot_workflow/steps/select_host.html b/src/templates/snapshot_workflow/steps/select_host.html index a0af67b..4243145 100644 --- a/src/templates/snapshot_workflow/steps/select_host.html +++ b/src/templates/snapshot_workflow/steps/select_host.html @@ -6,7 +6,7 @@ {% block content %} {% bootstrap_form_errors form type='non_fields' %} -<form id="host_select_form" action="/wf/workflow/" method="POST" class="form"> +<form id="step_form" method="POST" class="form"> {% csrf_token %} <input type="hidden" id="hidden_json_input", name="host"/> </form> @@ -81,13 +81,3 @@ if(initial){ } </script> {% endblock content %} - -{% block onleave %} -var ajaxForm = $("#host_select_form"); -var formData = ajaxForm.serialize(); -req = new XMLHttpRequest(); -req.open("POST", "/wf/workflow/", false); -req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); -req.onerror = function() { alert("problem submitting form"); } -req.send(formData); -{% endblock %} 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) |