mirror of
https://github.com/zulip/zulip.git
synced 2025-11-03 05:23:35 +00:00
integrations: Add OpenSearch incoming webhook integration.
Co-authored-by: merlinz01 <158784988+merlinz01@users.noreply.github.com>
This commit is contained in:
0
zerver/webhooks/opensearch/__init__.py
Normal file
0
zerver/webhooks/opensearch/__init__.py
Normal file
82
zerver/webhooks/opensearch/doc.md
Normal file
82
zerver/webhooks/opensearch/doc.md
Normal file
@@ -0,0 +1,82 @@
|
||||
# Zulip OpenSearch integration
|
||||
|
||||
Get OpenSearch alerts in Zulip!
|
||||
|
||||
### Create Zulip bot for OpenSearch notifications
|
||||
|
||||
{start_tabs}
|
||||
|
||||
1. {!create-an-incoming-webhook.md!}
|
||||
|
||||
1. {!generate-webhook-url-basic.md!}
|
||||
|
||||
{end_tabs}
|
||||
|
||||
### Create an OpenSearch notification channel
|
||||
|
||||
{start_tabs}
|
||||
|
||||
1. From the OpenSearch Menu, select **Notifications** from the
|
||||
**Management** section, and click **Create channel**.
|
||||
|
||||
1. Fill in the name and description. For **Channel type**, select
|
||||
**Custom webhook**. Set the **Method** to **POST**, and the **Define
|
||||
endpoints by** to **Webhook URL**. Paste the URL generated above into the
|
||||
**Webhook URL** field.
|
||||
|
||||
1. Click **Send test message**. A test message should appear in Zulip. Click
|
||||
**Create** to save the notification channel.
|
||||
|
||||
{end_tabs}
|
||||
|
||||
### Create an OpenSearch alert monitor
|
||||
|
||||
{start_tabs}
|
||||
|
||||
1. To use the notification channel created above in an alerting action,
|
||||
create an alert monitor. From the OpenSearch menu, select
|
||||
**Alerting** from the **OpenSearch Plugins** section, and click
|
||||
**Create monitor**.
|
||||
|
||||
1. [Configure the alert monitor][alert-monitor] by entering the
|
||||
monitor details, selecting the index to monitor, and adding a
|
||||
[trigger][trigger]. In the **Actions** section, select the notification
|
||||
channel created above as the **Notification** action.
|
||||
|
||||
1. OpenSearch sends notifications as plain text, so you will want to use a
|
||||
**Message template** to format your messages in Zulip. To generate the
|
||||
topic of your Zulip messages via the notification content, you can use
|
||||
the first line of your template to do so. It must be formatted as
|
||||
**topic: DYNAMIC_TOPIC_CONTENT**, and all message content should start on
|
||||
the second line of the template. For example, this template was used to
|
||||
generate the example screenshot below:
|
||||
|
||||
```
|
||||
{% raw %}
|
||||
topic: {{ctx.monitor.name}}
|
||||
Alert of severity **{{ctx.trigger.severity}}** triggered by **{{ctx.trigger.name}}** at {{ctx.periodStart}} UTC.
|
||||
{% endraw %}
|
||||
```
|
||||
|
||||
!!! tip ""
|
||||
|
||||
The **Message template** supports Markdown and Mustache template
|
||||
variables.
|
||||
|
||||
1. Click **Send test message** to test the integration, and click **Create**
|
||||
to save the monitor.
|
||||
|
||||
{end_tabs}
|
||||
|
||||
{!congrats.md!}
|
||||
|
||||

