Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Opensearch discover link support #1310

Merged
merged 69 commits into from
Nov 18, 2023
Merged
Show file tree
Hide file tree
Changes from 62 commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
7bf5931
Create opensearch_discover.py
luffynextgen Nov 14, 2023
72c6a1f
Update kibana_external_url_formatter.py
luffynextgen Nov 14, 2023
c6143b8
Update elastalert.py
luffynextgen Nov 14, 2023
e2e24d5
Update schema.yaml
luffynextgen Nov 14, 2023
a1e78ff
Update ruletypes.rst
luffynextgen Nov 14, 2023
98c3e40
Update ruletypes.rst
luffynextgen Nov 14, 2023
0435758
Update CHANGELOG.md
luffynextgen Nov 14, 2023
7f5b3ae
Update ruletypes.rst
luffynextgen Nov 14, 2023
8eb3252
Update schema.yaml
luffynextgen Nov 15, 2023
72eef1b
Update opensearch_discover.py
luffynextgen Nov 15, 2023
a21862e
Update elastalert.py
luffynextgen Nov 15, 2023
01a882c
Update loaders.py
luffynextgen Nov 15, 2023
b3209b8
Update slack.py
luffynextgen Nov 15, 2023
94941dc
Update teams.py
luffynextgen Nov 15, 2023
39ea6f0
Update mattermost.py
luffynextgen Nov 15, 2023
b99e173
Update teams.py
luffynextgen Nov 15, 2023
9cd6496
Update rocketchat.py
luffynextgen Nov 15, 2023
5c958b9
Update schema.yaml
luffynextgen Nov 15, 2023
47cc3d1
Create opensearch_discover_test.py
luffynextgen Nov 15, 2023
3896fe3
Update teams_test.py
luffynextgen Nov 15, 2023
a520201
Update mattermost.py
luffynextgen Nov 15, 2023
24488fb
Update mattermost_test.py
luffynextgen Nov 15, 2023
9ffb9ce
Update rocketchat.py
luffynextgen Nov 15, 2023
fb18f37
Update rocketchat_test.py
luffynextgen Nov 15, 2023
a05b8e5
Update slack_test.py
luffynextgen Nov 15, 2023
f91e6ab
Update loaders_test.py
luffynextgen Nov 15, 2023
423bd86
Update ruletypes.rst
luffynextgen Nov 15, 2023
ac135b0
Update ruletypes.rst
luffynextgen Nov 15, 2023
66b1147
Update ruletypes.rst
luffynextgen Nov 15, 2023
e283036
Update ruletypes.rst
luffynextgen Nov 15, 2023
2fd6ac3
Merge pull request #1 from luffynextgen/luffynextgen-patch-3
luffynextgen Nov 15, 2023
99f5035
Update ruletypes.rst
luffynextgen Nov 15, 2023
89bdaa4
Update ruletypes.rst
luffynextgen Nov 15, 2023
9701674
Update loaders.py
luffynextgen Nov 15, 2023
a43ef0a
Update ruletypes.rst
luffynextgen Nov 15, 2023
6317f95
Update opensearch_discover.py
luffynextgen Nov 15, 2023
eb3979d
Update mattermost.py
luffynextgen Nov 15, 2023
6291cc8
Update slack.py
luffynextgen Nov 15, 2023
9b20e4e
Update teams_test.py
luffynextgen Nov 15, 2023
cd0bd32
Merge pull request #2 from luffynextgen/luffynextgen-patch-5
luffynextgen Nov 15, 2023
703b601
Update opensearch_discover_test.py
luffynextgen Nov 16, 2023
f30d45a
Update mattermost_test.py
luffynextgen Nov 16, 2023
93cdc69
Update teams_test.py
luffynextgen Nov 16, 2023
6dfe308
Update slack_test.py
luffynextgen Nov 16, 2023
342650b
Update loaders_test.py
luffynextgen Nov 16, 2023
2f9b66c
Update opensearch_discover_test.py
luffynextgen Nov 16, 2023
74a016a
Update opensearch_discover_test.py
luffynextgen Nov 16, 2023
f1bfbe4
Update slack_test.py
luffynextgen Nov 16, 2023
687f355
Update opensearch_discover_test.py
luffynextgen Nov 16, 2023
47190f3
Merge branch 'jertel:master' into master
luffynextgen Nov 16, 2023
c5fce25
Merge branch 'jertel:master' into master
luffynextgen Nov 17, 2023
f06ef4b
Update elastalert.py
luffynextgen Nov 17, 2023
42762f9
Create opensearch_external_url_formatter.py
luffynextgen Nov 17, 2023
8e07132
Create opensearch_external_url_formatter_test.py
luffynextgen Nov 17, 2023
5f9f553
Update opensearch_discover_test.py
luffynextgen Nov 17, 2023
5c82c89
Update opensearch_discover_test.py
luffynextgen Nov 17, 2023
1fa776c
Update opensearch_discover.py
luffynextgen Nov 17, 2023
4f44d05
Update ruletypes.rst
luffynextgen Nov 17, 2023
c2ad286
Update opensearch_external_url_formatter_test.py
luffynextgen Nov 17, 2023
523f274
Update opensearch_external_url_formatter.py
luffynextgen Nov 17, 2023
367ce02
Update opensearch_external_url_formatter_test.py
luffynextgen Nov 17, 2023
49daa71
Update opensearch_external_url_formatter_test.py
luffynextgen Nov 17, 2023
0a79d85
Update ruletypes.rst
luffynextgen Nov 17, 2023
4cb537d
Update ruletypes.rst
luffynextgen Nov 17, 2023
8b4a381
Update kibana_external_url_formatter.py
luffynextgen Nov 17, 2023
c421445
Update kibana_external_url_formatter.py
luffynextgen Nov 17, 2023
52b5db9
Update ruletypes.rst
luffynextgen Nov 17, 2023
087f0e7
Update elastalert.py
luffynextgen Nov 17, 2023
c53c9c3
Update opensearch_external_url_formatter_test.py
luffynextgen Nov 17, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

