def get_trace_component_for_action_execution(action_execution_db, liveaction_db):
    """
    Returns the trace_component compatible dict representation of an actionexecution.

    :param action_execution_db: ActionExecution to translate
    :type action_execution_db: ActionExecutionDB

    :param liveaction_db: LiveAction corresponding to the supplied ActionExecution
    :type liveaction_db: LiveActionDB

    :rtype: ``dict``
    """
    if not action_execution_db:
        raise ValueError('action_execution_db expected.')
    trace_component = {
        'id': str(action_execution_db.id),
        'ref': str(action_execution_db.action.get('ref', ''))
    }
    caused_by = {}
    parent_context = executions.get_parent_context(liveaction_db=liveaction_db)
    if liveaction_db and parent_context:
        caused_by['type'] = 'action_execution'
        caused_by['id'] = liveaction_db.context['parent'].get('execution_id', None)
    elif action_execution_db.rule and action_execution_db.trigger_instance:
        # Once RuleEnforcement is available that can be used instead.
        caused_by['type'] = 'rule'
        caused_by['id'] = '%s:%s' % (action_execution_db.rule['id'],
                                     action_execution_db.trigger_instance['id'])

    trace_component['caused_by'] = caused_by
    return trace_component
예제 #2
0
파일: trace.py 프로젝트: st2sandbox/st2
def get_trace_component_for_action_execution(action_execution_db,
                                             liveaction_db):
    """
    Returns the trace_component compatible dict representation of an actionexecution.

    :param action_execution_db: ActionExecution to translate
    :type action_execution_db: ActionExecutionDB

    :param liveaction_db: LiveAction corresponding to the supplied ActionExecution
    :type liveaction_db: LiveActionDB

    :rtype: ``dict``
    """
    if not action_execution_db:
        raise ValueError("action_execution_db expected.")
    trace_component = {
        "id": str(action_execution_db.id),
        "ref": str(action_execution_db.action.get("ref", "")),
    }
    caused_by = {}
    parent_context = executions.get_parent_context(liveaction_db=liveaction_db)
    if liveaction_db and parent_context:
        caused_by["type"] = "action_execution"
        caused_by["id"] = liveaction_db.context["parent"].get(
            "execution_id", None)
    elif action_execution_db.rule and action_execution_db.trigger_instance:
        # Once RuleEnforcement is available that can be used instead.
        caused_by["type"] = "rule"
        caused_by["id"] = "%s:%s" % (
            action_execution_db.rule["id"],
            action_execution_db.trigger_instance["id"],
        )

    trace_component["caused_by"] = caused_by
    return trace_component
예제 #3
0
파일: trace.py 프로젝트: st2sandbox/st2
def get_trace_db_by_live_action(liveaction):
    """
    Given a liveaction does the best attempt to return a TraceDB.
    1. From trace_context in liveaction.context
    2. From parent in liveaction.context
    3. From action_execution associated with provided liveaction
    4. Creates a new TraceDB (which calling method is on the hook to persist).

    :param liveaction: liveaction from which to figure out a TraceDB.
    :type liveaction: ``LiveActionDB``

    :returns: (boolean, TraceDB) if the TraceDB was created(but not saved to DB) or
               retrieved from the DB and the TraceDB itself.
    :rtype: ``tuple``
    """
    trace_db = None
    created = False
    # 1. Try to get trace_db from liveaction context.
    #    via trigger_instance + rule or via user specified trace_context
    trace_context = liveaction.context.get(TRACE_CONTEXT, None)
    if trace_context:
        trace_context = _get_valid_trace_context(trace_context)
        trace_db = get_trace(trace_context=trace_context,
                             ignore_trace_tag=True)
        # found a trace_context but no trace_db. This implies a user supplied
        # trace_tag so create a new trace_db
        if not trace_db:
            trace_db = TraceDB(trace_tag=trace_context.trace_tag)
            created = True
        return (created, trace_db)
    # 2. If not found then check if parent context contains an execution_id.
    #    This cover case for child execution of a workflow.
    parent_context = executions.get_parent_context(liveaction_db=liveaction)
    if not trace_context and parent_context:
        parent_execution_id = parent_context.get("execution_id", None)
        if parent_execution_id:
            # go straight to a trace_db. If there is a parent execution then that must
            # be associated with a Trace.
            trace_db = get_trace_db_by_action_execution(
                action_execution_id=parent_execution_id)
            if not trace_db:
                raise StackStormDBObjectNotFoundError(
                    "No trace found for execution %s" % parent_execution_id)
            return (created, trace_db)
    # 3. Check if the action_execution associated with liveaction leads to a trace_db
    execution = ActionExecution.get(liveaction__id=str(liveaction.id))
    if execution:
        trace_db = get_trace_db_by_action_execution(action_execution=execution)
    # 4. No trace_db found, therefore create one. This typically happens
    #    when execution is run by hand.
    if not trace_db:
        trace_db = TraceDB(trace_tag="execution-%s" % str(liveaction.id))
        created = True
    return (created, trace_db)
