Esempio n. 1
0
    def test_validate_input_chain_mapping_action_template(self):
        o = Orchestration("test", 1)
        at = ActionTemplate("action",
                            1,
                            action_type=ActionType.SHELL,
                            code='',
                            schema={
                                'input': {
                                    'param1': {}
                                },
                                'required': ['param1']
                            })

        s1 = o.add_step(undo=False,
                        action_template=at,
                        schema={'mapping': {
                            'param1': "value"
                        }})
        s2 = o.add_step(undo=False,
                        action_type=ActionType.SHELL,
                        schema={
                            'input': {
                                'param2': {}
                            },
                            'required': ['param2']
                        })

        validate_input_chain(o, params=dict(input={'param2'}))

        with self.assertRaises(errors.MissingParameters) as e:
            validate_input_chain(o, params=dict(input={'param1'}))

        self.assertEqual(['input.param2'], e.exception.parameters)
Esempio n. 2
0
    def test_validate_input_chain(self):
        o = Orchestration("test", 1)
        s1 = o.add_step(undo=False,
                        schema={
                            'input': {
                                'param1': {}
                            },
                            'required': ['param1'],
                            'output': {
                                'param2': {}
                            }
                        },
                        action_type=ActionType.SHELL,
                        code='')
        s2 = o.add_step(undo=False,
                        parents=[s1],
                        schema={
                            'input': {
                                'param3': {},
                                'param4': {}
                            },
                            'required': ['param3', 'param4'],
                            'mapping': {
                                'param3': {
                                    'from': 'param2'
                                }
                            }
                        },
                        action_type=ActionType.SHELL,
                        code='')
        s3 = o.add_step(undo=False,
                        parents=[s2],
                        schema={
                            'input': {
                                'param2': {},
                                'param5': {}
                            },
                            'required': ['param2']
                        },
                        action_type=ActionType.SHELL,
                        code='')

        validate_input_chain(o, params=dict(input={'param1', 'param4'}))

        with self.assertRaises(errors.MissingParameters) as e:
            validate_input_chain(o, params=dict(input={'param1'}))

        self.assertEqual(['input.param4'], e.exception.parameters)
Esempio n. 3
0
    def test_validate_input_chain_vault_container(self):
        o = Orchestration("test", 1)
        at1 = ActionTemplate("action1",
                             1,
                             action_type=ActionType.SHELL,
                             code='',
                             schema={
                                 'input': {
                                     'vault.var': {}
                                 },
                                 'required': ['vault.var']
                             })

        s1 = o.add_step(undo=False, action_template=at1, schema={})

        validate_input_chain(o, params=dict(vault={'var'}))

        with self.assertRaises(errors.MissingParameters) as e:
            validate_input_chain(o, params=dict())

        self.assertEqual(['vault.var'], e.exception.parameters)
Esempio n. 4
0
    def test_validate_input_chain_mapping_default_value(self):
        o = Orchestration("test", 1)
        at1 = ActionTemplate("action1",
                             1,
                             action_type=ActionType.SHELL,
                             code='',
                             schema={
                                 'input': {
                                     'input1': {},
                                     'input2': {
                                         'default': 1
                                     }
                                 },
                                 'required': ['input1'],
                                 'output': ['out1', 'out2']
                             })
        at2 = ActionTemplate("action2",
                             1,
                             action_type=ActionType.SHELL,
                             code='',
                             schema={
                                 'input': {
                                     'out1': {},
                                     'out2': {},
                                     'input2': {}
                                 },
                                 'required': ['out1', 'out2', 'input2'],
                                 'output': []
                             })

        s1 = o.add_step(undo=False, action_template=at1, schema={})
        s2 = o.add_step(undo=False,
                        action_template=at2,
                        schema={},
                        parents=[s1])

        with self.assertRaises(errors.MissingParameters) as e:
            validate_input_chain(o, params=dict(input={'input1'}))

        self.assertEqual(['input.input2'], e.exception.parameters)
