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)
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)
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
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()
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)