Esempio n. 1
0
 def __init__(self, tester):
     self.tester = tester
     self.notify_trigger = ResourceReference.to_string_reference(
         pack=NOTIFY_TRIGGER_TYPE['pack'],
         name=NOTIFY_TRIGGER_TYPE['name'])
     self.action_trigger = ResourceReference.to_string_reference(
         pack=ACTION_TRIGGER_TYPE['pack'],
         name=ACTION_TRIGGER_TYPE['name'])
Esempio n. 2
0
    def _register_rules_from_pack(self, pack, rules):
        registered_count = 0

        for rule in rules:
            LOG.debug('Loading rule from %s.', rule)
            try:
                content = self._meta_loader.load(rule)
                pack_field = content.get('pack', None)
                if not pack_field:
                    content['pack'] = pack
                    pack_field = pack
                if pack_field != pack:
                    raise Exception('Model is in pack "%s" but field "pack" is different: %s' %
                                    (pack, pack_field))
                rule_api = RuleAPI(**content)
                rule_api.validate()
                rule_db = RuleAPI.to_model(rule_api)

                # Migration from rule without pack to rule with pack.
                # There might be a rule with same name but in pack `default`
                # generated in migration script. In this case, we want to
                # delete so we don't have duplicates.
                if pack_field != DEFAULT_PACK_NAME:
                    try:
                        rule_ref = ResourceReference.to_string_reference(name=content['name'],
                                                                         pack=DEFAULT_PACK_NAME)
                        LOG.debug('Looking for rule %s in pack %s', content['name'],
                                  DEFAULT_PACK_NAME)
                        existing = Rule.get_by_ref(rule_ref)
                        LOG.debug('Existing = %s', existing)
                        if existing:
                            LOG.debug('Found rule in pack default: %s; Deleting.', rule_ref)
                            Rule.delete(existing)
                    except:
                        LOG.exception('Exception deleting rule from %s pack.', DEFAULT_PACK_NAME)

                try:
                    rule_ref = ResourceReference.to_string_reference(name=content['name'],
                                                                     pack=content['pack'])
                    existing = Rule.get_by_ref(rule_ref)
                    if existing:
                        rule_db.id = existing.id
                        LOG.debug('Found existing rule: %s with id: %s', rule_ref, existing.id)
                except ValueError:
                    LOG.debug('Rule %s not found. Creating new one.', rule)

                try:
                    rule_db = Rule.add_or_update(rule_db)
                    extra = {'rule_db': rule_db}
                    LOG.audit('Rule updated. Rule %s from %s.', rule_db, rule, extra=extra)
                except Exception:
                    LOG.exception('Failed to create rule %s.', rule_api.name)
            except:
                LOG.exception('Failed registering rule from %s.', rule)
            else:
                registered_count += 1

        return registered_count
Esempio n. 3
0
 def __init__(self, connection, queues, trigger_dispatcher=None):
     super(Notifier, self).__init__(connection, queues)
     self._trigger_dispatcher = trigger_dispatcher
     self._notify_trigger = ResourceReference.to_string_reference(
         pack=NOTIFY_TRIGGER_TYPE["pack"], name=NOTIFY_TRIGGER_TYPE["name"]
     )
     self._action_trigger = ResourceReference.to_string_reference(
         pack=ACTION_TRIGGER_TYPE["pack"], name=ACTION_TRIGGER_TYPE["name"]
     )
Esempio n. 4
0
 def __init__(self, q_connection=None, trigger_dispatcher=None):
     self._queue_consumer = LiveActionUpdateQueueConsumer(q_connection, self)
     self._consumer_thread = None
     self._trigger_dispatcher = trigger_dispatcher
     self._notify_trigger = ResourceReference.to_string_reference(
         pack=NOTIFY_TRIGGER_TYPE['pack'],
         name=NOTIFY_TRIGGER_TYPE['name'])
     self._action_trigger = ResourceReference.to_string_reference(
         pack=ACTION_TRIGGER_TYPE['pack'],
         name=ACTION_TRIGGER_TYPE['name'])
Esempio n. 5
0
    def _get_executions(self, **kw):
        action_ref = kw.get('action', None)

        if action_ref:
            action_name = ResourceReference.get_name(action_ref)
            action_pack = ResourceReference.get_pack(action_ref)
            del kw['action']
            kw['action.name'] = action_name
            kw['action.pack'] = action_pack

        return super(ActionExecutionHistoryController, self)._get_all(**kw)
Esempio n. 6
0
File: utils.py Progetto: lyandut/st2
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
Esempio n. 7
0
File: rule.py Progetto: joshgre/st2
    def to_model(cls, rule):
        name = getattr(rule, 'name', None)
        description = getattr(rule, 'description', None)

        # Create a trigger for the provided rule
        trigger_db = TriggerService.create_trigger_db_from_rule(rule)

        trigger = reference.get_str_resource_ref_from_model(trigger_db)
        criteria = dict(getattr(rule, 'criteria', {}))
        pack = getattr(rule, 'pack', DEFAULT_PACK_NAME)
        ref = ResourceReference.to_string_reference(pack=pack, name=name)

        # Validate criteria
        validator.validate_criteria(criteria)

        # Validate trigger parameters
        validator.validate_trigger_parameters(trigger_db=trigger_db)

        action = ActionExecutionSpecDB(ref=rule.action['ref'],
                                       parameters=rule.action['parameters'])

        enabled = rule.enabled
        tags = TagsHelper.to_model(getattr(rule, 'tags', []))

        model = cls.model(name=name, description=description, pack=pack, ref=ref, trigger=trigger,
                          criteria=criteria, action=action, enabled=enabled, tags=tags)
        return model
