Skip to content

Commit

Permalink
Merge pull request #260 from nsano-rururu/rocketchat_kibana_discover
Browse files Browse the repository at this point in the history
Rocket.Chat add kibana discover
  • Loading branch information
jertel authored Jun 11, 2021
2 parents 48acacb + 31c356b commit f3cbfc3
Show file tree
Hide file tree
Showing 4 changed files with 222 additions and 3 deletions.
12 changes: 9 additions & 3 deletions docs/source/ruletypes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2398,7 +2398,7 @@ The alerter requires the following option:

Optional:

``rocket_chat_username_override``: By default RocketChat will use username defined in Integration when posting to the channel. Use this option to change it (free text).
``rocket_chat_username_override``: By default Rocket.Chat will use username defined in Integration when posting to the channel. Use this option to change it (free text).

``rocket_chat_channel_override``: Incoming webhooks have a default channel, but it can be overridden. A public channel can be specified “#other-channel”, and a Direct Message with “@username”.

Expand All @@ -2409,9 +2409,15 @@ ElastAlert rule. Any Apple emoji can be used, see http://emojipedia.org/apple/ .

``rocket_chat_text_string``: Notification message you want to add.

``rocket_chat_proxy``: By default ElastAlert will not use a network proxy to send notifications to RocketChat. Set this option using ``hostname:port`` if you need to use a proxy.
``rocket_chat_proxy``: By default ElastAlert will not use a network proxy to send notifications to Rocket.Chat. Set this option using ``hostname:port`` if you need to use a proxy.

```rocket_chat_alert_fields``: You can add additional fields to your RocketChat alerts using this field. Specify the title using `title` and a value for the field using `value`. Additionally you can specify whether or not this field should be a `short` field using `short: true`.
``rocket_chat_attach_kibana_discover_url``: Enables the attachment of the ``kibana_discover_url`` to the Rocket.Chat notification. The config ``generate_kibana_discover_url`` must also be ``True`` in order to generate the url. Defaults to ``False``.

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

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

```rocket_chat_alert_fields``: You can add additional fields to your Rocket.Chat alerts using this field. Specify the title using `title` and a value for the field using `value`. Additionally you can specify whether or not this field should be a `short` field using `short: true`.

Example rocket_chat_alert_fields::

Expand Down
12 changes: 12 additions & 0 deletions elastalert/alerters/rocketchat.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ def __init__(self, rule):
self.rocket_chat_msg_color = self.rule.get('rocket_chat_msg_color', 'danger')
self.rocket_chat_text_string = self.rule.get('rocket_chat_text_string', '')
self.rocket_chat_alert_fields = self.rule.get('rocket_chat_alert_fields', '')
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')

def format_body(self, body):
return body
Expand Down Expand Up @@ -77,6 +80,15 @@ def alert(self, matches):
if self.rocket_chat_emoji_override != '':
payload['emoji'] = self.rocket_chat_emoji_override

if self.rocket_chat_attach_kibana_discover_url:
kibana_discover_url = lookup_es_key(matches[0], 'kibana_discover_url')
if kibana_discover_url:
payload['attachments'].append({
'color': self.rocket_chat_kibana_discover_color,
'title': self.rocket_chat_kibana_discover_title,
'title_link': kibana_discover_url
})

for url in self.rocket_chat_webhook_url:
for channel_override in self.rocket_chat_channel_override:
try:
Expand Down
3 changes: 3 additions & 0 deletions elastalert/schema.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,9 @@ properties:
rocket_chat_msg_color: {enum: [good, warning, danger]}
rocket_chat_text_string: {type: string}
rocket_chat_proxy: {type: string}
rocket_chat_attach_kibana_discover_url {type: boolean}
rocket_chat_kibana_discover_color {type: string}
rocket_chat_kibana_discover_title {type: string}

### ServiceNow
servicenow_rest_url: {type: string}
Expand Down
198 changes: 198 additions & 0 deletions tests/alerters/rocketchat_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -628,3 +628,201 @@ def test_rocketchat_required_error(rocket_chat_webhook_url, expected_data):
assert expected_data == actual_data
except Exception as ea:
assert expected_data in str(ea)


def test_rocket_chat_attach_kibana_discover_url_when_generated():
rule = {
'name': 'Test Rule',
'type': 'any',
'alert_subject': 'Cool subject',
'alert': [],
'rocket_chat_webhook_url': 'http://please.dontgohere.rocketchat',
'rocket_chat_attach_kibana_discover_url': True
}
rules_loader = FileRulesLoader({})
rules_loader.load_modules(rule)
alert = RocketChatAlerter(rule)
match = {
'@timestamp': '2021-01-01T00:00:00',
'somefield': 'foobarbaz',
'kibana_discover_url': 'http://localhost:5601/app/discover#/'
}
with mock.patch('requests.post') as mock_post_request:
alert.alert([match])

