예제 #1
0
파일: base.py 프로젝트: zwunix/st2
class ChangeRevFakeModelDB(stormbase.StormBaseDB,
                           stormbase.ChangeRevisionFieldMixin):
    context = stormbase.EscapedDictField()
예제 #2
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']
예제 #3
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())
    # 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': ['context.user']
        }, {
            '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']
예제 #4
0
파일: rule.py 프로젝트: yetudada/st2
class RuleDB(stormbase.StormFoundationDB, stormbase.TagsMixin,
             stormbase.ContentPackResourceMixin, stormbase.UIDFieldMixin):
    """Specifies the action to invoke on the occurrence of a Trigger. It
    also includes the transformation to perform to match the impedance
    between the payload of a TriggerInstance and input of a action.
    Attribute:
        trigger: Trigger that trips this rule.
        criteria:
        action: Action to execute when the rule is tripped.
        status: enabled or disabled. If disabled occurrence of the trigger
        does not lead to execution of a action and vice-versa.
    """
    RESOURCE_TYPE = ResourceType.RULE
    UID_FIELDS = ['pack', 'name']

    name = me.StringField(required=True)
    ref = me.StringField(required=True)
    description = me.StringField()
    pack = me.StringField(required=False,
                          help_text='Name of the content pack.',
                          unique_with='name')
    type = me.EmbeddedDocumentField(RuleTypeSpecDB, default=RuleTypeSpecDB())
    trigger = me.StringField()
    criteria = stormbase.EscapedDictField()
    action = me.EmbeddedDocumentField(ActionExecutionSpecDB)
    context = me.DictField(default={}, help_text='Contextual info on the rule')
    enabled = me.BooleanField(
        required=True,
        default=True,
        help_text=u'Flag indicating whether the rule is enabled.')

    meta = {
        'indexes': [
            {
                'fields': ['enabled']
            },
            {
                'fields': ['action.ref']
            },
            {
                'fields': ['trigger']
            },
            {
                'fields': ['context.user']
            },
        ] + (stormbase.ContentPackResourceMixin.get_indexes() +
             stormbase.TagsMixin.get_indexes() +
             stormbase.UIDFieldMixin.get_indexes())
    }

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

        NOTE: This method results in one addition "get one" query where we retrieve corresponding
        action model so we can correctly mask secret parameters.

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

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

        action_ref = result.get('action', {}).get('ref', None)

        if not action_ref:
            return result

        action_db = self._get_referenced_action_model(action_ref=action_ref)

        if not action_db:
            return result

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

        return result

    def _get_referenced_action_model(self, action_ref):
        """
        Return Action object for the action referenced in a rule.

        :param action_ref: Action reference.
        :type action_ref: ``str``

        :rtype: ``ActionDB``
        """
        # NOTE: We need to retrieve pack and name since that's needed for the PK
        action_dbs = Action.query(
            only_fields=['pack', 'ref', 'name', 'parameters'],
            ref=action_ref,
            limit=1)

        if action_dbs:
            return action_dbs[0]

        return None

    def __init__(self, *args, **values):
        super(RuleDB, self).__init__(*args, **values)
        self.ref = self.get_reference().ref
        self.uid = self.get_uid()
예제 #5
0
class FakeModelDB(stormbase.StormBaseDB):
    context = stormbase.EscapedDictField()
    index = mongoengine.IntField(min_value=0)
    category = mongoengine.StringField()
    timestamp = mongoengine.DateTimeField()
예제 #6
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)
예제 #7
0
파일: execution.py 프로젝트: st2sandbox/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 = 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):
        """
        Masks the secret parameters in input and output schema for action execution output.

        :param value: action execution object.
        :type value: ``dict``

        :return: result: action execution object with masked secret paramters in input and output schema.
        :rtype: result: ``dict``
        """

        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"]
                    },
                )

        output_value = ActionExecutionDB.result.parse_field_value(result["result"])
        masked_output_value = output_schema.mask_secret_output(result, output_value)
        result["result"] = masked_output_value

        # 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"]