Esempio n. 8
0
    def _register_trigger_type(self, trigger_definition, attempt_no=0):
        LOG.debug('Attempt no %s to register trigger %s.', attempt_no, trigger_definition['name'])

        ref = ResourceReference.to_string_reference(pack=trigger_definition['pack'],
                                                    name=trigger_definition['name'])
        if self._is_triggertype_exists(ref):
            return

        payload = json.dumps(trigger_definition)

        try:
            r = requests.post(url=self._trigger_type_endpoint, data=payload,
                              headers=self._http_post_headers, timeout=self._timeout)
            if r.status_code == httplib.CREATED:
                LOG.info('Registered trigger %s.', trigger_definition['name'])
            elif r.status_code == httplib.CONFLICT:
                LOG.info('Trigger %s is already registered.', trigger_definition['name'])
            else:
                LOG.error('Seeing status code %s on an attempt to register trigger %s.',
                          r.status_code, trigger_definition['name'])
        except requests.exceptions.ConnectionError:
            if attempt_no < self._max_attempts:
                self._retry_wait = self._retry_wait * (attempt_no + 1)
                LOG.debug('    ConnectionError. Will retry in %ss.', self._retry_wait)
                eventlet.spawn_after(self._retry_wait, self._register_trigger_type,
                                     trigger_definition=trigger_definition,
                                     attempt_no=(attempt_no + 1))
            else:
                LOG.warn('Failed to register trigger %s. ' % trigger_definition['name'] +
                         ' Exceeded max attempts to register trigger.')
        except:
            LOG.exception('Failed to register trigger %s.', trigger_definition['name'])
Esempio n. 9
0
    def run(self, action_parameters):

        liveaction_db = action_utils.get_liveaction_by_id(self.liveaction_id)
        exc = ActionExecution.get(liveaction__id=str(liveaction_db.id))

        # Assemble and dispatch trigger
        trigger_ref = ResourceReference.to_string_reference(
            pack=INQUIRY_TRIGGER['pack'],
            name=INQUIRY_TRIGGER['name']
        )
        trigger_payload = {
            "id": str(exc.id),
            "route": self.route
        }
        self.trigger_dispatcher.dispatch(trigger_ref, trigger_payload)

        # We only want to request a pause if this has a parent
        if liveaction_db.context.get("parent"):

            # Get the root liveaction and request that it pauses
            root_liveaction = action_service.get_root_liveaction(liveaction_db)
            action_service.request_pause(
                root_liveaction,
                self.context.get('user', None)
            )

        result = {
            "schema": self.schema,
            "roles": self.roles_param,
            "users": self.users_param,
            "route": self.route,
            "ttl": self.ttl
        }
        return (LIVEACTION_STATUS_PENDING, result, None)
Esempio n. 10
0
    def to_model(cls, alias):
        name = alias.name
        description = getattr(alias, "description", None)
        pack = alias.pack
        ref = ResourceReference.to_string_reference(pack=pack, name=name)
        enabled = getattr(alias, "enabled", True)
        action_ref = alias.action_ref
        formats = alias.formats
        ack = getattr(alias, "ack", None)
        result = getattr(alias, "result", None)
        extra = getattr(alias, "extra", None)

        model = cls.model(
            name=name,
            description=description,
            pack=pack,
            ref=ref,
            enabled=enabled,
            action_ref=action_ref,
            formats=formats,
            ack=ack,
            result=result,
            extra=extra,
        )
        return model
Esempio n. 11
0
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')
Esempio n. 12
0
def post_trigger(action_execution):
    if not ACTION_SENSOR_ENABLED:
        return
    try:
        payload = json.dumps({
            'trigger': ResourceReference.to_string_reference(
                pack=ACTION_TRIGGER_TYPE['pack'], name=ACTION_TRIGGER_TYPE['name']),
            'payload': {
                'execution_id': str(action_execution.id),
                'status': action_execution.status,
                'start_timestamp': str(action_execution.start_timestamp),
                'action_name': action_execution.action,
                'parameters': action_execution.parameters,
                'result': action_execution.result
            }
        })
        LOG.debug('POSTing %s for %s. Payload - %s.', ACTION_TRIGGER_TYPE['name'],
                  action_execution.id, payload)
        r = requests.post(TRIGGER_INSTANCE_ENDPOINT,
                          data=payload,
                          headers=HTTP_POST_HEADER,
                          timeout=TIMEOUT)
    except:
        LOG.exception('Failed to fire trigger for action_execution %s.', str(action_execution.id))
    else:
        if r.status_code in [200, 201, 202]:
            LOG.debug('POSTed actionexecution %s as a trigger.', action_execution.id)
        else:
            LOG.warn('Seeing status code %s on an attempt to post triggerinstance for %s.',
                     r.status_code, action_execution.id)
Esempio n. 13
0
File: rule.py Progetto: hejin/st2
    def to_model(cls, rule):
        kwargs = {}
        kwargs['name'] = getattr(rule, 'name', None)
        kwargs['description'] = getattr(rule, 'description', None)

        # Create a trigger for the provided rule
        trigger_db = TriggerService.create_trigger_db_from_rule(rule)
        kwargs['trigger'] = reference.get_str_resource_ref_from_model(trigger_db)

        # Validate trigger parameters
        validator.validate_trigger_parameters(trigger_db=trigger_db)

        kwargs['pack'] = getattr(rule, 'pack', DEFAULT_PACK_NAME)
        kwargs['ref'] = ResourceReference.to_string_reference(pack=kwargs['pack'],
                                                              name=kwargs['name'])

        # Validate criteria
        kwargs['criteria'] = dict(getattr(rule, 'criteria', {}))
        validator.validate_criteria(kwargs['criteria'])

        kwargs['action'] = ActionExecutionSpecDB(ref=rule.action['ref'],
                                                 parameters=rule.action.get('parameters', {}))

        rule_type = dict(getattr(rule, 'type', {}))
        if rule_type:
            kwargs['type'] = RuleTypeSpecDB(ref=rule_type['ref'],
                                            parameters=rule_type.get('parameters', {}))

        kwargs['enabled'] = getattr(rule, 'enabled', False)
        kwargs['tags'] = TagsHelper.to_model(getattr(rule, 'tags', []))

        model = cls.model(**kwargs)
        return model
