def invoke_post_run(liveaction_db, action_db=None): LOG.info('Invoking post run for action execution %s.', liveaction_db.id) # Identify action and runner. if not action_db: action_db = action_db_utils.get_action_by_ref(liveaction_db.action) if not action_db: LOG.exception('Unable to invoke post run. Action %s no longer exists.', liveaction_db.action) return LOG.info('Action execution %s runs %s of runner type %s.', liveaction_db.id, action_db.name, action_db.runner_type['name']) # Get an instance of the action runner. runnertype_db = action_db_utils.get_runnertype_by_name( action_db.runner_type['name']) runner = runners.get_runner(runnertype_db.runner_module) # Configure the action runner. runner.action = action_db runner.action_name = action_db.name runner.action_execution_id = str(liveaction_db.id) runner.entry_point = content_utils.get_entry_point_abs_path( pack=action_db.pack, entry_point=action_db.entry_point) runner.context = getattr(liveaction_db, 'context', dict()) runner.callback = getattr(liveaction_db, 'callback', dict()) runner.libs_dir_path = content_utils.get_action_libs_abs_path( pack=action_db.pack, entry_point=action_db.entry_point) # Invoke the post_run method. runner.post_run(liveaction_db.status, liveaction_db.result)
def test_get_action_libs_abs_path(self): orig_path = cfg.CONF.content.system_packs_base_path cfg.CONF.content.system_packs_base_path = '/tests/packs' # entry point relative. acutal_path = get_action_libs_abs_path(pack='foo', entry_point='foo/bar.py') expected_path = os.path.join(cfg.CONF.content.system_packs_base_path, 'foo', 'actions', os.path.join('foo', ACTION_LIBS_DIR)) self.assertEqual(acutal_path, expected_path, 'Action libs path doesn\'t match.') # entry point absolute. acutal_path = get_action_libs_abs_path( pack='foo', entry_point='/tests/packs/foo/tmp/foo.py') expected_path = os.path.join('/tests/packs/foo/tmp', ACTION_LIBS_DIR) self.assertEqual(acutal_path, expected_path, 'Action libs path doesn\'t match.') cfg.CONF.content.system_packs_base_path = orig_path
def test_get_action_libs_abs_path(self): orig_path = cfg.CONF.content.system_packs_base_path cfg.CONF.content.system_packs_base_path = '/tests/packs' # entry point relative. acutal_path = get_action_libs_abs_path(pack='foo', entry_point='foo/bar.py') expected_path = os.path.join(cfg.CONF.content.system_packs_base_path, 'foo', 'actions', os.path.join('foo', ACTION_LIBS_DIR)) self.assertEqual(acutal_path, expected_path, 'Action libs path doesn\'t match.') # entry point absolute. acutal_path = get_action_libs_abs_path( pack='foo', entry_point='/tests/packs/foo/tmp/foo.py') expected_path = os.path.join('/tests/packs/foo/tmp', ACTION_LIBS_DIR) self.assertEqual(acutal_path, expected_path, 'Action libs path doesn\'t match.') cfg.CONF.content.system_packs_base_path = orig_path
def invoke_post_run(liveaction_db, action_db=None): # NOTE: This import has intentionally been moved here to avoid massive performance overhead # (1+ second) for other functions inside this module which don't need to use those imports. from st2common.runners import base as runners from st2common.util import action_db as action_db_utils from st2common.content import utils as content_utils LOG.info("Invoking post run for action execution %s.", liveaction_db.id) # Identify action and runner. if not action_db: action_db = action_db_utils.get_action_by_ref(liveaction_db.action) if not action_db: LOG.error( "Unable to invoke post run. Action %s no longer exists.", liveaction_db.action, ) return LOG.info( "Action execution %s runs %s of runner type %s.", liveaction_db.id, action_db.name, action_db.runner_type["name"], ) # Get instance of the action runner and related configuration. runner_type_db = action_db_utils.get_runnertype_by_name( action_db.runner_type["name"]) runner = runners.get_runner(name=runner_type_db.name) entry_point = content_utils.get_entry_point_abs_path( pack=action_db.pack, entry_point=action_db.entry_point) libs_dir_path = content_utils.get_action_libs_abs_path( pack=action_db.pack, entry_point=action_db.entry_point) # Configure the action runner. runner.runner_type_db = runner_type_db runner.action = action_db runner.action_name = action_db.name runner.liveaction = liveaction_db runner.liveaction_id = str(liveaction_db.id) runner.entry_point = entry_point runner.context = getattr(liveaction_db, "context", dict()) runner.callback = getattr(liveaction_db, "callback", dict()) runner.libs_dir_path = libs_dir_path # Invoke the post_run method. runner.post_run(liveaction_db.status, liveaction_db.result)
def get_action_libs_abs_path(pack=None, entry_point=None): return utils.get_action_libs_abs_path(pack, entry_point)
def _get_action_libs_abs_path(self, pack, entry_point): return content_utils.get_action_libs_abs_path(pack=pack, entry_point=entry_point)
def _get_action_libs_abs_path(self, pack, entry_point): return content_utils.get_action_libs_abs_path(pack=pack, entry_point=entry_point)
def base(event, context, passthrough=False): # Set up logging logger = logging.getLogger() # Read DEBUG value from the environment variable debug = os.environ.get('ST2_DEBUG', False) if str(debug).lower() in ['true', '1']: debug = True if debug: logger.setLevel(logging.DEBUG) else: logger.setLevel(logging.INFO) if isinstance(event, basestring): try: event = json.loads(event) except ValueError as e: LOG.error("ERROR: Can not parse `event`: '{}'\n{}".format( str(event), str(e))) raise e LOG.info("Received event: " + json.dumps(event, indent=2)) # Special case for Lambda function being called over HTTP via API gateway # See # https://serverless.com/framework/docs/providers/aws/events/apigateway # #example-lambda-proxy-event-default # for details is_event_body_string = (isinstance(event.get('body'), basestring) is True) content_type = event.get('headers', {}).get('content-type', '').lower() if is_event_body_string: if content_type == 'application/json': try: event['body'] = json.loads(event['body']) except Exception as e: LOG.warn('`event` has `body` which is not JSON: %s', str(e.message)) elif content_type == 'application/x-www-form-urlencoded': try: event['body'] = dict( parse_qsl(['body'], keep_blank_values=True)) except Exception as e: LOG.warn('`event` has `body` which is not `%s`: %s', content_type, str(e.message)) else: LOG.warn('Unsupported event content type: %s' % (content_type)) action_name = os.environ['ST2_ACTION'] try: action_db = ACTIONS[action_name] except KeyError: raise ValueError('No action named "%s" has been installed.' % (action_name)) manager = DriverManager(namespace='st2common.runners.runner', invoke_on_load=False, name=action_db.runner_type['name']) runnertype_db = RunnerTypeAPI.to_model( RunnerTypeAPI(**manager.driver.get_metadata()[0])) if passthrough: runner = PassthroughRunner() else: runner = manager.driver.get_runner() runner._sandbox = False runner.runner_type_db = runnertype_db runner.action = action_db runner.action_name = action_db.name # runner.liveaction = liveaction_db # runner.liveaction_id = str(liveaction_db.id) # runner.execution = ActionExecution.get(liveaction__id=runner.liveaction_id) # runner.execution_id = str(runner.execution.id) runner.entry_point = content_utils.get_entry_point_abs_path( pack=action_db.pack, entry_point=action_db.entry_point) runner.context = {} # getattr(liveaction_db, 'context', dict()) # runner.callback = getattr(liveaction_db, 'callback', dict()) runner.libs_dir_path = content_utils.get_action_libs_abs_path( pack=action_db.pack, entry_point=action_db.entry_point) # For re-run, get the ActionExecutionDB in which the re-run is based on. # rerun_ref_id = runner.context.get('re-run', {}).get('ref') # runner.rerun_ex_ref = ActionExecution.get(id=rerun_ref_id) if rerun_ref_id else None config_schema = CONFIG_SCHEMAS.get(action_db.pack, None) config_values = os.environ.get('ST2_CONFIG', None) if config_schema and config_values: runner._config = validate_config_against_schema( config_schema=config_schema, config_object=json.loads(config_values), config_path=None, pack_name=action_db.pack) param_values = os.environ.get('ST2_PARAMETERS', None) try: if param_values: live_params = param_utils.render_live_params( runner_parameters=runnertype_db.runner_parameters, action_parameters=action_db.parameters, params=json.loads(param_values), action_context={}, additional_contexts={'input': event}) else: live_params = event if debug and 'log_level' not in live_params: # Set log_level runner parameter live_params['log_level'] = 'DEBUG' runner_params, action_params = param_utils.render_final_params( runner_parameters=runnertype_db.runner_parameters, action_parameters=action_db.parameters, params=live_params, action_context={}) except ParamException as e: raise actionrunner.ActionRunnerException(str(e)) runner.runner_parameters = runner_params LOG.debug('Performing pre-run for runner: %s', runner.runner_id) runner.pre_run() (status, output, context) = runner.run(action_params) output_values = os.environ.get('ST2_OUTPUT', None) if output_values: try: result = param_utils.render_live_params( runner_parameters=runnertype_db.runner_parameters, action_parameters=action_db.parameters, params=json.loads(output_values), action_context={}, additional_contexts={ 'input': event, 'output': output }) except ParamException as e: raise actionrunner.ActionRunnerException(str(e)) else: result = output # Log the logs generated by the action. We do that so the actual action logs # (action stderr) end up in CloudWatch output = output or {} if output.get('stdout', None): LOG.info('Action stdout: %s' % (output['stdout'])) if output.get('stderr', None): LOG.info('Action stderr and logs: %s' % (output['stderr'])) return { 'event': event, 'live_params': live_params, 'output': output, 'result': result }
def get_action_libs_abs_path(pack=None, entry_point=None): return utils.get_action_libs_abs_path(pack, entry_point)
def main(): # Read DEBUG value from the environment variable debug = os.environ.get('ST2_DEBUG', False) if str(debug).lower() in ['true', '1']: debug = True if debug: LOG.setLevel(logging.DEBUG) else: LOG.setLevel(logging.INFO) # Read input = os.environ.get('ST2_INPUT', {}) if isinstance(input, six.string_types): try: input = json.loads(input) except ValueError as e: LOG.error("ERROR: Can not parse `input`: '{}'\n{}".format(str(input), str(e))) raise e LOG.debug("Received input: " + json.dumps(input, indent=2)) # Read action name from environment variable action_name = os.environ['ST2_ACTION'] try: action_db = ACTIONS[action_name] except KeyError: raise ValueError('No action named "%s" has been installed.' % (action_name)) # Initialize runner manager = DriverManager(namespace='st2common.runners.runner', invoke_on_load=False, name=action_db.runner_type['name']) runnertype_db = RunnerTypeAPI.to_model(RunnerTypeAPI(**manager.driver.get_metadata())) runner = manager.driver.get_runner() runner._sandbox = False runner.runner_type_db = runnertype_db runner.action = action_db runner.action_name = action_db.name runner.entry_point = content_utils.get_entry_point_abs_path(pack=action_db.pack, entry_point=action_db.entry_point) runner.context = {} runner.libs_dir_path = content_utils.get_action_libs_abs_path(pack=action_db.pack, entry_point=action_db.entry_point) config_schema = CONFIG_SCHEMAS.get(action_db.pack, None) config_values = os.environ.get('ST2_CONFIG', None) if config_schema and config_values: runner._config = validate_config_against_schema(config_schema=config_schema, config_object=json.loads(config_values), config_path=None, pack_name=action_db.pack) param_values = os.environ.get('ST2_PARAMETERS', None) try: if param_values: live_params = param_utils.render_live_params( runner_parameters=runnertype_db.runner_parameters, action_parameters=action_db.parameters, params=json.loads(param_values), action_context={}, additional_contexts={ 'input': input }) else: live_params = input if debug and 'log_level' not in live_params: # Set log_level runner parameter live_params['log_level'] = 'DEBUG' runner_params, action_params = param_utils.render_final_params( runner_parameters=runnertype_db.runner_parameters, action_parameters=action_db.parameters, params=live_params, action_context={}) except ParamException as e: raise actionrunner.ActionRunnerException(str(e)) runner.runner_parameters = runner_params LOG.debug('Performing pre-run for runner: %s', runner.runner_id) runner.pre_run() (status, output, context) = runner.run(action_params) try: output['result'] = json.loads(output['result']) except Exception: pass output_values = os.environ.get('ST2_OUTPUT', None) if output_values: try: result = param_utils.render_live_params( runner_parameters={}, action_parameters={}, params=json.loads(output_values), action_context={}, additional_contexts={ 'input': input, 'output': output }) except ParamException as e: raise actionrunner.ActionRunnerException(str(e)) else: result = output output = output or {} if output.get('stdout', None): LOG.info('Action stdout: %s' % (output['stdout'])) if output.get('stderr', None): LOG.info('Action stderr and logs: %s' % (output['stderr'])) print(json.dumps(result))