Skip to content
Snippets Groups Projects
check_eol 7.68 KiB
#!/bin/bash
# ======================================================================
#
# Icinga/ Nagios Check
# EOL - End of life detection - Warn before reaching end of life
#
#   - includes inc_pluginfunctions
#   - eol data are organized in check_eol*.cfg
#   - detection functions are in check_eol-detect-[name]
#
# ----------------------------------------------------------------------
#
# REQUIREMENTS:
#   - linux (Centos, Debian, Ubuntu, ...)
#
# ----------------------------------------------------------------------
#
# SYNTAX:
#
# check_eol
#   show help and known product keys
#
# check_eol PRODUCT
#   detect PRODUCT and its EOL date in the *cfg files.
#   Remark: all keys are lowercase. Some product keys are followed by a
#           major version, some by major and a minor version,
#
# check_eol detect[KEY]
#   There is a special prefix "detect".
#   KEY is one of OS|PHP .. you can use uppercase or lowercase.
#
# ----------------------------------------------------------------------
#
# EXAMPLES:
#
#   use a product key and version
#     check_eol centos 7
#     check_eol php 7.4
#
#   use auto detection of a version
#     check_eol os detect
#     check_eol php detect
#
# ----------------------------------------------------------------------
# 2020-02-21  v1.0  <axel.hahn@iml.unibe.ch>
# 2020-03-05  v1.1  <axel.hahn@iml.unibe.ch> switch to ph.* helper functions
# ======================================================================

. `dirname $0`/inc_pluginfunctions
eolcfg="${0}-data/*.cfg"

_version="0.3"

# --- limits
typeset -i iDaysWarn=365
typeset -i iDaysCritical=90
bDebug=false


myKey=
myEolEnd=
typeset -i myDaysLeft=


# ----------------------------------------------------------------------
# automatic detection
# ----------------------------------------------------------------------

# auto detetct an os or a version based on cli output
# used on param detect*
# global string  myKey   name of product
function autodetect(){

    myVersion=

    case $myKey in
        'os')
            # ----- detect operating system and major version
            # see inc_pluginfunctions
            myKey=`ph.getOS`
            myVersion=`ph.getOSMajor`
            ;;
        'mysqlany')            
            local _tmpfile=/tmp/detect_mysql_$$
            mysql --version >$_tmpfile 2>&1
            if [ $? -ne 0 ]; then
                rm -f $_tmpfile
                ph.abort "UNKNOWN: mysql was not found. A Mysql version cannot be detected."
            fi

            # default: mysql
            myKey=mysql

            # scan for forks:
            # todo: add ... percona ... memdb ... whatever
            grep "MariaDB" $_tmpfile >/dev/null && myKey=mariadb

            rm -f $_tmpfile
            ;;
        *)
            # echo ERROR: detection for [$1] is not implemented
    esac

    detectorPlugin="$0-versiondetect/detect-$myKey"
    if [ -x "$detectorPlugin" ]; then
        myVersion=`. "$detectorPlugin"`
    fi
    if [ -z "$myVersion" ]; then
        ph.abort "UNKNOWN: [$myKey] was not detected properly. It is unknown or output for version cannot be parsed."
    fi
}


# ----------------------------------------------------------------------
# functions for eol check
# ----------------------------------------------------------------------

# get count of days left to a given date
# param  string  date as "YYYY-MM-DD"
function getDaysLeft(){
    
    local mydate=$1
    echo $mydate | grep "[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]" >/dev/null
    if [ $? -eq 0 ]; then
        typeset -i local tsend=`date --date="$mydate" +%s`
        typeset -i local daysLeft=($tsend - `date +%s`)/60/60/24
        echo $daysLeft
    fi
}

