def convert(self, mistral_wf, expr_type=None, force=False): variables_used_in_output = set() expr_converter = self.expr_type_converter(expr_type) orquesta_wf = ruamel.yaml.comments.CommentedMap() orquesta_wf['version'] = '1.0' if force: for attr in WORKFLOW_UNSUPPORTED_ATTRIBUTES: val = mistral_wf.get(attr) if val: orquesta_wf[attr] = val else: for attr in WORKFLOW_UNSUPPORTED_ATTRIBUTES: if attr in mistral_wf: raise NotImplementedError(("Workflow contains an attribute '{}' that is not" " supported in orquesta.").format(attr)) if mistral_wf.get('description'): orquesta_wf['description'] = mistral_wf['description'] if mistral_wf.get('type'): if mistral_wf['type'] not in WORKFLOW_TYPES: raise NotImplementedError(("Workflows of type '{}' are NOT supported." " Only 'direct' workflows can be converted"). format(mistral_wf['type'])) if mistral_wf.get('input'): orquesta_wf['input'] = ExpressionConverter.convert_list(mistral_wf['input']) if mistral_wf.get('vars'): expression_vars = ExpressionConverter.convert_dict(mistral_wf['vars']) orquesta_wf['vars'] = self.dict_to_list(expression_vars) if mistral_wf.get('output'): output = ExpressionConverter.convert_dict(mistral_wf['output']) orquesta_wf['output'] = self.dict_to_list(output) variables_used_in_output = self.extract_context_variables(output) if mistral_wf.get('tasks'): o_tasks = self.convert_tasks( mistral_wf['tasks'], expr_converter, variables_used_in_output, force=force) if o_tasks: orquesta_wf['tasks'] = o_tasks return orquesta_wf
def convert_task_transition_simple(self, transitions, publish, orquesta_expr, expr_converter): # if this is a simple name of a task: # on-success: # - do_thing_a # - do_thing_b # # this should produce the following in orquesta # next: # - when: "{{ succeeded() }}" # do: # - do_thing_a # - do_thing_b simple_transition = ruamel.yaml.comments.CommentedMap() # on-complete doesn't have an orquesta_expr, so we should not # add the 'when' clause in that case if orquesta_expr: simple_transition['when'] = expr_converter.wrap_expression(orquesta_expr) # add in published variables if publish: publish_converted = ExpressionConverter.convert_dict(publish) simple_transition['publish'] = self.dict_to_list(publish_converted) # add in the transition list if transitions: simple_transition['do'] = transitions return simple_transition
def convert_tasks(self, mistral_wf_tasks, expr_converter, force=False): orquesta_wf_tasks = ruamel.yaml.comments.CommentedMap() for task_name, m_task_spec in six.iteritems(mistral_wf_tasks): o_task_spec = ruamel.yaml.comments.CommentedMap() if force: for attr in TASK_UNSUPPORTED_ATTRIBUTES: val = m_task_spec.get(attr) if val: o_task_spec[attr] = val else: for attr in TASK_UNSUPPORTED_ATTRIBUTES: if attr in m_task_spec: raise NotImplementedError( ("Task '{}' contains an attribute '{}'" " that is not supported in orquesta.").format( task_name, attr)) if m_task_spec.get('action'): o_task_spec['action'] = m_task_spec['action'] if m_task_spec.get('join'): o_task_spec['join'] = m_task_spec['join'] if m_task_spec.get('input'): o_task_spec['input'] = ExpressionConverter.convert_dict( m_task_spec['input']) o_task_transitions = self.convert_task_transitions( m_task_spec, expr_converter) o_task_spec.update(o_task_transitions) orquesta_wf_tasks[task_utils.translate_task_name( task_name)] = o_task_spec return orquesta_wf_tasks
def test_convert_dict(self): expr = { "jinja_str": "{{ _.test_jinja }}", "yaql_str": "<% $.test_yaql %>", } result = ExpressionConverter.convert_dict(expr) self.assertEqual( result, { "jinja_str": "{{ ctx().test_jinja }}", "yaql_str": "<% ctx().test_yaql %>", })
def test_convert_dict_nested_list(self): expr = { "expr_list": [ "{{ _.a }}", "<% $.a %>", ] } result = ExpressionConverter.convert_dict(expr) self.assertEqual(result, {"expr_list": [ "{{ ctx().a }}", "<% ctx().a %>", ]})
def test_convert_dict_nested_dict(self): expr = { "expr_dict": { "nested_jinja": "{{ _.a }}", "nested_yaql": "<% $.a %>", } } result = ExpressionConverter.convert_dict(expr) self.assertEqual( result, { "expr_dict": { "nested_jinja": "{{ ctx().a }}", "nested_yaql": "<% ctx().a %>", } })
def convert_task_transition_expr(self, task_name, expression_list, publish, orquesta_expr): # group all complex expressions by their common expression # this way we can keep all of the transitions with the same # expressions in the same `when:` condition # # on-success: # - do_thing_a: "{{ _.x }}" # - do_thing_b: "{{ _.x }}" # - do_thing_c: "{{ not _.x }}" # # should produce the following in orquesta # # next: # - when: "{{ succeeded() and _.x }}" # do: # - do_thing_a # - do_thing_b # - when: "{{ succeeded() and not _.x }}" # do: # - do_thing_c transitions = [] for expr, task_list in six.iteritems(expression_list): expr_transition = ruamel.yaml.comments.CommentedMap() expr_converted = ExpressionConverter.convert(expr) # for some transitions (on-complete) the orquesta_expr may be empty # so only add it in, if it's necessary if orquesta_expr: converter = ExpressionConverter.get_converter(expr_converted) expr_converted = converter.unwrap_expression(expr_converted) o_expr = '{} and ({})'.format(orquesta_expr, expr_converted) o_expr = converter.wrap_expression(o_expr) else: o_expr = expr_converted expr_transition['when'] = o_expr if publish: converted_publish = ExpressionConverter.convert_dict(publish) expr_transition['publish'] = [{k: v} for k, v in converted_publish.items()] expr_transition['when'] = self.replace_immediately_referenced_variables(task_name, expr_transition['when'], converted_publish) expr_transition['do'] = task_list transitions.append(expr_transition) return transitions