expanded checks + refactoring, cleanup

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2023-06-30 16:26:13 +03:00
parent af640e2c7b
commit a3dd84af4c
4 changed files with 253 additions and 43 deletions

View File

@ -1,6 +1,9 @@
#!/usr/bin/bash #!/usr/bin/bash
#---------------------------------------------------------------------- #----------------------------------------------------------------------
CT_DIR=${CT_DIR:=/etc/pve/lxc/}
#---------------------------------------------------------------------- #----------------------------------------------------------------------
#QUIET= #QUIET=
#DRY_RUN= #DRY_RUN=
@ -17,12 +20,40 @@
#---------------------------------------------------------------------- #----------------------------------------------------------------------
# get CT hostname... # get CT hostname...
cthostname(){ ct2hostname(){
local ct=${CT_DIR}/${id}.conf local ct=${CT_DIR}/${1}.conf
local host=$(cat $ct | grep hostname | head -1) local host=$(cat $ct | grep hostname | head -1)
echo ${host/hostname: /} echo ${host/hostname: /}
} }
hostname2ct(){
if [ -e "${CT_DIR}/${1}.conf" ] ; then
echo $1
fi
local running=$2
running=${running:=any}
local ct
local host
for ct in "${CT_DIR}"/*.conf ; do
host=$(cat $ct | grep hostname | head -1)
host=${host/hostname: /}
if [ "$host" = $1 ] ; then
ct=${ct#${CT_DIR}}
ct=${ct%.conf}
ct=${ct#\/}
# filter results if needed...
if [ $running = "any" ] ; then
echo $ct
else
local status=`pct status $ct`
if [ "$running" = "${status/status: /}" ] ; then
echo $ct
fi
fi
fi
done
}
#---------------------------------------------------------------------- #----------------------------------------------------------------------
fillsection(){ ( fillsection(){ (

View File

@ -1,45 +1,220 @@
#!/usr/bin/bash #!/usr/bin/bash
#----------------------------------------------------------------------
IFS=$'\n' IFS=$'\n' \
SITES=("$@") SITES=("$@")
TIMEOUT=${TIMEOUT:=10} TIMEOUT=${TIMEOUT:=10}
TRIES=${TRIES:=2}3
SAFE=${SAFE:=1}
OK_STATUS='2[0-9][0-9]|30[1-9]|401|501' HTTP_TRIES=${HTTP_TRIES:=2}
HTTP_SAFE=${HTTP_SAFE:=no}
HTTP_OK_STATUS=${HTTP_OK_STATUS:='2[0-9][0-9]|30[1-9]|401|501'}
check(){
local comment=`sed \
-e 's/^\(.*\)https\?:\/\/.*$/\1/' \ #----------------------------------------------------------------------
source .pct-helpers
#----------------------------------------------------------------------
# Handlers...
declare -A HANDLERS
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Proxmox lxc
#
# lxc://<id>:<cmd>:<value>
#
# supported commands:
# status:<status>
# ip:<dev>=<ip>
# service:<name>=<status>
#
HANDLERS[lxc]=check-lxc
declare -A LXC_HANDLERS
LXC_HANDLERS[status]=check-lxc-status
check-lxc-status(){
local status=`pct status $1`
status=${status/status: /}
[ "$status" = "$2" ] \
&& echo "OK" \
|| echo "ERROR"
}
LXC_HANDLERS[ip]=check-lxc-ip
check-lxc-ip(){
local dev=${2/=*/}
local ip=${2/*=/}
local res=$(\
lxc-attach $1 ip a show dev $dev \
| awk '/inet / {print $2}')
[ "$ip" = "$res" ] \
&& echo "OK" \
|| echo "ERROR"
}
LXC_HANDLERS[service]=check-lxc-service
check-lxc-service(){
local service=${2/=*/}
local status=${2/*=/}
local res=$(\
lxc-attach $1 systemctl status $service \
| awk '/Active: / {print $2}')
[ "$status" = "$res" ] \
&& echo "OK" \
|| echo "ERROR"
}
check-lxc(){
local target=`sed \
-e 's/^.*\s*lxc:\/\///' \
-e 's/^\s*//;s/\s*$//' \ -e 's/^\s*//;s/\s*$//' \
<<<$1` <<<$1`
local cmd=`sed 's/^[^:]*://' <<<$target`
target=${target/:*/}
local value=`sed 's/^[^:]*://' <<<$cmd`
cmd=${cmd/:*/}
if [ -z ${LXC_HANDLERS[$cmd]} ] ; then
echo "ERROR (unknown command: $cmd)"
return
fi
${LXC_HANDLERS[$cmd]} "$target" "$value"
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# OpenVPN
#
# NOTE: this will not work if 'tls-auth' is enabled...
HANDLERS[ovpn]=check-ovpn
check-ovpn(){
local target=`sed \
-e 's/^.*\s*ovpn:\/\///' \
-e 's/^\s*//;s/\s*$//' \
<<<$1`
local port=`cut -sd ':' -f 2 <<<$target`
port=${port:=1194}
target=`cut -d ':' -f 1 <<<$target`
local res=$(echo -e "\x38\x01\x00\x00\x00\x00\x00\x00\x00" \
| timeout $TIMEOUT nc -u 46.138.244.248 5555 \
| cat -v)
if [ -z $res ] ; then
echo ERROR
else
echo OK
fi
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# SSH
HANDLERS[ssh]=check-ssh
HANDLERS[git]=check-ssh
check-ssh(){
local target=`sed \
-e 's/^.*\s*\(ssh\|git\):\/\///' \
-e 's/^\s*//;s/\s*$//' \
<<<$1`
local port=`cut -sd ':' -f 2 <<<$target`
port=${port:=22}
target=`cut -d ':' -f 1 <<<$target`
# open port...
response=$(\
[ $(sleep $TIMEOUT \
| telnet $target $port 2> /dev/null \
| grep SSH) ] \
&& echo "OK" \
|| echo "ERROR" )
echo $response
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# HTTP/HTTPS
HANDLERS[http]=check-http
HANDLERS[https]=check-http
status_pattern="\(${HTTP_OK_STATUS//|/\\|}\)"
check-http(){
local target=`sed \ local target=`sed \
-e 's/^.*\s*\(https\?:\/\/\)/\1/' \ -e 's/^.*\s*\(https\?:\/\/\)/\1/' \
-e 's/^\s*//;s/\s*$//' \ -e 's/^\s*//;s/\s*$//' \
<<<$1` <<<$1`
# open port...
# nmap $target -Pn -p ssh | grep open
# http/https # http/https
if [ $SAFE ] ; then if [ "$HTTP_SAFE" = "no" ] ; then
local safe=--no-check-certificate local safe=--no-check-certificate
else else
local safe local safe
fi fi
local response=$(\ local response=$(\
wget -S --spider -T $TIMEOUT --tries=$TRIES $safe $target 2>&1 \ wget -S --spider -T $TIMEOUT --tries=$HTTP_TRIES $safe $target 2>&1 \
| awk '/HTTP\// {print $2}' ) | awk '/HTTP\// {print $2}' )
if [ "$(grep "$status_pattern" <<<$response)" ] ; then
response=OK
else
response="ERROR ($response)"
fi
echo $response
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PROTOCOLS=$(printf "\\|%s" "${!HANDLERS[@]}")
PROTOCOLS=${PROTOCOLS:2}
check(){
local comment=`sed \
-e 's/^\(.*\)\('"$PROTOCOLS"'\):\/\/.*$/\1/' \
-e 's/^\s*//;s/\s*$//' \
<<<$1`
local target=`sed \
-e 's/^.*\s*\(\('"$PROTOCOLS"'\):\/\/\)/\1/' \
-e 's/^\s*//;s/\s*$//' \
<<<$1`
local scheme=`sed 's/\('"$PROTOCOLS"'\):\/\/.*/\1/' \
<<<$target`
echo "COMMENT=$comment" echo "COMMENT=$comment"
echo "URL=$target" echo "URL=$target"
echo "RESPONSE=$response" # call the checker...
echo "RESPONSE=$(${HANDLERS[$scheme]} "$target")"
} }
#----------------------------------------------------------------------
problems= problems=
status_pattern="\(${OK_STATUS//|/\\|}\)"
for site in ${SITES[@]} ; do for site in ${SITES[@]} ; do
# skip things we do not recognize...
if ! [ "$(grep "$PROTOCOLS://" <<<$site)" ] ; then
echo $site
continue
fi
IFS=$'\n' \ IFS=$'\n' \
res=($(check "$site")) res=($(check "$site"))
@ -54,14 +229,7 @@ for site in ${SITES[@]} ; do
! [ -z $comment ] \ ! [ -z $comment ] \
&& comment="$comment " && comment="$comment "
#if [ $(grep '\(2[0-9][0-9]\|30[1-9]\|401\|501\)' <<<$res) ] ; then echo "${comment}${site} : ${res}"
if [ $(grep "$status_pattern" <<<$res) ] ; then
state=OK
else
state="ERROR ($res)"
problems=1
fi
echo "${comment}${site} : ${state}"
done done
if [ $problems ] ; then if [ $problems ] ; then
@ -69,4 +237,6 @@ if [ $problems ] ; then
fi fi
#----------------------------------------------------------------------
# vim:set ts=4 sw=4 : # vim:set ts=4 sw=4 :

View File

@ -20,7 +20,7 @@ tpl=$3
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ct=${CT_DIR}/${id}.conf ct=${CT_DIR}/${id}.conf
host=$(cthostname $id) host=$(ct2hostname $id)
running=$(pct list | grep "running\s*$host\s*$") running=$(pct list | grep "running\s*$host\s*$")

View File

@ -1,6 +1,5 @@
#!/usr/bin/bash #!/usr/bin/bash
source .pct-helpers
@ -16,6 +15,12 @@ CONFIG=${CONFIG:=/etc/pve/nodes/pve/config}
TMP_RESULTS=${TMP_RESULTS:=${CONFIG}.live} TMP_RESULTS=${TMP_RESULTS:=${CONFIG}.live}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
source .pct-helpers
#----------------------------------------------------------------------
DATE=`date +'%Y-%m-%d %H:%M'` DATE=`date +'%Y-%m-%d %H:%M'`
@ -33,29 +38,33 @@ fi
# read the sites from the status section in $CONFIG... # read the sites from the status section in $CONFIG...
IFS=$'\n' \ readarray -t lines <<<$(\
SITES=($(\
sed -n '/STATUS BEGIN/,/STATUS END/p' "$CONFIG" \ sed -n '/STATUS BEGIN/,/STATUS END/p' "$CONFIG" \
| sed \ | sed \
-e '1d;$d' \ -e '1d;$d' \
-e 's/^#//' \ -e 's/^#//' \
-e 's/^\**//' \
-e 's/%3A/:/g' \ -e 's/%3A/:/g' \
-e 's/ : .*//' \ -e 's/ : \(OK\|**ERROR\).*//')
| grep 'http'))
# fill the status section -> $TMP_RESULTS... # fill the status section -> $TMP_RESULTS...
cp -f "$CONFIG" "$CONFIG".bak cp -f "$CONFIG" "$CONFIG".bak
{ {
echo '#<!-- STATUS BEGIN -->' echo '#<!-- STATUS BEGIN -->'
for site in "${SITES[@]}" ; do for line in "${lines[@]}" ; do
./check-status "$site" \ # empty lines...
if [[ "$line" =~ ^[[:space:]]*$ ]] ; then
echo "#"
continue
# skip check date...
elif [[ "$line" =~ ^_\(checked[[:blank:]]on:[[:blank:]].*\)_$ ]] ; then
continue
fi
./check-status "$line" \
| tee -a $TEXT_STATUS \ | tee -a $TEXT_STATUS \
| sed \ | sed \
-e 's/^\s*\(.*ERROR.*$\)/**\1**/' \ -e 's/^\(.*\)\(ERROR.*$\)/\1**\2**/' \
-e 's/^/#/' \ -e 's/^/#/'
-e 's/$/\n#/'
done done
echo "#_(checked on: ${DATE})_" echo "#_(checked on: ${DATE})_"
echo '#<!-- STATUS END -->' echo '#<!-- STATUS END -->'