Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,12 @@
MongoDB
</a>
</td>
<td align="center" width="150">
<a href="https://docs.keephq.dev/providers/documentation/mongodbatlas-provider" target="_blank">
<img width="40" src="keep-ui/public/icons/mongodbatlas-icon.png" alt="MongoDB Atlas"/><br/>
MongoDB Atlas
</a>
</td>
<td align="center" width="150">
<a href="https://docs.keephq.dev/providers/documentation/mysql-provider" target="_blank">
<img width="40" src="keep-ui/public/icons/mysql-icon.png" alt="MySQL"/><br/>
Expand Down
1 change: 1 addition & 0 deletions docs/mint.json
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@
"providers/documentation/mock-provider",
"providers/documentation/monday-provider",
"providers/documentation/mongodb-provider",
"providers/documentation/mongodbatlas-provider",
"providers/documentation/mysql-provider",
"providers/documentation/netbox-provider",
"providers/documentation/netdata-provider",
Expand Down
69 changes: 69 additions & 0 deletions docs/providers/documentation/mongodbatlas-provider.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
---
title: "MongoDB Atlas Provider"
sidebarTitle: "MongoDB Atlas"
description: "MongoDB Atlas provider allows pulling alerts from Atlas projects and receiving Atlas alert webhooks."
---
import AutoGeneratedSnippet from '/snippets/providers/mongodbatlas-snippet-autogenerated.mdx';

<AutoGeneratedSnippet />

import ProviderLogo from '@components/ProviderLogo';

<ProviderLogo src="/icons/mongodbatlas-icon.png" alt="MongoDB Atlas Logo" />

# MongoDB Atlas Provider

The MongoDB Atlas provider connects Keep to an Atlas project. It supports two ways of getting alerts into Keep:

1. **Pulling** open, tracking, and closed alerts from the [Atlas Administration API](https://www.mongodb.com/docs/api/doc/atlas-admin-api-v2/operation/operation-listalerts).
2. **Receiving** alert notifications pushed by an Atlas [webhook integration](https://www.mongodb.com/docs/atlas/tutorial/webhook-integration/).

## Setup

### Prerequisites

1. An Atlas project.
2. An API key pair (organization or project) with the **Project Read Only** role on the project. See [Grant Programmatic Access to Atlas](https://www.mongodb.com/docs/atlas/configure-api-access/).
3. The project (group) ID: a 24-character hex string, found under **Project Settings**.

### Configuration

```yaml
authentication:
api_public_key: "abcdefgh" # Atlas API public key
api_private_key: "00000000-0000-0000-0000-000000000000" # Atlas API private key
group_id: "5d1b6f8e8c2e4e2d3c4a5b6d" # Atlas project (group) ID
# api_url: "https://cloud.mongodbgov.com" # only for Atlas for Government
```

If your Atlas project restricts API access by IP, add Keep's IP to the API key's access list.

### Webhook configuration

To have Atlas push alerts to Keep:

1. In Atlas, go to your project and click **Integrations**.
2. Choose **Webhook** and click **Configure**.
3. Set the URL to your Keep webhook URL, with your API key as the `api_key` query parameter.
4. In **Alerts** > **Alert Settings**, select **Webhook** as a notification method on the alert configurations you want in Keep.

Notes:

- Atlas webhook requests can't carry custom headers, so authentication uses the `api_key` query parameter rather than the `X-API-KEY` header.
- Atlas payloads carry a status (`OPEN`, `TRACKING`, `CLOSED`) but no severity, so alerts arrive in Keep with `warning` severity. Use Keep mapping rules if you want severities derived from `eventTypeName`.
- Alerts are deduplicated on the Atlas alert `id`, which is stable across an alert's open/close lifecycle.

## Status mapping

| Atlas status | Keep status |
| ------------ | ----------- |
| `OPEN` | `firing` |
| `TRACKING` | `pending` |
| `CLOSED`, `CANCELLED` | `resolved` |
| acknowledged (via `acknowledgedUntil`) | `acknowledged` |

## Useful links

- [Atlas alert basics](https://www.mongodb.com/docs/atlas/alert-basics/)
- [Configure alerts](https://www.mongodb.com/docs/atlas/configure-alerts/)
- [Webhook integration](https://www.mongodb.com/docs/atlas/tutorial/webhook-integration/)
8 changes: 8 additions & 0 deletions docs/providers/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,14 @@ By leveraging Keep Providers, users are able to deeply integrate Keep with the t
}
></Card>

<Card
title="MongoDB Atlas"
href="/providers/documentation/mongodbatlas-provider"
icon={
<img src="https://img.logo.dev/mongodb.com?token=pk_dfXfZBoKQMGDTIgqu7LvYg" />
}
></Card>

<Card
title="MySQL"
href="/providers/documentation/mysql-provider"
Expand Down
35 changes: 35 additions & 0 deletions docs/snippets/providers/mongodbatlas-snippet-autogenerated.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{/* This snippet is automatically generated using scripts/docs_render_provider_snippets.py
Do not edit it manually, as it will be overwritten */}

## Authentication
This provider requires authentication.
- **api_public_key**: Atlas API public key (required: True, sensitive: False)
- **api_private_key**: Atlas API private key (required: True, sensitive: True)
- **group_id**: Atlas project (group) ID (required: True, sensitive: False)
- **api_url**: Atlas API base URL (required: False, sensitive: False)

Certain scopes may be required to perform specific actions or queries via the provider. Below is a summary of relevant scopes and their use cases:
- **Project Read Only**: Read access to the project, required to list alerts (mandatory) ([Documentation](https://www.mongodb.com/docs/atlas/reference/user-roles/#mongodb-authrole-Project-Read-Only))



## In workflows

This provider can't be used as a "step" or "action" in workflows. If you want to use it, please let us know by creating an issue in the [GitHub repository](https://github.com/keephq/keep/issues).



## Connecting via Webhook (omnidirectional)
This provider supports webhooks.


To send alerts from MongoDB Atlas to Keep:

1. In Atlas, go to your project and click Integrations.
2. Choose Webhook and click Configure.
3. Set the URL to KEEP_BACKEND_URL/alerts/event/mongodbatlas?api_key={api_key}
4. Leave the secret empty (Keep authenticates via the api_key query parameter) and save.
5. In Alerts > Alert Settings, add or edit alert configurations and select Webhook as a notification method.

Atlas does not include a severity in webhook payloads, so alerts arrive with warning severity and can be re-mapped in Keep.

Binary file added keep-ui/public/icons/mongodbatlas-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file.
226 changes: 226 additions & 0 deletions keep/providers/mongodbatlas_provider/mongodbatlas_provider.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,226 @@
"""
MongodbatlasProvider is a class that allows to pull alerts from MongoDB Atlas
and to receive Atlas alert webhooks.
"""

import dataclasses
import datetime

import pydantic
import requests
from requests.auth import HTTPDigestAuth

from keep.api.models.alert import AlertDto, AlertSeverity, AlertStatus
from keep.contextmanager.contextmanager import ContextManager
from keep.exceptions.provider_exception import ProviderException
from keep.providers.base.base_provider import BaseProvider
from keep.providers.models.provider_config import ProviderConfig, ProviderScope


@pydantic.dataclasses.dataclass
class MongodbatlasProviderAuthConfig:
"""MongoDB Atlas authentication configuration."""

api_public_key: str = dataclasses.field(
metadata={
"required": True,
"description": "Atlas API public key",
"hint": "Organization or project API key with Project Read Only access",
"documentation_url": "https://www.mongodb.com/docs/atlas/configure-api-access/",
}
)
api_private_key: str = dataclasses.field(
metadata={
"required": True,
"description": "Atlas API private key",
"sensitive": True,
}
)
group_id: str = dataclasses.field(
metadata={
"required": True,
"description": "Atlas project (group) ID",
"hint": "24-character hexadecimal string, found under Project Settings",
}
)
api_url: str = dataclasses.field(
default="https://cloud.mongodb.com",
metadata={
"required": False,
"description": "Atlas API base URL",
"hint": "Change for MongoDB Atlas for Government (https://cloud.mongodbgov.com)",
},
)


class MongodbatlasProvider(BaseProvider):
"""Pull alerts from MongoDB Atlas and receive Atlas alert webhooks."""

PROVIDER_DISPLAY_NAME = "MongoDB Atlas"
PROVIDER_CATEGORY = ["Database", "Monitoring"]
PROVIDER_TAGS = ["alert"]
FINGERPRINT_FIELDS = ["id"]

ATLAS_API_VERSION_HEADER = "application/vnd.atlas.2023-01-01+json"
PAGE_SIZE = 500 # Atlas API maximum for itemsPerPage

PROVIDER_SCOPES = [
ProviderScope(
name="Project Read Only",
description="Read access to the project, required to list alerts",
mandatory=True,
documentation_url="https://www.mongodb.com/docs/atlas/reference/user-roles/#mongodb-authrole-Project-Read-Only",
alias="Project Read Only",
),
]

STATUS_MAP = {
"OPEN": AlertStatus.FIRING,
"TRACKING": AlertStatus.PENDING,
"CLOSED": AlertStatus.RESOLVED,
"CANCELLED": AlertStatus.RESOLVED,
}

webhook_description = ""
webhook_template = ""
webhook_markdown = """
To send alerts from MongoDB Atlas to Keep:

1. In Atlas, go to your project and click Integrations.
2. Choose Webhook and click Configure.
3. Set the URL to {keep_webhook_api_url}?api_key={api_key}
4. Leave the secret empty (Keep authenticates via the api_key query parameter) and save.
5. In Alerts > Alert Settings, add or edit alert configurations and select Webhook as a notification method.

Atlas does not include a severity in webhook payloads, so alerts arrive with warning severity and can be re-mapped in Keep.
"""

def __init__(
self, context_manager: ContextManager, provider_id: str, config: ProviderConfig
):
super().__init__(context_manager, provider_id, config)

def validate_config(self):
self.authentication_config = MongodbatlasProviderAuthConfig(
**self.config.authentication
)

def dispose(self):
pass

@property
def _auth(self) -> HTTPDigestAuth:
return HTTPDigestAuth(
self.authentication_config.api_public_key,
self.authentication_config.api_private_key,
)

def _alerts_url(self) -> str:
base = self.authentication_config.api_url.rstrip("/")
return (
f"{base}/api/atlas/v2/groups/{self.authentication_config.group_id}/alerts"
)

def validate_scopes(self) -> dict[str, bool | str]:
try:
response = requests.get(
self._alerts_url(),
auth=self._auth,
headers={"Accept": self.ATLAS_API_VERSION_HEADER},
params={"itemsPerPage": 1},
timeout=10,
)
response.raise_for_status()
return {"Project Read Only": True}
except requests.exceptions.HTTPError as e:
if e.response.status_code in (401, 403):
return {
"Project Read Only": "Authentication failed, check the API key pair and that it has Project Read Only access"
}
return {"Project Read Only": str(e)}
except requests.exceptions.RequestException as e:
return {"Project Read Only": str(e)}

def _get_alerts(self) -> list[AlertDto]:
alerts = []
page_num = 1
while True:
try:
response = requests.get(
self._alerts_url(),
auth=self._auth,
headers={"Accept": self.ATLAS_API_VERSION_HEADER},
params={"itemsPerPage": self.PAGE_SIZE, "pageNum": page_num},
timeout=30,
)
response.raise_for_status()
except requests.exceptions.RequestException as e:
raise ProviderException(
f"Failed to get alerts from MongoDB Atlas: {e}"
) from e
data = response.json()
results = data.get("results", [])
alerts.extend(self._format_alert(alert) for alert in results)
if not results or page_num * self.PAGE_SIZE >= data.get("totalCount", 0):
break
page_num += 1
return alerts

@staticmethod
def _format_alert(
event: dict, provider_instance: "BaseProvider" = None
) -> AlertDto:
# Webhook payloads use the same schema as the Admin API alert resource,
# so this formatter serves both the pull and push paths. Atlas does not
# include a severity, only a status.
status = MongodbatlasProvider.STATUS_MAP.get(
event.get("status"), AlertStatus.FIRING
)
if event.get("acknowledgedUntil") and status == AlertStatus.FIRING:
status = AlertStatus.ACKNOWLEDGED
current_value = event.get("currentValue") or {}
return AlertDto(
id=event.get("id"),
name=event.get("eventTypeName", "MongoDB Atlas alert"),
status=status,
severity=AlertSeverity.WARNING,
lastReceived=event.get("updated")
or event.get("created")
or datetime.datetime.now(tz=datetime.timezone.utc).isoformat(),
description=event.get("humanReadable"),
source=["mongodbatlas"],
cluster=event.get("clusterName"),
replicaSet=event.get("replicaSetName"),
host=event.get("hostnameAndPort"),
metric=event.get("metricName"),
currentValue=current_value.get("number"),
currentValueUnits=current_value.get("units"),
groupId=event.get("groupId"),
alertConfigId=event.get("alertConfigId"),
)


if __name__ == "__main__":
import logging
import os

logging.basicConfig(level=logging.DEBUG, handlers=[logging.StreamHandler()])
context_manager = ContextManager(
tenant_id="singletenant",
workflow_id="test",
)
config = ProviderConfig(
authentication={
"api_public_key": os.environ.get("ATLAS_API_PUBLIC_KEY"),
"api_private_key": os.environ.get("ATLAS_API_PRIVATE_KEY"),
"group_id": os.environ.get("ATLAS_GROUP_ID"),
}
)
provider = MongodbatlasProvider(
context_manager=context_manager,
provider_id="mongodbatlas",
config=config,
)
print(provider.validate_scopes())
alerts = provider.get_alerts()
print(f"Got {len(alerts)} alerts")
Loading