Beispiel #1
0
    def put(self, triggertype, triggertype_ref_or_id):
        triggertype_db = self._get_by_ref_or_id(ref_or_id=triggertype_ref_or_id)
        triggertype_id = triggertype_db.id

        try:
            validate_not_part_of_system_pack(triggertype_db)
        except ValueValidationException as e:
            abort(http_client.BAD_REQUEST, six.text_type(e))

        try:
            triggertype_db = TriggerTypeAPI.to_model(triggertype)
            if triggertype.id is not None and len(triggertype.id) > 0 and \
               triggertype.id != triggertype_id:
                LOG.warning('Discarding mismatched id=%s found in payload and using uri_id=%s.',
                            triggertype.id, triggertype_id)
            triggertype_db.id = triggertype_id
            old_triggertype_db = triggertype_db
            triggertype_db = TriggerType.add_or_update(triggertype_db)
        except (ValidationError, ValueError) as e:
            LOG.exception('Validation failed for triggertype data=%s', triggertype)
            abort(http_client.BAD_REQUEST, six.text_type(e))
            return

        extra = {'old_triggertype_db': old_triggertype_db, 'new_triggertype_db': triggertype_db}
        LOG.audit('TriggerType updated. TriggerType.id=%s' % (triggertype_db.id), extra=extra)

        triggertype_api = TriggerTypeAPI.from_model(triggertype_db)
        return triggertype_api
Beispiel #2
0
    def post(self, triggertype):
        """
            Create a new triggertype.

            Handles requests:
                POST /triggertypes/
        """

        try:
            triggertype_db = TriggerTypeAPI.to_model(triggertype)
            triggertype_db = TriggerType.add_or_update(triggertype_db)
        except (ValidationError, ValueError) as e:
            LOG.exception('Validation failed for triggertype data=%s.',
                          triggertype)
            abort(http_client.BAD_REQUEST, str(e))
            return
        else:
            extra = {'triggertype_db': triggertype_db}
            LOG.audit('TriggerType created. TriggerType.id=%s' %
                      (triggertype_db.id),
                      extra=extra)
            if not triggertype_db.parameters_schema:
                TriggerTypeController._create_shadow_trigger(triggertype_db)

        triggertype_api = TriggerTypeAPI.from_model(triggertype_db)

        return Response(json=triggertype_api, status=http_client.CREATED)
Beispiel #3
0
    def post(self, triggertype):
        """
            Create a new triggertype.

            Handles requests:
                POST /triggertypes/
        """

        try:
            triggertype_db = TriggerTypeAPI.to_model(triggertype)
            triggertype_db = TriggerType.add_or_update(triggertype_db)
        except (ValidationError, ValueError) as e:
            LOG.exception('Validation failed for triggertype data=%s.',
                          triggertype)
            abort(http_client.BAD_REQUEST, str(e))
            return
        except StackStormDBObjectConflictError as e:
            LOG.warn(
                'TriggerType creation of %s failed with uniqueness conflict. Exception : %s',
                triggertype, str(e))
            abort(http_client.CONFLICT,
                  str(e),
                  body={'conflict-id': e.conflict_id})
            return
        else:
            extra = {'triggertype_db': triggertype_db}
            LOG.audit('TriggerType created. TriggerType.id=%s' %
                      (triggertype_db.id),
                      extra=extra)
            if not triggertype_db.parameters_schema:
                TriggerTypeController._create_shadow_trigger(triggertype_db)

        triggertype_api = TriggerTypeAPI.from_model(triggertype_db)

        return triggertype_api
