diff --git a/bundles/sshmon/files/check_cpu_stats b/bundles/sshmon/files/check_cpu_stats new file mode 100644 index 0000000..28a6dfe --- /dev/null +++ b/bundles/sshmon/files/check_cpu_stats @@ -0,0 +1,184 @@ +#!/bin/bash +# ======================================================================================== +# CPU Utilization Statistics plugin for Nagios +# +# Written by : Steve Bosek +# Patched by : Bas van der Doorn +# Release : 2.2 +# Creation date : 8 September 2007 +# Revision date : 23 November 2008 +# Package : DTB Nagios Plugin +# Description : Nagios plugin (script) to check cpu utilization statistics. +# This script has been designed and written on Unix plateform (Linux, Aix, Solaris), +# requiring iostat as external program. The locations of these can easily +# be changed by editing the variables $IOSTAT at the top of the script. +# The script is used to query 4 of the key cpu statistics (user,system,iowait,idle) +# at the same time. Note though that there is only one set of warning +# and critical values for iowait percent. +# +# Usage : ./check_cpu_stats.sh [-w ] [-c ] [ -n ]) +# ---------------------------------------------------------------------------------------- +# +# TODO: Support for HP-UX +# +# +# ======================================================================================== +# +# HISTORY : +# Release | Date | Authors | Description +# --------------+---------------+---------------+------------------------------------------ +# 2.0 | 16.02.08 | Steve Bosek | Solaris support and new parameters +# | | | New Parameters : - iostat seconds intervals +# | | | - iostat report number +# 2.1 | 08.06.08 | Steve Bosek | Bug perfdata and convert comma in point for Linux result +# 2.1.1 | 20.11.08 | Bas van der Doorn | Fixed improperly terminated string +# 2.1.2 | 23.11.08 | Bas van der Doorn | Fixed linux steal reported as idle, comparisons +# 2.2 | 23.11.08 | Bas van der Doorn | Capable systems will output nice and steal data +# ----------------------------------------------------------------------------------------- +# +# ========================================================================================= + +# Paths to commands used in this script. These may have to be modified to match your system setup. + +IOSTAT=/usr/bin/iostat + +# Nagios return codes +STATE_OK=0 +STATE_WARNING=1 +STATE_CRITICAL=2 +STATE_UNKNOWN=3 + +# Plugin parameters value if not define +WARNING_THRESHOLD=${WARNING_THRESHOLD:="30"} +CRITICAL_THRESHOLD=${CRITICAL_THRESHOLD:="100"} +INTERVAL_SEC=${INTERVAL_SEC:="1"} +NUM_REPORT=${NUM_REPORT:="3"} + +# Plugin variable description +PROGNAME=$(basename $0) +RELEASE="Revision 2.1.1" +AUTHOR="(c) 2008 Steve Bosek (steve.bosek@gmail.com)" + +if [ ! -x $IOSTAT ]; then + echo "UNKNOWN: iostat not found or is not executable by the nagios user." + exit $STATE_UNKNOWN +fi + +# Functions plugin usage +print_release() { + echo "$RELEASE $AUTHOR" +} + +print_usage() { + echo "" + echo "$PROGNAME $RELEASE - CPU Utilization check script for Nagios" + echo "" + echo "Usage: check_cpu_stats.sh -w -c (-i -n)" + echo "" + echo " -w Warning level in % for cpu iowait" + echo " -c Crical level in % for cpu iowait" + echo " -i Interval in seconds for iostat (default : 1)" + echo " -n Number report for iostat (default : 3)" + echo " -h Show this page" + echo "" + echo "Usage: $PROGNAME" + echo "Usage: $PROGNAME --help" + echo "" +} + +print_help() { + print_usage + echo "" + echo "This plugin will check cpu utilization (user,system,iowait,idle in %)" + echo "" + exit 0 +} + +# Parse parameters +while [ $# -gt 0 ]; do + case "$1" in + -h | --help) + print_help + exit $STATE_OK + ;; + -v | --version) + print_release + exit $STATE_OK + ;; + -w | --warning) + shift + WARNING_THRESHOLD=$1 + ;; + -c | --critical) + shift + CRITICAL_THRESHOLD=$1 + ;; + -i | --interval) + shift + INTERVAL_SEC=$1 + ;; + -n | --number) + shift + NUM_REPORT=$1 + ;; + *) echo "Unknown argument: $1" + print_usage + exit $STATE_UNKNOWN + ;; + esac +shift +done + +# CPU Utilization Statistics Unix Plateform ( Linux,AIX,Solaris are supported ) +case `uname` in + Linux ) CPU_REPORT=`iostat -c $INTERVAL_SEC $NUM_REPORT | sed -e 's/,/./g' | tr -s ' ' ';' | sed '/^$/d' | tail -1` + CPU_REPORT_SECTIONS=`echo ${CPU_REPORT} | grep ';' -o | wc -l` + CPU_USER=`echo $CPU_REPORT | cut -d ";" -f 2` + CPU_NICE=`echo $CPU_REPORT | cut -d ";" -f 3` + CPU_SYSTEM=`echo $CPU_REPORT | cut -d ";" -f 4` + CPU_IOWAIT=`echo $CPU_REPORT | cut -d ";" -f 5` + CPU_IOWAIT_MAJOR=`echo $CPU_IOWAIT | cut -d "." -f 1` + if [ ${CPU_REPORT_SECTIONS} -ge 6 ]; then + CPU_STEAL=`echo $CPU_REPORT | cut -d ";" -f 6` + CPU_IDLE=`echo $CPU_REPORT | cut -d ";" -f 7` + NAGIOS_DATA="user=${CPU_USER}% system=${CPU_SYSTEM}% iowait=${CPU_IOWAIT}% idle=${CPU_IDLE}% nice=${CPU_NICE}% steal=${CPU_STEAL}% | CpuUser=${CPU_USER};CpuSystem=${CPU_SYSTEM};CpuIoWait=${CPU_IOWAIT};CpuIdle=${CPU_IDLE};CpuNice=${CPU_NICE};CpuSteal=${CPU_STEAL};$WARNING_THRESHOLD;$CRITICAL_THRESHOLD" + else + CPU_IDLE=`echo $CPU_REPORT | cut -d ";" -f 6` + NAGIOS_DATA="user=${CPU_USER}% system=${CPU_SYSTEM}% iowait=${CPU_IOWAIT}% idle=${CPU_IDLE}% nice=${CPU_NICE}% | CpuUser=${CPU_USER};CpuSystem=${CPU_SYSTEM};CpuIoWait=${CPU_IOWAIT};CpuIdle=${CPU_IDLE};CpuNice=${CPU_NICE};$WARNING_THRESHOLD;$CRITICAL_THRESHOLD" + fi + ;; + AIX ) CPU_REPORT=`iostat -t $INTERVAL_SEC $NUM_REPORT | sed -e 's/,/./g'|tr -s ' ' ';' | tail -1` + CPU_USER=`echo $CPU_REPORT | cut -d ";" -f 4` + CPU_SYSTEM=`echo $CPU_REPORT | cut -d ";" -f 5` + CPU_IOWAIT=`echo $CPU_REPORT | cut -d ";" -f 7` + CPU_IOWAIT_MAJOR=`echo $CPU_IOWAIT | cut -d "." -f 1` + CPU_IDLE=`echo $CPU_REPORT | cut -d ";" -f 6` + NAGIOS_DATA="user=${CPU_USER}% system=${CPU_SYSTEM}% iowait=${CPU_IOWAIT}% idle=${CPU_IDLE}% | CpuUser=${CPU_USER};CpuSystem=${CPU_SYSTEM};CpuIoWait=${CPU_IOWAIT};CpuIdle=${CPU_IDLE};$WARNING_THRESHOLD;$CRITICAL_THRESHOLD" + ;; + SunOS ) CPU_REPORT=`iostat -c $INTERVAL_SEC $NUM_REPORT | tail -1` + CPU_USER=`echo $CPU_REPORT | awk '{ print $1 }'` + CPU_SYSTEM=`echo $CPU_REPORT | awk '{ print $2 }'` + CPU_IOWAIT=`echo $CPU_REPORT | awk '{ print $3 }'` + CPU_IOWAIT_MAJOR=`echo $CPU_IOWAIT | cut -d "." -f 1` + CPU_IDLE=`echo $CPU_REPORT | awk '{ print $4 }'` + NAGIOS_DATA="user=${CPU_USER}% system=${CPU_SYSTEM}% iowait=${CPU_IOWAIT}% idle=${CPU_IDLE}% | CpuUser=${CPU_USER};CpuSystem=${CPU_SYSTEM};CpuIoWait=${CPU_IOWAIT};CpuIdle=${CPU_IDLE};$WARNING_THRESHOLD;$CRITICAL_THRESHOLD" + ;; + *) echo "UNKNOWN: `uname` not yet supported by this plugin. Coming soon !" + exit $STATE_UNKNOWN + ;; + esac + +# Return + if [ ${CPU_IOWAIT_MAJOR} -ge $WARNING_THRESHOLD ] && [ ${CPU_IOWAIT_MAJOR} -lt $CRITICAL_THRESHOLD ]; then + echo "CPU STATISTICS WARNING : ${NAGIOS_DATA}" + exit $STATE_WARNING + elif [ ${CPU_IOWAIT_MAJOR} -ge $CRITICAL_THRESHOLD ]; then + echo "CPU STATISTICS CRITICAL : ${NAGIOS_DATA}" + exit $STATE_CRITICAL + else + echo "CPU STATISTICS OK : ${NAGIOS_DATA}" + exit $STATE_OK + fi + + + diff --git a/bundles/sshmon/files/check_http_url_for_string b/bundles/sshmon/files/check_http_url_for_string new file mode 100644 index 0000000..376d59f --- /dev/null +++ b/bundles/sshmon/files/check_http_url_for_string @@ -0,0 +1,13 @@ +#!/bin/bash + +url=$1 +string=$2 + +if curl -m 30 -sLk "$url" | grep -F "$string" > /dev/null +then + echo OK + exit 0 +else + echo "CRITICAL - String '$string' not found in '$url'" + exit 2 +fi diff --git a/bundles/sshmon/files/check_http_wget b/bundles/sshmon/files/check_http_wget new file mode 100644 index 0000000..ade5dbe --- /dev/null +++ b/bundles/sshmon/files/check_http_wget @@ -0,0 +1,80 @@ +#!/usr/bin/env python3 + +#this is actually a python https requests query, its called check_http_wget cause it got replaced + +from sys import exit +from argparse import ArgumentParser + +import requests + +OK = 0 +CRITICAL = 2 + +parser = ArgumentParser() +parser.add_argument( + '--url', + required=True, +) +parser.add_argument( + '--check-string', +) +parser.add_argument( + '--no-follow-redirects', + action='store_true', +) +parser.add_argument( + '--timeout', + default=15, + type=int, +) +parser.add_argument( + '--useragent', +) +parser.add_argument( + '--proxy_url', +) + +parser.add_argument('--no-verify-ssl', dest='verify_ssl', action='store_false') +parser.set_defaults(verify_ssl=True) + +if __name__ == '__main__': + parsed_args = parser.parse_args() + requests_kwargs = { + 'timeout': parsed_args.timeout, + } + + if parsed_args.useragent: + requests_kwargs['headers'] = { + 'User-Agent': parsed_args.useragent, + } + if parsed_args.proxy_url: + requests_kwargs['proxies'] = { + 'http': parsed_args.proxy_url, + 'https': parsed_args.proxy_url, + } + + if not parsed_args.verify_ssl: + requests_kwargs['verify'] = False + requests.packages.urllib3.disable_warnings() + + if parsed_args.no_follow_redirects: + requests_kwargs['allow_redirects'] = False + + try: + r = requests.get(parsed_args.url, **requests_kwargs) + except Exception as e: + print(e) + exit(CRITICAL) + + if parsed_args.check_string: + if not parsed_args.check_string in r.text: + print("String '{}' not found on URL '{}'".format(parsed_args.check_string, parsed_args.url)) + exit(CRITICAL) + else: + try: + r.raise_for_status() + except Exception as e: + print("Error: {}".format(repr(e))) + exit(CRITICAL) + print('OK') + exit(OK) diff --git a/bundles/sshmon/files/check_https_certificate_at_url b/bundles/sshmon/files/check_https_certificate_at_url new file mode 100644 index 0000000..323f4ac --- /dev/null +++ b/bundles/sshmon/files/check_https_certificate_at_url @@ -0,0 +1,42 @@ +#!/bin/bash + +host=$1 +port=$2 + +cert=$(echo | openssl s_client -connect "$host":"$port" -servername "$host" 2>/dev/null | openssl x509) +issuer_hash=$(echo "$cert" | openssl x509 -noout -issuer_hash) +not_after=$(echo "$cert" | openssl x509 -noout -dates | grep '^notAfter=') + +if [[ -z "$cert" ]] || [[ -z "$issuer_hash" ]] || [[ -z "$not_after" ]] +then + echo "UNKNOWN - Could not retrieve certificate! [$host:$port]" + exit 3 +fi + +warn_days=60 +crit_days=30 + +case "$issuer_hash" in + # issuer=C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3 + 4f06f81d) + warn_days=10 + crit_days=3 + ;; +esac + +if ! echo "$cert" | openssl x509 -noout -checkend 0 >/dev/null 2>&1 +then + echo "CRITICAL - Certificate has expired! [$host:$port] [$not_after]" + exit 2 +elif ! echo "$cert" | openssl x509 -noout -checkend $((86400 * crit_days)) >/dev/null 2>&1 +then + echo "CRITICAL - Certificate will expire really soon: [$host:$port] [$not_after]" + exit 2 +elif ! echo "$cert" | openssl x509 -noout -checkend $((86400 * warn_days)) >/dev/null 2>&1 +then + echo "WARNING - Certificate will expire soon: [$host:$port] [$not_after]" + exit 1 +fi + +echo "OK - [$host:$port] [$not_after]" +exit 0 diff --git a/bundles/sshmon/files/check_mounts b/bundles/sshmon/files/check_mounts new file mode 100644 index 0000000..43ec850 --- /dev/null +++ b/bundles/sshmon/files/check_mounts @@ -0,0 +1,153 @@ +#!/usr/bin/env python3 + + +from argparse import ArgumentParser +from subprocess import check_output +from tempfile import TemporaryFile + + +check_filesystem_types = { + 'ext2', + 'ext3', + 'ext4', + 'vfat', +} + + +def read_systemd(): + """ + Read configured mount units from systemd. + """ + + lines = check_output( + 'systemctl list-unit-files -at mount --no-legend --no-pager', + shell=True, + ).decode('UTF-8').splitlines() + + for line in lines: + frag_path = None + fstype = None + options = None + source_path = None + state = None + where = None + + mountunit = line.split()[0] + props = check_output( + 'systemctl show -p FragmentPath,Options,SourcePath,Type,UnitFileState,Where -- ' + mountunit, + shell=True, + ).decode('UTF-8') + for pline in props.splitlines(): + if pline.startswith('FragmentPath='): + frag_path = pline[len('FragmentPath='):] + elif pline.startswith('Options='): + options = pline[len('Options='):] + elif pline.startswith('SourcePath='): + source_path = pline[len('SourcePath='):] + elif pline.startswith('Type='): + fstype = pline[len('Type='):] + elif pline.startswith('UnitFileState='): + state = pline[len('UnitFileState='):] + elif pline.startswith('Where='): + where = pline[len('Where='):] + + if state not in ('enabled', 'generated', 'static'): + continue + + # The properties of mount units change once they are mounted. + # For example, "options" and "type" change from "bind"/"none" to + # something like "ext4"/"rw,relatime" once a bind-mount is + # mounted. + # + # fstype can be an empty string if an admin decides to simply + # not specify the type in its mount unit. (Only good old fstab + # forced setting fstype.) + if ( + options != 'bind' and + fstype != '' and + fstype not in check_filesystem_types + ): + continue + + # Traditional mountpoints, those are represented by systemd + # units which are auto-generated. + if source_path == '/etc/fstab': + yield where + # Okay, this is a real systemd mount unit. Has it been + # configured by an admin or is it noise? + elif frag_path.startswith('/etc/systemd/system'): + yield where + + +def read_unix(path): + """ + Read /etc/fstab or /proc/self/mounts. + """ + + with open(path, 'r') as fp: + lines = fp.read().splitlines() + + for line in lines: + line = line.strip() + if line.startswith('#'): + continue + + fields = line.split() + if len(fields) < 3 or fields[2] not in check_filesystem_types: + continue + + # Only the mountpoint. + yield fields[1] + + +def rwtest(path): + try: + with TemporaryFile(dir=path) as fp: + pass + except Exception: + return False + return True + + +parser = ArgumentParser() +parser.add_argument('--ignore', nargs='*') +args = parser.parse_args() + +# read_systemd() does not return everything on systems older than 18.04. +configured = set(read_systemd()) | set(read_unix('/etc/fstab')) +mounted = set(read_unix('/proc/self/mounts')) + +configured -= set(args.ignore or []) +mounted -= set(args.ignore or []) + +missing_mounted = configured - mounted +missing_configured = mounted - configured +mounted_as_configured = mounted & configured + +all_mounts = configured | mounted +not_okay = {} + +for i in missing_mounted: + not_okay[i] = 'not mounted' + +for i in missing_configured: + not_okay[i] = 'not in fstab nor systemd unit' + +for i in mounted_as_configured: + if not rwtest(i): + not_okay[i] = 'mounted read-only' + +exitcode = 0 + +# Two loops to have CRITICAL printed before OK without having to create +# a new data structure. +for i in sorted(all_mounts): + if i in not_okay: + print('CRITICAL - {}: {}'.format(i, not_okay[i])) + exitcode = 2 + +for i in sorted(all_mounts): + if i not in not_okay: + print('OK - {}'.format(i)) + +exit(exitcode) diff --git a/bundles/sshmon/files/check_ram b/bundles/sshmon/files/check_ram new file mode 100644 index 0000000..525c556 --- /dev/null +++ b/bundles/sshmon/files/check_ram @@ -0,0 +1,86 @@ +#!/bin/bash +# +# Plugin to check free ram space +# using check_by_ssh +# by Markus Walther (voltshock@gmx.de) +# The script needs a working check_by_ssh connection and needs to run on the client to check it +# +# Command-Line for check_by_ssh +# command_line $USER1$/check_by_ssh -H $HOSTNAME$ -p $ARG1$ -C "$ARG2$ $ARG3$ $ARG4$ $ARG5$ $ARG6$" +# +# Command-Line for service (example) +# check_by_ssh!82!/nagios/check_ram.sh!20!10 +# +########################################################## + +case $1 in + --help | -h ) + echo "Usage: check_ram [warn] [crit]" + echo " [warn] and [crit] as int" + echo " Example: check_ram 20 10" + exit 3 + ;; + * ) + ;; +esac + +warn=$1 +crit=$2 + +if [[ "$1" == disabled ]] +then + echo "OK: Check disabled" + exit 0 +fi + +if [ ! "$1" -o ! "$2" ]; then + echo "Usage: check_ram [warn] [crit]" + echo " [warn] and [crit] as int" + echo " Example: check_ram 20 10" + echo "Unknown: Options missing: using default (warn=20, crit=10)" + warn=`echo $((20))` + crit=`echo $((10))` +fi + +full=`free | grep Mem | sed -r 's/\ +/\ /g' | cut -d \ -f 2` +free=`free | grep "buffers/cache" | sed -r 's/\ +/\ /g' | cut -d \ -f 4` +if [ "x$free" = "x" ]; then + # The output of "free" has changed in winter 2014: It removed the + # "buffers/cache" line, but added an "available" column. We're going + # to use that new one. + free=`free | grep Mem | sed -r 's/\ +/\ /g' | cut -d \ -f 7` +fi + +if [ -r /proc/spl/kstat/zfs/arcstats ] +then + # This system is using ZFS. ZFS does not use the standard I/O + # caching mechanism of Linux. As a result, ZFS caches appear as "in + # use by an application", which is not entirely true, since they + # will be freed when actual applications need memory. + # + # Add the current size of the ZFS ARC to the amount of free memory. + free=$(gawk -vfree="$free" '/^size / { printf "%d\n", free + $3 / 1024 }' \ + /proc/spl/kstat/zfs/arcstats) +fi + +if [ "$warn" -lt "$crit" -o "$warn" -eq "$crit" ]; then + echo "Unknown: [warn] must be larger than [crit]" + exit 3 +fi + +use=`echo $(( ($free * 100) / $full ))` + +if [ "$use" -gt "$warn" -o "$use" -eq "$warn" ]; then + echo "OK: $use% free memory" + exit 0 + elif [ "$use" -lt "$warn" -a "$use" -gt "$crit" ]; then + echo "Warning: $use% free memory" + exit 1 + elif [ "$use" -eq "$crit" -o "$use" -lt "$crit" ]; then + echo "Critical: $use% free memory" + exit 2 + else + echo "Unknown" + exit 3 +fi + diff --git a/bundles/sshmon/files/check_systemd_unit b/bundles/sshmon/files/check_systemd_unit new file mode 100644 index 0000000..948f75f --- /dev/null +++ b/bundles/sshmon/files/check_systemd_unit @@ -0,0 +1,10 @@ +#!/bin/bash + +if ! systemctl --quiet is-active "$1" +then + echo "CRITICAL - systemd unit $1 not active" + exit 2 +else + echo OK + exit 0 +fi diff --git a/bundles/sshmon/files/sshmon b/bundles/sshmon/files/sshmon new file mode 100644 index 0000000..76038cc --- /dev/null +++ b/bundles/sshmon/files/sshmon @@ -0,0 +1,25 @@ +#!/bin/bash +# ^^^^ Because we need Bash arrays. + +set -e + +UNKNOWN=3 + +unset command +declare -A command +. /etc/sshmon.cfg + +if [[ -z "$SSH_ORIGINAL_COMMAND" ]] +then + echo "No command given" >&2 + exit $UNKNOWN +fi + +execute=${command["$SSH_ORIGINAL_COMMAND"]} +if [[ -z "$execute" ]] +then + echo "Unknown command" >&2 + exit $UNKNOWN +fi + +exec sh -c "$execute" diff --git a/bundles/sshmon/files/sshmon.cfg b/bundles/sshmon/files/sshmon.cfg new file mode 100644 index 0000000..efac5f5 --- /dev/null +++ b/bundles/sshmon/files/sshmon.cfg @@ -0,0 +1,3 @@ +% for name, command in sorted(check_commands.items()): +command[${name}]='${command}' +% endfor diff --git a/bundles/sshmon/files/sudoers b/bundles/sshmon/files/sudoers new file mode 100644 index 0000000..30efe27 --- /dev/null +++ b/bundles/sshmon/files/sudoers @@ -0,0 +1,10 @@ +<% + commands = set() + for maybe_fault in check_commands.values(): + commands.add(str(maybe_fault)) +%>\ +% for command in sorted(commands): +% if command.startswith('sudo '): +sshmon ALL=NOPASSWD: ${command[len('sudo '):]} +% endif +% endfor diff --git a/bundles/sshmon/items.py b/bundles/sshmon/items.py new file mode 100644 index 0000000..978f9b9 --- /dev/null +++ b/bundles/sshmon/items.py @@ -0,0 +1,57 @@ +def collect_commands(): + check_commands = {} + + for bundle, bundle_config in node.metadata.get('icinga2_api', {}).items(): + for service, service_config in bundle_config.get('services', {}).items(): + # The default for check_command is also set in metadata.py + # and in icinga2 bundle + if ( + service_config.get('check_command', 'sshmon') == 'sshmon' and + 'vars.sshmon_command' in service_config and + 'command_on_monitored_host' in service_config + ): + check_commands[service_config['vars.sshmon_command']] = service_config['command_on_monitored_host'] + + return check_commands + + +pkg_apt = { + 'gawk': {}, # needed by check_ram + 'libwww-perl': {}, # needed by check_nginx_status + 'sysstat': {}, # needed by check_cpu_stats + 'monitoring-plugins': {}, +} + +check_commands = collect_commands() + +files = { + '/etc/sshmon.cfg': { + 'content_type': 'mako', + 'context': { + 'check_commands': check_commands, + }, + }, + '/etc/sudoers.d/sshmon': { + 'source': 'sudoers', + 'content_type': 'mako', + 'context': { + 'check_commands': check_commands, + }, + }, + '/usr/local/sbin/sshmon': { + 'mode': '0755', + }, +} + +for check in { + 'cpu_stats', + 'mounts', + 'ram', + 'http_url_for_string', + 'https_certificate_at_url', + 'http_wget', + 'systemd_unit', +}: + files["/usr/local/share/icinga/plugins/check_{}".format(check)] = { + 'mode': "0755", + } diff --git a/bundles/sshmon/metadata.py b/bundles/sshmon/metadata.py new file mode 100644 index 0000000..371cf3d --- /dev/null +++ b/bundles/sshmon/metadata.py @@ -0,0 +1,110 @@ +from bundlewrap.utils import Fault + +from os.path import join +from re import sub + + +with open(join(repo.path, 'data', 'sshmon', 'sshmon.pub'), 'r') as fp: + pubkey = fp.read().strip() + +defaults = { + 'icinga2_api': { + 'basic': { + 'services': { + 'CPU': { + 'command_on_monitored_host': '/usr/local/share/icinga/plugins/check_cpu_stats', + }, + 'LOAD': { + 'command_on_monitored_host': '/usr/lib/nagios/plugins/check_load -r -w 4,2,1 -c 8,4,2', + } + }, + }, + }, + 'users': { + 'sshmon': { + 'password_hash': 'x', + 'ssh_pubkey': { + 'command="/usr/local/sbin/sshmon" {}'.format(pubkey), + }, + 'sudo_commands': [], + }, + }, +} + + +@metadata_reactor +def autogenerate_sshmon_command(metadata): + result = { + 'icinga2_api': {}, + } + + for bundle, bundle_config in metadata.get('icinga2_api', {}).items(): + for service, service_config in bundle_config.get('services', {}).items(): + # The default for check_command is also set in items.py and + # in icinga2 bundle + if ( + service_config.get('check_command', 'sshmon') == 'sshmon' and + 'command_on_monitored_host' in service_config + ): + service_normalized = sub('[^a-zA-Z0-9]', '_', service) + + result['icinga2_api'].setdefault(bundle, {}).setdefault('services', {}).setdefault(service, {}) + result['icinga2_api'][bundle]['services'][service]['vars.sshmon_command'] = service_normalized + + return result + + +@metadata_reactor +def default_checks(metadata): + disk_space_warning = metadata.get('sshmon/disk_space/warning', 15) + disk_space_critical = metadata.get('sshmon/disk_space/critical', 5) + disk_space_warning_inodes = metadata.get('sshmon/disk_space/warning_inodes', 15) + disk_space_critical_inodes = metadata.get('sshmon/disk_space/critical_inodes', 5) + disk_space_ignore_patterns = metadata.get('sshmon/disk_space/ignore_patterns', set()) + + ram_warning = metadata.get('sshmon/ram_usage/warning', 9) + ram_critical = metadata.get('sshmon/ram_usage/critical', 8) + + mounts_options = metadata.get('sshmon/check_mounts_options', '') + + check_internet_http_url = metadata.get('sshmon/check_internet_http_url', 'https://ftp-stud.hs-esslingen.de') + + disk_space_extra_args = set() + + for pattern in disk_space_ignore_patterns: + disk_space_extra_args.add(f'-I {pattern}') + + for pool in metadata.get('zfs/pools', {}).keys(): + disk_space_extra_args.add(f'--ignore-ereg-partition={pool}') + + disk_space_ignore_patterns_string = ' '.join(sorted(disk_space_extra_args)) + + return { + 'icinga2_api': { + 'basic': { + 'services': { + 'DISK SPACE': { + 'command_on_monitored_host': str( + '/usr/lib/nagios/plugins/check_disk -X nfs -X nfs4 -X squashfs ' + f'-w {disk_space_warning} -c {disk_space_critical} ' + f'-W {disk_space_warning_inodes} -K {disk_space_critical_inodes} ' + '-A -I "^/dev$" -I "^/run" -I "^/sys" -i "/sys/kernel/debug/tracing" ' + f'{disk_space_ignore_patterns_string}', + ), + }, + 'MOUNTS': { + 'command_on_monitored_host': f'sudo /usr/local/share/icinga/plugins/check_mounts {mounts_options}', + }, + 'RAM': { + 'command_on_monitored_host': f'/usr/local/share/icinga/plugins/check_ram {ram_warning} {ram_critical}', + 'max_check_attempts': '12', + 'retry_interval': '30m', + }, + 'INTERNET': { + 'command_on_monitored_host': f'/usr/local/share/icinga/plugins/check_http_wget --url {check_internet_http_url}', + 'vars.sshmon_timeout': 20, + } + }, + }, + }, + }