expected_data = {
'username': 'elastalert2',
'channel': '',
'emoji': ':ghost:',
'attachments': [
{
'color': 'danger',
'title': 'Cool subject',
'text': BasicMatchString(rule, match).__str__(),
'fields': []
},
{
'color': '#ec4b98',
'title': 'Discover in Kibana',
'title_link': 'http://localhost:5601/app/discover#/'
}
],
'text': ''
}

mock_post_request.assert_called_once_with(
rule['rocket_chat_webhook_url'],
data=mock.ANY,
headers={'content-type': 'application/json'},
proxies=None
)
assert expected_data == json.loads(mock_post_request.call_args_list[0][1]['data'])


def test_rocket_chat_attach_kibana_discover_url_when_not_generated():
rule = {
'name': 'Test Rule',
'type': 'any',
'alert_subject': 'Cool subject',
'alert': [],
'rocket_chat_webhook_url': 'http://please.dontgohere.rocketchat',
'rocket_chat_attach_kibana_discover_url': True
}

rules_loader = FileRulesLoader({})
rules_loader.load_modules(rule)
alert = RocketChatAlerter(rule)
match = {
'somefield': 'foobarbaz',
'@timestamp': '2021-01-01T00:00:00'
}

with mock.patch('requests.post') as mock_post_request:
alert.alert([match])

expected_data = {
'username': 'elastalert2',
'channel': '',
'emoji': ':ghost:',
'attachments': [
{
'color': 'danger',
'title': 'Cool subject',
'text': BasicMatchString(rule, match).__str__(),
'fields': []
}
],
'text': ''
}

mock_post_request.assert_called_once_with(
rule['rocket_chat_webhook_url'],
data=mock.ANY,
headers={'content-type': 'application/json'},
proxies=None
)
assert expected_data == json.loads(mock_post_request.call_args_list[0][1]['data'])


def test_rocket_chat_kibana_discover_title():
rule = {
'name': 'Test Rule',
'type': 'any',
'alert_subject': 'Cool subject',
'alert': [],
'rocket_chat_webhook_url': 'http://please.dontgohere.rocketchat',
'rocket_chat_attach_kibana_discover_url': True,
'rocket_chat_kibana_discover_title': 'Click to discover in Kibana'
}

rules_loader = FileRulesLoader({})
rules_loader.load_modules(rule)
alert = RocketChatAlerter(rule)
match = {
'somefield': 'foobarbaz',
'@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 = {
'username': 'elastalert2',
'channel': '',
'emoji': ':ghost:',
'attachments': [
{
'color': 'danger',
'title': 'Cool subject',
'text': BasicMatchString(rule, match).__str__(),
'fields': []
},
{
'color': '#ec4b98',
'title': 'Click to discover in Kibana',
'title_link': 'http://localhost:5601/app/discover#/'
}
],
'text': ''
}

mock_post_request.assert_called_once_with(
rule['rocket_chat_webhook_url'],
data=mock.ANY,
headers={'content-type': 'application/json'},
proxies=None
)
assert expected_data == json.loads(mock_post_request.call_args_list[0][1]['data'])


def test_rocket_chat_kibana_discover_color():
rule = {
'name': 'Test Rule',
'type': 'any',
'alert_text_type': 'alert_text_only',
'alert': [],
'rocket_chat_webhook_url': 'http://please.dontgohere.rocket_chat',
'rocket_chat_attach_kibana_discover_url': True,
'rocket_chat_kibana_discover_color': 'blue'
}

rules_loader = FileRulesLoader({})
rules_loader.load_modules(rule)
alert = RocketChatAlerter(rule)
match = {
'somefield': 'foobarbaz',
'@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 = {
'username': 'elastalert2',
'channel': '',
'emoji': ':ghost:',
'attachments': [
{
'color': 'danger',
'title': 'Test Rule',
'text': BasicMatchString(rule, match).__str__(),
'fields': []
},
{
'color': 'blue',
'title': 'Discover in Kibana',
'title_link': 'http://localhost:5601/app/discover#/'
}
],
'text': ''
}

mock_post_request.assert_called_once_with(
rule['rocket_chat_webhook_url'],
data=mock.ANY,
headers={'content-type': 'application/json'},
proxies=None
)
assert expected_data == json.loads(mock_post_request.call_args_list[0][1]['data'])

0 comments on commit f3cbfc3

Please sign in to comment.