示例#1
0
文件: action.py 项目: zwunix/st2
class ActionDB(stormbase.StormFoundationDB, stormbase.TagsMixin,
               stormbase.ContentPackResourceMixin, stormbase.UIDFieldMixin):
    """
    The system entity that represents a Stack Action/Automation in the system.

    Attribute:
        enabled: A flag indicating whether this action is enabled in the system.
        entry_point: The entry point to the action.
        runner_type: The actionrunner is used to execute the action.
        parameters: The specification for parameters for the action.
    """

    RESOURCE_TYPE = ResourceType.ACTION
    UID_FIELDS = ['pack', 'name']

    name = me.StringField(required=True)
    ref = me.StringField(required=True)
    description = me.StringField()
    enabled = me.BooleanField(
        required=True, default=True,
        help_text='A flag indicating whether the action is enabled.')
    entry_point = me.StringField(
        required=True,
        help_text='The entry point to the action.')
    pack = me.StringField(
        required=False,
        help_text='Name of the content pack.',
        unique_with='name')
    runner_type = me.DictField(
        required=True, default={},
        help_text='The action runner to use for executing the action.')
    parameters = stormbase.EscapedDynamicField(
        help_text='The specification for parameters for the action.')
    output_schema = stormbase.EscapedDynamicField(
        help_text='The schema for output of the action.')
    notify = me.EmbeddedDocumentField(NotificationSchema)

    meta = {
        'indexes': [
            {'fields': ['name']},
            {'fields': ['pack']},
            {'fields': ['ref']},
        ] + (stormbase.ContentPackResourceMixin.get_indexes() +
            stormbase.TagsMixin.get_indexes() +
            stormbase.UIDFieldMixin.get_indexes())
    }

    def __init__(self, *args, **values):
        super(ActionDB, self).__init__(*args, **values)
        self.ref = self.get_reference().ref
        self.uid = self.get_uid()

    def is_workflow(self):
        """
        Return True if this action is a workflow, False otherwise.

        :rtype: ``bool``
        """
        # pylint: disable=unsubscriptable-object
        return self.runner_type['name'] in WORKFLOW_RUNNER_TYPES
示例#2
0
class NotificationSubSchema(me.EmbeddedDocument):
    """
    Schema for notification settings to be specified for action success/failure.
    """

    message = me.StringField()
    data = stormbase.EscapedDynamicField(
        default={}, help_text="Payload to be sent as part of notification.")
    routes = me.ListField(default=["notify.default"],
                          help_text="Routes to post notifications to.")
    channels = (
        me.
        ListField(  # Deprecated. Only here for backward compatibility reasons.
            default=["notify.default"],
            help_text="Routes to post notifications to."))

    def __str__(self):
        result = []
        result.append("NotificationSubSchema@")
        result.append(str(id(self)))
        result.append('(message="%s", ' % str(self.message))
        result.append('data="%s", ' % str(self.data))
        result.append('routes="%s", ' % str(self.routes))
        result.append('[**deprecated**]channels="%s")' % str(self.channels))
        return "".join(result)
示例#3
0
class ConfigDB(stormbase.StormFoundationDB):
    """
    System entity representing pack config.
    """
    pack = me.StringField(
        required=True,
        unique=True,
        help_text='Name of the content pack this config belongs to.')
    values = stormbase.EscapedDynamicField(
        help_text='Config values.',
        default={})

    def mask_secrets(self, value):
        """
        Process the model dictionary and mask secret values.

        :type value: ``dict``
        :param value: Document dictionary.

        :rtype: ``dict``
        """
        result = copy.deepcopy(value)

        config_schema = config_schema_access.get_by_pack(result['pack'])

        secret_parameters = get_secret_parameters(parameters=config_schema.attributes)
        result['values'] = mask_secret_parameters(parameters=result['values'],
                                                  secret_parameters=secret_parameters)

        return result