Beispiel #4
0
    def put(self, triggertype, triggertype_ref_or_id):
        triggertype_db = self._get_by_ref_or_id(ref_or_id=triggertype_ref_or_id)
        triggertype_id = triggertype_db.id

        try:
            validate_not_part_of_system_pack(triggertype_db)
        except ValueValidationException as e:
            abort(http_client.BAD_REQUEST, str(e))

        try:
            triggertype_db = TriggerTypeAPI.to_model(triggertype)
            if triggertype.id is not None and len(triggertype.id) > 0 and \
               triggertype.id != triggertype_id:
                LOG.warning('Discarding mismatched id=%s found in payload and using uri_id=%s.',
                            triggertype.id, triggertype_id)
            triggertype_db.id = triggertype_id
            old_triggertype_db = triggertype_db
            triggertype_db = TriggerType.add_or_update(triggertype_db)
        except (ValidationError, ValueError) as e:
            LOG.exception('Validation failed for triggertype data=%s', triggertype)
            abort(http_client.BAD_REQUEST, str(e))
            return

        extra = {'old_triggertype_db': old_triggertype_db, 'new_triggertype_db': triggertype_db}
        LOG.audit('TriggerType updated. TriggerType.id=%s' % (triggertype_db.id), extra=extra)

        triggertype_api = TriggerTypeAPI.from_model(triggertype_db)
        return triggertype_api
Beispiel #5
0
    def post(self, triggertype):
        """
            Create a new triggertype.

            Handles requests:
                POST /triggertypes/
        """

        try:
            triggertype_db = TriggerTypeAPI.to_model(triggertype)
            triggertype_db = TriggerType.add_or_update(triggertype_db)
        except (ValidationError, ValueError) as e:
            LOG.exception('Validation failed for triggertype data=%s.', triggertype)
            abort(http_client.BAD_REQUEST, str(e))
            return
        except StackStormDBObjectConflictError as e:
            LOG.warn('TriggerType creation of %s failed with uniqueness conflict. Exception : %s',
                     triggertype, str(e))
            abort(http_client.CONFLICT, str(e), body={'conflict-id': e.conflict_id})
            return
        else:
            extra = {'triggertype_db': triggertype_db}
            LOG.audit('TriggerType created. TriggerType.id=%s' % (triggertype_db.id), extra=extra)
            if not triggertype_db.parameters_schema:
                TriggerTypeController._create_shadow_trigger(triggertype_db)

        triggertype_api = TriggerTypeAPI.from_model(triggertype_db)

        return triggertype_api
Beispiel #6
0
def create_trigger_type_db(trigger_type, log_not_unique_error_as_debug=False):
    """
    Creates a trigger type db object in the db given trigger_type definition as dict.

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

    :param log_not_unique_error_as_debug: True to lot NotUnique errors under debug instead of
                                          error log level. This is to be used in scenarios where
                                          failure is non-fatal (e.g. when services register
                                          internal trigger types which is an idempotent
                                          operation).
    :type log_not_unique_error_as_debug: ``bool``

    :rtype: ``object``
    """
    trigger_type_api = TriggerTypeAPI(**trigger_type)
    trigger_type_api.validate()
    ref = ResourceReference.to_string_reference(name=trigger_type_api.name,
                                                pack=trigger_type_api.pack)
    trigger_type_db = get_trigger_type_db(ref)

    if not trigger_type_db:
        trigger_type_db = TriggerTypeAPI.to_model(trigger_type_api)
        LOG.debug('verified trigger and formulated TriggerDB=%s',
                  trigger_type_db)
        trigger_type_db = TriggerType.add_or_update(
            trigger_type_db,
            log_not_unique_error_as_debug=log_not_unique_error_as_debug)

    return trigger_type_db
Beispiel #7
0
    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'])))
        trace_service.add_or_update_given_trace_context(
            trace_context={'trace_tag': 'test_triggered_execution_trace'},
            trigger_instances=[str(trigger_instance.id)])
        enforcer = RuleEnforcer(trigger_instance, rule)
        enforcer.enforce()

        # Wait for the action execution to complete and then confirm outcome.
        liveaction = LiveAction.get(context__trigger_instance__id=str(trigger_instance.id))
        self.assertIsNotNone(liveaction)
        liveaction = self._wait_on_status(liveaction, action_constants.LIVEACTION_STATUS_FAILED)

        execution = self._get_action_execution(
            liveaction__id=str(liveaction.id),
            raise_exception=True
        )

        self.assertDictEqual(execution.trigger, vars(TriggerAPI.from_model(trigger)))
        self.assertDictEqual(execution.trigger_type, vars(TriggerTypeAPI.from_model(trigger_type)))
        self.assertDictEqual(execution.trigger_instance,
                             vars(TriggerInstanceAPI.from_model(trigger_instance)))
        self.assertDictEqual(execution.rule, vars(RuleAPI.from_model(rule)))
        action = action_utils.get_action_by_ref(liveaction.action)
        self.assertDictEqual(execution.action, vars(ActionAPI.from_model(action)))
        runner = RunnerType.get_by_name(action.runner_type['name'])
        self.assertDictEqual(execution.runner, vars(RunnerTypeAPI.from_model(runner)))
        liveaction = LiveAction.get_by_id(str(liveaction.id))
        self.assertEqual(execution.start_timestamp, liveaction.start_timestamp)
        self.assertEqual(execution.end_timestamp, liveaction.end_timestamp)
        self.assertEqual(execution.result, liveaction.result)
        self.assertEqual(execution.status, liveaction.status)
        self.assertEqual(execution.context, liveaction.context)
        self.assertEqual(execution.liveaction['callback'], liveaction.callback)
        self.assertEqual(execution.liveaction['action'], liveaction.action)