## New features
- [Iris] Alerter added - [#1301](https://github.com/jertel/elastalert2/pull/1301) - @malinkinsa

- [Opensearch] Add the possibility to generate an opensearch discovery url - [#1310](https://github.com/jertel/elastalert2/pull/1310)
## Other changes
- Refactored FlatlineRule to make it more extensible - [#1291](https://github.com/jertel/elastalert2/pull/1291) - @rundef
- Add support for Kibana 8.11 for Kibana Discover - [#1305](https://github.com/jertel/elastalert2/pull/1305) - @nsano-rururu
Expand Down
130 changes: 130 additions & 0 deletions docs/source/ruletypes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ Rule Configuration Cheat Sheet
+--------------------------------------------------------------+ |
| ``generate_kibana_discover_url`` (boolean, default False) | |
+--------------------------------------------------------------+ |
| ``generate_opensearch_discover_url`` (boolean, default False)| |
+--------------------------------------------------------------+ |
| ``shorten_kibana_discover_url`` (boolean, default False) | |
+--------------------------------------------------------------+ |
| ``kibana_discover_app_url`` (string, no default) | |
Expand All @@ -86,6 +88,22 @@ Rule Configuration Cheat Sheet
+--------------------------------------------------------------+ |
| ``kibana_discover_to_timedelta`` (time, default: 10 min) | |
+--------------------------------------------------------------+ |
| ``shorten_kibana_discover_url`` (boolean, default False) | |
luffynextgen marked this conversation as resolved.
Show resolved Hide resolved
+--------------------------------------------------------------+ |
| ``opensearch_discover_app_url`` (string, no default) | |
+--------------------------------------------------------------+ |
| ``opensearch_discover_version`` (string, no default) | |
+--------------------------------------------------------------+ |
| ``opensearch_discover_index_pattern_id`` (string, no default)| |
+--------------------------------------------------------------+ |
| ``opensearch_discover_security_tenant`` (string, no default)| |
nsano-rururu marked this conversation as resolved.
Show resolved Hide resolved
+--------------------------------------------------------------+ |
|``opensearch_discover_columns`` (list of strs,default _source)| |
+--------------------------------------------------------------+ |
| ``opensearch_discover_from_timedelta`` (time,default: 10 min)| |
+--------------------------------------------------------------+ |
| ``opensearch_discover_to_timedelta`` (time, default: 10 min) | |
+--------------------------------------------------------------+ |
| ``use_local_time`` (boolean, default True) | |
+--------------------------------------------------------------+ |
| ``realert`` (time, default: 1 min) | |
Expand Down Expand Up @@ -777,6 +795,118 @@ The `to` time is calculated by adding this timedelta to the event time. Default

``kibana_discover_to_timedelta: minutes: 2``

opensearch_url
^^^^^^^^^^^^^^

``opensearch_url``: The base url of the opensearch application. If not specified, a URL will be constructed using ``es_host``
and ``es_port``.

This value will be used if ``generate_opensearch_discover_url`` is true and ``opensearch_discover_app_url`` is a relative path

(Optional, string, default ``http://<opensearch_host>:<opensearch_port>/_plugin/_dashboards/``)

generate_opensearch_discover_url
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

``generate_opensearch_discover_url``: Enables the generation of the ``opensearch_discover_url`` variable for the Opensearch Discover application.
This setting requires the following settings are also configured:

- ``opensearch_discover_app_url``
- ``opensearch_discover_version``
- ``opensearch_discover_index_pattern_id``

``generate_opensearch_discover_url: true``

Example opensearch_discover_app_url only usage for opensearch::

generate_opensearch_discover_url: true
opensearch_discover_app_url: "http://localhost:5601/app/data-explorer/discover?security_tenant=Admin#"
opensearch_discover_index_pattern_id: "4babf380-c3b1-11eb-b616-1b59c2feec54"
opensearch_discover_version: "2.11"
alert_text: '{}'
alert_text_args: [ opensearch_discover_url ]
alert_text_type: alert_text_only

Example opensearch_url + opensearch_discover_app_url usage for opensearch::

generate_opensearch_discover_url: true
opensearch_url: "http://localhost:5601/"
opensearch_discover_app_url: "app/data-explorer/discover?security_tenant=Admin#"
opensearch_discover_index_pattern_id: "4babf380-c3b1-11eb-b616-1b59c2feec54"
opensearch_discover_version: "2.11"
alert_text: '{}'
alert_text_args: [ opensearch_discover_url ]
alert_text_type: alert_text_only

opensearch_discover_app_url
^^^^^^^^^^^^^^^^^^^^^^^^^^^

``opensearch_discover_app_url``: The url of the opensearch Discover application used to generate the ``opensearch_discover_url`` variable.
This value can use `$VAR` and `${VAR}` references to expand environment variables.
This value should be relative to the base opensearch url defined by ``opensearch_url`` and will vary depending on your installation.

``opensearch_discover_app_url: app/discover#/``

(Optional, string, no default)

opensearch_discover_version
^^^^^^^^^^^^^^^^^^^^^^^^^^^

``opensearch_discover_version``: Specifies the version of the opensearch Discover application.

The currently supported versions of opensearch Discover are:

- `2.11`

``opensearch_discover_version: '2.11'``

opensearch_discover_index_pattern_id
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

``opensearch_discover_index_pattern_id``: The id of the index pattern to link to in the opensearch Discover application.
These ids are usually generated and can be found in url of the index pattern management page, or by exporting its saved object.


Example export of an index pattern's saved object:

.. code-block:: text

[
{
"_id": "4e97d188-8a45-4418-8a37-07ed69b4d34c",
"_type": "index-pattern",
"_source": { ... }
}
]

You can modify an index pattern's id by exporting the saved object, modifying the ``_id`` field, and re-importing.

``opensearch_discover_index_pattern_id: 4e97d188-8a45-4418-8a37-07ed69b4d34c``

opensearch_discover_columns
^^^^^^^^^^^^^^^^^^^^^^^^^^^

``opensearch_discover_columns``: The columns to display in the generated opensearch Discover application link.
Defaults to the ``_source`` column.

``opensearch_discover_columns: [ timestamp, message ]``

opensearch_discover_from_timedelta
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

``opensearch_discover_from_timedelta``: The offset to the `from` time of the opensearch Discover link's time range.
The `from` time is calculated by subtracting this timedelta from the event time. Defaults to 10 minutes.

``opensearch_discover_from_timedelta: minutes: 2``

opensearch_discover_to_timedelta
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

``opensearch_discover_to_timedelta``: The offset to the `to` time of the opensearch Discover link's time range.
The `to` time is calculated by adding this timedelta to the event time. Defaults to 10 minutes.

``opensearch_discover_to_timedelta: minutes: 2``

use_local_time
^^^^^^^^^^^^^^

Expand Down
13 changes: 13 additions & 0 deletions elastalert/alerters/mattermost.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ def __init__(self, rule):
self.mattermost_attach_kibana_discover_url = self.rule.get('mattermost_attach_kibana_discover_url', False)
self.mattermost_kibana_discover_color = self.rule.get('mattermost_kibana_discover_color', '#ec4b98')
self.mattermost_kibana_discover_title = self.rule.get('mattermost_kibana_discover_title', 'Discover in Kibana')
self.mattermost_attach_opensearch_discover_url = self.rule.get('mattermost_attach_opensearch_discover_url', False)
self.mattermost_opensearch_discover_color = self.rule.get('mattermost_opensearch_discover_color', '#ec4b98')
self.mattermost_opensearch_discover_title = self.rule.get('mattermost_opensearch_discover_title', 'Discover in opensearch')

def get_aggregation_summary_text__maximum_width(self):
width = super(MattermostAlerter, self).get_aggregation_summary_text__maximum_width()
Expand Down Expand Up @@ -143,7 +146,17 @@ def alert(self, matches):
'title': self.mattermost_kibana_discover_title,
'title_link': kibana_discover_url
})

if self.mattermost_attach_opensearch_discover_url:
opensearch_discover_url = lookup_es_key(matches[0], 'opensearch_discover_url')
if opensearch_discover_url:
payload['attachments'].append({
'color': self.mattermost_opensearch_discover_color,
'title': self.mattermost_opensearch_discover_title,
'title_link': opensearch_discover_url
})


for url in self.mattermost_webhook_url:
for channel_override in self.mattermost_channel_override:
try:
Expand Down
12 changes: 12 additions & 0 deletions elastalert/alerters/rocketchat.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ def __init__(self, rule):
self.rocket_chat_attach_kibana_discover_url = self.rule.get('rocket_chat_attach_kibana_discover_url', False)
self.rocket_chat_kibana_discover_color = self.rule.get('rocket_chat_kibana_discover_color', '#ec4b98')
self.rocket_chat_kibana_discover_title = self.rule.get('rocket_chat_kibana_discover_title', 'Discover in Kibana')
self.rocket_chat_attach_opensearch_discover_url = self.rule.get('rocket_chat_attach_opensearch_discover_url', False)
self.rocket_chat_opensearch_discover_color = self.rule.get('rocket_chat_opensearch_discover_color', '#ec4b98')
self.rocket_chat_opensearch_discover_title = self.rule.get('rocket_chat_opensearch_discover_title', 'Discover in opensearch')
self.rocket_chat_ignore_ssl_errors = self.rule.get('rocket_chat_ignore_ssl_errors', False)
self.rocket_chat_timeout = self.rule.get('rocket_chat_timeout', 10)
self.rocket_chat_ca_certs = self.rule.get('rocket_chat_ca_certs')
Expand Down Expand Up @@ -92,6 +95,15 @@ def alert(self, matches):
'title_link': kibana_discover_url
})

if self.rocket_chat_attach_opensearch_discover_url:
opensearch_discover_url = lookup_es_key(matches[0], 'opensearch_discover_url')
if opensearch_discover_url:
payload['attachments'].append({
'color': self.rocket_chat_opensearch_discover_color,
'title': self.rocket_chat_opensearch_discover_title,
'title_link': opensearch_discover_url
})

for url in self.rocket_chat_webhook_url:
for channel_override in self.rocket_chat_channel_override:
try:
Expand Down
11 changes: 11 additions & 0 deletions elastalert/alerters/slack.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ def __init__(self, rule):
self.slack_attach_kibana_discover_url = self.rule.get('slack_attach_kibana_discover_url', False)
self.slack_kibana_discover_color = self.rule.get('slack_kibana_discover_color', '#ec4b98')
self.slack_kibana_discover_title = self.rule.get('slack_kibana_discover_title', 'Discover in Kibana')
self.slack_attach_opensearch_discover_url = self.rule.get('slack_attach_opensearch_discover_url', False)
self.slack_opensearch_discover_color = self.rule.get('slack_opensearch_discover_color', '#ec4b98')
self.slack_opensearch_discover_title = self.rule.get('slack_opensearch_discover_title', 'Discover in Opensearch')
self.slack_footer = self.rule.get('slack_footer', '')
self.slack_footer_icon = self.rule.get('slack_footer_icon', '')
self.slack_image_url = self.rule.get('slack_image_url', '')
Expand Down Expand Up @@ -141,6 +144,14 @@ def alert(self, matches):
'title': self.slack_kibana_discover_title,
'title_link': kibana_discover_url
})
if self.slack_attach_opensearch_discover_url:
opensearch_discover_url = lookup_es_key(matches[0], 'opensearch_discover_url')
if opensearch_discover_url:
payload['attachments'].append({
'color': self.slack_opensearch_discover_color,
'title': self.slack_opensearch_discover_title,
'title_link': opensearch_discover_url
})