Esempio n. 14
0
def _register_internal_trigger_type(trigger_definition):
    try:
        trigger_type_db = create_trigger_type_db(trigger_type=trigger_definition)
    except (NotUniqueError, StackStormDBObjectConflictError):
        # We ignore conflict error since this operation is idempotent and race is not an issue
        LOG.debug('Internal trigger type "%s" already exists, ignoring...' %
                  (trigger_definition['name']), exc_info=True)

        ref = ResourceReference.to_string_reference(name=trigger_definition['name'],
                                                    pack=trigger_definition['pack'])
        trigger_type_db = get_trigger_type_db(ref)

    if trigger_type_db:
        LOG.debug('Registered internal trigger: %s.', trigger_definition['name'])

    # trigger types with parameters do no require a shadow trigger.
    if trigger_type_db and not trigger_type_db.parameters_schema:
        try:
            trigger_db = create_shadow_trigger(trigger_type_db)

            extra = {'trigger_db': trigger_db}
            LOG.audit('Trigger created for parameter-less internal TriggerType. Trigger.id=%s' %
                      (trigger_db.id), extra=extra)
        except StackStormDBObjectConflictError:
            LOG.debug('Shadow trigger "%s" already exists. Ignoring.',
                      trigger_type_db.get_reference().ref, exc_info=True)

        except (ValidationError, ValueError):
            LOG.exception('Validation failed in shadow trigger. TriggerType=%s.',
                          trigger_type_db.get_reference().ref)
            raise

    return trigger_type_db
Esempio n. 15
0
    def _get_by_ref_or_id(self, ref_or_id, exclude_fields=None, include_fields=None):
        """
        Retrieve resource object by an id of a reference.

        Note: This method throws StackStormDBObjectNotFoundError exception if the object is not
        found in the database.
        """

        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)

        if ResourceReference.is_resource_reference(ref_or_id):
            # references always contain a dot and id's can't contain it
            is_reference = True
        else:
            is_reference = False

        if is_reference:
            resource_db = self._get_by_ref(resource_ref=ref_or_id, exclude_fields=exclude_fields,
                                          include_fields=include_fields)
        else:
            resource_db = self._get_by_id(resource_id=ref_or_id, exclude_fields=exclude_fields,
                                          include_fields=include_fields)

        if not resource_db:
            msg = 'Resource with a reference or id "%s" not found' % (ref_or_id)
            raise StackStormDBObjectNotFoundError(msg)

        return resource_db
Esempio n. 16
0
    def _register_action(self, pack, action):
        content = self._meta_loader.load(action)
        pack_field = content.get('pack', None)
        if not pack_field:
            content['pack'] = pack
            pack_field = pack
        if pack_field != pack:
            raise Exception('Model is in pack "%s" but field "pack" is different: %s' %
                            (pack, pack_field))

        action_api = ActionAPI(**content)
        action_api.validate()
        action_validator.validate_action(action_api)
        model = ActionAPI.to_model(action_api)

        action_ref = ResourceReference.to_string_reference(pack=pack, name=str(content['name']))
        existing = action_utils.get_action_by_ref(action_ref)
        if not existing:
            LOG.debug('Action %s not found. Creating new one with: %s', action_ref, content)
        else:
            LOG.debug('Action %s found. Will be updated from: %s to: %s',
                      action_ref, existing, model)
            model.id = existing.id

        try:
            model = Action.add_or_update(model)
            extra = {'action_db': model}
            LOG.audit('Action updated. Action %s from %s.', model, action, extra=extra)
        except Exception:
            LOG.exception('Failed to write action to db %s.', model.name)
            raise
Esempio n. 17
0
    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
Esempio n. 18
0
def register_trigger_type(trigger_definition, attempt_no=0):
    LOG.debug('Attempt no %s to register trigger %s.', attempt_no, trigger_definition['name'])

    ref = ResourceReference.to_string_reference(pack=trigger_definition['pack'],
                                                name=trigger_definition['name'])
    if _is_triggertype_exists(ref):
        return

    payload = json.dumps(trigger_definition)

    try:
        r = requests.post(url=TRIGGER_TYPE_ENDPOINT, data=payload,
                          headers=HTTP_POST_HEADER, timeout=TIMEOUT)
        if r.status_code == httplib.CREATED:
            LOG.info('Registered trigger %s.', trigger_definition['name'])
        elif r.status_code == httplib.CONFLICT:
            LOG.info('Trigger %s is already registered.', trigger_definition['name'])
        else:
            LOG.error('Seeing status code %s on an attempt to register trigger %s.',
                      r.status_code, trigger_definition['name'])
    except requests.exceptions.ConnectionError:
        if attempt_no < MAX_ATTEMPTS:
            retry_wait = RETRY_WAIT * (attempt_no + 1)
            LOG.debug('    ConnectionError. Will retry in %ss.', retry_wait)
            eventlet.spawn_after(retry_wait, register_trigger_type,
                                 trigger_definition=trigger_definition,
                                 attempt_no=(attempt_no + 1))
        else:
            LOG.warn('Failed to register trigger %s. Exceeded max attempts to register trigger.',
                     trigger_definition['name'])
    except:
        LOG.exception('Failed to register trigger %s.', trigger_definition['name'])
Esempio n. 19
0
    def test_create_or_update_trigger_db_simple_triggers(self):
        test_fixtures = {
            'triggertypes': ['triggertype1.yaml']
        }
        loader = FixturesLoader()
        fixtures = loader.save_fixtures_to_db(fixtures_pack='generic', fixtures_dict=test_fixtures)
        triggertypes = fixtures['triggertypes']
        trigger_type_ref = ResourceReference.to_string_reference(
            name=triggertypes['triggertype1.yaml']['name'],
            pack=triggertypes['triggertype1.yaml']['pack'])

        trigger = {
            'name': triggertypes['triggertype1.yaml']['name'],
            'pack': triggertypes['triggertype1.yaml']['pack'],
            'type': trigger_type_ref
        }
        trigger_service.create_or_update_trigger_db(trigger)
        triggers = Trigger.get_all()
        self.assertTrue(len(triggers) == 1, 'Only one trigger should be created.')
        self.assertTrue(triggers[0]['name'] == triggertypes['triggertype1.yaml']['name'])

        # Try adding duplicate
        trigger_service.create_or_update_trigger_db(trigger)
        triggers = Trigger.get_all()
        self.assertTrue(len(triggers) == 1, 'Only one trigger should be present.')
        self.assertTrue(triggers[0]['name'] == triggertypes['triggertype1.yaml']['name'])
