merge dev
This commit is contained in:
parent
e62d7111cb
commit
ba347d60db
|
@ -0,0 +1,32 @@
|
||||||
|
import argparse
|
||||||
|
import json
|
||||||
|
|
||||||
|
import requests
|
||||||
|
from urllib3.exceptions import InsecureRequestWarning
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description='Check OPNsense network traffic for a host.')
|
||||||
|
parser.add_argument('--api', required=True, help='Full URL to your Icinga2 API.')
|
||||||
|
parser.add_argument('--user', required=True, help='API username.')
|
||||||
|
parser.add_argument('--password', required=True, help='API password.')
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
# Retrieve a list of unacknowledged alerts
|
||||||
|
requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)
|
||||||
|
payload = {
|
||||||
|
"type": "Service",
|
||||||
|
"filter": "service.name == \"apt\" && service.acknowledgement == 0",
|
||||||
|
"author": "Auto-Acknowledgement Script",
|
||||||
|
"comment": "This alert has been automatically acknowledged.",
|
||||||
|
"notify": True,
|
||||||
|
"pretty": True
|
||||||
|
}
|
||||||
|
|
||||||
|
# Send the API request
|
||||||
|
response = requests.post(f'{args.api}/v1/actions/acknowledge-problem', headers={"Accept": "application/json"}, auth=(args.user, args.password), data=json.dumps(payload), verify=False)
|
||||||
|
|
||||||
|
# Check the response status code
|
||||||
|
if response.status_code == 200:
|
||||||
|
print("All pending alerts have been acknowledged.")
|
||||||
|
else:
|
||||||
|
print("Failed to acknowledge the alerts. Status code:", response.status_code)
|
||||||
|
print(response.text)
|
|
@ -0,0 +1,13 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
apt-get install snmpd sudo perl libconfig-general-perl libdata-dumper-simple-perl libsort-naturally-perl libexception-class-perl libencode-perl make
|
||||||
|
|
||||||
|
TMP=$(mktemp -d)
|
||||||
|
git clone https://github.com/Tontonitch/interfacetable_v3t.git "$TMP"
|
||||||
|
|
||||||
|
cd "$TMP"
|
||||||
|
chmod a+x ./configure
|
||||||
|
./configure --prefix=/usr/local/interfacetable_v3t --with-nagios-user=nagios --with-nagios-group=nagios
|
||||||
|
make install
|
||||||
|
|
||||||
|
rm -rf "$TMP"
|
240
check_curl old
240
check_curl old
|
@ -1,240 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
# startup checks
|
|
||||||
|
|
||||||
if [ -z "$BASH" ]; then
|
|
||||||
echo "Please use BASH."
|
|
||||||
exit 3
|
|
||||||
fi
|
|
||||||
if [ ! -e "/usr/bin/which" ]; then
|
|
||||||
echo "/usr/bin/which is missing."
|
|
||||||
exit 3
|
|
||||||
fi
|
|
||||||
curl=$(which curl)
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echo "Please install curl."
|
|
||||||
exit 3
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
# Default Values
|
|
||||||
proxy=""
|
|
||||||
method="GET"
|
|
||||||
body=""
|
|
||||||
contains=""
|
|
||||||
lacks=""
|
|
||||||
insecure=0
|
|
||||||
debug=0
|
|
||||||
warning=700
|
|
||||||
encodeurl=0
|
|
||||||
critical=2000
|
|
||||||
url=""
|
|
||||||
follow=0
|
|
||||||
header=""
|
|
||||||
name="default"
|
|
||||||
cookies=0
|
|
||||||
|
|
||||||
# Usage Info
|
|
||||||
usage() {
|
|
||||||
echo '''Usage: check_curl [OPTIONS]
|
|
||||||
[OPTIONS]:
|
|
||||||
-U URL Target URL
|
|
||||||
-M METHOD HTTP Method (default: GET)
|
|
||||||
-N NAME Display Name of scanned object (default: default)
|
|
||||||
-B BODY Request Body to be sent (default: not sent)
|
|
||||||
-E ENCODEURL Send body defined with url encoding (curl --data-urlencode) (default: off)
|
|
||||||
-I INSECURE Sets the curl flag --insecure
|
|
||||||
-C CONTAINS If not contained in response body, CRITICAL will be returned
|
|
||||||
-L LACKS If contained in response body, CRITICAL will be returned (-C has priority when both are set)
|
|
||||||
-w WARNING Warning threshold in milliseconds (default: 700)
|
|
||||||
-c CRITICAL Critical threshold in milliseconds (default: 2000)
|
|
||||||
-H HEADER Send Header (i.E. "AUTHORIZATION: Bearer 8*.UdUYwrl!nK")
|
|
||||||
-F FOLLOW Follow redirects (default: OFF)
|
|
||||||
-D DEBUG Only prints the curl command (default: OFF)
|
|
||||||
-P PROXY Set Proxy Address (default: No Proxy)
|
|
||||||
-K COOKIES Enables/Disabled cookie handling in a temporary cookie jar'''
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Check which threshold was reached
|
|
||||||
checkTime() {
|
|
||||||
if [ $1 -gt $critical ]; then
|
|
||||||
echo -n "CRITICAL: Slow "
|
|
||||||
elif [ $1 -gt $warning ]; then
|
|
||||||
echo -n "WARNING: Slow "
|
|
||||||
else
|
|
||||||
echo -n "OK"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Return code value
|
|
||||||
getStatus() {
|
|
||||||
if [ $1 -gt $critical ]; then
|
|
||||||
return 2
|
|
||||||
elif [ $1 -gt $warning ]; then
|
|
||||||
return 1
|
|
||||||
else
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
#main
|
|
||||||
#get options
|
|
||||||
while getopts "P:M:B:C:w:c:U:H:IFN:O:EL:D:K" opt; do
|
|
||||||
case $opt in
|
|
||||||
K)
|
|
||||||
cookies=1
|
|
||||||
;;
|
|
||||||
P)
|
|
||||||
proxy=$OPTARG
|
|
||||||
;;
|
|
||||||
M)
|
|
||||||
method=$OPTARG
|
|
||||||
;;
|
|
||||||
B)
|
|
||||||
body=$OPTARG
|
|
||||||
;;
|
|
||||||
C)
|
|
||||||
contains=$OPTARG
|
|
||||||
;;
|
|
||||||
w)
|
|
||||||
warning=$OPTARG
|
|
||||||
;;
|
|
||||||
c)
|
|
||||||
critical=$OPTARG
|
|
||||||
;;
|
|
||||||
U)
|
|
||||||
url=$OPTARG
|
|
||||||
;;
|
|
||||||
L)
|
|
||||||
lacks=$OPTARG
|
|
||||||
;;
|
|
||||||
I)
|
|
||||||
insecure=1
|
|
||||||
;;
|
|
||||||
N)
|
|
||||||
name=$( echo $OPTARG | sed -e 's/[^A-Za-z0-9._-]/_/g' )
|
|
||||||
;;
|
|
||||||
E)
|
|
||||||
encodeurl=1
|
|
||||||
;;
|
|
||||||
H)
|
|
||||||
header=$OPTARG
|
|
||||||
;;
|
|
||||||
F)
|
|
||||||
follow=1
|
|
||||||
;;
|
|
||||||
D)
|
|
||||||
debug=1
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
usage
|
|
||||||
exit 3
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
#hostname is required
|
|
||||||
if [ -z "$url" ] || [ $# -eq 0 ]; then
|
|
||||||
echo "Error: URL is required"
|
|
||||||
usage
|
|
||||||
exit 3
|
|
||||||
fi
|
|
||||||
|
|
||||||
proxyarg=""
|
|
||||||
if [ ! -z $proxy ] ; then
|
|
||||||
proxyarg=" -x "$proxy" "
|
|
||||||
fi
|
|
||||||
headerarg=""
|
|
||||||
if [ ! -z "$header" ] ; then
|
|
||||||
headerarg=' -H "'$header'" '
|
|
||||||
fi
|
|
||||||
followarg=""
|
|
||||||
if [ $follow -eq 1 ] ; then
|
|
||||||
followarg=" -L "
|
|
||||||
fi
|
|
||||||
insecurearg=""
|
|
||||||
if [ $insecure -eq 1 ] ; then
|
|
||||||
insecurearg=" --insecure "
|
|
||||||
fi
|
|
||||||
cookiesarg=""
|
|
||||||
if [ $cookies -eq 1 ] ; then
|
|
||||||
COOKIE_JAR_TEMP_PATH=$(mktemp /tmp/check_curl_cookiejar.XXXXXX)
|
|
||||||
cookiesarg=" -c ${COOKIE_JAR_TEMP_PATH} -b ${COOKIE_JAR_TEMP_PATH}"
|
|
||||||
fi
|
|
||||||
bodyarg=""
|
|
||||||
if [ ! -z $body ]; then
|
|
||||||
body=$(echo $body| sed "s/\"/\\\\\"/g")
|
|
||||||
bodyarg=" --data \""$body"\""
|
|
||||||
if [ $encodeurl -eq 1 ]; then
|
|
||||||
bodyarg=" --data-urlencode \""$body"\""
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ $debug -eq 1 ]; then
|
|
||||||
echo $curl --no-keepalive -s $insecurearg $proxyarg $followarg $bodyarg $headerarg -X $method $cookiesarg "$url"
|
|
||||||
exit 0
|
|
||||||
else
|
|
||||||
start=$(echo $(($(date +%s%N)/1000000)))
|
|
||||||
body=$(eval $curl --no-keepalive -s $insecurearg $proxyarg $followarg $bodyarg $headerarg -X $method $cookiesarg "$url")
|
|
||||||
status=$?
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ $cookies -eq 1 ] ; then
|
|
||||||
rm -f ${COOKIE_JAR_TEMP_PATH}
|
|
||||||
fi
|
|
||||||
|
|
||||||
end=$(echo $(($(date +%s%N)/1000000)))
|
|
||||||
#decide output by return code
|
|
||||||
if [ $status -eq 0 ] ; then
|
|
||||||
if [ -n "$contains" ]; then
|
|
||||||
if [[ ! $body =~ $contains ]]; then
|
|
||||||
echo "CRITICAL: body does not contain '${contains}'. Body: '$(echo $body | sed 's/\(.\{50\}\).*/\1.../')' |time=$((end - start))ms;${warning};${critical};0;"$critical"ms"
|
|
||||||
exit 2
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
if [ -n "$lacks" ]; then
|
|
||||||
if [[ $body == *$lacks* ]]; then
|
|
||||||
echo "CRITICAL: body contains '${lacks}'|time=$((end - start))ms;${warning};${critical};0;"$critical"ms"
|
|
||||||
exit 2
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
echo "$(checkTime $((end - start))) $((end - start))ms - ${url}|time=$((end - start))ms;${warning};${critical};0;"$critical"ms"
|
|
||||||
getStatus $((end - start))
|
|
||||||
exit $?
|
|
||||||
else
|
|
||||||
case $status in
|
|
||||||
1)
|
|
||||||
echo "CRITICAL: Unsupported protocol"
|
|
||||||
;;
|
|
||||||
3)
|
|
||||||
echo "CRITICAL: Malformed URL"
|
|
||||||
;;
|
|
||||||
5)
|
|
||||||
echo "CRITICAL: Couldn't resolve proxy $proxy"
|
|
||||||
;;
|
|
||||||
6)
|
|
||||||
echo "CRITICAL: Couldn't resolve host"
|
|
||||||
;;
|
|
||||||
7)
|
|
||||||
echo "CRITICAL: Couldn't connect to proxy $proxy"
|
|
||||||
;;
|
|
||||||
22)
|
|
||||||
echo "CRITICAL: Server returned http code >= 400"
|
|
||||||
;;
|
|
||||||
52)
|
|
||||||
echo "CRITICAL: Server returned empty response (52)"
|
|
||||||
;;
|
|
||||||
56)
|
|
||||||
echo "CRITICAL: Failure recieving network data (56)"
|
|
||||||
;;
|
|
||||||
60)
|
|
||||||
echo "CRITICAL: SSL/TLS connection problem (60)"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "UNKNOWN: $status - ${url}"
|
|
||||||
exit 3
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
exit 2
|
|
||||||
fi
|
|
||||||
|
|
|
@ -7,19 +7,11 @@ import traceback
|
||||||
import hurry
|
import hurry
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import requests
|
import requests
|
||||||
from hurry.filesize import size
|
|
||||||
from urllib3.exceptions import InsecureRequestWarning
|
from urllib3.exceptions import InsecureRequestWarning
|
||||||
|
|
||||||
import checker.nagios as nagios
|
import checker.nagios as nagios
|
||||||
from checker.markdown import list_to_markdown_table
|
from checker.markdown import list_to_markdown_table
|
||||||
|
from checker.units import filesize
|
||||||
|
|
||||||
def filesize(bytes: int, spaces: bool = True):
|
|
||||||
x = size(bytes, system=hurry.filesize.alternative)
|
|
||||||
if spaces:
|
|
||||||
return x
|
|
||||||
else:
|
|
||||||
return x.replace(' ', '')
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
@ -28,7 +20,7 @@ def main():
|
||||||
parser.add_argument('--key', required=True, help='OPNsense API key.')
|
parser.add_argument('--key', required=True, help='OPNsense API key.')
|
||||||
parser.add_argument('--secret', required=True, help='OPNsense API secret.')
|
parser.add_argument('--secret', required=True, help='OPNsense API secret.')
|
||||||
parser.add_argument('--interface', required=True, help='Interface to check (e.g., lan). Can be something like "lan,wan"')
|
parser.add_argument('--interface', required=True, help='Interface to check (e.g., lan). Can be something like "lan,wan"')
|
||||||
parser.add_argument('--host', required=True, help='IP of the host to check.')
|
parser.add_argument('--host', required=True, help='Address of the host to check.')
|
||||||
parser.add_argument('--duration', default=10, type=int, help='How many seconds to gather statistics.')
|
parser.add_argument('--duration', default=10, type=int, help='How many seconds to gather statistics.')
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
@ -39,7 +31,7 @@ def main():
|
||||||
|
|
||||||
# Map interface names to their internal names
|
# Map interface names to their internal names
|
||||||
interfaces_mapping = requests.get(f'https://{args.opnsense}/api/diagnostics/traffic/interface',
|
interfaces_mapping = requests.get(f'https://{args.opnsense}/api/diagnostics/traffic/interface',
|
||||||
headers={'Accept': 'application/json'}, auth=(args.key, args.secret), verify=False)
|
headers={'Accept': 'application/json'}, auth=(args.key, args.secret), verify=False, timeout=10)
|
||||||
if interfaces_mapping.status_code != 200:
|
if interfaces_mapping.status_code != 200:
|
||||||
print(f'UNKNOWN: unable to query OPNsense API for interface mappings: {interfaces_mapping.status_code}\n{interfaces_mapping.text}')
|
print(f'UNKNOWN: unable to query OPNsense API for interface mappings: {interfaces_mapping.status_code}\n{interfaces_mapping.text}')
|
||||||
sys.exit(nagios.UNKNOWN)
|
sys.exit(nagios.UNKNOWN)
|
||||||
|
@ -60,7 +52,7 @@ def main():
|
||||||
traffic_data = []
|
traffic_data = []
|
||||||
for _ in range(args.duration):
|
for _ in range(args.duration):
|
||||||
response = requests.get(f'https://{args.opnsense}/api/diagnostics/traffic/top/{interface}',
|
response = requests.get(f'https://{args.opnsense}/api/diagnostics/traffic/top/{interface}',
|
||||||
headers={'Accept': 'application/json'}, auth=(args.key, args.secret), verify=False)
|
headers={'Accept': 'application/json'}, auth=(args.key, args.secret), verify=False, timeout=10)
|
||||||
if response.status_code != 200:
|
if response.status_code != 200:
|
||||||
print(f'UNKNOWN: unable to query OPNsense API for {interface}: {response.status_code}\n{response.text}')
|
print(f'UNKNOWN: unable to query OPNsense API for {interface}: {response.status_code}\n{response.text}')
|
||||||
sys.exit(nagios.UNKNOWN)
|
sys.exit(nagios.UNKNOWN)
|
||||||
|
@ -70,7 +62,7 @@ def main():
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
|
||||||
if not len(traffic_data):
|
if not len(traffic_data):
|
||||||
print(f'UNKNOWN: Interface {args.interface} not found in OPNsense API response.')
|
print('UNKNOWN: Interface or host not found in OPNsense API response.')
|
||||||
sys.exit(nagios.UNKNOWN)
|
sys.exit(nagios.UNKNOWN)
|
||||||
|
|
||||||
check_result[name] = {
|
check_result[name] = {
|
||||||
|
@ -92,7 +84,6 @@ def main():
|
||||||
ok = []
|
ok = []
|
||||||
perf_data = []
|
perf_data = []
|
||||||
|
|
||||||
output_table = [('Interface', 'Rate In', 'Rate Out', 'Cumulative In', 'Cumulative Out', 'Connections', 'Status')]
|
|
||||||
for name, data in check_result.items():
|
for name, data in check_result.items():
|
||||||
# TODO: figure out status
|
# TODO: figure out status
|
||||||
if -1 >= crit_value:
|
if -1 >= crit_value:
|
||||||
|
@ -107,14 +98,16 @@ def main():
|
||||||
ok.append(name)
|
ok.append(name)
|
||||||
status = '[OK]'
|
status = '[OK]'
|
||||||
|
|
||||||
perf_data.append(f'{name}-rate_in={filesize(data["rate_in"], spaces=False)};{warn_value};{crit_value};')
|
perf_data.append(f'{name}-rate_in={filesize(data["rate_in"], spaces=False)};{warn_value};{crit_value};0')
|
||||||
perf_data.append(f'{name}-rate_out={filesize(data["rate_out"], spaces=False)};{warn_value};{crit_value};')
|
perf_data.append(f'{name}-rate_out={filesize(data["rate_out"], spaces=False)};{warn_value};{crit_value};0')
|
||||||
perf_data.append(f'{name}-cumulative_in={filesize(data["cumulative_in"], spaces=False)};{warn_value};{crit_value};')
|
perf_data.append(f'{name}-cumulative_in={filesize(data["cumulative_in"], spaces=False)};{warn_value};{crit_value};0')
|
||||||
perf_data.append(f'{name}-cumulative_out={filesize(data["cumulative_out"], spaces=False)};{warn_value};{crit_value};')
|
perf_data.append(f'{name}-cumulative_out={filesize(data["cumulative_out"], spaces=False)};{warn_value};{crit_value};0')
|
||||||
perf_data.append(f'{name}-connections={data["connections"]};{warn_value};{crit_value};')
|
perf_data.append(f'{name}-connections={data["connections"]};{warn_value};{crit_value};0')
|
||||||
|
|
||||||
output_table.append((name, filesize(data['rate_in']), filesize(data['rate_out']), filesize(data['cumulative_in']), filesize(data['cumulative_out']),
|
output_table = [
|
||||||
data['connections'], status))
|
('Host', 'Interface', 'Rate In', 'Rate Out', 'Cumulative In', 'Cumulative Out', 'Connections', 'Status'),
|
||||||
|
(args.host, name, filesize(data['rate_in']), filesize(data['rate_out']), filesize(data['cumulative_in']), filesize(data['cumulative_out']), data['connections'], status)
|
||||||
|
]
|
||||||
print(list_to_markdown_table(output_table, align='left', seperator='!', borders=False))
|
print(list_to_markdown_table(output_table, align='left', seperator='!', borders=False))
|
||||||
|
|
||||||
print(f' |{" ".join(perf_data)}')
|
print(f' |{" ".join(perf_data)}')
|
||||||
|
|
|
@ -0,0 +1,169 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
import argparse
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import traceback
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import certifi
|
||||||
|
import numpy as np
|
||||||
|
import requests
|
||||||
|
|
||||||
|
import checker.nagios as nagios
|
||||||
|
from checker.markdown import list_to_markdown_table
|
||||||
|
from checker.units import filesize
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description='Check the Proxmox API for network traffic for a host.')
|
||||||
|
parser.add_argument('--node', required=True, help='The name and address of Proxmox node in valid JSON in this format: ["bigserver", "192.168.1.222"]. This allows you to use datalists in Director.')
|
||||||
|
parser.add_argument('--user', required=True, help='The Proxmox user. Something like "monitoring@pve!icinga2"')
|
||||||
|
parser.add_argument('--password', required=True, help='Password.')
|
||||||
|
parser.add_argument('--host', required=True, help='The ID of the host to check.')
|
||||||
|
parser.add_argument('--type', required=True, choices=['qemu', 'lxc'], help='Type of host. "qemu" or "lxc"')
|
||||||
|
parser.add_argument('--metrics', required=True, help='What stats to check. Can list multiple seperated by commas. For example, "netin,netout"')
|
||||||
|
parser.add_argument('--levels', required=True, help='Warning levels. In JSON format: {"netin":{"warn":50, "crit":100, "type": "filesize"}, "netout":{"warn":50, "crit":100, "type": "filesize"}}')
|
||||||
|
parser.add_argument('--timeframe', default=5, help='Timeframe to average the data to in minutes. Default: 5 minutes')
|
||||||
|
parser.add_argument('--verify', default=True, help="What to verify the SSL connection with. Can be a file path, or false to disable verification. If you're having issues with CA certs, try setting it to your system's CA bundle (/etc/ssl/certs/ca-certificates.crt).")
|
||||||
|
parser.add_argument('--verify-force', action='store_true', help="Delete the certifi cert and replace it with whatever you specify in --verify")
|
||||||
|
parser.add_argument('--table', action='store_true', help='Print the results in a table.')
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
# def where():
|
||||||
|
# return args.verify
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
if args.verify_force:
|
||||||
|
if not args.verify:
|
||||||
|
print('UNKNOWN: must supply --verify when using --verify-force')
|
||||||
|
sys.exit(nagios.UNKNOWN)
|
||||||
|
if Path(certifi.where()).exists():
|
||||||
|
os.remove(certifi.where())
|
||||||
|
os.symlink(args.verify, certifi.where())
|
||||||
|
print(f'Pointed {certifi.where()} to {args.verify}')
|
||||||
|
if Path(requests.certs.where()).exists():
|
||||||
|
os.remove(requests.certs.where())
|
||||||
|
os.symlink(args.verify, requests.certs.where())
|
||||||
|
print(f'Pointed {requests.certs.where()} to {args.verify}')
|
||||||
|
|
||||||
|
try:
|
||||||
|
metrics_levels = json.loads(args.levels)
|
||||||
|
except Exception as e:
|
||||||
|
print('UNKNOWN: Failed to parse --levels JSON:', e)
|
||||||
|
sys.exit(nagios.UNKNOWN)
|
||||||
|
|
||||||
|
try:
|
||||||
|
args.node = json.loads(args.node)
|
||||||
|
pve_node = args.node[0]
|
||||||
|
pve_node_address = args.node[1]
|
||||||
|
except Exception as e:
|
||||||
|
print('UNKNOWN: Failed to parse --node JSON:', e)
|
||||||
|
sys.exit(nagios.UNKNOWN)
|
||||||
|
|
||||||
|
# requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)
|
||||||
|
try:
|
||||||
|
pve_auth_ticket = requests.post(f'https://{pve_node_address}:8006/api2/json/access/ticket', data={"username": args.user, "password": args.password}).json()['data']['ticket']
|
||||||
|
response = requests.get(f'https://{pve_node_address}:8006/api2/json/nodes/{pve_node}/{args.type}/{args.host}/rrddata?timeframe=hour',
|
||||||
|
# headers={"Authorization": f'PVEAPIToken={args.user}={args.token}'},
|
||||||
|
cookies={'PVEAuthCookie': pve_auth_ticket},
|
||||||
|
verify=args.verify)
|
||||||
|
except requests.exceptions.SSLError as e:
|
||||||
|
print('UNSKNOWN: SSL error ', e)
|
||||||
|
print('Using cert:', args.verify)
|
||||||
|
print('certifi using cert:', certifi.where())
|
||||||
|
print('requests using cert:', requests.certs.where())
|
||||||
|
sys.exit(nagios.UNKNOWN)
|
||||||
|
|
||||||
|
try:
|
||||||
|
api_data = json.loads(response.text)['data']
|
||||||
|
except Exception as e:
|
||||||
|
print(f'UNKNOWN: Failed to parse JSON {e}')
|
||||||
|
print(response.text)
|
||||||
|
sys.exit(nagios.UNKNOWN)
|
||||||
|
|
||||||
|
# Load the data
|
||||||
|
metrics_data = {}
|
||||||
|
for item in args.metrics.split(','):
|
||||||
|
if item not in metrics_levels.keys():
|
||||||
|
print(f'UNKNOWN: missing metric "{item}" in --levels')
|
||||||
|
sys.exit(nagios.UNKNOWN)
|
||||||
|
if 'warn' not in metrics_levels[item].keys():
|
||||||
|
print(f'UNKNOWN: missing key "warn" for metric "{item}" in --levels')
|
||||||
|
sys.exit(nagios.UNKNOWN)
|
||||||
|
if 'crit' not in metrics_levels[item].keys():
|
||||||
|
print(f'UNKNOWN: missing key "crit" for metric "{item}" in --levels')
|
||||||
|
sys.exit(nagios.UNKNOWN)
|
||||||
|
if 'type' not in metrics_levels[item].keys():
|
||||||
|
print(f'UNKNOWN: missing key "type" for metric "{item}" in --levels')
|
||||||
|
sys.exit(nagios.UNKNOWN)
|
||||||
|
|
||||||
|
metrics_data[item] = []
|
||||||
|
for m in api_data:
|
||||||
|
for k, v in m.items():
|
||||||
|
if k == item:
|
||||||
|
if isinstance(v, float):
|
||||||
|
v = np.round(v, 2)
|
||||||
|
metrics_data[item].append(v)
|
||||||
|
|
||||||
|
check_data = {}
|
||||||
|
exit_code = nagios.OK
|
||||||
|
for metric, value in metrics_data.items():
|
||||||
|
check_data[metric] = {}
|
||||||
|
# Average the data. Expects the interval to be 1 minute
|
||||||
|
avg = np.round(np.average(value[-5:-1]), 2)
|
||||||
|
check_data[metric]['value'] = avg
|
||||||
|
|
||||||
|
if metrics_levels[metric]['type'] == 'filesize':
|
||||||
|
check_data[metric]['value_str'] = filesize(avg)
|
||||||
|
else:
|
||||||
|
check_data[metric]['value_str'] = str(avg)
|
||||||
|
|
||||||
|
if avg >= metrics_levels[metric]['crit']:
|
||||||
|
check_data[metric]['status'] = nagios.CRITICAL
|
||||||
|
check_data[metric]['status_str'] = '[CRITICAL]'
|
||||||
|
elif avg >= metrics_levels[metric]['warn']:
|
||||||
|
check_data[metric]['status'] = nagios.WARN
|
||||||
|
check_data[metric]['status_str'] = '[WARNING]'
|
||||||
|
else:
|
||||||
|
check_data[metric]['status'] = nagios.OK
|
||||||
|
check_data[metric]['status_str'] = '[OK]'
|
||||||
|
|
||||||
|
if exit_code < check_data[metric]['status']:
|
||||||
|
exit_code = check_data[metric]['status']
|
||||||
|
|
||||||
|
if exit_code == nagios.OK:
|
||||||
|
output_str = 'OK: '
|
||||||
|
elif exit_code == nagios.WARNING:
|
||||||
|
output_str = 'WARNING: '
|
||||||
|
elif exit_code == nagios.CRITICAL:
|
||||||
|
output_str = 'CRITICAL: '
|
||||||
|
|
||||||
|
perf_data = []
|
||||||
|
for metric, data in check_data.items():
|
||||||
|
output_str = output_str + f"{metric} {data['value_str']}, "
|
||||||
|
perf_data.append(f"{metric}={data['value_str'].replace(' ', '')};{metrics_levels[metric]['warn']};{metrics_levels[metric]['crit']};;")
|
||||||
|
|
||||||
|
print(output_str.strip(', ').strip(), end=('\n' if args.table else ''))
|
||||||
|
|
||||||
|
perf_data_str = f'|{" ".join(perf_data)}'
|
||||||
|
|
||||||
|
if args.table:
|
||||||
|
output_table = [('Metric', 'Value', 'Status')]
|
||||||
|
for metric, data in check_data.items():
|
||||||
|
output_table.append((metric, data['value_str'], data['status_str']))
|
||||||
|
print(list_to_markdown_table(output_table, align='left', seperator='!', borders=False))
|
||||||
|
# else:
|
||||||
|
# perf_data_str = ' ' + perf_data_str
|
||||||
|
|
||||||
|
print(perf_data_str)
|
||||||
|
sys.exit(exit_code)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
try:
|
||||||
|
main()
|
||||||
|
except Exception as e:
|
||||||
|
print(f'UNKNOWN: exception "{e}"')
|
||||||
|
print(traceback.format_exc())
|
||||||
|
sys.exit(nagios.UNKNOWN)
|
|
@ -0,0 +1,16 @@
|
||||||
|
from hurry.filesize import size
|
||||||
|
|
||||||
|
def filesize(bytes: int, spaces: bool = True):
|
||||||
|
system = [
|
||||||
|
(1024 ** 5, ' PB'),
|
||||||
|
(1024 ** 4, ' TB'),
|
||||||
|
(1024 ** 3, ' GB'),
|
||||||
|
(1024 ** 2, ' MB'),
|
||||||
|
(1024 ** 1, ' KB'),
|
||||||
|
(1024 ** 0, ' B'),
|
||||||
|
]
|
||||||
|
x = size(bytes, system=system)
|
||||||
|
if spaces:
|
||||||
|
return x
|
||||||
|
else:
|
||||||
|
return x.replace(' ', '')
|
71
install.sh
71
install.sh
|
@ -1,20 +1,75 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# apt update && apt install -y git && cd /opt && git -C /opt/icinga2-checks pull || git clone https://git.dp15.us/dpanzer/icinga2-checks.git /opt/icinga2-checks && bash /opt/icinga2-checks/install.sh
|
# apt update && apt install -y git && cd /opt && git -C /opt/icinga2-checks pull || git clone https://git.dp15.us/dpanzer/icinga2-checks.git /opt/icinga2-checks && bash /opt/icinga2-checks/install.sh
|
||||||
# 3 4 * * * /bin/bash /opt/icinga2-checks/install.sh
|
|
||||||
|
ln_existing() {
|
||||||
|
src=$1
|
||||||
|
dest=$2
|
||||||
|
if [[ -e "$dest" ]] || [[ -L "$dest" ]]; then
|
||||||
|
rm "$dest"
|
||||||
|
fi
|
||||||
|
ln -s "$src" "$dest"
|
||||||
|
}
|
||||||
|
|
||||||
apt update
|
apt update
|
||||||
apt install -y python3-venv git sysstat bc
|
apt install -y python3-venv git sysstat bc
|
||||||
|
pip install -U pip wheel setuptools
|
||||||
|
|
||||||
pip install psutil
|
mkdir -p /usr/lib64/nagios/plugins/
|
||||||
|
|
||||||
|
# Install global pip packages
|
||||||
|
#pip install psutil
|
||||||
|
|
||||||
git -C /opt/icinga2-checks pull || git clone https://git.dp15.us/dpanzer/icinga2-checks.git /opt/icinga2-checks
|
git -C /opt/icinga2-checks pull || git clone https://git.dp15.us/dpanzer/icinga2-checks.git /opt/icinga2-checks
|
||||||
|
|
||||||
rm /usr/lib64/nagios/plugins/check_iowait
|
mkdir -p /opt/venvs
|
||||||
ln -s /opt/icinga2-checks/check_iowait.sh /usr/lib64/nagios/plugins/check_iowait
|
|
||||||
|
|
||||||
rm /usr/lib64/nagios/plugins/check_bandwidth
|
if [[ ! -d /opt/venvs/icinga2_checks ]]; then
|
||||||
ln -s /opt/icinga2-checks/check_bandwidth /usr/lib64/nagios/plugins/check_bandwidth
|
echo "Creating venv in /opt/venvs/icinga2_checks"
|
||||||
|
python3 -m venv /opt/venvs/icinga2_checks
|
||||||
|
fi
|
||||||
|
if [[ ! -d /opt/venvs/check_pve ]]; then
|
||||||
|
echo "Creating venv in /opt/venvs/check_pve"
|
||||||
|
python3 -m venv /opt/venvs/check_pve
|
||||||
|
fi
|
||||||
|
|
||||||
rm /usr/lib64/nagios/plugins/check_curl
|
/opt/venvs/icinga2_checks/bin/pip install -U pip wheel setuptools
|
||||||
ln -s /opt/icinga2-checks/check_curl /usr/lib64/nagios/plugins/check_curl
|
/opt/venvs/icinga2_checks/bin/pip install -r /opt/icinga2-checks/requirements.txt
|
||||||
|
|
||||||
|
/opt/venvs/check_pve/bin/pip install -U pip wheel setuptools
|
||||||
|
/opt/venvs/check_pve/bin/pip install -r /opt/icinga2-checks/check_pve/requirements.txt
|
||||||
|
|
||||||
|
ln_existing /opt/icinga2-checks/check_iowait.sh /usr/lib64/nagios/plugins/check_iowait
|
||||||
|
ln_existing /opt/icinga2-checks/check_bandwidth.py /usr/lib64/nagios/plugins/check_bandwidth
|
||||||
|
ln_existing /opt/icinga2-checks/check_curl.sh /usr/lib64/nagios/plugins/check_curl
|
||||||
|
|
||||||
|
ln_existing /etc/ssl/certs/ca-certificates.crt /opt/venvs/icinga2_checks/lib/python3.10/site-packages/certifi/cacert.pem
|
||||||
|
|
||||||
|
# ==============================================================================
|
||||||
|
# Install the Linuxfabrik checks
|
||||||
|
|
||||||
|
if [[ ! -d /opt/linuxfabrik-monitoring-plugins ]]; then
|
||||||
|
git clone https://github.com/Linuxfabrik/monitoring-plugins.git /opt/linuxfabrik-monitoring-plugins
|
||||||
|
|
||||||
|
if [[ ! -d /opt/venvs/linuxfabrik ]]; then
|
||||||
|
echo "Creating venv in /opt/venvs/linuxfabrik"
|
||||||
|
python3 -m venv /opt/venvs/linuxfabrik
|
||||||
|
fi
|
||||||
|
|
||||||
|
/opt/venvs/linuxfabrik/bin/pip install psutil
|
||||||
|
|
||||||
|
cd /opt/linuxfabrik-monitoring-plugins
|
||||||
|
rm -rf lib
|
||||||
|
git clone https://github.com/Linuxfabrik/lib.git
|
||||||
|
/opt/venvs/linuxfabrik/bin/pip install bs4 psutil smbprotocol vici pymysql
|
||||||
|
fi
|
||||||
|
|
||||||
|
ln_existing /opt/linuxfabrik-monitoring-plugins/check-plugins/disk-io/disk-io3 /usr/lib64/nagios/plugins/disk-io
|
||||||
|
ln_existing /opt/linuxfabrik-monitoring-plugins/check-plugins/cpu-usage/cpu-usage3 /usr/lib64/nagios/plugins/cpu-usage
|
||||||
|
ln_existing /opt/linuxfabrik-monitoring-plugins/check-plugins/disk-usage/disk-usage3 /usr/lib64/nagios/plugins/disk-usage
|
||||||
|
ln_existing /opt/linuxfabrik-monitoring-plugins/check-plugins/memory-usage/memory-usage3 /usr/lib64/nagios/plugins/memory-usage
|
||||||
|
ln_existing /opt/linuxfabrik-monitoring-plugins/check-plugins/ping/ping3 /usr/lib64/nagios/plugins/ping
|
||||||
|
ln_existing /opt/linuxfabrik-monitoring-plugins/check-plugins/disk-smart/disk-smart3 /usr/lib64/nagios/plugins/disk-smart
|
||||||
|
|
||||||
|
setcap cap_net_raw+ep /usr/lib/nagios/plugins/check_icmp
|
||||||
|
setcap cap_net_raw+ep /usr/lib/nagios/plugins/check_ping
|
|
@ -13,3 +13,4 @@ aiofiles~=0.6.0
|
||||||
markdown~=3.4.1
|
markdown~=3.4.1
|
||||||
psutil~=5.9.4
|
psutil~=5.9.4
|
||||||
hurry.filesize
|
hurry.filesize
|
||||||
|
certifi
|
Loading…
Reference in New Issue