示例#4
0
class ActionExecutionDB(stormbase.StormFoundationDB):
    trigger = stormbase.EscapedDictField()
    trigger_type = stormbase.EscapedDictField()
    trigger_instance = stormbase.EscapedDictField()
    rule = stormbase.EscapedDictField()
    action = stormbase.EscapedDictField(required=True)
    runner = stormbase.EscapedDictField(required=True)
    # Only the diff between the liveaction type and what is replicated
    # in the ActionExecutionDB object.
    liveaction = stormbase.EscapedDictField(required=True)
    status = me.StringField(required=True,
                            help_text='The current status of the liveaction.')
    start_timestamp = ComplexDateTimeField(
        default=date_utils.get_datetime_utc_now,
        help_text='The timestamp when the liveaction was created.')
    end_timestamp = ComplexDateTimeField(
        help_text='The timestamp when the liveaction has finished.')
    parameters = me.DictField(
        default={},
        help_text='The key-value pairs passed as to the action runner & action.'
    )
    result = stormbase.EscapedDynamicField(default={},
                                           help_text='Action defined result.')
    context = me.DictField(
        default={},
        help_text='Contextual information on the action execution.')
    parent = me.StringField()
    children = me.ListField(field=me.StringField())

    meta = {
        'indexes': [{
            'fields': ['parent']
        }, {
            'fields': ['liveaction.id']
        }, {
            'fields': ['start_timestamp']
        }, {
            'fields': ['action.ref']
        }, {
            'fields': ['status']
        }]
    }

    def mask_secrets(self, value):
        result = copy.deepcopy(value)

        execution_parameters = value['parameters']
        parameters = {}
        # pylint: disable=no-member
        parameters.update(value.get('action', {}).get('parameters', {}))
        parameters.update(value.get('runner', {}).get('runner_parameters', {}))

        secret_parameters = get_secret_parameters(parameters=parameters)
        result['parameters'] = mask_secret_parameters(
            parameters=execution_parameters,
            secret_parameters=secret_parameters)
        return result
示例#5
0
class ConfigDB(stormbase.StormFoundationDB):
    """
    System entity representing pack config.
    """
    pack = me.StringField(
        required=True,
        unique=True,
        help_text='Name of the content pack this config belongs to.')
    values = stormbase.EscapedDynamicField(help_text='Config values.')
示例#6
0
class ConfigSchemaDB(stormbase.StormFoundationDB):
    """
    System entity representing a config schema for a particular pack.
    """

    pack = me.StringField(
        required=True,
        unique=True,
        help_text='Name of the content pack this schema belongs to.')
    attributes = stormbase.EscapedDynamicField(
        help_text='The specification for config schema attributes.')
示例#7
0
class WorkflowExecutionDB(stormbase.StormFoundationDB,
                          stormbase.ChangeRevisionFieldMixin):
    RESOURCE_TYPE = types.ResourceType.EXECUTION

    action_execution = me.StringField(required=True)
    spec = stormbase.EscapedDictField()
    graph = stormbase.EscapedDictField()
    flow = stormbase.EscapedDictField()
    input = stormbase.EscapedDictField()
    output = stormbase.EscapedDictField()
    status = me.StringField(required=True)
    errors = stormbase.EscapedDynamicField()
    start_timestamp = db_field_types.ComplexDateTimeField(
        default=date_utils.get_datetime_utc_now)
    end_timestamp = db_field_types.ComplexDateTimeField()

    meta = {'indexes': [{'fields': ['action_execution']}]}
示例#8
0
class NotificationSubSchema(me.EmbeddedDocument):
    """
        Schema for notification settings to be specified for action success/failure.
    """
    message = me.StringField()
    data = stormbase.EscapedDynamicField(
        default={}, help_text='Payload to be sent as part of notification.')
    channels = me.ListField(default=['notify.default'],
                            help_text='Channels to post notifications to.')

    def __str__(self):
        result = []
        result.append('NotificationSubSchema@')
        result.append(str(id(self)))
        result.append('(message="%s", ' % str(self.message))
        result.append('data="%s", ' % str(self.data))
        result.append('channels="%s")' % str(self.channels))
        return ''.join(result)