if self.slack_attach_jira_ticket_url and self.pipeline is not None and 'jira_ticket' in self.pipeline:
jira_url = '%s/browse/%s' % (self.pipeline['jira_server'], self.pipeline['jira_ticket'])
Expand Down
17 changes: 17 additions & 0 deletions elastalert/alerters/teams.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ def __init__(self, rule):
self.ms_teams_alert_facts = self.rule.get('ms_teams_alert_facts', '')
self.ms_teams_attach_kibana_discover_url = self.rule.get('ms_teams_attach_kibana_discover_url', False)
self.ms_teams_kibana_discover_title = self.rule.get('ms_teams_kibana_discover_title', 'Discover in Kibana')
self.ms_teams_attach_opensearch_discover_url = self.rule.get('ms_teams_attach_opensearch_discover_url', False)
self.ms_teams_opensearch_discover_title = self.rule.get('ms_teams_opensearch_discover_title', 'Discover in opensearch')

def format_body(self, body):
if self.ms_teams_alert_fixed_width:
Expand Down Expand Up @@ -88,6 +90,21 @@ def alert(self, matches):
],
}
]
if self.ms_teams_attach_opensearch_discover_url:
opensearch_discover_url = lookup_es_key(matches[0], 'opensearch_discover_url')
if opensearch_discover_url:
payload['potentialAction'] = [
{
'@type': 'OpenUri',
'name': self.ms_teams_opensearch_discover_title,
'targets': [
{
'os': 'default',
'uri': opensearch_discover_url,
}
],
}
]

