aboutsummaryrefslogtreecommitdiffstats
path: root/src/workflow/workflow_manager.py
diff options
context:
space:
mode:
authorParker Berberian <pberberian@iol.unh.edu>2018-10-10 16:06:47 -0400
committerParker Berberian <pberberian@iol.unh.edu>2018-10-15 13:16:11 -0400
commit1f3a770d2547848590f39e9d9b9bdffeb94eec14 (patch)
tree97222e5facd1a242d951c38482315057b5790d51 /src/workflow/workflow_manager.py
parent6d4019e59eda897384e9c00d1daf8b2ce87d128f (diff)
Lab as a Service 2.0
See changes here: https://wiki.opnfv.org/display/INF/Pharos+Laas Change-Id: I59ada5f98e70a28d7f8c14eab3239597e236ca26 Signed-off-by: Sawyer Bergeron <sbergeron@iol.unh.edu> Signed-off-by: Parker Berberian <pberberian@iol.unh.edu>
Diffstat (limited to 'src/workflow/workflow_manager.py')
-rw-r--r--src/workflow/workflow_manager.py251
1 files changed, 251 insertions, 0 deletions
diff --git a/src/workflow/workflow_manager.py b/src/workflow/workflow_manager.py
new file mode 100644
index 0000000..16fa468
--- /dev/null
+++ b/src/workflow/workflow_manager.py
@@ -0,0 +1,251 @@
+##############################################################################
+# Copyright (c) 2018 Sawyer Bergeron, Parker Berberian, and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+
+from django.db import models
+from django.contrib.auth.models import User
+from django.core import serializers
+from django.http import HttpResponse, JsonResponse
+
+import json
+import uuid
+import random
+
+from resource_inventory.models import *
+from booking.models import Booking
+from workflow.workflow_factory import WorkflowFactory, MetaStep, MetaRelation
+from workflow.models import Repository, Confirmation_Step
+
+import logging
+logger = logging.getLogger(__name__)
+
+class SessionManager():
+
+ def __init__(self, request=None):
+ self.repository = Repository()
+ self.repository.el[self.repository.SESSION_USER] = request.user
+ self.repository.el['active_step'] = 0
+ self.steps = []
+ self.factory = WorkflowFactory()
+ c_step = WorkflowFactory().make_step(Confirmation_Step, self.repository)
+ self.steps.append(c_step)
+ metaconfirm = MetaStep()
+ metaconfirm.index = 0
+ metaconfirm.short_title = "confirm"
+ self.repository.el['steps'] = 1;
+ self.metaworkflow = None
+ self.metaworkflows = []
+ self.metarelations = []
+ self.relationreverselookup = {}
+ self.initialized = False
+ self.active_index = 0
+ self.step_meta = [metaconfirm]
+ self.relation_depth = 0
+
+ def add_workflow(self, workflow_type=None, target_id=None, **kwargs):
+ if target_id is not None:
+ self.prefill_repo(target_id, workflow_type)
+ factory_steps, meta_info = self.factory.conjure(workflow_type=workflow_type, repo=self.repository)
+ offset = len(meta_info)
+ for relation in self.metarelations:
+ if relation.depth > self.relation_depth:
+ self.relation_depth = relation.depth
+ if relation.parent >= self.repository.el['active_step']:
+ relation.parent += offset
+ for i in range(0, len(relation.children)):
+ if relation.children[i] >= self.repository.el['active_step']:
+ relation.children[i] += offset
+ self.step_meta[self.active_index:self.active_index] = meta_info
+ self.steps[self.active_index:self.active_index] = factory_steps
+
+ if self.initialized:
+ relation = MetaRelation()
+ relation.parent = self.repository.el['active_step'] + offset
+ relation.depth = self.relationreverselookup[self.step_meta[relation.parent]].depth + 1
+ if relation.depth > self.relation_depth:
+ self.relation_depth = relation.depth
+ for i in range(self.repository.el['active_step'], offset + self.repository.el['active_step']):
+ relation.children.append(i)
+ self.relationreverselookup[self.step_meta[i]] = relation
+ relation.color = "#%06x" % random.randint(0, 0xFFFFFF)
+ self.metarelations.append(relation)
+ else:
+ relation = MetaRelation()
+ relation.depth = 0
+ relation.parent = 500000000000
+ for i in range(0, len(self.step_meta)):
+ relation.children.append(i)
+ self.relationreverselookup[self.step_meta[i]] = relation
+ self.metarelations.append(relation)
+ self.initialized = True
+
+
+ def status(self, request):
+ try:
+ workflows = []
+ steps = []
+ for step in self.step_meta:
+ steps.append(step.to_json())
+ parents = {}
+ children = {}
+ responsejson = {}
+ responsejson["steps"] = steps
+ responsejson["active"] = self.repository.el['active_step']
+ responsejson["relations"] = []
+ i = 0
+ for relation in self.metarelations:
+ responsejson["relations"].append(relation.to_json())
+ children[relation.parent] = i
+ for child in relation.children:
+ parents[child] = i
+ i += 1
+ responsejson['max_depth'] = self.relation_depth
+ responsejson['parents'] = parents
+ responsejson['children'] = children
+ return JsonResponse(responsejson, safe=False)
+ except Exception as e:
+ pass
+
+ 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.steps[self.active_index].post_render(request)
+ return self.steps[self.active_index].render(request)
+
+ def post_render(self, request):
+ return self.steps[self.active_index].post_render(request)
+
+ def goto(self, num, **kwargs):
+ self.repository.el['active_step'] = int(num)
+ self.active_index = int(num)
+ #TODO: change to include some checking
+
+ def prefill_repo(self, target_id, workflow_type):
+ self.repository.el[self.repository.EDIT] = True
+ edit_object = None
+ if workflow_type == 0:
+ edit_object = Booking.objects.get(pk=target_id)
+ self.prefill_booking(edit_object)
+ elif workflow_type == 1:
+ edit_object = GenericResourceBundle.objects.get(pk=target_id)
+ self.prefill_resource(edit_object)
+ elif workflow_type == 2:
+ edit_object = ConfigBundle.objects.get(pk=target_id)
+ self.prefill_config(edit_object)
+
+
+ def prefill_booking(self, booking):
+ models = self.make_booking_models(booking)
+ confirmation = self.make_booking_confirm(booking)
+ self.repository.el[self.repository.BOOKING_MODELS] = models
+ self.repository.el[self.repository.CONFIRMATION] = confirmation
+ self.repository.el[self.repository.GRESOURCE_BUNDLE_MODELS] = self.make_grb_models(booking.resource.template)
+ self.repository.el[self.repository.BOOKING_SELECTED_GRB] = self.make_grb_models(booking.resource.template)['bundle']
+ self.repository.el[self.repository.CONFIG_MODELS] = self.make_config_models(booking.config_bundle)
+
+ def prefill_resource(self, resource):
+ models = self.make_grb_models(resource)
+ confirm = self.make_grb_confirm(resource)
+ self.repository.el[self.repository.GRESOURCE_BUNDLE_MODELS] = models
+ self.repository.el[self.repository.CONFIRMATION] = confirm
+
+ def prefill_config(self, config):
+ models = self.make_config_models(config)
+ confirm = self.make_config_confirm(config)
+ self.repository.el[self.repository.CONFIG_MODELS] = models
+ self.repository.el[self.repository.CONFIRMATION] = confirm
+ grb_models = self.make_grb_models(config.bundle)
+ self.repository.el[self.repository.GRESOURCE_BUNDLE_MODELS] = grb_models
+ self.repository.el[self.repository.SWCONF_SELECTED_GRB] = config.bundle
+
+ def make_grb_models(self, resource):
+ models = self.repository.el.get(self.repository.GRESOURCE_BUNDLE_MODELS, {})
+ models['hosts'] = []
+ models['bundle'] = resource
+ models['interfaces'] = {}
+ models['vlans'] = {}
+ for host in resource.getHosts():
+ models['hosts'].append(host)
+ models['interfaces'][host.resource.name] = []
+ models['vlans'][host.resource.name] = {}
+ for interface in host.generic_interfaces.all():
+ models['interfaces'][host.resource.name].append(interface)
+ models['vlans'][host.resource.name][interface.profile.name] = []
+ for vlan in interface.vlans.all():
+ models['vlans'][host.resource.name][interface.profile.name].append(vlan)
+ return models
+
+ def make_grb_confirm(self, resource):
+ confirm = self.repository.el.get(self.repository.CONFIRMATION, {})
+ confirm['resource'] = {}
+ confirm['resource']['hosts'] = []
+ confirm['resource']['lab'] = resource.lab.lab_user.username
+ for host in resource.getHosts():
+ confirm['resource']['hosts'].append({"name": host.resource.name, "profile": host.profile.name})
+ return confirm
+
+ def make_config_models(self, config):
+ models = self.repository.el.get(self.repository.CONFIG_MODELS, {})
+ models['bundle'] = config
+ models['host_configs'] = []
+ for host_conf in HostConfiguration.objects.filter(bundle=config):
+ models['host_configs'].append(host_conf)
+ models['opnfv'] = OPNFVConfig.objects.filter(bundle=config).last()
+ return models
+
+ def make_config_confirm(self, config):
+ confirm = self.repository.el.get(self.repository.CONFIRMATION, {})
+ confirm['configuration'] = {}
+ confirm['configuration']['hosts'] = []
+ confirm['configuration']['name'] = config.name
+ confirm['configuration']['description'] = config.description
+ opnfv = OPNFVConfig.objects.filter(bundle=config).last()
+ confirm['configuration']['installer'] = opnfv.installer.name
+ confirm['configuration']['scenario'] = opnfv.scenario.name
+ for host_conf in HostConfiguration.objects.filter(bundle=config):
+ h = {"name": host_conf.host.resource.name, "image": host_conf.image.name, "role": host_conf.opnfvRole.name}
+ confirm['configuration']['hosts'].append(h)
+ return confirm
+
+ def make_booking_models(self, booking):
+ models = self.repository.el.get(self.repository.BOOKING_MODELS, {})
+ models['booking'] = booking
+ models['collaborators'] = []
+ for user in booking.collaborators.all():
+ models['collaborators'].append(user)
+ return models
+
+ def make_booking_confirm(self, booking):
+ confirm = self.repository.el.get(self.repository.CONFIRMATION, {})
+ confirm['booking'] = {}
+ confirm['booking']['length'] = (booking.end - booking.start).days
+ confirm['booking']['project'] = booking.project
+ confirm['booking']['purpose'] = booking.purpose
+ confirm['booking']['resource name'] = booking.resource.template.name
+ confirm['booking']['configuration name'] = booking.config_bundle.name
+ confirm['booking']['collaborators'] = []
+ for user in booking.collaborators.all():
+ confirm['booking']['collaborators'].append(user.username)
+ return confirm
+
+
+class ManagerTracker():
+ instance = None
+
+ managers = {}
+
+ def __init__(self):
+ pass
+
+ @staticmethod
+ def getInstance():
+ if ManagerTracker.instance is None:
+ ManagerTracker.instance = ManagerTracker()
+ return ManagerTracker.instance