示例#9
0
class WorkflowExecutionDB(stormbase.StormFoundationDB,
                          stormbase.ChangeRevisionFieldMixin):
    RESOURCE_TYPE = types.ResourceType.EXECUTION

    action_execution = me.StringField(required=True)
    spec = stormbase.EscapedDictField()
    graph = me.DictField()
    input = JSONDictEscapedFieldCompatibilityField()
    notify = me.DictField()
    context = JSONDictEscapedFieldCompatibilityField()
    state = JSONDictEscapedFieldCompatibilityField()
    status = me.StringField(required=True)
    output = JSONDictEscapedFieldCompatibilityField()
    errors = stormbase.EscapedDynamicField()
    start_timestamp = db_field_types.ComplexDateTimeField(
        default=date_utils.get_datetime_utc_now)
    end_timestamp = db_field_types.ComplexDateTimeField()

    meta = {"indexes": [{"fields": ["action_execution"]}]}
示例#10
0
class ActionExecutionDB(stormbase.StormFoundationDB):
    trigger = stormbase.EscapedDictField()
    trigger_type = stormbase.EscapedDictField()
    trigger_instance = stormbase.EscapedDictField()
    rule = stormbase.EscapedDictField()
    action = stormbase.EscapedDictField(required=True)
    runner = stormbase.EscapedDictField(required=True)
    # Only the diff between the liveaction type and what is replicated
    # in the ActionExecutionDB object.
    liveaction = stormbase.EscapedDictField(required=True)
    status = me.StringField(required=True,
                            help_text='The current status of the liveaction.')
    start_timestamp = ComplexDateTimeField(
        default=datetime.datetime.utcnow,
        help_text='The timestamp when the liveaction was created.')
    end_timestamp = ComplexDateTimeField(
        help_text='The timestamp when the liveaction has finished.')
    parameters = me.DictField(
        default={},
        help_text=
        'The key-value pairs passed as to the action runner &  execution.')
    result = stormbase.EscapedDynamicField(default={},
                                           help_text='Action defined result.')
    context = me.DictField(
        default={},
        help_text='Contextual information on the action execution.')
    parent = me.StringField()
    children = me.ListField(field=me.StringField())

    meta = {
        'indexes': [{
            'fields': ['parent']
        }, {
            'fields': ['liveaction.id']
        }, {
            'fields': ['start_timestamp']
        }, {
            'fields': ['action.ref']
        }, {
            'fields': ['status']
        }]
    }
示例#11
0
文件: liveaction.py 项目: dekoder/st2
class LiveActionDB(stormbase.StormFoundationDB):
    """
        The databse entity that represents a Stack Action/Automation in
        the system.

        Attributes:
            status: the most recently observed status of the execution.
                    One of "starting", "running", "completed", "error".
            result: an embedded document structure that holds the
                    output and exit status code from the action.
    """

    # TODO: Can status be an enum at the Mongo layer?
    status = me.StringField(required=True,
                            help_text='The current status of the liveaction.')
    start_timestamp = ComplexDateTimeField(
        default=date_utils.get_datetime_utc_now,
        help_text='The timestamp when the liveaction was created.')
    end_timestamp = ComplexDateTimeField(
        help_text='The timestamp when the liveaction has finished.')
    action = me.StringField(
        required=True,
        help_text='Reference to the action that has to be executed.')
    parameters = me.DictField(
        default={},
        help_text=
        'The key-value pairs passed as to the action runner &  execution.')
    result = stormbase.EscapedDynamicField(default={},
                                           help_text='Action defined result.')
    context = me.DictField(
        default={},
        help_text='Contextual information on the action execution.')
    callback = me.DictField(
        default={},
        help_text=
        'Callback information for the on completion of action execution.')
    runner_info = me.DictField(
        default={},
        help_text='Reference to the runner that executed this liveaction.')
    notify = me.EmbeddedDocumentField(NotificationSchema)

    meta = {'indexes': ['-start_timestamp', 'action']}
示例#12
0
class LiveActionDB_EscapedDynamicField(LiveActionDB):
    result = stormbase.EscapedDynamicField(default={})

    field1 = stormbase.EscapedDynamicField(default={})
    field2 = stormbase.EscapedDynamicField(default={})
    field3 = stormbase.EscapedDynamicField(default={})
 class LiveActionDB_OldFieldType(LiveActionDB):
     result = stormbase.EscapedDynamicField(default={})
 class ActionExecutionDB_OldFieldType(ActionExecutionDB):
     result = stormbase.EscapedDynamicField(default={})
