示例#1
0
文件: filter.py 项目: zwunix/st2
    def filter(self):
        """
        Return true if the rule is applicable to the provided trigger instance.

        :rtype: ``bool``
        """
        LOG.info('Validating rule %s for %s.',
                 self.rule.ref,
                 self.trigger['name'],
                 extra=self._base_logger_context)

        if not self.rule.enabled:
            if self.extra_info:
                LOG.info('Validation failed for rule %s as it is disabled.',
                         self.rule.ref)
            return False

        criteria = self.rule.criteria
        is_rule_applicable = True

        if criteria and not self.trigger_instance.payload:
            return False

        payload_lookup = PayloadLookup(self.trigger_instance.payload)

        LOG.debug('Trigger payload: %s',
                  self.trigger_instance.payload,
                  extra=self._base_logger_context)

        for (criterion_k, criterion_v) in six.iteritems(criteria):
            is_rule_applicable, payload_value, criterion_pattern = self._check_criterion(
                criterion_k, criterion_v, payload_lookup)
            if not is_rule_applicable:
                if self.extra_info:
                    criteria_extra_info = '\n'.join([
                        '  key: %s' % criterion_k,
                        '  pattern: %s' % criterion_pattern,
                        '  type: %s' % criterion_v['type'],
                        '  payload: %s' % payload_value
                    ])
                    LOG.info('Validation for rule %s failed on criteria -\n%s',
                             self.rule.ref,
                             criteria_extra_info,
                             extra=self._base_logger_context)
                break

        if not is_rule_applicable:
            LOG.debug('Rule %s not applicable for %s.',
                      self.rule.id,
                      self.trigger['name'],
                      extra=self._base_logger_context)

        return is_rule_applicable
示例#2
0
 def setUpClass(cls):
     cls.payload = PayloadLookup({
         "pikachu": "Has no ears",
         "charmander": "Plays with fire",
     })
     super(PayloadLookupTestCase, cls).setUpClass()
示例#3
0
def search(value, criteria_pattern, criteria_condition, check_function):
    """
    Search a list of values that match all child criteria. If condition is 'any', return a
    successful match if any items match all child criteria. If condition is 'all', return a
    successful match if ALL items match all child criteria.

    value: the payload list to search
    condition: one of:
      * any - return true if any payload items of the list match all criteria items
      * all - return true if all payload items of the list match all criteria items
      * all2any - return true if all payload items of the list match any criteria items
      * any2any - return true if any payload items match any criteria items
    pattern: a dictionary of criteria to apply to each item of the list

    This operator has O(n) algorithmic complexity in terms of number of child patterns.
    This operator has O(n) algorithmic complexity in terms of number of payload fields.

    However, it has O(n_patterns * n_payloads) algorithmic complexity, where:
      n_patterns = number of child patterns
      n_payloads = number of fields in payload
    It is therefore very easy to write a slow rule when using this operator.

    This operator should ONLY be used when trying to match a small number of child patterns and/or
    a small number of payload list elements.

    Other conditions (such as 'count', 'count_gt', 'count_gte', etc.) can be added as needed.

    Data from the trigger:

    {
        "fields": [
            {
                "field_name": "Status",
                "to_value": "Approved"
            }
        ]
    }

    Example #1

    ---
    criteria:
      trigger.fields:
        type: search
        # Controls whether this criteria has to match any or all items of the list
        condition: any  # or all or all2any or any2any
        pattern:
          # Here our context is each item of the list
          # All of these patterns have to match the item for the item to match
          # These are simply other operators applied to each item in the list
          # "#" and text after are ignored.
          # This allows dictionary keys to be unique but refer to the same field
          item.field_name:
            type: "equals"
            pattern: "Status"

          item.to_value:
            type: "equals"
            pattern: "Approved"

          item.field_name#1:
            type: "greaterthan"
            pattern: 40

          item.field_name#2:
            type: "lessthan"
            pattern: 50
    """
    if isinstance(value, dict):
        value = [value]
    payloadItemMatch = all
    patternMatch = all
    if criteria_condition == "any":
        payloadItemMatch = any
    elif criteria_condition == "all2any":
        patternMatch = any
    elif criteria_condition == "any2any":
        payloadItemMatch = any
        patternMatch = any
    elif criteria_condition != "all":
        raise UnrecognizedConditionError(
            "The '%s' condition is not recognized for type search, 'any', 'all', 'any2any'"
            " and 'all2any' are allowed" % criteria_condition)

    rtn = payloadItemMatch([
        # any/all payload item can match
        patternMatch([
            # Match any/all patterns
            check_function(
                child_criterion_k,
                child_criterion_v,
                PayloadLookup(child_payload,
                              prefix=TRIGGER_ITEM_PAYLOAD_PREFIX),
            ) for child_criterion_k, child_criterion_v in six.iteritems(
                criteria_pattern)
        ]) for child_payload in value
    ])
    return rtn
