mirror of
https://github.com/zulip/zulip.git
synced 2025-11-04 22:13:26 +00:00
Add a webhook to create messages from Splunk search alerts. The search alert JSON includes the first search result and a link to view the full results. The following fields are used: * search_name - the name of the saved search * results_link - URL of the full search results * host - the host the search result came from * source - the source file on that host * _raw - the raw text of the logged event. The Zulip message contains: * search name * host * source * raw The destination stream and message topic are configurable: the default stream is "splunk" and the default topic "Splunk Alert". If the topic is not provided in the URL, the search name is used instead (truncated if too long. If a needed field is missing, a default value is used instead. Example: "Missing source" It is possible to configure a Splunk search to not include some values, so I've provided defaults rather than return an error for missing data. In practice, these fields are unlikely to be deliberately suppressed. Note: alerts are only available for Splunk servers using a valid trial, developer, or paid license. I've added tests for the normal case of one search result, the topic from the search name, and for a search missing one of the fields used. Tested using Splunk Enterprise 6.5.1. Fixes #3477
45 lines
2.0 KiB
Python
45 lines
2.0 KiB
Python
# Webhooks for external integrations.
|
|
from __future__ import absolute_import
|
|
from django.utils.translation import ugettext as _
|
|
from zerver.lib.actions import check_send_message
|
|
from zerver.lib.response import json_success, json_error
|
|
from zerver.decorator import REQ, has_request_variables, api_key_only_webhook_view
|
|
from zerver.lib.validator import check_dict, check_string
|
|
from zerver.models import Client, UserProfile, MAX_SUBJECT_LENGTH
|
|
|
|
from django.http import HttpRequest, HttpResponse
|
|
from typing import Dict, Any, Iterable, Optional, Text
|
|
|
|
@api_key_only_webhook_view('Splunk')
|
|
@has_request_variables
|
|
def api_splunk_webhook(request, user_profile, client,
|
|
payload=REQ(argument_type='body'), stream=REQ(default='splunk'),
|
|
topic=REQ(default=None)):
|
|
# type: (HttpRequest, UserProfile, Client, Dict[str, Any], Text, Optional[Text]) -> HttpResponse
|
|
|
|
# use default values if expected data is not provided
|
|
search_name = payload.get('search_name', 'Missing search_name')
|
|
results_link = payload.get('results_link', 'Missing results_link')
|
|
host = payload.get('result', {}).get('host', 'Missing host')
|
|
source = payload.get('result', {}).get('source', 'Missing source')
|
|
raw = payload.get('result', {}).get('_raw', 'Missing _raw')
|
|
|
|
# if no topic provided, use search name but truncate if too long
|
|
if topic is None:
|
|
if len(search_name) >= MAX_SUBJECT_LENGTH:
|
|
topic = "{}...".format(search_name[:(MAX_SUBJECT_LENGTH - 3)])
|
|
else:
|
|
topic = search_name
|
|
|
|
# construct the message body
|
|
body = "Splunk alert from saved search"
|
|
body_template = ('\n[{search}]({link})\nhost: {host}'
|
|
'\nsource: {source}\n\nraw: {raw}')
|
|
body += body_template.format(search = search_name, link = results_link,
|
|
host = host, source = source, raw = raw)
|
|
|
|
# send the message
|
|
check_send_message(user_profile, client, 'stream', [stream], topic, body)
|
|
|
|
return json_success()
|