class LiveActionDB(stormbase.StormFoundationDB):
    """
        The databse entity that represents a Stack Action/Automation in
        the system.

        Attributes:
            status: the most recently observed status of the execution.
                    One of "starting", "running", "completed", "error".
            result: an embedded document structure that holds the
                    output and exit status code from the action.
    """

    # TODO: Can status be an enum at the Mongo layer?
    status = me.StringField(required=True,
                            help_text='The current status of the liveaction.')
    start_timestamp = ComplexDateTimeField(
        default=date_utils.get_datetime_utc_now,
        help_text='The timestamp when the liveaction was created.')
    end_timestamp = ComplexDateTimeField(
        help_text='The timestamp when the liveaction has finished.')
    action = me.StringField(
        required=True,
        help_text='Reference to the action that has to be executed.')
    parameters = stormbase.EscapedDynamicField(
        default={},
        help_text=
        'The key-value pairs passed as to the action runner & execution.')
    result = stormbase.EscapedDynamicField(default={},
                                           help_text='Action defined result.')
    context = me.DictField(
        default={},
        help_text='Contextual information on the action execution.')
    callback = me.DictField(
        default={},
        help_text=
        'Callback information for the on completion of action execution.')
    runner_info = me.DictField(
        default={},
        help_text=
        'Information about the runner which executed this live action (hostname, pid).'
    )
    notify = me.EmbeddedDocumentField(NotificationSchema)

    meta = {
        'indexes': [
            {
                'fields': ['-start_timestamp', 'action']
            },
            {
                'fields': ['start_timestamp']
            },
            {
                'fields': ['end_timestamp']
            },
            {
                'fields': ['action']
            },
            {
                'fields': ['status']
            },
        ]
    }

    def mask_secrets(self, value):
        from st2common.util import action_db

        result = copy.deepcopy(value)
        execution_parameters = value['parameters']

        # TODO: This results into two DB looks, we should cache action and runner type object
        # for each liveaction...
        #
        #       ,-'"-.
        # .    f .--. \
        # .\._,\._',' j_
        #  7______""-'__`,
        parameters = action_db.get_action_parameters_specs(
            action_ref=self.action)

        secret_parameters = get_secret_parameters(parameters=parameters)
        result['parameters'] = mask_secret_parameters(
            parameters=execution_parameters,
            secret_parameters=secret_parameters)
        return result

    def get_masked_parameters(self):
        """
        Retrieve parameters with the secrets masked.

        :rtype: ``dict``
        """
        serializable_dict = self.to_serializable_dict(mask_secrets=True)
        return serializable_dict['parameters']
示例#16
0
class LiveActionDB(stormbase.StormFoundationDB):
    workflow_execution = me.StringField()
    task_execution = me.StringField()
    # TODO: Can status be an enum at the Mongo layer?
    status = me.StringField(required=True,
                            help_text="The current status of the liveaction.")
    start_timestamp = ComplexDateTimeField(
        default=date_utils.get_datetime_utc_now,
        help_text="The timestamp when the liveaction was created.",
    )
    end_timestamp = ComplexDateTimeField(
        help_text="The timestamp when the liveaction has finished.")
    action = me.StringField(
        required=True,
        help_text="Reference to the action that has to be executed.")
    action_is_workflow = me.BooleanField(
        default=False,
        help_text=
        "A flag indicating whether the referenced action is a workflow.",
    )
    parameters = stormbase.EscapedDynamicField(
        default={},
        help_text=
        "The key-value pairs passed as to the action runner & execution.",
    )
    result = JSONDictEscapedFieldCompatibilityField(
        default={}, help_text="Action defined result.")
    context = me.DictField(
        default={},
        help_text="Contextual information on the action execution.")
    callback = me.DictField(
        default={},
        help_text=
        "Callback information for the on completion of action execution.",
    )
    runner_info = me.DictField(
        default={},
        help_text=
        "Information about the runner which executed this live action (hostname, pid).",
    )
    notify = me.EmbeddedDocumentField(NotificationSchema)
    delay = me.IntField(
        min_value=0,
        help_text=
        "How long (in milliseconds) to delay the execution before scheduling.",
    )

    meta = {
        "indexes": [
            {
                "fields": ["-start_timestamp", "action"]
            },
            {
                "fields": ["start_timestamp"]
            },
            {
                "fields": ["end_timestamp"]
            },
            {
                "fields": ["action"]
            },
            {
                "fields": ["status"]
            },
            {
                "fields": ["context.trigger_instance.id"]
            },
            {
                "fields": ["workflow_execution"]
            },
            {
                "fields": ["task_execution"]
            },
        ],
    }

    def mask_secrets(self, value):
        from st2common.util import action_db

        result = copy.deepcopy(value)
        execution_parameters = value["parameters"]

        # TODO: This results into two DB looks, we should cache action and runner type object
        # for each liveaction...
        #
        #       ,-'"-.
        # .    f .--. \
        # .\._,\._',' j_
        #  7______""-'__`,
        parameters = action_db.get_action_parameters_specs(
            action_ref=self.action)

        secret_parameters = get_secret_parameters(parameters=parameters)
        result["parameters"] = mask_secret_parameters(
            parameters=execution_parameters,
            secret_parameters=secret_parameters)
        return result

    def get_masked_parameters(self):
        """
        Retrieve parameters with the secrets masked.

        :rtype: ``dict``
        """
        serializable_dict = self.to_serializable_dict(mask_secrets=True)
        return serializable_dict["parameters"]
