diff --git a/director-cli.sh b/director-cli.sh index 6bc7c5a5b8aa1f4b5c4e5dd8884eb6135e1bafe1..3b62dfd70b3aa575c78af35ce0c3160b3bc76420 100755 --- a/director-cli.sh +++ b/director-cli.sh @@ -10,7 +10,6 @@ # actions for a host, commands, services # # This script contains specific logic for IML -# - use puppet facts # - UniBe network and group names - see hostCreate() # # ---------------------------------------------------------------------- @@ -21,19 +20,18 @@ # 2023-02-17 v0.5 ah add hostnamme into CFGSTORAGE # 2023-02-17 v0.6 ah remove invalid line in cleanup # 2023-02-17 v0.7 ah check inc_getconfig.sh exists and hostname -f has a value +# 2023-10-25 v0.8 ah generate json with "jo"; optimze http requests on services; parallel service function call # ====================================================================== -_version="0.7" -tmpfile=/tmp/outcurl.tmp -tmpfile2=/tmp/outcurl2.tmp +_version="0.8" + +which curl >/dev/null || exit 1 +which jo >/dev/null || exit 1 # a custom file to source instead of detecting local data loadfile= -# UNUSED -# APICLIENT=`dirname $0`/api2director - # MY_NAME=`facter fqdn | cut -f -2 -d ">"` # MY_IP=`facter ipaddress | cut -f -2 -d ">"` @@ -45,6 +43,15 @@ loadfile= typeset cfg_debug=false typeset cfg_dryrun=false +export regexPrivateNetworks="^(10\.|172\.1[6-9]\.|172.2[0-9]\.|172\.3[01]\.|192.168\.)" + +# json for a host: set group if the system is pingable by Icinga or in a private network +hostImportReachable="host in network" +hostImportPrivate="host passive only" + +# default groups (jo params) +hostDefaultgroups="groups[]=iml groups[]=iml-server" + # ====================================================================== # # FUNCTIONS @@ -83,138 +90,94 @@ typeset cfg_dryrun=false # ---------------------------------------------------------------------- # ............................................................ - # set $ch to store all object vars - + # generate json parameters for jo function _generateJsonForHost(){ if [ -z "$loadfile" ]; then # --- host infos - local MY_Platform=$(uname -a | cut -f 1 -d ' ') . $(dirname $0)/plugins/inc_pluginfunctions || exit 1 local MY_OSName=$(ph.getOS) local MY_OSMajorVersion=$(ph.getOSMajor) fi - export CFGSTORAGE="${MY_NAME}-directorhost" - ( - $ch --flush - $ch --set object_name \"$MY_NAME\" - $ch --set object_type '"object"' - $ch --set address \"$MY_IP\" - $ch --set display_name \"$MY_NAME\" - $ch --set zone \"$MY_ZONE\" - - $ch --set icon_image \"/images/os/${MY_OSName}.png\" - $ch --set icon_image_alt \"${MY_Platform}\:\ ${MY_OSName}\ ${MY_OSMajorVersion}\" - ) 2>/dev/null - - # --- detect phase - # local phase="live" - # for myphase in preview stage demo - # do - # echo $MY_NAME | grep "\.$myphase\." >/dev/null && phase=$myphase - # done - - ( - # ----- facter data to host vars - $ch --set vars.platform \"${MY_Platform}\" - $ch --set vars.os \"${MY_OSName}${MY_OSMajorVersion}\" - - # ----- set host type - - # host in the UNIBE network: - if echo "$MY_IP" | grep -E "^(10\.|172\.1[6-9]\.|172.2[0-9]\.|172\.3[01]\.|192.168\.)" >/dev/null - then - $ch --set imports '["host passive only"]' - else - $ch --set imports '["host in network"]' + local JSONPARAMS=" + object_name=$MY_NAME + object_type=object + address=$MY_IP + display_name=$MY_NAME - # port checks initiated by icinga server to monitor client - if [ -n "${host_vars_tcpport}" -a "${host_vars_tcpport}" != "[]" ]; then - host_vars_tcpport=$(echo ${host_vars_tcpport} | sed "s# ##g") - $ch --set vars.tcp_port "${host_vars_tcpport}" - fi - fi - - - # ----- /host type + zone=$MY_ZONE + icon_image=/images/os/${MY_OSName}.png + icon_image_alt="\"${MY_Platform}:\ ${MY_OSName}\ ${MY_OSMajorVersion}\"" - # ----- host groups - # all host groups must exist in director - otherwise the creation - # of a host will fail - # see https://icinga.one.iml.unibe.ch/icingaweb2/director/dashboard?name=hosts#!/icingaweb2/director/hostgroups - - $ch --set groups '["iml", "iml-server"]' + vars.platform=${MY_Platform} \ + vars.os=${MY_OSName}${MY_OSMajorVersion} + " + # ----- set host type + # check if host is in a private network: + if echo "$MY_IP" | grep -E "${regexPrivateNetworks}" >/dev/null + then + JSONPARAMS+='imports[]="${hostImportPrivate}" ' + else + JSONPARAMS+='imports[]="${hostImportReachable}" ' + fi - # ... and add some others - # $ch --add groups \"iml-phase-$phase\" + # port checks initiated by icinga server to monitor client + if [ -n "${host_vars_tcpport}" -a "${host_vars_tcpport}" != "[]" ]; then + JSONPARAMS+='vars.tcp_port=${host_vars_tcpport} ' + fi - ) 2>/dev/null + # ----- host groups + # all host groups must exist in director - otherwise the creation + # of a host will fail + JSONPARAMS+="${hostDefaultgroups} " - # ----- generate data and send to DIRECTOR - # DATA=`$ch --json 2>/dev/null` - # $ch --flush 2>/dev/null + echo "$JSONPARAMS" } # ............................................................ - # set $ch to store all object vars - # UNUSED see response of GET director/commands/templates - # function _generateJsonForCommand(){ - # export CFGSTORAGE="command-${IDC_command__obj_name}" - # ( - # $ch --flush - # $ch --set object_name "\"${IDC_command__obj_name}\"" - # $ch --set object_type \"template\" - # - # ) 2>/dev/null - # } - - # ............................................................ - # set $ch to store all object vars + # generate json parameters for jo + # global int checkInterval fetched in check configuration by _parseCheckConfig + # global string IDC_service__obj_name generated var from check name in _generateVarsByCheckname + # global string IDC_command__obj_name generated var from check name in _generateVarsByCheckname function _generateJsonForServicetemplate(){ - export CFGSTORAGE="${MY_NAME}-service-${IDC_service__obj_name}" - ( - $ch --flush - $ch --set object_name "\"${IDC_service__obj_name}\"" - $ch --set check_command \"${IDC_command__obj_name}\" - $ch --set object_type \"template\" + local JSONPARAMS=" + object_name="\"${IDC_service__obj_name}\"" + check_command=\""${IDC_command__obj_name}\"" + object_type=template - $ch --set enable_active_checks false - $ch --set enable_passive_checks true + enable_active_checks=false + enable_passive_checks=true - $ch --set check_interval "\"${checkInterval}s\"" # see _parseCheckConfig FILE + check_interval="\"${checkInterval}s\"" # graphite - # $ch --set enable_perfdata true - # $ch --set vars.check_command \"${checkName}\" # for graphite plugin - + enable_perfdata=true + vars.check_command=\"${checkName}\" + " if [ ! -z "${checkIcon}" ]; then - $ch --set icon_image \"${checkIcon}\" - $ch --set icon_image_alt \"${checkName}\" + JSONPARAMS+="icon_image=\"${checkIcon}\" icon_image_alt=\"${checkName}\" " fi if [ ! -z "${checkMaxAttempts}" ]; then - $ch --set max_check_attempts \"${checkMaxAttempts}\" + JSONPARAMS+="max_check_attempts=${checkMaxAttempts}" fi - - - ) 2>/dev/null + echo "$JSONPARAMS" } # ............................................................ - # set $ch to store all object vars + # generate json parameters for jo function _generateJsonForSvclink(){ - export CFGSTORAGE="${MY_NAME}-servicelink-${IDC_svcathost__obj_name}" - ( - $ch --flush - $ch --set object_name "\"${IDC_svcathost__obj_name}\"" - $ch --set object_type \"object\" - $ch --set host "\"${MY_NAME}\"" - $ch --set imports "[ \"${IDC_service__obj_name}\" ]" - ) 2>/dev/null + local JSONPARAMS=" + object_name="\"${IDC_svcathost__obj_name}\"" + check_type=object + host=${MY_NAME} + imports[]="\"${IDC_service__obj_name}\"" + " + echo "JSONPARAMS" } # ............................................................ @@ -271,7 +234,7 @@ typeset cfg_dryrun=false _sUrlDelete=director/host?name=${_object_name} _existFilter="object_name" - _generateJsonForHost + _jsonparams="$( _generateJsonForHost )" ;; 'service') @@ -286,7 +249,7 @@ typeset cfg_dryrun=false _sUrlDelete=director/service?name=${_object_name} _existFilter='"object_name": ' - _generateJsonForServicetemplate + _jsonparams="$( _generateJsonForServicetemplate )" ;; 'svclink') @@ -303,7 +266,7 @@ typeset cfg_dryrun=false # _existFilter="object_name.*${IDC_svcathost__obj_name}" _existFilter='"object_name": ' - _generateJsonForSvclink + _jsonparams="$( _generateJsonForSvclink )" ;; *) @@ -361,12 +324,10 @@ typeset cfg_dryrun=false return fi - # --- get json data of object if [ $_bSendData = true ]; then - _jsondata=$($ch --json 2>/dev/null) + _jsondata=$( eval jo -p -d. $_jsonparams ) fi - $ch --flush 2>/dev/null # --- http request if [ ${_paramDryrun} = false ]; then @@ -377,7 +338,7 @@ typeset cfg_dryrun=false exit 1 fi if [ $_bShowResponse = true ]; then - http.getResponseHeader + # http.getResponseHeader http.getResponse fi @@ -427,22 +388,6 @@ typeset cfg_dryrun=false # ---------------------------------------------------------------------- - - # ............................................................ - # helper to create a base config for the current host - # UNUSED - function UNUSED_initHostdata(){ - export CFGSTORAGE="${MY_NAME}-directorhost" - ( - $ch --flush - $ch --set object_name \"$MY_NAME\" - $ch --set object_type '"object"' - $ch --set address \"$MY_IP\" - $ch --set display_name \"$MY_NAME\" - ) 2>/dev/null - } - - # ............................................................ # create a host with PUT on director API function hostCreate(){ @@ -539,12 +484,9 @@ typeset cfg_dryrun=false IDC_command__obj_name="${checkName}" IDC_service__obj_name="service-template_for_command_${checkName}" IDC_svcathost__obj_name="$(_getName4Svcathost ${checkName})" - # IDC_service__obj_name="${checkName}" - # IDC_svcathost__obj_name="${checkName}" - IDC_command__cachefile="${dir_data}/command_${checkName}__at-director.txt" - # IDC_service__cachefile="${dir_data}/all_defined_services__at-director.txt" - # IDC_svcathost__cachefile="${dir_data}/all_services_on_host__at-director.txt" + # set | grep "^IDC" + } @@ -553,22 +495,20 @@ typeset cfg_dryrun=false # create a service in Icinga director # uses global variables only function serviceCreateOrUpdate(){ - _h2 "${FUNCNAME[0]}()" - - local sMode=update - local sMethod=POST - local _sUrl="director/service?name=${IDC_service__obj_name}" + # _h2 "${FUNCNAME[0]}()" + echo ">>> ${FUNCNAME[0]}() - ${IDC_service__obj_name}" - ObjAction exists service - if [ $? -ne 0 ]; then - ObjAction create service - else - ObjAction update service + local _action=create + if ObjAction exists service; then + _action=update fi - if [ $? -ne 0 ]; then - echo "ERROR :/" + + if ObjAction $_action service; then + echo "OK $_action service ${IDC_service__obj_name}" + return 0 else - echo "OK" + echo "ERROR :/ $_action service ${IDC_service__obj_name}" + return 1 fi } @@ -577,25 +517,26 @@ typeset cfg_dryrun=false # create a service in Icinga director # param string filename of check config function serviceCreateByCfgFile(){ - _h2 "${FUNCNAME[0]}($1) - create single service of given file" + # _h2 "${FUNCNAME[0]}($1) - create single service of given file" + echo ">>>>>> ${FUNCNAME[0]}($1) - create single service of given file" _parseCheckConfig "${1}" _generateVarsByCheckname "${checkName}" # create command if it does not exist - serviceCreateOrUpdate - - ObjAction exists service - if [ $? -eq 0 ]; then - ObjAction exists svclink - if [ $? -ne 0 ]; then - ObjAction create svclink + if serviceCreateOrUpdate >/dev/null ; then + if ! ObjAction exists svclink; then + if ObjAction create svclink; then + echo "OK: linked service ${checkName} on host [$MY_NAME] was created" + else + echo "ERROR :-/ unable to create linked service ${checkName} on host [$MY_NAME]" + fi else echo "SKIP: linked service on host [${IDC_svcathost__obj_name}] exists" # TODO, uncomment -- wenn es sinnvolle Features gibt # ObjAction update svclink fi else - echo "SKIP link ... service template for ${checkName} not ready." + echo "SKIP: service ${checkName} not ready - unable to create a service link." fi } @@ -608,9 +549,18 @@ typeset cfg_dryrun=false # loop over all services and create for mycheckfile in $(getChecks) do - serviceCreateByCfgFile "${mycheckfile}" - echo + serviceCreateByCfgFile "${mycheckfile}" & + done + + # wait until all background processes are done. + # 1 line in output is the header and one sub process is the ps command --> check > 2 items + local _iProcesses=$( getChecks | wc -w ) + while [ $_iProcesses -gt 2 ]; do + echo "Processes: $_iProcesses" + sleep 2 + _iProcesses=$( ps --ppid "$$" | wc -l ) done + echo "Done ${FUNCNAME[0]}" } @@ -861,8 +811,7 @@ do hostDelete ;; '--hs' | '--hostshow') - _generateJsonForHost - $ch --json 2>/dev/null + eval jo -p -d. $( _generateJsonForHost ) ;; # ----- check actions