Esempio n. 20
0
    def test_exception_thrown_when_rule_creation_no_trigger_yes_triggertype(self):
        test_fixtures = {
            'triggertypes': ['triggertype1.yaml']
        }
        loader = FixturesLoader()
        fixtures = loader.save_fixtures_to_db(fixtures_pack='generic', fixtures_dict=test_fixtures)
        triggertypes = fixtures['triggertypes']
        trigger_type_ref = ResourceReference.to_string_reference(
            name=triggertypes['triggertype1.yaml']['name'],
            pack=triggertypes['triggertype1.yaml']['pack'])

        rule = {
            'name': 'fancyrule',
            'trigger': {
                'type': trigger_type_ref
            },
            'criteria': {

            },
            'action': {
                'ref': 'core.local',
                'parameters': {
                    'cmd': 'date'
                }
            }
        }
        rule_api = RuleAPI(**rule)
        self.assertRaises(TriggerDoesNotExistException,
                          trigger_service.create_trigger_db_from_rule, rule_api)
Esempio n. 21
0
 def test_get_all(self):
     holder = TimersHolder()
     for _, model in TestTimersHolder.MODELS.items():
         holder.add_trigger(
             ref=ResourceReference.to_string_reference(pack=model["pack"], name=model["name"]), trigger=model
         )
     self.assertEqual(len(holder.get_all()), 5)
Esempio n. 22
0
    def to_model(cls, action):
        name = getattr(action, "name", None)
        description = getattr(action, "description", None)
        enabled = bool(getattr(action, "enabled", True))
        entry_point = str(action.entry_point)
        pack = str(action.pack)
        runner_type = {"name": str(action.runner_type)}
        parameters = getattr(action, "parameters", dict())
        tags = TagsHelper.to_model(getattr(action, "tags", []))
        ref = ResourceReference.to_string_reference(pack=pack, name=name)

        if getattr(action, "notify", None):
            notify = NotificationsHelper.to_model(action.notify)
        else:
            notify = None

        model = cls.model(
            name=name,
            description=description,
            enable=enabled,
            enabled=enabled,
            entry_point=entry_point,
            pack=pack,
            runner_type=runner_type,
            tags=tags,
            parameters=parameters,
            notify=notify,
            ref=ref,
        )

        return model
Esempio n. 23
0
    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
Esempio n. 24
0
    def test_chain_runner_task_is_canceled_while_running(self, request):
        # Second task in the action is CANCELED, make sure runner doesn't get stuck in an infinite
        # loop
        chain_runner = acr.get_runner()
        chain_runner.entry_point = CHAIN_2_PATH
        chain_runner.action = ACTION_1

        original_run_action = chain_runner._run_action

        def mock_run_action(*args, **kwargs):
            original_live_action = args[0]
            if original_live_action.action == 'wolfpack.a2':
                status = LIVEACTION_STATUS_CANCELED
            else:
                status = LIVEACTION_STATUS_SUCCEEDED
            request.return_value = (DummyActionExecution(status=status), None)
            liveaction = original_run_action(*args, **kwargs)
            return liveaction

        chain_runner._run_action = mock_run_action
        action_ref = ResourceReference.to_string_reference(name=ACTION_1.name, pack=ACTION_1.pack)
        chain_runner.liveaction = LiveActionDB(action=action_ref)
        chain_runner.pre_run()
        status, _, _ = chain_runner.run({})

        self.assertEqual(status, LIVEACTION_STATUS_CANCELED)
        self.assertNotEqual(chain_runner.chain_holder.actionchain, None)
        # Chain count should be 2 since the last task doesn't get called since the second one was
        # canceled
        self.assertEqual(request.call_count, 2)
Esempio n. 25
0
File: action.py Progetto: Bala96/st2
    def to_model(cls, action):
        name = getattr(action, 'name', None)
        description = getattr(action, 'description', None)
        enabled = bool(getattr(action, 'enabled', True))
        entry_point = str(action.entry_point)
        pack = str(action.pack)
        runner_type = {'name': str(action.runner_type)}
        parameters = getattr(action, 'parameters', dict())
        tags = TagsHelper.to_model(getattr(action, 'tags', []))
        ref = ResourceReference.to_string_reference(pack=pack, name=name)

        if getattr(action, 'notify', None):
            notify = NotificationsHelper.to_model(action.notify)
        else:
            # We use embedded document model for ``notify`` in action model. If notify is
            # set notify to None, Mongoengine interprets ``None`` as unmodified
            # field therefore doesn't delete the embedded document. Therefore, we need
            # to use an empty document.
            notify = NotificationsHelper.to_model({})

        model = cls.model(name=name, description=description, enabled=enabled,
                          entry_point=entry_point, pack=pack, runner_type=runner_type,
                          tags=tags, parameters=parameters, notify=notify,
                          ref=ref)

        return model
Esempio n. 26
0
 def test_get_one_by_ref(self):
     rule_name = RuleViewControllerTestCase.RULE_1.name
     rule_pack = RuleViewControllerTestCase.RULE_1.pack
     ref = ResourceReference.to_string_reference(name=rule_name, pack=rule_pack)
     get_resp = self.__do_get_one(ref)
     self.assertEqual(get_resp.json['name'], rule_name)
     self.assertEqual(get_resp.status_int, http_client.OK)
Esempio n. 27
0
    def test_chain_runner_dependent_results_param(self, request):
        chain_runner = acr.get_runner()
        chain_runner.entry_point = CHAIN_DEP_RESULTS_INPUT
        chain_runner.action = ACTION_1
        action_ref = ResourceReference.to_string_reference(name=ACTION_1.name, pack=ACTION_1.pack)
        chain_runner.liveaction = LiveActionDB(action=action_ref)
        chain_runner.pre_run()
        chain_runner.run({'s1': 1})
        self.assertNotEqual(chain_runner.chain_holder.actionchain, None)

        if six.PY2:
            expected_values = [{u'p1': u'1'},
                               {u'p1': u'1'},
                               {u'out': u"{'c2': {'o1': '1'}, 'c1': {'o1': '1'}}"}]
        else:
            expected_values = [{'p1': '1'},
                               {'p1': '1'},
                               {'out': "{'c1': {'o1': '1'}, 'c2': {'o1': '1'}}"}]

        # Each of the call_args must be one of
        self.assertEqual(request.call_count, 3)
        for call_args in request.call_args_list:
            self.assertTrue(call_args[0][0].parameters in expected_values)
            expected_values.remove(call_args[0][0].parameters)

        self.assertEqual(len(expected_values), 0, 'Not all expected values received.')