示例#17
0
class ActionExecutionDB(stormbase.StormFoundationDB):
    RESOURCE_TYPE = ResourceType.EXECUTION
    UID_FIELDS = ['id']

    trigger = stormbase.EscapedDictField()
    trigger_type = stormbase.EscapedDictField()
    trigger_instance = stormbase.EscapedDictField()
    rule = stormbase.EscapedDictField()
    action = stormbase.EscapedDictField(required=True)
    runner = stormbase.EscapedDictField(required=True)
    # Only the diff between the liveaction type and what is replicated
    # in the ActionExecutionDB object.
    liveaction = stormbase.EscapedDictField(required=True)
    status = me.StringField(
        required=True,
        help_text='The current status of the liveaction.')
    start_timestamp = ComplexDateTimeField(
        default=date_utils.get_datetime_utc_now,
        help_text='The timestamp when the liveaction was created.')
    end_timestamp = ComplexDateTimeField(
        help_text='The timestamp when the liveaction has finished.')
    parameters = stormbase.EscapedDynamicField(
        default={},
        help_text='The key-value pairs passed as to the action runner & action.')
    result = stormbase.EscapedDynamicField(
        default={},
        help_text='Action defined result.')
    context = me.DictField(
        default={},
        help_text='Contextual information on the action execution.')
    parent = me.StringField()
    children = me.ListField(field=me.StringField())
    log = me.ListField(field=me.DictField())

    meta = {
        'indexes': [
            {'fields': ['rule.ref']},
            {'fields': ['action.ref']},
            {'fields': ['liveaction.id']},
            {'fields': ['start_timestamp']},
            {'fields': ['end_timestamp']},
            {'fields': ['status']},
            {'fields': ['parent']},
            {'fields': ['-start_timestamp', 'action.ref', 'status']}
        ]
    }

    def get_uid(self):
        # TODO Construct od from non id field:
        uid = [self.RESOURCE_TYPE, str(self.id)]
        return ':'.join(uid)

    def mask_secrets(self, value):
        result = copy.deepcopy(value)

        execution_parameters = value['parameters']
        parameters = {}
        # pylint: disable=no-member
        parameters.update(value.get('action', {}).get('parameters', {}))
        parameters.update(value.get('runner', {}).get('runner_parameters', {}))

        secret_parameters = get_secret_parameters(parameters=parameters)
        result['parameters'] = mask_secret_parameters(parameters=execution_parameters,
                                                      secret_parameters=secret_parameters)
        return result

    def get_masked_parameters(self):
        """
        Retrieve parameters with the secrets masked.

        :rtype: ``dict``
        """
        serializable_dict = self.to_serializable_dict(mask_secrets=True)
        return serializable_dict['parameters']