Esempio n. 5
0
def launch_orchestration(orchestration_id):
    data = request.get_json()
    if orchestration_id:
        orchestration = Orchestration.query.get_or_raise(orchestration_id)
    else:
        iden = (data.get('orchestration'), )
        columns = ('orchestration', )
        query = Orchestration.query.filter_by(name=data.get('orchestration'))
        if 'version' in data:
            iden += (data.get('version'), )
            columns += ('version', )
            query = query.filter_by(version=data.get('version'))
        query = query.order_by(Orchestration.version.desc())
        if query.count() <= 1:
            orchestration = query.one_or_none()
        else:
            orchestration = query.first()
        if not orchestration:
            raise errors.EntityNotFound('Orchestration', iden, columns)

    if not orchestration.steps:
        return errors.GenericError(
            'orchestration does not have steps to execute',
            orchestration_id=orchestration_id)

    params = data.get('params') or {}
    hosts = data.get('hosts', Server.get_current().id)

    a = set(orchestration.target)
    if not isinstance(hosts, dict):
        hosts = dict(all=hosts)
    b = set(hosts.keys())
    c = a - b
    if len(c) > 0:
        raise errors.TargetUnspecified(c)
    c = b - a
    if len(c) > 0:
        raise errors.TargetNotNeeded(c)

    not_found = normalize_hosts(hosts)
    if not_found:
        raise errors.ServerNormalizationError(not_found)

    for target, target_hosts in hosts.items():
        if len(target_hosts) == 0:
            raise errors.EmptyTarget(target)
    # check param entries
    # rest = orchestration.user_parameters - set(params.keys())
    # if rest:
    #     rest = list(rest)
    #     rest.sort()
    #     return {'error': f"Parameter(s) not specified: {', '.join(rest)}"}, 404

    execution_id = str(uuid.uuid4())

    executor_id = get_jwt_identity()
    vc = Context(params,
                 dict(execution_id=None,
                      root_orch_execution_id=execution_id,
                      orch_execution_id=execution_id,
                      executor_id=executor_id),
                 vault=Vault.get_variables_from(executor_id,
                                                scope=data.get(
                                                    'scope', 'global')))

    if not data.get('skip_validation', False):
        validate_input_chain(
            orchestration, {
                'input': set(params.keys()),
                'env': set(vc.env.keys()),
                'vault': set(vc.vault.keys())
            })

    if request.get_json().get('background', True):
        future = executor.submit(deploy_orchestration,
                                 orchestration=orchestration.id,
                                 var_context=vc,
                                 hosts=hosts,
                                 timeout=data.get('timeout', None))
        try:
            future.result(5)
        except concurrent.futures.TimeoutError:
            return {'execution_id': execution_id}, 202
        except Exception as e:
            current_app.logger.exception(
                f"Exception got when executing orchestration {orchestration}")
            raise
    else:
        try:
            deploy_orchestration(orchestration=orchestration,
                                 var_context=vc,
                                 hosts=hosts,
                                 timeout=data.get('timeout', None))
        except Exception as e:
            current_app.logger.exception(
                f"Exception got when executing orchestration {orchestration}")
            raise
    return OrchExecution.query.get(execution_id).to_json(
        add_step_exec=True,
        human=check_param_in_uri('human'),
        split_lines=True), 200
Esempio n. 6
0
    def test_validate_input_chain_mapping_with_orch(self):
        o = Orchestration('Schema Orch',
                          1,
                          id='00000000-0000-0000-0000-000000000001')
        s1 = o.add_step(id=1,
                        action_type=ActionType.SHELL,
                        undo=False,
                        schema={
                            'input': {
                                '1_a': {},
                                '1_b': {}
                            },
                            'required': ['1_b'],
                            'output': ['1_c']
                        })
        s2 = o.add_step(undo=False,
                        action_type=ActionType.SHELL,
                        schema={
                            'input': {
                                '2_a': {}
                            },
                            'required': ['2_a'],
                            'output': ['2_b']
                        })

        s3 = o.add_step(undo=False,
                        action_type=ActionType.SHELL,
                        parents=[s1],
                        schema={
                            'input': {
                                '3_a': {},
                                '3_b': {}
                            },
                            'required': ['3_a'],
                            'mapping': {
                                '3_a': {
                                    'from': '2_b'
                                }
                            }
                        })

        db.session.add(o)
        o2 = Orchestration('Schema Orch', 1)
        at = ActionTemplate.query.filter_by(name='orchestration',
                                            version=1).one()
        s1 = o2.add_step(id=1,
                         action_template=at,
                         undo=False,
                         schema={'mapping': {
                             'orchestration': o.id
                         }})
        s2 = o2.add_step(undo=False,
                         action_type=1,
                         parents=[s1],
                         schema={
                             'input': {
                                 "1": {},
                                 "2": {}
                             },
                             'required': ["1"],
                             'mapping': {
                                 "1": {
                                     'from': '1_c'
                                 }
                             }
                         })

        validate_input_chain(o2, params=dict(input={'hosts', '1_b', '2_a'}))