예제 #4
0
파일: trace.py 프로젝트: AlexeyDeyneko/st2
def get_trace_db_by_live_action(liveaction):
    """
    Given a liveaction does the best attempt to return a TraceDB.
    1. From trace_context in liveaction.context
    2. From parent in liveaction.context
    3. From action_execution associated with provided liveaction
    4. Creates a new TraceDB (which calling method is on the hook to persist).

    :param liveaction: liveaction from which to figure out a TraceDB.
    :type liveaction: ``LiveActionDB``

    :returns: (boolean, TraceDB) if the TraceDB was created(but not saved to DB) or
               retrieved from the DB and the TraceDB itself.
    :rtype: ``tuple``
    """
    trace_db = None
    created = False
    # 1. Try to get trace_db from liveaction context.
    #    via trigger_instance + rule or via user specified trace_context
    trace_context = liveaction.context.get(TRACE_CONTEXT, None)
    if trace_context:
        trace_context = _get_valid_trace_context(trace_context)
        trace_db = get_trace(trace_context=trace_context, ignore_trace_tag=True)
        # found a trace_context but no trace_db. This implies a user supplied
        # trace_tag so create a new trace_db
        if not trace_db:
            trace_db = TraceDB(trace_tag=trace_context.trace_tag)
            created = True
        return (created, trace_db)
    # 2. If not found then check if parent context contains an execution_id.
    #    This cover case for child execution of a workflow.
    parent_context = executions.get_parent_context(liveaction_db=liveaction)
    if not trace_context and parent_context:
        parent_execution_id = parent_context.get('execution_id', None)
        if parent_execution_id:
            # go straight to a trace_db. If there is a parent execution then that must
            # be associated with a Trace.
            trace_db = get_trace_db_by_action_execution(action_execution_id=parent_execution_id)
            if not trace_db:
                raise StackStormDBObjectNotFoundError('No trace found for execution %s' %
                                                      parent_execution_id)
            return (created, trace_db)
    # 3. Check if the action_execution associated with liveaction leads to a trace_db
    execution = ActionExecution.get(liveaction__id=str(liveaction.id))
    if execution:
        trace_db = get_trace_db_by_action_execution(action_execution=execution)
    # 4. No trace_db found, therefore create one. This typically happens
    #    when execution is run by hand.
    if not trace_db:
        trace_db = TraceDB(trace_tag='execution-%s' % str(liveaction.id))
        created = True
    return (created, trace_db)