|
||||
|
||||
### Related documentation
|
||||
|
||||
{!webhooks-url-specification.md!}
|
||||
|
||||
* [OpenSearch alert monitor][alert-monitor]
|
||||
|
||||
[alert-monitor]: https://opensearch.org/docs/latest/observing-your-data/alerting/index/#creating-an-alert-monitor
|
||||
[trigger]: https://opensearch.org/docs/latest/observing-your-data/alerting/triggers/
|
||||
5
zerver/webhooks/opensearch/fixtures/default_template.txt
Normal file
5
zerver/webhooks/opensearch/fixtures/default_template.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
Monitor Storage size monitor just entered alert status. Please investigate the issue.
|
||||
- Trigger: Storage size over 1TB
|
||||
- Severity: 1
|
||||
- Period start: 2025-02-25T00:58:39.607Z UTC
|
||||
- Period end: 2025-02-25T00:59:39.607Z UTC
|
||||
2
zerver/webhooks/opensearch/fixtures/example_template.txt
Normal file
2
zerver/webhooks/opensearch/fixtures/example_template.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
topic: Resource Monitor
|
||||
Alert of severity **3** triggered by **Insufficient memory** at 2025-03-04T15:52:59.372Z UTC.
|
||||
@@ -0,0 +1 @@
|
||||
Test message content body for config id Uz5bK5UBeE4fYdADfbg0
|
||||
39
zerver/webhooks/opensearch/tests.py
Normal file
39
zerver/webhooks/opensearch/tests.py
Normal file
@@ -0,0 +1,39 @@
|
||||
from typing_extensions import override
|
||||
|
||||
from zerver.lib.test_classes import WebhookTestCase
|
||||
|
||||
|
||||
class OpensearchHookTests(WebhookTestCase):
|
||||
CHANNEL_NAME = "Opensearch Alerts"
|
||||
TOPIC_NAME = "OpenSearch alerts"
|
||||
URL_TEMPLATE = "/api/v1/external/opensearch?stream={stream}&api_key={api_key}"
|
||||
WEBHOOK_DIR_NAME = "opensearch"
|
||||
|
||||
@override
|
||||
def setUp(self) -> None:
|
||||
super().setUp()
|
||||
self.url = self.build_webhook_url()
|
||||
|
||||
@override
|
||||
def get_body(self, fixture_name: str) -> str:
|
||||
body = self.webhook_fixture_data(self.WEBHOOK_DIR_NAME, fixture_name, file_type="txt")
|
||||
return body
|
||||
|
||||
def test_test_notification_from_channel(self) -> None:
|
||||
message = "Test message content body for config id Uz5bK5UBeE4fYdADfbg0"
|
||||
self.check_webhook("test_notification", self.TOPIC_NAME, message, content_type="text/plain")
|
||||
|
||||
def test_test_notification_from_monitor_action(self) -> None:
|
||||
message = (
|
||||
"Monitor Storage size monitor just entered alert status. Please investigate the issue.\n"
|
||||
"- Trigger: Storage size over 1TB\n"
|
||||
"- Severity: 1\n"
|
||||
"- Period start: 2025-02-25T00:58:39.607Z UTC\n"
|
||||
"- Period end: 2025-02-25T00:59:39.607Z UTC"
|
||||
)
|
||||
self.check_webhook("default_template", self.TOPIC_NAME, message, content_type="text/plain")
|
||||
|
||||
def test_example_template_notification(self) -> None:
|
||||
message = "Alert of severity **3** triggered by **Insufficient memory** at 2025-03-04T15:52:59.372Z UTC."
|
||||
expected_topic = "Resource Monitor"
|
||||
self.check_webhook("example_template", expected_topic, message, content_type="text/plain")
|
||||
33
zerver/webhooks/opensearch/view.py
Normal file
33
zerver/webhooks/opensearch/view.py
Normal file
@@ -0,0 +1,33 @@
|
||||
from typing import Annotated
|
||||
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
|
||||
from zerver.decorator import webhook_view
|
||||
from zerver.lib.response import json_success
|
||||
from zerver.lib.typed_endpoint import ApiParamConfig, typed_endpoint
|
||||
from zerver.lib.webhooks.common import check_send_webhook_message
|
||||
from zerver.models import UserProfile
|
||||
|
||||
|
||||
@webhook_view("OpenSearch")
|
||||
@typed_endpoint
|
||||
def api_opensearch_webhook(
|
||||
request: HttpRequest,
|
||||
user_profile: UserProfile,
|
||||
*,
|
||||
payload: Annotated[str, ApiParamConfig(argument_type_is_body=True)],
|
||||
) -> HttpResponse:
|
||||
"""
|
||||
OpenSearch only sends text/plain payloads, even when the Content-Type is
|
||||
set to other formats.
|
||||
Supports passing in the topic as the first line of the payload, with the
|
||||
topic prefixed by "topic:".
|
||||
"""
|
||||
end_of_line = payload.find("\n")
|
||||
if payload.startswith("topic:") and end_of_line != -1:
|
||||
topic = payload[6:end_of_line].strip()
|
||||
message = payload[end_of_line + 1 :]
|
||||
check_send_webhook_message(request, user_profile, topic, message)
|
||||
else:
|
||||
check_send_webhook_message(request, user_profile, "OpenSearch alerts", payload)
|
||||
return json_success(request)
|
||||
Reference in New Issue
Block a user