From 3db4fed1d55ca1e9e915d8f8381f496eaa176543 Mon Sep 17 00:00:00 2001 From: Tal Date: Fri, 3 Jan 2025 15:49:35 +0200 Subject: [PATCH 01/12] chore(version): bump (#2972) --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 859bc0811..8c766f55b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "keep" -version = "0.33.7" +version = "0.33.8" description = "Alerting. for developers, by developers." authors = ["Keep Alerting LTD"] packages = [{include = "keep"}] From 0b5e146e2d8b2e825f7ed37d74ca928bb0f6e818 Mon Sep 17 00:00:00 2001 From: Adilbek Kangerey Date: Sat, 4 Jan 2025 01:08:02 +0500 Subject: [PATCH 02/12] fix: event as list[AlertDTO] not included in the condition (#2966) Co-authored-by: Tal --- keep/api/tasks/process_event_task.py | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/keep/api/tasks/process_event_task.py b/keep/api/tasks/process_event_task.py index 09415a90d..4b9b7fcb7 100644 --- a/keep/api/tasks/process_event_task.py +++ b/keep/api/tasks/process_event_task.py @@ -597,12 +597,26 @@ def process_event( except Exception: provider_class = ProvidersFactory.get_provider_class("keep") - event = provider_class.format_alert( - tenant_id=tenant_id, - event=event, - provider_id=provider_id, - provider_type=provider_type, - ) + if isinstance(event, list): + event_list = [] + for event_item in event: + if not isinstance(event_item, AlertDto): + event_list.append(provider_class.format_alert( + tenant_id=tenant_id, + event=event_item, + provider_id=provider_id, + provider_type=provider_type, + )) + else: + event_list.append(event_item) + event = event_list + else: + event = provider_class.format_alert( + tenant_id=tenant_id, + event=event, + provider_id=provider_id, + provider_type=provider_type, + ) # SHAHAR: for aws cloudwatch, we get a subscription notification message that we should skip # todo: move it to be generic if event is None and provider_type == "cloudwatch": From 1a6ea83486934b7e3ed378b61e4fe2bb2fba35c7 Mon Sep 17 00:00:00 2001 From: Shahar Glazner Date: Sat, 4 Jan 2025 18:28:45 +0200 Subject: [PATCH 03/12] feat(ui): minor changes in the uI (#2977) --- keep-ui/app/(keep)/alerts/ViewAlertModal.tsx | 4 +- .../(keep)/alerts/alerts-rules-builder.tsx | 104 ++++++++---------- 2 files changed, 45 insertions(+), 63 deletions(-) diff --git a/keep-ui/app/(keep)/alerts/ViewAlertModal.tsx b/keep-ui/app/(keep)/alerts/ViewAlertModal.tsx index 9bda67c80..17ae55cb8 100644 --- a/keep-ui/app/(keep)/alerts/ViewAlertModal.tsx +++ b/keep-ui/app/(keep)/alerts/ViewAlertModal.tsx @@ -99,7 +99,7 @@ export const ViewAlertModal: React.FC = ({

Alert Details

@@ -130,7 +130,7 @@ export const ViewAlertModal: React.FC = ({
{alert && ( -
+        
           

{

{highlightKeys(alert, alert.enriched_fields)}

}

diff --git a/keep-ui/app/(keep)/alerts/alerts-rules-builder.tsx b/keep-ui/app/(keep)/alerts/alerts-rules-builder.tsx index 96e18f9c7..957305bc2 100644 --- a/keep-ui/app/(keep)/alerts/alerts-rules-builder.tsx +++ b/keep-ui/app/(keep)/alerts/alerts-rules-builder.tsx @@ -12,6 +12,7 @@ import QueryBuilder, { } from "react-querybuilder"; import "react-querybuilder/dist/query-builder.scss"; import { Table } from "@tanstack/react-table"; +import { FiSave } from "react-icons/fi"; import { AlertDto, severityMapping, @@ -27,8 +28,6 @@ import { FiExternalLink } from "react-icons/fi"; import { usePathname, useRouter, useSearchParams } from "next/navigation"; import { toast } from "react-toastify"; import { CornerDownLeft } from "lucide-react"; -import { Link } from "@/components/ui"; -import { DocumentTextIcon } from "@heroicons/react/24/outline"; import { STATIC_PRESETS_NAMES } from "@/entities/presets/model/constants"; import { Preset } from "@/entities/presets/model/types"; import { usePresetActions } from "@/entities/presets/model/usePresetActions"; @@ -89,7 +88,7 @@ const CustomMenuList = (props: MenuListProps<{}>) => { Enter to update query { + // Use existing validation logic const celQuery = formatQuery(parseCEL(celExpression), "cel"); - - // Normalize both strings by: - // 1. Removing all whitespace - // 2. Creating versions with both single and double quotes - const normalizedCelQuery = celQuery.replace(/\s+/g, ""); - const normalizedExpression = celExpression.replace(/\s+/g, ""); - - // Create variants with different quote styles - const celQuerySingleQuotes = normalizedCelQuery.replace(/"/g, "'"); - const celQueryDoubleQuotes = normalizedCelQuery.replace(/'/g, '"'); - const isValidCEL = - normalizedExpression === celQuerySingleQuotes || - normalizedExpression === celQueryDoubleQuotes || + celQuery.replace(/\s+/g, "") === celExpression.replace(/\s+/g, "") || celExpression === ""; if (isValidCEL && celExpression.length) { + // If CEL is valid and not empty, set the CEL rules for the preset and open the modal setPresetCEL?.(celExpression); setIsModalOpen?.(true); } else { + // If CEL is invalid or empty, inform the user alert("You can only save a valid CEL expression."); setIsValidCEL(isValidCEL); } @@ -573,25 +563,28 @@ export const AlertsRulesBuilder = ({
{/* Textarea and error message container */}
-