commit ba67bb368bdb1dec94aaa48acadc2d1354f5bf77 Author: Benjamin Renard Date: Wed Oct 26 12:20:22 2022 +0200 First version diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4c5f88a --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*~ +.*.swp diff --git a/README.md b/README.md new file mode 100644 index 0000000..ee8282c --- /dev/null +++ b/README.md @@ -0,0 +1,41 @@ +# Monitoring plugin to check ESPHome devices status + +This Icinga/Nagios check plugin permit to check ESPHome devices status using the ESPHome Dashboard API : + +- check if device is reachable +- check if device upgrade is available + +## Installation + +``` +apt install git +git clone https://gitea.zionetrix.net/bn8/check_esphome_devices.git /usr/local/src/check_esphome_devices +mkdir -p /usr/local/lib/nagios/plugins +ln -s /usr/local/src/check_esphome_devices/check_esphome_devices /usr/local/lib/nagios/plugins/ +echo "command[check_esphome_devices]=/usr/local/lib/nagios/plugins/check_esphome_devices" > /etc/nagios/nrpe.d/esphome.cfg +service nagios-nrpe-server reload +``` + +## Usage + +``` +usage: check_esphome_devices [-h] [-d] [-H HOST] + +optional arguments: + -h, --help show this help message and exit + -d, --debug + -H HOST, --host HOST ESPHome dashboard URL (default: http://127.0.0.1:6052) +``` + +## Copyright + +Copyright (c) 2022 Benjamin Renard + +## License + +This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 3 as published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + diff --git a/check_esphome_devices b/check_esphome_devices new file mode 100755 index 0000000..a49c5c2 --- /dev/null +++ b/check_esphome_devices @@ -0,0 +1,124 @@ +#!/usr/bin/python3 +""" +Icinga/Nagios plugin to check ESPHome devices status using the ESPHome +Dashboard API. + +Copyright (c) 2022 Benjamin Renard + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License version 3 +as published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +""" + +import argparse +import sys +import logging + +import requests + + +# nagios exit code +STATUS = { + 'OK': 0, + 'WARNING': 1, + 'CRITICAL': 2, + 'UNKNOWN': 3 +} + +DEFAULT_HOST = 'http://127.0.0.1:6052' + +parser = argparse.ArgumentParser() +parser.add_argument( + '-d', '--debug', + action="store_true", + dest="debug", + default=False +) + +parser.add_argument( + '-H', '--host', + action="store", + dest="host", + help=f'ESPHome dashboard URL (default: {DEFAULT_HOST})', + type=str, + default=DEFAULT_HOST +) + +options = parser.parse_args() + +logging.basicConfig( + level=logging.DEBUG if options.debug else logging.INFO, + format='%(asctime)s - %(levelname)s - %(message)s') + +if options.host[-1] == '/': + options.host = options.host[-1] + +r = requests.get(f'{options.host}/devices') +devices_data = r.json() +logging.debug('Devices data: %s (%s)', devices_data, type(devices_data)) + +if not devices_data: + print('UNKNOWN - Fail to retreive devices using ESPHome Dashboard API') + sys.exit(STATUS['UNKNOWN']) + +r = requests.get(f'{options.host}/ping') +ping_data = r.json() +logging.debug('Ping data: %s (%s)', ping_data, type(ping_data)) + +if not ping_data: + print( + 'UNKNOWN - Fail to retreive devices status ' + 'using ESPHome Dashboard API') + sys.exit(STATUS['UNKNOWN']) + +UPDATE_AVAILABLE = 0 +UNREACHABLE_DEVICES = 0 +NO_PING_DATA = 0 +errors = [] +devices = {} +for dev in devices_data['configured']: + devices[dev['name']] = dev + logging.debug('Device %s: %s', dev['name'], dev) + if dev['deployed_version'] != dev['current_version']: + UPDATE_AVAILABLE += 1 + errors.append( + f'Update available for device {dev["name"]} ' + f'({dev["deployed_version"]} => {dev["current_version"]})') + + if dev['configuration'] not in ping_data: + errors.append( + f'No ping data found for device {dev["name"]} ' + f'({dev["configuration"]})') + elif not ping_data[dev['configuration']]: + errors.append(f'Device {dev["name"]} is unreachable') + +if not errors: + print(f'OK - no problem detected on the {len(devices)} devices') + EXIT_STATUS = STATUS['OK'] +else: + msg = [] + if UNREACHABLE_DEVICES: + msg.append(f'{UNREACHABLE_DEVICES} unreachable devices') + if NO_PING_DATA: + msg.append(f'{NO_PING_DATA} missing ping device status') + if UPDATE_AVAILABLE: + msg.append(f'{UPDATE_AVAILABLE} update available') + print(f'WARNING - {", ".join(msg)}') + EXIT_STATUS = STATUS['WARNING'] +print("\n".join([ + ( + f'- {name} (version = {dev["deployed_version"]}, ' + f'address = {dev["address"]})' + ) + for name, dev in devices.items() +])) +sys.exit(EXIT_STATUS)