2023-04-21 23:54:16 -06:00
|
|
|
import json
|
2023-04-21 23:54:17 -06:00
|
|
|
import os
|
|
|
|
import sys
|
2023-04-21 23:54:16 -06:00
|
|
|
from pathlib import Path
|
|
|
|
|
2023-04-21 23:54:17 -06:00
|
|
|
import urllib3
|
2023-04-21 23:54:16 -06:00
|
|
|
from flask import Flask, Response, request
|
|
|
|
from icinga2api.client import Client
|
|
|
|
|
2024-02-25 21:01:11 -07:00
|
|
|
script_dir = os.path.dirname(os.path.realpath(__file__))
|
|
|
|
sys.path.insert(0, str(Path(script_dir).parent))
|
2023-04-21 23:54:16 -06:00
|
|
|
from checker import nagios
|
2023-04-21 23:54:16 -06:00
|
|
|
|
2023-10-02 15:00:49 -06:00
|
|
|
# TODO: add query arg to not return an error when the host check is down
|
|
|
|
|
|
|
|
|
2023-04-21 23:54:17 -06:00
|
|
|
endpoint = 'https://localhost:8080' # Icinga2 URL for the API. Defaults to "https://localhost:8080"
|
|
|
|
icinga2_user = 'icingaweb2' # API username. Defaults to "icingaweb2"
|
|
|
|
icinga2_pw = '' # API password or set ICINGA2KUMA_ICINGA2_PW
|
2023-04-21 23:54:16 -06:00
|
|
|
|
2023-04-21 23:54:17 -06:00
|
|
|
if (icinga2_pw == '' or not icinga2_pw) and os.environ.get('ICINGA2KUMA_ICINGA2_PW'):
|
|
|
|
icinga2_pw = os.environ.get('ICINGA2KUMA_ICINGA2_PW')
|
|
|
|
else:
|
|
|
|
print('Must specify icinga2 API password.')
|
|
|
|
sys.exit(1)
|
|
|
|
|
|
|
|
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
|
|
|
|
|
|
|
client = Client(endpoint, icinga2_user, icinga2_pw)
|
2023-04-21 23:54:16 -06:00
|
|
|
|
2023-04-21 23:54:16 -06:00
|
|
|
app = Flask(__name__)
|
2023-04-21 23:54:16 -06:00
|
|
|
|
|
|
|
|
|
|
|
@app.route('/host')
|
|
|
|
@app.route('/host/')
|
|
|
|
@app.route("/host/<hostid>")
|
|
|
|
def get_host_state(hostid=None):
|
|
|
|
path = Path(request.base_url)
|
2024-09-08 13:45:31 -06:00
|
|
|
args_service = request.args.get('service', '').split(',')
|
|
|
|
args_exclude_service = request.args.get('exclude', '').split(',') # do not list these services
|
|
|
|
args_ignore_service = request.args.get('ignore', '').split(',') # do not trigger a fail if these services fail
|
2023-04-21 23:54:16 -06:00
|
|
|
kuma_mode = True if request.args.get('kuma') == 'true' else False
|
|
|
|
|
|
|
|
if not hostid:
|
|
|
|
return Response(json.dumps({'error': 'must specify host'}), status=406, mimetype='application/json')
|
|
|
|
|
|
|
|
result = {
|
|
|
|
'host': {},
|
|
|
|
'services': {},
|
2023-04-21 23:54:17 -06:00
|
|
|
'failed_services': [],
|
|
|
|
'excluded_services': [],
|
|
|
|
'ignored_services': [],
|
2023-04-21 23:54:16 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
host_status = client.objects.list('Host', filters='match(hpattern, host.name)', filter_vars={'hpattern': hostid})
|
|
|
|
if not len(host_status):
|
|
|
|
return Response(json.dumps({'error': 'could not find host'}), status=404, mimetype='application/json')
|
|
|
|
else:
|
|
|
|
host_status = host_status[0]
|
|
|
|
|
|
|
|
result['host'] = {
|
|
|
|
'name': host_status['name'],
|
|
|
|
'state': 0 if (host_status['attrs']['acknowledgement'] or host_status['attrs']['acknowledgement_expiry']) else host_status['attrs']['state'],
|
|
|
|
'actual_state': host_status['attrs']['state'],
|
|
|
|
'attrs': {
|
|
|
|
**host_status['attrs']
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
services_status = client.objects.list('Service', filters='match(hpattern, host.name)', filter_vars={'hpattern': hostid})
|
|
|
|
for attrs in services_status:
|
|
|
|
name = attrs['name'].split('!')[1]
|
2023-04-21 23:54:17 -06:00
|
|
|
if name in args_exclude_service:
|
|
|
|
result['excluded_services'].append(name)
|
|
|
|
else:
|
|
|
|
result['services'][name] = {
|
|
|
|
'state': 0 if (attrs['attrs']['acknowledgement'] or attrs['attrs']['acknowledgement_expiry']) else attrs['attrs']['state'],
|
|
|
|
'actual_state': attrs['attrs']['state'],
|
|
|
|
'attrs': {
|
|
|
|
**attrs
|
|
|
|
}
|
2023-04-21 23:54:16 -06:00
|
|
|
}
|
|
|
|
|
2024-09-08 13:45:31 -06:00
|
|
|
for i in range(len(args_service)):
|
|
|
|
if '+' in args_service[i]:
|
|
|
|
args_service[i].replace('+', ' ')
|
|
|
|
|
2023-04-21 23:54:16 -06:00
|
|
|
if len(args_service):
|
|
|
|
services = {}
|
|
|
|
for service in args_service:
|
|
|
|
if service in result['services'].keys():
|
|
|
|
services[service] = result['services'][service]
|
|
|
|
else:
|
|
|
|
return Response(json.dumps({'error': 'service not found', 'service': service}), status=400, mimetype='application/json')
|
|
|
|
result['services'] = services
|
|
|
|
|
2023-04-21 23:54:17 -06:00
|
|
|
# if kuma_mode:
|
|
|
|
for name, service in result['services'].items():
|
|
|
|
if service['state'] != nagios.OK and name not in args_ignore_service:
|
|
|
|
result['failed_services'].append({'name': name, 'state': service['state']})
|
|
|
|
if result['host']['state'] != nagios.OK:
|
|
|
|
result['failed_services'].append({'name': hostid, 'state': result['host']['state']})
|
2023-04-21 23:54:16 -06:00
|
|
|
|
2023-04-21 23:54:17 -06:00
|
|
|
if kuma_mode and len(result['failed_services']):
|
2023-04-21 23:54:16 -06:00
|
|
|
return Response(json.dumps(result), status=410, mimetype='application/json')
|
|
|
|
else:
|
|
|
|
return result
|
2024-09-08 13:45:31 -06:00
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
app.run()
|