bundles/icinga2: add notification support via ntfy

This commit is contained in:
Franzi 2023-04-09 17:32:36 +02:00
parent 25aabad865
commit b3e490720e
Signed by: kunsi
GPG key ID: 12E3D2136B818350
5 changed files with 81 additions and 36 deletions

View file

@ -1,16 +1,17 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from json import load
from sys import exit from sys import exit
from requests import get from requests import get
SIPGATE_USER = '${node.metadata['icinga2']['sipgate_user']}' with open('/etc/icinga2/notification_config.json') as f:
SIPGATE_PASS = '${node.metadata['icinga2']['sipgate_pass']}' CONFIG = load(f)
try: try:
r = get( r = get(
'https://api.sipgate.com/v2/balance', 'https://api.sipgate.com/v2/balance',
auth=(SIPGATE_USER, SIPGATE_PASS), auth=(CONFIG['sipgate']['user'], CONFIG['sipgate']['password']),
headers={'Accept': 'application/json'}, headers={'Accept': 'application/json'},
) )

View file

@ -3,22 +3,14 @@
import email.mime.text import email.mime.text
import smtplib import smtplib
from argparse import ArgumentParser from argparse import ArgumentParser
from json import dumps from json import dumps, load
from subprocess import run from subprocess import run
from sys import argv from sys import argv
from requests import post from requests import post
SIPGATE_USER='${node.metadata['icinga2']['sipgate_user']}' with open('/etc/icinga2/notification_config.json') as f:
SIPGATE_PASS='${node.metadata['icinga2']['sipgate_pass']}' CONFIG = load(f)
STATUS_TO_EMOJI = {
'critical': '🔥',
'down': '🚨🚨🚨',
'ok': '🆗',
'up': '👌',
'warning': '⚡',
}
parser = ArgumentParser( parser = ArgumentParser(
prog='icinga_notification_wrapper', prog='icinga_notification_wrapper',
@ -73,36 +65,31 @@ def notify_per_sms():
output_text = '' output_text = ''
else: else:
output_text = '\n\n{}'.format(args.output) output_text = '\n\n{}'.format(args.output)
if args.state.lower() in STATUS_TO_EMOJI:
message_text = '{emoji} {host}{service} {emoji}{output}'.format( message_text = 'ICINGA: {host}{service} is {state}{output}'.format(
emoji=STATUS_TO_EMOJI[args.state.lower()], host=args.host_name,
host=args.host_name, service=('/'+args.service_name if args.service_name else ''),
service=('/'+args.service_name if args.service_name else ''), state=args.state.upper(),
state=args.state.upper(), output=output_text,
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 = { message = {
'message': message_text, 'message': message_text,
'smsId': 's0', # XXX what does this mean? Documentation is unclear 'smsId': 's0', # XXX what does this mean? Documentation is unclear
'recipient': args.sms 'recipient': args.sms
} }
headers = { headers = {
'Content-type': 'application/json', 'Content-type': 'application/json',
'Accept': 'application/json' 'Accept': 'application/json'
} }
try: try:
r = post( r = post(
'https://api.sipgate.com/v2/sessions/sms', 'https://api.sipgate.com/v2/sessions/sms',
json=message, json=message,
headers=headers, headers=headers,
auth=(SIPGATE_USER, SIPGATE_PASS), auth=(CONFIG['sipgate']['user'], CONFIG['sipgate']['password']),
) )
if r.status_code == 204: 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))) 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(): def notify_per_mail():
if args.notification_type.lower() == 'recovery': if args.notification_type.lower() == 'recovery':
# Do not send recovery emails. # Do not send recovery emails.
@ -177,3 +195,5 @@ if __name__ == '__main__':
if args.sms: if args.sms:
notify_per_sms() notify_per_sms()
if CONFIG['ntfy']['user']:
notify_per_ntfy()

View file

@ -76,8 +76,6 @@ files = {
}, },
'/usr/local/share/icinga/plugins/check_sipgate_account_balance': { '/usr/local/share/icinga/plugins/check_sipgate_account_balance': {
'mode': '0755', 'mode': '0755',
'content_type': 'mako',
'cascade_skip': False, # contains faults
}, },
'/usr/local/share/icinga/plugins/check_freifunk_node': { '/usr/local/share/icinga/plugins/check_freifunk_node': {
'mode': '0755', 'mode': '0755',
@ -114,11 +112,22 @@ files = {
'svc_systemd:icinga2:restart', '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': { '/etc/icinga2/scripts/icinga_notification_wrapper': {
'source': 'scripts/icinga_notification_wrapper', 'source': 'scripts/icinga_notification_wrapper',
'content_type': 'mako',
'mode': '0755', 'mode': '0755',
'cascade_skip': False, # contains faults
}, },
'/etc/icinga2/features-available/ido-pgsql.conf': { '/etc/icinga2/features-available/ido-pgsql.conf': {
'source': 'icinga2/ido-pgsql.conf', 'source': 'icinga2/ido-pgsql.conf',

View file

@ -37,3 +37,11 @@ def join_faults(faults, by=' '):
lambda o: by.join([i.value for i in o]), lambda o: by.join([i.value for i in o]),
o=result, o=result,
) )
def dict_as_json(json):
return Fault(
'dict_as_json',
lambda o: metadata_to_json(o) + '\n',
o=json
)

View file

@ -54,8 +54,15 @@ nodes['ovh.icinga2'] = {
'restrict-to': { 'restrict-to': {
'172.19.138.0/24', '172.19.138.0/24',
}, },
'sipgate_user': bwpass.attr('sipgate.de/hi@kunsmann.eu', 'icinga_tokenid'), 'sipgate': {
'sipgate_pass': bwpass.attr('sipgate.de/hi@kunsmann.eu', 'icinga_token'), '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': { 'icinga2_api': {
'custom': { 'custom': {