Esempio n. 28
0
    def test_chain_runner_chain_second_task_times_out(self, request):
        # Second task in the chain times out so the action chain status should be timeout
        chain_runner = acr.get_runner()
        chain_runner.entry_point = CHAIN_2_PATH
        chain_runner.action = ACTION_1

        original_run_action = chain_runner._run_action

        def mock_run_action(*args, **kwargs):
            original_live_action = args[0]
            liveaction = original_run_action(*args, **kwargs)
            if original_live_action.action == 'wolfpack.a2':
                # Mock a timeout for second task
                liveaction.status = LIVEACTION_STATUS_TIMED_OUT
            return liveaction

        chain_runner._run_action = mock_run_action
        action_ref = ResourceReference.to_string_reference(name=ACTION_1.name, pack=ACTION_1.pack)
        chain_runner.liveaction = LiveActionDB(action=action_ref)
        chain_runner.pre_run()
        status, _, _ = chain_runner.run({})

        self.assertEqual(status, LIVEACTION_STATUS_TIMED_OUT)
        self.assertNotEqual(chain_runner.chain_holder.actionchain, None)
        # based on the chain the callcount is known to be 3. Not great but works.
        self.assertEqual(request.call_count, 3)
Esempio n. 29
0
def _get_api_models_from_disk(artifact_type, pack_dir=None):
    loader = ContentPackLoader()
    artifacts = None

    if pack_dir:
        artifacts_dir = loader.get_content_from_pack(pack_dir, artifact_type)
        pack_name = os.path.basename(os.path.normpath(pack_dir))
        artifacts = {pack_name: artifacts_dir}
    else:
        packs_dirs = content_utils.get_packs_base_paths()
        artifacts = loader.get_content(packs_dirs, artifact_type)

    artifacts_dict = {}
    for pack_name, pack_path in artifacts.items():
        artifacts_paths = registrar.get_resources_from_pack(pack_path)
        for artifact_path in artifacts_paths:
            artifact = meta_loader.load(artifact_path)
            if artifact_type == "sensors":
                sensors_dir = os.path.dirname(artifact_path)
                sensor_file_path = os.path.join(sensors_dir, artifact["entry_point"])
                artifact["artifact_uri"] = "file://" + sensor_file_path
            name = artifact.get("name", None) or artifact.get("class_name", None)
            if not artifact.get("pack", None):
                artifact["pack"] = pack_name
            ref = ResourceReference.to_string_reference(name=name, pack=pack_name)
            API_MODEL = API_MODELS_ARTIFACT_TYPES[artifact_type]
            # Following conversions are required because we add some fields with
            # default values in db model. If we don't do these conversions,
            # we'll see a unnecessary diff for those fields.
            artifact_api = API_MODEL(**artifact)
            artifact_db = API_MODEL.to_model(artifact_api)
            artifact_api = API_MODEL.from_model(artifact_db)
            artifacts_dict[ref] = artifact_api

    return artifacts_dict
Esempio n. 30
0
File: base.py Progetto: Pulsant/st2
    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
Esempio n. 31
0
 def _get_liveaction_model(self, action_db, params):
     status = action_constants.LIVEACTION_STATUS_REQUESTED
     start_timestamp = date_utils.get_datetime_utc_now()
     action_ref = ResourceReference(name=action_db.name,
                                    pack=action_db.pack).ref
     parameters = params
     context = {'user': cfg.CONF.system_user.user}
     liveaction_db = LiveActionDB(status=status,
                                  start_timestamp=start_timestamp,
                                  action=action_ref,
                                  parameters=parameters,
                                  context=context)
     return liveaction_db
Esempio n. 32
0
 def test_chain_runner_dict_param_temp(self, request):
     chain_runner = acr.get_runner()
     chain_runner.entry_point = CHAIN_DICT_TEMP_PATH
     chain_runner.action = ACTION_1
     action_ref = ResourceReference.to_string_reference(name=ACTION_1.name, pack=ACTION_1.pack)
     chain_runner.liveaction = LiveActionDB(action=action_ref)
     chain_runner.container_service = RunnerContainerService()
     chain_runner.pre_run()
     chain_runner.run({'s1': 1, 's2': 2, 's3': 3, 's4': 4})
     self.assertNotEqual(chain_runner.chain_holder.actionchain, None)
     expected_value = {"p1": {"p1.3": "[3, 4]", "p1.2": "2", "p1.1": "1"}}
     mock_args, _ = request.call_args
     self.assertEqual(mock_args[0].parameters, expected_value)
Esempio n. 33
0
 def test_chain_runner_failure_path(self, request):
     chain_runner = acr.get_runner()
     chain_runner.entry_point = CHAIN_1_PATH
     chain_runner.action = ACTION_1
     action_ref = ResourceReference.to_string_reference(name=ACTION_1.name, pack=ACTION_1.pack)
     chain_runner.liveaction = LiveActionDB(action=action_ref)
     chain_runner.container_service = RunnerContainerService()
     chain_runner.pre_run()
     status, _, _ = chain_runner.run({})
     self.assertEqual(status, LIVEACTION_STATUS_FAILED)
     self.assertNotEqual(chain_runner.chain_holder.actionchain, None)
     # based on the chain the callcount is known to be 2. Not great but works.
     self.assertEqual(request.call_count, 2)
