Skip to content

Commit c55e40a

Browse files
committed
add Nagios provider via webhook notifications
1 parent 10dded9 commit c55e40a

4 files changed

Lines changed: 267 additions & 0 deletions

File tree

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
---
2+
title: "Nagios Provider"
3+
sidebarTitle: "Nagios"
4+
description: "Nagios provider allows you to receive host and service alerts from Nagios in Keep."
5+
---
6+
7+
import AutoGeneratedSnippet from '/snippets/providers/nagios-snippet-autogenerated.mdx';
8+
9+
<AutoGeneratedSnippet />
10+
11+
# Nagios Provider
12+
13+
The Nagios provider allows you to forward host and service notifications from
14+
Nagios into Keep using a webhook-based integration.
15+
16+
This provider is intentionally lightweight and focuses on the most common
17+
integration path for Nagios Core: custom notification commands that POST a JSON
18+
payload to Keep.
19+
20+
## Overview
21+
22+
The provider supports:
23+
24+
- Host notifications
25+
- Service notifications
26+
- Problem and recovery flows through `notification_type`
27+
- State/severity normalization into Keep alerts
28+
29+
## Webhook Configuration
30+
31+
To configure Nagios to send alerts to Keep:
32+
33+
1. Create a custom notification command that sends an HTTP POST request.
34+
2. Set the target URL to your Keep webhook endpoint:
35+
36+
```text
37+
{keep_webhook_api_url}
38+
```
39+
40+
3. Add an `X-API-KEY` header using a Keep API key with webhook permissions.
41+
4. Build the request body from standard Nagios macros.
42+
43+
Example payload for a **service** notification:
44+
45+
```json
46+
{
47+
"alert_type": "service",
48+
"notification_type": "$NOTIFICATIONTYPE$",
49+
"timestamp": "$LONGDATETIME$",
50+
"host_name": "$HOSTNAME$",
51+
"host_display_name": "$HOSTDISPLAYNAME$",
52+
"host_address": "$HOSTADDRESS$",
53+
"service_name": "$SERVICEDESC$",
54+
"service_display_name": "$SERVICEDESC$",
55+
"service_state": "$SERVICESTATE$",
56+
"service_state_type": "$SERVICESTATETYPE$",
57+
"service_attempt": "$SERVICEATTEMPT$",
58+
"service_output": "$SERVICEOUTPUT$",
59+
"service_perfdata": "$SERVICEPERFDATA$",
60+
"service_check_command": "$SERVICECHECKCOMMAND$"
61+
}
62+
```
63+
64+
Example payload for a **host** notification:
65+
66+
```json
67+
{
68+
"alert_type": "host",
69+
"notification_type": "$NOTIFICATIONTYPE$",
70+
"timestamp": "$LONGDATETIME$",
71+
"host_name": "$HOSTNAME$",
72+
"host_display_name": "$HOSTDISPLAYNAME$",
73+
"host_address": "$HOSTADDRESS$",
74+
"host_state": "$HOSTSTATE$",
75+
"host_output": "$HOSTOUTPUT$"
76+
}
77+
```
78+
79+
## Suggested Command Example
80+
81+
One practical approach is to use `curl` from a custom Nagios notification
82+
command:
83+
84+
```bash
85+
/usr/bin/curl -X POST \
86+
-H "Content-Type: application/json" \
87+
-H "X-API-KEY: <KEEP_API_KEY>" \
88+
-d '<JSON_PAYLOAD_FROM_MACROS>' \
89+
'<KEEP_WEBHOOK_URL>'
90+
```
91+
92+
You can then attach that command to `host_notification_commands` and
93+
`service_notification_commands` in your Nagios object definitions.
94+
95+
## State Mapping
96+
97+
### Host States
98+
99+
| Nagios State | Keep Status | Keep Severity |
100+
|:-------------|:------------|:--------------|
101+
| UP | RESOLVED | INFO |
102+
| DOWN | FIRING | CRITICAL |
103+
| UNREACHABLE | FIRING | CRITICAL |
104+
105+
### Service States
106+
107+
| Nagios State | Keep Status | Keep Severity |
108+
|:-------------|:------------|:--------------|
109+
| OK | RESOLVED | INFO |
110+
| WARNING | FIRING | WARNING |
111+
| CRITICAL | FIRING | CRITICAL |
112+
| UNKNOWN | FIRING | INFO |
113+
114+
## Useful Links
115+
116+
- [Nagios Standard Macros](https://assets.nagios.com/downloads/nagioscore/docs/nagioscore/4/en/macrolist.html)
117+
- [Nagios Notifications](https://assets.nagios.com/downloads/nagioscore/docs/nagioscore/4/en/notifications.html)
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{/* This snippet is automatically generated using scripts/docs_render_provider_snippets.py
2+
Do not edit it manually, as it will be overwritten */}
3+
4+
5+
## In workflows
6+
7+
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).
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from keep.providers.nagios_provider.nagios_provider import NagiosProvider
2+
3+
__all__ = ["NagiosProvider"]
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
"""
2+
Nagios Provider is a class that provides a way to receive alerts from Nagios
3+
using webhook notifications.
4+
"""
5+
6+
from keep.api.models.alert import AlertDto, AlertSeverity, AlertStatus
7+
from keep.contextmanager.contextmanager import ContextManager
8+
from keep.providers.base.base_provider import BaseProvider
9+
from keep.providers.models.provider_config import ProviderConfig
10+
11+
12+
class NagiosProvider(BaseProvider):
13+
"""
14+
Receive Nagios host and service notifications into Keep via webhooks.
15+
"""
16+
17+
webhook_documentation_here_differs_from_general_documentation = True
18+
webhook_description = ""
19+
webhook_template = ""
20+
webhook_markdown = """
21+
To send alerts from Nagios to Keep, configure a custom notification command:
22+
23+
1. Create a notification command that POSTs JSON to `{keep_webhook_api_url}`.
24+
2. Add header `X-API-KEY` with your Keep API key (webhook role).
25+
3. Use Nagios macros such as `$NOTIFICATIONTYPE$`, `$HOSTNAME$`, `$HOSTSTATE$`,
26+
`$HOSTOUTPUT$`, `$SERVICEDESC$`, `$SERVICESTATE$`, and `$SERVICEOUTPUT$` to
27+
build the JSON payload.
28+
4. Attach the command to your host and/or service notification definitions.
29+
5. For a complete example, see the [Keep documentation](https://docs.keephq.dev/providers/documentation/nagios-provider).
30+
"""
31+
32+
PROVIDER_DISPLAY_NAME = "Nagios"
33+
PROVIDER_TAGS = ["alert"]
34+
PROVIDER_CATEGORY = ["Monitoring"]
35+
WEBHOOK_INSTALLATION_REQUIRED = True
36+
37+
HOST_STATUS_MAP = {
38+
"UP": AlertStatus.RESOLVED,
39+
"DOWN": AlertStatus.FIRING,
40+
"UNREACHABLE": AlertStatus.FIRING,
41+
}
42+
43+
HOST_SEVERITY_MAP = {
44+
"UP": AlertSeverity.INFO,
45+
"DOWN": AlertSeverity.CRITICAL,
46+
"UNREACHABLE": AlertSeverity.CRITICAL,
47+
}
48+
49+
SERVICE_STATUS_MAP = {
50+
"OK": AlertStatus.RESOLVED,
51+
"WARNING": AlertStatus.FIRING,
52+
"CRITICAL": AlertStatus.FIRING,
53+
"UNKNOWN": AlertStatus.FIRING,
54+
}
55+
56+
SERVICE_SEVERITY_MAP = {
57+
"OK": AlertSeverity.INFO,
58+
"WARNING": AlertSeverity.WARNING,
59+
"CRITICAL": AlertSeverity.CRITICAL,
60+
"UNKNOWN": AlertSeverity.INFO,
61+
}
62+
63+
def __init__(
64+
self, context_manager: ContextManager, provider_id: str, config: ProviderConfig
65+
):
66+
super().__init__(context_manager, provider_id, config)
67+
68+
def dispose(self):
69+
"""
70+
Dispose of the provider.
71+
"""
72+
pass
73+
74+
def validate_config(self):
75+
"""
76+
Nagios webhook integration does not require provider-side configuration.
77+
"""
78+
pass
79+
80+
@staticmethod
81+
def _format_alert(
82+
event: dict, provider_instance: "BaseProvider" = None
83+
) -> AlertDto | list[AlertDto]:
84+
"""
85+
Format Nagios notification payload into Keep alert format.
86+
87+
Supported payloads are intentionally simple and map closely to Nagios
88+
host/service notification macros configured in the webhook command.
89+
"""
90+
alert_type = (event.get("alert_type") or "service").lower()
91+
92+
if alert_type == "host":
93+
state = event.get("host_state", "DOWN")
94+
output = event.get("host_output", "No output provided")
95+
return AlertDto(
96+
id=event.get("host_name"),
97+
name=event.get("host_display_name") or event.get("host_name"),
98+
status=NagiosProvider.HOST_STATUS_MAP.get(state, AlertStatus.FIRING),
99+
severity=NagiosProvider.HOST_SEVERITY_MAP.get(
100+
state, AlertSeverity.CRITICAL
101+
),
102+
description=output,
103+
source=["nagios"],
104+
hostname=event.get("host_name"),
105+
state=state,
106+
lastReceived=event.get("timestamp"),
107+
timestamp=event.get("timestamp"),
108+
notification_type=event.get("notification_type"),
109+
raw_output=output,
110+
host_address=event.get("host_address"),
111+
)
112+
113+
state = event.get("service_state", "CRITICAL")
114+
output = event.get("service_output", "No output provided")
115+
return AlertDto(
116+
id=event.get("service_name") or event.get("host_name"),
117+
name=event.get("service_display_name") or event.get("service_name"),
118+
status=NagiosProvider.SERVICE_STATUS_MAP.get(state, AlertStatus.FIRING),
119+
severity=NagiosProvider.SERVICE_SEVERITY_MAP.get(
120+
state, AlertSeverity.CRITICAL
121+
),
122+
description=output,
123+
source=["nagios"],
124+
hostname=event.get("host_name"),
125+
host_address=event.get("host_address"),
126+
service_name=event.get("service_name"),
127+
check_command=event.get("service_check_command"),
128+
state=state,
129+
lastReceived=event.get("timestamp"),
130+
timestamp=event.get("timestamp"),
131+
notification_type=event.get("notification_type"),
132+
raw_output=output,
133+
current_attempt=event.get("service_attempt"),
134+
state_type=event.get("service_state_type"),
135+
performance_data=event.get("service_perfdata"),
136+
)
137+
138+
139+
if __name__ == "__main__":
140+
pass

0 commit comments

Comments
 (0)