# ====================================================================== # # 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 }