-
Notifications
You must be signed in to change notification settings - Fork 792
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
318 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
--- | ||
title: "ILert" | ||
sidebarTitle: "ILert Provider" | ||
description: "ILert provider allows you to create, update, and resolve incidents in ILert for effective incident management and response." | ||
--- | ||
|
||
## Inputs | ||
|
||
- `summary`: str: A brief summary of the incident or situation you're reporting. | ||
- `status`: IlertIncidentStatus = IlertIncidentStatus.INVESTIGATING: The current status of the incident (e.g., INVESTIGATING, RESOLVED, MONITORING, IDENTIFIED). | ||
- `message`: str = "": A detailed message describing the incident or situation. | ||
- `affectedServices`: str = "[]": A JSON string representing the list of affected services and their statuses. | ||
- `id`: str = "0": The ID of the incident to update. If set to "0", a new incident will be created. | ||
|
||
## Outputs | ||
|
||
_No information yet, feel free to contribute it using the "Edit this page" link at the bottom of the page_ | ||
|
||
## Authentication Parameters | ||
|
||
The `ilert_token` is required for connecting to the ILert provider. This should be a valid API token provided by ILert. | ||
|
||
## Connecting with the Provider | ||
|
||
### API Token | ||
|
||
To obtain the ILert API token, follow these steps: | ||
|
||
1. Log in to your ILert account. | ||
2. Navigate to the "API Tokens" section under your user profile or account settings. | ||
3. Generate a new API token. | ||
4. Make sure "Read Permission" and "Write Permission" are checked. | ||
5. Click on "Save" | ||
|
||
Ensure you have the necessary permissions assigned to the token for creating and updating incidents. | ||
|
||
## Scopes | ||
|
||
ILert integration does not require specific scopes to be set for API token as permissions are managed directly within ILert's platform. | ||
|
||
## Notes | ||
|
||
_No information yet, feel free to contribute it using the "Edit this page" link at the bottom of the page_ | ||
|
||
## Useful Links | ||
|
||
- [ILert API Documentation](https://api.ilert.com/api-docs/) | ||
- [ILert Incident Management](https://www.ilert.com/incident-management/) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
id: aad72d69-92b9-4e21-8f67-97d2a69bf8ac | ||
description: Create ILert incident upon Keep Alert | ||
triggers: | ||
- filters: | ||
- key: source | ||
value: keep | ||
type: alert | ||
owners: [] | ||
services: [] | ||
steps: [] | ||
actions: | ||
- name: ilert-action | ||
provider: | ||
config: '{{ providers.ilert-default }}' | ||
type: ilert | ||
with: | ||
affectedServices: | ||
- impact: OPERATIONAL | ||
service: | ||
id: 339743 | ||
message: A mock incident created with Keep! | ||
status: INVESTIGATING | ||
summary: Keep Incident {{ alert.name }} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,246 @@ | ||
""" | ||
Ilert Provider is a class that allows to create/close incidents in Ilert. | ||
""" | ||
import dataclasses | ||
import enum | ||
import json | ||
import os | ||
|
||
import pydantic | ||
import requests | ||
|
||
from keep.contextmanager.contextmanager import ContextManager | ||
from keep.providers.base.base_provider import BaseProvider | ||
from keep.providers.models.provider_config import ProviderConfig, ProviderScope | ||
from keep.providers.providers_factory import ProvidersFactory | ||
|
||
|
||
class IlertIncidentStatus(str, enum.Enum): | ||
""" | ||
Ilert incident status. | ||
""" | ||
|
||
INVESTIGATING = "INVESTIGATING" | ||
RESOLVED = "RESOLVED" | ||
MONITORING = "MONITORING" | ||
IDENTIFIED = "IDENTIFIED" | ||
|
||
|
||
class IlertServiceStatus(str, enum.Enum): | ||
""" | ||
Ilert service status. | ||
""" | ||
|
||
OPERATIONAL = "OPERATIONAL" | ||
DEGRADED = "DEGRADED" | ||
PARTIAL_OUTAGE = "PARTIAL_OUTAGE" | ||
MAJOR_OUTAGE = "MAJOR_OUTAGE" | ||
UNDER_MAINTENANCE = "UNDER_MAINTENANCE" | ||
|
||
|
||
class IlertServiceNoIncludes(pydantic.BaseModel): | ||
""" | ||
Ilert service. | ||
""" | ||
|
||
id: str | ||
|
||
|
||
class IlertAffectedService(pydantic.BaseModel): | ||
""" | ||
Ilert affected service. | ||
""" | ||
|
||
service: IlertServiceNoIncludes | ||
impact: IlertServiceStatus | ||
|
||
|
||
@pydantic.dataclasses.dataclass | ||
class IlertProviderAuthConfig: | ||
""" | ||
Ilert authentication configuration. | ||
""" | ||
|
||
ilert_token: str = dataclasses.field( | ||
metadata={ | ||
"required": True, | ||
"description": "ILert API token", | ||
"hint": "Bearer eyJhbGc...", | ||
"sensitive": True, | ||
} | ||
) | ||
ilert_host: str = dataclasses.field( | ||
metadata={ | ||
"required": False, | ||
"description": "ILert API host", | ||
"hint": "https://api.ilert.com/api", | ||
}, | ||
default="https://api.ilert.com/api", | ||
) | ||
|
||
|
||
class IlertProvider(BaseProvider): | ||
"""Create/Resolve incidents in Ilert.""" | ||
|
||
PROVIDER_SCOPES = [ | ||
ProviderScope("read_permission", "Read permission", mandatory=True), | ||
ProviderScope("write_permission", "Write permission", mandatory=False), | ||
] | ||
|
||
def __init__( | ||
self, context_manager: ContextManager, provider_id: str, config: ProviderConfig | ||
): | ||
super().__init__(context_manager, provider_id, config) | ||
|
||
def dispose(self): | ||
""" | ||
Dispose the provider. | ||
""" | ||
pass | ||
|
||
def validate_config(self): | ||
""" | ||
Validates required configuration for Ilert provider. | ||
""" | ||
self.authentication_config = IlertProviderAuthConfig( | ||
**self.config.authentication | ||
) | ||
|
||
def validate_scopes(self): | ||
scopes = {} | ||
self.logger.info("Validating scopes") | ||
for scope in self.PROVIDER_SCOPES: | ||
try: | ||
if scope.name == "read_permission": | ||
requests.get( | ||
f"{self.authentication_config.ilert_host}/incidents", | ||
headers={ | ||
"Authorization": self.authentication_config.ilert_token | ||
}, | ||
) | ||
scopes[scope.name] = True | ||
elif scope.name == "write_permission": | ||
# TODO: find a way to validate write_permissions, for now it is always "validated" sucessfully. | ||
scopes[scope.name] = True | ||
except Exception as e: | ||
self.logger.warning( | ||
"Failed to validate scope", | ||
extra={"scope": scope.name}, | ||
) | ||
scopes[scope.name] = str(e) | ||
self.logger.info("Scopes validated", extra=scopes) | ||
return scopes | ||
|
||
def _notify( | ||
self, | ||
summary: str, | ||
status: IlertIncidentStatus = IlertIncidentStatus.INVESTIGATING, | ||
message: str = "", | ||
affectedServices: str | list = "[]", | ||
id: str = "0", | ||
**kwargs: dict, | ||
): | ||
self.logger.info( | ||
"Creating/updating Ilert incident", | ||
extra={ | ||
"summary": summary, | ||
"status": status, | ||
"incident_message": message, | ||
"affectedServices": affectedServices, | ||
"id": id, | ||
}, | ||
) | ||
headers = {"Authorization": self.authentication_config.ilert_token} | ||
|
||
# Create or update incident | ||
payload = { | ||
"id": id, | ||
"summary": summary, | ||
"status": str(status), | ||
"message": message, | ||
**kwargs, | ||
} | ||
if affectedServices: | ||
try: | ||
payload["affectedServices"] = ( | ||
json.loads(affectedServices) | ||
if isinstance(affectedServices, str) | ||
else affectedServices | ||
) | ||
except Exception: | ||
self.logger.warning( | ||
"Failed to parse affectedServices", | ||
extra={"affectedServices": affectedServices}, | ||
) | ||
|
||
# if id is set, we update the incident, otherwise we create a new one | ||
should_update = id and id != "0" | ||
if not should_update: | ||
response = requests.post( | ||
f"{self.authentication_config.ilert_host}/incidents", | ||
headers=headers, | ||
json=payload, | ||
) | ||
else: | ||
response = requests.put( | ||
f"{self.authentication_config.ilert_host}/incidents/{id}", | ||
headers=headers, | ||
json=payload, | ||
) | ||
|
||
if not response.ok: | ||
self.logger.error( | ||
"Failed to create/update Ilert incident", | ||
extra={ | ||
"status_code": response.status_code, | ||
"response": response.text, | ||
}, | ||
) | ||
raise Exception( | ||
f"Failed to create/update Ilert incident: {response.status_code} {response.text}" | ||
) | ||
self.logger.info( | ||
"Ilert incident created/updated", | ||
extra={"status_code": response.status_code}, | ||
) | ||
|
||
|
||
if __name__ == "__main__": | ||
# Output debug messages | ||
import logging | ||
|
||
logging.basicConfig(level=logging.DEBUG, handlers=[logging.StreamHandler()]) | ||
context_manager = ContextManager( | ||
tenant_id="singletenant", | ||
workflow_id="test", | ||
) | ||
# Load environment variables | ||
import os | ||
|
||
api_key = os.environ.get("ILERT_API_TOKEN") | ||
|
||
provider_config = { | ||
"authentication": {"ilert_token": api_key}, | ||
} | ||
provider: IlertProvider = ProvidersFactory.get_provider( | ||
context_manager=context_manager, | ||
provider_id="ilert", | ||
provider_type="ilert", | ||
provider_config=provider_config, | ||
) | ||
result = provider._query( | ||
"Example", | ||
message="Lorem Ipsum", | ||
status="MONITORING", | ||
affectedServices=json.dumps( | ||
[ | ||
{ | ||
"impact": "OPERATIONAL", | ||
"service": {"id": 339743}, | ||
} | ||
] | ||
), | ||
id="242530", | ||
) | ||
print(result) |
b8f0a18
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
keep – ./
keep-eight.vercel.app
keep-keephq.vercel.app
keep-git-main-keephq.vercel.app
platform.keephq.dev