Esempio n. 34
0
 def test_chain_runner_success_path(self, request):
     chain_runner = acr.get_runner()
     chain_runner.entry_point = CHAIN_1_PATH
     chain_runner.action = ACTION_1
     action_ref = ResourceReference.to_string_reference(name=ACTION_1.name, pack=ACTION_1.pack)
     chain_runner.liveaction = LiveActionDB(action=action_ref)
     chain_runner.liveaction.notify = CHAIN_NOTIFY_DB
     chain_runner.container_service = RunnerContainerService()
     chain_runner.pre_run()
     chain_runner.run({})
     self.assertNotEqual(chain_runner.chain_holder.actionchain, None)
     # based on the chain the callcount is known to be 3. Not great but works.
     self.assertEqual(request.call_count, 3)
Esempio n. 35
0
    def test_get_one_by_ref(self):
        post_resp = self.__do_post(RulesControllerTestCase.RULE_1)
        rule_name = post_resp.json['name']
        rule_pack = post_resp.json['pack']
        ref = ResourceReference.to_string_reference(name=rule_name,
                                                    pack=rule_pack)
        rule_id = post_resp.json['id']
        get_resp = self.__do_get_one(ref)
        self.assertEqual(get_resp.json['name'], rule_name)
        self.assertEqual(get_resp.status_int, http_client.OK)
        self.__do_delete(rule_id)

        post_resp = self.__do_post(RulesControllerTestCase.RULE_SPACE)
        rule_name = post_resp.json['name']
        rule_pack = post_resp.json['pack']
        ref = ResourceReference.to_string_reference(name=rule_name,
                                                    pack=rule_pack)
        rule_id = post_resp.json['id']
        get_resp = self.__do_get_one(ref)
        self.assertEqual(get_resp.json['name'], rule_name)
        self.assertEqual(get_resp.status_int, http_client.OK)
        self.__do_delete(rule_id)
Esempio n. 36
0
 def test_chain_runner_list_param_temp(self, request):
     chain_runner = acr.get_runner()
     chain_runner.entry_point = CHAIN_LIST_TEMP_PATH
     chain_runner.action = ACTION_1
     action_ref = ResourceReference.to_string_reference(
         name=ACTION_1.name, pack=ACTION_1.pack
     )
     chain_runner.liveaction = LiveActionDB(action=action_ref)
     chain_runner.pre_run()
     chain_runner.run({"s1": 1, "s2": 2, "s3": 3, "s4": 4})
     self.assertNotEqual(chain_runner.chain_holder.actionchain, None)
     mock_args, _ = request.call_args
     self.assertEqual(mock_args[0].parameters, {"p1": "[2, 3, 4]"})
Esempio n. 37
0
File: utils.py Progetto: miqui/st2
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]}
Esempio n. 38
0
 def test_chain_runner_vars_action_params(self, request):
     chain_runner = acr.get_runner()
     chain_runner.entry_point = CHAIN_WITH_ACTIONPARAM_VARS
     chain_runner.action = ACTION_2
     action_ref = ResourceReference.to_string_reference(name=ACTION_2.name,
                                                        pack=ACTION_2.pack)
     chain_runner.liveaction = LiveActionDB(action=action_ref)
     chain_runner.pre_run()
     chain_runner.run({'input_a': 'two'})
     self.assertNotEqual(chain_runner.chain_holder.actionchain, None)
     expected_value = {'inttype': 1, 'strtype': 'two', 'booltype': True}
     mock_args, _ = request.call_args
     self.assertEqual(mock_args[0].parameters, expected_value)
Esempio n. 39
0
    def to_model(cls, action):
        model = super(cls, cls).to_model(action)
        model.enabled = bool(action.enabled)
        model.entry_point = str(action.entry_point)
        model.pack = str(action.pack)
        model.runner_type = {'name': str(action.runner_type)}
        model.parameters = getattr(action, 'parameters', dict())
        model.tags = TagsHelper.to_model(getattr(action, 'tags', []))
        model.ref = ResourceReference.to_string_reference(pack=model.pack, name=model.name)
        if getattr(action, 'notify', None):
            model.notify = NotificationsHelper.to_model(action.notify)

        return model
Esempio n. 40
0
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
Esempio n. 41
0
 def test_chain_runner_success_task_action_call_with_no_params(self, request):
     # Make sure that the runner doesn't explode if task definition contains
     # no "params" section
     chain_runner = acr.get_runner()
     chain_runner.entry_point = CHAIN_ACTION_CALL_NO_PARAMS_PATH
     chain_runner.action = ACTION_1
     action_ref = ResourceReference.to_string_reference(name=ACTION_1.name, pack=ACTION_1.pack)
     chain_runner.liveaction = LiveActionDB(action=action_ref)
     chain_runner.liveaction.notify = CHAIN_NOTIFY_DB
     chain_runner.pre_run()
     chain_runner.run({})
     self.assertNotEqual(chain_runner.chain_holder.actionchain, None)
     # based on the chain the callcount is known to be 3. Not great but works.
     self.assertEqual(request.call_count, 3)
Esempio n. 42
0
    def test_params_and_parameters_attributes_both_work(self, _):
        action_ref = ResourceReference.to_string_reference(
            name=ACTION_2.name, pack=ACTION_2.pack
        )

        # "params" attribute used
        chain_runner = acr.get_runner()
        chain_runner.entry_point = CHAIN_ACTION_PARAMS_ATTRIBUTE
        chain_runner.action = ACTION_2
        chain_runner.liveaction = LiveActionDB(action=action_ref)
        chain_runner.pre_run()

        original_build_liveaction_object = chain_runner._build_liveaction_object

        def mock_build_liveaction_object(action_node, resolved_params, parent_context):
            # Verify parameters are correctly passed to the action
            self.assertEqual(resolved_params, {"pparams": "v1"})
            original_build_liveaction_object(
                action_node=action_node,
                resolved_params=resolved_params,
                parent_context=parent_context,
            )

        chain_runner._build_liveaction_object = mock_build_liveaction_object

        action_parameters = {}
        status, output, _ = chain_runner.run(action_parameters=action_parameters)
        self.assertEqual(status, LIVEACTION_STATUS_SUCCEEDED)

        # "parameters" attribute used
        chain_runner = acr.get_runner()
        chain_runner.entry_point = CHAIN_ACTION_PARAMETERS_ATTRIBUTE
        chain_runner.action = ACTION_2
        chain_runner.liveaction = LiveActionDB(action=action_ref)
        chain_runner.pre_run()

        def mock_build_liveaction_object(action_node, resolved_params, parent_context):
            # Verify parameters are correctly passed to the action
            self.assertEqual(resolved_params, {"pparameters": "v1"})
            original_build_liveaction_object(
                action_node=action_node,
                resolved_params=resolved_params,
                parent_context=parent_context,
            )

        chain_runner._build_liveaction_object = mock_build_liveaction_object

        action_parameters = {}
        status, output, _ = chain_runner.run(action_parameters=action_parameters)
        self.assertEqual(status, LIVEACTION_STATUS_SUCCEEDED)