Beispiel #8
0
 def test_execution_creation_action_triggered_by_rule(self):
     # Wait for the action execution to complete and then confirm outcome.
     trigger_type = self.MODELS['triggertypes']['triggertype2.yaml']
     trigger = self.MODELS['triggers']['trigger2.yaml']
     trigger_instance = self.MODELS['triggerinstances']['trigger_instance_1.yaml']
     test_liveaction = self.FIXTURES['liveactions']['liveaction3.yaml']
     rule = self.MODELS['rules']['rule3.yaml']
     # Setup LiveAction to point to right rule and trigger_instance.
     # XXX: We need support for dynamic fixtures.
     test_liveaction['context']['rule']['id'] = str(rule.id)
     test_liveaction['context']['trigger_instance']['id'] = str(trigger_instance.id)
     test_liveaction_api = LiveActionAPI(**test_liveaction)
     test_liveaction = LiveAction.add_or_update(LiveActionAPI.to_model(test_liveaction_api))
     liveaction = LiveAction.get(context__trigger_instance__id=str(trigger_instance.id))
     self.assertIsNotNone(liveaction)
     self.assertEqual(liveaction.status, action_constants.LIVEACTION_STATUS_REQUESTED)
     executions_util.create_execution_object(liveaction)
     execution = self._get_action_execution(liveaction__id=str(liveaction.id),
                                            raise_exception=True)
     self.assertDictEqual(execution.trigger, vars(TriggerAPI.from_model(trigger)))
     self.assertDictEqual(execution.trigger_type, vars(TriggerTypeAPI.from_model(trigger_type)))
     self.assertDictEqual(execution.trigger_instance,
                          vars(TriggerInstanceAPI.from_model(trigger_instance)))
     self.assertDictEqual(execution.rule, vars(RuleAPI.from_model(rule)))
     action = action_utils.get_action_by_ref(liveaction.action)
     self.assertDictEqual(execution.action, vars(ActionAPI.from_model(action)))
     runner = RunnerType.get_by_name(action.runner_type['name'])
     self.assertDictEqual(execution.runner, vars(RunnerTypeAPI.from_model(runner)))
     liveaction = LiveAction.get_by_id(str(liveaction.id))
     self.assertEquals(execution.liveaction['id'], str(liveaction.id))
Beispiel #9
0
    def _register_trigger_from_pack(self, pack, trigger):
        trigger_metadata_file_path = trigger

        LOG.debug('Loading trigger from %s.', trigger_metadata_file_path)
        content = self._meta_loader.load(file_path=trigger_metadata_file_path)

        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))

        trigger_api = TriggerTypeAPI(**content)
        trigger_model = TriggerTypeAPI.to_model(trigger_api)

        trigger_types = TriggerType.query(pack=trigger_model.pack, name=trigger_model.name)
        if len(trigger_types) >= 1:
            trigger_type = trigger_types[0]
            LOG.debug('Found existing trigger id:%s with name:%s. Will update it.',
                      trigger_type.id, trigger_type.name)
            trigger_model.id = trigger_type.id

        try:
            trigger_model = TriggerType.add_or_update(trigger_model)
        except:
            LOG.exception('Failed creating trigger model for %s', trigger)

        return trigger_model
