def post(self, execution): try: # Initialize execution context if it does not exist. if not hasattr(execution, 'context'): execution.context = dict() # Retrieve user context from the request header. user = pecan.request.headers.get('X-User-Name') if not user: user = cfg.CONF.system_user.user execution.context['user'] = user # Retrieve other st2 context from request header. if ('st2-context' in pecan.request.headers and pecan.request.headers['st2-context']): context = pecan.request.headers['st2-context'].replace("'", "\"") execution.context.update(json.loads(context)) # Schedule the action execution. executiondb = ActionExecutionAPI.to_model(execution) executiondb = action_service.schedule(executiondb) return ActionExecutionAPI.from_model(executiondb) except ValueError as e: LOG.exception('Unable to execute action.') abort(http_client.BAD_REQUEST, str(e)) except jsonschema.ValidationError as e: LOG.exception('Unable to execute action. Parameter validation failed.') abort(http_client.BAD_REQUEST, str(e)) except Exception as e: LOG.exception('Unable to execute action. Unexpected error encountered.') abort(http_client.INTERNAL_SERVER_ERROR, str(e))
def test_basic_execution(self): liveaction = LiveActionDB(action='core.local', parameters={'cmd': 'uname -a'}) liveaction, _ = action_service.schedule(liveaction) liveaction = LiveAction.get_by_id(str(liveaction.id)) self.assertEqual(liveaction.status, LIVEACTION_STATUS_FAILED) execution = self._get_action_execution(liveaction__id=str( liveaction.id), raise_exception=True) self.assertDictEqual(execution.trigger, {}) self.assertDictEqual(execution.trigger_type, {}) self.assertDictEqual(execution.trigger_instance, {}) self.assertDictEqual(execution.rule, {}) action = action_utils.get_action_by_ref('core.local') self.assertDictEqual(execution.action, vars(ActionAPI.from_model(action))) runner = RunnerType.get_by_name(action.runner_type['name']) self.assertDictEqual(execution.runner, vars(RunnerTypeAPI.from_model(runner))) liveaction = LiveAction.get_by_id(str(liveaction.id)) self.assertEqual(execution.start_timestamp, liveaction.start_timestamp) self.assertEqual(execution.end_timestamp, liveaction.end_timestamp) self.assertEqual(execution.result, liveaction.result) self.assertEqual(execution.status, liveaction.status) self.assertEqual(execution.context, liveaction.context) self.assertEqual(execution.liveaction['callback'], liveaction.callback) self.assertEqual(execution.liveaction['action'], liveaction.action)
def test_launch_workflow_with_auth(self): MistralRunner.entry_point = mock.PropertyMock(return_value=WF1_YAML_FILE_PATH) execution = LiveActionDB(action=WF1_NAME, parameters=ACTION_PARAMS, context=ACTION_CONTEXT) liveaction, _ = action_service.schedule(execution) liveaction = LiveAction.get_by_id(str(liveaction.id)) self.assertEqual(liveaction.status, LIVEACTION_STATUS_RUNNING) mistral_context = liveaction.context.get('mistral', None) self.assertIsNotNone(mistral_context) self.assertEqual(mistral_context['execution_id'], WF1_EXEC.get('id')) self.assertEqual(mistral_context['workflow_name'], WF1_EXEC.get('workflow_name')) workflow_input = copy.deepcopy(ACTION_PARAMS) workflow_input.update({'count': '3'}) env = { '__actions': { 'st2.action': { 'st2_context': { 'auth_token': TOKEN_DB.token, 'endpoint': 'http://0.0.0.0:9101/v1/actionexecutions', 'parent': str(liveaction.id) } } } } executions.ExecutionManager.create.assert_called_with( WF1_NAME, workflow_input=workflow_input, env=env)
def test_launch_workflow_with_many_workflows(self): MistralRunner.entry_point = mock.PropertyMock(return_value=WF2_YAML_FILE_PATH) execution = LiveActionDB(action=WF2_NAME, parameters=ACTION_PARAMS) liveaction, _ = action_service.schedule(execution) liveaction = LiveAction.get_by_id(str(liveaction.id)) self.assertEqual(liveaction.status, LIVEACTION_STATUS_FAILED) self.assertIn('Multiple workflows is not supported.', liveaction.result['message'])
def test_launch_workflow_mistral_offline(self): MistralRunner.entry_point = mock.PropertyMock(return_value=WF1_YAML_FILE_PATH) execution = LiveActionDB(action=WF1_NAME, parameters=ACTION_PARAMS) liveaction, _ = action_service.schedule(execution) liveaction = LiveAction.get_by_id(str(liveaction.id)) self.assertEqual(liveaction.status, LIVEACTION_STATUS_FAILED) self.assertIn('Failed to connect to mistral', liveaction.result['message'])
def test_launch_workbook_with_many_workflows_no_default(self): MistralRunner.entry_point = mock.PropertyMock(return_value=WB3_YAML_FILE_PATH) execution = LiveActionDB(action=WB3_NAME, parameters=ACTION_PARAMS) liveaction, _ = action_service.schedule(execution) liveaction = LiveAction.get_by_id(str(liveaction.id)) self.assertEqual(liveaction.status, LIVEACTION_STATUS_FAILED) self.assertIn('Default workflow cannot be determined.', liveaction.result['message'])
def test_basic_execution(self): action_ref = ResourceReference(name='local', pack='core') execution = ActionExecutionDB(action=action_ref.ref, parameters={'cmd': 'uname -a'}) execution = action_service.schedule(execution) execution = ActionExecution.get_by_id(str(execution.id)) self.assertEqual(execution.status, ACTIONEXEC_STATUS_SUCCEEDED) history = ActionExecutionHistory.get(execution__id=str(execution.id), raise_exception=True) self.assertDictEqual(history.trigger, {}) self.assertDictEqual(history.trigger_type, {}) self.assertDictEqual(history.trigger_instance, {}) self.assertDictEqual(history.rule, {}) action, _ = action_utils.get_action_by_dict({ 'name': action_ref.name, 'pack': action_ref.pack }) self.assertDictEqual(history.action, vars(ActionAPI.from_model(action))) runner = RunnerType.get_by_name(action.runner_type['name']) self.assertDictEqual(history.runner, vars(RunnerTypeAPI.from_model(runner))) execution = ActionExecution.get_by_id(str(execution.id)) self.assertDictEqual(history.execution, vars(ActionExecutionAPI.from_model(execution)))
def test_chained_executions(self): action_ref = ResourceReference(name='chain', pack='core') execution = ActionExecutionDB(action=action_ref.ref) execution = action_service.schedule(execution) execution = ActionExecution.get_by_id(str(execution.id)) self.assertEqual(execution.status, ACTIONEXEC_STATUS_SUCCEEDED) history = ActionExecutionHistory.get(execution__id=str(execution.id), raise_exception=True) action, _ = action_utils.get_action_by_dict({ 'name': action_ref.name, 'pack': action_ref.pack }) self.assertDictEqual(history.action, vars(ActionAPI.from_model(action))) runner = RunnerType.get_by_name(action.runner_type['name']) self.assertDictEqual(history.runner, vars(RunnerTypeAPI.from_model(runner))) execution = ActionExecution.get_by_id(str(execution.id)) self.assertDictEqual(history.execution, vars(ActionExecutionAPI.from_model(execution))) self.assertGreater(len(history.children), 0) for child in history.children: record = ActionExecutionHistory.get(id=child, raise_exception=True) self.assertEqual(record.parent, str(history.id)) self.assertEqual(record.action['name'], 'local') self.assertEqual(record.runner['name'], 'run-local')
def test_chained_executions(self): liveaction = LiveActionDB(action='core.chain') liveaction, _ = action_service.schedule(liveaction) liveaction = LiveAction.get_by_id(str(liveaction.id)) self.assertEqual(liveaction.status, LIVEACTION_STATUS_FAILED) execution = self._get_action_execution(liveaction__id=str( liveaction.id), raise_exception=True) action = action_utils.get_action_by_ref('core.chain') self.assertDictEqual(execution.action, vars(ActionAPI.from_model(action))) runner = RunnerType.get_by_name(action.runner_type['name']) self.assertDictEqual(execution.runner, vars(RunnerTypeAPI.from_model(runner))) liveaction = LiveAction.get_by_id(str(liveaction.id)) self.assertEqual(execution.start_timestamp, liveaction.start_timestamp) self.assertEqual(execution.end_timestamp, liveaction.end_timestamp) self.assertEqual(execution.result, liveaction.result) self.assertEqual(execution.status, liveaction.status) self.assertEqual(execution.context, liveaction.context) self.assertEqual(execution.liveaction['callback'], liveaction.callback) self.assertEqual(execution.liveaction['action'], liveaction.action) self.assertGreater(len(execution.children), 0) for child in execution.children: record = ActionExecution.get(id=child, raise_exception=True) self.assertEqual(record.parent, str(execution.id)) self.assertEqual(record.action['name'], 'local') self.assertEqual(record.runner['name'], 'run-local')
def post(self, execution): try: # Initialize execution context if it does not exist. if not hasattr(execution, 'context'): execution.context = dict() # Retrieve user context from the request header. user = pecan.request.headers.get('X-User-Name') if not user: user = cfg.CONF.system_user.user execution.context['user'] = user # Retrieve other st2 context from request header. if ('st2-context' in pecan.request.headers and pecan.request.headers['st2-context']): context = pecan.request.headers['st2-context'].replace( "'", "\"") execution.context.update(json.loads(context)) # Schedule the action execution. executiondb = ActionExecutionAPI.to_model(execution) executiondb = action_service.schedule(executiondb) return ActionExecutionAPI.from_model(executiondb) except ValueError as e: LOG.exception('Unable to execute action.') abort(http_client.BAD_REQUEST, str(e)) except jsonschema.ValidationError as e: LOG.exception( 'Unable to execute action. Parameter validation failed.') abort(http_client.BAD_REQUEST, str(e)) except Exception as e: LOG.exception( 'Unable to execute action. Unexpected error encountered.') abort(http_client.INTERNAL_SERVER_ERROR, str(e))
def test_chained_executions(self): liveaction = LiveActionDB(action='core.chain') liveaction, _ = action_service.schedule(liveaction) liveaction = LiveAction.get_by_id(str(liveaction.id)) self.assertEqual(liveaction.status, LIVEACTION_STATUS_FAILED) execution = self._get_action_execution(liveaction__id=str(liveaction.id), raise_exception=True) action = action_utils.get_action_by_ref('core.chain') self.assertDictEqual(execution.action, vars(ActionAPI.from_model(action))) runner = RunnerType.get_by_name(action.runner_type['name']) self.assertDictEqual(execution.runner, vars(RunnerTypeAPI.from_model(runner))) liveaction = LiveAction.get_by_id(str(liveaction.id)) self.assertEqual(execution.start_timestamp, liveaction.start_timestamp) self.assertEqual(execution.end_timestamp, liveaction.end_timestamp) self.assertEqual(execution.result, liveaction.result) self.assertEqual(execution.status, liveaction.status) self.assertEqual(execution.context, liveaction.context) self.assertEqual(execution.liveaction['callback'], liveaction.callback) self.assertEqual(execution.liveaction['action'], liveaction.action) self.assertGreater(len(execution.children), 0) for child in execution.children: record = ActionExecution.get(id=child, raise_exception=True) self.assertEqual(record.parent, str(execution.id)) self.assertEqual(record.action['name'], 'local') self.assertEqual(record.runner['name'], 'run-local')
def _run_action(self, action_node, parent_execution_id, params, wait_for_completion=True): liveaction = LiveActionDB(action=action_node.ref) liveaction.parameters = action_param_utils.cast_params( action_ref=action_node.ref, params=params) if action_node.notify: liveaction.notify = NotificationsHelper.to_model( action_node.notify) liveaction.context = { 'parent': str(parent_execution_id), 'chain': vars(action_node) } liveaction, _ = action_service.schedule(liveaction) while (wait_for_completion and liveaction.status != LIVEACTION_STATUS_SUCCEEDED and liveaction.status != LIVEACTION_STATUS_FAILED): eventlet.sleep(1) liveaction = action_db_util.get_liveaction_by_id(liveaction.id) return liveaction
def test_launch_workbook_name_mismatch(self): action_ref = 'generic.workbook_v2_name_mismatch' MistralRunner.entry_point = mock.PropertyMock(return_value=WB1_YAML_FILE_PATH) execution = LiveActionDB(action=action_ref, parameters=ACTION_PARAMS) liveaction, _ = action_service.schedule(execution) liveaction = LiveAction.get_by_id(str(liveaction.id)) self.assertEqual(liveaction.status, LIVEACTION_STATUS_FAILED) self.assertIn('Name of the workbook must be the same', liveaction.result['message'])
def test_launch_workflow(self): MistralRunner.entry_point = mock.PropertyMock( return_value=WORKFLOW_YAML) execution = ActionExecutionDB(action='core.workflow-v2', parameters={'friend': 'Rocky'}) execution = action_service.schedule(execution) execution = ActionExecution.get_by_id(str(execution.id)) self.assertEqual(execution.status, ACTIONEXEC_STATUS_RUNNING)
def _invoke_action(action, action_args, context=None): action_ref = action['ref'] execution = ActionExecutionDB(action=action_ref, context=context, parameters=action_args) execution = action_service.schedule(execution) return ({ 'id': str(execution.id) } if execution.status == ACTIONEXEC_STATUS_SCHEDULED else None)
def test_callback(self): execution = ActionExecutionDB( action='core.local', parameters={'cmd': 'uname -a'}, callback={'source': 'mistral', 'url': 'http://localhost:8989/v2/tasks/12345'}) execution = action_service.schedule(execution) execution = ActionExecution.get_by_id(str(execution.id)) self.assertEqual(execution.status, ACTIONEXEC_STATUS_SUCCEEDED) requests.request.assert_called_with('PUT', execution.callback['url'], data=json.dumps({'state': 'SUCCESS', 'result': '{}'}), headers={'content-type': 'application/json'})
def test_launch_when_workbook_not_exists(self): execution = LiveActionDB(action=WB1_NAME, parameters=ACTION_PARAMS) liveaction, _ = action_service.schedule(execution) liveaction = LiveAction.get_by_id(str(liveaction.id)) self.assertEqual(liveaction.status, LIVEACTION_STATUS_RUNNING) mistral_context = liveaction.context.get('mistral', None) self.assertIsNotNone(mistral_context) self.assertEqual(mistral_context['execution_id'], WB1_EXEC.get('id')) self.assertEqual(mistral_context['workflow_name'], WB1_EXEC.get('workflow_name'))
def test_launch_when_workbook_definition_changed(self): MistralRunner.entry_point = mock.PropertyMock(return_value=WB1_YAML_FILE_PATH) execution = LiveActionDB(action=WB1_NAME, parameters=ACTION_PARAMS) liveaction, _ = action_service.schedule(execution) liveaction = LiveAction.get_by_id(str(liveaction.id)) self.assertEqual(liveaction.status, LIVEACTION_STATUS_RUNNING) mistral_context = liveaction.context.get('mistral', None) self.assertIsNotNone(mistral_context) self.assertEqual(mistral_context['execution_id'], WB1_EXEC.get('id')) self.assertEqual(mistral_context['workflow_name'], WB1_EXEC.get('workflow_name'))
def _invoke_action(action, params, context=None): action_ref = action['ref'] # prior to shipping off the params cast them to the right type. params = action_param_utils.cast_params(action_ref, params) liveaction = LiveActionDB(action=action_ref, context=context, parameters=params) liveaction, _ = action_service.schedule(liveaction) return ({ 'id': str(liveaction.id) } if liveaction.status == LIVEACTION_STATUS_SCHEDULED else None)
def _run_action(action_ref, parent_execution_id, params, wait_for_completion=True): execution = ActionExecutionDB(action=action_ref) execution.parameters = ActionChainRunner._cast_params(action_ref, params) execution.context = {'parent': str(parent_execution_id)} execution = action_service.schedule(execution) while (wait_for_completion and execution.status != ACTIONEXEC_STATUS_SUCCEEDED and execution.status != ACTIONEXEC_STATUS_FAILED): eventlet.sleep(1) execution = action_db_util.get_actionexec_by_id(execution.id) return execution
def _run_action(action_ref, parent_execution_id, params, wait_for_completion=True): execution = ActionExecutionDB(action=action_ref) execution.parameters = ActionChainRunner._cast_params( action_ref, params) execution.context = {'parent': str(parent_execution_id)} execution = action_service.schedule(execution) while (wait_for_completion and execution.status != ACTIONEXEC_STATUS_SUCCEEDED and execution.status != ACTIONEXEC_STATUS_FAILED): eventlet.sleep(1) execution = action_db_util.get_actionexec_by_id(execution.id) return execution
def test_callback(self): execution = LiveActionDB( action='core.local', parameters={'cmd': 'uname -a'}, callback={ 'source': 'mistral', 'url': 'http://localhost:8989/v2/action_executions/12345' } ) liveaction, _ = action_service.schedule(execution) liveaction = LiveAction.get_by_id(str(liveaction.id)) self.assertEqual(liveaction.status, LIVEACTION_STATUS_SUCCEEDED) requests.request.assert_called_with('PUT', liveaction.callback['url'], data=json.dumps({'state': 'SUCCESS', 'output': NON_EMPTY_RESULT}), headers={'content-type': 'application/json'})
def _run_action(action_node, parent_execution_id, params, wait_for_completion=True): execution = LiveActionDB(action=action_node.ref) execution.parameters = action_param_utils.cast_params(action_ref=action_node.ref, params=params) execution.context = { 'parent': str(parent_execution_id), 'chain': vars(action_node) } liveaction, _ = action_service.schedule(execution) while (wait_for_completion and liveaction.status != LIVEACTION_STATUS_SUCCEEDED and liveaction.status != LIVEACTION_STATUS_FAILED): eventlet.sleep(1) liveaction = action_db_util.get_liveaction_by_id(liveaction.id) return liveaction
def test_schedule(self): context = {'user': USERNAME} parameters = {'hosts': 'localhost', 'cmd': 'uname -a'} request = ActionExecutionDB(action=ACTION_REF, context=context, parameters=parameters) request = action_service.schedule(request) execution = ActionExecution.get_by_id(str(request.id)) self.assertIsNotNone(execution) self.assertEqual(execution.id, request.id) action = '.'.join([self.actiondb.pack, self.actiondb.name]) actual_action = execution.action self.assertEqual(actual_action, action) self.assertEqual(execution.context['user'], request.context['user']) self.assertDictEqual(execution.parameters, request.parameters) self.assertEqual(execution.status, ACTIONEXEC_STATUS_SCHEDULED) # mongoengine DateTimeField stores datetime only up to milliseconds self.assertEqual(isotime.format(execution.start_timestamp, usec=False), isotime.format(request.start_timestamp, usec=False))
def _schedule_execution(self, action_alias_db, params, notify): try: # prior to shipping off the params cast them to the right type. params = action_param_utils.cast_params(action_ref=action_alias_db.action_ref, params=params) liveaction = LiveActionDB(action=action_alias_db.action_ref, context={}, parameters=params, notify=notify) _, action_execution_db = action_service.schedule(liveaction) return action_execution_db except ValueError as e: LOG.exception('Unable to execute action.') pecan.abort(http_client.BAD_REQUEST, str(e)) except jsonschema.ValidationError as e: LOG.exception('Unable to execute action. Parameter validation failed.') pecan.abort(http_client.BAD_REQUEST, str(e)) except Exception as e: LOG.exception('Unable to execute action. Unexpected error encountered.') pecan.abort(http_client.INTERNAL_SERVER_ERROR, str(e))
def test_basic_execution(self): action_ref = ResourceReference(name='local', pack='core') execution = ActionExecutionDB(action=action_ref.ref, parameters={'cmd': 'uname -a'}) execution = action_service.schedule(execution) execution = ActionExecution.get_by_id(str(execution.id)) self.assertEqual(execution.status, ACTIONEXEC_STATUS_SUCCEEDED) history = ActionExecutionHistory.get(execution__id=str(execution.id), raise_exception=True) self.assertDictEqual(history.trigger, {}) self.assertDictEqual(history.trigger_type, {}) self.assertDictEqual(history.trigger_instance, {}) self.assertDictEqual(history.rule, {}) action, _ = action_utils.get_action_by_dict( {'name': action_ref.name, 'pack': action_ref.pack}) self.assertDictEqual(history.action, vars(ActionAPI.from_model(action))) runner = RunnerType.get_by_name(action.runner_type['name']) self.assertDictEqual(history.runner, vars(RunnerTypeAPI.from_model(runner))) execution = ActionExecution.get_by_id(str(execution.id)) self.assertDictEqual(history.execution, vars(ActionExecutionAPI.from_model(execution)))
def _run_action(action_node, parent_execution_id, params, wait_for_completion=True): execution = LiveActionDB(action=action_node.ref) execution.parameters = action_param_utils.cast_params( action_ref=action_node.ref, params=params) execution.context = { 'parent': str(parent_execution_id), 'chain': vars(action_node) } execution, _ = action_service.schedule(execution) while (wait_for_completion and execution.status != LIVEACTION_STATUS_SUCCEEDED and execution.status != LIVEACTION_STATUS_FAILED): eventlet.sleep(1) execution = action_db_util.get_liveaction_by_id(execution.id) return execution
def _invoke_action(action, params, context=None): """ Schedule an action execution. :rtype: :class:`LiveActionDB` on successful schedueling, None otherwise. """ action_ref = action['ref'] # prior to shipping off the params cast them to the right type. params = action_param_utils.cast_params(action_ref, params) liveaction = LiveActionDB(action=action_ref, context=context, parameters=params) liveaction, _ = action_service.schedule(liveaction) if liveaction.status == LIVEACTION_STATUS_SCHEDULED: return liveaction else: return None
def test_callback(self): execution = ActionExecutionDB( action='core.local', parameters={'cmd': 'uname -a'}, callback={ 'source': 'mistral', 'url': 'http://localhost:8989/v2/tasks/12345' }) execution = action_service.schedule(execution) execution = ActionExecution.get_by_id(str(execution.id)) self.assertEqual(execution.status, ACTIONEXEC_STATUS_SUCCEEDED) requests.request.assert_called_with( 'PUT', execution.callback['url'], data=json.dumps({ 'state': 'SUCCESS', 'result': '{}' }), headers={'content-type': 'application/json'})
def post(self, execution): try: # Initialize execution context if it does not exist. if not hasattr(execution, 'context'): execution.context = dict() # Retrieve username of the authed user (note - if auth is disabled, user will not be # set so we fall back to the system user name) request_token = pecan.request.context.get('token', None) if request_token: user = request_token.user else: user = cfg.CONF.system_user.user execution.context['user'] = user # Retrieve other st2 context from request header. if ('st2-context' in pecan.request.headers and pecan.request.headers['st2-context']): context = jsonify.try_loads( pecan.request.headers['st2-context']) if not isinstance(context, dict): raise ValueError( 'Unable to convert st2-context from the headers into JSON.' ) execution.context.update(context) # Schedule the action execution. liveactiondb = LiveActionAPI.to_model(execution) _, actionexecutiondb = action_service.schedule(liveactiondb) return ActionExecutionAPI.from_model(actionexecutiondb) except ValueError as e: LOG.exception('Unable to execute action.') abort(http_client.BAD_REQUEST, str(e)) except jsonschema.ValidationError as e: LOG.exception( 'Unable to execute action. Parameter validation failed.') abort(http_client.BAD_REQUEST, str(e)) except Exception as e: LOG.exception( 'Unable to execute action. Unexpected error encountered.') abort(http_client.INTERNAL_SERVER_ERROR, str(e))
def test_chained_executions(self): action_ref = ResourceReference(name='chain', pack='core') execution = ActionExecutionDB(action=action_ref.ref) execution = action_service.schedule(execution) execution = ActionExecution.get_by_id(str(execution.id)) self.assertEqual(execution.status, ACTIONEXEC_STATUS_SUCCEEDED) history = ActionExecutionHistory.get(execution__id=str(execution.id), raise_exception=True) action, _ = action_utils.get_action_by_dict( {'name': action_ref.name, 'pack': action_ref.pack}) self.assertDictEqual(history.action, vars(ActionAPI.from_model(action))) runner = RunnerType.get_by_name(action.runner_type['name']) self.assertDictEqual(history.runner, vars(RunnerTypeAPI.from_model(runner))) execution = ActionExecution.get_by_id(str(execution.id)) self.assertDictEqual(history.execution, vars(ActionExecutionAPI.from_model(execution))) self.assertGreater(len(history.children), 0) for child in history.children: record = ActionExecutionHistory.get(id=child, raise_exception=True) self.assertEqual(record.parent, str(history.id)) self.assertEqual(record.action['name'], 'local') self.assertEqual(record.runner['name'], 'run-local')
def test_basic_execution(self): execution = ActionExecutionDB(action='core.local', parameters={'cmd': 'uname -a'}) execution = action_service.schedule(execution) execution = ActionExecution.get_by_id(str(execution.id)) self.assertEqual(execution.status, ACTIONEXEC_STATUS_FAILED) history = ActionExecutionHistory.get(execution__id=str(execution.id), raise_exception=True) self.assertDictEqual(history.trigger, {}) self.assertDictEqual(history.trigger_type, {}) self.assertDictEqual(history.trigger_instance, {}) self.assertDictEqual(history.rule, {}) action = action_utils.get_action_by_ref('core.local') self.assertDictEqual(history.action, vars(ActionAPI.from_model(action))) runner = RunnerType.get_by_name(action.runner_type['name']) self.assertDictEqual(history.runner, vars(RunnerTypeAPI.from_model(runner))) execution = ActionExecution.get_by_id(str(execution.id)) self.assertDictEqual(history.execution, vars(ActionExecutionAPI.from_model(execution)))
def test_basic_execution(self): liveaction = LiveActionDB(action='core.local', parameters={'cmd': 'uname -a'}) liveaction, _ = action_service.schedule(liveaction) liveaction = LiveAction.get_by_id(str(liveaction.id)) self.assertEqual(liveaction.status, LIVEACTION_STATUS_FAILED) execution = self._get_action_execution(liveaction__id=str(liveaction.id), raise_exception=True) self.assertDictEqual(execution.trigger, {}) self.assertDictEqual(execution.trigger_type, {}) self.assertDictEqual(execution.trigger_instance, {}) self.assertDictEqual(execution.rule, {}) action = action_utils.get_action_by_ref('core.local') self.assertDictEqual(execution.action, vars(ActionAPI.from_model(action))) runner = RunnerType.get_by_name(action.runner_type['name']) self.assertDictEqual(execution.runner, vars(RunnerTypeAPI.from_model(runner))) liveaction = LiveAction.get_by_id(str(liveaction.id)) self.assertEqual(execution.start_timestamp, liveaction.start_timestamp) self.assertEqual(execution.end_timestamp, liveaction.end_timestamp) self.assertEqual(execution.result, liveaction.result) self.assertEqual(execution.status, liveaction.status) self.assertEqual(execution.context, liveaction.context) self.assertEqual(execution.liveaction['callback'], liveaction.callback) self.assertEqual(execution.liveaction['action'], liveaction.action)
def post(self, execution): try: # Initialize execution context if it does not exist. if not hasattr(execution, 'context'): execution.context = dict() # Retrieve username of the authed user (note - if auth is disabled, user will not be # set so we fall back to the system user name) request_token = pecan.request.context.get('token', None) if request_token: user = request_token.user else: user = cfg.CONF.system_user.user execution.context['user'] = user # Retrieve other st2 context from request header. if ('st2-context' in pecan.request.headers and pecan.request.headers['st2-context']): context = jsonify.try_loads(pecan.request.headers['st2-context']) if not isinstance(context, dict): raise ValueError('Unable to convert st2-context from the headers into JSON.') execution.context.update(context) # Schedule the action execution. liveactiondb = LiveActionAPI.to_model(execution) _, actionexecutiondb = action_service.schedule(liveactiondb) return ActionExecutionAPI.from_model(actionexecutiondb) except ValueError as e: LOG.exception('Unable to execute action.') abort(http_client.BAD_REQUEST, str(e)) except jsonschema.ValidationError as e: LOG.exception('Unable to execute action. Parameter validation failed.') abort(http_client.BAD_REQUEST, str(e)) except Exception as e: LOG.exception('Unable to execute action. Unexpected error encountered.') abort(http_client.INTERNAL_SERVER_ERROR, str(e))
def test_launch_workflow_when_workbook_not_exists(self): execution = ActionExecutionDB(action='core.workflow-v2', parameters={'friend': 'Rocky'}) execution = action_service.schedule(execution) execution = ActionExecution.get_by_id(str(execution.id)) self.assertEqual(execution.status, ACTIONEXEC_STATUS_RUNNING)
def test_launch_workflow_when_definition_changed(self): MistralRunner.entry_point = mock.PropertyMock(return_value=WORKFLOW_YAML) execution = ActionExecutionDB(action='core.workflow-v2', parameters={'friend': 'Rocky'}) execution = action_service.schedule(execution) execution = ActionExecution.get_by_id(str(execution.id)) self.assertEqual(execution.status, ACTIONEXEC_STATUS_RUNNING)
def _invoke_action(action, action_args, context=None): action_ref = action['ref'] execution = ActionExecutionDB(action=action_ref, context=context, parameters=action_args) execution = action_service.schedule(execution) return ({'id': str(execution.id)} if execution.status == ACTIONEXEC_STATUS_SCHEDULED else None)