Esempio n. 43
0
    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
Esempio n. 44
0
    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']
Esempio n. 45
0
    def to_model(cls, alias):
        name = alias.name
        description = getattr(alias, 'description', None)
        pack = alias.pack
        ref = ResourceReference.to_string_reference(pack=pack, name=name)
        enabled = getattr(alias, 'enabled', True)
        action_ref = alias.action_ref
        formats = alias.formats
        ack = getattr(alias, 'ack', None)
        result = getattr(alias, 'result', None)

        model = cls.model(name=name, description=description, pack=pack, ref=ref, enabled=enabled,
                          action_ref=action_ref, formats=formats, ack=ack, result=result)
        return model
Esempio n. 46
0
 def test_get_all_filters_filter_by_type(self):
     holder = TimersHolder()
     for _, model in TestTimersHolder.MODELS.items():
         holder.add_trigger(
             ref=ResourceReference.to_string_reference(pack=model["pack"],
                                                       name=model["name"]),
             trigger=model,
         )
     self.assertEqual(
         len(holder.get_all(timer_type=INTERVAL_TIMER_TRIGGER_REF)), 3)
     self.assertEqual(
         len(holder.get_all(timer_type=DATE_TIMER_TRIGGER_REF)), 1)
     self.assertEqual(
         len(holder.get_all(timer_type=CRON_TIMER_TRIGGER_REF)), 1)
Esempio n. 47
0
def validate_action(action_api):
    runner_db = _get_runner_model(action_api)

    # Check if pack is valid.
    if not _is_valid_pack(action_api.pack):
        packs_base_paths = get_packs_base_paths()
        packs_base_paths = ','.join(packs_base_paths)
        msg = ('Content pack "%s" is not found or doesn\'t contain actions directory. '
               'Searched in: %s' %
               (action_api.pack, packs_base_paths))
        raise ValueValidationException(msg)

    # Check if parameters defined are valid.
    action_ref = ResourceReference.to_string_reference(pack=action_api.pack, name=action_api.name)
    _validate_parameters(action_ref, action_api.parameters, runner_db.runner_parameters)
Esempio n. 48
0
def _get_api_models_from_db(persistence_model, pack_dir=None):
    filters = {}
    if pack_dir:
        pack_name = os.path.basename(os.path.normpath(pack_dir))
        filters = {'pack': pack_name}
    models = persistence_model.query(**filters)
    models_dict = {}
    for model in models:
        model_pack = getattr(model, 'pack', None) or DEFAULT_PACK_NAME
        model_ref = ResourceReference.to_string_reference(name=model.name, pack=model_pack)
        if getattr(model, 'id', None):
            del model.id
        API_MODEL = API_MODELS_PERSISTENT_MODELS[persistence_model]
        models_dict[model_ref] = API_MODEL.from_model(model)
    return models_dict
Esempio n. 49
0
    def test_to_string_reference(self):
        ref = ResourceReference.to_string_reference(pack='mapack', name='moname')
        self.assertEqual(ref, 'mapack.moname')

        expected_msg = r'Pack name should not contain "\."'
        self.assertRaisesRegexp(ValueError, expected_msg, ResourceReference.to_string_reference,
                                pack='pack.invalid', name='bar')

        expected_msg = 'Both pack and name needed for building'
        self.assertRaisesRegexp(ValueError, expected_msg, ResourceReference.to_string_reference,
                                pack='pack', name=None)

        expected_msg = 'Both pack and name needed for building'
        self.assertRaisesRegexp(ValueError, expected_msg, ResourceReference.to_string_reference,
                                pack=None, name='name')
Esempio n. 50
0
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
Esempio n. 51
0
 def test_chain_runner_no_default(self, request):
     chain_runner = acr.get_runner()
     chain_runner.entry_point = CHAIN_NO_DEFAULT
     chain_runner.action = ACTION_1
     action_ref = ResourceReference.to_string_reference(name=ACTION_1.name, pack=ACTION_1.pack)
     chain_runner.liveaction = LiveActionDB(action=action_ref)
     chain_runner.pre_run()
     chain_runner.run({})
     self.assertNotEqual(chain_runner.chain_holder.actionchain, None)
     # In case of this chain default_node is the first_node.
     default_node = chain_runner.chain_holder.actionchain.default
     first_node = chain_runner.chain_holder.actionchain.chain[0]
     self.assertEqual(default_node, first_node.name)
     # based on the chain the callcount is known to be 3. Not great but works.
     self.assertEqual(request.call_count, 3)
Esempio n. 52
0
def _get_trigger_db(trigger):
    # TODO: This method should die in a fire
    # XXX: Do not make this method public.

    if isinstance(trigger, dict):
        name = trigger.get('name', None)
        pack = trigger.get('pack', None)

        if name and pack:
            ref = ResourceReference.to_string_reference(name=name, pack=pack)
            return get_trigger_db_by_ref(ref)
        return get_trigger_db_given_type_and_params(type=trigger['type'],
                                                    parameters=trigger.get('parameters', {}))
    else:
        raise Exception('Unrecognized object')
