Ad Widget

Collapse

External script receives too many parameters

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • frater
    Senior Member
    • Oct 2010
    • 340

    #1

    External script receives too many parameters

    I wanted to use a script that was already working on its own inside Zabbix
    It returns when a certificate is about to expire.

    Somehow it wasn't working for Zabbix. The first thing you check is permissions, but after some debugging it turned out it was receiving more parameters than I expected (or should???).

    I'm feeding it with {HOST.CONN} and I expect this {MACRO} to resolve to the DNS or IP, whatever I set it to be primary.
    The port was something I don't need now, so the key is "certexpire[ {HOST.CONN1} ]"

    It turned out I was getting a repetition of HOSTS and the 2nd parameter ($2) with false info.

    I assume this is a bug?
    Can someone confirm/deny this?

    The line "PORT=443" is my workaround......
    The script is now working as it should.


    This is the script:
    Code:
    #!/bin/bash
    export PATH=${PATH}:/usr/local/sbin:/sbin:/usr/sbin:/bin:/usr/bin
    HOST=$1
    PORT=$2
    
    [ -z "${HOST}" ] && exit 1
    [ -z "${PORT}" ] && PORT=443
    PORT=443
    
    EXPIRE_DATE=`echo "" | openssl s_client -connect ${HOST}:${PORT} 2>/dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | openssl x509 -enddate -noout 2>/dev/null|  sed 's/notAfter\=//'`
    
    if [ -z "${EXPIRE_DATE}" ]; then
      echo '-2'
    else
      EXPIRE_SECS=`date -d "${EXPIRE_DATE}" +%s`
      EXPIRE_TIME=$(( ${EXPIRE_SECS} - `date +%s` ))
      echo $(( ${EXPIRE_TIME} / 24 / 3600 ))
    fi
    Zabbix agents on Linux, FreeBSD, Windows, AVM-Fritz!box, DD-WRT and QNAP
  • untergeek
    Senior Member
    Zabbix Certified Specialist
    • Jun 2009
    • 512

    #2
    HOST.CONN: IP and host DNS name depending on host settings.

    That's why you're getting multiples. There an AND in there.

    External scripts also passes things curiously. If you call an external script with no arguments, e.g. an item with no variable, then the zabbix hostname (whatever you call the host) is sent, whether you use it or not. You can pass more than one argument, e.g. "more than one value" space or comma separated but enclosed in quotes, but the entire string will be considered the second argument, i.e. $2

    What I interpret that to mean is that HOST.CONN is sending "hostname.example.com 10.0.0.1" or some such and it is being considered the entirety of $2.

    Knowing this allows you to work around it. For example, you could
    Code:
    echo $2 | awk '{print $1}'
    to get the first part of the "bundle arg" as a new variable. You can still use HOST.CONN in this way if you need to. Far better, I would think, would be to do one of three things.

    1. Send the IP {IPADDRESS} do a reverse lookup and use the FQDN that way.
    2. Send the FQDN {HOST.DNS} and use that.
    3. If it's something else, make a custom macro and send that {$MACRO}

    Comment

    • frater
      Senior Member
      • Oct 2010
      • 340

      #3
      I decided to debug it by adding the command
      Code:
      echo "$*" >>/tmp/remotespeed
      I now use the item "remotespeed[ {HOST.CONN1}, 443]"

      It seems the script receives:
      Code:
      10.0.0.9 10.0.0.9, 443
      Isn't the external script interface just buggy?
      And why does it add the comma?

      I can work around it, but I don't think it should be any different than the agent scripts.

      Initially I wanted to create a more general script called "httpspeed", which would be called with
      Code:
      httpspeed[ https://{HOST.CONN1}/Remote/ ]
      And to check for instance the remote webif of a router
      Code:
      httpspeed[ https://{HOST.CONN1}/ , 8080 ]
      But this awkward behaviour makes this impossible.
      Shouldn't I file a bug report?

      BTW, here's the script I'm using to check if the remote portal of a Windows Server is stil working and up to speed. I would rather have a more general script where I would enter the URL in the Zabbix-webif.

      Code:
      #!/bin/bash
      export PATH=${PATH}:/usr/local/sbin:/sbin:/usr/sbin:/bin:/usr/bin
      
      HOST=$1
      
      STATUS=`httping -s -l -c3 -i2 -t4 https://${HOST}/Remote/ | grep -o 'time=.*' |  awk -F= '{print $2}' | sort -n | tail -n2 | head -n1`
      
      if echo "${STATUS}" ] | grep -q ' ms' ; then
       SPEED=`echo "${STATUS}" ] | grep -o '.* ms ' | tr -cd '[0-9.]' | awk -F. '{print $1}'`
       if [ -z "${SPEED}" ] ; then
        echo '-2'
       else
        if echo "${STATUS}" ] | grep -q '302 Found' ; then
         echo "${SPEED}"
        else
         echo '-1'
        fi
       fi
      else
       echo '-2'
      fi
      Last edited by frater; 03-08-2011, 01:54.
      Zabbix agents on Linux, FreeBSD, Windows, AVM-Fritz!box, DD-WRT and QNAP

      Comment

      • untergeek
        Senior Member
        Zabbix Certified Specialist
        • Jun 2009
        • 512

        #4
        That's exactly what I said. External scripts get one arg automatically, the Zabbix hostname. The second is optional and is specified in square brackets. You can add as many things as you like within the brackets, but Zabbix will interpret it as one big argument—spaces, commas and all, just like your included example.

        It may be interpreted as a bug. I personally would like the option to pass more arguments in a logical, comma separated way. However, these are the cards we've been dealt up through revision 1.8.5. You can split the uber-argument with some clever logic, or you can revise your plan and only send one argument—whatever works best for you.

        Comment

        • untergeek
          Senior Member
          Zabbix Certified Specialist
          • Jun 2009
          • 512

          #5
          To elaborate:

          Code:
          ALL_ARGS=$2
          # ALL_ARGS="http://10.0.0.9,/REMOTE,8080"
          
          PROTO_URL=$(echo $ALL_ARGS | awk -F, '{print $1}')
          URI=$(echo $ALL_ARGS | awk -F, '{print $2}')
          PORT=$(echo $ALL_ARGS | awk -F, '{print $3}')
          
          URL=${PROTO_URL}:${PORT}${URI}
          
          # URL="http://10.0.0.9:8080/REMOTE"
          It's not necessarily the best way to fix the situation, but it's really simple to work around when you know what's going on.

          Comment

          • frater
            Senior Member
            • Oct 2010
            • 340

            #6
            My workaround is this:

            Code:
            echo "${BASH_SOURCE}" | grep -q "zabbix" && shift 1
            I want to use that command on the CLI just like I expect it in zabbix.
            Initially I wanted to use the $USER variable, but to my surprise it was empty (??).

            Because the scripts in /etc/zabbix/externalscripts are merely symbolic links to scripts placed in /usr/local/sbin/
            I therefore decided to use the variable "BASH_SOURCE"

            I thought maybe it was something "dash" does (I hate this shell), but after doing this:
            Code:
            rm /bin/sh
            ln -s /bin/bash /bin/sh
            It was still the same.

            Well...
            I now have my workaround.
            I only need to use the parameters literally in the zabbix webif....
            Last edited by frater; 03-08-2011, 09:31.
            Zabbix agents on Linux, FreeBSD, Windows, AVM-Fritz!box, DD-WRT and QNAP

            Comment

            • frater
              Senior Member
              • Oct 2010
              • 340

              #7
              With your input I'm now able to make the script I initially wanted to make.
              This script is more general and can be used for more than just the remote portal of Windows Small Business Server.

              It tests the speed of a URL and will work on the command line and in zabbix

              /etc/zabbix/externalscripts# cat httpspeed
              Code:
              #!/bin/bash
              export PATH=${PATH}:/usr/local/sbin:/sbin:/usr/sbin:/bin:/usr/bin
              
              echo "${BASH_SOURCE}" | grep -q "zabbix" && shift 1
              
              OPTIONS=
              URL="$*"
              RETURN=-1
              COUNTS=2
              
              if [ ! -z "${URL}" ] ; then
               # Check if it's https and modify OPTIONS
               echo "${URL}" | grep -q 'https' && OPTIONS="${OPTIONS} -l"
              
               # Invoke httping
               STATUS=`httping ${OPTIONS} -s -c${COUNTS} -t1 ${URL} 2>/dev/null | grep -o 'time=.*' |  awk -F= '{print $2}' | sort -n | head -n1`
              
               if echo "${STATUS}" ] | grep -q ' ms' ; then
              
                RETURN=-2
                SPEED=`echo "${STATUS}" ]  | grep -o '.* ms ' | tr -cd '0-9.' | awk -F. '{print $1}'`
                STATCODE=`echo "${STATUS}" | awk '{print $3}' | tr -cd '0-9'`
              
                if [ ! -z "${STATCODE}" ] ; then
                 if echo "${STATCODE}" |  egrep -q '^(200|201|202|301|302|303|304)$' ; then
                  RETURN=${SPEED}
                 else
                  RETURN="-${STATCODE}"
                 fi
                fi
               fi
              fi
              echo "${RETURN}"
              Last edited by frater; 03-08-2011, 17:24.
              Zabbix agents on Linux, FreeBSD, Windows, AVM-Fritz!box, DD-WRT and QNAP

              Comment

              Working...