Skip to content

Commit

Permalink
Merge branch 'refs/heads/main' into feat-manual-enrichment
Browse files Browse the repository at this point in the history
# Conflicts:
#	keep-ui/app/(keep)/alerts/EnrichAlertModal.tsx
  • Loading branch information
35C4n0r committed Nov 21, 2024
2 parents d9856e9 + 132237b commit 0e3ea59
Show file tree
Hide file tree
Showing 379 changed files with 5,257 additions and 3,455 deletions.
5 changes: 4 additions & 1 deletion docker/Dockerfile.api
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,7 @@ RUN chgrp -R 0 /app && chmod -R g=u /app
RUN chown -R keep:keep /app
RUN chown -R keep:keep /venv
USER keep
ENTRYPOINT ["gunicorn", "keep.api.api:get_app", "--bind" , "0.0.0.0:8080" , "--workers", "4" , "-k" , "uvicorn.workers.UvicornWorker", "-c", "/venv/lib/python3.11/site-packages/keep/api/config.py"]

ENTRYPOINT ["/venv/lib/python3.11/site-packages/keep/entrypoint.sh"]

CMD ["gunicorn", "keep.api.api:get_app", "--bind" , "0.0.0.0:8080" , "--workers", "4" , "-k" , "uvicorn.workers.UvicornWorker", "-c", "/venv/lib/python3.11/site-packages/keep/api/config.py"]
2 changes: 2 additions & 0 deletions docker/Dockerfile.dev.api
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ RUN . /venv/bin/activate && poetry install --no-root
ENV PYTHONPATH="/app:${PYTHONPATH}"
ENV PATH="/venv/bin:${PATH}"
ENV VIRTUAL_ENV="/venv"
ENV POSTHOG_DISABLED="true"

ENTRYPOINT ["/app/keep/entrypoint.sh"]

CMD ["gunicorn", "keep.api.api:get_app", "--bind" , "0.0.0.0:8080" , "--workers", "1" , "-k" , "uvicorn.workers.UvicornWorker", "-c", "./keep/api/config.py", "--reload"]
1 change: 1 addition & 0 deletions docs/deployment/configuration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ General configuration variables control the core behavior of the Keep server. Th
| **KEEP_API_URL** | Specifies the Keep API URL | No | Constructed from HOST and PORT | Valid URL |
| **KEEP_STORE_RAW_ALERTS** | Enables storing of raw alerts | No | "false" | "true" or "false" |
| **TENANT_CONFIGURATION_RELOAD_TIME** | Time in minutes to reload tenant configurations | No | 5 | Positive integer |
| **KEEP_LIVE_DEMO_MODE** | Keep will simulate incoming alerts and other activity | No | "false" | "true" or "false" |

### Logging and Environment
<Info>
Expand Down
Binary file added docs/images/appdynamics_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/appdynamics_10.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/appdynamics_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/appdynamics_3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/appdynamics_4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/appdynamics_5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/appdynamics_6.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/appdynamics_7.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/appdynamics_8.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/appdynamics_9.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
96 changes: 89 additions & 7 deletions docs/providers/documentation/appdynamics-provider.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,100 @@ The AppDynamics provider requires the following authentication parameter:
- `Host`: This is the hostname of the AppDynamics instance you wish to connect to. It identifies the AppDynamics server that the API will interact with.

