#!/bin/bash
# ======================================================================
#
# !!! WORK IN PROGRESS !!! DO NOT USE YET !!!
#
# Check MYSQL / MARIADB SERVER
#
# requirements:
# - mysql client
#
# installation:
# - execute check_mysqlserver -i
#
# ----------------------------------------------------------------------
# 2020-08-xx  v0.0  <axel.hahn@iml.unibe.ch>
# ======================================================================


. `dirname $0`/inc_pluginfunctions
_version="0.1"

# --- set HOME
HOME=/etc/icinga2-passive-client
# cd $( dirname $0)
# cd ..
# HOME=$( pwd ); export HOME
# cd - >/dev/null

# --- other vars...
cfgfile=$HOME/.my.cnf
myuser=icingamonitor
datafile=/tmp/mysqlvars.out

# new line
NL="
"

out=

# ----------------------------------------------------------------------
# FUNCTIONS
# ----------------------------------------------------------------------

# uninstall database user
function _uninstall(){
    echo UNINSTALL ...
    mysql -e "DROP user $myuser@localhost ;"
}

# (re)install database user for monitoring
function _install(){
    echo INSTALLING ...
    local pwlength=64
    
    echo "- check mysql connection..."
    mysql -e ";"
    if [ $? -ne 0 ]; then
        echo "ERROR: mysql connect without password failed."
        exit 1
    fi

    echo "- creating mysql user $myuser@localhost with random password ($pwlength chars)..."
    mypw=$( head /dev/urandom | tr -dc A-Za-z0-9 | head -c $pwlength )

    mysql -e "CREATE USER $myuser@localhost IDENTIFIED BY '$mypw';"
    if [ $? -ne 0 ]; then
        echo "ERROR: mysql command to create user failed."
        exit 1
    fi
    echo "- grant SELECT on mysql tables ..."
    mysql -e "GRANT SELECT ON mysql.* TO $myuser@localhost;"
    if [ $? -ne 0 ]; then
        echo "ERROR: mysql command to grant permissions failed."
        exit 1
    fi

    echo "- flush privileges ..."
    mysql -e "FLUSH PRIVILEGES;"

    echo "- creating config file $cfgfile ... "
    cat  >$cfgfile <<EOF
#
# generated on `date`
#
[client]
user=$myuser
host=localhost
password=$mypw

EOF
    ls -l $cfgfile
    if [ $? -ne 0 ]; then
        echo "ERROR: creation of config file failed."
        exit 1
    fi
}

function _usage(){
    cat <<EOH
______________________________________________________________________

CHECK MYSQL SERVER :: v${_version}

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

USAGE:
  `basename $0` [OPTIONS] -m METHOD

OPTIONS:
  -h  this help
  -i  install monitoring user (must be executed as root)
  -u  uninstall monitoring user (must be executed as root)

PARAMETERS:
  -m  method; valid methods are:
      connections  current/ max connections
      connects     connects per min and aborted connections/ clients
      commands     current running statements insert, select, ...

EXAMPLES:
  `basename $0` -i
  `basename $0` -m commands

EOH
}

function _mysqlreadvars(){
    mysql -e "SHOW GLOBAL VARIABLES ;" --skip-column-names >$datafile
    mysql -e "SHOW STATUS ;"           --skip-column-names >>$datafile
}

function _mysqlgetvar() {
    local sVarname=$1
    grep "^$sVarname[^_a-z]" ${datafile} | awk '{ print $2 }'
}
# get a value from mysql status output
# param  string  variable name
# param  string  prefix to remove from beginning of variable
# param  (set)   flag if it is a delta value
function _mysqlrendervar() {
    local sVarname=$1
    local sRemove=$2
    local sDeltaUnit=$3
    local sFloat=$4

    # local iValue=`grep "^$sVarname[^_a-z]" ${datafile} | awk '{ print $2 }'`
    local iValue=`_mysqlgetvar "$sVarname"`
    if [ "$iValue" = "" ]; then
            ph.abort "no value for ${sVarname}"
    fi

    # get label for perfdata
    local sLabel=`echo ${sVarname} | sed "s#^${sRemove}##g"`
    
    if [ ! -z $sDeltaUnit ]; then
        local iSpeed=` ph.perfdeltaspeed "mysql-${sVarname}" ${iValue} $sDeltaUnit $sFloat`
        out="${out}${sLabel}: ${iValue} ... delta = ${iSpeed} per $sDeltaUnit${NL}"
        ph.perfadd "${sLabel}"   "${iSpeed}"
    else
        out="${out}${sLabel}: ${iValue}${NL}"
        ph.perfadd "${sLabel}" "${iValue}"
    fi

}

