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.http import JsonResponse
13 from booking.models import Booking
14 from workflow.workflow_factory import WorkflowFactory
15 from workflow.models import Repository
16 from resource_inventory.models import (
17 GenericResourceBundle,
24 logger = logging.getLogger(__name__)
27 class SessionManager():
28 def active_workflow(self):
29 return self.workflows[-1]
31 def __init__(self, request=None):
34 self.owner = request.user
36 self.factory = WorkflowFactory()
38 def set_step_statuses(self, superclass_type, desired_enabled=True):
39 workflow = self.active_workflow()
40 steps = workflow.steps
42 if isinstance(step, superclass_type):
48 def add_workflow(self, workflow_type=None, target_id=None, **kwargs):
49 if target_id is not None:
50 self.prefill_repo(target_id, workflow_type)
53 if(len(self.workflows) >= 1):
54 defaults = self.workflows[-1].repository.get_child_defaults()
55 repo.set_defaults(defaults)
56 repo.el[repo.HAS_RESULT] = False
57 repo.el[repo.SESSION_USER] = self.owner
58 repo.el[repo.SESSION_MANAGER] = self
59 self.workflows.append(
60 self.factory.create_workflow(
61 workflow_type=workflow_type,
66 def pop_workflow(self):
67 multiple_wfs = len(self.workflows) > 1
69 if self.workflows[-1].repository.el[Repository.RESULT]: # move result
70 key = self.workflows[-1].repository.el[Repository.RESULT_KEY]
71 result = self.workflows[-1].repository.el[Repository.RESULT]
72 self.workflows[-2].repository.el[key] = result
74 current_repo = self.workflows[-1].repository
75 return (multiple_wfs, current_repo.el[current_repo.RESULT])
77 def status(self, request):
80 for step in self.active_workflow().steps:
81 meta_json.append(step.to_json())
83 responsejson["steps"] = meta_json
84 responsejson["active"] = self.active_workflow().repository.el['active_step']
85 responsejson["workflow_count"] = len(self.workflows)
86 return JsonResponse(responsejson, safe=False)
90 def render(self, request, **kwargs):
91 # filter out when a step needs to handle post/form data
92 # if 'workflow' in post data, this post request was meant for me, not step
93 if request.method == 'POST' and request.POST.get('workflow', None) is None:
94 return self.active_workflow().steps[self.active_workflow().active_index].post_render(request)
95 return self.active_workflow().steps[self.active_workflow().active_index].render(request)
97 def post_render(self, request):
98 return self.active_workflow().steps[self.active_workflow().active_index].post_render(request)
100 def get_active_step(self):
101 return self.active_workflow().steps[self.active_workflow().active_index]
103 def go_next(self, **kwargs):
104 # need to verify current step is valid to allow this
105 if self.get_active_step().valid < 200:
107 next_step = self.active_workflow().active_index + 1
108 if next_step >= len(self.active_workflow().steps):
109 raise Exception("Out of bounds request for step")
110 while not self.active_workflow().steps[next_step].enabled:
112 self.active_workflow().repository.el['active_step'] = next_step
113 self.active_workflow().active_index = next_step
115 def go_prev(self, **kwargs):
116 prev_step = self.active_workflow().active_index - 1
118 raise Exception("Out of bounds request for step")
119 while not self.active_workflow().steps[prev_step].enabled:
121 self.active_workflow().repository.el['active_step'] = prev_step
122 self.active_workflow().active_index = prev_step
124 def prefill_repo(self, target_id, workflow_type):
125 self.repository.el[self.repository.EDIT] = True
127 if workflow_type == 0:
128 edit_object = Booking.objects.get(pk=target_id)
129 self.prefill_booking(edit_object)
130 elif workflow_type == 1:
131 edit_object = GenericResourceBundle.objects.get(pk=target_id)
132 self.prefill_resource(edit_object)
133 elif workflow_type == 2:
134 edit_object = ConfigBundle.objects.get(pk=target_id)
135 self.prefill_config(edit_object)
137 def prefill_booking(self, booking):
138 models = self.make_booking_models(booking)
139 confirmation = self.make_booking_confirm(booking)
140 self.active_workflow().repository.el[self.active_workflow().repository.BOOKING_MODELS] = models
141 self.active_workflow().repository.el[self.active_workflow().repository.CONFIRMATION] = confirmation
142 self.active_workflow().repository.el[self.active_workflow().repository.GRESOURCE_BUNDLE_MODELS] = self.make_grb_models(booking.resource.template)
143 self.active_workflow().repository.el[self.active_workflow().repository.SELECTED_GRESOURCE_BUNDLE] = self.make_grb_models(booking.resource.template)['bundle']
144 self.active_workflow().repository.el[self.active_workflow().repository.CONFIG_MODELS] = self.make_config_models(booking.config_bundle)
146 def prefill_resource(self, resource):
147 models = self.make_grb_models(resource)
148 confirm = self.make_grb_confirm(resource)
149 self.active_workflow().repository.el[self.active_workflow().repository.GRESOURCE_BUNDLE_MODELS] = models
150 self.active_workflow().repository.el[self.active_workflow().repository.CONFIRMATION] = confirm
152 def prefill_config(self, config):
153 models = self.make_config_models(config)
154 confirm = self.make_config_confirm(config)
155 self.active_workflow().repository.el[self.active_workflow().repository.CONFIG_MODELS] = models
156 self.active_workflow().repository.el[self.active_workflow().repository.CONFIRMATION] = confirm
157 grb_models = self.make_grb_models(config.bundle)
158 self.active_workflow().repository.el[self.active_workflow().repository.GRESOURCE_BUNDLE_MODELS] = grb_models
160 def make_grb_models(self, resource):
161 models = self.active_workflow().repository.el.get(self.active_workflow().repository.GRESOURCE_BUNDLE_MODELS, {})
163 models['bundle'] = resource
164 models['interfaces'] = {}
166 for host in resource.getHosts():
167 models['hosts'].append(host)
168 models['interfaces'][host.resource.name] = []
169 models['vlans'][host.resource.name] = {}
170 for interface in host.generic_interfaces.all():
171 models['interfaces'][host.resource.name].append(interface)
172 models['vlans'][host.resource.name][interface.profile.name] = []
173 for vlan in interface.vlans.all():
174 models['vlans'][host.resource.name][interface.profile.name].append(vlan)
177 def make_grb_confirm(self, resource):
178 confirm = self.active_workflow().repository.el.get(self.active_workflow().repository.CONFIRMATION, {})
179 confirm['resource'] = {}
180 confirm['resource']['hosts'] = []
181 confirm['resource']['lab'] = resource.lab.lab_user.username
182 for host in resource.getHosts():
183 confirm['resource']['hosts'].append({"name": host.resource.name, "profile": host.profile.name})
186 def make_config_models(self, config):
187 models = self.active_workflow().repository.el.get(self.active_workflow().repository.CONFIG_MODELS, {})
188 models['bundle'] = config
189 models['host_configs'] = []
190 for host_conf in HostConfiguration.objects.filter(bundle=config):
191 models['host_configs'].append(host_conf)
192 models['opnfv'] = OPNFVConfig.objects.filter(bundle=config).last()
195 def make_config_confirm(self, config):
196 confirm = self.active_workflow().repository.el.get(self.active_workflow().repository.CONFIRMATION, {})
197 confirm['configuration'] = {}
198 confirm['configuration']['hosts'] = []
199 confirm['configuration']['name'] = config.name
200 confirm['configuration']['description'] = config.description
201 opnfv = OPNFVConfig.objects.filter(bundle=config).last()
202 confirm['configuration']['installer'] = opnfv.installer.name
203 confirm['configuration']['scenario'] = opnfv.scenario.name
204 for host_conf in HostConfiguration.objects.filter(bundle=config):
205 h = {"name": host_conf.host.resource.name, "image": host_conf.image.name, "role": host_conf.opnfvRole.name}
206 confirm['configuration']['hosts'].append(h)
209 def make_booking_models(self, booking):
210 models = self.active_workflow().repository.el.get(self.active_workflow().repository.BOOKING_MODELS, {})
211 models['booking'] = booking
212 models['collaborators'] = []
213 for user in booking.collaborators.all():
214 models['collaborators'].append(user)
217 def make_booking_confirm(self, booking):
218 confirm = self.active_workflow().repository.el.get(self.active_workflow().repository.CONFIRMATION, {})
219 confirm['booking'] = {}
220 confirm['booking']['length'] = (booking.end - booking.start).days
221 confirm['booking']['project'] = booking.project
222 confirm['booking']['purpose'] = booking.purpose
223 confirm['booking']['resource name'] = booking.resource.template.name
224 confirm['booking']['configuration name'] = booking.config_bundle.name
225 confirm['booking']['collaborators'] = []
226 for user in booking.collaborators.all():
227 confirm['booking']['collaborators'].append(user.username)
231 class ManagerTracker():
241 if ManagerTracker.instance is None:
242 ManagerTracker.instance = ManagerTracker()
243 return ManagerTracker.instance