Skip to content

Commit

Permalink
Merge pull request #575 from nsano-rururu/alertmanamger_add_basic_auth
Browse files Browse the repository at this point in the history
Add support for basic auth to alertmanager
  • Loading branch information
jertel authored Nov 24, 2021
2 parents d58be74 + 70fdf34 commit 133b76d
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 5 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

## New features
- Add metric_agg_script to MetricAggregationRule [#558](https://github.com/jertel/elastalert2/pull/558) - @dequis
- [Alertmanager]Add support for basic authentication - [#575](https://github.com/jertel/elastalert2/pull/575) - @nsano-rururu

## Other changes
- sphinx 4.2.0 to 4.3.0 and tzlocal==2.1 - [#561](https://github.com/jertel/elastalert2/pull/561) - @nsano-rururu
Expand Down
4 changes: 4 additions & 0 deletions docs/source/ruletypes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1731,6 +1731,10 @@ Optional:

``alertmanager_timeout``: You can specify a timeout value, in seconds, for making communicating with Alertmanager. The default is 10. If a timeout occurs, the alert will be retried next time ElastAlert 2 cycles.

``alertmanager_basic_auth_login``: Basic authentication username.

``alertmanager_basic_auth_password``: Basic authentication password.

Example usage::

alert:
Expand Down
8 changes: 7 additions & 1 deletion elastalert/alerters/alertmanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import requests
from requests import RequestException
from requests.auth import HTTPBasicAuth

from elastalert.alerts import Alerter, DateTimeEncoder
from elastalert.util import EAException, elastalert_logger, lookup_es_key
Expand All @@ -27,6 +28,9 @@ def __init__(self, rule):
self.ca_certs = self.rule.get('alertmanager_ca_certs')
self.ignore_ssl_errors = self.rule.get('alertmanager_ignore_ssl_errors', False)
self.timeout = self.rule.get('alertmanager_timeout', 10)
self.alertmanager_basic_auth_login = self.rule.get('alertmanager_basic_auth_login', None)
self.alertmanager_basic_auth_password = self.rule.get('alertmanager_basic_auth_password', None)


@staticmethod
def _json_or_string(obj):
Expand All @@ -38,6 +42,7 @@ def _json_or_string(obj):
def alert(self, matches):
headers = {'content-type': 'application/json'}
proxies = {'https': self.proxies} if self.proxies else None
auth = HTTPBasicAuth(self.alertmanager_basic_auth_login, self.alertmanager_basic_auth_password) if self.alertmanager_basic_auth_login else None

self.labels.update({
label: self._json_or_string(lookup_es_key(matches[0], term))
Expand Down Expand Up @@ -70,7 +75,8 @@ def alert(self, matches):
headers=headers,
verify=verify,
proxies=proxies,
timeout=self.timeout
timeout=self.timeout,
auth=auth
)

warnings.resetwarnings()
Expand Down
2 changes: 2 additions & 0 deletions elastalert/schema.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,8 @@ properties:
alertmanager_ca_certs: {type: boolean}
alertmanager_ignore_ssl_errors: {type: boolean}
alertmanager_timeout: {type: integer}
alertmanager_basic_auth_login: {type: string}
alertmanager_basic_auth_password: {type: string}
alertmanager_labels:
type: object
minProperties: 1
Expand Down
72 changes: 68 additions & 4 deletions tests/alerters/alertmanager_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from unittest import mock

from requests import RequestException
from requests.auth import HTTPBasicAuth

from elastalert.alerters.alertmanager import AlertmanagerAlerter
from elastalert.loaders import FileRulesLoader
Expand Down Expand Up @@ -63,7 +64,8 @@ def test_alertmanager(caplog):
headers={'content-type': 'application/json'},
proxies=None,
verify=True,
timeout=10
timeout=10,
auth=None
)
assert expected_data == json.loads(mock_post_request.call_args_list[0][1]['data'])
assert ('elastalert', logging.INFO, "Alert sent to Alertmanager") == caplog.record_tuples[0]
Expand Down Expand Up @@ -121,7 +123,8 @@ def test_alertmanager_porxy():
headers={'content-type': 'application/json'},
proxies={'https': 'http://proxy.url'},
verify=True,
timeout=10
timeout=10,
auth=None
)
assert expected_data == json.loads(mock_post_request.call_args_list[0][1]['data'])

Expand Down Expand Up @@ -178,7 +181,8 @@ def test_alertmanager_timeout():
headers={'content-type': 'application/json'},
proxies=None,
verify=True,
timeout=20
timeout=20,
auth=None
)
assert expected_data == json.loads(mock_post_request.call_args_list[0][1]['data'])

Expand Down Expand Up @@ -251,7 +255,8 @@ def test_alertmanager_ca_certs(ca_certs, ignore_ssl_errors, excpet_verify):
headers={'content-type': 'application/json'},
proxies=None,
verify=excpet_verify,
timeout=10
timeout=10,
auth=None
)
assert expected_data == json.loads(mock_post_request.call_args_list[0][1]['data'])

Expand Down Expand Up @@ -322,3 +327,62 @@ def test_alertmanager_required_error(alertmanager_hosts, expected_data):
except Exception as ea:
print('ea %s' % str(ea))
assert expected_data in str(ea)


def test_alertmanager_basic_auth():
rule = {
'name': 'Test Alertmanager Rule',
'type': 'any',
'alertmanager_hosts': ['http://alertmanager:9093'],
'alertmanager_alertname': 'Title',
'alertmanager_annotations': {'severity': 'error'},
'alertmanager_labels': {'source': 'elastalert'},
'alertmanager_fields': {'msg': 'message', 'log': '@log_name'},
'alertmanager_basic_auth_login': 'user',
'alertmanager_basic_auth_password': 'password',
'alert_subject_args': ['message', '@log_name'],
'alert': []
}
rules_loader = FileRulesLoader({})
rules_loader.load_modules(rule)
alert = AlertmanagerAlerter(rule)
match = {
'@timestamp': '2021-01-01T00:00:00',
'somefield': 'foobarbaz',
'message': 'Quit 123',
'@log_name': 'mysqld.general'
}
with mock.patch('requests.post') as mock_post_request:
alert.alert([match])

expected_data = [
{
'annotations':
{
'severity': 'error',
'summary': 'Test Alertmanager Rule',
'description': 'Test Alertmanager Rule\n\n' +
'@log_name: mysqld.general\n' +
'@timestamp: 2021-01-01T00:00:00\n' +
'message: Quit 123\nsomefield: foobarbaz\n'
},
'labels': {
'source': 'elastalert',
'msg': 'Quit 123',
'log': 'mysqld.general',
'alertname': 'Title',
'elastalert_rule': 'Test Alertmanager Rule'
}
}
]

mock_post_request.assert_called_once_with(
'http://alertmanager:9093/api/v1/alerts',
data=mock.ANY,
headers={'content-type': 'application/json'},
proxies=None,
verify=True,
timeout=10,
auth=HTTPBasicAuth('user', 'password')
)
assert expected_data == json.loads(mock_post_request.call_args_list[0][1]['data'])

0 comments on commit 133b76d

Please sign in to comment.