function _mysqlrenderdelta() {
    local deltaUnit=$3
    test -z $deltaUnit && deltaUnit="sec"
    _mysqlrendervar "$1" "$2" $deltaUnit $4
}
# ----------------------------------------------------------------------
# MAIN
# ----------------------------------------------------------------------

bOptInstall=`   ph.hasParamoption "i" "$@"`
bOptUninstall=` ph.hasParamoption "u" "$@"`
bOptHelp=`      ph.hasParamoption "h" "$@"`

if [ $bOptHelp -eq 1 -o $# -lt 1 ]; then
    _usage
    exit 0
fi

# --- check required tools
ph.reqire mysql

# --- install
if [ $bOptInstall -eq 1 -a "$( whoami )" = "root" ]; then
    if [ -f $cfgfile ]; then
        ph.status "SKIP installation. config file already exists: $cfgfile."
        ph.exit
    fi
    HOME=/root
    export HOME

    _uninstall
    _install

    ph.status "Installation was done"
    ph.exit
fi

# --- uninstall
if [ $bOptUninstall -eq 1 -a "$( whoami )" = "root" ]; then
    HOME=/root

    _uninstall
    rm -f $cfgfile

    ph.status "Uninstalled."
    ph.exit
fi


# --- check installation
grep $myuser $cfgfile >/dev/null 2>/dev/null 
if [ $? -ne 0 ]; then
    ph.abort "MYSQL access not possible yet. You need to install the monitoring user first: as root execute `basename $0` -i"
fi

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

# --- get data
_mysqlreadvars
if [ $? -ne 0 ]; then
    rm -f $datafile
    ph.abort "MYSQL access not possible. Maybe Mysql is not running??"
fi

# --- set optional limits
# typeset -i iWarnLimit=`     ph.getValueWithParam 0 w "$@"`
# typeset -i iCriticalLimit=` ph.getValueWithParam 0 c "$@"`

sMode=`ph.getValueWithParam '' m "$@"`

case "${sMode}" in

    "connections")
        descr="current/ max connections"

        _mysqlrendervar    max_connections
        _mysqlrendervar    Max_used_connections
        _mysqlrendervar    Threads_connected
        ;;

    "connects")
        descr="connects per min and aborted connections/ clients"
        _mysqlrenderdelta  Connections            "" min float
        _mysqlrenderdelta  Aborted_clients        "" min float
        _mysqlrenderdelta  Aborted_connects       "" min float
        ;;

    "commands")
        descr="currently executed commands"
        _mysqlrendervar Com_delete  "Com_"
        _mysqlrendervar Com_insert  "Com_"
        _mysqlrendervar Com_replace "Com_"
        _mysqlrendervar Com_select  "Com_"
        _mysqlrendervar Com_update  "Com_"
        ;;

    "qcache-blocks")
        descr="query cache blocks"
        _mysqlgetvar "have_query_cache" | grep "YES" >/dev/null || ph.abort "Query cache is not active"
        _mysqlrendervar Qcache_total_blocks "Qcache_"
        _mysqlrendervar Qcache_free_blocks  "Qcache_"
        ;;

    "qcache-queries")
        descr="query cache data"
        _mysqlgetvar "have_query_cache" | grep "YES" >/dev/null || ph.abort "Query cache is not active"
        _mysqlrendervar    Qcache_queries_in_cache  "Qcache_"
        _mysqlrenderdelta  Qcache_not_cached        "Qcache_"  min  float
        _mysqlrenderdelta  Qcache_lowmem_prunes     "Qcache_"  min  float
        ;;
    "qcache-hits")
        descr="query cache hits"
        _mysqlgetvar "have_query_cache" | grep "YES" >/dev/null || ph.abort "Query cache is not active"
        _mysqlrendervar    Qcache_hits        "Qcache_"
        _mysqlrendervar    Qcache_inserts     "Qcache_"
        _mysqlrendervar    Qcache_not_cached  "Qcache_"

        ;;

    *)
        echo ERRROR: [${sMode}] is an INVALID mode
        _usage
        ph.abort

esac

ph.status "Mysql $sMode :: $descr"
echo "$out"

rm -f $datafile
ph.exit

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