示例#18
0
class ActionExecutionDB(stormbase.StormFoundationDB):
    RESOURCE_TYPE = ResourceType.EXECUTION
    UID_FIELDS = ["id"]

    trigger = stormbase.EscapedDictField()
    trigger_type = stormbase.EscapedDictField()
    trigger_instance = stormbase.EscapedDictField()
    rule = stormbase.EscapedDictField()
    action = stormbase.EscapedDictField(required=True)
    runner = stormbase.EscapedDictField(required=True)
    # Only the diff between the liveaction type and what is replicated
    # in the ActionExecutionDB object.
    liveaction = stormbase.EscapedDictField(required=True)
    workflow_execution = me.StringField()
    task_execution = me.StringField()
    status = me.StringField(required=True,
                            help_text="The current status of the liveaction.")
    start_timestamp = ComplexDateTimeField(
        default=date_utils.get_datetime_utc_now,
        help_text="The timestamp when the liveaction was created.",
    )
    end_timestamp = ComplexDateTimeField(
        help_text="The timestamp when the liveaction has finished.")
    parameters = stormbase.EscapedDynamicField(
        default={},
        help_text=
        "The key-value pairs passed as to the action runner & action.",
    )
    result = JSONDictEscapedFieldCompatibilityField(
        default={}, help_text="Action defined result.")
    result_size = me.IntField(default=0,
                              help_text="Serialized result size in bytes")
    context = me.DictField(
        default={},
        help_text="Contextual information on the action execution.")
    parent = me.StringField()
    children = me.ListField(field=me.StringField())
    log = me.ListField(field=me.DictField())
    delay = me.IntField(min_value=0)
    # Do not use URLField for web_url. If host doesn't have FQDN set, URLField validation blows.
    web_url = me.StringField(required=False)

    meta = {
        "indexes": [
            {
                "fields": ["rule.ref"]
            },
            {
                "fields": ["action.ref"]
            },
            {
                "fields": ["liveaction.id"]
            },
            {
                "fields": ["start_timestamp"]
            },
            {
                "fields": ["end_timestamp"]
            },
            {
                "fields": ["status"]
            },
            {
                "fields": ["parent"]
            },
            {
                "fields": ["rule.name"]
            },
            {
                "fields": ["runner.name"]
            },
            {
                "fields": ["trigger.name"]
            },
            {
                "fields": ["trigger_type.name"]
            },
            {
                "fields": ["trigger_instance.id"]
            },
            {
                "fields": ["context.user"]
            },
            {
                "fields": ["-start_timestamp", "action.ref", "status"]
            },
            {
                "fields": ["workflow_execution"]
            },
            {
                "fields": ["task_execution"]
            },
        ]
    }

    def get_uid(self):
        # TODO Construct id from non id field:
        uid = [self.RESOURCE_TYPE, str(self.id)]  # pylint: disable=no-member
        return ":".join(uid)

    def mask_secrets(self, value):
        result = copy.deepcopy(value)

        liveaction = result["liveaction"]
        parameters = {}
        # pylint: disable=no-member
        parameters.update(value.get("action", {}).get("parameters", {}))
        parameters.update(value.get("runner", {}).get("runner_parameters", {}))

        secret_parameters = get_secret_parameters(parameters=parameters)
        result["parameters"] = mask_secret_parameters(
            parameters=result.get("parameters", {}),
            secret_parameters=secret_parameters)

        if "parameters" in liveaction:
            liveaction["parameters"] = mask_secret_parameters(
                parameters=liveaction["parameters"],
                secret_parameters=secret_parameters)

            if liveaction.get("action", "") == "st2.inquiry.respond":
                # Special case to mask parameters for `st2.inquiry.respond` action
                # In this case, this execution is just a plain python action, not
                # an inquiry, so we don't natively have a handle on the response
                # schema.
                #
                # To prevent leakage, we can just mask all response fields.
                #
                # Note: The 'string' type in secret_parameters doesn't matter,
                #       it's just a placeholder to tell mask_secret_parameters()
                #       that this parameter is indeed a secret parameter and to
                #       mask it.
                result["parameters"]["response"] = mask_secret_parameters(
                    parameters=liveaction["parameters"]["response"],
                    secret_parameters={
                        p: "string"
                        for p in liveaction["parameters"]["response"]
                    },
                )

        # TODO(mierdin): This logic should be moved to the dedicated Inquiry
        # data model once it exists.
        result["result"] = ActionExecutionDB.result.parse_field_value(
            result["result"])

        if self.runner.get("name") == "inquirer":
            schema = result["result"].get("schema", {})
            response = result["result"].get("response", {})

            # We can only mask response secrets if response and schema exist and are
            # not empty
            if response and schema:
                result["result"]["response"] = mask_inquiry_response(
                    response, schema)
        return result

    def get_masked_parameters(self):
        """
        Retrieve parameters with the secrets masked.

        :rtype: ``dict``
        """
        serializable_dict = self.to_serializable_dict(mask_secrets=True)
        return serializable_dict["parameters"]
