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 ##############################################################################
11 from django.db import models
12 from django.contrib.auth.models import User
13 from django.core import serializers
14 from django.http import HttpResponse, JsonResponse
20 from resource_inventory.models import *
21 from booking.models import Booking
22 from workflow.workflow_factory import WorkflowFactory, MetaStep, MetaRelation
23 from workflow.models import Repository, Confirmation_Step
26 logger = logging.getLogger(__name__)
28 class SessionManager():
30 def __init__(self, request=None):
31 self.repository = Repository()
32 self.repository.el[self.repository.SESSION_USER] = request.user
33 self.repository.el['active_step'] = 0
35 self.factory = WorkflowFactory()
36 c_step = WorkflowFactory().make_step(Confirmation_Step, self.repository)
37 self.steps.append(c_step)
38 metaconfirm = MetaStep()
40 metaconfirm.short_title = "confirm"
41 self.repository.el['steps'] = 1;
42 self.metaworkflow = None
43 self.metaworkflows = []
44 self.metarelations = []
45 self.relationreverselookup = {}
46 self.initialized = False
48 self.step_meta = [metaconfirm]
49 self.relation_depth = 0
51 def add_workflow(self, workflow_type=None, target_id=None, **kwargs):
52 if target_id is not None:
53 self.prefill_repo(target_id, workflow_type)
54 factory_steps, meta_info = self.factory.conjure(workflow_type=workflow_type, repo=self.repository)
55 offset = len(meta_info)
56 for relation in self.metarelations:
57 if relation.depth > self.relation_depth:
58 self.relation_depth = relation.depth
59 if relation.parent >= self.repository.el['active_step']:
60 relation.parent += offset
61 for i in range(0, len(relation.children)):
62 if relation.children[i] >= self.repository.el['active_step']:
63 relation.children[i] += offset
64 self.step_meta[self.active_index:self.active_index] = meta_info
65 self.steps[self.active_index:self.active_index] = factory_steps
68 relation = MetaRelation()
69 relation.parent = self.repository.el['active_step'] + offset
70 relation.depth = self.relationreverselookup[self.step_meta[relation.parent]].depth + 1
71 if relation.depth > self.relation_depth:
72 self.relation_depth = relation.depth
73 for i in range(self.repository.el['active_step'], offset + self.repository.el['active_step']):
74 relation.children.append(i)
75 self.relationreverselookup[self.step_meta[i]] = relation
76 relation.color = "#%06x" % random.randint(0, 0xFFFFFF)
77 self.metarelations.append(relation)
79 relation = MetaRelation()
81 relation.parent = 500000000000
82 for i in range(0, len(self.step_meta)):
83 relation.children.append(i)
84 self.relationreverselookup[self.step_meta[i]] = relation
85 self.metarelations.append(relation)
86 self.initialized = True
89 def status(self, request):
93 for step in self.step_meta:
94 steps.append(step.to_json())
98 responsejson["steps"] = steps
99 responsejson["active"] = self.repository.el['active_step']
100 responsejson["relations"] = []
102 for relation in self.metarelations:
103 responsejson["relations"].append(relation.to_json())
104 children[relation.parent] = i
105 for child in relation.children:
108 responsejson['max_depth'] = self.relation_depth
109 responsejson['parents'] = parents
110 responsejson['children'] = children
111 return JsonResponse(responsejson, safe=False)
112 except Exception as e:
115 def render(self, request, **kwargs):
116 #filter out when a step needs to handle post/form data
117 # if 'workflow' in post data, this post request was meant for me, not step
118 if request.method == 'POST' and request.POST.get('workflow', None) is None:
119 return self.steps[self.active_index].post_render(request)
120 return self.steps[self.active_index].render(request)
122 def post_render(self, request):
123 return self.steps[self.active_index].post_render(request)
125 def goto(self, num, **kwargs):
126 self.repository.el['active_step'] = int(num)
127 self.active_index = int(num)
128 #TODO: change to include some checking
130 def prefill_repo(self, target_id, workflow_type):
131 self.repository.el[self.repository.EDIT] = True
133 if workflow_type == 0:
134 edit_object = Booking.objects.get(pk=target_id)
135 self.prefill_booking(edit_object)
136 elif workflow_type == 1:
137 edit_object = GenericResourceBundle.objects.get(pk=target_id)
138 self.prefill_resource(edit_object)
139 elif workflow_type == 2:
140 edit_object = ConfigBundle.objects.get(pk=target_id)
141 self.prefill_config(edit_object)
144 def prefill_booking(self, booking):
145 models = self.make_booking_models(booking)
146 confirmation = self.make_booking_confirm(booking)
147 self.repository.el[self.repository.BOOKING_MODELS] = models
148 self.repository.el[self.repository.CONFIRMATION] = confirmation
149 self.repository.el[self.repository.GRESOURCE_BUNDLE_MODELS] = self.make_grb_models(booking.resource.template)
150 self.repository.el[self.repository.BOOKING_SELECTED_GRB] = self.make_grb_models(booking.resource.template)['bundle']
151 self.repository.el[self.repository.CONFIG_MODELS] = self.make_config_models(booking.config_bundle)
153 def prefill_resource(self, resource):
154 models = self.make_grb_models(resource)
155 confirm = self.make_grb_confirm(resource)
156 self.repository.el[self.repository.GRESOURCE_BUNDLE_MODELS] = models
157 self.repository.el[self.repository.CONFIRMATION] = confirm
159 def prefill_config(self, config):
160 models = self.make_config_models(config)
161 confirm = self.make_config_confirm(config)
162 self.repository.el[self.repository.CONFIG_MODELS] = models
163 self.repository.el[self.repository.CONFIRMATION] = confirm
164 grb_models = self.make_grb_models(config.bundle)
165 self.repository.el[self.repository.GRESOURCE_BUNDLE_MODELS] = grb_models
166 self.repository.el[self.repository.SWCONF_SELECTED_GRB] = config.bundle
168 def make_grb_models(self, resource):
169 models = self.repository.el.get(self.repository.GRESOURCE_BUNDLE_MODELS, {})
171 models['bundle'] = resource
172 models['interfaces'] = {}
174 for host in resource.getHosts():
175 models['hosts'].append(host)
176 models['interfaces'][host.resource.name] = []
177 models['vlans'][host.resource.name] = {}
178 for interface in host.generic_interfaces.all():
179 models['interfaces'][host.resource.name].append(interface)
180 models['vlans'][host.resource.name][interface.profile.name] = []
181 for vlan in interface.vlans.all():
182 models['vlans'][host.resource.name][interface.profile.name].append(vlan)
185 def make_grb_confirm(self, resource):
186 confirm = self.repository.el.get(self.repository.CONFIRMATION, {})
187 confirm['resource'] = {}
188 confirm['resource']['hosts'] = []
189 confirm['resource']['lab'] = resource.lab.lab_user.username
190 for host in resource.getHosts():
191 confirm['resource']['hosts'].append({"name": host.resource.name, "profile": host.profile.name})
194 def make_config_models(self, config):
195 models = self.repository.el.get(self.repository.CONFIG_MODELS, {})
196 models['bundle'] = config
197 models['host_configs'] = []
198 for host_conf in HostConfiguration.objects.filter(bundle=config):
199 models['host_configs'].append(host_conf)
200 models['opnfv'] = OPNFVConfig.objects.filter(bundle=config).last()
203 def make_config_confirm(self, config):
204 confirm = self.repository.el.get(self.repository.CONFIRMATION, {})
205 confirm['configuration'] = {}
206 confirm['configuration']['hosts'] = []
207 confirm['configuration']['name'] = config.name
208 confirm['configuration']['description'] = config.description
209 opnfv = OPNFVConfig.objects.filter(bundle=config).last()
210 confirm['configuration']['installer'] = opnfv.installer.name
211 confirm['configuration']['scenario'] = opnfv.scenario.name
212 for host_conf in HostConfiguration.objects.filter(bundle=config):
213 h = {"name": host_conf.host.resource.name, "image": host_conf.image.name, "role": host_conf.opnfvRole.name}
214 confirm['configuration']['hosts'].append(h)
217 def make_booking_models(self, booking):
218 models = self.repository.el.get(self.repository.BOOKING_MODELS, {})
219 models['booking'] = booking
220 models['collaborators'] = []
221 for user in booking.collaborators.all():
222 models['collaborators'].append(user)
225 def make_booking_confirm(self, booking):
226 confirm = self.repository.el.get(self.repository.CONFIRMATION, {})
227 confirm['booking'] = {}
228 confirm['booking']['length'] = (booking.end - booking.start).days
229 confirm['booking']['project'] = booking.project
230 confirm['booking']['purpose'] = booking.purpose
231 confirm['booking']['resource name'] = booking.resource.template.name
232 confirm['booking']['configuration name'] = booking.config_bundle.name
233 confirm['booking']['collaborators'] = []
234 for user in booking.collaborators.all():
235 confirm['booking']['collaborators'].append(user.username)
239 class ManagerTracker():
249 if ManagerTracker.instance is None:
250 ManagerTracker.instance = ManagerTracker()
251 return ManagerTracker.instance