mirror of
https://github.com/zulip/zulip.git
synced 2025-10-23 04:52:12 +00:00
integrations: Add OpenSearch incoming webhook integration.
Co-authored-by: merlinz01 <158784988+merlinz01@users.noreply.github.com>
This commit is contained in:
BIN
static/images/integrations/bot_avatars/opensearch.png
Normal file
BIN
static/images/integrations/bot_avatars/opensearch.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.6 KiB |
5
static/images/integrations/logos/opensearch.svg
Normal file
5
static/images/integrations/logos/opensearch.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M61.7374 23.5C60.4878 23.5 59.4748 24.513 59.4748 25.7626C59.4748 44.3813 44.3813 59.4748 25.7626 59.4748C24.513 59.4748 23.5 60.4878 23.5 61.7374C23.5 62.987 24.513 64 25.7626 64C46.8805 64 64 46.8805 64 25.7626C64 24.513 62.987 23.5 61.7374 23.5Z" fill="#005EB8"/>
|
||||
<path d="M48.0814 38C50.2572 34.4505 52.3615 29.7178 51.9475 23.0921C51.0899 9.36725 38.6589 -1.04463 26.9206 0.0837327C22.3253 0.525465 17.6068 4.2712 18.026 10.9805C18.2082 13.8961 19.6352 15.6169 21.9544 16.9399C24.1618 18.1992 26.9978 18.9969 30.2128 19.9011C34.0962 20.9934 38.6009 22.2203 42.063 24.7717C46.2125 27.8295 49.0491 31.3743 48.0814 38Z" fill="#003B5C"/>
|
||||
<path d="M3.91861 14C1.74276 17.5495 -0.361506 22.2822 0.0524931 28.9079C0.910072 42.6327 13.3411 53.0446 25.0794 51.9163C29.6747 51.4745 34.3932 47.7288 33.974 41.0195C33.7918 38.1039 32.3647 36.3831 30.0456 35.0601C27.8382 33.8008 25.0022 33.0031 21.7872 32.0989C17.9038 31.0066 13.3991 29.7797 9.93694 27.2283C5.78746 24.1704 2.95092 20.6257 3.91861 14Z" fill="#005EB8"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
BIN
static/images/integrations/opensearch/001.png
Normal file
BIN
static/images/integrations/opensearch/001.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 43 KiB |
@@ -528,6 +528,7 @@ WEBHOOK_INTEGRATIONS: list[WebhookIntegration] = [
|
||||
WebhookIntegration("netlify", ["continuous-integration", "deployment"]),
|
||||
WebhookIntegration("newrelic", ["monitoring"], display_name="New Relic"),
|
||||
WebhookIntegration("opencollective", ["financial"], display_name="Open Collective"),
|
||||
WebhookIntegration("opensearch", ["monitoring"], display_name="OpenSearch"),
|
||||
WebhookIntegration("opsgenie", ["meta-integration", "monitoring"]),
|
||||
WebhookIntegration("pagerduty", ["monitoring"], display_name="PagerDuty"),
|
||||
WebhookIntegration("papertrail", ["monitoring"]),
|
||||
@@ -773,6 +774,7 @@ DOC_SCREENSHOT_CONFIG: dict[str, list[BaseScreenshotConfig]] = {
|
||||
"netlify": [ScreenshotConfig("deploy_building.json")],
|
||||
"newrelic": [ScreenshotConfig("incident_activated_new_default_payload.json")],
|
||||
"opencollective": [ScreenshotConfig("one_time_donation.json")],
|
||||
"opensearch": [ScreenshotConfig("example_template.txt")],
|
||||
"opsgenie": [ScreenshotConfig("addrecipient.json")],
|
||||
"pagerduty": [ScreenshotConfig("trigger_v2.json")],
|
||||
"papertrail": [ScreenshotConfig("short_post.json", payload_as_query_param=True)],
|
||||
|
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