Beispiel #10
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
Beispiel #11
0
def create_trigger_type_db(trigger_type):
    """
    Creates 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``
    """
    trigger_type_api = TriggerTypeAPI(**trigger_type)
    trigger_type_api.validate()
    ref = ResourceReference.to_string_reference(name=trigger_type_api.name, pack=trigger_type_api.pack)
    trigger_type_db = get_trigger_type_db(ref)

    if not trigger_type_db:
        trigger_type_db = TriggerTypeAPI.to_model(trigger_type_api)
        LOG.debug("verified trigger and formulated TriggerDB=%s", trigger_type_db)
        trigger_type_db = TriggerType.add_or_update(trigger_type_db)
    return trigger_type_db
Beispiel #12
0
def create_execution_object(liveaction, action_db=None, runnertype_db=None, publish=True):
    if not action_db:
        action_db = action_utils.get_action_by_ref(liveaction.action)

    if not runnertype_db:
        runnertype_db = RunnerType.get_by_name(action_db.runner_type['name'])

    attrs = {
        'action': vars(ActionAPI.from_model(action_db)),
        'parameters': liveaction['parameters'],
        'runner': vars(RunnerTypeAPI.from_model(runnertype_db))
    }
    attrs.update(_decompose_liveaction(liveaction))

    if 'rule' in liveaction.context:
        rule = reference.get_model_from_ref(Rule, liveaction.context.get('rule', {}))
        attrs['rule'] = vars(RuleAPI.from_model(rule))

    if 'trigger_instance' in liveaction.context:
        trigger_instance_id = liveaction.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, liveaction.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 = _get_parent_execution(liveaction)
    if parent:
        attrs['parent'] = str(parent.id)

    attrs['log'] = [_create_execution_log_entry(liveaction['status'])]

    # TODO: This object initialization takes 20-30or so ms
    execution = ActionExecutionDB(**attrs)
    # TODO: Do 100% research this is fully safe and unique in distributed setups
    execution.id = ObjectId()
    execution.web_url = _get_web_url_for_execution(str(execution.id))

    # NOTE: User input data is already validate as part of the API request,
    # other data is set by us. Skipping validation here makes operation 10%-30% faster
    execution = ActionExecution.add_or_update(execution, publish=publish, validate=False)

    if parent and str(execution.id) not in parent.children:
        values = {}
        values['push__children'] = str(execution.id)
        ActionExecution.update(parent, **values)

    return execution
Beispiel #13
0
def create_trigger_type_db(trigger_type):
    """
    Creates 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``
    """
    trigger_type_api = TriggerTypeAPI(**trigger_type)
    trigger_type_api.validate()
    ref = ResourceReference.to_string_reference(name=trigger_type_api.name,
                                                pack=trigger_type_api.pack)
    trigger_type_db = get_trigger_type_db(ref)

    if not trigger_type_db:
        trigger_type_db = TriggerTypeAPI.to_model(trigger_type_api)
        LOG.debug('verified trigger and formulated TriggerDB=%s', trigger_type_db)
        trigger_type_db = TriggerType.add_or_update(trigger_type_db)
    return trigger_type_db
def create_execution_object(liveaction, publish=True):
    action_db = action_utils.get_action_by_ref(liveaction.action)
    runner = RunnerType.get_by_name(action_db.runner_type['name'])

    attrs = {
        'action': vars(ActionAPI.from_model(action_db)),
        'parameters': liveaction['parameters'],
        'runner': vars(RunnerTypeAPI.from_model(runner))
    }
    attrs.update(_decompose_liveaction(liveaction))

    if 'rule' in liveaction.context:
        rule = reference.get_model_from_ref(Rule,
                                            liveaction.context.get('rule', {}))
        attrs['rule'] = vars(RuleAPI.from_model(rule))

    if 'trigger_instance' in liveaction.context:
        trigger_instance_id = liveaction.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, liveaction.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 = _get_parent_execution(liveaction)
    if parent:
        attrs['parent'] = str(parent.id)

    attrs['log'] = [_create_execution_log_entry(liveaction['status'])]

    execution = ActionExecutionDB(**attrs)
    execution = ActionExecution.add_or_update(execution, publish=False)

    # Update the web_url field in execution. Unfortunately, we need
    # the execution id for constructing the URL which we only get
    # after the model is written to disk.
    execution.web_url = _get_web_url_for_execution(str(execution.id))
    execution = ActionExecution.add_or_update(execution, publish=publish)

    if parent:
        if str(execution.id) not in parent.children:
            parent.children.append(str(execution.id))
            ActionExecution.add_or_update(parent)

    return execution
