Implement Segmented Workflows
[pharos-tools.git] / dashboard / src / workflow / workflow_factory.py
1 ##############################################################################
2 # Copyright (c) 2018 Sawyer Bergeron, Parker Berberian, and others.
3 #
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 ##############################################################################
9
10
11 from workflow.booking_workflow import Booking_Resource_Select, SWConfig_Select, Booking_Meta
12 from workflow.resource_bundle_workflow import Define_Hardware, Define_Nets, Resource_Meta_Info
13 from workflow.sw_bundle_workflow import Config_Software, Define_Software, SWConf_Resource_Select
14 from workflow.snapshot_workflow import Select_Host_Step, Image_Meta_Step
15 from workflow.models import Repository, Confirmation_Step
16
17 import uuid
18
19 import logging
20 logger = logging.getLogger(__name__)
21
22
23 class BookingMetaWorkflow(object):
24     workflow_type = 0
25     color = "#0099ff"
26     is_child = False
27
28
29 class ResourceMetaWorkflow(object):
30     workflow_type = 1
31     color = "#ff6600"
32
33
34 class ConfigMetaWorkflow(object):
35     workflow_type = 2
36     color = "#00ffcc"
37
38 class MetaStep(object):
39
40     UNTOUCHED = 0
41     INVALID = 100
42     VALID = 200
43
44     def set_invalid(self, message, code=100):
45         self.valid = code
46         self.message = message
47
48     def set_valid(self, message, code=200):
49         self.valid = code
50         self.message = message
51
52     def __init__(self, *args, **kwargs):
53         self.short_title = "error"
54         self.skip_step = 0
55         self.valid = 0
56         self.message = ""
57         self.id = uuid.uuid4()
58
59     def to_json(self):
60         return {
61             'title': self.short_title,
62             'skip': self.skip_step,
63             'valid': self.valid,
64             'message': self.message,
65         }
66
67     def __str__(self):
68         return "metastep: " + str(self.short_title)
69
70     def __hash__(self):
71         return hash(self.id)
72
73     def __eq__(self, other):
74         return self.id.int == other.id.int
75
76     def __ne__(self, other):
77         return self.id.int != other.id.int
78
79 class Workflow(object):
80     def __init__(self, steps, metasteps, repository):
81         self.repository = repository
82         self.steps = steps
83         self.metasteps = metasteps
84         self.active_index = 0
85
86 class WorkflowFactory():
87     booking_steps = [
88         Booking_Resource_Select,
89         SWConfig_Select,
90         Booking_Meta,
91     ]
92
93     resource_steps = [
94         Define_Hardware,
95         Define_Nets,
96         Resource_Meta_Info,
97     ]
98
99     config_steps = [
100         SWConf_Resource_Select,
101         Define_Software,
102         Config_Software,
103     ]
104
105     snapshot_steps = [
106         Select_Host_Step,
107         Image_Meta_Step,
108     ]
109
110     def conjure(self, workflow_type=None, repo=None):
111         workflow_types = [
112             self.booking_steps,
113             self.resource_steps,
114             self.config_steps,
115             self.snapshot_steps,
116         ]
117
118         steps = self.make_steps(workflow_types[workflow_type], repository=repo)
119         meta_steps = self.metaize(steps=steps, wf_type=workflow_type)
120         return steps, meta_steps
121
122     def create_workflow(self, workflow_type=None, repo=None):
123         steps, meta_steps = self.conjure(workflow_type, repo)
124         c_step = self.make_step(Confirmation_Step, repo)
125         metaconfirm = MetaStep()
126         metaconfirm.short_title = "confirm"
127         metaconfirm.index = len(steps)
128         steps.append(c_step)
129         meta_steps.append(metaconfirm)
130         return Workflow(steps, meta_steps, repo)
131
132     def make_steps(self, step_types, repository):
133         steps = []
134         for step_type in step_types:
135             steps.append(self.make_step(step_type, repository))
136
137         return steps
138
139     def make_step(self, step_type, repository):
140         iden = step_type.description + step_type.title + step_type.template
141         return step_type(iden, repository)
142
143     def metaize(self, steps, wf_type):
144         meta_dict = []
145         for step in steps:
146             meta_step = MetaStep()
147             meta_step.short_title = step.short_title
148             meta_dict.append(meta_step)
149             step.metastep = meta_step
150
151         return meta_dict