def _schedule_execution(self, action_alias_db, params, notify, context, requester_user, show_secrets): action_ref = action_alias_db.action_ref action_db = action_utils.get_action_by_ref(action_ref) if not action_db: raise StackStormDBObjectNotFoundError('Action with ref "%s" not found ' % (action_ref)) assert_user_has_resource_db_permission(user_db=requester_user, resource_db=action_db, permission_type=PermissionType.ACTION_EXECUTE) 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, cast_overrides=CAST_OVERRIDES) if not context: context = { 'action_alias_ref': reference.get_ref_from_model(action_alias_db), 'user': get_system_username() } liveaction = LiveActionDB(action=action_alias_db.action_ref, context=context, parameters=params, notify=notify) _, action_execution_db = action_service.request(liveaction) mask_secrets = self._get_mask_secrets(requester_user, show_secrets=show_secrets) return ActionExecutionAPI.from_model(action_execution_db, mask_secrets=mask_secrets) 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 _schedule_execution(self, liveaction): # Initialize execution context if it does not exist. if not hasattr(liveaction, 'context'): liveaction.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 liveaction.context['user'] = user LOG.debug('User is: %s' % 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.' ) liveaction.context.update(context) # Schedule the action execution. liveactiondb = LiveActionAPI.to_model(liveaction) _, actionexecutiondb = action_service.request(liveactiondb) from_model_kwargs = self._get_from_model_kwargs_for_request( request=pecan.request) return ActionExecutionAPI.from_model(actionexecutiondb, from_model_kwargs)
def _schedule_execution(self, execution): # 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.request(liveactiondb) return ActionExecutionAPI.from_model(actionexecutiondb)
def _schedule_execution(self, action_alias_db, params, notify, context): action_ref = action_alias_db.action_ref action_db = action_utils.get_action_by_ref(action_ref) if not action_db: raise StackStormDBObjectNotFoundError('Action with ref "%s" not found ' % (action_ref)) assert_request_user_has_resource_db_permission(request=pecan.request, resource_db=action_db, permission_type=PermissionType.ACTION_EXECUTE) 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, cast_overrides=CAST_OVERRIDES) if not context: context = { 'action_alias_ref': reference.get_ref_from_model(action_alias_db), 'user': get_system_username() } liveaction = LiveActionDB(action=action_alias_db.action_ref, context=context, parameters=params, notify=notify) _, action_execution_db = action_service.request(liveaction) return ActionExecutionAPI.from_model(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 _schedule_execution(self, liveaction): # Initialize execution context if it does not exist. if not hasattr(liveaction, 'context'): liveaction.context = dict() liveaction.context['user'] = get_requester() LOG.debug('User is: %s' % liveaction.context['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.') liveaction.context.update(context) # Schedule the action execution. liveaction_db = LiveActionAPI.to_model(liveaction) liveaction_db, actionexecution_db = action_service.create_request(liveaction_db) action_db = action_utils.get_action_by_ref(liveaction_db.action) runnertype_db = action_utils.get_runnertype_by_name(action_db.runner_type['name']) try: liveaction_db.parameters = param_utils.render_live_params( runnertype_db.runner_parameters, action_db.parameters, liveaction_db.parameters, liveaction_db.context) except ParamException as e: raise ValueValidationException(str(e)) liveaction_db = LiveAction.add_or_update(liveaction_db, publish=False) _, actionexecution_db = action_service.publish_request(liveaction_db, actionexecution_db) from_model_kwargs = self._get_from_model_kwargs_for_request(request=pecan.request) return ActionExecutionAPI.from_model(actionexecution_db, from_model_kwargs)
def process(self, execution): LOG.debug('Got execution from queue: %s', execution) if execution.status not in COMPLETION_STATUSES: return execution_api = ActionExecutionAPI.from_model(execution, mask_secrets=True) self.pending_executions.put_nowait(execution_api) LOG.debug("Added execution to queue.")
def _schedule_execution(self, liveaction): # Initialize execution context if it does not exist. if not hasattr(liveaction, "context"): liveaction.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 liveaction.context["user"] = user LOG.debug("User is: %s" % 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.") liveaction.context.update(context) # Schedule the action execution. liveactiondb = LiveActionAPI.to_model(liveaction) _, actionexecutiondb = action_service.request(liveactiondb) from_model_kwargs = self._get_from_model_kwargs_for_request(request=pecan.request) return ActionExecutionAPI.from_model(actionexecutiondb, from_model_kwargs)
def _schedule_execution(self, liveaction): # Initialize execution context if it does not exist. if not hasattr(liveaction, 'context'): liveaction.context = dict() liveaction.context['user'] = self._get_requester() LOG.debug('User is: %s' % liveaction.context['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.' ) liveaction.context.update(context) # Schedule the action execution. liveactiondb = LiveActionAPI.to_model(liveaction) _, actionexecutiondb = action_service.request(liveactiondb) from_model_kwargs = self._get_from_model_kwargs_for_request( request=pecan.request) return ActionExecutionAPI.from_model(actionexecutiondb, from_model_kwargs)
def delete(self, id, requester_user, **kwargs): """ Stops a single execution. Handles requests: DELETE /executions/<id> """ if not requester_user: requester_user = UserDB(cfg.CONF.system_user.user) execution_api = self._get_one_by_id( id=id, requester_user=requester_user, permission_type=PermissionType.EXECUTION_STOP) if not execution_api: abort(http_client.NOT_FOUND, 'Execution with id %s not found.' % id) liveaction_id = execution_api.liveaction['id'] if not liveaction_id: abort( http_client.INTERNAL_SERVER_ERROR, 'Execution object missing link to liveaction %s.' % liveaction_id) try: liveaction_db = LiveAction.get_by_id(liveaction_id) except: abort( http_client.INTERNAL_SERVER_ERROR, 'Execution object missing link to liveaction %s.' % liveaction_id) if liveaction_db.status == LIVEACTION_STATUS_CANCELED: LOG.info('Action %s already in "canceled" state; \ returning execution object.' % liveaction_db.id) return execution_api if liveaction_db.status not in LIVEACTION_CANCELABLE_STATES: abort( http_client.OK, 'Action cannot be canceled. State = %s.' % liveaction_db.status) try: (liveaction_db, execution_db) = action_service.request_cancellation( liveaction_db, requester_user.name or cfg.CONF.system_user.user) except: LOG.exception('Failed requesting cancellation for liveaction %s.', liveaction_db.id) abort(http_client.INTERNAL_SERVER_ERROR, 'Failed canceling execution.') from_model_kwargs = self._get_from_model_kwargs_for_request(**kwargs) return ActionExecutionAPI.from_model(execution_db, from_model_kwargs)
def test_model_complete(self): # Create API object. obj = ActionExecutionAPI(**copy.deepcopy(self.fake_history_workflow)) self.assertDictEqual(obj.trigger, self.fake_history_workflow['trigger']) self.assertDictEqual(obj.trigger_type, self.fake_history_workflow['trigger_type']) self.assertDictEqual(obj.trigger_instance, self.fake_history_workflow['trigger_instance']) self.assertDictEqual(obj.rule, self.fake_history_workflow['rule']) self.assertDictEqual(obj.action, self.fake_history_workflow['action']) self.assertDictEqual(obj.runner, self.fake_history_workflow['runner']) self.assertEquals(obj.liveaction, self.fake_history_workflow['liveaction']) self.assertIsNone(getattr(obj, 'parent', None)) self.assertListEqual(obj.children, self.fake_history_workflow['children']) # Convert API object to DB model. model = ActionExecutionAPI.to_model(obj) self.assertEqual(str(model.id), obj.id) self.assertDictEqual(model.trigger, self.fake_history_workflow['trigger']) self.assertDictEqual(model.trigger_type, self.fake_history_workflow['trigger_type']) self.assertDictEqual(model.trigger_instance, self.fake_history_workflow['trigger_instance']) self.assertDictEqual(model.rule, self.fake_history_workflow['rule']) self.assertDictEqual(model.action, self.fake_history_workflow['action']) self.assertDictEqual(model.runner, self.fake_history_workflow['runner']) doc = copy.deepcopy(self.fake_history_workflow['liveaction']) doc['start_timestamp'] = doc['start_timestamp'] doc['end_timestamp'] = doc['end_timestamp'] self.assertDictEqual(model.liveaction, doc) self.assertIsNone(getattr(model, 'parent', None)) self.assertListEqual(model.children, self.fake_history_workflow['children']) # Convert DB model to API object. obj = ActionExecutionAPI.from_model(model) self.assertEqual(str(model.id), obj.id) self.assertDictEqual(obj.trigger, self.fake_history_workflow['trigger']) self.assertDictEqual(obj.trigger_type, self.fake_history_workflow['trigger_type']) self.assertDictEqual(obj.trigger_instance, self.fake_history_workflow['trigger_instance']) self.assertDictEqual(obj.rule, self.fake_history_workflow['rule']) self.assertDictEqual(obj.action, self.fake_history_workflow['action']) self.assertDictEqual(obj.runner, self.fake_history_workflow['runner']) self.assertDictEqual(obj.liveaction, self.fake_history_workflow['liveaction']) self.assertIsNone(getattr(obj, 'parent', None)) self.assertListEqual(obj.children, self.fake_history_workflow['children'])
def test_model_complete(self): # Create API object. obj = ActionExecutionAPI(**copy.deepcopy(self.fake_history_workflow)) self.assertDictEqual(obj.trigger, self.fake_history_workflow["trigger"]) self.assertDictEqual(obj.trigger_type, self.fake_history_workflow["trigger_type"]) self.assertDictEqual(obj.trigger_instance, self.fake_history_workflow["trigger_instance"]) self.assertDictEqual(obj.rule, self.fake_history_workflow["rule"]) self.assertDictEqual(obj.action, self.fake_history_workflow["action"]) self.assertDictEqual(obj.runner, self.fake_history_workflow["runner"]) self.assertEqual(obj.liveaction, self.fake_history_workflow["liveaction"]) self.assertIsNone(getattr(obj, "parent", None)) self.assertListEqual(obj.children, self.fake_history_workflow["children"]) # Convert API object to DB model. model = ActionExecutionAPI.to_model(obj) self.assertEqual(str(model.id), obj.id) self.assertDictEqual(model.trigger, self.fake_history_workflow["trigger"]) self.assertDictEqual(model.trigger_type, self.fake_history_workflow["trigger_type"]) self.assertDictEqual(model.trigger_instance, self.fake_history_workflow["trigger_instance"]) self.assertDictEqual(model.rule, self.fake_history_workflow["rule"]) self.assertDictEqual(model.action, self.fake_history_workflow["action"]) self.assertDictEqual(model.runner, self.fake_history_workflow["runner"]) doc = copy.deepcopy(self.fake_history_workflow["liveaction"]) doc["start_timestamp"] = doc["start_timestamp"] doc["end_timestamp"] = doc["end_timestamp"] self.assertDictEqual(model.liveaction, doc) self.assertIsNone(getattr(model, "parent", None)) self.assertListEqual(model.children, self.fake_history_workflow["children"]) # Convert DB model to API object. obj = ActionExecutionAPI.from_model(model) self.assertEqual(str(model.id), obj.id) self.assertDictEqual(obj.trigger, self.fake_history_workflow["trigger"]) self.assertDictEqual(obj.trigger_type, self.fake_history_workflow["trigger_type"]) self.assertDictEqual(obj.trigger_instance, self.fake_history_workflow["trigger_instance"]) self.assertDictEqual(obj.rule, self.fake_history_workflow["rule"]) self.assertDictEqual(obj.action, self.fake_history_workflow["action"]) self.assertDictEqual(obj.runner, self.fake_history_workflow["runner"]) self.assertDictEqual(obj.liveaction, self.fake_history_workflow["liveaction"]) self.assertIsNone(getattr(obj, "parent", None)) self.assertListEqual(obj.children, self.fake_history_workflow["children"])
def _schedule_execution(self, liveaction, user=None, context_string=None, show_secrets=False): # Initialize execution context if it does not exist. if not hasattr(liveaction, 'context'): liveaction.context = dict() liveaction.context['user'] = user LOG.debug('User is: %s' % liveaction.context['user']) # Retrieve other st2 context from request header. if context_string: context = try_loads(context_string) if not isinstance(context, dict): raise ValueError( 'Unable to convert st2-context from the headers into JSON.' ) liveaction.context.update(context) # Schedule the action execution. liveaction_db = LiveActionAPI.to_model(liveaction) liveaction_db, actionexecution_db = action_service.create_request( liveaction_db) action_db = action_utils.get_action_by_ref(liveaction_db.action) runnertype_db = action_utils.get_runnertype_by_name( action_db.runner_type['name']) try: liveaction_db.parameters = param_utils.render_live_params( runnertype_db.runner_parameters, action_db.parameters, liveaction_db.parameters, liveaction_db.context) except ParamException: # By this point the execution is already in the DB therefore need to mark it failed. _, e, tb = sys.exc_info() action_service.update_status(liveaction=liveaction_db, new_status=LIVEACTION_STATUS_FAILED, result={ 'error': str(e), 'traceback': ''.join( traceback.format_tb(tb, 20)) }) # Might be a good idea to return the actual ActionExecution rather than bubble up # the execption. raise ValueValidationException(str(e)) liveaction_db = LiveAction.add_or_update(liveaction_db, publish=False) _, actionexecution_db = action_service.publish_request( liveaction_db, actionexecution_db) execution_api = ActionExecutionAPI.from_model( actionexecution_db, mask_secrets=(not show_secrets)) return Response(json=execution_api, status=http_client.CREATED)
def delete(self, exec_id): """ Stops a single execution. Handles requests: DELETE /actionexecutions/<id> """ execution_api = self._get_one(id=exec_id) if not execution_api: abort(http_client.NOT_FOUND, 'Execution with id %s not found.' % exec_id) return liveaction_id = execution_api.liveaction['id'] if not liveaction_id: abort( http_client.INTERNAL_SERVER_ERROR, 'Execution object missing link to liveaction %s.' % liveaction_id) try: liveaction_db = LiveAction.get_by_id(liveaction_id) except: abort( http_client.INTERNAL_SERVER_ERROR, 'Execution object missing link to liveaction %s.' % liveaction_id) return if liveaction_db.status == LIVEACTION_STATUS_CANCELED: abort(http_client.OK, 'Action is already in "canceled" state.') if liveaction_db.status not in CANCELABLE_STATES: abort( http_client.OK, 'Action cannot be canceled. State = %s.' % liveaction_db.status) return liveaction_db.status = 'canceled' liveaction_db.end_timestamp = date_utils.get_datetime_utc_now() liveaction_db.result = {'message': 'Action canceled by user.'} try: LiveAction.add_or_update(liveaction_db) except: LOG.exception( 'Failed updating status to canceled for liveaction %s.', liveaction_db.id) abort(http_client.INTERNAL_SERVER_ERROR, 'Failed canceling execution.') return execution_db = execution_service.update_execution(liveaction_db) from_model_kwargs = self._get_from_model_kwargs_for_request( request=pecan.request) return ActionExecutionAPI.from_model(execution_db, from_model_kwargs)
def test_get_one(self): obj_id = random.choice(self.refs.keys()) response = self.app.get('/v1/executions/%s' % obj_id) self.assertEqual(response.status_int, 200) self.assertIsInstance(response.json, dict) record = response.json fake_record = ActionExecutionAPI.from_model(self.refs[obj_id]) self.assertEqual(record['id'], obj_id) self.assertDictEqual(record['action'], fake_record.action) self.assertDictEqual(record['runner'], fake_record.runner) self.assertDictEqual(record['liveaction'], fake_record.liveaction)
def test_get_one(self): obj_id = random.choice(list(self.refs.keys())) response = self.app.get('/v1/executions/%s' % obj_id) self.assertEqual(response.status_int, 200) self.assertIsInstance(response.json, dict) record = response.json fake_record = ActionExecutionAPI.from_model(self.refs[obj_id]) self.assertEqual(record['id'], obj_id) self.assertDictEqual(record['action'], fake_record.action) self.assertDictEqual(record['runner'], fake_record.runner) self.assertDictEqual(record['liveaction'], fake_record.liveaction)
def test_model_partial(self): # Create API object. obj = ActionExecutionAPI( **copy.deepcopy(self.fake_history_subtasks[0])) self.assertIsNone(getattr(obj, 'trigger', None)) self.assertIsNone(getattr(obj, 'trigger_type', None)) self.assertIsNone(getattr(obj, 'trigger_instance', None)) self.assertIsNone(getattr(obj, 'rule', None)) self.assertDictEqual(obj.action, self.fake_history_subtasks[0]['action']) self.assertDictEqual(obj.runner, self.fake_history_subtasks[0]['runner']) self.assertDictEqual(obj.liveaction, self.fake_history_subtasks[0]['liveaction']) self.assertEqual(obj.parent, self.fake_history_subtasks[0]['parent']) self.assertIsNone(getattr(obj, 'children', None)) # Convert API object to DB model. model = ActionExecutionAPI.to_model(obj) self.assertEqual(str(model.id), obj.id) self.assertDictEqual(model.trigger, {}) self.assertDictEqual(model.trigger_type, {}) self.assertDictEqual(model.trigger_instance, {}) self.assertDictEqual(model.rule, {}) self.assertDictEqual(model.action, self.fake_history_subtasks[0]['action']) self.assertDictEqual(model.runner, self.fake_history_subtasks[0]['runner']) doc = copy.deepcopy(self.fake_history_subtasks[0]['liveaction']) doc['start_timestamp'] = doc['start_timestamp'] doc['end_timestamp'] = doc['end_timestamp'] self.assertDictEqual(model.liveaction, doc) self.assertEqual(model.parent, self.fake_history_subtasks[0]['parent']) self.assertListEqual(model.children, []) # Convert DB model to API object. obj = ActionExecutionAPI.from_model(model) self.assertEqual(str(model.id), obj.id) self.assertIsNone(getattr(obj, 'trigger', None)) self.assertIsNone(getattr(obj, 'trigger_type', None)) self.assertIsNone(getattr(obj, 'trigger_instance', None)) self.assertIsNone(getattr(obj, 'rule', None)) self.assertDictEqual(obj.action, self.fake_history_subtasks[0]['action']) self.assertDictEqual(obj.runner, self.fake_history_subtasks[0]['runner']) self.assertDictEqual(obj.liveaction, self.fake_history_subtasks[0]['liveaction']) self.assertEqual(obj.parent, self.fake_history_subtasks[0]['parent']) self.assertIsNone(getattr(obj, 'children', None))
def delete(self, exec_id): """ Stops a single execution. Handles requests: DELETE /executions/<id> """ execution_api = self._get_one(id=exec_id) if not execution_api: abort(http_client.NOT_FOUND, 'Execution with id %s not found.' % exec_id) liveaction_id = execution_api.liveaction['id'] if not liveaction_id: abort( http_client.INTERNAL_SERVER_ERROR, 'Execution object missing link to liveaction %s.' % liveaction_id) try: liveaction_db = LiveAction.get_by_id(liveaction_id) except: abort( http_client.INTERNAL_SERVER_ERROR, 'Execution object missing link to liveaction %s.' % liveaction_id) if liveaction_db.status == LIVEACTION_STATUS_CANCELED: abort(http_client.OK, 'Action is already in "canceled" state.') if liveaction_db.status not in CANCELABLE_STATES: abort( http_client.OK, 'Action cannot be canceled. State = %s.' % liveaction_db.status) try: (liveaction_db, execution_db) = action_service.request_cancellation( liveaction_db, self._get_requester()) except: LOG.exception('Failed requesting cancellation for liveaction %s.', liveaction_db.id) abort(http_client.INTERNAL_SERVER_ERROR, 'Failed canceling execution.') from_model_kwargs = self._get_from_model_kwargs_for_request( request=pecan.request) return ActionExecutionAPI.from_model(execution_db, from_model_kwargs)
def delete(self, id, requester_user, show_secrets=False): """ Stops a single execution. Handles requests: DELETE /executions/<id> """ if not requester_user: requester_user = UserDB(cfg.CONF.system_user.user) from_model_kwargs = { 'mask_secrets': self._get_mask_secrets(requester_user, show_secrets=show_secrets) } execution_api = self._get_one_by_id(id=id, requester_user=requester_user, from_model_kwargs=from_model_kwargs, permission_type=PermissionType.EXECUTION_STOP) if not execution_api: abort(http_client.NOT_FOUND, 'Execution with id %s not found.' % id) liveaction_id = execution_api.liveaction['id'] if not liveaction_id: abort(http_client.INTERNAL_SERVER_ERROR, 'Execution object missing link to liveaction %s.' % liveaction_id) try: liveaction_db = LiveAction.get_by_id(liveaction_id) except: abort(http_client.INTERNAL_SERVER_ERROR, 'Execution object missing link to liveaction %s.' % liveaction_id) if liveaction_db.status == action_constants.LIVEACTION_STATUS_CANCELED: LOG.info( 'Action %s already in "canceled" state; \ returning execution object.' % liveaction_db.id ) return execution_api if liveaction_db.status not in action_constants.LIVEACTION_CANCELABLE_STATES: abort(http_client.OK, 'Action cannot be canceled. State = %s.' % liveaction_db.status) try: (liveaction_db, execution_db) = action_service.request_cancellation( liveaction_db, requester_user.name or cfg.CONF.system_user.user) except: LOG.exception('Failed requesting cancellation for liveaction %s.', liveaction_db.id) abort(http_client.INTERNAL_SERVER_ERROR, 'Failed canceling execution.') return ActionExecutionAPI.from_model(execution_db, mask_secrets=from_model_kwargs['mask_secrets'])
def delete(self, exec_id): """ Stops a single execution. Handles requests: DELETE /actionexecutions/<id> """ execution_api = self._get_one(id=exec_id) if not execution_api: abort(http_client.NOT_FOUND, 'Execution with id %s not found.' % exec_id) return liveaction_id = execution_api.liveaction['id'] if not liveaction_id: abort(http_client.INTERNAL_SERVER_ERROR, 'Execution object missing link to liveaction %s.' % liveaction_id) try: liveaction_db = LiveAction.get_by_id(liveaction_id) except: abort(http_client.INTERNAL_SERVER_ERROR, 'Execution object missing link to liveaction %s.' % liveaction_id) return if liveaction_db.status == LIVEACTION_STATUS_CANCELED: abort(http_client.OK, 'Action is already in "canceled" state.') if liveaction_db.status not in CANCELABLE_STATES: abort(http_client.OK, 'Action cannot be canceled. State = %s.' % liveaction_db.status) return liveaction_db.status = 'canceled' liveaction_db.end_timestamp = date_utils.get_datetime_utc_now() liveaction_db.result = {'message': 'Action canceled by user.'} try: LiveAction.add_or_update(liveaction_db) except: LOG.exception('Failed updating status to canceled for liveaction %s.', liveaction_db.id) abort(http_client.INTERNAL_SERVER_ERROR, 'Failed canceling execution.') return execution_db = execution_service.update_execution(liveaction_db) from_model_kwargs = self._get_from_model_kwargs_for_request(request=pecan.request) return ActionExecutionAPI.from_model(execution_db, from_model_kwargs)
def _bootstrap(self): marker = self._get_export_marker_from_db() LOG.info('Using marker %s...' % marker) missed_executions = self._get_missed_executions_from_db(export_marker=marker) LOG.info('Found %d executions not exported yet...', len(missed_executions)) for missed_execution in missed_executions: if missed_execution.status not in COMPLETION_STATUSES: continue execution_api = ActionExecutionAPI.from_model(missed_execution, mask_secrets=True) try: LOG.debug('Missed execution %s', execution_api) self.pending_executions.put_nowait(execution_api) except: LOG.exception('Failed adding execution to in-memory queue.') continue LOG.info('Bootstrapped executions...')
def delete(self, exec_id): """ Stops a single execution. Handles requests: DELETE /executions/<id> """ execution_api = self._get_one(id=exec_id) if not execution_api: abort(http_client.NOT_FOUND, 'Execution with id %s not found.' % exec_id) liveaction_id = execution_api.liveaction['id'] if not liveaction_id: abort(http_client.INTERNAL_SERVER_ERROR, 'Execution object missing link to liveaction %s.' % liveaction_id) try: liveaction_db = LiveAction.get_by_id(liveaction_id) except: abort(http_client.INTERNAL_SERVER_ERROR, 'Execution object missing link to liveaction %s.' % liveaction_id) if liveaction_db.status == LIVEACTION_STATUS_CANCELED: LOG.info( 'Action %s already in "canceled" state; \ returning execution object.' % liveaction_db.id ) return execution_api if liveaction_db.status not in LIVEACTION_CANCELABLE_STATES: abort(http_client.OK, 'Action cannot be canceled. State = %s.' % liveaction_db.status) try: (liveaction_db, execution_db) = action_service.request_cancellation( liveaction_db, get_requester()) except: LOG.exception('Failed requesting cancellation for liveaction %s.', liveaction_db.id) abort(http_client.INTERNAL_SERVER_ERROR, 'Failed canceling execution.') from_model_kwargs = self._get_from_model_kwargs_for_request(request=pecan.request) return ActionExecutionAPI.from_model(execution_db, from_model_kwargs)
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 _schedule_execution(self, liveaction): # Initialize execution context if it does not exist. if not hasattr(liveaction, 'context'): liveaction.context = dict() liveaction.context['user'] = get_requester() LOG.debug('User is: %s' % liveaction.context['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.' ) liveaction.context.update(context) # Schedule the action execution. liveaction_db = LiveActionAPI.to_model(liveaction) liveaction_db, actionexecution_db = action_service.create_request( liveaction_db) action_db = action_utils.get_action_by_ref(liveaction_db.action) runnertype_db = action_utils.get_runnertype_by_name( action_db.runner_type['name']) try: liveaction_db.parameters = param_utils.render_live_params( runnertype_db.runner_parameters, action_db.parameters, liveaction_db.parameters, liveaction_db.context) except ParamException as e: raise ValueValidationException(str(e)) liveaction_db = LiveAction.add_or_update(liveaction_db, publish=False) _, actionexecution_db = action_service.publish_request( liveaction_db, actionexecution_db) from_model_kwargs = self._get_from_model_kwargs_for_request( request=pecan.request) return ActionExecutionAPI.from_model(actionexecution_db, from_model_kwargs)
def test_model_partial(self): # Create API object. obj = ActionExecutionAPI(**copy.deepcopy(self.fake_history_subtasks[0])) self.assertIsNone(getattr(obj, 'trigger', None)) self.assertIsNone(getattr(obj, 'trigger_type', None)) self.assertIsNone(getattr(obj, 'trigger_instance', None)) self.assertIsNone(getattr(obj, 'rule', None)) self.assertDictEqual(obj.action, self.fake_history_subtasks[0]['action']) self.assertDictEqual(obj.runner, self.fake_history_subtasks[0]['runner']) self.assertDictEqual(obj.liveaction, self.fake_history_subtasks[0]['liveaction']) self.assertEqual(obj.parent, self.fake_history_subtasks[0]['parent']) self.assertIsNone(getattr(obj, 'children', None)) # Convert API object to DB model. model = ActionExecutionAPI.to_model(obj) self.assertEqual(str(model.id), obj.id) self.assertDictEqual(model.trigger, {}) self.assertDictEqual(model.trigger_type, {}) self.assertDictEqual(model.trigger_instance, {}) self.assertDictEqual(model.rule, {}) self.assertDictEqual(model.action, self.fake_history_subtasks[0]['action']) self.assertDictEqual(model.runner, self.fake_history_subtasks[0]['runner']) doc = copy.deepcopy(self.fake_history_subtasks[0]['liveaction']) doc['start_timestamp'] = doc['start_timestamp'] doc['end_timestamp'] = doc['end_timestamp'] self.assertDictEqual(model.liveaction, doc) self.assertEqual(model.parent, self.fake_history_subtasks[0]['parent']) self.assertListEqual(model.children, []) # Convert DB model to API object. obj = ActionExecutionAPI.from_model(model) self.assertEqual(str(model.id), obj.id) self.assertIsNone(getattr(obj, 'trigger', None)) self.assertIsNone(getattr(obj, 'trigger_type', None)) self.assertIsNone(getattr(obj, 'trigger_instance', None)) self.assertIsNone(getattr(obj, 'rule', None)) self.assertDictEqual(obj.action, self.fake_history_subtasks[0]['action']) self.assertDictEqual(obj.runner, self.fake_history_subtasks[0]['runner']) self.assertDictEqual(obj.liveaction, self.fake_history_subtasks[0]['liveaction']) self.assertEqual(obj.parent, self.fake_history_subtasks[0]['parent']) self.assertIsNone(getattr(obj, 'children', None))
def _schedule_execution(self, liveaction, user=None): # Initialize execution context if it does not exist. if not hasattr(liveaction, 'context'): liveaction.context = dict() liveaction.context['user'] = user LOG.debug('User is: %s' % liveaction.context['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.') liveaction.context.update(context) # Schedule the action execution. liveaction_db = LiveActionAPI.to_model(liveaction) liveaction_db, actionexecution_db = action_service.create_request(liveaction_db) action_db = action_utils.get_action_by_ref(liveaction_db.action) runnertype_db = action_utils.get_runnertype_by_name(action_db.runner_type['name']) try: liveaction_db.parameters = param_utils.render_live_params( runnertype_db.runner_parameters, action_db.parameters, liveaction_db.parameters, liveaction_db.context) except ParamException: # By this point the execution is already in the DB therefore need to mark it failed. _, e, tb = sys.exc_info() action_service.update_status( liveaction=liveaction_db, new_status=LIVEACTION_STATUS_FAILED, result={'error': str(e), 'traceback': ''.join(traceback.format_tb(tb, 20))}) # Might be a good idea to return the actual ActionExecution rather than bubble up # the execption. raise ValueValidationException(str(e)) liveaction_db = LiveAction.add_or_update(liveaction_db, publish=False) _, actionexecution_db = action_service.publish_request(liveaction_db, actionexecution_db) from_model_kwargs = self._get_from_model_kwargs_for_request(request=pecan.request) return ActionExecutionAPI.from_model(actionexecution_db, from_model_kwargs)
def _schedule_execution(self, liveaction): # Initialize execution context if it does not exist. if not hasattr(liveaction, 'context'): liveaction.context = dict() liveaction.context['user'] = self._get_requester() LOG.debug('User is: %s' % liveaction.context['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.') liveaction.context.update(context) # Schedule the action execution. liveactiondb = LiveActionAPI.to_model(liveaction) _, actionexecutiondb = action_service.request(liveactiondb) from_model_kwargs = self._get_from_model_kwargs_for_request(request=pecan.request) return ActionExecutionAPI.from_model(actionexecutiondb, from_model_kwargs)
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 _append_view_properties(self, rule_enforcement_apis): """ Method which appends corresponding execution (if available) and trigger instance object properties. """ trigger_instance_ids = set([]) execution_ids = [] for rule_enforcement_api in rule_enforcement_apis: if rule_enforcement_api.get('trigger_instance_id', None): trigger_instance_ids.add(str(rule_enforcement_api['trigger_instance_id'])) if rule_enforcement_api.get('execution_id', None): execution_ids.append(rule_enforcement_api['execution_id']) # 1. Retrieve corresponding execution objects # NOTE: Executions contain a lot of field and could contain a lot of data so we only # retrieve fields we need only_fields = [ 'id', 'action.ref', 'action.parameters', 'runner.name', 'runner.runner_parameters', 'parameters', 'status' ] execution_dbs = ActionExecution.query(id__in=execution_ids, only_fields=only_fields) execution_dbs_by_id = {} for execution_db in execution_dbs: execution_dbs_by_id[str(execution_db.id)] = execution_db # 2. Retrieve corresponding trigger instance objects trigger_instance_dbs = TriggerInstance.query(id__in=list(trigger_instance_ids)) trigger_instance_dbs_by_id = {} for trigger_instance_db in trigger_instance_dbs: trigger_instance_dbs_by_id[str(trigger_instance_db.id)] = trigger_instance_db # Ammend rule enforcement objects with additional data for rule_enforcement_api in rule_enforcement_apis: rule_enforcement_api['trigger_instance'] = {} rule_enforcement_api['execution'] = {} trigger_instance_id = rule_enforcement_api.get('trigger_instance_id', None) execution_id = rule_enforcement_api.get('execution_id', None) trigger_instance_db = trigger_instance_dbs_by_id.get(trigger_instance_id, None) execution_db = execution_dbs_by_id.get(execution_id, None) if trigger_instance_db: trigger_instance_api = TriggerInstanceAPI.from_model(trigger_instance_db) rule_enforcement_api['trigger_instance'] = trigger_instance_api if execution_db: execution_api = ActionExecutionAPI.from_model(execution_db) rule_enforcement_api['execution'] = execution_api return rule_enforcement_apis
def _schedule_execution(self, liveaction, requester_user, action_db, user=None, context_string=None, show_secrets=False): # Initialize execution context if it does not exist. if not hasattr(liveaction, 'context'): liveaction.context = dict() liveaction.context['user'] = user liveaction.context['pack'] = action_db.pack LOG.debug('User is: %s' % liveaction.context['user']) # Retrieve other st2 context from request header. if context_string: context = try_loads(context_string) if not isinstance(context, dict): raise ValueError('Unable to convert st2-context from the headers into JSON.') liveaction.context.update(context) # Include RBAC context (if RBAC is available and enabled) if cfg.CONF.rbac.enable: user_db = UserDB(name=user) role_dbs = rbac_service.get_roles_for_user(user_db=user_db, include_remote=True) roles = [role_db.name for role_db in role_dbs] liveaction.context['rbac'] = { 'user': user, 'roles': roles } # Schedule the action execution. liveaction_db = LiveActionAPI.to_model(liveaction) runnertype_db = action_utils.get_runnertype_by_name(action_db.runner_type['name']) try: liveaction_db.parameters = param_utils.render_live_params( runnertype_db.runner_parameters, action_db.parameters, liveaction_db.parameters, liveaction_db.context) except param_exc.ParamException: # We still need to create a request, so liveaction_db is assigned an ID liveaction_db, actionexecution_db = action_service.create_request( liveaction=liveaction_db, action_db=action_db, runnertype_db=runnertype_db) # By this point the execution is already in the DB therefore need to mark it failed. _, e, tb = sys.exc_info() action_service.update_status( liveaction=liveaction_db, new_status=action_constants.LIVEACTION_STATUS_FAILED, result={'error': six.text_type(e), 'traceback': ''.join(traceback.format_tb(tb, 20))}) # Might be a good idea to return the actual ActionExecution rather than bubble up # the exception. raise validation_exc.ValueValidationException(six.text_type(e)) # The request should be created after the above call to render_live_params # so any templates in live parameters have a chance to render. liveaction_db, actionexecution_db = action_service.create_request(liveaction=liveaction_db, action_db=action_db, runnertype_db=runnertype_db) _, actionexecution_db = action_service.publish_request(liveaction_db, actionexecution_db) mask_secrets = self._get_mask_secrets(requester_user, show_secrets=show_secrets) execution_api = ActionExecutionAPI.from_model(actionexecution_db, mask_secrets=mask_secrets) return Response(json=execution_api, status=http_client.CREATED)
def put(self, id, liveaction_api, requester_user, show_secrets=False): """ Updates a single execution. Handles requests: PUT /executions/<id> """ if not requester_user: requester_user = UserDB(cfg.CONF.system_user.user) from_model_kwargs = { 'mask_secrets': self._get_mask_secrets(requester_user, show_secrets=show_secrets) } execution_api = self._get_one_by_id( id=id, requester_user=requester_user, from_model_kwargs=from_model_kwargs, permission_type=PermissionType.EXECUTION_STOP) if not execution_api: abort(http_client.NOT_FOUND, 'Execution with id %s not found.' % id) liveaction_id = execution_api.liveaction['id'] if not liveaction_id: abort( http_client.INTERNAL_SERVER_ERROR, 'Execution object missing link to liveaction %s.' % liveaction_id) try: liveaction_db = LiveAction.get_by_id(liveaction_id) except: abort( http_client.INTERNAL_SERVER_ERROR, 'Execution object missing link to liveaction %s.' % liveaction_id) if liveaction_db.status in action_constants.LIVEACTION_COMPLETED_STATES: abort(http_client.BAD_REQUEST, 'Execution is already in completed state.') def update_status(liveaction_api, liveaction_db): status = liveaction_api.status result = getattr(liveaction_api, 'result', None) liveaction_db = action_service.update_status( liveaction_db, status, result) actionexecution_db = ActionExecution.get( liveaction__id=str(liveaction_db.id)) return (liveaction_db, actionexecution_db) try: if (liveaction_db.status == action_constants.LIVEACTION_STATUS_CANCELING and liveaction_api.status == action_constants.LIVEACTION_STATUS_CANCELED): if action_service.is_children_active(liveaction_id): liveaction_api.status = action_constants.LIVEACTION_STATUS_CANCELING liveaction_db, actionexecution_db = update_status( liveaction_api, liveaction_db) elif (liveaction_api.status == action_constants.LIVEACTION_STATUS_CANCELING or liveaction_api.status == action_constants.LIVEACTION_STATUS_CANCELED): liveaction_db, actionexecution_db = action_service.request_cancellation( liveaction_db, requester_user.name or cfg.CONF.system_user.user) elif (liveaction_db.status == action_constants.LIVEACTION_STATUS_PAUSING and liveaction_api.status == action_constants.LIVEACTION_STATUS_PAUSED): if action_service.is_children_active(liveaction_id): liveaction_api.status = action_constants.LIVEACTION_STATUS_PAUSING liveaction_db, actionexecution_db = update_status( liveaction_api, liveaction_db) elif (liveaction_api.status == action_constants.LIVEACTION_STATUS_PAUSING or liveaction_api.status == action_constants.LIVEACTION_STATUS_PAUSED): liveaction_db, actionexecution_db = action_service.request_pause( liveaction_db, requester_user.name or cfg.CONF.system_user.user) elif liveaction_api.status == action_constants.LIVEACTION_STATUS_RESUMING: liveaction_db, actionexecution_db = action_service.request_resume( liveaction_db, requester_user.name or cfg.CONF.system_user.user) else: liveaction_db, actionexecution_db = update_status( liveaction_api, liveaction_db) except runner_exc.InvalidActionRunnerOperationError as e: LOG.exception('Failed updating liveaction %s. %s', liveaction_db.id, str(e)) abort(http_client.BAD_REQUEST, 'Failed updating execution. %s' % str(e)) except runner_exc.UnexpectedActionExecutionStatusError as e: LOG.exception('Failed updating liveaction %s. %s', liveaction_db.id, str(e)) abort(http_client.BAD_REQUEST, 'Failed updating execution. %s' % str(e)) except Exception as e: LOG.exception('Failed updating liveaction %s. %s', liveaction_db.id, str(e)) abort(http_client.INTERNAL_SERVER_ERROR, 'Failed updating execution due to unexpected error.') mask_secrets = self._get_mask_secrets(requester_user, show_secrets=show_secrets) execution_api = ActionExecutionAPI.from_model( actionexecution_db, mask_secrets=mask_secrets) return execution_api
def _schedule_execution(self, liveaction, requester_user, user=None, context_string=None, show_secrets=False, pack=None): # Initialize execution context if it does not exist. if not hasattr(liveaction, 'context'): liveaction.context = dict() liveaction.context['user'] = user liveaction.context['pack'] = pack LOG.debug('User is: %s' % liveaction.context['user']) # Retrieve other st2 context from request header. if context_string: context = try_loads(context_string) if not isinstance(context, dict): raise ValueError( 'Unable to convert st2-context from the headers into JSON.' ) liveaction.context.update(context) # Include RBAC context (if RBAC is available and enabled) if cfg.CONF.rbac.enable: user_db = UserDB(name=user) role_dbs = rbac_service.get_roles_for_user(user_db=user_db, include_remote=True) roles = [role_db.name for role_db in role_dbs] liveaction.context['rbac'] = {'user': user, 'roles': roles} # Schedule the action execution. liveaction_db = LiveActionAPI.to_model(liveaction) action_db = action_utils.get_action_by_ref(liveaction_db.action) runnertype_db = action_utils.get_runnertype_by_name( action_db.runner_type['name']) try: liveaction_db.parameters = param_utils.render_live_params( runnertype_db.runner_parameters, action_db.parameters, liveaction_db.parameters, liveaction_db.context) except param_exc.ParamException: # We still need to create a request, so liveaction_db is assigned an ID liveaction_db, actionexecution_db = action_service.create_request( liveaction_db) # By this point the execution is already in the DB therefore need to mark it failed. _, e, tb = sys.exc_info() action_service.update_status( liveaction=liveaction_db, new_status=action_constants.LIVEACTION_STATUS_FAILED, result={ 'error': str(e), 'traceback': ''.join(traceback.format_tb(tb, 20)) }) # Might be a good idea to return the actual ActionExecution rather than bubble up # the exception. raise validation_exc.ValueValidationException(str(e)) # The request should be created after the above call to render_live_params # so any templates in live parameters have a chance to render. liveaction_db, actionexecution_db = action_service.create_request( liveaction_db) liveaction_db = LiveAction.add_or_update(liveaction_db, publish=False) _, actionexecution_db = action_service.publish_request( liveaction_db, actionexecution_db) mask_secrets = self._get_mask_secrets(requester_user, show_secrets=show_secrets) execution_api = ActionExecutionAPI.from_model( actionexecution_db, mask_secrets=mask_secrets) return Response(json=execution_api, status=http_client.CREATED)
def delete(self, id, requester_user, show_secrets=False): """ Stops a single execution. Handles requests: DELETE /executions/<id> """ if not requester_user: requester_user = UserDB(name=cfg.CONF.system_user.user) from_model_kwargs = { "mask_secrets": self._get_mask_secrets(requester_user, show_secrets=show_secrets) } execution_api = self._get_one_by_id( id=id, requester_user=requester_user, from_model_kwargs=from_model_kwargs, permission_type=PermissionType.EXECUTION_STOP, ) if not execution_api: abort(http_client.NOT_FOUND, "Execution with id %s not found." % id) liveaction_id = execution_api.liveaction["id"] if not liveaction_id: abort( http_client.INTERNAL_SERVER_ERROR, "Execution object missing link to liveaction %s." % liveaction_id, ) try: liveaction_db = LiveAction.get_by_id(liveaction_id) except: abort( http_client.INTERNAL_SERVER_ERROR, "Execution object missing link to liveaction %s." % liveaction_id, ) if liveaction_db.status == action_constants.LIVEACTION_STATUS_CANCELED: LOG.info('Action %s already in "canceled" state; \ returning execution object.' % liveaction_db.id) return execution_api if liveaction_db.status not in action_constants.LIVEACTION_CANCELABLE_STATES: abort( http_client.OK, "Action cannot be canceled. State = %s." % liveaction_db.status, ) try: (liveaction_db, execution_db) = action_service.request_cancellation( liveaction_db, requester_user.name or cfg.CONF.system_user.user) except: LOG.exception("Failed requesting cancellation for liveaction %s.", liveaction_db.id) abort(http_client.INTERNAL_SERVER_ERROR, "Failed canceling execution.") return ActionExecutionAPI.from_model( execution_db, mask_secrets=from_model_kwargs["mask_secrets"])
def put(self, id, liveaction_api, requester_user, show_secrets=False): """ Updates a single execution. Handles requests: PUT /executions/<id> """ if not requester_user: requester_user = UserDB(cfg.CONF.system_user.user) from_model_kwargs = { 'mask_secrets': self._get_mask_secrets(requester_user, show_secrets=show_secrets) } execution_api = self._get_one_by_id(id=id, requester_user=requester_user, from_model_kwargs=from_model_kwargs, permission_type=PermissionType.EXECUTION_STOP) if not execution_api: abort(http_client.NOT_FOUND, 'Execution with id %s not found.' % id) liveaction_id = execution_api.liveaction['id'] if not liveaction_id: abort(http_client.INTERNAL_SERVER_ERROR, 'Execution object missing link to liveaction %s.' % liveaction_id) try: liveaction_db = LiveAction.get_by_id(liveaction_id) except: abort(http_client.INTERNAL_SERVER_ERROR, 'Execution object missing link to liveaction %s.' % liveaction_id) if liveaction_db.status in action_constants.LIVEACTION_COMPLETED_STATES: abort(http_client.BAD_REQUEST, 'Execution is already in completed state.') def update_status(liveaction_api, liveaction_db): status = liveaction_api.status result = getattr(liveaction_api, 'result', None) liveaction_db = action_service.update_status(liveaction_db, status, result) actionexecution_db = ActionExecution.get(liveaction__id=str(liveaction_db.id)) return (liveaction_db, actionexecution_db) try: if (liveaction_db.status == action_constants.LIVEACTION_STATUS_CANCELING and liveaction_api.status == action_constants.LIVEACTION_STATUS_CANCELED): if action_service.is_children_active(liveaction_id): liveaction_api.status = action_constants.LIVEACTION_STATUS_CANCELING liveaction_db, actionexecution_db = update_status(liveaction_api, liveaction_db) elif (liveaction_api.status == action_constants.LIVEACTION_STATUS_CANCELING or liveaction_api.status == action_constants.LIVEACTION_STATUS_CANCELED): liveaction_db, actionexecution_db = action_service.request_cancellation( liveaction_db, requester_user.name or cfg.CONF.system_user.user) elif (liveaction_db.status == action_constants.LIVEACTION_STATUS_PAUSING and liveaction_api.status == action_constants.LIVEACTION_STATUS_PAUSED): if action_service.is_children_active(liveaction_id): liveaction_api.status = action_constants.LIVEACTION_STATUS_PAUSING liveaction_db, actionexecution_db = update_status(liveaction_api, liveaction_db) elif (liveaction_api.status == action_constants.LIVEACTION_STATUS_PAUSING or liveaction_api.status == action_constants.LIVEACTION_STATUS_PAUSED): liveaction_db, actionexecution_db = action_service.request_pause( liveaction_db, requester_user.name or cfg.CONF.system_user.user) elif liveaction_api.status == action_constants.LIVEACTION_STATUS_RESUMING: liveaction_db, actionexecution_db = action_service.request_resume( liveaction_db, requester_user.name or cfg.CONF.system_user.user) else: liveaction_db, actionexecution_db = update_status(liveaction_api, liveaction_db) except runner_exc.InvalidActionRunnerOperationError as e: LOG.exception('Failed updating liveaction %s. %s', liveaction_db.id, six.text_type(e)) abort(http_client.BAD_REQUEST, 'Failed updating execution. %s' % six.text_type(e)) except runner_exc.UnexpectedActionExecutionStatusError as e: LOG.exception('Failed updating liveaction %s. %s', liveaction_db.id, six.text_type(e)) abort(http_client.BAD_REQUEST, 'Failed updating execution. %s' % six.text_type(e)) except Exception as e: LOG.exception('Failed updating liveaction %s. %s', liveaction_db.id, six.text_type(e)) abort( http_client.INTERNAL_SERVER_ERROR, 'Failed updating execution due to unexpected error.' ) mask_secrets = self._get_mask_secrets(requester_user, show_secrets=show_secrets) execution_api = ActionExecutionAPI.from_model(actionexecution_db, mask_secrets=mask_secrets) return execution_api