for url in self.ms_teams_webhook_url:
try:
Expand Down
20 changes: 20 additions & 0 deletions elastalert/elastalert.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
from elastalert.enhancements import DropMatchException
from elastalert.kibana_discover import generate_kibana_discover_url
from elastalert.kibana_external_url_formatter import create_kibana_external_url_formatter
from elastalert.opensearch_discover import generate_opensearch_discover_url
from elastalert.opensearch_external_url_formatter import create_opensearch_external_url_formatter
from elastalert.prometheus_wrapper import PrometheusWrapper
from elastalert.ruletypes import FlatlineRule
from elastalert.util import (add_keyword_postfix, cronite_datetime_to_timestamp, dt_to_ts, dt_to_unix, EAException,
Expand Down Expand Up @@ -1347,6 +1349,14 @@ def send_alert(self, matches, rule, alert_time=None, retried=False):
kb_link_formatter = self.get_kibana_discover_external_url_formatter(rule)
matches[0]['kibana_discover_url'] = kb_link_formatter.format(kb_link)

if rule.get('generate_opensearch_discover_url'):
kb_link = generate_opensearch_discover_url(rule, matches[0])
luffynextgen marked this conversation as resolved.
Show resolved Hide resolved
if kb_link:
kb_link_formatter = self.get_opensearch_discover_external_url_formatter(rule)
luffynextgen marked this conversation as resolved.
Show resolved Hide resolved
matches[0]['opensearch_discover_url'] = kb_link_formatter.format(kb_link)



# Enhancements were already run at match time if
# run_enhancements_first is set or
# retried==True, which means this is a retry of a failed alert
Expand Down Expand Up @@ -1439,6 +1449,16 @@ def get_kibana_discover_external_url_formatter(self, rule):
rule[key] = formatter
return formatter


def get_opensearch_discover_external_url_formatter(self, rule):
""" Gets or create the external url formatter for Opensearch discover links """
key = '__opensearch_discover_external_url_formatter__'
formatter = rule.get(key)
if formatter is None:
formatter = create_opensearch_external_url_formatter(rule)
rule[key] = formatter
return formatter

def writeback(self, doc_type, body, rule=None, match_body=None):
# ES 2.0 - 2.3 does not support dots in field names.
if self.replace_dots_in_field_names:
Expand Down
12 changes: 12 additions & 0 deletions elastalert/kibana_external_url_formatter.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,3 +157,15 @@ def create_kibana_external_url_formatter(
return ShortKibanaExternalUrlFormatter(base_url, auth, security_tenant, new_shortener, verify)

return AbsoluteKibanaExternalUrlFormatter(base_url, security_tenant)

def create_opensearch_external_url_formatter(
luffynextgen marked this conversation as resolved.
Show resolved Hide resolved
nsano-rururu marked this conversation as resolved.
Show resolved Hide resolved
rule,
shorten: bool,
security_tenant: str,
) -> KibanaExternalUrlFormatter:
'''Creates a Kibana external url formatter'''
luffynextgen marked this conversation as resolved.
Show resolved Hide resolved

base_url = rule.get('kibana_url')
luffynextgen marked this conversation as resolved.
Show resolved Hide resolved

return AbsoluteKibanaExternalUrlFormatter(base_url, security_tenant)

luffynextgen marked this conversation as resolved.
Show resolved Hide resolved
4 changes: 4 additions & 0 deletions elastalert/loaders.py
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,10 @@ def load_options(self, rule, conf, filename, args=None):
rule['kibana_discover_from_timedelta'] = datetime.timedelta(**rule['kibana_discover_from_timedelta'])
if 'kibana_discover_to_timedelta' in rule:
rule['kibana_discover_to_timedelta'] = datetime.timedelta(**rule['kibana_discover_to_timedelta'])
if 'opensearch_discover_from_timedelta' in rule:
rule['opensearch_discover_from_timedelta'] = datetime.timedelta(**rule['opensearch_discover_from_timedelta'])
if 'opensearch_discover_to_timedelta' in rule:
rule['opensearch_discover_to_timedelta'] = datetime.timedelta(**rule['opensearch_discover_to_timedelta'])
except (KeyError, TypeError) as e:
raise EAException('Invalid time format used: %s' % e)

Expand Down
Loading