Skip to content

Commit

Permalink
feat: Merge branch 'feature/basic-impersonation' of https://github.co…
Browse files Browse the repository at this point in the history
…m/palad-in/keep into feature/basic-impersonation
  • Loading branch information
shahargl committed Oct 1, 2024
2 parents dccf848 + 5468a06 commit 68e11c2
Show file tree
Hide file tree
Showing 23 changed files with 1,070 additions and 421 deletions.
2 changes: 1 addition & 1 deletion docs/deployment/kubernetes.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ helm install keep keephq/keep

Notice for it to work locally, you'll need this port forwarding:
```
# expose the UI
kubectl port-forward svc/keep-frontend 3000:3000
kubectl port-forward svc/keep-backend 8080:8080
```

To learn more about Keep's helm chart, see https://github.com/keephq/helm-charts/blob/main/README.md
Expand Down
8 changes: 4 additions & 4 deletions docs/deployment/stress-testing.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,18 @@ The primary parameters that affect the specification requirements for Keep are:

### Testing Scenarios:

- **Low Volume (< 10,000 total alerts, 100's of alerts per day)**:
- **Low Volume (< 10,000 total alerts, hundreds of alerts per day)**:
- **Setup**: Use a standard relational database (e.g., MySQL, PostgreSQL) with default configurations.
- **Expectations**: Keep should handle queries and alert ingestion with minimal resource usage.

- **Medium Volume (10,000 - 100,000 total alerts, 1000's of alerts per day)**:
- **Medium Volume (10,000 - 100,000 total alerts, thousands of alerts per day)**:
- **Setup**: Scale the database to larger instances or clusters. Adjust best practices to the DB (e.g. increasing innodb_buffer_pool_size)
- **Expectations**: CPU and RAM usage should increase proportionally but remain within acceptable limits.

3. **High Volume (100,000 - 1,000,000 total alerts, 5000's of alerts per day)**:
3. **High Volume (100,000 - 1,000,000 total alerts, >five thousands of alerts per day)**:
- **Setup**: Deploy Keep with Elasticsearch for storing alerts as documents.
- **Expectations**: The system should maintain performance levels despite the large alert volume, with increased resource usage managed through scaling strategies.
4. **Very High Volume (> 1,000,000 total alerts, 10k's of alerts per day)**:
4. **Very High Volume (> 1,000,000 total alerts, tens of thousands of alerts per day)**:
- **Setup**: Deploy Keep with Elasticsearch for storing alerts as documents.
- **Setup #2**: Deploy Keep with Redis and with ARQ to use Redis as a queue.

Expand Down
15 changes: 15 additions & 0 deletions examples/workflows/incident_example.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
workflow:
id: aks-example
description: aks-example
triggers:
- type: incident
events:
- updated
- created

actions:
- name: just-echo
provider:
type: console
with:
message: "Hey there! I am an incident!"
6 changes: 3 additions & 3 deletions keep-ui/app/alerts/alert-name.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,11 @@ export default function AlertName({
}

return (
<div className="flex items-center justify-between">
<div className="truncate" title={alert.name}>
<div className="flex items-start justify-between">
<div className="truncate whitespace-pre-wrap" title={alert.name}>
{name}
</div>
<div>
<div className="flex-shrink-0">
{(url ?? generatorURL) && (
<a href={url || generatorURL} target="_blank">
<Icon
Expand Down
161 changes: 161 additions & 0 deletions keep-ui/app/incidents/[id]/incident-workflow-sidebar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
import { Fragment } from "react";
import { Dialog, Transition } from "@headlessui/react";
import { Text, Button, TextInput, Badge, Title, Card } from "@tremor/react";
import { IoMdClose } from "react-icons/io";
import { WorkflowExecution } from "app/workflows/builder/types";
import {
getIcon,
getTriggerIcon,
extractTriggerValue,
} from "app/workflows/[workflow_id]/workflow-execution-table";
import { useWorkflowExecution } from "utils/hooks/useWorkflowExecutions";

interface IncidentWorkflowSidebarProps {
isOpen: boolean;
toggle: VoidFunction;
selectedExecution: WorkflowExecution;
}

const IncidentWorkflowSidebar: React.FC<IncidentWorkflowSidebarProps> = ({
isOpen,
toggle,
selectedExecution,
}) => {
const { data: workflowExecutionData } = useWorkflowExecution(
selectedExecution.workflow_id,
selectedExecution.id
);

return (
<Transition appear show={isOpen} as={Fragment}>
<Dialog onClose={toggle}>
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="ease-in duration-200"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<div className="fixed inset-0 bg-black/30 z-20" aria-hidden="true" />
</Transition.Child>
<Transition.Child
as={Fragment}
enter="transition ease-in-out duration-300 transform"
enterFrom="translate-x-full"
enterTo="translate-x-0"
leave="transition ease-in-out duration-300 transform"
leaveFrom="translate-x-0"
leaveTo="translate-x-full"
>
<Dialog.Panel className="fixed right-0 inset-y-0 w-2/4 bg-white z-30 p-6 overflow-auto flex flex-col">
<div className="flex justify-between mb-4">
<div>
<Dialog.Title className="text-3xl font-bold" as={Title}>
Workflow Execution Details
<Badge
className="ml-4 capitalize"
color={
selectedExecution.status === "error"
? "red"
: selectedExecution.status === "success"
? "green"
: "orange"
}
>
{selectedExecution.status}
</Badge>
</Dialog.Title>
</div>
<div>
<Button onClick={toggle} variant="light">
<IoMdClose className="h-6 w-6 text-gray-500" />
</Button>
</div>
</div>

<div className="flex-grow space-y-4">
<Card>
<div className="space-y-4">
<div>
<Text className="block text-sm font-medium text-gray-700 mb-2">
Execution ID
</Text>
<TextInput value={selectedExecution.id} readOnly />
</div>
<div>
<Text className="block text-sm font-medium text-gray-700 mb-2">
Status
</Text>
<div className="flex items-center">
{getIcon(selectedExecution.status)}
<span className="ml-2 capitalize">
{selectedExecution.status}
</span>
</div>
</div>
<div>
<Text className="block text-sm font-medium text-gray-700 mb-2">
Triggered By
</Text>
<Button
className="px-3 py-0.5 bg-white text-black rounded-xl border-2 border-gray-400 inline-flex items-center gap-2 font-bold hover:bg-white border-gray-400"
variant="secondary"
tooltip={selectedExecution.triggered_by ?? ""}
icon={getTriggerIcon(
extractTriggerValue(selectedExecution.triggered_by)
)}
>
<div>
{extractTriggerValue(selectedExecution.triggered_by)}
</div>
</Button>
</div>
<div>
<Text className="block text-sm font-medium text-gray-700 mb-2">
Execution Time
</Text>
<TextInput
value={
selectedExecution.execution_time
? `${selectedExecution.execution_time} seconds`
: "N/A"
}
readOnly
/>
</div>
<div>
<Text className="block text-sm font-medium text-gray-700 mb-2">
Started At
</Text>
<TextInput value={selectedExecution.started} readOnly />
</div>
</div>
</Card>

<Card>
<Text className="block text-sm font-medium text-gray-700 mb-2">
Execution Logs
</Text>
<div className="bg-gray-100 p-4 rounded-md overflow-auto max-h-96">
<pre className="whitespace-pre-wrap">
{Array.isArray(workflowExecutionData?.logs)
? workflowExecutionData.logs.map((log, index) => (
<div key={index}>
{log.timestamp} - {log.message}
</div>
))
: workflowExecutionData?.logs || "No logs available"}
</pre>
</div>
</Card>
</div>
</Dialog.Panel>
</Transition.Child>
</Dialog>
</Transition>
);
};

export default IncidentWorkflowSidebar;
Loading

0 comments on commit 68e11c2

Please sign in to comment.