Module: check_mk
Branch: master
Commit: 5cdc5c5fe25ea7bdef717a19599dae4696eed986
URL:
http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=5cdc5c5fe25ea7…
Author: Lars Michelsen <lm(a)mathias-kettner.de>
Date: Sun Apr 14 17:01:21 2019 +0200
RuleMatcher: Implement ability to query fields of nested documents
Change-Id: I17c6e08a60ebcfc4759f163ab8de82e0facb4d17
---
cmk/utils/rulesets/rule_matcher.py | 19 +++++++++++++++++--
tests/unit/cmk/utils/rulesets/test_rule_matcher.py | 10 +++++++++-
2 files changed, 26 insertions(+), 3 deletions(-)
diff --git a/cmk/utils/rulesets/rule_matcher.py b/cmk/utils/rulesets/rule_matcher.py
index 2c11da8..098affd 100644
--- a/cmk/utils/rulesets/rule_matcher.py
+++ b/cmk/utils/rulesets/rule_matcher.py
@@ -96,15 +96,30 @@ class RuleMatcher(object):
yield self._match_leaf_clause(document, field_or_op, cond)
def _match_leaf_clause(self, document, field, condition):
+ field_exists, value = True, None
+ try:
+ value = self._get_value(document, field)
+ except KeyError:
+ field_exists = False
+
if isinstance(condition, collections.Mapping):
# There are two options for dicts. It's either a operator object or
# a nested document match (which is only possible as full document
# equal comparison). In case of an operator object all keys are operators.
if self._is_operator_object(condition):
- return all(self._match_operator_object(document[field], condition))
+ return all(self._match_operator_object(value, condition))
# Realize the leaf equal comparison
- return field in document and document[field] == condition
+ return field_exists and value == condition
+
+ def _get_value(self, document, field):
+ """Returns either the value or raises a KeyError in case the field
does not exist
+ This method implements the ability to query fields of nested documents.
+ """
+ if not isinstance(field, six.string_types) or "." not in field:
+ return document[field]
+
+ return reduce(operator.getitem, field.split("."), document)
def _is_operator_object(self, condition):
"""Once one operator field is found in the
expression"""
diff --git a/tests/unit/cmk/utils/rulesets/test_rule_matcher.py
b/tests/unit/cmk/utils/rulesets/test_rule_matcher.py
index a14c215..1f988ce 100644
--- a/tests/unit/cmk/utils/rulesets/test_rule_matcher.py
+++ b/tests/unit/cmk/utils/rulesets/test_rule_matcher.py
@@ -70,10 +70,18 @@ SIMPLE_MATCHES = [
}, []),
Case({u"düng": u"däng"}, [HOST_TEST]),
Case({1: 2}, [HOST_PROD]),
+ Case({"not_existing": "bla"}, []),
]
NESTED_FIELD_MATCHES = [
- # Case({"tags.crit": "test"}, [HOST_TEST]),
+ Case({"tags.crit": "test"}, [HOST_TEST]),
+ Case({"tags.crit": {
+ "$eq": "test"
+ }}, [HOST_TEST]),
+ Case({"tags.crit": {
+ "$ne": "test"
+ }}, [HOST_PROD]),
+ Case({"tags.not_existing": "test"}, []),
]
COMPARISON_MATCHES = [