def get_one(self, name, scope=SYSTEM_SCOPE, user=None, decrypt=False): """ List key by name. Handle: GET /keys/key1 """ self._validate_scope(scope=scope) if user: # Providing a user implies a user scope scope = USER_SCOPE requester_user = get_requester() user = user or requester_user is_admin = request_user_is_admin(request=pecan.request) # User needs to be either admin or requesting item for itself self._validate_decrypt_query_parameter(decrypt=decrypt, scope=scope, is_admin=is_admin) # Validate that the authenticated user is admin if user query param is provided assert_request_user_is_admin_if_user_query_param_is_provider(request=pecan.request, user=user) key_ref = get_key_reference(scope=scope, name=name, user=user) from_model_kwargs = {'mask_secrets': not decrypt} kvp_api = self._get_one_by_scope_and_name( name=key_ref, scope=scope, from_model_kwargs=from_model_kwargs ) return kvp_api
def _handle_schedule_execution(self, liveaction_api): """ :param liveaction: LiveActionAPI object. :type liveaction: :class:`LiveActionAPI` """ # Assert the permissions action_ref = liveaction_api.action action_db = action_utils.get_action_by_ref(action_ref) user = liveaction_api.user or get_requester() assert_request_user_has_resource_db_permission(request=pecan.request, resource_db=action_db, permission_type=PermissionType.ACTION_EXECUTE) # TODO: Validate user is admin if user is provided assert_request_user_is_admin_if_user_query_param_is_provider(request=pecan.request, user=user) try: return self._schedule_execution(liveaction=liveaction_api, user=user) 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, re.sub("u'([^']*)'", r"'\1'", e.message)) except TraceNotFoundException as e: abort(http_client.BAD_REQUEST, str(e)) except ValueValidationException as e: raise e except Exception as e: LOG.exception('Unable to execute action. Unexpected error encountered.') abort(http_client.INTERNAL_SERVER_ERROR, str(e))
def get_all(self, prefix=None, scope=FULL_SYSTEM_SCOPE, user=None, decrypt=False, **kwargs): """ List all keys. Handles requests: GET /keys/ """ if not scope: scope = FULL_SYSTEM_SCOPE if user: # Providing a user implies a user scope scope = FULL_USER_SCOPE scope = get_datastore_full_scope(scope) requester_user = get_requester() user = user or requester_user is_all_scope = (scope == ALL_SCOPE) is_admin = request_user_is_admin(request=pecan.request) if is_all_scope and not is_admin: msg = '"all" scope requires administrator access' raise AccessDeniedError(message=msg, user_db=requester_user) # User needs to be either admin or requesting items for themselves self._validate_decrypt_query_parameter(decrypt=decrypt, scope=scope, is_admin=is_admin) # Validate that the authenticated user is admin if user query param is provided assert_request_user_is_admin_if_user_query_param_is_provided( request=pecan.request, user=user) from_model_kwargs = {'mask_secrets': not decrypt} kwargs['prefix'] = prefix if scope and scope not in ALL_SCOPE: self._validate_scope(scope=scope) kwargs['scope'] = scope if scope == USER_SCOPE or scope == FULL_USER_SCOPE: # Make sure we only returned values scoped to current user if kwargs['prefix']: kwargs['prefix'] = get_key_reference(name=kwargs['prefix'], scope=scope, user=requester_user) else: kwargs['prefix'] = get_key_reference(name='', scope=scope, user=user) kvp_apis = super(KeyValuePairController, self)._get_all(from_model_kwargs=from_model_kwargs, **kwargs) return kvp_apis
def put(self, kvp, name, scope=FULL_SYSTEM_SCOPE): """ Create a new entry or update an existing one. """ if not scope: scope = FULL_SYSTEM_SCOPE requester_user = get_requester() scope = getattr(kvp, 'scope', scope) scope = get_datastore_full_scope(scope) self._validate_scope(scope=scope) user = getattr(kvp, 'user', requester_user) or requester_user # Validate that the authenticated user is admin if user query param is provided assert_request_user_is_admin_if_user_query_param_is_provider(request=pecan.request, user=user) key_ref = get_key_reference(scope=scope, name=name, user=user) lock_name = self._get_lock_name_for_key(name=key_ref, scope=scope) LOG.debug('PUT scope: %s, name: %s', scope, name) # TODO: Custom permission check since the key doesn't need to exist here # Note: We use lock to avoid a race with self._coordinator.get_lock(lock_name): try: existing_kvp_api = self._get_one_by_scope_and_name( scope=scope, name=key_ref ) except StackStormDBObjectNotFoundError: existing_kvp_api = None kvp.name = key_ref kvp.scope = scope try: kvp_db = KeyValuePairAPI.to_model(kvp) if existing_kvp_api: kvp_db.id = existing_kvp_api.id kvp_db = KeyValuePair.add_or_update(kvp_db) except (ValidationError, ValueError) as e: LOG.exception('Validation failed for key value data=%s', kvp) abort(http_client.BAD_REQUEST, str(e)) return except CryptoKeyNotSetupException as e: LOG.exception(str(e)) abort(http_client.BAD_REQUEST, str(e)) return except InvalidScopeException as e: LOG.exception(str(e)) abort(http_client.BAD_REQUEST, str(e)) return extra = {'kvp_db': kvp_db} LOG.audit('KeyValuePair updated. KeyValuePair.id=%s' % (kvp_db.id), extra=extra) kvp_api = KeyValuePairAPI.from_model(kvp_db) return kvp_api
def get_one(self, name, scope=FULL_SYSTEM_SCOPE, user=None, decrypt=False): """ List key by name. Handle: GET /keys/key1 """ if not scope: scope = FULL_SYSTEM_SCOPE if user: # Providing a user implies a user scope scope = FULL_USER_SCOPE scope = get_datastore_full_scope(scope) self._validate_scope(scope=scope) requester_user = get_requester() user = user or requester_user is_admin = request_user_is_admin(request=pecan.request) # User needs to be either admin or requesting item for itself self._validate_decrypt_query_parameter(decrypt=decrypt, scope=scope, is_admin=is_admin) # Validate that the authenticated user is admin if user query param is provided assert_request_user_is_admin_if_user_query_param_is_provided( request=pecan.request, user=user) key_ref = get_key_reference(scope=scope, name=name, user=user) from_model_kwargs = {'mask_secrets': not decrypt} kvp_api = self._get_one_by_scope_and_name( name=key_ref, scope=scope, from_model_kwargs=from_model_kwargs) return kvp_api
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 put(self, kvp, name, scope=FULL_SYSTEM_SCOPE): """ Create a new entry or update an existing one. """ if not scope: scope = FULL_SYSTEM_SCOPE requester_user = get_requester() scope = getattr(kvp, 'scope', scope) scope = get_datastore_full_scope(scope) self._validate_scope(scope=scope) user = getattr(kvp, 'user', requester_user) or requester_user # Validate that the authenticated user is admin if user query param is provided assert_request_user_is_admin_if_user_query_param_is_provided( request=pecan.request, user=user) key_ref = get_key_reference(scope=scope, name=name, user=user) lock_name = self._get_lock_name_for_key(name=key_ref, scope=scope) LOG.debug('PUT scope: %s, name: %s', scope, name) # TODO: Custom permission check since the key doesn't need to exist here # Note: We use lock to avoid a race with self._coordinator.get_lock(lock_name): try: existing_kvp_api = self._get_one_by_scope_and_name( scope=scope, name=key_ref) except StackStormDBObjectNotFoundError: existing_kvp_api = None kvp.name = key_ref kvp.scope = scope try: kvp_db = KeyValuePairAPI.to_model(kvp) if existing_kvp_api: kvp_db.id = existing_kvp_api.id kvp_db = KeyValuePair.add_or_update(kvp_db) except (ValidationError, ValueError) as e: LOG.exception('Validation failed for key value data=%s', kvp) abort(http_client.BAD_REQUEST, str(e)) return except CryptoKeyNotSetupException as e: LOG.exception(str(e)) abort(http_client.BAD_REQUEST, str(e)) return except InvalidScopeException as e: LOG.exception(str(e)) abort(http_client.BAD_REQUEST, str(e)) return extra = {'kvp_db': kvp_db} LOG.audit('KeyValuePair updated. KeyValuePair.id=%s' % (kvp_db.id), extra=extra) kvp_api = KeyValuePairAPI.from_model(kvp_db) return kvp_api
def post(self, payload): action_alias_name = payload.name if payload else None if not action_alias_name: pecan.abort(http_client.BAD_REQUEST, 'Alias execution "name" is required') format_str = payload.format or '' command = payload.command or '' try: action_alias_db = ActionAlias.get_by_name(action_alias_name) except ValueError: action_alias_db = None if not action_alias_db: msg = 'Unable to identify action alias with name "%s".' % (action_alias_name) pecan.abort(http_client.NOT_FOUND, msg) return if not action_alias_db.enabled: msg = 'Action alias with name "%s" is disabled.' % (action_alias_name) pecan.abort(http_client.BAD_REQUEST, msg) return execution_parameters = extract_parameters_for_action_alias_db( action_alias_db=action_alias_db, format_str=format_str, param_stream=command) notify = self._get_notify_field(payload) context = { 'action_alias_ref': reference.get_ref_from_model(action_alias_db), 'api_user': payload.user, 'user': get_requester(), 'source_channel': payload.source_channel } execution = self._schedule_execution(action_alias_db=action_alias_db, params=execution_parameters, notify=notify, context=context) result = { 'execution': execution, 'actionalias': ActionAliasAPI.from_model(action_alias_db) } if action_alias_db.ack: if 'format' in action_alias_db.ack: result.update({ 'message': render({'alias': action_alias_db.ack['format']}, result)['alias'] }) if 'extra' in action_alias_db.ack: result.update({ 'extra': render(action_alias_db.ack['extra'], result) }) return result
def post(self, payload): action_alias_name = payload.name if payload else None if not action_alias_name: pecan.abort(http_client.BAD_REQUEST, 'Alias execution "name" is required') format_str = payload.format or '' command = payload.command or '' try: action_alias_db = ActionAlias.get_by_name(action_alias_name) except ValueError: action_alias_db = None if not action_alias_db: msg = 'Unable to identify action alias with name "%s".' % ( action_alias_name) pecan.abort(http_client.NOT_FOUND, msg) return if not action_alias_db.enabled: msg = 'Action alias with name "%s" is disabled.' % ( action_alias_name) pecan.abort(http_client.BAD_REQUEST, msg) return execution_parameters = self._extract_parameters( action_alias_db=action_alias_db, format_str=format_str, param_stream=command) notify = self._get_notify_field(payload) context = { 'action_alias_ref': reference.get_ref_from_model(action_alias_db), 'api_user': payload.user, 'user': get_requester(), 'source_channel': payload.source_channel } execution = self._schedule_execution(action_alias_db=action_alias_db, params=execution_parameters, notify=notify, context=context) result = { 'execution': execution, 'actionalias': ActionAliasAPI.from_model(action_alias_db) } if action_alias_db.ack and 'format' in action_alias_db.ack: result.update({ 'message': render({'alias': action_alias_db.ack['format']}, result)['alias'] }) return result
def _validate_decrypt_query_parameter(self, decrypt, scope, is_admin): """ Validate that the provider user is either admin or requesting to decrypt value for themselves. """ requester_user = get_requester() if decrypt and (scope != USER_SCOPE and not is_admin): msg = 'Decrypt option requires administrator access' raise AccessDeniedError(message=msg, user_db=requester_user)
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: # 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 assert_request_user_is_admin_if_user_query_param_is_provider(request, user): """ Function which asserts that the request user is administator if "user" query parameter is provided and doesn't match the current user. """ requester_user = get_requester() is_admin = request_user_is_admin(request=request) if user != requester_user and not is_admin: msg = '"user" attribute can only be provided by admins' raise AccessDeniedError(message=msg, user_db=requester_user)
def assert_request_user_is_admin_if_user_query_param_is_provider( request, user): """ Function which asserts that the request user is administator if "user" query parameter is provided and doesn't match the current user. """ requester_user = get_requester() is_admin = request_user_is_admin(request=request) if user != requester_user and not is_admin: msg = '"user" attribute can only be provided by admins' raise AccessDeniedError(message=msg, user_db=requester_user)
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 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 get_all(self, prefix=None, scope=FULL_SYSTEM_SCOPE, user=None, decrypt=False, **kwargs): """ List all keys. Handles requests: GET /keys/ """ if not scope: scope = FULL_SYSTEM_SCOPE if user: # Providing a user implies a user scope scope = FULL_USER_SCOPE scope = get_datastore_full_scope(scope) requester_user = get_requester() user = user or requester_user is_all_scope = (scope == ALL_SCOPE) is_admin = request_user_is_admin(request=pecan.request) if is_all_scope and not is_admin: msg = '"all" scope requires administrator access' raise AccessDeniedError(message=msg, user_db=requester_user) # User needs to be either admin or requesting items for themselves self._validate_decrypt_query_parameter(decrypt=decrypt, scope=scope, is_admin=is_admin) # Validate that the authenticated user is admin if user query param is provided assert_request_user_is_admin_if_user_query_param_is_provider(request=pecan.request, user=user) from_model_kwargs = {'mask_secrets': not decrypt} kwargs['prefix'] = prefix if scope and scope not in ALL_SCOPE: self._validate_scope(scope=scope) kwargs['scope'] = scope if scope == USER_SCOPE or scope == FULL_USER_SCOPE: # Make sure we only returned values scoped to current user if kwargs['prefix']: kwargs['prefix'] = get_key_reference(name=kwargs['prefix'], scope=scope, user=requester_user) else: kwargs['prefix'] = get_key_reference(name='', scope=scope, user=user) kvp_apis = super(KeyValuePairController, self)._get_all(from_model_kwargs=from_model_kwargs, **kwargs) return kvp_apis
def delete(self, name, scope=FULL_SYSTEM_SCOPE, user=None): """ Delete the key value pair. Handles requests: DELETE /keys/1 """ if not scope: scope = FULL_SYSTEM_SCOPE scope = get_datastore_full_scope(scope) self._validate_scope(scope=scope) requester_user = get_requester() user = user or requester_user # Validate that the authenticated user is admin if user query param is provided assert_request_user_is_admin_if_user_query_param_is_provider(request=pecan.request, user=user) key_ref = get_key_reference(scope=scope, name=name, user=user) lock_name = self._get_lock_name_for_key(name=key_ref, scope=scope) # Note: We use lock to avoid a race with self._coordinator.get_lock(lock_name): from_model_kwargs = {'mask_secrets': True} kvp_api = self._get_one_by_scope_and_name( name=key_ref, scope=scope, from_model_kwargs=from_model_kwargs ) kvp_db = KeyValuePairAPI.to_model(kvp_api) LOG.debug('DELETE /keys/ lookup with scope=%s name=%s found object: %s', scope, name, kvp_db) try: KeyValuePair.delete(kvp_db) except Exception as e: LOG.exception('Database delete encountered exception during ' 'delete of name="%s". ', name) abort(http_client.INTERNAL_SERVER_ERROR, str(e)) return extra = {'kvp_db': kvp_db} LOG.audit('KeyValuePair deleted. KeyValuePair.id=%s' % (kvp_db.id), extra=extra)
def delete(self, name, scope=FULL_SYSTEM_SCOPE, user=None): """ Delete the key value pair. Handles requests: DELETE /keys/1 """ if not scope: scope = FULL_SYSTEM_SCOPE scope = get_datastore_full_scope(scope) self._validate_scope(scope=scope) requester_user = get_requester() user = user or requester_user # Validate that the authenticated user is admin if user query param is provided assert_request_user_is_admin_if_user_query_param_is_provided( request=pecan.request, user=user) key_ref = get_key_reference(scope=scope, name=name, user=user) lock_name = self._get_lock_name_for_key(name=key_ref, scope=scope) # Note: We use lock to avoid a race with self._coordinator.get_lock(lock_name): from_model_kwargs = {'mask_secrets': True} kvp_api = self._get_one_by_scope_and_name( name=key_ref, scope=scope, from_model_kwargs=from_model_kwargs) kvp_db = KeyValuePairAPI.to_model(kvp_api) LOG.debug( 'DELETE /keys/ lookup with scope=%s name=%s found object: %s', scope, name, kvp_db) try: KeyValuePair.delete(kvp_db) except Exception as e: LOG.exception( 'Database delete encountered exception during ' 'delete of name="%s". ', name) abort(http_client.INTERNAL_SERVER_ERROR, str(e)) return extra = {'kvp_db': kvp_db} LOG.audit('KeyValuePair deleted. KeyValuePair.id=%s' % (kvp_db.id), extra=extra)
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 _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 post(self, payload): action_alias_name = payload.name if payload else None if not action_alias_name: pecan.abort(http_client.BAD_REQUEST, 'Alias execution "name" is required') format_str = payload.format or '' command = payload.command or '' try: action_alias_db = ActionAlias.get_by_name(action_alias_name) except ValueError: action_alias_db = None if not action_alias_db: msg = 'Unable to identify action alias with name "%s".' % (action_alias_name) pecan.abort(http_client.NOT_FOUND, msg) return if not action_alias_db.enabled: msg = 'Action alias with name "%s" is disabled.' % (action_alias_name) pecan.abort(http_client.BAD_REQUEST, msg) return execution_parameters = self._extract_parameters(action_alias_db=action_alias_db, format_str=format_str, param_stream=command) notify = self._get_notify_field(payload) context = { 'action_alias_ref': reference.get_ref_from_model(action_alias_db), 'api_user': payload.user, 'user': get_requester(), 'source_channel': payload.source_channel } execution = self._schedule_execution(action_alias_db=action_alias_db, params=execution_parameters, notify=notify, context=context) return str(execution.id)
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: # 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'] = 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)