示例#4
0
文件: operators.py 项目: zwunix/st2
def search(value, criteria_pattern, criteria_condition, check_function):
    """
    Search a list of values that match all child criteria. If condition is 'any', return a
    successful match if any items match all child criteria. If condition is 'all', return a
    successful match if ALL items match all child criteria.

    value: the payload list to search
    condition: one of:
      * any - return true if any items of the list match and false if none of them match
      * all - return true if all items of the list match and false if any of them do not match
    pattern: a dictionary of criteria to apply to each item of the list

    This operator has O(n) algorithmic complexity in terms of number of child patterns.
    This operator has O(n) algorithmic complexity in terms of number of payload fields.

    However, it has O(n_patterns * n_payloads) algorithmic complexity, where:
      n_patterns = number of child patterns
      n_payloads = number of fields in payload
    It is therefore very easy to write a slow rule when using this operator.

    This operator should ONLY be used when trying to match a small number of child patterns and/or
    a small number of payload list elements.

    Other conditions (such as 'count', 'count_gt', 'count_gte', etc.) can be added as needed.

    Data from the trigger:

    {
        "fields": [
            {
                "field_name": "Status",
                "to_value": "Approved"
            }
        ]
    }

    And an example usage in criteria:

    ---
    criteria:
      trigger.fields:
        type: search
        # Controls whether this criteria has to match any or all items of the list
        condition: any  # or all
        pattern:
          # Here our context is each item of the list
          # All of these patterns have to match the item for the item to match
          # These are simply other operators applied to each item in the list
          item.field_name:
            type: "equals"
            pattern: "Status"

          item.to_value:
            type: "equals"
            pattern: "Approved"
    """
    if criteria_condition == 'any':
        # Any item of the list can match all patterns
        rtn = any([
            # Any payload item can match
            all([
                # Match all patterns
                check_function(
                    child_criterion_k, child_criterion_v,
                    PayloadLookup(child_payload,
                                  prefix=TRIGGER_ITEM_PAYLOAD_PREFIX))
                for child_criterion_k, child_criterion_v in six.iteritems(
                    criteria_pattern)
            ]) for child_payload in value
        ])
    elif criteria_condition == 'all':
        # Every item of the list must match all patterns
        rtn = all([
            # All payload items must match
            all([
                # Match all patterns
                check_function(
                    child_criterion_k, child_criterion_v,
                    PayloadLookup(child_payload,
                                  prefix=TRIGGER_ITEM_PAYLOAD_PREFIX))
                for child_criterion_k, child_criterion_v in six.iteritems(
                    criteria_pattern)
            ]) for child_payload in value
        ])
    else:
        raise UnrecognizedConditionError(
            "The '%s' search condition is not recognized, only 'any' "
            "and 'all' are allowed" % criteria_condition)

    return rtn
示例#5
0
    def filter(self):
        """
        Return true if the rule is applicable to the provided trigger instance.

        :rtype: ``bool``
        """
        LOG.info(
            "Validating rule %s for %s.",
            self.rule.ref,
            self.trigger["name"],
            extra=self._base_logger_context,
        )

        if not self.rule.enabled:
            if self.extra_info:
                LOG.info("Validation failed for rule %s as it is disabled.",
                         self.rule.ref)
            return False

        criteria = self.rule.criteria
        is_rule_applicable = True

        if criteria and not self.trigger_instance.payload:
            return False

        payload_lookup = PayloadLookup(self.trigger_instance.payload)

        LOG.debug(
            "Trigger payload: %s",
            self.trigger_instance.payload,
            extra=self._base_logger_context,
        )

        for (criterion_k, criterion_v) in six.iteritems(criteria):
            (
                is_rule_applicable,
                payload_value,
                criterion_pattern,
            ) = self._check_criterion(criterion_k, criterion_v, payload_lookup)
            if not is_rule_applicable:
                if self.extra_info:
                    criteria_extra_info = "\n".join([
                        "  key: %s" % criterion_k,
                        "  pattern: %s" % criterion_pattern,
                        "  type: %s" % criterion_v["type"],
                        "  payload: %s" % payload_value,
                    ])
                    LOG.info(
                        "Validation for rule %s failed on criteria -\n%s",
                        self.rule.ref,
                        criteria_extra_info,
                        extra=self._base_logger_context,
                    )
                break

        if not is_rule_applicable:
            LOG.debug(
                "Rule %s not applicable for %s.",
                self.rule.id,
                self.trigger["name"],
                extra=self._base_logger_context,
            )

        return is_rule_applicable