Skip to content
Snippets Groups Projects
inc_functions.sh 8.51 KiB

# ======================================================================
#
# OUTPUT FUNCTIONS
#
# ======================================================================

  isInteractiveShell=false
  test $PPID -ne 1 && isInteractiveShell=true

  # ..................................................................
  # write debug output to STDERR
  function _wd(){
    if [ $cfg_debug = true ]; then
          echo -e "\e[33m# DEBUG: $*\e[0m" >&2
    fi
  }

  # ..................................................................
  # write header string
  function _h1(){ 
    echo
    echo
    echo "###############| $* |###############" 
    echo
  }
  function _h2(){
    echo
    echo "---------- $*"
  }
  function _h3(){
    echo
    echo ">>>>> $*"
  }

  # ......................................................................
  # logging output. writes timestamp and the given message to ${logfile}
  # params  string(s)  message to log
  #
  function _log(){
    echo "$(date) | $*" >> "${logfile}"
  }

  # echo and logging output
  # params  string(s)  message to log
  #
  function _elog(){
    echo "$*"
    _log "$*"
  }

  # echo if there is an interactive shell
  # params  string(s)  message to log
  function _echo(){
    test "$isInteractiveShell" = "true" && echo "$*"
  }

# ======================================================================
#
# DATE AND TIME FUNCTIONS
#
# ======================================================================

  # ......................................................................
  # get age of a file in sec
  # param  string  filename to test
  function _getFileAge(){
    echo $(($(date +%s) - $(date +%s -r "$1")))
  }

  # ......................................................................
  # get current unix timestamp
  # no param
  function _getUnixTs(){
    date +%s
  }

  # get a list of config file of all checks to execute
  # no params
  function getChecks(){
    if [ -z "${dir_checks}" ]; then
      echo "ERROR: config dir for checks is empty."
      echo "Verify value of dir_checks in $dir_cfg/client.cfg"
      exit 1
    fi

    if [ ! -d "${dir_checks}" ]; then
      echo "ERROR: config dir for checks dir_checks does not exist: $dir_checks"
      exit 1
    fi

    for myconfig in $(ls -1 ${dir_checks}/*)
    do
      echo "${myconfig}"
    done
  }

  # parse a config file and set global vars:
  #   checkName
  #   checkCommand
  #   checkInterval
  # param  string  full path of a config file
  function _parseCheckConfig(){
    local _myconfig="$1"

    # EXAMPLE a config contains ...
    # checkname=check_cronstatus
    # command=check_cronstatus -param1 -param2
    # interval=60
    # icon=/images/icon.png
    # max_check_attempts=3

    checkName=$(cat "$_myconfig" | grep ^checkname= | cut -f 2- -d "=" | sed 's# #_#g')
    checkCommand=$(cat "$_myconfig" | grep ^command_$MY_NAME= | cut -f 2- -d "=")
    test -z "$checkCommand" && checkCommand=$(cat "$_myconfig" | grep ^command= | cut -f 2- -d "=")
    checkInterval=$(cat "$_myconfig" | grep ^interval= | cut -f 2 -d "=")
    checkIcon=$(cat "$_myconfig" | grep ^icon= | cut -f 2- -d "=")
    checkMaxAttempts=$(cat "$_myconfig" | grep ^max_check_attempts= | cut -f 2 -d "=")
  }

# ======================================================================
#
# NETWORK FUNCTIONS
#
# ======================================================================

function _getinet4(){
    ip -4 addr | grep inet
}

# filter output of _getinet4
# TODO: bonded devices
# param  string  filter method
#                by type
#                - loopback  filter loopback
#                - net       filter network addresses
#                - peer      filter peer
#                - physical  filter physical addresses
#                - virtual   filter 
#
#                by address range:
#                - private   filter ips from private network ranges
#                - public    filter non private ips (opposite of "private")
#                output
#                - ip         must be the last: get ip address only
# _getinet4 | _ipf 
function _ipf(){
    local _filter=$1

    local _regexInclude='.*'
    local _regexExclude='idonotmatchtoskip'

    if [ -z $_filter ]; then
        echo ERROR: filter _ipf requires a param
    fi

    # 10.0.0.0    – 10.255.255.255 	
    # 172.16.0.0  – 172.31.255.255
    # 192.168.0.0 – 192.168.255.255
    local _privateranges='(10\.|172\.1[6-9]\.|172.2[0-9]\.|172\.3[01]\.|192.168\.)'

    case $_filter in

        # --- types
        'loopback')
            _regexInclude=' scope host '
            ;;
        'physical')
            _regexExclude="( scope host | peer |:vip)"
            ;;
        'virtual')
            _regexInclude=":vip"
            ;;
        'net')
            _regexInclude=' scope global '
            ;;
        'peer')
            _regexInclude=' peer .* scope global '
            ;;

        # --- private/ public ips
        'private')
            _regexInclude=" ${_privateranges}.*"
            ;;
        'public')
            _regexInclude=" scope global "
            _regexExclude=" ${_privateranges}\.*"
            ;;

        # --- output filter
        'ip')
            awk '{ print $2 }' | cut -f 1 -d '/'
            return 0
            ;;
        *)
            echo ERROR: filter [$_filter] is not supported ... showing all.
    esac

    grep -E  "$_regexInclude" | grep -Ev "$_regexExclude" | sed "s#^    ##g"
}

function _getIp(){
  ( _getinet4 | _ipf public | _ipf physical | _ipf ip ; _getinet4 | _ipf private | _ipf physical | _ipf ip ) | head -1
}

function _getIpFrontend(){
  _getinet4 | _ipf public | _ipf physical | _ipf ip
}
function _getIpVirtual(){
  _getinet4 | _ipf virtual | _ipf ip
}
function _getIpPrivate(){
  _getinet4 | _ipf private | _ipf ip
}


# ======================================================================
#
# REST API FUNCTIONS
#
# ======================================================================

  # ..................................................................
  # read config file and apply API base settings
  # param  string  filename of config file
  function _initHttpWithConfigfile(){

    # read config like /etc/icinga2-passive-client/api-director.cfg
    # ... it contains
    # RestApiBaseUrl="https://HOST/path"
    # RestApiUser="USER"
    # RestApiPassword="PASSWORD"
    # RestApiDocs="https://icinga.com/docs/something"
    . "$1" || exit 1

    http.init
    http.setAuth     "${RestApiUser}:${RestApiPassword}"
    http.setBaseUrl  "${RestApiBaseUrl}"
    http.setDocs     "${RestApiDocs}"

  }

  # ..................................................................
  # make a curl request and show the response header + body
  # param  string  method - GET|POST|...see http.setMethod
  # param  string  relative URL behind API base url
  # param  string  optional: data for PUTs and POSTs
  function _APIcall(){

    http.makeRequest "$1" "$2" "$3"
    if http.isServerError >/dev/null; then
      _elog "CRITICAL ERROR: API request failed with a server error $1 $2"
      exit 1
    fi

    _echo "$( http.getResponseHeader )"
    _echo "$( http.getResponse )"

  }

  # ..................................................................
  # make an rest API regeques with GET command to update local cache
  # file of an object.
  # The cache file will be deleted if the http response code is not OK.
  #
  # global  $APICLIENT  rest api wrapper
  #
  # param  string  url behind RestAPI base path
  # param  string  filename of the local cache file
  function _getApiObject(){
    local _url=$1
    local _outfile=$2

    #http.setDebug   1
    # http.setUrl     "${_url}"
    # http.setMethod  "GET"
    # http.setBody    ""
    # http.makeRequest

    http.makeRequest GET "${_url}" ""

    if [ ! -z "$(http.isok)" ]; then
      _wd "OK, Object $_url exists - updating cache file $_outfile"
      http.responseExport "${_outfile}"
    else
      _wd "FAILED :-/ GET $_url was NOT successful - removing $_outfile"
      rm -f "${_outfile}"
    fi

  }


  # show name of linked service on a host
  # it is used to 
  #   - link the service to a host on director
  #   - send process data from client to icinga
  #
  # param  string  name of check (=checkName after _parseCheckConfig FILE)
  # param  bool    flag: reverse renaming: linkname --> checkname
  function _getName4Svcathost(){

    echo $1
    # prefix was removed ... reverse functionailty not needed (sed fails)
    #
    # local prefix="added_service_for_command_"
    # local prefix=""
    # if [ $# -eq 1 ]; then
    #   echo "${prefix}${1}"
    # else
    #   echo $1 | sed "s#$prefix##g"
    # fi
  }