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

VictorOps: Set state_message and entity_display_name from rule #329

Merged
merged 4 commits into from
Jul 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
# 2.x.x

## Breaking changes
- None
- [VictorOps] Changed `state_message` and `entity_display_name` values to be taken from an alert rule. - [#329](https://github.com/jertel/elastalert2/pull/329) - @ChristophShyper
- Potentially a breaking change if the alert subject changes due to the new default behavior.

## New features
- None
Expand Down
2 changes: 1 addition & 1 deletion docs/source/ruletypes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2707,7 +2707,7 @@ Optional:

``victorops_entity_id``: The identity of the incident used by Splunk On-Call (Formerly VictorOps) to correlate incidents throughout the alert lifecycle. If not defined, Splunk On-Call (Formerly VictorOps) will assign a random string to each alert.

``victorops_entity_display_name``: Human-readable name of alerting entity to summarize incidents without affecting the life-cycle workflow.
``victorops_entity_display_name``: Human-readable name of alerting entity to summarize incidents without affecting the life-cycle workflow. Will use ``alert_subject`` if not set.

``victorops_proxy``: By default ElastAlert will not use a network proxy to send notifications to Splunk On-Call (Formerly VictorOps). Set this option using ``hostname:port`` if you need to use a proxy. only supports https.

Expand Down
7 changes: 6 additions & 1 deletion elastalert/alerters/victorops.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def __init__(self, rule):
self.victorops_routing_key = self.rule.get('victorops_routing_key', None)
self.victorops_message_type = self.rule.get('victorops_message_type', None)
self.victorops_entity_id = self.rule.get('victorops_entity_id', None)
self.victorops_entity_display_name = self.rule.get('victorops_entity_display_name', 'no entity display name')
self.victorops_entity_display_name = self.rule.get('victorops_entity_display_name', None) # set entity_display_name from alert_subject by default
self.url = 'https://alert.victorops.com/integrations/generic/20131114/alert/%s/%s' % (
self.victorops_api_key, self.victorops_routing_key)
self.victorops_proxy = self.rule.get('victorops_proxy', None)
Expand All @@ -29,12 +29,17 @@ def alert(self, matches):
headers = {'content-type': 'application/json'}
# set https proxy, if it was provided
proxies = {'https': self.victorops_proxy} if self.victorops_proxy else None
# set title with alert_subject
self.victorops_entity_display_name = self.create_title(matches) if \
self.victorops_entity_display_name is None else self.victorops_entity_display_name
payload = {
"message_type": self.victorops_message_type,
"entity_display_name": self.victorops_entity_display_name,
"monitoring_tool": "ElastAlert",
"state_message": body
}
# add all data from event payload
payload.update(matches[0])
if self.victorops_entity_id:
payload["entity_id"] = self.victorops_entity_id

Expand Down
57 changes: 53 additions & 4 deletions tests/alerters/victorops_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,50 @@ def test_victorops(caplog):
'message_type': rule['victorops_message_type'],
'entity_display_name': rule['victorops_entity_display_name'],
'monitoring_tool': 'ElastAlert',
'state_message': 'Test VictorOps Rule\n\n@timestamp: 2021-01-01T00:00:00\nsomefield: foobarbaz\n'
'state_message': 'Test VictorOps Rule\n\n@timestamp: 2021-01-01T00:00:00\nsomefield: foobarbaz\n',
'@timestamp': '2021-01-01T00:00:00',
'somefield': 'foobarbaz'
}

mock_post_request.assert_called_once_with(
'https://alert.victorops.com/integrations/generic/20131114/alert/xxxx1/xxxx2',
data=mock.ANY,
headers={'content-type': 'application/json'},
proxies=None
)

actual_data = json.loads(mock_post_request.call_args_list[0][1]['data'])
assert expected_data == actual_data
assert ('elastalert', logging.INFO, 'Trigger sent to VictorOps') == caplog.record_tuples[0]


def test_victorops_no_title(caplog):
caplog.set_level(logging.INFO)
rule = {
'name': 'Test VictorOps Rule',
'type': 'any',
'victorops_api_key': 'xxxx1',
'victorops_routing_key': 'xxxx2',
'victorops_message_type': 'INFO',
'alert': []
}
rules_loader = FileRulesLoader({})
rules_loader.load_modules(rule)
alert = VictorOpsAlerter(rule)
match = {
'@timestamp': '2021-01-01T00:00:00',
'somefield': 'foobarbaz'
}
with mock.patch('requests.post') as mock_post_request:
alert.alert([match])

expected_data = {
'message_type': rule['victorops_message_type'],
'entity_display_name': rule['name'],
'monitoring_tool': 'ElastAlert',
'state_message': 'Test VictorOps Rule\n\n@timestamp: 2021-01-01T00:00:00\nsomefield: foobarbaz\n',
'@timestamp': '2021-01-01T00:00:00',
'somefield': 'foobarbaz'
}

mock_post_request.assert_called_once_with(
Expand Down Expand Up @@ -76,7 +119,9 @@ def test_victorops_proxy():
'message_type': rule['victorops_message_type'],
'entity_display_name': rule['victorops_entity_display_name'],
'monitoring_tool': 'ElastAlert',
'state_message': 'Test VictorOps Rule\n\n@timestamp: 2021-01-01T00:00:00\nsomefield: foobarbaz\n'
'state_message': 'Test VictorOps Rule\n\n@timestamp: 2021-01-01T00:00:00\nsomefield: foobarbaz\n',
'@timestamp': '2021-01-01T00:00:00',
'somefield': 'foobarbaz'
}

mock_post_request.assert_called_once_with(
Expand Down Expand Up @@ -141,7 +186,9 @@ def test_victorops_entity_id():
'entity_display_name': rule['victorops_entity_display_name'],
'monitoring_tool': 'ElastAlert',
'state_message': 'Test VictorOps Rule\n\n@timestamp: 2021-01-01T00:00:00\nsomefield: foobarbaz\n',
'entity_id': '12345'
'entity_id': '12345',
'@timestamp': '2021-01-01T00:00:00',
'somefield': 'foobarbaz'
}

mock_post_request.assert_called_once_with(
Expand Down Expand Up @@ -186,7 +233,9 @@ def test_victorops_message_type(message_type, except_message_type):
'message_type': except_message_type,
'entity_display_name': rule['victorops_entity_display_name'],
'monitoring_tool': 'ElastAlert',
'state_message': 'Test VictorOps Rule\n\n@timestamp: 2021-01-01T00:00:00\nsomefield: foobarbaz\n'
'state_message': 'Test VictorOps Rule\n\n@timestamp: 2021-01-01T00:00:00\nsomefield: foobarbaz\n',
'@timestamp': '2021-01-01T00:00:00',
'somefield': 'foobarbaz'
}

mock_post_request.assert_called_once_with(
Expand Down