示例#19
0
class ModelWithEscapedDynamicFieldDB(stormbase.StormFoundationDB):
    result = stormbase.EscapedDynamicField(default={}, use_header=False)
    counter = me.IntField(default=0)

    meta = {"collection": "model_result_test"}
示例#20
0
class LiveActionDB_EscapedDictField(LiveActionDB):
    result = stormbase.EscapedDictField(default={})

    field1 = stormbase.EscapedDynamicField(default={}, use_header=False)
    field2 = stormbase.EscapedDynamicField(default={}, use_header=False)
    field3 = stormbase.EscapedDynamicField(default={}, use_header=False)
示例#21
0
文件: execution.py 项目: versus/st2
class ActionExecutionDB(stormbase.StormFoundationDB):
    RESOURCE_TYPE = ResourceType.EXECUTION
    UID_FIELDS = ['id']

    trigger = stormbase.EscapedDictField()
    trigger_type = stormbase.EscapedDictField()
    trigger_instance = stormbase.EscapedDictField()
    rule = stormbase.EscapedDictField()
    action = stormbase.EscapedDictField(required=True)
    runner = stormbase.EscapedDictField(required=True)
    # Only the diff between the liveaction type and what is replicated
    # in the ActionExecutionDB object.
    liveaction = stormbase.EscapedDictField(required=True)
    workflow_execution = me.StringField()
    task_execution = me.StringField()
    status = me.StringField(required=True,
                            help_text='The current status of the liveaction.')
    start_timestamp = ComplexDateTimeField(
        default=date_utils.get_datetime_utc_now,
        help_text='The timestamp when the liveaction was created.')
    end_timestamp = ComplexDateTimeField(
        help_text='The timestamp when the liveaction has finished.')
    parameters = stormbase.EscapedDynamicField(
        default={},
        help_text='The key-value pairs passed as to the action runner & action.'
    )
    result = stormbase.EscapedDynamicField(default={},
                                           help_text='Action defined result.')
    context = me.DictField(
        default={},
        help_text='Contextual information on the action execution.')
    parent = me.StringField()
    children = me.ListField(field=me.StringField())
    log = me.ListField(field=me.DictField())
    # Do not use URLField for web_url. If host doesn't have FQDN set, URLField validation blows.
    web_url = me.StringField(required=False)

    meta = {
        'indexes': [{
            'fields': ['rule.ref']
        }, {
            'fields': ['action.ref']
        }, {
            'fields': ['liveaction.id']
        }, {
            'fields': ['start_timestamp']
        }, {
            'fields': ['end_timestamp']
        }, {
            'fields': ['status']
        }, {
            'fields': ['parent']
        }, {
            'fields': ['rule.name']
        }, {
            'fields': ['runner.name']
        }, {
            'fields': ['trigger.name']
        }, {
            'fields': ['trigger_type.name']
        }, {
            'fields': ['trigger_instance.id']
        }, {
            'fields': ['context.user']
        }, {
            'fields': ['-start_timestamp', 'action.ref', 'status']
        }, {
            'fields': ['workflow_execution']
        }, {
            'fields': ['task_execution']
        }]
    }

    def get_uid(self):
        # TODO Construct od from non id field:
        uid = [self.RESOURCE_TYPE, str(self.id)]
        return ':'.join(uid)

    def mask_secrets(self, value):
        result = copy.deepcopy(value)

        liveaction = result['liveaction']
        parameters = {}
        # pylint: disable=no-member
        parameters.update(value.get('action', {}).get('parameters', {}))
        parameters.update(value.get('runner', {}).get('runner_parameters', {}))

        secret_parameters = get_secret_parameters(parameters=parameters)
        result['parameters'] = mask_secret_parameters(
            parameters=result['parameters'],
            secret_parameters=secret_parameters)

        if 'parameters' in liveaction:
            liveaction['parameters'] = mask_secret_parameters(
                parameters=liveaction['parameters'],
                secret_parameters=secret_parameters)

            if liveaction.get('action', '') == 'st2.inquiry.respond':
                # Special case to mask parameters for `st2.inquiry.respond` action
                # In this case, this execution is just a plain python action, not
                # an inquiry, so we don't natively have a handle on the response
                # schema.
                #
                # To prevent leakage, we can just mask all response fields.
                #
                # Note: The 'string' type in secret_parameters doesn't matter,
                #       it's just a placeholder to tell mask_secret_parameters()
                #       that this parameter is indeed a secret parameter and to
                #       mask it.
                result['parameters']['response'] = mask_secret_parameters(
                    parameters=liveaction['parameters']['response'],
                    secret_parameters={
                        p: 'string'
                        for p in liveaction['parameters']['response']
                    })

        # TODO(mierdin): This logic should be moved to the dedicated Inquiry
        # data model once it exists.
        if self.runner.get('name') == "inquirer":

            schema = result['result'].get('schema', {})
            response = result['result'].get('response', {})

            # We can only mask response secrets if response and schema exist and are
            # not empty
            if response and schema:
                result['result']['response'] = mask_inquiry_response(
                    response, schema)
        return result

    def get_masked_parameters(self):
        """
        Retrieve parameters with the secrets masked.

        :rtype: ``dict``
        """
        serializable_dict = self.to_serializable_dict(mask_secrets=True)
        return serializable_dict['parameters']
