Skip to content

Commit

Permalink
Merge branch 'main' into checkmk
Browse files Browse the repository at this point in the history
  • Loading branch information
shahargl authored Oct 29, 2024
2 parents cc3e64e + f549b05 commit 9881b2a
Show file tree
Hide file tree
Showing 77 changed files with 3,710 additions and 884 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ Workflow triggers can either be executed manually when an alert is activated or
          
<img width=32 height=32 src="https://github.com/keephq/keep/blob/main/keep-ui/public/icons/grafana-icon.png?raw=true"/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<img width=32 height=32 src="https://github.com/keephq/keep/blob/main/keep-ui/public/icons/graylog-icon.png?raw=true"/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<img width=32 height=32 src="https://github.com/keephq/keep/blob/main/keep-ui/public/icons/prometheus-icon.png?raw=true"/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<img width=32 height=32 src="https://github.com/keephq/keep/blob/main/keep-ui/public/icons/sumologic-icon.png?raw=true"/>
Expand Down
3 changes: 3 additions & 0 deletions docs/api-ref/alerts/get-alert-quality.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
openapi: get /alerts/quality/metrics
---
3 changes: 3 additions & 0 deletions docs/api-ref/incidents/add-comment.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
openapi: post /incidents/{incident_id}/comment
---
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
openapi: get /incidents/{incident_id}/future_incidents
---
3 changes: 3 additions & 0 deletions docs/api-ref/incidents/get-incident-workflows.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
openapi: get /incidents/{incident_id}/workflows
---
3 changes: 3 additions & 0 deletions docs/api-ref/incidents/get-incidents-meta.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
openapi: get /incidents/meta
---
3 changes: 3 additions & 0 deletions docs/api-ref/incidents/merge-incidents.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
openapi: post /incidents/merge
---
5 changes: 3 additions & 2 deletions docs/deployment/authentication/keycloak-auth.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ To start Keep with Keycloak authentication, set the following environment variab
| AUTH_TYPE | Set to 'KEYCLOAK' for Keycloak authentication | Yes | - |
| KEYCLOAK_ID | Your Keycloak client ID (e.g. keep) | Yes | - |
| KEYCLOAK_ISSUER | Full URL to Your Keycloak issuer URL e.g. http://localhost:8181/auth/realms/keep | Yes | - |
| KEYCLOAK_SECRET | Your Keycloak client secret | Yes | keep-keycloak-secret |

#### Backend Environment Variables

Expand All @@ -50,5 +51,5 @@ To start Keep with Keycloak authentication, set the following environment variab
### Example configuration