# detect product in *cfg files and find its EOL
# global string  myKey       name of product
# global string  myVersion   its version
function findEolDate(){
    line=`grep "^$myKey:$myVersion:" $eolcfg | sort -n | tail -1`
    if [ ! -z "$line" ]; then
        
        myEolEnd=`echo $line | cut -f 4 -d ":"`
        myComment=`echo $line | cut -f 5 -d ":"`
        myDaysLeft=`getDaysLeft $myEolEnd`
        # --- verify days left with limits
        ph.setStatus "ok"
        if [ $myDaysLeft -lt $iDaysWarn ]; then
            ph.setStatus "warning"
            if [ $myDaysLeft -lt $iDaysCritical ]; then
                ph.setStatus "critical"
            fi
        fi
        if [ $myDaysLeft -ge 0 ]; then
            ph.status "[$myKey $myVersion] ends on $myEolEnd ... $myDaysLeft days left $myComment" 
        else
            echo "[$myKey $myVersion] ended on $myEolEnd ... `echo $myDaysLeft | sed 's#\-##'` days EXPIRED ALREADY !!! $myComment" 
        fi
        echo
        grep "^$myKey:" $eolcfg | grep -v ":$myKey:[0-9]" | cut -f 3- -d ":"
        echo
        echo "Limit Info: warn below $iDaysWarn days; critical below $iDaysCritical days"
        ph.perfadd "$myKey-v$myVersion" "${myDaysLeft}" $iDaysWarn $iDaysCritical 0

    else
        ph.setStatus "unknown"
        echo "UNKNOWN. Sorry, [$myKey $myVersion] was not found in $eolcfg."
        echo
        grep "^$myKey:" $eolcfg >/dev/null
        if [ $? -eq 0 ]; then
            echo "HINT: the product [$myKey] is known ... but not the version [$myVersion] ... or its date is invalid i.e. 30th of feb or not YYYY-MM-DD"
            echo
            grep "^$myKey:" $eolcfg | grep -v ":$myKey:[0-9]" | cut -f 3- -d ":"
            echo
            echo "Maybe an admin can add the version in `grep -l "^$myKey:" $eolcfg`"
            echo "Existing/ known versions are:"
            grep "^$myKey:[0-9]" $eolcfg | cut -f 3 -d ":" | sort -un
        else
            echo "The product key [$myKey] was not detected in any version."
        fi
    fi
}

# ----------------------------------------------------------------------
# MAIN
# ----------------------------------------------------------------------

# --- no param? show help

if [ $# -lt 2 ]; then
    cat <<EOH
______________________________________________________________________

CHECK EOL :: v${_version}

(c) Institute for Medical Education - Univerity of Bern
Licence: GNU GPL 3
______________________________________________________________________

Check and of support of an OS or a product.
The dates are defined in the files check_eol-*.cfg
For detailed information see `basename $0`.md

USAGE
  $ `basename $0` [-c CRITICAL] [-w WARING] PRODUCT VERSION

PARAMETERS
  PRODUCT  set a product; known product keys are listed below

`grep "^[a-zA-Z]" $eolcfg | cut -f 2 -d ":" | sort -un | sed "s#^#             #g"`

  VERSION  set a version.
           Autodetection:
           There is a special handling vor version "detect".
           You can set "os" as product to detect the (linux) distribution.
           See examples below.

OPTIONS
  -c  set critical limit; default $iDaysCritical
  -w  set warning limit; default $iDaysWarn

EXAMPLES
  `basename $0` php 7.4
  `basename $0` -w 100 -c 30 php 7.4
  `basename $0` os detect
  `basename $0` php detect

EOH

    ph.abort
fi

# --- parse params I: override warning and critical
typeset -i iShift=0
while getopts ":c: :w:" opt
do
    case $opt in
        c)
            iDaysCritical=$OPTARG
            iShift=$iShift+2
            ;;
        w)
            iDaysWarn=$OPTARG
            iShift=$iShift+2
            ;;
        *)
            ph.abort "ERROR: parameter unknown -- $opt"
            
    esac
done
shift $iShift

# --- verify warning and critical
if [ $iDaysWarn -lt $iDaysCritical ]; then
    ph.abort "ERROR: warning limit $iDaysWarn cannot be lower critical $iDaysCritical"
fi


# --- parse params II: get product and version
myKey=$1
myVersion=$2
test $myVersion = "detect" && autodetect $myKey
findEolDate "$myKey" "$myVersion"

# --- bye
ph.exit

# ----------------------------------------------------------------------