예제 #5
0
def create_request(liveaction):
    """
    Create an action execution.

    :return: (liveaction, execution)
    :rtype: tuple
    """
    # Use the user context from the parent action execution. Subtasks in a workflow
    # action can be invoked by a system user and so we want to use the user context
    # from the original workflow action.
    parent_context = executions.get_parent_context(liveaction)
    if parent_context:
        parent_user = parent_context.get('user', None)
        if parent_user:
            liveaction.context['user'] = parent_user

    # Validate action.
    action_db = action_utils.get_action_by_ref(liveaction.action)
    if not action_db:
        raise ValueError('Action "%s" cannot be found.' % liveaction.action)
    if not action_db.enabled:
        raise ValueError('Unable to execute. Action "%s" is disabled.' %
                         liveaction.action)

    runnertype_db = action_utils.get_runnertype_by_name(
        action_db.runner_type['name'])

    if not hasattr(liveaction, 'parameters'):
        liveaction.parameters = dict()

    # Validate action parameters.
    schema = util_schema.get_schema_for_action_parameters(action_db)
    validator = util_schema.get_validator()
    util_schema.validate(liveaction.parameters,
                         schema,
                         validator,
                         use_default=True,
                         allow_default_none=True)

    # validate that no immutable params are being overriden. Although possible to
    # ignore the override it is safer to inform the user to avoid surprises.
    immutables = _get_immutable_params(action_db.parameters)
    immutables.extend(_get_immutable_params(runnertype_db.runner_parameters))
    overridden_immutables = [
        p for p in six.iterkeys(liveaction.parameters) if p in immutables
    ]
    if len(overridden_immutables) > 0:
        raise ValueError(
            'Override of immutable parameter(s) %s is unsupported.' %
            str(overridden_immutables))

    # Set notification settings for action.
    # XXX: There are cases when we don't want notifications to be sent for a particular
    # execution. So we should look at liveaction.parameters['notify']
    # and not set liveaction.notify.
    if not _is_notify_empty(action_db.notify):
        liveaction.notify = action_db.notify

    # Write to database and send to message queue.
    liveaction.status = action_constants.LIVEACTION_STATUS_REQUESTED
    liveaction.start_timestamp = date_utils.get_datetime_utc_now()

    # Set the "action_is_workflow" attribute
    liveaction.action_is_workflow = action_db.is_workflow()

    # Publish creation after both liveaction and actionexecution are created.
    liveaction = LiveAction.add_or_update(liveaction, publish=False)

    # Get trace_db if it exists. This could throw. If it throws, we have to cleanup
    # liveaction object so we don't see things in requested mode.
    trace_db = None
    try:
        _, trace_db = trace_service.get_trace_db_by_live_action(liveaction)
    except db_exc.StackStormDBObjectNotFoundError as e:
        _cleanup_liveaction(liveaction)
        raise trace_exc.TraceNotFoundException(str(e))

    execution = executions.create_execution_object(liveaction, publish=False)

    if trace_db:
        trace_service.add_or_update_given_trace_db(
            trace_db=trace_db,
            action_executions=[
                trace_service.get_trace_component_for_action_execution(
                    execution, liveaction)
            ])

    return liveaction, execution
예제 #6
0
파일: action.py 프로젝트: shivankittech/st2
def create_request(liveaction, action_db=None, runnertype_db=None):
    """
    Create an action execution.

    :param action_db: Action model to operate one. If not provided, one is retrieved from the
                      database using values from "liveaction".
    :type action_db: :class:`ActionDB`

    :param runnertype_db: Runner model to operate one. If not provided, one is retrieved from the
                          database using values from "liveaction".
    :type runnertype_db: :class:`RunnerTypeDB`

    :return: (liveaction, execution)
    :rtype: tuple
    """
    # We import this here to avoid conflicts w/ runners that might import this
    # file since the runners don't have the config context by default.
    from st2common.metrics.base import get_driver

    # Use the user context from the parent action execution. Subtasks in a workflow
    # action can be invoked by a system user and so we want to use the user context
    # from the original workflow action.
    parent_context = executions.get_parent_context(liveaction) or {}
    parent_user = parent_context.get("user", None)

    if parent_user:
        liveaction.context["user"] = parent_user

    # Validate action
    if not action_db:
        action_db = action_utils.get_action_by_ref(liveaction.action)

    if not action_db:
        raise ValueError('Action "%s" cannot be found.' % liveaction.action)
    if not action_db.enabled:
        raise ValueError('Unable to execute. Action "%s" is disabled.' %
                         liveaction.action)

    if not runnertype_db:
        runnertype_db = action_utils.get_runnertype_by_name(
            action_db.runner_type["name"])

    if not hasattr(liveaction, "parameters"):
        liveaction.parameters = dict()

    # For consistency add pack to the context here in addition to RunnerContainer.dispatch() method
    liveaction.context["pack"] = action_db.pack

    # Validate action parameters.
    schema = util_schema.get_schema_for_action_parameters(
        action_db, runnertype_db)
    validator = util_schema.get_validator()
    util_schema.validate(
        liveaction.parameters,
        schema,
        validator,
        use_default=True,
        allow_default_none=True,
    )

    # validate that no immutable params are being overriden. Although possible to
    # ignore the override it is safer to inform the user to avoid surprises.
    immutables = _get_immutable_params(action_db.parameters)
    immutables.extend(_get_immutable_params(runnertype_db.runner_parameters))
    overridden_immutables = [
        p for p in six.iterkeys(liveaction.parameters) if p in immutables
    ]
    if len(overridden_immutables) > 0:
        raise ValueError(
            "Override of immutable parameter(s) %s is unsupported." %
            str(overridden_immutables))

    # Set notification settings for action.
    # XXX: There are cases when we don't want notifications to be sent for a particular
    # execution. So we should look at liveaction.parameters['notify']
    # and not set liveaction.notify.
    if not _is_notify_skipped(liveaction) and not _is_notify_empty(
            action_db.notify):
        liveaction.notify = action_db.notify

    # Write to database and send to message queue.
    liveaction.status = action_constants.LIVEACTION_STATUS_REQUESTED
    liveaction.start_timestamp = date_utils.get_datetime_utc_now()

    # Set the "action_is_workflow" attribute
    liveaction.action_is_workflow = action_db.is_workflow()

    # Publish creation after both liveaction and actionexecution are created.
    liveaction = LiveAction.add_or_update(liveaction, publish=False)
    # Get trace_db if it exists. This could throw. If it throws, we have to cleanup
    # liveaction object so we don't see things in requested mode.
    trace_db = None
    try:
        _, trace_db = trace_service.get_trace_db_by_live_action(liveaction)
    except db_exc.StackStormDBObjectNotFoundError as e:
        _cleanup_liveaction(liveaction)
        raise trace_exc.TraceNotFoundException(six.text_type(e))

    execution = executions.create_execution_object(
        liveaction=liveaction,
        action_db=action_db,
        runnertype_db=runnertype_db,
        publish=False,
    )

    if trace_db:
        trace_service.add_or_update_given_trace_db(
            trace_db=trace_db,
            action_executions=[
                trace_service.get_trace_component_for_action_execution(
                    execution, liveaction)
            ],
        )

    get_driver().inc_counter("action.executions.%s" % (liveaction.status))

    return liveaction, execution