示例#22
0
class LiveActionDB(stormbase.StormFoundationDB):
    workflow_execution = me.StringField()
    task_execution = me.StringField()
    # TODO: Can status be an enum at the Mongo layer?
    status = me.StringField(required=True,
                            help_text='The current status of the liveaction.')
    start_timestamp = ComplexDateTimeField(
        default=date_utils.get_datetime_utc_now,
        help_text='The timestamp when the liveaction was created.')
    end_timestamp = ComplexDateTimeField(
        help_text='The timestamp when the liveaction has finished.')
    action = me.StringField(
        required=True,
        help_text='Reference to the action that has to be executed.')
    action_is_workflow = me.BooleanField(
        default=False,
        help_text=
        'A flag indicating whether the referenced action is a workflow.')
    parameters = stormbase.EscapedDynamicField(
        default={},
        help_text=
        'The key-value pairs passed as to the action runner & execution.')
    result = stormbase.EscapedDynamicField(default={},
                                           help_text='Action defined result.')
    context = me.DictField(
        default={},
        help_text='Contextual information on the action execution.')
    callback = me.DictField(
        default={},
        help_text=
        'Callback information for the on completion of action execution.')
    runner_info = me.DictField(
        default={},
        help_text=
        'Information about the runner which executed this live action (hostname, pid).'
    )
    notify = me.EmbeddedDocumentField(NotificationSchema)

    meta = {
        'indexes': [{
            'fields': ['-start_timestamp', 'action']
        }, {
            'fields': ['start_timestamp']
        }, {
            'fields': ['end_timestamp']
        }, {
            'fields': ['action']
        }, {
            'fields': ['status']
        }, {
            'fields': ['context.trigger_instance.id']
        }, {
            'fields': ['workflow_execution']
        }, {
            'fields': ['task_execution']
        }]
    }

    def mask_secrets(self, value):
        from st2common.util import action_db

        result = copy.deepcopy(value)
        execution_parameters = value['parameters']

        # TODO: This results into two DB looks, we should cache action and runner type object
        # for each liveaction...
        #
        #       ,-'"-.
        # .    f .--. \
        # .\._,\._',' j_
        #  7______""-'__`,
        parameters = action_db.get_action_parameters_specs(
            action_ref=self.action)

        secret_parameters = get_secret_parameters(parameters=parameters)
        result['parameters'] = mask_secret_parameters(
            parameters=execution_parameters,
            secret_parameters=secret_parameters)
        return result

    def get_masked_parameters(self):
        """
        Retrieve parameters with the secrets masked.

        :rtype: ``dict``
        """
        serializable_dict = self.to_serializable_dict(mask_secrets=True)
        return serializable_dict['parameters']