improve check_curl, use common HTTP function on py
This commit is contained in:
parent
2ca897f0a0
commit
792838d50d
443
check_curl.sh
443
check_curl.sh
|
@ -1,185 +1,382 @@
|
||||||
#!/usr/bin/env bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Define the usage message
|
# Default values
|
||||||
usage() {
|
WARN_TIME=1
|
||||||
echo "Usage: $0 -u <url> [-w <warning>] [-c <critical>] [-C <contains>] [-L] [-I] [-H <headers>] [-p] [-R] [-s]"
|
CRIT_TIME=2
|
||||||
echo "[Arguments]:
|
FOLLOW_REDIRECTS=""
|
||||||
-u Specify the URL to check (required).
|
INSECURE=""
|
||||||
-w Set the warn level for response time (default: 1 second).
|
HEADERS=""
|
||||||
-c Set the critical level for response time (default: 2 seconds).
|
PRINT_CURL=""
|
||||||
-C If the body does not contain this string, return CRITICAL.
|
RESOLVE=""
|
||||||
-L Follow redirects.
|
IGNORE_STATUS=""
|
||||||
-I Insecure mode (--insecure).
|
TIMEOUT=""
|
||||||
-H Specify headers. Formatted like \"Header1: value,Header2: value\"
|
|
||||||
-p Print the curl command and exit
|
|
||||||
-R Set curl --resolve option.
|
|
||||||
-s Ignore the response status code."
|
|
||||||
exit 3
|
|
||||||
}
|
|
||||||
|
|
||||||
# Parse the command-line arguments
|
# Parse arguments
|
||||||
while getopts "u:w:c:C:H:R:LhIps" opt; do
|
while getopts "u:w:c:C:LH:IpR:st:" opt; do
|
||||||
case $opt in
|
case $opt in
|
||||||
u)
|
u)
|
||||||
URL=$OPTARG
|
URL="$OPTARG"
|
||||||
;;
|
;;
|
||||||
w)
|
w)
|
||||||
WARNING_LEVEL=$OPTARG
|
WARN_TIME="$OPTARG"
|
||||||
;;
|
;;
|
||||||
c)
|
c)
|
||||||
CRITICAL_LEVEL=$OPTARG
|
CRIT_TIME="$OPTARG"
|
||||||
;;
|
|
||||||
L)
|
|
||||||
FOLLOW_REDIRECTS="-L"
|
|
||||||
;;
|
;;
|
||||||
C)
|
C)
|
||||||
CONTAINS=$OPTARG
|
CRIT_STRING="$OPTARG"
|
||||||
|
;;
|
||||||
|
L)
|
||||||
|
FOLLOW_REDIRECTS="--location"
|
||||||
;;
|
;;
|
||||||
I)
|
I)
|
||||||
INSECURE="--insecure"
|
INSECURE="--insecure"
|
||||||
;;
|
;;
|
||||||
H)
|
H)
|
||||||
HEADERS=$OPTARG
|
HEADERS="--header $OPTARG"
|
||||||
;;
|
;;
|
||||||
p)
|
p)
|
||||||
PRINT_ONLY=true
|
PRINT_CURL="yes"
|
||||||
;;
|
;;
|
||||||
R)
|
R)
|
||||||
RESOLVE="--resolve $OPTARG"
|
RESOLVE="--resolve $OPTARG"
|
||||||
;;
|
;;
|
||||||
s)
|
s)
|
||||||
IGNORE_STATUS_CODE=true
|
IGNORE_STATUS="yes"
|
||||||
;;
|
;;
|
||||||
h)
|
t)
|
||||||
usage
|
TIMEOUT="--max-time $OPTARG"
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
usage
|
echo "Invalid option: -$OPTARG" >&2
|
||||||
|
exit 3
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
WARNING_LEVEL=${WARNING_LEVEL:-1}
|
# Check if URL is provided
|
||||||
CRITICAL_LEVEL=${CRITICAL_LEVEL:-2}
|
|
||||||
#FOLLOW_REDIRECTS=${FOLLOW_REDIRECTS:-""}
|
|
||||||
PRINT_ONLY=${PRINT_ONLY:-false}
|
|
||||||
IGNORE_STATUS_CODE=${IGNORE_STATUS_CODE:-false}
|
|
||||||
|
|
||||||
if [ -z "$URL" ]; then
|
if [ -z "$URL" ]; then
|
||||||
usage
|
echo "Usage: $0 -u URL [options]"
|
||||||
fi
|
|
||||||
|
|
||||||
HEADER_ARGS=""
|
|
||||||
IFS=',' read -ra values <<<"$HEADERS"
|
|
||||||
for value in "${values[@]}"; do
|
|
||||||
HEADER_ARGS+=' -H "'$value'" '
|
|
||||||
done
|
|
||||||
|
|
||||||
TMP_ERROR_LOG=$(mktemp)
|
|
||||||
TMP_RESPONSE=$(mktemp)
|
|
||||||
|
|
||||||
if $PRINT_ONLY; then
|
|
||||||
printf "%s" "curl --output \"$TMP_RESPONSE\" -s -w \"%{http_code}\n%{time_total}\" $(echo "${HEADER_ARGS[@]}" | tr -s ' ') $FOLLOW_REDIRECTS $INSECURE $RESOLVE $URL\n"
|
|
||||||
exit 3
|
exit 3
|
||||||
fi
|
fi
|
||||||
|
|
||||||
RESPONSE=$(curl --output "$TMP_RESPONSE" -w "%{http_code}\n%{time_total}" $(echo "${HEADER_ARGS[@]}" | tr -s ' ') $FOLLOW_REDIRECTS $INSECURE $RESOLVE $URL 2>"$TMP_ERROR_LOG")
|
# Prepare curl command
|
||||||
|
CURL_CMD="curl -w %{http_code};%{time_total} -o /dev/null -s $FOLLOW_REDIRECTS $INSECURE $HEADERS $RESOLVE $TIMEOUT $URL"
|
||||||
|
|
||||||
# shellcheck disable=SC2181
|
# Print curl command if requested
|
||||||
status=$?
|
if [ "$PRINT_CURL" = "yes" ]; then
|
||||||
if [ $status -ne 0 ]; then
|
echo "$CURL_CMD"
|
||||||
case $status in
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Execute curl command
|
||||||
|
CURL_OUTPUT=$($CURL_CMD)
|
||||||
|
CURL_EXIT=$?
|
||||||
|
|
||||||
|
# Parse curl output
|
||||||
|
HTTP_CODE=$(echo "$CURL_OUTPUT" | cut -d ';' -f 1)
|
||||||
|
RESPONSE_TIME=$(echo "$CURL_OUTPUT" | cut -d ';' -f 2)
|
||||||
|
|
||||||
|
# Check curl exit status
|
||||||
|
if [ $CURL_EXIT -ne 0 ]; then
|
||||||
|
case $CURL_EXIT in
|
||||||
1)
|
1)
|
||||||
msg="CRITICAL: Unsupported protocol"
|
msg="CRITICAL - Unsupported protocol"
|
||||||
|
;;
|
||||||
|
2)
|
||||||
|
msg="CRITICAL - Failed to initialize"
|
||||||
;;
|
;;
|
||||||
3)
|
3)
|
||||||
msg="CRITICAL: Malformed URL $URL"
|
msg="CRITICAL - Malformed URL"
|
||||||
|
;;
|
||||||
|
4)
|
||||||
|
msg="CRITICAL - Feature or option not enabled"
|
||||||
|
;;
|
||||||
|
5)
|
||||||
|
msg="CRITICAL - Couldn't resolve proxy"
|
||||||
;;
|
;;
|
||||||
# 5)
|
|
||||||
# msg="CRITICAL: Could not resolve proxy $proxy"
|
|
||||||
# ;;
|
|
||||||
6)
|
6)
|
||||||
msg="CRITICAL: Could not resolve host $URL"
|
msg="CRITICAL - Could not resolve host"
|
||||||
;;
|
;;
|
||||||
7)
|
7)
|
||||||
msg="CRITICAL: Could not connect to host (7)"
|
msg="CRITICAL - Could not connect to host"
|
||||||
|
;;
|
||||||
|
8)
|
||||||
|
msg="CRITICAL - Unknown FTP server response"
|
||||||
|
;;
|
||||||
|
9)
|
||||||
|
msg="CRITICAL - FTP access denied"
|
||||||
|
;;
|
||||||
|
10)
|
||||||
|
msg="CRITICAL - FTP accept failed"
|
||||||
|
;;
|
||||||
|
11)
|
||||||
|
msg="CRITICAL - FTP weird PASS reply"
|
||||||
|
;;
|
||||||
|
12)
|
||||||
|
msg="CRITICAL - FTP timeout during active session"
|
||||||
|
;;
|
||||||
|
13)
|
||||||
|
msg="CRITICAL - Unknown response to FTP PASV command"
|
||||||
|
;;
|
||||||
|
14)
|
||||||
|
msg="CRITICAL - Unknown FTP 227 format"
|
||||||
|
;;
|
||||||
|
15)
|
||||||
|
msg="CRITICAL - FTP cannot get host"
|
||||||
|
;;
|
||||||
|
16)
|
||||||
|
msg="CRITICAL - HTTP/2 error"
|
||||||
|
;;
|
||||||
|
17)
|
||||||
|
msg="CRITICAL - FTP could not set binary"
|
||||||
|
;;
|
||||||
|
18)
|
||||||
|
msg="CRITICAL - Partial file"
|
||||||
|
;;
|
||||||
|
19)
|
||||||
|
msg="CRITICAL - FTP could not download/access the given file"
|
||||||
|
;;
|
||||||
|
# Skipping 20 as it is not used
|
||||||
|
21)
|
||||||
|
msg="CRITICAL - Quote error"
|
||||||
;;
|
;;
|
||||||
22)
|
22)
|
||||||
msg="CRITICAL: Server returned http code >= 400"
|
msg="CRITICAL - Server returned http code >= 400"
|
||||||
|
;;
|
||||||
|
23)
|
||||||
|
msg="CRITICAL - Write error"
|
||||||
|
;;
|
||||||
|
# Skipping 24 as it is not used
|
||||||
|
25)
|
||||||
|
msg="CRITICAL - Upload failed"
|
||||||
|
;;
|
||||||
|
26)
|
||||||
|
msg="CRITICAL - Read error"
|
||||||
|
;;
|
||||||
|
27)
|
||||||
|
msg="CRITICAL - Out of memory"
|
||||||
|
;;
|
||||||
|
28)
|
||||||
|
msg="CRITICAL - Operation timeout"
|
||||||
|
;;
|
||||||
|
# Skipping 29 and 30 as they are not used
|
||||||
|
31)
|
||||||
|
msg="CRITICAL - FTP could not use REST"
|
||||||
|
;;
|
||||||
|
# Skipping 32 as it is not used
|
||||||
|
33)
|
||||||
|
msg="CRITICAL - HTTP range error"
|
||||||
|
;;
|
||||||
|
34)
|
||||||
|
msg="CRITICAL - HTTP post error"
|
||||||
|
;;
|
||||||
|
35)
|
||||||
|
msg="CRITICAL - A TLS/SSL connect error"
|
||||||
|
;;
|
||||||
|
36)
|
||||||
|
msg="CRITICAL - Bad download resume"
|
||||||
|
;;
|
||||||
|
37)
|
||||||
|
msg="CRITICAL - Couldn't read the given file when using the FILE:// scheme"
|
||||||
|
;;
|
||||||
|
38)
|
||||||
|
msg="CRITICAL - LDAP cannot bind"
|
||||||
|
;;
|
||||||
|
39)
|
||||||
|
msg="CRITICAL - LDAP search failed"
|
||||||
|
;;
|
||||||
|
# Skipping 40 and 41 as they are not used
|
||||||
|
42)
|
||||||
|
msg="CRITICAL - Aborted by callback"
|
||||||
|
;;
|
||||||
|
43)
|
||||||
|
msg="CRITICAL - Bad function argument"
|
||||||
|
;;
|
||||||
|
# Skipping 44 as it is not used
|
||||||
|
45)
|
||||||
|
msg="CRITICAL - Interface error"
|
||||||
|
;;
|
||||||
|
# Skipping 46 as it is not used
|
||||||
|
47)
|
||||||
|
msg="CRITICAL - Too many redirects"
|
||||||
|
;;
|
||||||
|
48)
|
||||||
|
msg="CRITICAL - Unknown option specified to libcurl"
|
||||||
|
;;
|
||||||
|
49)
|
||||||
|
msg="CRITICAL - Malformed telnet option"
|
||||||
|
;;
|
||||||
|
# Skipping 50 as it is not used
|
||||||
|
51)
|
||||||
|
msg="CRITICAL - The server's SSL/TLS certificate or SSH fingerprint failed verification"
|
||||||
;;
|
;;
|
||||||
52)
|
52)
|
||||||
msg="CRITICAL: Server returned empty response (52)"
|
msg="CRITICAL - Server returned empty response"
|
||||||
|
;;
|
||||||
|
53)
|
||||||
|
msg="CRITICAL - SSL crypto engine not found"
|
||||||
|
;;
|
||||||
|
54)
|
||||||
|
msg="CRITICAL - Cannot set SSL crypto engine as default"
|
||||||
|
;;
|
||||||
|
55)
|
||||||
|
msg="CRITICAL - Failed sending network data"
|
||||||
;;
|
;;
|
||||||
56)
|
56)
|
||||||
msg="CRITICAL: Failure recieving network data (56)"
|
msg="CRITICAL - Failure receiving network data"
|
||||||
|
;;
|
||||||
|
# Skipping 57 as it is not used
|
||||||
|
58)
|
||||||
|
msg="CRITICAL - Problem with the local certificate"
|
||||||
|
;;
|
||||||
|
59)
|
||||||
|
msg="CRITICAL - Couldn't use the specified SSL cipher"
|
||||||
;;
|
;;
|
||||||
60)
|
60)
|
||||||
msg="CRITICAL: SSL/TLS connection problem (60)"
|
msg="CRITICAL - SSL/TLS connection problem"
|
||||||
|
;;
|
||||||
|
61)
|
||||||
|
msg="CRITICAL - Unrecognized transfer encoding"
|
||||||
|
;;
|
||||||
|
# Skipping 62 as it is not used
|
||||||
|
63)
|
||||||
|
msg="CRITICAL - Maximum file size exceeded"
|
||||||
|
;;
|
||||||
|
64)
|
||||||
|
msg="CRITICAL - Requested SSL (TLS) level failed"
|
||||||
|
;;
|
||||||
|
65)
|
||||||
|
msg="CRITICAL - Sending the data requires a rewind that failed"
|
||||||
|
;;
|
||||||
|
66)
|
||||||
|
msg="CRITICAL - Failed to initialize the OpenSSL SSL Engine"
|
||||||
|
;;
|
||||||
|
67)
|
||||||
|
msg="CRITICAL - The user name, password, or similar was not accepted and curl failed to log in"
|
||||||
|
;;
|
||||||
|
68)
|
||||||
|
msg="CRITICAL - File not found on TFTP server"
|
||||||
|
;;
|
||||||
|
69)
|
||||||
|
msg="CRITICAL - Permission problem on TFTP server"
|
||||||
|
;;
|
||||||
|
70)
|
||||||
|
msg="CRITICAL - Out of disk space on TFTP server"
|
||||||
|
;;
|
||||||
|
71)
|
||||||
|
msg="CRITICAL - Illegal TFTP operation"
|
||||||
|
;;
|
||||||
|
72)
|
||||||
|
msg="CRITICAL - Unknown TFTP transfer ID"
|
||||||
|
;;
|
||||||
|
73)
|
||||||
|
msg="CRITICAL - File already exists (TFTP)"
|
||||||
|
;;
|
||||||
|
74)
|
||||||
|
msg="CRITICAL - No such user (TFTP)"
|
||||||
|
;;
|
||||||
|
# Skipping 75 and 76 as they are not used
|
||||||
|
77)
|
||||||
|
msg="CRITICAL - Problem with reading the SSL CA cert"
|
||||||
|
;;
|
||||||
|
78)
|
||||||
|
msg="CRITICAL - The resource (file) referenced in the URL does not exist"
|
||||||
|
;;
|
||||||
|
79)
|
||||||
|
msg="CRITICAL - An unspecified error occurred during the SSH session"
|
||||||
|
;;
|
||||||
|
80)
|
||||||
|
msg="CRITICAL - Failed to shut down the SSL connection"
|
||||||
|
;;
|
||||||
|
# Skipping 81 as it is not used
|
||||||
|
82)
|
||||||
|
msg="CRITICAL - Could not load CRL file, missing or wrong format"
|
||||||
|
;;
|
||||||
|
83)
|
||||||
|
msg="CRITICAL - TLS certificate issuer check failed"
|
||||||
|
;;
|
||||||
|
84)
|
||||||
|
msg="CRITICAL - The FTP PRET command failed"
|
||||||
|
;;
|
||||||
|
85)
|
||||||
|
msg="CRITICAL - RTSP, mismatch of CSeq numbers"
|
||||||
|
;;
|
||||||
|
86)
|
||||||
|
msg="CRITICAL - RTSP, mismatch of Session Identifiers"
|
||||||
|
;;
|
||||||
|
87)
|
||||||
|
msg="CRITICAL - Unable to parse FTP file list"
|
||||||
|
;;
|
||||||
|
88)
|
||||||
|
msg="CRITICAL - FTP chunk callback reported error"
|
||||||
|
;;
|
||||||
|
89)
|
||||||
|
msg="CRITICAL - No connection available, the session will be queued"
|
||||||
|
;;
|
||||||
|
90)
|
||||||
|
msg="CRITICAL - SSL public key does not match pinned public key"
|
||||||
|
;;
|
||||||
|
91)
|
||||||
|
msg="CRITICAL - Invalid SSL certificate status"
|
||||||
|
;;
|
||||||
|
92)
|
||||||
|
msg="CRITICAL - Stream error in HTTP/2 framing layer"
|
||||||
|
;;
|
||||||
|
93)
|
||||||
|
msg="CRITICAL - An API function was called from inside a callback"
|
||||||
|
;;
|
||||||
|
94)
|
||||||
|
msg="CRITICAL - Authentication error"
|
||||||
|
;;
|
||||||
|
95)
|
||||||
|
msg="CRITICAL - HTTP/3 layer error"
|
||||||
|
;;
|
||||||
|
96)
|
||||||
|
msg="CRITICAL - QUIC connection error"
|
||||||
|
;;
|
||||||
|
97)
|
||||||
|
msg="CRITICAL - Proxy handshake error"
|
||||||
|
;;
|
||||||
|
98)
|
||||||
|
msg="CRITICAL - A TLS client certificate is required but was not provided"
|
||||||
|
;;
|
||||||
|
99)
|
||||||
|
msg="CRITICAL - An internal call to poll() or select() returned error that is not recoverable"
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo "UNKNOWN: $status - $URL"
|
echo "UNKNOWN - $CURL_EXIT -> $URL"
|
||||||
exit 3
|
exit 3
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
echo "$msg -> $URL"
|
||||||
echo -e "$msg"
|
|
||||||
# echo "Error log:"
|
|
||||||
# cat "$TMP_ERROR_LOG"
|
|
||||||
rm -rf "$TMP_ERROR_LOG"
|
|
||||||
exit 2
|
exit 2
|
||||||
fi
|
fi
|
||||||
rm -rf "$TMP_ERROR_LOG"
|
|
||||||
|
|
||||||
RESPONSE_CODE=$(echo "$RESPONSE" | head -n 1)
|
# Check HTTP code
|
||||||
RESPONSE_TIME=$(printf "%.3f" $(echo "$RESPONSE" | tail -n 1))
|
if [ "$IGNORE_STATUS" != "yes" ] && [ "$HTTP_CODE" -ne 200 ]; then
|
||||||
|
echo "CRITICAL - Server returned HTTP code $HTTP_CODE -> $URL"
|
||||||
OUTPUT_MSG=""
|
exit 2
|
||||||
OUTPUT_CODE=0
|
|
||||||
|
|
||||||
if ([ $RESPONSE_CODE -eq 200 ] || $IGNORE_STATUS_CODE) && [ "$(echo "$RESPONSE_TIME < $CRITICAL_LEVEL" | bc -l)" -eq 1 ]; then
|
|
||||||
OUTPUT_MSG="OK: ${RESPONSE_TIME}s - $URL"
|
|
||||||
OUTPUT_CODE=0
|
|
||||||
elif ([ $RESPONSE_CODE -eq 200 ] || $IGNORE_STATUS_CODE) && [ "$(echo "$RESPONSE_TIME < $WARNING_LEVEL" | bc -l)" -eq 1 ]; then
|
|
||||||
OUTPUT_MSG="WARNING: response time is slow ($RESPONSE_TIME seconds)."
|
|
||||||
OUTPUT_CODE=1
|
|
||||||
elif ([ $RESPONSE_CODE -eq 200 ] || $IGNORE_STATUS_CODE); then
|
|
||||||
OUTPUT_MSG"CRITICAL: response time is very slow ($RESPONSE_TIME seconds)."
|
|
||||||
OUTPUT_CODE=2
|
|
||||||
else
|
|
||||||
OUTPUT_MSG="CRITICAL: website did not return 200, response was $RESPONSE_CODE code."
|
|
||||||
OUTPUT_CODE=2
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -n ${CONTAINS+x} ]]; then
|
# Check response time
|
||||||
if ! grep -q "$CONTAINS" "$TMP_RESPONSE"; then
|
if [ $(echo "$RESPONSE_TIME > $CRIT_TIME" | bc) -eq 1 ]; then
|
||||||
OUTPUT_MSG+="\nCRITICAL: response did not contain required string!\nFound: $(cat "$TMP_RESPONSE")"
|
echo "CRITICAL - Response time $RESPONSE_TIME seconds -> $URL | response_time=${RESPONSE_TIME}s"
|
||||||
OUTPUT_CODE=2
|
exit 2
|
||||||
# else
|
elif [ $(echo "$RESPONSE_TIME > $WARN_TIME" | bc) -eq 1 ]; then
|
||||||
# OUTPUT_MSG+="\nOK: response contained required string."
|
echo "WARNING - Response time $RESPONSE_TIME seconds -> $URL | response_time=${RESPONSE_TIME}s"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check critical string
|
||||||
|
if [ -n "$CRIT_STRING" ]; then
|
||||||
|
BODY=$(curl -s $FOLLOW_REDIRECTS $INSECURE $HEADERS $RESOLVE $TIMEOUT $URL)
|
||||||
|
if [[ ! $BODY =~ $CRIT_STRING ]]; then
|
||||||
|
echo "CRITICAL - Response body does not contain '$CRIT_STRING'"
|
||||||
|
exit 2
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
rm -rf "$TMP_RESPONSE"
|
|
||||||
|
|
||||||
if $IGNORE_STATUS_CODE && [[ $RESPONSE_CODE -ne 200 ]]; then
|
# All checks passed
|
||||||
OUTPUT_MSG+="\nResponse code was $RESPONSE_CODE."
|
echo "OK - Response time $RESPONSE_TIME seconds -> $URL | response_time=${RESPONSE_TIME}s"
|
||||||
fi
|
exit 0
|
||||||
|
|
||||||
OUTPUT_MSG+=" | response_time=${RESPONSE_TIME}s;$WARNING_LEVEL;$CRITICAL_LEVEL;0"
|
|
||||||
|
|
||||||
case $OUTPUT_CODE in
|
|
||||||
#0)
|
|
||||||
# echo "OK: $URL"
|
|
||||||
# ;;
|
|
||||||
1)
|
|
||||||
echo "WARNING: $URL"
|
|
||||||
;;
|
|
||||||
2)
|
|
||||||
echo "CRITICAL: $URL"
|
|
||||||
;;
|
|
||||||
3)
|
|
||||||
echo "UNKNOWN: $URL"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
echo -e "$OUTPUT_MSG"
|
|
||||||
exit $OUTPUT_CODE
|
|
||||||
|
|
|
@ -0,0 +1,185 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Define the usage message
|
||||||
|
usage() {
|
||||||
|
echo "Usage: $0 -u <url> [-w <warning>] [-c <critical>] [-C <contains>] [-L] [-I] [-H <headers>] [-p] [-R] [-s]"
|
||||||
|
echo "[Arguments]:
|
||||||
|
-u Specify the URL to check (required).
|
||||||
|
-w Set the warn level for response time (default: 1 second).
|
||||||
|
-c Set the critical level for response time (default: 2 seconds).
|
||||||
|
-C If the body does not contain this string, return CRITICAL.
|
||||||
|
-L Follow redirects.
|
||||||
|
-I Insecure mode (--insecure).
|
||||||
|
-H Specify headers. Formatted like \"Header1: value,Header2: value\"
|
||||||
|
-p Print the curl command and exit
|
||||||
|
-R Set curl --resolve option.
|
||||||
|
-s Ignore the response status code."
|
||||||
|
exit 3
|
||||||
|
}
|
||||||
|
|
||||||
|
# Parse the command-line arguments
|
||||||
|
while getopts "u:w:c:C:H:R:LhIps" opt; do
|
||||||
|
case $opt in
|
||||||
|
u)
|
||||||
|
URL=$OPTARG
|
||||||
|
;;
|
||||||
|
w)
|
||||||
|
WARNING_LEVEL=$OPTARG
|
||||||
|
;;
|
||||||
|
c)
|
||||||
|
CRITICAL_LEVEL=$OPTARG
|
||||||
|
;;
|
||||||
|
L)
|
||||||
|
FOLLOW_REDIRECTS="-L"
|
||||||
|
;;
|
||||||
|
C)
|
||||||
|
CONTAINS=$OPTARG
|
||||||
|
;;
|
||||||
|
I)
|
||||||
|
INSECURE="--insecure"
|
||||||
|
;;
|
||||||
|
H)
|
||||||
|
HEADERS=$OPTARG
|
||||||
|
;;
|
||||||
|
p)
|
||||||
|
PRINT_ONLY=true
|
||||||
|
;;
|
||||||
|
R)
|
||||||
|
RESOLVE="--resolve $OPTARG"
|
||||||
|
;;
|
||||||
|
s)
|
||||||
|
IGNORE_STATUS_CODE=true
|
||||||
|
;;
|
||||||
|
h)
|
||||||
|
usage
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
usage
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
WARNING_LEVEL=${WARNING_LEVEL:-1}
|
||||||
|
CRITICAL_LEVEL=${CRITICAL_LEVEL:-2}
|
||||||
|
#FOLLOW_REDIRECTS=${FOLLOW_REDIRECTS:-""}
|
||||||
|
PRINT_ONLY=${PRINT_ONLY:-false}
|
||||||
|
IGNORE_STATUS_CODE=${IGNORE_STATUS_CODE:-false}
|
||||||
|
|
||||||
|
if [ -z "$URL" ]; then
|
||||||
|
usage
|
||||||
|
fi
|
||||||
|
|
||||||
|
HEADER_ARGS=""
|
||||||
|
IFS=',' read -ra values <<<"$HEADERS"
|
||||||
|
for value in "${values[@]}"; do
|
||||||
|
HEADER_ARGS+=' -H "'$value'" '
|
||||||
|
done
|
||||||
|
|
||||||
|
TMP_ERROR_LOG=$(mktemp)
|
||||||
|
TMP_RESPONSE=$(mktemp)
|
||||||
|
|
||||||
|
if $PRINT_ONLY; then
|
||||||
|
printf "%s" "curl --output \"$TMP_RESPONSE\" -s -w \"%{http_code}\n%{time_total}\" $(echo "${HEADER_ARGS[@]}" | tr -s ' ') $FOLLOW_REDIRECTS $INSECURE $RESOLVE $URL\n"
|
||||||
|
exit 3
|
||||||
|
fi
|
||||||
|
|
||||||
|
RESPONSE=$(curl --output "$TMP_RESPONSE" -w "%{http_code}\n%{time_total}" $(echo "${HEADER_ARGS[@]}" | tr -s ' ') $FOLLOW_REDIRECTS $INSECURE $RESOLVE $URL 2>"$TMP_ERROR_LOG")
|
||||||
|
|
||||||
|
# shellcheck disable=SC2181
|
||||||
|
status=$?
|
||||||
|
if [ $status -ne 0 ]; then
|
||||||
|
case $status in
|
||||||
|
1)
|
||||||
|
msg="CRITICAL: Unsupported protocol"
|
||||||
|
;;
|
||||||
|
3)
|
||||||
|
msg="CRITICAL: Malformed URL $URL"
|
||||||
|
;;
|
||||||
|
# 5)
|
||||||
|
# msg="CRITICAL: Could not resolve proxy $proxy"
|
||||||
|
# ;;
|
||||||
|
6)
|
||||||
|
msg="CRITICAL: Could not resolve host $URL"
|
||||||
|
;;
|
||||||
|
7)
|
||||||
|
msg="CRITICAL: Could not connect to host (7)"
|
||||||
|
;;
|
||||||
|
22)
|
||||||
|
msg="CRITICAL: Server returned http code >= 400"
|
||||||
|
;;
|
||||||
|
52)
|
||||||
|
msg="CRITICAL: Server returned empty response (52)"
|
||||||
|
;;
|
||||||
|
56)
|
||||||
|
msg="CRITICAL: Failure recieving network data (56)"
|
||||||
|
;;
|
||||||
|
60)
|
||||||
|
msg="CRITICAL: SSL/TLS connection problem (60)"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "UNKNOWN: $status - $URL"
|
||||||
|
exit 3
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
echo -e "$msg"
|
||||||
|
# echo "Error log:"
|
||||||
|
# cat "$TMP_ERROR_LOG"
|
||||||
|
rm -rf "$TMP_ERROR_LOG"
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
rm -rf "$TMP_ERROR_LOG"
|
||||||
|
|
||||||
|
RESPONSE_CODE=$(echo "$RESPONSE" | head -n 1)
|
||||||
|
RESPONSE_TIME=$(printf "%.3f" $(echo "$RESPONSE" | tail -n 1))
|
||||||
|
|
||||||
|
OUTPUT_MSG=""
|
||||||
|
OUTPUT_CODE=0
|
||||||
|
|
||||||
|
if ([ $RESPONSE_CODE -eq 200 ] || $IGNORE_STATUS_CODE) && [ "$(echo "$RESPONSE_TIME < $CRITICAL_LEVEL" | bc -l)" -eq 1 ]; then
|
||||||
|
OUTPUT_MSG="OK: ${RESPONSE_TIME}s - $URL"
|
||||||
|
OUTPUT_CODE=0
|
||||||
|
elif ([ $RESPONSE_CODE -eq 200 ] || $IGNORE_STATUS_CODE) && [ "$(echo "$RESPONSE_TIME < $WARNING_LEVEL" | bc -l)" -eq 1 ]; then
|
||||||
|
OUTPUT_MSG="WARNING: response time is slow ($RESPONSE_TIME seconds)."
|
||||||
|
OUTPUT_CODE=1
|
||||||
|
elif ([ $RESPONSE_CODE -eq 200 ] || $IGNORE_STATUS_CODE); then
|
||||||
|
OUTPUT_MSG"CRITICAL: response time is very slow ($RESPONSE_TIME seconds)."
|
||||||
|
OUTPUT_CODE=2
|
||||||
|
else
|
||||||
|
OUTPUT_MSG="CRITICAL: website did not return 200, response was $RESPONSE_CODE code."
|
||||||
|
OUTPUT_CODE=2
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n ${CONTAINS+x} ]]; then
|
||||||
|
if ! grep -q "$CONTAINS" "$TMP_RESPONSE"; then
|
||||||
|
OUTPUT_MSG+="\nCRITICAL: response did not contain required string!\nFound: $(cat "$TMP_RESPONSE")"
|
||||||
|
OUTPUT_CODE=2
|
||||||
|
# else
|
||||||
|
# OUTPUT_MSG+="\nOK: response contained required string."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
rm -rf "$TMP_RESPONSE"
|
||||||
|
|
||||||
|
if $IGNORE_STATUS_CODE && [[ $RESPONSE_CODE -ne 200 ]]; then
|
||||||
|
OUTPUT_MSG+="\nResponse code was $RESPONSE_CODE."
|
||||||
|
fi
|
||||||
|
|
||||||
|
OUTPUT_MSG+=" | response_time=${RESPONSE_TIME}s;$WARNING_LEVEL;$CRITICAL_LEVEL;0"
|
||||||
|
|
||||||
|
case $OUTPUT_CODE in
|
||||||
|
#0)
|
||||||
|
# echo "OK: $URL"
|
||||||
|
# ;;
|
||||||
|
1)
|
||||||
|
echo "WARNING: $URL"
|
||||||
|
;;
|
||||||
|
2)
|
||||||
|
echo "CRITICAL: $URL"
|
||||||
|
;;
|
||||||
|
3)
|
||||||
|
echo "UNKNOWN: $URL"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
echo -e "$OUTPUT_MSG"
|
||||||
|
exit $OUTPUT_CODE
|
|
@ -8,6 +8,7 @@ from typing import List
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
from checker import nagios
|
from checker import nagios
|
||||||
|
from checker.http import get_with_retry
|
||||||
|
|
||||||
|
|
||||||
def get_disk_wwn_ids(ignore_non_smart: bool = False) -> List[str] or bool:
|
def get_disk_wwn_ids(ignore_non_smart: bool = False) -> List[str] or bool:
|
||||||
|
@ -42,7 +43,7 @@ def get_disk_wwn_ids(ignore_non_smart: bool = False) -> List[str] or bool:
|
||||||
|
|
||||||
def get_smart_health(wwn_id: str, scrutiny_endpoint: str) -> dict:
|
def get_smart_health(wwn_id: str, scrutiny_endpoint: str) -> dict:
|
||||||
url = f"{scrutiny_endpoint}/api/device/{wwn_id}/details"
|
url = f"{scrutiny_endpoint}/api/device/{wwn_id}/details"
|
||||||
response = requests.get(url)
|
response = get_with_retry(url)
|
||||||
if response.status_code == 200:
|
if response.status_code == 200:
|
||||||
return response.json()
|
return response.json()
|
||||||
elif response.status_code == 404:
|
elif response.status_code == 404:
|
||||||
|
|
Loading…
Reference in New Issue