Beispiel #15
0
def create_or_update_trigger_type_db(trigger_type,
                                     log_not_unique_error_as_debug=False):
    """
    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``

    :param log_not_unique_error_as_debug: True to lot NotUnique errors under debug instead of
                                          error log level. This is to be used in scenarios where
                                          failure is non-fatal (e.g. when services register
                                          internal trigger types which is an idempotent
                                          operation).
    :type log_not_unique_error_as_debug: ``bool``

    :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,
            log_not_unique_error_as_debug=log_not_unique_error_as_debug)
    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
Beispiel #16
0
def create_execution_object(liveaction, publish=True):
    action_db = action_utils.get_action_by_ref(liveaction.action)
    runner = RunnerType.get_by_name(action_db.runner_type['name'])

    attrs = {
        'action': vars(ActionAPI.from_model(action_db)),
        'parameters': liveaction['parameters'],
        'runner': vars(RunnerTypeAPI.from_model(runner))
    }
    attrs.update(_decompose_liveaction(liveaction))

    if 'rule' in liveaction.context:
        rule = reference.get_model_from_ref(Rule, liveaction.context.get('rule', {}))
        attrs['rule'] = vars(RuleAPI.from_model(rule))

    if 'trigger_instance' in liveaction.context:
        trigger_instance_id = liveaction.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, liveaction.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 = _get_parent_execution(liveaction)
    if parent:
        attrs['parent'] = str(parent.id)

    attrs['log'] = [_create_execution_log_entry(liveaction['status'])]

    execution = ActionExecutionDB(**attrs)
    execution = ActionExecution.add_or_update(execution, publish=False)

    # Update the web_url field in execution. Unfortunately, we need
    # the execution id for constructing the URL which we only get
    # after the model is written to disk.
    execution.web_url = _get_web_url_for_execution(str(execution.id))
    execution = ActionExecution.add_or_update(execution, publish=publish)

    if parent:
        if str(execution.id) not in parent.children:
            parent.children.append(str(execution.id))
            ActionExecution.add_or_update(parent)

    return execution
Beispiel #17
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

    trigger_type_db = TriggerType.add_or_update(trigger_type_api)

    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
Beispiel #18
0
    def post(self, triggertype):
        """
            Create a new triggertype.

            Handles requests:
                POST /triggertypes/
        """

        try:
            triggertype_db = TriggerTypeAPI.to_model(triggertype)
            triggertype_db = TriggerType.add_or_update(triggertype_db)
        except (ValidationError, ValueError) as e:
            LOG.exception('Validation failed for triggertype data=%s.', triggertype)
            abort(http_client.BAD_REQUEST, six.text_type(e))
            return
        else:
            extra = {'triggertype_db': triggertype_db}
            LOG.audit('TriggerType created. TriggerType.id=%s' % (triggertype_db.id), extra=extra)
            if not triggertype_db.parameters_schema:
                TriggerTypeController._create_shadow_trigger(triggertype_db)

        triggertype_api = TriggerTypeAPI.from_model(triggertype_db)

        return Response(json=triggertype_api, status=http_client.CREATED)
Beispiel #19
0
def create_execution_object(liveaction, publish=True):
    action_db = action_utils.get_action_by_ref(liveaction.action)
    runner = RunnerType.get_by_name(action_db.runner_type['name'])

    attrs = {
        'action': vars(ActionAPI.from_model(action_db)),
        'runner': vars(RunnerTypeAPI.from_model(runner))
    }
    attrs.update(_decompose_liveaction(liveaction))

    if 'rule' in liveaction.context:
        rule = reference.get_model_from_ref(Rule,
                                            liveaction.context.get('rule', {}))
        attrs['rule'] = vars(RuleAPI.from_model(rule))

    if 'trigger_instance' in liveaction.context:
        trigger_instance_id = liveaction.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, liveaction.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 = ActionExecution.get(
        liveaction__id=liveaction.context.get('parent', ''))
    if parent:
        attrs['parent'] = str(parent.id)

    execution = ActionExecutionDB(**attrs)
    execution = ActionExecution.add_or_update(execution, publish=publish)

    if parent:
        if str(execution.id) not in parent.children:
            parent.children.append(str(execution.id))
            ActionExecution.add_or_update(parent)

    return execution
Beispiel #20
0
def create_execution_object(liveaction, publish=True):
    action_db = action_utils.get_action_by_ref(liveaction.action)
    runner = RunnerType.get_by_name(action_db.runner_type['name'])

    attrs = {
        'action': vars(ActionAPI.from_model(action_db)),
        'parameters': liveaction['parameters'],
        'runner': vars(RunnerTypeAPI.from_model(runner))
    }
    attrs.update(_decompose_liveaction(liveaction))

    if 'rule' in liveaction.context:
        rule = reference.get_model_from_ref(Rule, liveaction.context.get('rule', {}))
        attrs['rule'] = vars(RuleAPI.from_model(rule))

    if 'trigger_instance' in liveaction.context:
        trigger_instance_id = liveaction.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, liveaction.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 = _get_parent_execution(liveaction)
    if parent:
        attrs['parent'] = str(parent.id)

    execution = ActionExecutionDB(**attrs)
    execution = ActionExecution.add_or_update(execution, publish=publish)

    if parent:
        if str(execution.id) not in parent.children:
            parent.children.append(str(execution.id))
            ActionExecution.add_or_update(parent)

    return execution
Beispiel #21
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
Beispiel #22
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

    trigger_type_db = TriggerType.add_or_update(trigger_type_api)

    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
Beispiel #23
0
    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"])))
        trace_service.add_or_update_given_trace_context(
            trace_context={"trace_tag": "test_triggered_execution_trace"},
            trigger_instances=[str(trigger_instance.id)],
        )
        enforcer = RuleEnforcer(trigger_instance, rule)
        enforcer.enforce()

        # Wait for the action execution to complete and then confirm outcome.
        liveaction = LiveAction.get(
            context__trigger_instance__id=str(trigger_instance.id))
        self.assertIsNotNone(liveaction)
        liveaction = self._wait_on_status(
            liveaction, action_constants.LIVEACTION_STATUS_FAILED)

        execution = self._get_action_execution(liveaction__id=str(
            liveaction.id),
                                               raise_exception=True)

        self.assertDictEqual(execution.trigger,
                             vars(TriggerAPI.from_model(trigger)))
        self.assertDictEqual(execution.trigger_type,
                             vars(TriggerTypeAPI.from_model(trigger_type)))
        self.assertDictEqual(
            execution.trigger_instance,
            vars(TriggerInstanceAPI.from_model(trigger_instance)),
        )
        self.assertDictEqual(execution.rule, vars(RuleAPI.from_model(rule)))
        action = action_utils.get_action_by_ref(liveaction.action)
        self.assertDictEqual(execution.action,
                             vars(ActionAPI.from_model(action)))
        runner = RunnerType.get_by_name(action.runner_type["name"])
        self.assertDictEqual(execution.runner,
                             vars(RunnerTypeAPI.from_model(runner)))
        liveaction = LiveAction.get_by_id(str(liveaction.id))
        self.assertEqual(execution.start_timestamp, liveaction.start_timestamp)
        # NOTE: Timestamp of liveaction and execution may be a bit different, depending on how long
        # it takes to persist each object in the database
        self.assertEqual(
            execution.end_timestamp.replace(microsecond=0),
            liveaction.end_timestamp.replace(microsecond=0),
        )
        self.assertEqual(execution.result, liveaction.result)
        self.assertEqual(execution.status, liveaction.status)
        self.assertEqual(execution.context, liveaction.context)
        self.assertEqual(execution.liveaction["callback"], liveaction.callback)
        self.assertEqual(execution.liveaction["action"], liveaction.action)