Esempio n. 53
0
    def _delete_shadow_trigger(triggertype_db):
        # shadow Trigger's have the same name as the shadowed TriggerType.
        triggertype_ref = ResourceReference(name=triggertype_db.name, pack=triggertype_db.pack)
        trigger_db = TriggerService.get_trigger_db_by_ref(triggertype_ref.ref)
        if not trigger_db:
            LOG.warn('No shadow trigger found for %s. Will skip delete.', triggertype_db)
            return
        try:
            Trigger.delete(trigger_db)
        except Exception:
            LOG.exception('Database delete encountered exception during delete of id="%s". ',
                          trigger_db.id)

        extra = {'trigger_db': trigger_db}
        LOG.audit('Trigger deleted. Trigger.id=%s' % (trigger_db.id), extra=extra)
Esempio n. 54
0
    def _get_liveaction_model(self, params):
        status = 'initializing'
        start_timestamp = date_utils.get_datetime_utc_now()
        action_ref = ResourceReference(name=ParamsUtilsTest.action_db.name,
                                       pack=ParamsUtilsTest.action_db.pack).ref
        liveaction_db = LiveActionDB(status=status,
                                     start_timestamp=start_timestamp,
                                     action=action_ref,
                                     parameters=params)
        liveaction_db.context = {
            'source_channel': 'awesome',
            'api_user': '******'
        }

        return liveaction_db
Esempio n. 55
0
    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
Esempio n. 56
0
    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
Esempio n. 57
0
    def test_update_liveaction_result_with_dotted_key(self):
        liveaction_db = LiveActionDB()
        liveaction_db.status = "initializing"
        liveaction_db.start_timestamp = get_datetime_utc_now()
        liveaction_db.action = ResourceReference(
            name=ActionDBUtilsTestCase.action_db.name,
            pack=ActionDBUtilsTestCase.action_db.pack,
        ).ref
        params = {
            "actionstr": "foo",
            "some_key_that_aint_exist_in_action_or_runner": "bar",
            "runnerint": 555,
        }
        liveaction_db.parameters = params
        liveaction_db = LiveAction.add_or_update(liveaction_db)
        origliveaction_db = copy.copy(liveaction_db)

        # Update by id.
        newliveaction_db = action_db_utils.update_liveaction_status(
            status="running", liveaction_id=liveaction_db.id)

        # Verify id didn't change.
        self.assertEqual(origliveaction_db.id, newliveaction_db.id)
        self.assertEqual(newliveaction_db.status, "running")

        # Verify that state is published.
        self.assertTrue(LiveActionPublisher.publish_state.called)
        LiveActionPublisher.publish_state.assert_called_once_with(
            newliveaction_db, "running")

        now = get_datetime_utc_now()
        status = "succeeded"
        result = {"a": 1, "b": True, "a.b.c": "abc"}
        context = {"third_party_id": uuid.uuid4().hex}
        newliveaction_db = action_db_utils.update_liveaction_status(
            status=status,
            result=result,
            context=context,
            end_timestamp=now,
            liveaction_id=liveaction_db.id,
        )

        self.assertEqual(origliveaction_db.id, newliveaction_db.id)
        self.assertEqual(newliveaction_db.status, status)
        self.assertIn("a.b.c", list(result.keys()))
        self.assertDictEqual(newliveaction_db.result, result)
        self.assertDictEqual(newliveaction_db.context, context)
        self.assertEqual(newliveaction_db.end_timestamp, now)
Esempio n. 58
0
def create_or_update_trigger_type_db(trigger_type):
    """
    Create or update a trigger type db object in the db given trigger_type definition as dict.

    :param trigger_type: Trigger type model.
    :type trigger_type: ``dict``

    :rtype: ``object``
    """
    assert isinstance(trigger_type, dict)

    trigger_type_api = TriggerTypeAPI(**trigger_type)
    trigger_type_api.validate()
    trigger_type_api = TriggerTypeAPI.to_model(trigger_type_api)

    ref = ResourceReference.to_string_reference(name=trigger_type_api.name,
                                                pack=trigger_type_api.pack)

    existing_trigger_type_db = get_trigger_type_db(ref)
    if existing_trigger_type_db:
        is_update = True
    else:
        is_update = False

    if is_update:
        trigger_type_api.id = existing_trigger_type_db.id

    try:
        trigger_type_db = TriggerType.add_or_update(trigger_type_api)
    except StackStormDBObjectConflictError:
        # Operation is idempotent and trigger could have already been created by
        # another process. Ignore object already exists because it simply means
        # there was a race and object is already in the database.
        trigger_type_db = get_trigger_type_db(ref)
        is_update = True

    extra = {'trigger_type_db': trigger_type_db}

    if is_update:
        LOG.audit('TriggerType updated. TriggerType.id=%s' %
                  (trigger_type_db.id),
                  extra=extra)
    else:
        LOG.audit('TriggerType created. TriggerType.id=%s' %
                  (trigger_type_db.id),
                  extra=extra)

    return trigger_type_db
Esempio n. 59
0
def get_resource_ref_from_model(model):
    """
    Return a ResourceReference given db_model.

    :param model: DB model that contains name and pack.
    :type model: ``object``

    :return: ResourceReference.
    """
    try:
        name = model.name
        pack = model.pack
    except AttributeError:
        raise Exception('Cannot build ResourceReference for model: %s. Name or pack missing.'
                        % model)
    return ResourceReference(name=name, pack=pack)
Esempio n. 60
0
    def test_action_chain_runner_referenced_action_doesnt_exist(self, mock_request):
        # Action referenced by a task doesn't exist, should result in a top level error
        chain_runner = acr.get_runner()
        chain_runner.entry_point = CHAIN_WITH_INVALID_ACTION
        chain_runner.action = ACTION_2
        action_ref = ResourceReference.to_string_reference(name=ACTION_2.name, pack=ACTION_2.pack)
        chain_runner.liveaction = LiveActionDB(action=action_ref)
        chain_runner.pre_run()

        action_parameters = {}
        status, output, _ = chain_runner.run(action_parameters=action_parameters)

        expected_error = ('Failed to run task "c1". Action with reference "wolfpack.a2" '
                          'doesn\'t exist.')
        self.assertEqual(status, LIVEACTION_STATUS_FAILED)
        self.assertIn(expected_error, output['error'])
        self.assertIn('Traceback', output['traceback'])