Ejemplo n.º 1
0
    def test_deploy_orchestration_stop_on_error(self, mock_run):
        mock_run.side_effect = [('', '', 0),
                                ('', '', 0),
                                ('err', '', 1),
                                ('', '', 0),
                                ('', '', 0),
                                ('', '', 0),
                                ('', '', 0),
                                ('', '', 0),
                                ('', '', 0)]

        o = Orchestration.query.get('bbbbbbbb-1234-5678-1234-bbbbbbbb0001')

        deploy_orchestration(o, var_context=self.vs,
                             hosts={'all': [self.s1.id, self.s2.id], 'frontend': [self.s1.id], 'backend': [self.s2.id]})

        self.assertEqual(1, OrchExecution.query.count())
        oe = OrchExecution.query.one()
        self.assertFalse(oe.success)
        self.assertTrue(oe.undo_success)

        self.assertEqual(8, StepExecution.query.count())

        e = StepExecution.query.filter_by(step_id='dddddddd-1234-5678-1234-dddddddd0001').one()
        self.assertTrue(e.success)

        e = StepExecution.query.filter_by(step_id='dddddddd-1234-5678-1234-dddddddd0003').one()
        self.assertFalse(e.success)

        ue4 = StepExecution.query.filter_by(step_id='dddddddd-1234-5678-1234-dddddddd0004').one()
        self.assertTrue(ue4.success)

        ue5 = StepExecution.query.filter_by(step_id='dddddddd-1234-5678-1234-dddddddd0005').one()
        self.assertTrue(ue5.success)
        self.assertGreater(ue5.start_time, ue4.start_time)

        ue6 = StepExecution.query.filter_by(step_id='dddddddd-1234-5678-1234-dddddddd0006').one()
        self.assertTrue(ue6.success)
        self.assertGreater(ue6.start_time, ue5.start_time)

        ue = StepExecution.query.filter_by(step_id='dddddddd-1234-5678-1234-dddddddd0002').filter_by(
            server_id=self.s1.id).one()
        self.assertTrue(ue.success)

        e = StepExecution.query.filter_by(step_id='dddddddd-1234-5678-1234-dddddddd0009').one()
        self.assertTrue(e.success)

        ue = StepExecution.query.filter_by(step_id='dddddddd-1234-5678-1234-dddddddd0002').filter_by(
            server_id=self.s2.id).one()
        self.assertTrue(ue.success)

        with self.app2.app_context():
            self.assertEqual(2, StepExecution.query.count())

            e = StepExecution.query.filter_by(step_id='dddddddd-1234-5678-1234-dddddddd0009').one()
            self.assertTrue(e.success)

            ue = StepExecution.query.filter_by(step_id='dddddddd-1234-5678-1234-dddddddd0002').one()
            self.assertTrue(ue.success)
Ejemplo n.º 2
0
    def test_deploy_orchestration_undo_on_error_false(self, mock_run):
        mock_run.side_effect = [('', '', 0),
                                ('', '', 0),
                                ('', '', 0),
                                ('', '', 0),
                                ('err', '', 1)]

        o = Orchestration.query.get('bbbbbbbb-1234-5678-1234-bbbbbbbb0001')
        o.undo_on_error = False
        deploy_orchestration(o, var_context=self.vs,
                             hosts={'all': [self.s1.id, self.s2.id], 'frontend': [self.s1.id], 'backend': [self.s2.id]})

        self.assertEqual(5, StepExecution.query.count())

        e = StepExecution.query.filter_by(step_id='dddddddd-1234-5678-1234-dddddddd0001').one()
        self.assertTrue(e.success)

        e = StepExecution.query.filter_by(step_id='dddddddd-1234-5678-1234-dddddddd0003').one()
        self.assertTrue(e.success)

        e = StepExecution.query.filter_by(step_id='dddddddd-1234-5678-1234-dddddddd0007').filter_by(
            server_id=self.s1.id).one()
        self.assertTrue(e.success)

        e = StepExecution.query.filter_by(step_id='dddddddd-1234-5678-1234-dddddddd0009').filter_by(
            server_id=self.s2.id).one()
        self.assertTrue(e.success)

        e = StepExecution.query.filter_by(step_id='dddddddd-1234-5678-1234-dddddddd0007').filter_by(
            server_id=self.s2.id).one()
        self.assertFalse(e.success)

        with self.app2.app_context():
            self.assertEqual(2, StepExecution.query.count())

            e = StepExecution.query.filter_by(step_id='dddddddd-1234-5678-1234-dddddddd0009').one()
            self.assertTrue(e.success)

            e = StepExecution.query.filter_by(step_id='dddddddd-1234-5678-1234-dddddddd0007').one()
            self.assertFalse(e.success)