To get a better understanding on how to use Keep together with Keycloak, you can:
- See [Keycloak](https://github.com/keephq/keep/tree/main/tests) directory for configuration, realm.json, etc
- See Keep + Keycloak [docker-compose example](https://github.com/keephq/keep/blob/main/keycloak/docker-compose.yml)
- See [Keycloak](https://github.com/keephq/keep/tree/main/keycloak) directory for configuration, realm.json, etc
- See Keep + Keycloak [docker-compose example](https://github.com/keephq/keep/blob/main/keycloak/docker-compose.yaml)
11 changes: 9 additions & 2 deletions docs/mint.json
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@
"providers/documentation/grafana-provider",
"providers/documentation/grafana_incident-provider",
"providers/documentation/grafana_oncall-provider",
"providers/documentation/graylog-provider",
"providers/documentation/http-provider",
"providers/documentation/ilert-provider",
"providers/documentation/incidentio-provider",
Expand Down Expand Up @@ -331,7 +332,8 @@
"api-ref/alerts/unenrich-alert",
"api-ref/alerts/search-alerts",
"api-ref/alerts/get-alert-audit",
"api-ref/alerts/get-alerts"
"api-ref/alerts/get-alerts",
"api-ref/alerts/get-alert-quality"
]
},
{
Expand Down Expand Up @@ -366,7 +368,12 @@
"api-ref/incidents/get-incident-alerts",
"api-ref/incidents/add-alerts-to-incident",
"api-ref/incidents/delete-alerts-from-incident",
"api-ref/incidents/confirm-incident"
"api-ref/incidents/confirm-incident",
"api-ref/incidents/add-comment",
"api-ref/incidents/get-future-incidents-for-an-incident",
"api-ref/incidents/get-incident-workflows",
"api-ref/incidents/get-incidents-meta",
"api-ref/incidents/merge-incidents"
]
},
{
Expand Down
2 changes: 1 addition & 1 deletion docs/openapi.json

Large diffs are not rendered by default.

59 changes: 59 additions & 0 deletions docs/providers/documentation/graylog-provider.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
---
title: "Graylog Provider"
sidebarTitle: "Graylog Provider"
description: "The Graylog provider enables webhook installations for receiving alerts in Keep"
---

## Overview

The **Graylog Provider** facilitates receiving alerts from Graylog by setting up Webhook connections. It allows seamless integration with Graylog to receive notifications about events and alerts through Keep.

## Authentication Parameters

- **Username** (required): Username for authenticating with Graylog's API.
- **Graylog Access Token** (required): Access token for authenticating with Graylog's API.
- **Deployment Url** (required): Deployment URL for connecting to the Graylog instance (e.g., `http://localhost:9000`).

## Scopes

- **authenticated**: Mandatory for all operations, ensures the user is authenticated.
- **authorized**: Mandatory for querying incidents and managing resources, ensures the user has `Admin` privileges.

## Connecting with the Provider

1. Obtain the **username** and **access token** from your Graylog instance by following [Graylog's API Access Documentation](https://go2docs.graylog.org/current/setting_up_graylog/rest_api_access_tokens.htm?tocpath=Set%20up%20Graylog%7CGet%20Started%20with%20Graylog%7CREST%C2%A0API%7C_____3#CreateanAccessToken).
2. Set the **deployment URL** to your Graylog instance's base URL (e.g., `http://127.0.0.1:9000`).
3. Ensure the user has the **Admin** role in Graylog.

## Features

The **Graylog Provider** supports the following key features:

- **Webhook Setup**: Configures webhooks to send alerts to Keep.
- **Alerts Retrieval**: Fetches and formats alerts from Graylog based on specified search parameters (only a maximum of 10000 most recent alerts)

## Inputs for Query
- **events_search_parameters**: Takes in a python dict
Example:
```
{
"filter": {"alerts": "only"},
"page": 1,
"per_page": 1000,
"query": "",
"timerange": {"range": 86400, "type": "relative"},
}
```
- You can modify this to fetch either alerts, events or both.

---

**Note**: Ensure that the product of `page` and `per_page` does not exceed 10,000.

---

## Useful Links

- [Graylog API Documentation](https://go2docs.graylog.org/current/what_is_graylog/what_is_graylog.htm?tocpath=What%20Is%20Graylog%253F%7C_____0)
- [Graylog Access Token](https://go2docs.graylog.org/current/setting_up_graylog/rest_api_access_tokens.htm?tocpath=Set%20up%20Graylog%7CGet%20Started%20with%20Graylog%7CREST%C2%A0API%7C_____3#CreateanAccessToken)
- [Quick Setup for Graylog & Integration with Keep](https://github.com/keephq/keep/keep/providers/graylog_provider/README.md)
8 changes: 8 additions & 0 deletions docs/providers/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,14 @@ By leveraging Keep Providers, users are able to deeply integrate Keep with the t
}
></Card>

<Card
title="Graylog"
href="/providers/documentation/graylog-provider"
icon={
<img src="https://github.com/keephq/keep/blob/main/keep-ui/public/icons/graylog-icon.png?raw=true" />
}
></Card>

<Card
title="HTTP"
href="/providers/documentation/http-provider"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import os
import logging

from fastapi import Depends, HTTPException

Expand All @@ -8,6 +9,8 @@
from keycloak.keycloak_uma import KeycloakUMA
from keycloak.uma_permissions import UMAPermission

logger = logging.getLogger(__name__)


class KeycloakAuthVerifier(AuthVerifierBase):
"""Handles authentication and authorization for Keycloak"""
Expand Down Expand Up @@ -55,6 +58,10 @@ def _verify_bearer_token(
email = payload.get("preferred_username")
org_id = payload.get("active_organization", {}).get("id")
org_realm = payload.get("active_organization", {}).get("name")
if org_id is None or org_realm is None:
logger.warning(
"Invalid Keycloak configuration - no org information for user. Check organization mapper: https://github.com/keephq/keep/blob/main/keycloak/keep-realm.json#L93"
)
role = (
payload.get("resource_access", {})
.get(self.keycloak_client_id, {})
Expand Down
121 changes: 71 additions & 50 deletions keep-ui/app/alerts/alert-pagination.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,15 @@ import {
ChevronLeftIcon,
ChevronRightIcon,
TableCellsIcon,
} from "@heroicons/react/24/outline";
} from "@heroicons/react/16/solid";
import { Button, Text } from "@tremor/react";
import { StylesConfig, SingleValueProps, components, GroupBase } from 'react-select';
import Select from 'react-select';
import {
StylesConfig,
SingleValueProps,
components,
GroupBase,
} from "react-select";
import Select from "react-select";
import { AlertDto } from "./models";
import { Table } from "@tanstack/react-table";
import { useAlerts } from "utils/hooks/useAlerts";
Expand All @@ -24,39 +29,46 @@ interface OptionType {
label: string;
}

const customStyles: StylesConfig<OptionType, false, GroupBase<OptionType>> = {
control: (provided, state) => ({
...provided,
borderColor: state.isFocused ? 'orange' : provided.borderColor,
'&:hover': { borderColor: 'orange' },
boxShadow: state.isFocused ? '0 0 0 1px orange' : provided.boxShadow,
}),
singleValue: (provided) => ({
...provided,
display: 'flex',
alignItems: 'center',
}),
menu: (provided) => ({
...provided,
color: 'orange',
}),
option: (provided, state) => ({
...provided,
backgroundColor: state.isSelected ? 'orange' : provided.backgroundColor,
'&:hover': { backgroundColor: state.isSelected ? 'orange' : '#f5f5f5' },
color: state.isSelected ? 'white' : provided.color,
}),
};

const SingleValue = ({ children, ...props }: SingleValueProps<OptionType, false, GroupBase<OptionType>>) => (
<components.SingleValue {...props}>
{children}
<TableCellsIcon className="w-4 h-4 ml-2" />
</components.SingleValue>
);
const customStyles: StylesConfig<OptionType, false, GroupBase<OptionType>> = {
control: (provided, state) => ({
...provided,
borderColor: state.isFocused ? "orange" : "rgb(229 231 235)",
borderRadius: "0.5rem",
"&:hover": { borderColor: "orange" },
boxShadow: state.isFocused ? "0 0 0 1px orange" : provided.boxShadow,
}),
singleValue: (provided) => ({
...provided,
display: "flex",
alignItems: "center",
}),
menu: (provided) => ({
...provided,
color: "orange",
}),
option: (provided, state) => ({
...provided,
backgroundColor: state.isSelected ? "orange" : provided.backgroundColor,
"&:hover": { backgroundColor: state.isSelected ? "orange" : "#f5f5f5" },
color: state.isSelected ? "white" : provided.color,
}),
};

const SingleValue = ({
children,
...props
}: SingleValueProps<OptionType, false, GroupBase<OptionType>>) => (
<components.SingleValue {...props}>
{children}
<TableCellsIcon className="w-4 h-4 ml-2" />
</components.SingleValue>
);

export default function AlertPagination({ presetName, table, isRefreshAllowed }: Props) {
export default function AlertPagination({
presetName,
table,
isRefreshAllowed,
}: Props) {
const { usePresetAlerts } = useAlerts();
const { mutate, isLoading: isValidating } = usePresetAlerts(presetName);

Expand All @@ -69,50 +81,59 @@ export default function AlertPagination({ presetName, table, isRefreshAllowed }:
Showing {pageCount === 0 ? 0 : pageIndex + 1} of {pageCount}
</Text>
<div className="flex gap-1">
<Select
styles={customStyles}
components={{ SingleValue }}
value={{ value: table.getState().pagination.pageSize.toString(), label: table.getState().pagination.pageSize.toString() }}
onChange={(selectedOption) => table.setPageSize(Number(selectedOption!.value))}
options={[
{ value: "10", label: "10" },
{ value: "20", label: "20" },
{ value: "50", label: "50" },
{ value: "100", label: "100" },
]}
menuPlacement="top"
<Select
styles={customStyles}
components={{ SingleValue }}
value={{
value: table.getState().pagination.pageSize.toString(),
label: table.getState().pagination.pageSize.toString(),
}}
onChange={(selectedOption) =>
table.setPageSize(Number(selectedOption!.value))
}
options={[
{ value: "10", label: "10" },
{ value: "20", label: "20" },
{ value: "50", label: "50" },
{ value: "100", label: "100" },
]}
menuPlacement="top"
/>
<div className="flex">
<Button
className="pagination-button"
icon={ChevronDoubleLeftIcon}
onClick={() => table.setPageIndex(0)}
disabled={!table.getCanPreviousPage()}
size="xs"
color="orange"
color="gray"
variant="secondary"
/>
<Button
className="pagination-button"
icon={ChevronLeftIcon}
onClick={table.previousPage}
disabled={!table.getCanPreviousPage()}
size="xs"
color="orange"
color="gray"
variant="secondary"
/>
<Button
className="pagination-button"
icon={ChevronRightIcon}
onClick={table.nextPage}
disabled={!table.getCanNextPage()}
size="xs"
color="orange"
color="gray"
variant="secondary"
/>
<Button
className="pagination-button"
icon={ChevronDoubleRightIcon}
onClick={() => table.setPageIndex(pageCount - 1)}
disabled={!table.getCanNextPage()}
size="xs"
color="orange"
color="gray"
variant="secondary"
/>
</div>
Expand Down
Loading

0 comments on commit 9881b2a

Please sign in to comment.