From dbb2aad28ffbb3cc104e0743713be9b12e7333f8 Mon Sep 17 00:00:00 2001 From: Arik Alon Date: Sun, 8 Dec 2024 12:42:26 +0200 Subject: [PATCH 1/2] bug fix: include scope with multiple label values, was evaluating only the first one In addition, if there was an error in sending to a sink, the "stop" wasn't respected --- .../playbooks/playbooks_event_handler_impl.py | 21 +++++++++------ src/robusta/utils/scope.py | 26 ++++++++++--------- 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/src/robusta/core/playbooks/playbooks_event_handler_impl.py b/src/robusta/core/playbooks/playbooks_event_handler_impl.py index 82f443f56..412186d7e 100644 --- a/src/robusta/core/playbooks/playbooks_event_handler_impl.py +++ b/src/robusta/core/playbooks/playbooks_event_handler_impl.py @@ -311,14 +311,19 @@ def __handle_findings(self, execution_event: ExecutionBaseEvent): # only write the finding if is matching against the sink matchers if sink.accepts(finding): - # create deep copy, so that iterating on one sink enrichments won't affect the others - # Each sink has a different findings, but enrichments are shared - finding_copy = copy.deepcopy(finding) - sink.write_finding(finding_copy, self.registry.get_sinks().platform_enabled) - - sink_info = sinks_info[sink_name] - sink_info.type = sink.__class__.__name__ - sink_info.findings_count += 1 + try: + # create deep copy, so that iterating on one sink enrichments won't affect the others + # Each sink has a different findings, but enrichments are shared + finding_copy = copy.deepcopy(finding) + sink.write_finding(finding_copy, self.registry.get_sinks().platform_enabled) + + sink_info = sinks_info[sink_name] + sink_info.type = sink.__class__.__name__ + sink_info.findings_count += 1 + except Exception: # if we have an error, we should still respect stop + logging.exception( + f"Failed to send finding {finding.aggregation_key} to sink {sink.sink_name}" + ) if sink.params.stop: return diff --git a/src/robusta/utils/scope.py b/src/robusta/utils/scope.py index 8eac6e2bc..7fb3e2bcf 100644 --- a/src/robusta/utils/scope.py +++ b/src/robusta/utils/scope.py @@ -1,7 +1,7 @@ import logging import re -from abc import abstractmethod, ABC -from typing import Dict, Optional, Union, List +from abc import ABC, abstractmethod +from typing import Dict, List, Optional, Union from pydantic import BaseModel, root_validator @@ -51,22 +51,24 @@ def scope_matches(self, scope: ScopeIncludeExcludeParamsT) -> bool: return False return True + def match_attribute(self, attr_name: str, attr_value, attr_matcher: str) -> bool: + if attr_name == "attributes": + return self.scope_match_attributes(attr_matcher, attr_value) + elif attr_name == "namespace_labels": + return self.scope_match_namespace_labels(attr_matcher, attr_value) + elif attr_name in ["labels", "annotations"]: + return self.match_labels_annotations(attr_matcher, attr_value) + elif re.fullmatch(attr_matcher, attr_value): + return True + return False + def scope_attribute_matches(self, attr_name: str, attr_matchers: List[str]) -> bool: data = self.get_data() if attr_name not in data: logging.warning(f'Scope match on non-existent attribute "{attr_name}" ({data=})') return False attr_value = data[attr_name] - for attr_matcher in attr_matchers: - if attr_name == "attributes": - return self.scope_match_attributes(attr_matcher, attr_value) - elif attr_name == "namespace_labels": - return self.scope_match_namespace_labels(attr_matcher, attr_value) - elif attr_name in ["labels", "annotations"]: - return self.match_labels_annotations(attr_matcher, attr_value) - elif re.fullmatch(attr_matcher, attr_value): - return True - return False + return any([self.match_attribute(attr_name, attr_value, matcher) for matcher in attr_matchers]) def scope_match_attributes(self, attr_matcher: str, attr_value: Dict[str, Union[List, Dict]]) -> bool: raise NotImplementedError From 67f6c926c21176d5937ed8e32c1ce19021974e18 Mon Sep 17 00:00:00 2001 From: Arik Alon Date: Sun, 8 Dec 2024 18:39:36 +0200 Subject: [PATCH 2/2] fix typo in conf.py - remove `/` --- docs/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index 46c5bab81..e944c76e3 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -114,7 +114,7 @@ "tutorials/playbook-track-secrets.html": "/master/playbook-reference/kubernetes-examples//playbook-track-secrets.html", "tutorials/alert-remediation.html": "/master/playbook-reference/prometheus-examples/alert-remediation.html", "tutorials/alert-custom-enrichment.html": "/master/playbook-reference/prometheus-examples/alert-custom-enrichment.html", - "/catalog/sinks/slack.html": "/master/configuration/sinks/slack.html" + "catalog/sinks/slack.html": "/master/configuration/sinks/slack.html" }