예제 #7
0
파일: action.py 프로젝트: StackStorm/st2
def create_request(liveaction, action_db=None, runnertype_db=None):
    """
    Create an action execution.

    :param action_db: Action model to operate one. If not provided, one is retrieved from the
                      database using values from "liveaction".
    :type action_db: :class:`ActionDB`

    :param runnertype_db: Runner model to operate one. If not provided, one is retrieved from the
                          database using values from "liveaction".
    :type runnertype_db: :class:`RunnerTypeDB`

    :return: (liveaction, execution)
    :rtype: tuple
    """
    # We import this here to avoid conflicts w/ runners that might import this
    # file since the runners don't have the config context by default.
    from st2common.metrics.base import get_driver

    # Use the user context from the parent action execution. Subtasks in a workflow
    # action can be invoked by a system user and so we want to use the user context
    # from the original workflow action.
    parent_context = executions.get_parent_context(liveaction) or {}
    parent_user = parent_context.get('user', None)

    if parent_user:
        liveaction.context['user'] = parent_user

    # Validate action
    if not action_db:
        action_db = action_utils.get_action_by_ref(liveaction.action)

    if not action_db:
        raise ValueError('Action "%s" cannot be found.' % liveaction.action)
    if not action_db.enabled:
        raise ValueError('Unable to execute. Action "%s" is disabled.' % liveaction.action)

    if not runnertype_db:
        runnertype_db = action_utils.get_runnertype_by_name(action_db.runner_type['name'])

    if not hasattr(liveaction, 'parameters'):
        liveaction.parameters = dict()

    # For consistency add pack to the context here in addition to RunnerContainer.dispatch() method
    liveaction.context['pack'] = action_db.pack

    # Validate action parameters.
    schema = util_schema.get_schema_for_action_parameters(action_db, runnertype_db)
    validator = util_schema.get_validator()
    util_schema.validate(liveaction.parameters, schema, validator, use_default=True,
                         allow_default_none=True)

    # validate that no immutable params are being overriden. Although possible to
    # ignore the override it is safer to inform the user to avoid surprises.
    immutables = _get_immutable_params(action_db.parameters)
    immutables.extend(_get_immutable_params(runnertype_db.runner_parameters))
    overridden_immutables = [p for p in six.iterkeys(liveaction.parameters) if p in immutables]
    if len(overridden_immutables) > 0:
        raise ValueError('Override of immutable parameter(s) %s is unsupported.'
                         % str(overridden_immutables))

    # Set notification settings for action.
    # XXX: There are cases when we don't want notifications to be sent for a particular
    # execution. So we should look at liveaction.parameters['notify']
    # and not set liveaction.notify.
    if not _is_notify_empty(action_db.notify):
        liveaction.notify = action_db.notify

    # Write to database and send to message queue.
    liveaction.status = action_constants.LIVEACTION_STATUS_REQUESTED
    liveaction.start_timestamp = date_utils.get_datetime_utc_now()

    # Set the "action_is_workflow" attribute
    liveaction.action_is_workflow = action_db.is_workflow()

    # Publish creation after both liveaction and actionexecution are created.
    liveaction = LiveAction.add_or_update(liveaction, publish=False)
    # Get trace_db if it exists. This could throw. If it throws, we have to cleanup
    # liveaction object so we don't see things in requested mode.
    trace_db = None
    try:
        _, trace_db = trace_service.get_trace_db_by_live_action(liveaction)
    except db_exc.StackStormDBObjectNotFoundError as e:
        _cleanup_liveaction(liveaction)
        raise trace_exc.TraceNotFoundException(six.text_type(e))

    execution = executions.create_execution_object(liveaction=liveaction, action_db=action_db,
                                                   runnertype_db=runnertype_db, publish=False)

    if trace_db:
        trace_service.add_or_update_given_trace_db(
            trace_db=trace_db,
            action_executions=[
                trace_service.get_trace_component_for_action_execution(execution, liveaction)
            ])

    get_driver().inc_counter('action.executions.%s' % (liveaction.status))

    return liveaction, execution