Ejemplo n.º 3
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
Ejemplo n.º 4
0
    def _execute(self,
                 params: Kwargs,
                 timeout=None,
                 context: Context = None) -> CompletedProcess:
        from dimensigon.use_cases.deployment import deploy_orchestration
        input_params = params['input']
        cp = CompletedProcess().set_start_time()
        # Validation
        orchestration = Orchestration.get(
            input_params.pop('orchestration', None),
            input_params.pop('version', None))
        if not isinstance(orchestration, Orchestration):
            cp.stderr = orchestration
            cp.success = False
            return cp.set_end_time()

        hosts = input_params.pop('hosts', None)
        if hosts is None:
            cp.stderr = "No hosts specified"
            cp.success = False
            return cp.set_end_time()
        hosts = copy.deepcopy(hosts)
        if isinstance(hosts, list):
            hosts = {'all': hosts}
        elif isinstance(hosts, str):
            hosts = {'all': [hosts]}
        not_found = normalize_hosts(hosts)
        if not_found:
            cp.stderr = str(errors.ServerNormalizationError(not_found))
            cp.success = False
            return cp.set_end_time()

        o_exe = OrchExecution(
            orchestration_id=orchestration.id,
            target=hosts,
            params=input_params,
            executor_id=context.env.get('executor_id'),
            server_id=context.env.get('server_id'),
            parent_step_execution_id=context.env.get('step_execution_id'))
        db.session.add(o_exe)
        se = StepExecution.query.get(context.env.get('step_execution_id'))
        if se:
            se.child_orch_execution_id = o_exe.id
        db.session.commit()

        cp.stdout = f"orch_execution_id={o_exe.id}"

        env = dict(context.env)
        env.update(
            root_orch_execution_id=context.env['root_orch_execution_id'],
            orch_execution_id=o_exe.id,
            executor_id=context.env['executor_id'])
        ctx = Context(input_params, env, vault=context.vault)
        try:
            deploy_orchestration(orchestration=orchestration,
                                 hosts=hosts,
                                 var_context=ctx,
                                 execution=o_exe,
                                 timeout=timeout)
        except Exception as e:
            cp.stderr = str(e) if str(e) else e.__class__.__name__
            cp.success = False
        else:
            context.merge_ctx(ctx)
            db.session.refresh(o_exe)
            cp.success = o_exe.success
        return cp.set_end_time()
Ejemplo n.º 5
0
    def test_deploy_orchestration(self, mock_run):
        mock_run.side_effect = [('', '', 0),
                                ('', '', 0),
                                ('', '', 0),
                                ('', '', 0),
                                ('', '', 0)]

        g.server = self.s1
        o = Orchestration.query.get('bbbbbbbb-1234-5678-1234-bbbbbbbb0001')

        deploy_orchestration(o.id, var_context=self.vs,
                             hosts={'all': [self.s1.id, self.s2.id], 'frontend': [self.s1.id], 'backend': [self.s2.id]})

        self.assertEqual(1, OrchExecution.query.count())
        oe = OrchExecution.query.one()
        orch_execution_id = oe.id
        self.assertTrue(oe.success)
        self.assertEqual(o, oe.orchestration)
        self.assertDictEqual(
            {'all': [str(self.s1.id), str(self.s2.id)], 'frontend': [str(self.s1.id)], 'backend': [str(self.s2.id)]},
            oe.target)
        self.assertDictEqual(dict(self.vs), oe.params)
        self.assertEqual(User.get_by_name('root'), oe.executor)
        self.assertIsNone(oe.service)
        self.assertTrue(oe.success)
        self.assertIsNone(oe.undo_success)

        self.assertEqual(5, StepExecution.query.count())

        e = StepExecution.query.filter_by(step_id='dddddddd-1234-5678-1234-dddddddd0001').filter_by(
            server_id=self.s1.id).one()
        self.assertTrue(e.success)

        e = StepExecution.query.filter_by(step_id='dddddddd-1234-5678-1234-dddddddd0003').filter_by(
            server_id=self.s1.id).one()
        self.assertTrue(e.success)

        e = StepExecution.query.filter_by(step_id='dddddddd-1234-5678-1234-dddddddd0007').filter_by(
            server_id=self.s1.id).one()
        self.assertTrue(e.success)

        e = StepExecution.query.filter_by(step_id='dddddddd-1234-5678-1234-dddddddd0009').filter_by(
            server_id=self.s2.id).one()
        self.assertTrue(e.success)

        e = StepExecution.query.filter_by(step_id='dddddddd-1234-5678-1234-dddddddd0007').filter_by(
            server_id=self.s2.id).one()
        self.assertTrue(e.success)

        with self.app2.app_context():
            self.assertEqual(1, OrchExecution.query.count())
            oe = OrchExecution.query.one()
            self.assertEqual(orch_execution_id, oe.id)
            self.assertEqual(o.id, oe.orchestration.id)
            self.assertDictEqual(
                {'all': [str(self.s1.id), str(self.s2.id)], 'frontend': [str(self.s1.id)],
                 'backend': [str(self.s2.id)]}, oe.target)
            self.assertDictEqual(dict(self.vs), oe.params)
            self.assertEqual(User.get_by_name('root'), oe.executor)
            self.assertIsNone(oe.service)
            # self.assertTrue(oe.success)
            # self.assertIsNone(oe.undo_success)

            self.assertEqual(2, StepExecution.query.count())

            e = StepExecution.query.filter_by(step_id='dddddddd-1234-5678-1234-dddddddd0009').one()
            self.assertTrue(e.success)

            e = StepExecution.query.filter_by(step_id='dddddddd-1234-5678-1234-dddddddd0007').one()
            self.assertTrue(e.success)