Skip to content

Commit c350174

Browse files
authored
Merge pull request ceph#59889 from adk3798/alertmanager-custom-webhook
mgr/cephadm: fix custom alertmanager webhooks Reviewed-by: John Mulligan <[email protected]>
2 parents 8af60d7 + a8498dd commit c350174

File tree

5 files changed

+141
-9
lines changed

5 files changed

+141
-9
lines changed

doc/cephadm/services/monitoring.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -598,7 +598,7 @@ webhook urls like so:
598598
service_type: alertmanager
599599
spec:
600600
user_data:
601-
default_webhook_urls:
601+
webhook_urls:
602602
- "https://foo"
603603
- "https://bar"
604604

src/pybind/mgr/cephadm/services/monitoring.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ def get_dependencies(cls, mgr: "CephadmOrchestrator",
311311

312312
def generate_config(self, daemon_spec: CephadmDaemonDeploySpec) -> Tuple[Dict[str, Any], List[str]]:
313313
assert self.TYPE == daemon_spec.daemon_type
314-
default_webhook_urls: List[str] = []
314+
webhook_urls: List[str] = []
315315

316316
spec = cast(AlertManagerSpec, self.mgr.spec_store[daemon_spec.service_name].spec)
317317
try:
@@ -321,7 +321,10 @@ def generate_config(self, daemon_spec: CephadmDaemonDeploySpec) -> Tuple[Dict[st
321321
user_data = spec.user_data
322322
if 'default_webhook_urls' in user_data and isinstance(
323323
user_data['default_webhook_urls'], list):
324-
default_webhook_urls.extend(user_data['default_webhook_urls'])
324+
webhook_urls.extend(user_data['default_webhook_urls'])
325+
if 'webhook_urls' in user_data and isinstance(
326+
user_data['webhook_urls'], list):
327+
webhook_urls.extend(user_data['webhook_urls'])
325328

326329
security_enabled, mgmt_gw_enabled, oauth2_enabled = self.mgr._get_security_config()
327330
if mgmt_gw_enabled:
@@ -340,7 +343,7 @@ def generate_config(self, daemon_spec: CephadmDaemonDeploySpec) -> Tuple[Dict[st
340343
context = {
341344
'security_enabled': security_enabled,
342345
'dashboard_urls': dashboard_urls,
343-
'default_webhook_urls': default_webhook_urls,
346+
'webhook_urls': webhook_urls,
344347
'snmp_gateway_urls': snmp_gateway_urls,
345348
'secure': secure,
346349
}

src/pybind/mgr/cephadm/templates/services/alertmanager/alertmanager.yml.j2

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,14 @@ route:
2323
group_interval: 10s
2424
repeat_interval: 1h
2525
receiver: 'ceph-dashboard'
26+
{% if webhook_urls %}
27+
continue: true
28+
- group_by: ['alertname']
29+
group_wait: 10s
30+
group_interval: 10s
31+
repeat_interval: 1h
32+
receiver: 'custom-receiver'
33+
{% endif %}
2634
{% if snmp_gateway_urls %}
2735
continue: true
2836
- receiver: 'snmp-gateway'
@@ -36,7 +44,9 @@ route:
3644
receivers:
3745
- name: 'default'
3846
webhook_configs:
39-
{% for url in default_webhook_urls %}
47+
- name: 'custom-receiver'
48+
webhook_configs:
49+
{% for url in webhook_urls %}
4050
- url: '{{ url }}'
4151
{% endfor %}
4252
- name: 'ceph-dashboard'

src/pybind/mgr/cephadm/tests/test_services.py

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,8 @@ def _get_config(self, url: str) -> str:
567567
receivers:
568568
- name: 'default'
569569
webhook_configs:
570+
- name: 'custom-receiver'
571+
webhook_configs:
570572
- name: 'ceph-dashboard'
571573
webhook_configs:
572574
- url: '{url}/api/prometheus_receiver'
@@ -714,6 +716,8 @@ def test_alertmanager_config_when_mgmt_gw_enabled(self, _get_fqdn, _run_cephadm,
714716
receivers:
715717
- name: 'default'
716718
webhook_configs:
719+
- name: 'custom-receiver'
720+
webhook_configs:
717721
- name: 'ceph-dashboard'
718722
webhook_configs:
719723
- url: 'https://host_fqdn:29443/internal/dashboard/api/prometheus_receiver'
@@ -813,6 +817,8 @@ def test_alertmanager_config_security_enabled(self, _get_fqdn, _run_cephadm, cep
813817
receivers:
814818
- name: 'default'
815819
webhook_configs:
820+
- name: 'custom-receiver'
821+
webhook_configs:
816822
- name: 'ceph-dashboard'
817823
webhook_configs:
818824
- url: 'http://{fqdn}:8080/api/prometheus_receiver'
@@ -867,6 +873,119 @@ def test_alertmanager_config_security_enabled(self, _get_fqdn, _run_cephadm, cep
867873
use_current_daemon_image=False,
868874
)
869875

876+
@pytest.mark.parametrize(
877+
"user_data",
878+
[
879+
({'webhook_urls': ['http://foo.com:9999', 'http://bar.com:1111']}),
880+
({'default_webhook_urls': ['http://bar.com:9999', 'http://foo.com:1111']}),
881+
({'default_webhook_urls': ['http://bar.com:9999', 'http://foo.com:1111'],
882+
'webhook_urls': ['http://foo.com:9999', 'http://bar.com:1111']}),
883+
],
884+
)
885+
@patch("cephadm.serve.CephadmServe._run_cephadm")
886+
@patch("socket.getfqdn")
887+
@patch("cephadm.module.CephadmOrchestrator.get_mgr_ip", lambda _: '::1')
888+
@patch("cephadm.services.monitoring.password_hash", lambda password: 'alertmanager_password_hash')
889+
@patch('cephadm.cert_mgr.CertMgr.get_root_ca', lambda instance: 'cephadm_root_cert')
890+
@patch('cephadm.cert_mgr.CertMgr.generate_cert', lambda instance, fqdn, ip: ('mycert', 'mykey'))
891+
def test_alertmanager_config_custom_webhook_urls(
892+
self,
893+
_get_fqdn,
894+
_run_cephadm,
895+
cephadm_module: CephadmOrchestrator,
896+
user_data: Dict[str, List[str]]
897+
):
898+
_run_cephadm.side_effect = async_side_effect(('{}', '', 0))
899+
cephadm_module.set_store(AlertmanagerService.USER_CFG_KEY, 'alertmanager_user')
900+
cephadm_module.set_store(AlertmanagerService.PASS_CFG_KEY, 'alertmanager_plain_password')
901+
fqdn = 'host1.test'
902+
_get_fqdn.return_value = fqdn
903+
904+
print(user_data)
905+
906+
urls = []
907+
if 'default_webhook_urls' in user_data:
908+
urls += user_data['default_webhook_urls']
909+
if 'webhook_urls' in user_data:
910+
urls += user_data['webhook_urls']
911+
tab_over = ' ' * 18 # since we'll be inserting this into an indented string
912+
webhook_configs_str = '\n'.join(f'{tab_over}- url: \'{u}\'' for u in urls)
913+
914+
with with_host(cephadm_module, 'test'):
915+
with with_service(cephadm_module, AlertManagerSpec(user_data=user_data)):
916+
917+
y = dedent(f"""
918+
# This file is generated by cephadm.
919+
# See https://prometheus.io/docs/alerting/configuration/ for documentation.
920+
921+
global:
922+
resolve_timeout: 5m
923+
http_config:
924+
tls_config:
925+
insecure_skip_verify: true
926+
927+
route:
928+
receiver: 'default'
929+
routes:
930+
- group_by: ['alertname']
931+
group_wait: 10s
932+
group_interval: 10s
933+
repeat_interval: 1h
934+
receiver: 'ceph-dashboard'
935+
continue: true
936+
- group_by: ['alertname']
937+
group_wait: 10s
938+
group_interval: 10s
939+
repeat_interval: 1h
940+
receiver: 'custom-receiver'
941+
942+
receivers:
943+
- name: 'default'
944+
webhook_configs:
945+
- name: 'custom-receiver'
946+
webhook_configs:
947+
{webhook_configs_str}
948+
- name: 'ceph-dashboard'
949+
webhook_configs:
950+
- url: 'http://{fqdn}:8080/api/prometheus_receiver'
951+
""").lstrip()
952+
953+
_run_cephadm.assert_called_with(
954+
'test',
955+
"alertmanager.test",
956+
['_orch', 'deploy'],
957+
[],
958+
stdin=json.dumps({
959+
"fsid": "fsid",
960+
"name": 'alertmanager.test',
961+
"image": '',
962+
"deploy_arguments": [],
963+
"params": {
964+
'tcp_ports': [9093, 9094],
965+
},
966+
"meta": {
967+
'service_name': 'alertmanager',
968+
'ports': [9093, 9094],
969+
'ip': None,
970+
'deployed_by': [],
971+
'rank': None,
972+
'rank_generation': None,
973+
'extra_container_args': None,
974+
'extra_entrypoint_args': None,
975+
},
976+
"config_blobs": {
977+
"files": {
978+
"alertmanager.yml": y,
979+
},
980+
'peers': [],
981+
"use_url_prefix": False,
982+
"ip_to_bind_to": "",
983+
}
984+
}),
985+
use_current_daemon_image=False,
986+
error_ok=True,
987+
)
988+
870989
@patch("cephadm.serve.CephadmServe._run_cephadm")
871990
@patch("socket.getfqdn")
872991
@patch("cephadm.module.CephadmOrchestrator.get_mgr_ip", lambda _: '::1')

src/python-common/ceph/deployment/service_spec.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2516,14 +2516,14 @@ def __init__(self,
25162516
# service_type: alertmanager
25172517
# service_id: xyz
25182518
# user_data:
2519-
# default_webhook_urls:
2519+
# webhook_urls:
25202520
# - "https://foo"
25212521
# - "https://bar"
25222522
#
25232523
# Documentation:
2524-
# default_webhook_urls - A list of additional URL's that are
2525-
# added to the default receivers'
2526-
# <webhook_configs> configuration.
2524+
# webhook_urls - A list of additional URL's that are
2525+
# added to the default receivers'
2526+
# <webhook_configs> configuration.
25272527
self.user_data = user_data or {}
25282528
self.secure = secure
25292529
self.only_bind_port_on_networks = only_bind_port_on_networks

0 commit comments

Comments
 (0)