## Connecting with the Provider
1. Ensure you have a AppDynamics account with the necessary [permissions](https://docs.appdynamics.com/accounts/en/cisco-appdynamics-on-premises-user-management/roles-and-permissions). The basic permissions required are `Account Owner` or `Administrator`. Alternatively you can create an account (instructions)[https://docs.appdynamics.com/accounts/en/global-account-administration/access-management/manage-user-accounts]
1. Ensure you have a AppDynamics account with the necessary [permissions](https://docs.appdynamics.com/accounts/en/cisco-appdynamics-on-premises-user-management/roles-and-permissions). The basic permissions required are `Account Owner` or `Administrator`. Alternatively you can create an account [instructions](https://docs.appdynamics.com/accounts/en/global-account-administration/access-management/manage-user-accounts)

### Basic Auth authentication
## Provider configuration

Obtain AppDynamics Username and Password:
1. Find your account name [here](https://accounts.appdynamics.com/overview).
2. Get the appId of the Appdynamics instance in which you wish to install the webhook into.
3. Determine the Host [here](https://accounts.appdynamics.com/overview).

OR create Access Token:
1. Follow instructions [here](https://docs.appdynamics.com/appd/23.x/latest/en/extend-appdynamics/appdynamics-apis/api-clients)
### Basic Auth authentication

1. Determine the Host [here](https://accounts.appdynamics.com/overview).
2. Get the appId of the Appdynamics instance in which you wish to install the webhook into.
1. Obtain AppDynamics **Username** and **Password**
2. Go to **Basic Auth** tab under **Authentication** section
3. Enter **Username** and **Password**

<Frame>
<img src="/images/appdynamics_9.png" width="1000" alt="Keep add AppDynamics Username and Password"/>
</Frame>

### Access Token authentication

1. Log in to the **Controller UI** as an **Account Owner** or other roles with the **Administer users**, **groups**, **roles** permission.
2. Go to **Administration**

<Frame>
<img src="/images/appdynamics_1.png" width="1000" alt="AppDynamics Administration"/>
</Frame>

3. Go to **API Client** tab

<Frame>
<img src="/images/appdynamics_2.png" width="1000" alt="AppDynamics API Client tab"/>
</Frame>

4. Click **+ Create**

<Frame>
<img src="/images/appdynamics_3.png" width="1000" alt="Create new AppDynamics API Client"/>
</Frame>

5. Fill Client **Name** and **Description**
6. Click **Generate Secret**

<Frame>
<img src="/images/appdynamics_4.png" width="1000" alt="AppDynamics generate API Client Secret"/>
</Frame>

<Tip>
This API Client secret is not an authentication token yet
</Tip>

7. Add **Account Owner** and/or **Administrator** roles

<Frame>
<img src="/images/appdynamics_5.png" width="1000" alt="AppDynamics add API Client roles"/>
</Frame>

8. Click **Save**

<Frame>
<img src="/images/appdynamics_6.png" width="1000" alt="AppDynamics save API Client"/>
</Frame>

9. Click **Generate Temporary Token**

<Frame>
<img src="/images/appdynamics_7.png" width="1000" alt="AppDynamics Generate API Client Temporary Access Token"/>
</Frame>

<Tip>
This token is not persistent, but since Keep uses it just once to install Webhook, we will use it without oAuth
</Tip>

10. Click **Save** one again
<Warning>
This is important. Otherwise generated token will not be saved and authentication will fail
</Warning>
11. Copy generated token

<Frame>
<img src="/images/appdynamics_8.png" width="1000" alt="AppDynamics copy API Client Temporary Access Token"/>
</Frame>

12. Go to **Access Token** tab under **Authentication** section

<Frame>
<img src="/images/appdynamics_10.png" width="1000" alt="Keep add AppDynamics Access Token"/>
</Frame>

13. Enter Access Token

## Connecting provider

1. Ensure **Install webhook** is checked
2. Click **Connect**

## Webhook Integration Modifications

Expand Down
8 changes: 8 additions & 0 deletions keep-ui/app/(keep)/[...not-found]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
"use client";

import { notFound } from "next/navigation";

// https://github.com/vercel/next.js/discussions/50034
export default function NotFoundDummy() {
notFound();
}
File renamed without changes.
4 changes: 2 additions & 2 deletions keep-ui/app/ai/model.ts → keep-ui/app/(keep)/ai/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ export interface AIStats {
incidents_count: number;
first_alert_datetime?: Date;
is_mining_enabled: boolean;
algorithm_verbose_name: string
algorithm_verbose_name: string;
}

export interface AILogs {
log: string;
}
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,43 +1,54 @@
import React, { useState, Fragment, useRef, FormEvent } from 'react';
import { Popover } from '@headlessui/react';
import { Button, Tab, TabGroup, TabList, TabPanels, TabPanel } from "@tremor/react";
import { IoColorPaletteOutline } from 'react-icons/io5';
import React, { useState, Fragment, useRef, FormEvent } from "react";
import { Popover } from "@headlessui/react";
import {
Button,
Tab,
TabGroup,
TabList,
TabPanels,
TabPanel,
} from "@tremor/react";
import { IoColorPaletteOutline } from "react-icons/io5";
import { FloatingArrow, arrow, offset, useFloating } from "@floating-ui/react";

const predefinedThemes = {
Transparent: {
critical: 'bg-white',
high: 'bg-white',
warning: 'bg-white',
low: 'bg-white',
info: 'bg-white'
critical: "bg-white",
high: "bg-white",
warning: "bg-white",
low: "bg-white",
info: "bg-white",
},
Keep: {
critical: 'bg-orange-400', // Highest opacity for critical
high: 'bg-orange-300',
warning: 'bg-orange-200',
low: 'bg-orange-100',
info: 'bg-orange-50' // Lowest opacity for info
critical: "bg-orange-400", // Highest opacity for critical
high: "bg-orange-300",
warning: "bg-orange-200",
low: "bg-orange-100",
info: "bg-orange-50", // Lowest opacity for info
},
Basic: {
critical: 'bg-red-200',
high: 'bg-orange-200',
warning: 'bg-yellow-200',
low: 'bg-green-200',
info: 'bg-blue-200'
}
critical: "bg-red-200",
high: "bg-orange-200",
warning: "bg-yellow-200",
low: "bg-green-200",
info: "bg-blue-200",
},
};

const themeKeyMapping = {
0: 'Transparent',
1: 'Keep',
2: 'Basic'
0: "Transparent",
1: "Keep",
2: "Basic",
};
type ThemeName = keyof typeof predefinedThemes;

export const ThemeSelection = ({ onThemeChange }: { onThemeChange: (theme: any) => void }) => {
export const ThemeSelection = ({
onThemeChange,
}: {
onThemeChange: (theme: any) => void;
}) => {
const arrowRef = useRef(null);
const [selectedTab, setSelectedTab] = useState<ThemeName>('Transparent');
const [selectedTab, setSelectedTab] = useState<ThemeName>("Transparent");

const { refs, floatingStyles, context } = useFloating({
strategy: "fixed",
Expand All @@ -50,22 +61,17 @@ export const ThemeSelection = ({ onThemeChange }: { onThemeChange: (theme: any)
handleApplyTheme(themeIndex as 0 | 1 | 2);
};




const handleApplyTheme = (themeKey: keyof typeof themeKeyMapping) => {
const themeName = themeKeyMapping[themeKey];
setSelectedTab(themeName as ThemeName);
};


};

const onApplyTheme = (close: () => void) => {
// themeName is now assured to be a key of predefinedThemes
const themeName: ThemeName = selectedTab;
const newTheme = predefinedThemes[themeName]; // This should now be error-free
onThemeChange(newTheme);
setSelectedTab('Transparent'); // Assuming 'Transparent' is a valid key
setSelectedTab("Transparent"); // Assuming 'Transparent' is a valid key
close(); // Close the popover
};

Expand All @@ -85,7 +91,7 @@ export const ThemeSelection = ({ onThemeChange }: { onThemeChange: (theme: any)
<Popover.Panel
className="bg-white z-30 p-4 rounded-sm"
ref={refs.setFloating}
style={{ ...floatingStyles, minWidth: '250px' }} // Adjust width here
style={{ ...floatingStyles, minWidth: "250px" }} // Adjust width here
>
<FloatingArrow
className="fill-white [&>path:last-of-type]:stroke-white"
Expand All @@ -100,19 +106,35 @@ export const ThemeSelection = ({ onThemeChange }: { onThemeChange: (theme: any)
<Tab>Basic</Tab>
</TabList>
<TabPanels>
{Object.keys(predefinedThemes).map(themeName => (
{Object.keys(predefinedThemes).map((themeName) => (
<TabPanel key={themeName}>
{Object.entries(predefinedThemes[themeName as keyof typeof predefinedThemes]).map(([severity, color]) => (
<div key={severity} className="flex justify-between items-center my-2">
<span>{severity.charAt(0).toUpperCase() + severity.slice(1).toLowerCase()}</span>
<div className={`w-6 h-6 rounded-full border border-gray-400 ${color}`}></div>
{Object.entries(
predefinedThemes[
themeName as keyof typeof predefinedThemes
]
).map(([severity, color]) => (
<div
key={severity}
className="flex justify-between items-center my-2"
>
<span>
{severity.charAt(0).toUpperCase() +
severity.slice(1).toLowerCase()}
</span>
<div
className={`w-6 h-6 rounded-full border border-gray-400 ${color}`}
></div>
</div>
))}
</TabPanel>
))}
</TabPanels>
</TabGroup>
<Button className="mt-5" color="orange" onClick={() => onApplyTheme(close)}>
<Button
className="mt-5"
color="orange"
onClick={() => onApplyTheme(close)}
>
Apply theme
</Button>
</Popover.Panel>
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Select, { components } from "react-select";
import { Button, TextInput, Text } from "@tremor/react";
import { PlusIcon } from "@heroicons/react/20/solid";
import { useForm, Controller, SubmitHandler } from "react-hook-form";
import { Providers } from "./../providers/providers";
import { Providers } from "../providers/providers";
import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { useApiUrl } from "utils/hooks/useConfig";
import { AlertDto } from "./models";
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@ import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydrated
import { FormEvent, useCallback, useEffect, useState } from "react";
import { toast } from "react-toastify";
import { useApiUrl } from "utils/hooks/useConfig";
import { useIncidents, usePollIncidents } from "../../utils/hooks/useIncidents";
import Loading from "../loading";
import {
useIncidents,
usePollIncidents,
} from "../../../utils/hooks/useIncidents";
import Loading from "@/app/(keep)/loading";
import { AlertDto } from "./models";
import { getIncidentName } from "@/entities/incidents/lib/utils";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Modal from "@/components/ui/Modal";
import { Callout, Button, Title, Card } from "@tremor/react";
import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession";
import { toast } from "react-toastify";
import Loading from "../loading";
import Loading from "@/app/(keep)/loading";
import { AlertDto } from "./models";
import { IncidentDto, IncidentCandidateDto } from "@/entities/incidents/model";
import { useApiUrl } from "utils/hooks/useConfig";
Expand Down
37 changes: 37 additions & 0 deletions keep-ui/app/(keep)/alerts/alert-dismiss-modal.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
.react-datepicker {
font-size: 14px !important;
color: #070707 !important;
}

.react-datepicker__header {
background-color: white !important;
padding-top: 0px !important;
border: none !important;
}

.react-datepicker__day-name {
color: #c7c7c7 !important;
font-size: 14px !important;
}

.react-datepicker__day {
color: black !important;
font-size: 13px !important;
}

.react-datepicker__day--selected,
.react-datepicker__day--keyboard-selected {
border-radius: 25px !important;
background: orange !important;
color: white !important;
}

.react-datepicker__time-list-item--selected {
background: orange !important;
color: white !important;
}

.react-datepicker__day--disabled,
.react-datepicker__time-list-item--disabled {
color: #c7c7c7 !important;
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit 0e3ea59

Please sign in to comment.