diff --git a/keep/api/core/db.py b/keep/api/core/db.py index e72dce8d2..2032f1cbb 100644 --- a/keep/api/core/db.py +++ b/keep/api/core/db.py @@ -827,7 +827,7 @@ def get_last_workflow_executions(tenant_id: str, limit=20): ) return execution_with_logs - + def get_workflow_executions_count(tenant_id: str): with Session(engine) as session: @@ -1745,7 +1745,7 @@ def get_incident_for_grouping_rule( # Create and add a new incident if it doesn't exist incident = Incident( tenant_id=tenant_id, - user_generated_name=f"Incident generated by rule {rule.name}", + user_generated_name=f"{rule.name}", rule_id=rule.id, rule_fingerprint=rule_fingerprint, is_predicted=False, diff --git a/keep/functions/__init__.py b/keep/functions/__init__.py index 503021a8e..14ab6de64 100644 --- a/keep/functions/__init__.py +++ b/keep/functions/__init__.py @@ -1,11 +1,11 @@ import copy import datetime -import json import re import urllib.parse from datetime import timedelta from itertools import groupby +import json5 as json import pytz from dateutil import parser from dateutil.parser import ParserError @@ -175,6 +175,22 @@ def slice(str_to_slice: str, start: int = 0, end: int = 0) -> str: return str_to_slice[int(start) : int(end)] +def join( + iterable: list | dict | str, delimiter: str = ",", prefix: str | None = None +) -> str: + if isinstance(iterable, str): + iterable = json.loads(iterable) + + if isinstance(iterable, dict): + if prefix: + return delimiter.join([f"{prefix}{k}={v}" for k, v in iterable.items()]) + return delimiter.join([f"{k}={v}" for k, v in iterable.items()]) + + if prefix: + return delimiter.join([f"{prefix}{item}" for item in iterable]) + return delimiter.join([str(item) for item in iterable]) + + def dict_pop(data: str | dict, *args) -> dict: if isinstance(data, str): data = json.loads(data) diff --git a/keep/iohandler/iohandler.py b/keep/iohandler/iohandler.py index 7f0f22fec..4bcbb015c 100644 --- a/keep/iohandler/iohandler.py +++ b/keep/iohandler/iohandler.py @@ -520,17 +520,10 @@ def __get_short_urls(self, urls: list) -> dict: if __name__ == "__main__": # debug & test context_manager = ContextManager("keep") - context_manager.event_context = { - "ticket_id": "1234", - "severity": "high", - "ticket_created_at": "2021-09-01T00:00:00Z", - } + context_manager.event_context = {"tags": {"k1": "v1", "k2": "v2"}} iohandler = IOHandler(context_manager) res = iohandler.render( - iohandler.quote( - "not '{{ alert.ticket_id }}' or (('{{ alert.ticket_status }}' in ['Resolved', 'Closed', 'Canceled']) and ('{{ alert.severity }}' == 'critical' or keep.datetime_compare(keep.utcnow(), keep.to_utc('{{ alert.ticket_created_at }}')) > 168))" - ), - safe=False, + 'https://www.keephq.dev?keep.join("{{alert.tags}}", "&", "prefix_")' ) from asteval import Interpreter diff --git a/keep/providers/cloudwatch_provider/cloudwatch_provider.py b/keep/providers/cloudwatch_provider/cloudwatch_provider.py index 3a04a9521..be200f8ca 100644 --- a/keep/providers/cloudwatch_provider/cloudwatch_provider.py +++ b/keep/providers/cloudwatch_provider/cloudwatch_provider.py @@ -257,6 +257,7 @@ def validate_scopes(self): # 4. validate start query logs_client = self.__generate_client("logs") + query = False try: query = logs_client.start_query( logGroupName="keepTest", @@ -277,6 +278,8 @@ def validate_scopes(self): else: self.logger.info("Error validating AWS logs:StartQuery scope") scopes["logs:StartQuery"] = str(e) + + query_id = False if query: try: query_id = logs_client.describe_queries().get("queries")[0]["queryId"] diff --git a/poetry.lock b/poetry.lock index 5ed29a9fb..65fa8a5cc 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2237,6 +2237,20 @@ files = [ {file = "jmespath-1.0.1.tar.gz", hash = "sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe"}, ] +[[package]] +name = "json5" +version = "0.9.28" +description = "A Python implementation of the JSON5 data format." +optional = false +python-versions = ">=3.8.0" +files = [ + {file = "json5-0.9.28-py3-none-any.whl", hash = "sha256:29c56f1accdd8bc2e037321237662034a7e07921e2b7223281a5ce2c46f0c4df"}, + {file = "json5-0.9.28.tar.gz", hash = "sha256:1f82f36e615bc5b42f1bbd49dbc94b12563c56408c6ffa06414ea310890e9a6e"}, +] + +[package.extras] +dev = ["build (==1.2.2.post1)", "coverage (==7.5.3)", "mypy (==1.13.0)", "pip (==24.3.1)", "pylint (==3.2.3)", "ruff (==0.7.3)", "twine (==5.1.1)", "uv (==0.5.1)"] + [[package]] name = "jwcrypto" version = "1.5.6" @@ -5353,4 +5367,4 @@ test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", [metadata] lock-version = "2.0" python-versions = ">=3.11,<3.12" -content-hash = "d405584a8c24ff3b5e3c7f4405d24145e5b2bf7b951f5c6279977d7cd0780d5e" +content-hash = "1f7fba5a2c241db5654d7f84018d40650402bdc53e46ef5b09e7fcf3d6f055a8" diff --git a/pyproject.toml b/pyproject.toml index ee75f9569..713a701e1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "keep" -version = "0.29.1" +version = "0.29.2" description = "Alerting. for developers, by developers." authors = ["Keep Alerting LTD"] readme = "README.md" @@ -95,6 +95,7 @@ networkx = "^3.3" google-auth = "2.34.0" clickhouse-driver = "^0.2.9" google-cloud-logging = "^3.11.3" +json5 = "^0.9.28" [tool.poetry.group.dev.dependencies] pre-commit = "^3.0.4" pre-commit-hooks = "^4.4.0"