def dispatch(self, actionexec_db): action_ref = ResourceReference.from_string_reference(ref=actionexec_db.action) (action_db, _) = get_action_by_dict( {'name': action_ref.name, 'pack': action_ref.pack}) runnertype_db = get_runnertype_by_name(action_db.runner_type['name']) runner_type = runnertype_db.name LOG.info('Dispatching runner for Action "%s"', actionexec_db) LOG.debug(' liverunner_type: %s', runner_type) LOG.debug(' RunnerType: %s', runnertype_db) LOG.debug(' ActionExecution: %s', actionexec_db) # Get runner instance. runner = self._get_runner(runnertype_db) LOG.debug('Runner instance for RunnerType "%s" is: %s', runnertype_db.name, runner) # Invoke pre_run, run, post_run cycle. result, actionexec_db = self._do_run(runner, runnertype_db, action_db, actionexec_db) LOG.debug('runner do_run result: %s', result) actionsensor.post_trigger(actionexec_db) LOG.audit('ActionExecution complete.', extra={'actionexecution': actionexec_db.to_serializable_dict()}) return result
def get_by_ref(cls, ref): if not ref: return None ref_obj = ResourceReference.from_string_reference(ref=ref) result = cls.query(name=ref_obj.name, pack=ref_obj.pack).first() return result
def _get_trigger_instance_db_from_file(self, file_path): data = self._meta_loader.load(file_path=file_path) instance = TriggerInstanceDB(**data) trigger_ref = ResourceReference.from_string_reference(instance['trigger']) trigger_db = TriggerDB(pack=trigger_ref.pack, name=trigger_ref.name, type=trigger_ref.ref) return instance, trigger_db
def user_has_rule_action_permission(user_db, action_ref): """ Check that the currently logged-in has necessary permissions on the action used / referenced inside the rule. Note: Rules can reference actions which don't yet exist in the system. """ if not cfg.CONF.rbac.enable: return True action_db = action_utils.get_action_by_ref(ref=action_ref) if not action_db: # We allow rules to be created for actions which don't yet exist in the # system ref = ResourceReference.from_string_reference(ref=action_ref) action_db = ActionDB(pack=ref.pack, name=ref.name, ref=action_ref) action_resolver = resolvers.get_resolver_for_resource_type(ResourceType.ACTION) has_action_permission = action_resolver.user_has_resource_db_permission( user_db=user_db, resource_db=action_db, permission_type=PermissionType.ACTION_EXECUTE) if has_action_permission: return True return False
def get_trigger_db(trigger): # TODO: This method should die in a fire if isinstance(trigger, str) or isinstance(trigger, unicode): # Assume reference was passed in ref_obj = ResourceReference.from_string_reference(ref=trigger) return _get_trigger_db_by_name_and_pack(name=ref_obj.name, pack=ref_obj.pack) if isinstance(trigger, dict): name = trigger.get('name', None) pack = trigger.get('pack', None) if name and pack: return _get_trigger_db_by_name_and_pack(name=name, pack=pack) return _get_trigger_db(type=trigger['type'], parameters=trigger.get('parameters', {})) if isinstance(trigger, object): name = getattr(trigger, 'name', None) pack = getattr(trigger, 'pack', None) parameters = getattr(trigger, 'parameters', {}) trigger_db = None if name and pack: trigger_db = _get_trigger_db_by_name_and_pack(name=name, pack=pack) else: trigger_db = _get_trigger_db(type=trigger.type, parameters=parameters) return trigger_db else: raise Exception('Unrecognized object')
def to_model(cls, trigger): name = getattr(trigger, "name", None) description = getattr(trigger, "description", None) pack = getattr(trigger, "pack", None) _type = getattr(trigger, "type", None) parameters = getattr(trigger, "parameters", {}) if _type and not parameters: trigger_type_ref = ResourceReference.from_string_reference(_type) name = trigger_type_ref.name if hasattr(trigger, "name") and trigger.name: name = trigger.name else: # assign a name if none is provided. name = str(uuid.uuid4()) model = cls.model( name=name, description=description, pack=pack, type=_type, parameters=parameters, ) return model
def user_has_rule_action_permission(user_db, action_ref): """ Check that the currently logged-in has necessary permissions on the action used / referenced inside the rule. Note: Rules can reference actions which don't yet exist in the system. """ if not cfg.CONF.rbac.enable: return True action_db = action_utils.get_action_by_ref(ref=action_ref) if not action_db: # We allow rules to be created for actions which don't yet exist in the # system ref = ResourceReference.from_string_reference(ref=action_ref) action_db = ActionDB(pack=ref.pack, name=ref.name, ref=action_ref) rbac_backend = get_backend_instance(cfg.CONF.rbac.backend) action_resolver = rbac_backend.get_resolver_for_resource_type( ResourceType.ACTION) has_action_permission = action_resolver.user_has_resource_db_permission( user_db=user_db, resource_db=action_db, permission_type=PermissionType.ACTION_EXECUTE) if has_action_permission: return True return False
def _get_trigger_instance_db_from_file(self, file_path): data = self._meta_loader.load(file_path=file_path) instance = TriggerInstanceDB(**data) trigger_ref = ResourceReference.from_string_reference(instance['trigger']) trigger_db = TriggerDB(pack=trigger_ref.pack, name=trigger_ref.name, type=trigger_ref.ref) return instance, trigger_db
def dispatch(self, actionexec_db): action_ref = ResourceReference.from_string_reference( ref=actionexec_db.action) (action_db, _) = get_action_by_dict({ 'name': action_ref.name, 'pack': action_ref.pack }) runnertype_db = get_runnertype_by_name(action_db.runner_type['name']) runner_type = runnertype_db.name LOG.info('Dispatching runner for Action "%s"', actionexec_db) LOG.debug(' liverunner_type: %s', runner_type) LOG.debug(' RunnerType: %s', runnertype_db) LOG.debug(' ActionExecution: %s', actionexec_db) # Get runner instance. runner = self._get_runner(runnertype_db) LOG.debug('Runner instance for RunnerType "%s" is: %s', runnertype_db.name, runner) # Invoke pre_run, run, post_run cycle. result, actionexec_db = self._do_run(runner, runnertype_db, action_db, actionexec_db) LOG.debug('runner do_run result: %s', result) actionsensor.post_trigger(actionexec_db) LOG.audit( 'ActionExecution complete. actionexec_id="%s" resulted in ' 'actionexecution_db="%s"', actionexec_db.id, actionexec_db) return result
def record_action_execution(self, body): try: history_id = bson.ObjectId() execution = ActionExecution.get_by_id(str(body.id)) action_ref = ResourceReference.from_string_reference( ref=execution.action) action_db, _ = action_utils.get_action_by_dict({ 'name': action_ref.name, 'pack': action_ref.pack }) runner = RunnerType.get_by_name(action_db.runner_type['name']) attrs = { 'id': history_id, 'action': vars(ActionAPI.from_model(action_db)), 'runner': vars(RunnerTypeAPI.from_model(runner)), 'execution': vars(ActionExecutionAPI.from_model(execution)) } if 'rule' in execution.context: rule = reference.get_model_from_ref( Rule, execution.context.get('rule', {})) attrs['rule'] = vars(RuleAPI.from_model(rule)) if 'trigger_instance' in execution.context: trigger_instance_id = execution.context.get( 'trigger_instance', {}) trigger_instance_id = trigger_instance_id.get('id', None) trigger_instance = TriggerInstance.get_by_id( trigger_instance_id) trigger = reference.get_model_by_resource_ref( db_api=Trigger, ref=trigger_instance.trigger) trigger_type = reference.get_model_by_resource_ref( db_api=TriggerType, ref=trigger.type) trigger_instance = reference.get_model_from_ref( TriggerInstance, execution.context.get('trigger_instance', {})) attrs['trigger_instance'] = vars( TriggerInstanceAPI.from_model(trigger_instance)) attrs['trigger'] = vars(TriggerAPI.from_model(trigger)) attrs['trigger_type'] = vars( TriggerTypeAPI.from_model(trigger_type)) parent = ActionExecutionHistory.get( execution__id=execution.context.get('parent', '')) if parent: attrs['parent'] = str(parent.id) if str(history_id) not in parent.children: parent.children.append(str(history_id)) ActionExecutionHistory.add_or_update(parent) history = ActionExecutionHistoryDB(**attrs) history = ActionExecutionHistory.add_or_update(history) except: LOG.exception('An unexpected error occurred while creating the ' 'action execution history.') raise
def _get_by_ref(self, resource_ref): try: ref = ResourceReference.from_string_reference(ref=resource_ref) except Exception: return None resource_db = self.access.query(name=ref.name, pack=ref.pack).first() return resource_db
def _get_by_ref(self, resource_ref): try: ref = ResourceReference.from_string_reference(ref=resource_ref) except Exception: return None resource_db = self.access.query(name=ref.name, pack=ref.pack).first() return resource_db
def get_by_ref(cls, ref): if not ref: return None ref_obj = ResourceReference.from_string_reference(ref=ref) result = cls.query(name=ref_obj.name, pack=ref_obj.pack).first() return result
def _get_trigger_dict_given_rule(rule): trigger = rule.trigger trigger_dict = {} triggertype_ref = ResourceReference.from_string_reference(trigger.get('type')) trigger_dict['pack'] = trigger_dict.get('pack', triggertype_ref.pack) trigger_dict['type'] = triggertype_ref.ref trigger_dict['parameters'] = rule.trigger.get('parameters', {}) return trigger_dict
def get_action_by_ref(action_ref): if (not isinstance(action_ref, str) and not isinstance(action_ref, unicode) and not isinstance(action_ref, ResourceReference)): raise Exception('Action reference has to be either str or ResourceReference.') if isinstance(action_ref, str) or isinstance(action_ref, unicode): action_ref = ResourceReference.from_string_reference(ref=action_ref) return _get_action_by_pack_and_name(name=action_ref.name, pack=action_ref.pack)
def _get_trigger_dict_given_rule(rule): trigger = rule.trigger trigger_dict = {} triggertype_ref = ResourceReference.from_string_reference(trigger.get("type")) trigger_dict["pack"] = trigger_dict.get("pack", triggertype_ref.pack) trigger_dict["type"] = triggertype_ref.ref trigger_dict["parameters"] = rule.trigger.get("parameters", {}) return trigger_dict
def _get_trigger_dict_given_rule(rule): trigger = rule.trigger trigger_dict = {} triggertype_ref = ResourceReference.from_string_reference(trigger.get('type')) trigger_dict['pack'] = trigger_dict.get('pack', triggertype_ref.pack) trigger_dict['type'] = triggertype_ref.ref trigger_dict['parameters'] = rule.trigger.get('parameters', {}) return trigger_dict
def test_triggered_execution(self): docs = { 'trigger_type': copy.deepcopy(fixture.ARTIFACTS['trigger_type']), 'trigger': copy.deepcopy(fixture.ARTIFACTS['trigger']), 'rule': copy.deepcopy(fixture.ARTIFACTS['rule']), 'trigger_instance': copy.deepcopy(fixture.ARTIFACTS['trigger_instance']) } # Trigger an action execution. trigger_type = TriggerType.add_or_update( TriggerTypeAPI.to_model(TriggerTypeAPI(**docs['trigger_type']))) trigger = Trigger.add_or_update( TriggerAPI.to_model(TriggerAPI(**docs['trigger']))) rule = RuleAPI.to_model(RuleAPI(**docs['rule'])) rule.trigger = reference.get_str_resource_ref_from_model(trigger) rule = Rule.add_or_update(rule) trigger_instance = TriggerInstance.add_or_update( TriggerInstanceAPI.to_model( TriggerInstanceAPI(**docs['trigger_instance']))) enforcer = RuleEnforcer(trigger_instance, rule) enforcer.enforce() # Wait for the action execution to complete and then confirm outcome. execution = ActionExecution.get( context__trigger_instance__id=str(trigger_instance.id)) self.assertIsNotNone(execution) execution = ActionExecution.get_by_id(str(execution.id)) self.assertEqual(execution.status, ACTIONEXEC_STATUS_SUCCEEDED) history = ActionExecutionHistory.get(execution__id=str(execution.id), raise_exception=True) self.assertDictEqual(history.trigger, vars(TriggerAPI.from_model(trigger))) self.assertDictEqual(history.trigger_type, vars(TriggerTypeAPI.from_model(trigger_type))) self.assertDictEqual( history.trigger_instance, vars(TriggerInstanceAPI.from_model(trigger_instance))) self.assertDictEqual(history.rule, vars(RuleAPI.from_model(rule))) action_ref = ResourceReference.from_string_reference( ref=execution.action) action, _ = action_utils.get_action_by_dict({ 'name': action_ref.name, 'pack': action_ref.pack }) self.assertDictEqual(history.action, vars(ActionAPI.from_model(action))) runner = RunnerType.get_by_name(action.runner_type['name']) self.assertDictEqual(history.runner, vars(RunnerTypeAPI.from_model(runner))) execution = ActionExecution.get_by_id(str(execution.id)) self.assertDictEqual(history.execution, vars(ActionExecutionAPI.from_model(execution)))
def _get_trigger_dict_given_rule(rule): trigger = rule.trigger trigger_dict = {} triggertype_ref = ResourceReference.from_string_reference( trigger.get("type")) trigger_dict["pack"] = trigger_dict.get("pack", triggertype_ref.pack) trigger_dict["type"] = triggertype_ref.ref trigger_dict["parameters"] = rule.trigger.get("parameters", {}) return trigger_dict
def get_reference(self): """ Retrieve referene object for this model. :rtype: :class:`ResourceReference` """ if getattr(self, 'ref', None): ref = ResourceReference.from_string_reference(ref=self.ref) else: ref = ResourceReference(pack=self.pack, name=self.name) return ref
def get_reference(self): """ Retrieve referene object for this model. :rtype: :class:`ResourceReference` """ if getattr(self, 'ref', None): ref = ResourceReference.from_string_reference(ref=self.ref) else: ref = ResourceReference(pack=self.pack, name=self.name) return ref
def get_action_by_ref(action_ref): if (not isinstance(action_ref, str) and not isinstance(action_ref, unicode) and not isinstance(action_ref, ResourceReference)): raise Exception( 'Action reference has to be either str or ResourceReference.') if isinstance(action_ref, str) or isinstance(action_ref, unicode): action_ref = ResourceReference.from_string_reference(ref=action_ref) return _get_action_by_pack_and_name(name=action_ref.name, pack=action_ref.pack)
def _get_trigger_api_given_rule(rule): trigger = rule.trigger triggertype_ref = ResourceReference.from_string_reference(trigger.get('type')) trigger_dict = {} trigger_name = trigger.get('name', None) if trigger_name: trigger_dict['name'] = trigger_name trigger_dict['pack'] = triggertype_ref.pack trigger_dict['type'] = triggertype_ref.ref trigger_dict['parameters'] = rule.trigger.get('parameters', {}) trigger_api = TriggerAPI(**trigger_dict) return trigger_api
def test_resource_reference_success(self): value = "pack1.name1" ref = ResourceReference.from_string_reference(ref=value) self.assertEqual(ref.pack, "pack1") self.assertEqual(ref.name, "name1") self.assertEqual(ref.ref, value) ref = ResourceReference(pack="pack1", name="name1") self.assertEqual(ref.ref, "pack1.name1") ref = ResourceReference(pack="pack1", name="name1.name2") self.assertEqual(ref.ref, "pack1.name1.name2")
def test_resource_reference_success(self): value = 'pack1.name1' ref = ResourceReference.from_string_reference(ref=value) self.assertEqual(ref.pack, 'pack1') self.assertEqual(ref.name, 'name1') self.assertEqual(ref.ref, value) ref = ResourceReference(pack='pack1', name='name1') self.assertEqual(ref.ref, 'pack1.name1') ref = ResourceReference(pack='pack1', name='name1.name2') self.assertEqual(ref.ref, 'pack1.name1.name2')
def _to_trigger(self, body): trigger = body.get('trigger', '') trigger_ref = None try: trigger_ref = ResourceReference.from_string_reference(ref=trigger) except InvalidResourceReferenceError: LOG.debug('Unable to parse reference.', exc_info=True) return { 'name': trigger_ref.name if trigger_ref else None, 'pack': trigger_ref.pack if trigger_ref else None, 'type': body.get('type', ''), 'parameters': {} }, body['payload']
def _to_trigger(self, body): trigger = body.get('trigger', '') trigger_ref = None try: trigger_ref = ResourceReference.from_string_reference(ref=trigger) except InvalidResourceReferenceError: LOG.debug('Unable to parse reference.', exc_info=True) return { 'name': trigger_ref.name if trigger_ref else None, 'pack': trigger_ref.pack if trigger_ref else None, 'type': body.get('type', ''), 'parameters': {} }, body['payload']
def get_by_ref(cls, ref, only_fields: Optional[List[str]] = None): """ :param: only_field: Optional lists if fields to retrieve. If not specified, it defaults to all fields. """ if not ref: return None ref_obj = ResourceReference.from_string_reference(ref=ref) result = cls.query(name=ref_obj.name, pack=ref_obj.pack, only_fields=only_fields).first() return result
def get_model_by_resource_ref(db_api, ref): """ Retrieve a DB model based on the resource reference. :param db_api: Class of the object to retrieve. :type db_api: ``object`` :param ref: Resource reference. :type ref: ``str`` :return: Retrieved object. """ ref_obj = ResourceReference.from_string_reference(ref=ref) result = db_api.query(name=ref_obj.name, pack=ref_obj.pack).first() return result
def _get_by_ref(self, resource_ref, exclude_fields=None, include_fields=None): if exclude_fields and include_fields: msg = ('exclude_fields and include_fields arguments are mutually exclusive. ' 'You need to provide either one or another, but not both.') raise ValueError(msg) try: ref = ResourceReference.from_string_reference(ref=resource_ref) except Exception: return None resource_db = self.access.query(name=ref.name, pack=ref.pack, exclude_fields=exclude_fields, only_fields=include_fields).first() return resource_db
def _get_by_ref(self, resource_ref, exclude_fields=None, include_fields=None): if exclude_fields and include_fields: msg = ('exclude_fields and include_fields arguments are mutually exclusive. ' 'You need to provide either one or another, but not both.') raise ValueError(msg) try: ref = ResourceReference.from_string_reference(ref=resource_ref) except Exception: return None resource_db = self.access.query(name=ref.name, pack=ref.pack, exclude_fields=exclude_fields, only_fields=include_fields).first() return resource_db
def _get_filters(self, **kwargs): filters = copy.deepcopy(kwargs) ref = filters.get('ref', None) if ref: try: ref_obj = ResourceReference.from_string_reference(ref=ref) except InvalidResourceReferenceError: raise filters['name'] = ref_obj.name filters['pack'] = ref_obj.pack del filters['ref'] return filters
def _get_filters(self, **kwargs): filters = copy.deepcopy(kwargs) ref = filters.get('ref', None) if ref: try: ref_obj = ResourceReference.from_string_reference(ref=ref) except InvalidResourceReferenceError: raise filters['name'] = ref_obj.name filters['pack'] = ref_obj.pack del filters['ref'] return filters
def get_model_by_resource_ref(db_api, ref): """ Retrieve a DB model based on the resource reference. :param db_api: Class of the object to retrieve. :type db_api: ``object`` :param ref: Resource reference. :type ref: ``str`` :return: Retrieved object. """ ref_obj = ResourceReference.from_string_reference(ref=ref) result = db_api.query(name=ref_obj.name, pack=ref_obj.pack).first() return result
def record_action_execution(self, body): try: history_id = bson.ObjectId() execution = ActionExecution.get_by_id(str(body.id)) action_ref = ResourceReference.from_string_reference(ref=execution.action) action_db, _ = action_utils.get_action_by_dict( {'name': action_ref.name, 'pack': action_ref.pack}) runner = RunnerType.get_by_name(action_db.runner_type['name']) attrs = { 'id': history_id, 'action': vars(ActionAPI.from_model(action_db)), 'runner': vars(RunnerTypeAPI.from_model(runner)), 'execution': vars(ActionExecutionAPI.from_model(execution)) } if 'rule' in execution.context: rule = reference.get_model_from_ref(Rule, execution.context.get('rule', {})) attrs['rule'] = vars(RuleAPI.from_model(rule)) if 'trigger_instance' in execution.context: trigger_instance_id = execution.context.get('trigger_instance', {}) trigger_instance_id = trigger_instance_id.get('id', None) trigger_instance = TriggerInstance.get_by_id(trigger_instance_id) trigger = reference.get_model_by_resource_ref(db_api=Trigger, ref=trigger_instance.trigger) trigger_type = reference.get_model_by_resource_ref(db_api=TriggerType, ref=trigger.type) trigger_instance = reference.get_model_from_ref( TriggerInstance, execution.context.get('trigger_instance', {})) attrs['trigger_instance'] = vars(TriggerInstanceAPI.from_model(trigger_instance)) attrs['trigger'] = vars(TriggerAPI.from_model(trigger)) attrs['trigger_type'] = vars(TriggerTypeAPI.from_model(trigger_type)) parent = ActionExecutionHistory.get(execution__id=execution.context.get('parent', '')) if parent: attrs['parent'] = str(parent.id) if str(history_id) not in parent.children: parent.children.append(str(history_id)) ActionExecutionHistory.add_or_update(parent) history = ActionExecutionHistoryDB(**attrs) history = ActionExecutionHistory.add_or_update(history) except: LOG.exception('An unexpected error occurred while creating the ' 'action execution history.') raise
def to_model(cls, trigger): model = super(cls, cls).to_model(trigger) model.pack = getattr(trigger, 'pack', None) model.type = getattr(trigger, 'type', None) model.parameters = getattr(trigger, 'parameters', {}) if model.type and not model.parameters: triggertype_ref = ResourceReference.from_string_reference(model.type) model.name = triggertype_ref.name if hasattr(trigger, 'name') and trigger.name: model.name = trigger.name else: # assign a name if none is provided. model.name = str(uuid.uuid4()) return model
def to_model(cls, trigger): model = super(cls, cls).to_model(trigger) model.pack = getattr(trigger, 'pack', None) model.type = getattr(trigger, 'type', None) model.parameters = getattr(trigger, 'parameters', {}) if model.type and not model.parameters: triggertype_ref = ResourceReference.from_string_reference( model.type) model.name = triggertype_ref.name if hasattr(trigger, 'name') and trigger.name: model.name = trigger.name else: # assign a name if none is provided. model.name = str(uuid.uuid4()) return model
def evaluate(self): """ Evaluate trigger instance against the rule. :return: ``True`` if the rule matches, ``False`` otherwise. :rtype: ``boolean`` """ rule_db = self._get_rule_db_from_file(file_path=self._rule_file_path) trigger_instance_db = \ self._get_trigger_instance_db_from_file(file_path=self._trigger_instance_file_path) trigger_ref = ResourceReference.from_string_reference(trigger_instance_db['trigger']) trigger_db = TriggerDB(pack=trigger_ref.pack, name=trigger_ref.name, type=trigger_ref.ref) matcher = RulesMatcher(trigger_instance=trigger_instance_db, trigger=trigger_db, rules=[rule_db]) matching_rules = matcher.get_matching_rules() return len(matching_rules) >= 1
def _transform_action(spec, action_key, input_key): if action_key not in spec or spec.get(action_key) == 'st2.action': return if spec.get(action_key) == 'st2.callback': raise Exception('st2.callback is deprecated.') # Convert parameters that are inline (i.e. action: some_action var1={$.value1} var2={$.value2}) # and split it to action name and input dict as illustrated below. # # action: some_action # input: # var1: <% $.value1 %> # var2: <% $.value2 %> # # This step to separate the action name and the input parameters is required # to wrap them with the st2.action proxy. # # action: st2.action # input: # ref: some_action # parameters: # var1: <% $.value1 %> # var2: <% $.value2 %> _eval_inline_params(spec, action_key, input_key) action_ref = spec.get(action_key) if action_ref and ResourceReference.is_resource_reference(action_ref): ref = ResourceReference.from_string_reference(ref=action_ref) actions = Action.query(name=ref.name, pack=ref.pack) action = actions.first() if actions else None else: action = None if action: spec[action_key] = 'st2.action' action_input = spec.get(input_key) spec[input_key] = {'ref': action_ref} if action_input: spec[input_key]['parameters'] = action_input
def _cast_params(action_ref, params): casts = { 'array': (lambda x: ast.literal_eval(x) if isinstance(x, str) or isinstance(x, unicode) else x), 'boolean': (lambda x: ast.literal_eval(x.capitalize()) if isinstance(x, str) or isinstance(x, unicode) else x), 'integer': int, 'number': float, 'object': (lambda x: json.loads(x) if isinstance(x, str) or isinstance(x, unicode) else x), 'string': str } action_db = action_db_util.get_action_by_ref( ResourceReference.from_string_reference(ref=action_ref)) action_parameters_schema = action_db.parameters runnertype_db = action_db_util.get_runnertype_by_name( action_db.runner_type['name']) runner_parameters_schema = runnertype_db.runner_parameters # combine into 1 list of parameter schemas parameters_schema = {} if runner_parameters_schema: parameters_schema.update(runner_parameters_schema) if action_parameters_schema: parameters_schema.update(action_parameters_schema) # cast each param individually for k, v in six.iteritems(params): parameter_schema = parameters_schema.get(k, None) if not parameter_schema: continue parameter_type = parameter_schema.get('type', None) if not parameter_type: continue cast = casts.get(parameter_type, None) if not cast: continue params[k] = cast(v) return params
def to_model(cls, trigger): name = getattr(trigger, 'name', None) description = getattr(trigger, 'description', None) pack = getattr(trigger, 'pack', None) _type = getattr(trigger, 'type', None) parameters = getattr(trigger, 'parameters', {}) if _type and not parameters: trigger_type_ref = ResourceReference.from_string_reference(_type) name = trigger_type_ref.name if hasattr(trigger, 'name') and trigger.name: name = trigger.name else: # assign a name if none is provided. name = str(uuid.uuid4()) model = cls.model(name=name, description=description, pack=pack, type=_type, parameters=parameters) return model
def _transform_action(spec, action_key, input_key): if action_key not in spec or spec.get(action_key) == 'st2.action': return if spec.get(action_key) == 'st2.callback': raise Exception('st2.callback is deprecated.') # Convert parameters that are inline (i.e. action: some_action var1={$.value1} var2={$.value2}) # and split it to action name and input dict as illustrated below. # # action: some_action # input: # var1: $.value1 # var2: $.value2 # # This step to separate the action name and the input parameters is required # to wrap them with the st2.action proxy. # # action: st2.action # input: # ref: some_action # parameters: # var1: $.value1 # var2: $.value2 _eval_inline_params(spec, action_key, input_key) action_ref = spec.get(action_key) if ResourceReference.is_resource_reference(action_ref): ref = ResourceReference.from_string_reference(ref=action_ref) actions = Action.query(name=ref.name, pack=ref.pack) action = actions.first() if actions else None else: action = None if action: spec[action_key] = 'st2.action' spec[input_key] = {'ref': action_ref, 'parameters': spec[input_key]}
def test_triggered_execution(self): docs = { 'trigger_type': copy.deepcopy(fixture.ARTIFACTS['trigger_type']), 'trigger': copy.deepcopy(fixture.ARTIFACTS['trigger']), 'rule': copy.deepcopy(fixture.ARTIFACTS['rule']), 'trigger_instance': copy.deepcopy(fixture.ARTIFACTS['trigger_instance'])} # Trigger an action execution. trigger_type = TriggerType.add_or_update( TriggerTypeAPI.to_model(TriggerTypeAPI(**docs['trigger_type']))) trigger = Trigger.add_or_update(TriggerAPI.to_model(TriggerAPI(**docs['trigger']))) rule = RuleAPI.to_model(RuleAPI(**docs['rule'])) rule.trigger = reference.get_str_resource_ref_from_model(trigger) rule = Rule.add_or_update(rule) trigger_instance = TriggerInstance.add_or_update( TriggerInstanceAPI.to_model(TriggerInstanceAPI(**docs['trigger_instance']))) enforcer = RuleEnforcer(trigger_instance, rule) enforcer.enforce() # Wait for the action execution to complete and then confirm outcome. execution = ActionExecution.get(context__trigger_instance__id=str(trigger_instance.id)) self.assertIsNotNone(execution) execution = ActionExecution.get_by_id(str(execution.id)) self.assertEqual(execution.status, ACTIONEXEC_STATUS_SUCCEEDED) history = ActionExecutionHistory.get(execution__id=str(execution.id), raise_exception=True) self.assertDictEqual(history.trigger, vars(TriggerAPI.from_model(trigger))) self.assertDictEqual(history.trigger_type, vars(TriggerTypeAPI.from_model(trigger_type))) self.assertDictEqual(history.trigger_instance, vars(TriggerInstanceAPI.from_model(trigger_instance))) self.assertDictEqual(history.rule, vars(RuleAPI.from_model(rule))) action_ref = ResourceReference.from_string_reference(ref=execution.action) action, _ = action_utils.get_action_by_dict( {'name': action_ref.name, 'pack': action_ref.pack}) self.assertDictEqual(history.action, vars(ActionAPI.from_model(action))) runner = RunnerType.get_by_name(action.runner_type['name']) self.assertDictEqual(history.runner, vars(RunnerTypeAPI.from_model(runner))) execution = ActionExecution.get_by_id(str(execution.id)) self.assertDictEqual(history.execution, vars(ActionExecutionAPI.from_model(execution)))
def evaluate(self): """ Evaluate trigger instance against the rule. :return: ``True`` if the rule matches, ``False`` otherwise. :rtype: ``boolean`` """ rule_db = self._get_rule_db_from_file(file_path=self._rule_file_path) trigger_instance_db = \ self._get_trigger_instance_db_from_file(file_path=self._trigger_instance_file_path) trigger_ref = ResourceReference.from_string_reference( trigger_instance_db['trigger']) trigger_db = TriggerDB(pack=trigger_ref.pack, name=trigger_ref.name, type=trigger_ref.ref) matcher = RulesMatcher(trigger_instance=trigger_instance_db, trigger=trigger_db, rules=[rule_db]) matching_rules = matcher.get_matching_rules() return len(matching_rules) >= 1
def _cast_params(action_ref, params): casts = { 'array': (lambda x: ast.literal_eval(x) if isinstance(x, str) or isinstance(x, unicode) else x), 'boolean': (lambda x: ast.literal_eval(x.capitalize()) if isinstance(x, str) or isinstance(x, unicode) else x), 'integer': int, 'number': float, 'object': (lambda x: json.loads(x) if isinstance(x, str) or isinstance(x, unicode) else x), 'string': str } action_db = action_db_util.get_action_by_ref( ResourceReference.from_string_reference(ref=action_ref)) action_parameters_schema = action_db.parameters runnertype_db = action_db_util.get_runnertype_by_name(action_db.runner_type['name']) runner_parameters_schema = runnertype_db.runner_parameters # combine into 1 list of parameter schemas parameters_schema = {} if runner_parameters_schema: parameters_schema.update(runner_parameters_schema) if action_parameters_schema: parameters_schema.update(action_parameters_schema) # cast each param individually for k, v in six.iteritems(params): parameter_schema = parameters_schema.get(k, None) if not parameter_schema: continue parameter_type = parameter_schema.get('type', None) if not parameter_type: continue cast = casts.get(parameter_type, None) if not cast: continue params[k] = cast(v) return params
def name_pack_query_args(ref): resource_ref = ResourceReference.from_string_reference(ref=ref) return {'name': resource_ref.name, 'pack': resource_ref.pack}
def name_pack_query_args(ref): resource_ref = ResourceReference.from_string_reference(ref=ref) return {"name": resource_ref.name, "pack": resource_ref.pack}
def name_pack_query_args(ref): resource_ref = ResourceReference.from_string_reference(ref=ref) return {'name': resource_ref.name, 'pack': resource_ref.pack}