diff --git a/bundles/icinga2/files/check_sipgate_account_balance b/bundles/icinga2/files/check_sipgate_account_balance index 843dfd9..65054ba 100644 --- a/bundles/icinga2/files/check_sipgate_account_balance +++ b/bundles/icinga2/files/check_sipgate_account_balance @@ -1,16 +1,17 @@ #!/usr/bin/env python3 +from json import load from sys import exit from requests import get -SIPGATE_USER = '${node.metadata['icinga2']['sipgate_user']}' -SIPGATE_PASS = '${node.metadata['icinga2']['sipgate_pass']}' +with open('/etc/icinga2/notification_config.json') as f: + CONFIG = load(f) try: r = get( 'https://api.sipgate.com/v2/balance', - auth=(SIPGATE_USER, SIPGATE_PASS), + auth=(CONFIG['sipgate']['user'], CONFIG['sipgate']['password']), headers={'Accept': 'application/json'}, ) diff --git a/bundles/icinga2/files/scripts/icinga_notification_wrapper b/bundles/icinga2/files/scripts/icinga_notification_wrapper index 72ab749..66a9f5b 100644 --- a/bundles/icinga2/files/scripts/icinga_notification_wrapper +++ b/bundles/icinga2/files/scripts/icinga_notification_wrapper @@ -3,22 +3,14 @@ import email.mime.text import smtplib from argparse import ArgumentParser -from json import dumps +from json import dumps, load from subprocess import run from sys import argv from requests import post -SIPGATE_USER='${node.metadata['icinga2']['sipgate_user']}' -SIPGATE_PASS='${node.metadata['icinga2']['sipgate_pass']}' - -STATUS_TO_EMOJI = { - 'critical': '🔥', - 'down': '🚨🚨🚨', - 'ok': '🆗', - 'up': '👌', - 'warning': '⚡', -} +with open('/etc/icinga2/notification_config.json') as f: + CONFIG = load(f) parser = ArgumentParser( prog='icinga_notification_wrapper', @@ -73,36 +65,31 @@ def notify_per_sms(): output_text = '' else: output_text = '\n\n{}'.format(args.output) - if args.state.lower() in STATUS_TO_EMOJI: - message_text = '{emoji} {host}{service} {emoji}{output}'.format( - emoji=STATUS_TO_EMOJI[args.state.lower()], - host=args.host_name, - service=('/'+args.service_name if args.service_name else ''), - state=args.state.upper(), - output=output_text, - ) - else: - message_text = 'ICINGA: {host}{service} is {state}{output}'.format( - host=args.host_name, - service=('/'+args.service_name if args.service_name else ''), - state=args.state.upper(), - output=output_text, - ) + + message_text = 'ICINGA: {host}{service} is {state}{output}'.format( + host=args.host_name, + service=('/'+args.service_name if args.service_name else ''), + state=args.state.upper(), + output=output_text, + ) + message = { 'message': message_text, 'smsId': 's0', # XXX what does this mean? Documentation is unclear 'recipient': args.sms } + headers = { 'Content-type': 'application/json', 'Accept': 'application/json' } + try: r = post( 'https://api.sipgate.com/v2/sessions/sms', json=message, headers=headers, - auth=(SIPGATE_USER, SIPGATE_PASS), + auth=(CONFIG['sipgate']['user'], CONFIG['sipgate']['password']), ) if r.status_code == 204: @@ -113,6 +100,37 @@ def notify_per_sms(): log_to_syslog('Sending a SMS to "{}" failed: {}'.format(args.sms, repr(e))) +def notify_per_ntfy(): + message_text = 'ICINGA: {host}{service} is {state}\n\n{output}'.format( + host=args.host_name, + service=('/'+args.service_name if args.service_name else ''), + state=args.state.upper(), + output=args.output, + ) + + if args.service_name: + subject = '[ICINGA] {}/{}'.format(args.host_name, args.service_name) + else: + subject = '[ICINGA] {}'.format(args.host_name) + + headers = { + 'Title': subject, + 'Priority': 'urgent', + } + + try: + r = post( + CONFIG['ntfy']['url'], + data=message_text, + headers=headers, + auth=(CONFIG['ntfy']['user'], CONFIG['ntfy']['password']), + ) + + r.raise_for_status() + except Exception as e: + log_to_syslog('Sending a Notification failed: {}'.format(repr(e))) + + def notify_per_mail(): if args.notification_type.lower() == 'recovery': # Do not send recovery emails. @@ -177,3 +195,5 @@ if __name__ == '__main__': if args.sms: notify_per_sms() + if CONFIG['ntfy']['user']: + notify_per_ntfy() diff --git a/bundles/icinga2/items.py b/bundles/icinga2/items.py index 1a42e70..ff763a2 100644 --- a/bundles/icinga2/items.py +++ b/bundles/icinga2/items.py @@ -76,8 +76,6 @@ files = { }, '/usr/local/share/icinga/plugins/check_sipgate_account_balance': { 'mode': '0755', - 'content_type': 'mako', - 'cascade_skip': False, # contains faults }, '/usr/local/share/icinga/plugins/check_freifunk_node': { 'mode': '0755', @@ -114,11 +112,22 @@ files = { 'svc_systemd:icinga2:restart', }, }, + '/etc/icinga2/notification_config.json': { + 'content': repo.libs.faults.dict_as_json({ + 'sipgate': { + 'user': node.metadata.get('icinga2/sipgate/user'), + 'password': node.metadata.get('icinga2/sipgate/pass'), + }, + 'ntfy': { + 'url': node.metadata.get('icinga2/ntfy/url'), + 'user': node.metadata.get('icinga2/ntfy/user'), + 'password': node.metadata.get('icinga2/ntfy/pass'), + }, + }), + }, '/etc/icinga2/scripts/icinga_notification_wrapper': { 'source': 'scripts/icinga_notification_wrapper', - 'content_type': 'mako', 'mode': '0755', - 'cascade_skip': False, # contains faults }, '/etc/icinga2/features-available/ido-pgsql.conf': { 'source': 'icinga2/ido-pgsql.conf', diff --git a/libs/faults.py b/libs/faults.py index 91d8b2f..8990b64 100644 --- a/libs/faults.py +++ b/libs/faults.py @@ -37,3 +37,11 @@ def join_faults(faults, by=' '): lambda o: by.join([i.value for i in o]), o=result, ) + + +def dict_as_json(json): + return Fault( + 'dict_as_json', + lambda o: metadata_to_json(o) + '\n', + o=json + ) diff --git a/nodes/ovh/icinga2.py b/nodes/ovh/icinga2.py index 1c930be..0de9a46 100644 --- a/nodes/ovh/icinga2.py +++ b/nodes/ovh/icinga2.py @@ -54,8 +54,15 @@ nodes['ovh.icinga2'] = { 'restrict-to': { '172.19.138.0/24', }, - 'sipgate_user': bwpass.attr('sipgate.de/hi@kunsmann.eu', 'icinga_tokenid'), - 'sipgate_pass': bwpass.attr('sipgate.de/hi@kunsmann.eu', 'icinga_token'), + 'sipgate': { + 'user': bwpass.attr('sipgate.de/hi@kunsmann.eu', 'icinga_tokenid'), + 'pass': bwpass.attr('sipgate.de/hi@kunsmann.eu', 'icinga_token'), + }, + 'ntfy': { + 'url': 'https://ntfy.franzi.business/icinga2', + 'user': vault.decrypt('encrypt$gAAAAABkMtfW_tyGDUh7TkVX6AN8wSkKixWcQiOrPUWHtDZqnzjqrAkfD40fD8M_PiPDvW5pAa6xHNcUSU34jHolxnC44rDiLw=='), + 'pass': vault.decrypt('encrypt$gAAAAABkMtfD8lenogwJc8uKeGZUQ8QVWHMpAqY_GLW3VhF3Jt0TOC4JiJn49qfaC9Ij5rw6GGsowNIsNBe1Ac83HXOLveANEU2o-O4fp5TxNF0xFWebCCtcaTkj_L2DjUbSUe8QVDn3'), + }, }, 'icinga2_api': { 'custom': {