improve check_curl, use common HTTP function on py

This commit is contained in:
Cyberes 2023-06-15 12:57:53 -06:00
parent 2ca897f0a0
commit 792838d50d
Signed by: cyberes
GPG Key ID: 6B4A33836A9500FE
3 changed files with 532 additions and 149 deletions

View File

@ -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
;;
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 exit 3
;; ;;
esac esac
done
echo -e "$msg" # Check if URL is provided
# echo "Error log:" if [ -z "$URL" ]; then
# cat "$TMP_ERROR_LOG" echo "Usage: $0 -u URL [options]"
rm -rf "$TMP_ERROR_LOG" exit 3
fi
# Prepare curl command
CURL_CMD="curl -w %{http_code};%{time_total} -o /dev/null -s $FOLLOW_REDIRECTS $INSECURE $HEADERS $RESOLVE $TIMEOUT $URL"
# Print curl command if requested
if [ "$PRINT_CURL" = "yes" ]; then
echo "$CURL_CMD"
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)
msg="CRITICAL - Unsupported protocol"
;;
2)
msg="CRITICAL - Failed to initialize"
;;
3)
msg="CRITICAL - Malformed URL"
;;
4)
msg="CRITICAL - Feature or option not enabled"
;;
5)
msg="CRITICAL - Couldn't resolve proxy"
;;
6)
msg="CRITICAL - Could not resolve 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)
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)
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)
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)
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 - $CURL_EXIT -> $URL"
exit 3
;;
esac
echo "$msg -> $URL"
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

185
check_curl_old.sh Executable file
View File

@ -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

View File

@ -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: