Skip to content

Commit

Permalink
Merge pull request #239 from nsano-rururu/mattermost_kibana_discover
Browse files Browse the repository at this point in the history
Mattermost add kibana discover and bugfix
  • Loading branch information
jertel authored Jun 6, 2021
2 parents 3b70f65 + 7fb672a commit 63da04c
Show file tree
Hide file tree
Showing 5 changed files with 220 additions and 5 deletions.
6 changes: 4 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@
- Add support for Elasticsearch API key authentication - [#208](https://github.com/jertel/elastalert2/pull/208) - @vbisserie
- Add support for Elasticsearch 7.13 for building Kibana Discover URLs - [#212](https://github.com/jertel/elastalert2/pull/212) - @nsano-rururu
- Follow symbolic links when traversing rules folder for rule files - [#214](https://github.com/jertel/elastalert2/pull/214) - @vbisserie
- Support optional suppression of SSL log warnings when http-posting alerts - [#222](https://github.com/jertel/elastalert2/pull/222/files) - @nsano-rururu
- Support optional suppression of SSL log warnings when http-posting alerts - [#222](https://github.com/jertel/elastalert2/pull/222) - @nsano-rururu
- Add support for inclusion of Kibana Discover URLs in MatterMost messages - [#239](https://github.com/jertel/elastalert2/pull/239) - @nsano-rururu

## Other changes
- Speed up unit tests by adding default parallelism - [#164](https://github.com/jertel/elastalert2/pull/164) - @ferozsalam
Expand All @@ -46,7 +47,8 @@
- Migrate away from external test mock dependency - [#233](https://github.com/jertel/elastalert2/pull/233) - @nsano-rururu
- Improve ElastAlert 2 documentation relating to running scenarios - [#234](https://github.com/jertel/elastalert2/pull/234) - @ferozsalam
- Improve test coverage and correct dict lookup syntax for alerter init functions - [#235](https://github.com/jertel/elastalert2/pull/235) - @nsano-rururu

- Fix schema bug with MatterMost alerts - [#239](https://github.com/jertel/elastalert2/pull/239) - @nsano-rururu
-
# 2.1.0

## Breaking changes
Expand Down
6 changes: 6 additions & 0 deletions docs/source/ruletypes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2223,6 +2223,12 @@ Example mattermost_msg_fields::

``mattermost_author_icon``: An optional URL used to display a 16x16 pixel icon beside the author_name. Defaults to "".

``mattermost_attach_kibana_discover_url``: Enables the attachment of the ``kibana_discover_url`` to the mattermost notification. The config ``generate_kibana_discover_url`` must also be ``True`` in order to generate the url. Defaults to ``False``.

``mattermost_kibana_discover_color``: The color of the Kibana Discover url attachment. Defaults to ``#ec4b98``.

``mattermost_kibana_discover_title``: The title of the Kibana Discover url attachment. Defaults to ``Discover in Kibana``.

Microsoft Teams
~~~~~~~~~~~~~~~

Expand Down
12 changes: 12 additions & 0 deletions elastalert/alerters/mattermost.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ def __init__(self, rule):
self.mattermost_author_name = self.rule.get('mattermost_author_name', '')
self.mattermost_author_link = self.rule.get('mattermost_author_link', '')
self.mattermost_author_icon = self.rule.get('mattermost_author_icon', '')
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')

def get_aggregation_summary_text__maximum_width(self):
width = super(MattermostAlerter, self).get_aggregation_summary_text__maximum_width()
Expand Down Expand Up @@ -128,6 +131,15 @@ def alert(self, matches):
if self.mattermost_author_icon != '':
payload['attachments'][0]['author_icon'] = self.mattermost_author_icon

if self.mattermost_attach_kibana_discover_url:
kibana_discover_url = lookup_es_key(matches[0], 'kibana_discover_url')
if kibana_discover_url:
payload['attachments'].append({
'color': self.mattermost_kibana_discover_color,
'title': self.mattermost_kibana_discover_title,
'title_link': kibana_discover_url
})

for url in self.mattermost_webhook_url:
try:
if self.mattermost_ignore_ssl_errors:
Expand Down
13 changes: 10 additions & 3 deletions elastalert/schema.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,6 @@ definitions:
milliseconds: {type: number}
schedule: {type: string}

filter: &filter {}

mattermostField: &mattermostField
type: object
additionalProperties: false
Expand All @@ -45,6 +43,12 @@ definitions:
args: *arrayOfString
short: {type: boolean}

arrayOfMattermostFields: &arrayOfMattermostField
type: array
items: *mattermostField

filter: &filter {}

required: [type, index, alert]
type: object

Expand Down Expand Up @@ -397,7 +401,7 @@ properties:
mattermost_icon_url_override: {type: string}
mattermost_msg_pretext: {type: string}
mattermost_msg_color: {enum: [good, warning, danger]}
mattermost_msg_fields: *mattermostField
mattermost_msg_fields: *arrayOfMattermostField
mattermost_title_link: {type: string}
mattermost_footer: {type: string}
mattermost_footer_icon: {type: string}
Expand All @@ -406,6 +410,9 @@ properties:
mattermost_author_name: {type: string}
mattermost_author_link: {type: string}
mattermost_author_icon: {type: string}
mattermost_attach_kibana_discover_url {type: boolean}
mattermost_kibana_discover_color {type: string}
mattermost_kibana_discover_title {type: string}

### Microsoft Teams
ms_teams_webhook_url: *arrayOfString
Expand Down
188 changes: 188 additions & 0 deletions tests/alerters/mattermost_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -904,3 +904,191 @@ def test_mattermost_required_error(mattermost_webhook_url, expected_data):
assert expected_data == actual_data
except Exception as ea:
assert expected_data in str(ea)


def test_mattermost_attach_kibana_discover_url_when_generated():
rule = {
'name': 'Test Rule',
'type': 'any',
'alert_text_type': 'alert_text_only',
'mattermost_attach_kibana_discover_url': True,
'mattermost_webhook_url': 'http://please.dontgohere.mattermost',
'alert': []
}
rules_loader = FileRulesLoader({})
rules_loader.load_modules(rule)
alert = MattermostAlerter(rule)
match = {
'@timestamp': '2021-01-01T00:00:00',
'kibana_discover_url': 'http://localhost:5601/app/discover#/'
}
with mock.patch('requests.post') as mock_post_request:
alert.alert([match])

expected_data = {
'attachments': [
{
'fallback': 'Test Rule: ',
'color': 'danger',
'title': 'Test Rule',
'pretext': '',
'fields': [],
'text': 'Test Rule\n\n'
},
{
'color': '#ec4b98',
'title': 'Discover in Kibana',
'title_link': 'http://localhost:5601/app/discover#/'
}
], 'username': 'elastalert'
}
mock_post_request.assert_called_once_with(
rule['mattermost_webhook_url'],
data=mock.ANY,
headers={'content-type': 'application/json'},
verify=True,
proxies=None
)

actual_data = json.loads(mock_post_request.call_args_list[0][1]['data'])
assert expected_data == actual_data


def test_mattermost_attach_kibana_discover_url_when_not_generated():
rule = {
'name': 'Test Rule',
'type': 'any',
'alert_text_type': 'alert_text_only',
'mattermost_attach_kibana_discover_url': True,
'mattermost_webhook_url': 'http://please.dontgohere.mattermost',
'alert': []
}
rules_loader = FileRulesLoader({})
rules_loader.load_modules(rule)
alert = MattermostAlerter(rule)
match = {
'@timestamp': '2021-01-01T00:00:00'
}
with mock.patch('requests.post') as mock_post_request:
alert.alert([match])

expected_data = {
'attachments': [
{
'fallback': 'Test Rule: ',
'color': 'danger',
'title': 'Test Rule',
'pretext': '',
'fields': [],
'text': 'Test Rule\n\n'
}
], 'username': 'elastalert'
}
mock_post_request.assert_called_once_with(
rule['mattermost_webhook_url'],
data=mock.ANY,
headers={'content-type': 'application/json'},
verify=True,
proxies=None
)

actual_data = json.loads(mock_post_request.call_args_list[0][1]['data'])
assert expected_data == actual_data


def test_mattermost_kibana_discover_title():
rule = {
'name': 'Test Rule',
'type': 'any',
'alert_text_type': 'alert_text_only',
'mattermost_attach_kibana_discover_url': True,
'mattermost_kibana_discover_title': 'Click to discover in Kibana',
'mattermost_webhook_url': 'http://please.dontgohere.mattermost',
'alert': []
}
rules_loader = FileRulesLoader({})
rules_loader.load_modules(rule)
alert = MattermostAlerter(rule)
match = {
'@timestamp': '2021-01-01T00:00:00',
'kibana_discover_url': 'http://localhost:5601/app/discover#/'
}
with mock.patch('requests.post') as mock_post_request:
alert.alert([match])

expected_data = {
'attachments': [
{
'fallback': 'Test Rule: ',
'color': 'danger',
'title': 'Test Rule',
'pretext': '',
'fields': [],
'text': 'Test Rule\n\n'
},
{
'color': '#ec4b98',
'title': 'Click to discover in Kibana',
'title_link': 'http://localhost:5601/app/discover#/'
}
], 'username': 'elastalert'
}
mock_post_request.assert_called_once_with(
rule['mattermost_webhook_url'],
data=mock.ANY,
headers={'content-type': 'application/json'},
verify=True,
proxies=None
)

actual_data = json.loads(mock_post_request.call_args_list[0][1]['data'])
assert expected_data == actual_data


def test_mattermost_kibana_discover_color():
rule = {
'name': 'Test Rule',
'type': 'any',
'alert_text_type': 'alert_text_only',
'mattermost_attach_kibana_discover_url': True,
'mattermost_kibana_discover_color': 'blue',
'mattermost_webhook_url': 'http://please.dontgohere.mattermost',
'alert': []
}
rules_loader = FileRulesLoader({})
rules_loader.load_modules(rule)
alert = MattermostAlerter(rule)
match = {
'@timestamp': '2021-01-01T00:00:00',
'kibana_discover_url': 'http://localhost:5601/app/discover#/'
}
with mock.patch('requests.post') as mock_post_request:
alert.alert([match])

expected_data = {
'attachments': [
{
'fallback': 'Test Rule: ',
'color': 'danger',
'title': 'Test Rule',
'pretext': '',
'fields': [],
'text': 'Test Rule\n\n'
},
{
'color': 'blue',
'title': 'Discover in Kibana',
'title_link': 'http://localhost:5601/app/discover#/'
}
], 'username': 'elastalert'
}
mock_post_request.assert_called_once_with(
rule['mattermost_webhook_url'],
data=mock.ANY,
headers={'content-type': 'application/json'},
verify=True,
proxies=None
)

actual_data = json.loads(mock_post_request.call_args_list[0][1]['data'])
assert expected_data == actual_data

0 comments on commit 63da04c

Please sign in to comment.