예제 #8
0
파일: action.py 프로젝트: AlexeyDeyneko/st2
def create_request(liveaction):
    """
    Create an action execution.

    :return: (liveaction, execution)
    :rtype: tuple
    """
    # Use the user context from the parent action execution. Subtasks in a workflow
    # action can be invoked by a system user and so we want to use the user context
    # from the original workflow action.
    parent_context = executions.get_parent_context(liveaction)
    if parent_context:
        parent_user = parent_context.get('user', None)
        if parent_user:
            liveaction.context['user'] = parent_user

    # Validate action.
    action_db = action_utils.get_action_by_ref(liveaction.action)
    if not action_db:
        raise ValueError('Action "%s" cannot be found.' % liveaction.action)
    if not action_db.enabled:
        raise ValueError('Unable to execute. Action "%s" is disabled.' % liveaction.action)

    runnertype_db = action_utils.get_runnertype_by_name(action_db.runner_type['name'])

    if not hasattr(liveaction, 'parameters'):
        liveaction.parameters = dict()

    # Validate action parameters.
    schema = util_schema.get_schema_for_action_parameters(action_db)
    validator = util_schema.get_validator()
    util_schema.validate(liveaction.parameters, schema, validator, use_default=True,
                         allow_default_none=True)

    # validate that no immutable params are being overriden. Although possible to
    # ignore the override it is safer to inform the user to avoid surprises.
    immutables = _get_immutable_params(action_db.parameters)
    immutables.extend(_get_immutable_params(runnertype_db.runner_parameters))
    overridden_immutables = [p for p in six.iterkeys(liveaction.parameters) if p in immutables]
    if len(overridden_immutables) > 0:
        raise ValueError('Override of immutable parameter(s) %s is unsupported.'
                         % str(overridden_immutables))

    # Set notification settings for action.
    # XXX: There are cases when we don't want notifications to be sent for a particular
    # execution. So we should look at liveaction.parameters['notify']
    # and not set liveaction.notify.
    if not _is_notify_empty(action_db.notify):
        liveaction.notify = action_db.notify

    # Write to database and send to message queue.
    liveaction.status = action_constants.LIVEACTION_STATUS_REQUESTED
    liveaction.start_timestamp = date_utils.get_datetime_utc_now()

    # Publish creation after both liveaction and actionexecution are created.
    liveaction = LiveAction.add_or_update(liveaction, publish=False)

    # Get trace_db if it exists. This could throw. If it throws, we have to cleanup
    # liveaction object so we don't see things in requested mode.
    trace_db = None
    try:
        _, trace_db = trace_service.get_trace_db_by_live_action(liveaction)
    except StackStormDBObjectNotFoundError as e:
        _cleanup_liveaction(liveaction)
        raise TraceNotFoundException(str(e))

    execution = executions.create_execution_object(liveaction, publish=False)

    if trace_db:
        trace_service.add_or_update_given_trace_db(
            trace_db=trace_db,
            action_executions=[
                trace_service.get_trace_component_for_action_execution(execution, liveaction)
            ])

    return liveaction, execution