NRDP in Linux - NO REQUEST HANDLER

Support forum for Nagios Core, Nagios Plugins, NCPA, NRPE, NSCA, NDOUtils and more. Engage with the community of users including those using the open source solutions.
sidserra
Posts: 28
Joined: Thu Jul 24, 2014 6:56 am

Re: NRDP in Linux - NO REQUEST HANDLER

Post by sidserra »

So, I did it, but isn't working. I created a sh script with the whole command inside it. When I tip ./scriptname.sh without the parameters (since whole command is inside it) in the xterm the script works fine, but not in crontab.
lmiltchev wrote:Modify the crontab as such (provide the full path to "send_nrdp.sh"):

Code: Select all

1 * * * * /full/path/to/the/send_nrdp.sh -u "http://serverip/nrdp" -t "nrdptoken" -H "senderhost" -S "statetoshow" -o "messagetoshow."
Hope this helps.
sidserra
Posts: 28
Joined: Thu Jul 24, 2014 6:56 am

Re: NRDP in Linux - NO REQUEST HANDLER

Post by sidserra »

I was testing some front-ends to Cron to figure out how to setup it or why all that I tried didn't work. I used Gnome-Schedule to run a simple task and forcing a log file to the command like:
./send_nrdp.sh -u http://ServerNrdpIp/nrdp -t NrdpToken -H SenderHost -S StateToShow -o MessageToShow > nrdp.log
inside the log file appeared this:
ERROR: The NRDP Server said BAD XML
But if I run the same command in a simple shell it works fine. Then I think that is a some resource in the script that the Cron isn't understand when it runs...
User avatar
lmiltchev
Former Nagios Staff
Posts: 13587
Joined: Mon May 23, 2011 12:15 pm

Re: NRDP in Linux - NO REQUEST HANDLER

Post by lmiltchev »

What is your NRDP version?
Be sure to check out our Knowledgebase for helpful articles and solutions!
sidserra
Posts: 28
Joined: Thu Jul 24, 2014 6:56 am

Re: NRDP in Linux - NO REQUEST HANDLER

Post by sidserra »

I believe to be the version 1.2, I didn`t find any reference about this in the files inside de nrdp zip file. In command line shell works fine, my problem is when I put it in the Cron. I replaced the arguments in the command line in a minimal xml file to the nrdp script doesn`t need to use it (the arguments); with this change, the command line was:
send_nrdp.sh -u "http://serverip/nrdp" -t "nrdptoken" -H "senderhost" -S "statetoshow" -o "messagetoshow."
and now it is:
send_nrdp.sh -u "http://serverip/nrdp" -t "nrdptoken" -f file.xml
Again, in a shell, the command works fine, but in the Cron still appears "ERROR: The NRDP Server said BAD XML".

Another question: I was reading about the nrpe plugin. The nrpe plugin can communicate with a remote server machine with Nagios core installed over the internet without a response from this server? For example, if I install nrpe on a remote machine, this machine can send data to remote server with Nagios installed without this server need to respond to the machine that sent the data? If yes, that's my solution of my problems...

Below you see the whole script in the send_nrdp.sh.

Code: Select all

#!/bin/bash
#
# Copyright (c) 2010-2012 Nagios Enterprises, LLC.
# Written by: Scott Wilkerson (nagios@nagios.org)
#
###########################

PROGNAME=$(basename $0)
RELEASE="Revision 0.3"

print_release() {
    echo "$RELEASE"
}
print_usage() {
    echo ""
    echo "$PROGNAME $RELEASE - Send NRPD script for Nagios"
    echo ""
    echo "Usage: send_nrdp.sh -u URL -t token [options]"
    echo ""
    echo "Usage: $PROGNAME -h display help"
    echo ""
}

print_help() {
        print_usage
        echo ""
        echo "This script is used to send NRPD data to a Nagios server"
        echo ""
        echo "Required:"
        echo "    -u","    URL of NRDP server.  Usually http://<IP_ADDRESS>/nrdp/"
        echo "    -t","    Shared token.  Must be the same token set in NRDP Server"
        echo ""
        echo "Options:"
        echo "    Single Check:"
        echo "        -H    host name"
        echo "        -s    service name"
        echo "        -S    State"
        echo "        -o     output"
        echo ""
        echo "    STDIN:"
        echo "        [-d    delimiter] (default -d \"\\t\")"
        echo "        With only the required parameters $PROGNAME is capable of"
        echo "        processing data piped to it either from a file or other"
        echo "        process.  By default, we use \t as the delimiter however this"
        echo "        may be specified with the -d option data should be in the"
        echo "        following formats one entry per line."
        echo "        For Host checks:"
        echo "        hostname    State    output"
        echo "        For Service checks"
        echo "        hostname    servicename    State    output"
        echo ""
        echo "    File:"
        echo "        -f /full/path/to/file"
        echo "        This file will be sent to the NRDP server specified in -u"
        echo "        The file should be an XML file in the following format"
        echo "        ##################################################"
        echo ""
        echo "        <?xml version='1.0'?>"
        echo "        <checkresults>"
        echo "          <checkresult type=\"host\" checktype=\"1\">"
        echo "            <hostname>YOUR_HOSTNAME</hostname>"
        echo "            <state>0</state>"
        echo "            <output>OK|perfdata=1.00;5;10;0</output>"
        echo "          </checkresult>"
        echo "          <checkresult type=\"service\" checktype=\"1\">"
        echo "            <hostname>YOUR_HOSTNAME</hostname>"
        echo "            <servicename>YOUR_SERVICENAME</servicename>"
        echo "            <state>0</state>"
        echo "            <output>OK|perfdata=1.00;5;10;0</output>"
        echo "          </checkresult>"
        echo "        </checkresults>"
        echo "        ##################################################"
        echo ""
        echo "    Directory:"
        echo "        -D /path/to/temp/dir"
        echo "        This is a directory that contains XML files in the format"
        echo "        above.  Additionally, if the -d flag is specified, $PROGNAME"
        echo "        will create temp files here if the server could not be reached."
        echo "        On additional calls with the same -D path, if a connection to"
        echo "        the server is successful, all temp files will be sent."
        exit 0
}

send_data() {
    pdata="token=$token&cmd=submitcheck&XMLDATA=$1"
    if [ ! "x$curl" == "x" ];then
        rslt=`curl -f --silent --insecure -d "$pdata" "$url/"`
        ret=$?
    else
        rslt=`wget -q -O - --post-data="$pdata" "$url/"`
        ret=$?
    fi
    status=`echo $rslt | sed -n 's|.*<status>\(.*\)</status>.*|\1|p'`
    message=`echo $rslt | sed -n 's|.*<message>\(.*\)</message>.*|\1|p'`
    if [ $ret != 0 ];then
        echo "ERROR: could not connect to NRDP server at $url"
        # verify we are not processing the directory already and then write to the directory
        if [ ! "$2" ] && [ $directory ];then
            if [ ! -d "$directory" ];then
                mkdir -p "$directory"
            fi
            # This is where we write to the tmp directory
            echo $xml > `mktemp $directory/nrdp.XXXXXX`
        fi
        exit 1
    fi
    
    if [ "$status" != "0" ];then
        # This means we couldn't connect to NRPD server
        echo "ERROR: The NRDP Server said $message"
        # verify we are not processing the directory already and then write to the directory
        if [ ! "$2" ] && [ $directory ];then
            if [ ! -d "$directory" ];then
                mkdir -p "$directory"
            fi
            # This is where we write to the tmp directory
            echo $xml > `mktemp $directory/nrdp.XXXXXX`
        fi
        
        exit 2
    fi
    
    # If this was a directory call and was successful, remove the file
    if [ $2 ] && [ "$status" == "0" ];then
        rm -f "$2"
    fi
    # If we weren't successful error
    if [ $ret != 0 ];then
        echo "exited with error "$ret
        exit $ret
    fi
}

# Parse parameters

while getopts "u:t:H:s:S:o:f:d:c:D:hv" option
do
  case $option in
    u) url=$OPTARG ;;
    t) token=$OPTARG ;;
    H) host=$OPTARG ;;
    s) service=$OPTARG ;;
    S) State=$OPTARG ;;
    o) output=$OPTARG ;;
    f) file=$OPTARG ;;
    d) delim=$OPTARG ;;
    c) checktype=$OPTARG ;;
    D) directory=$OPTARG ;;
    h) print_help 0;;
    v) print_release
        exit 0 ;;
  esac
done

if [ ! $checktype ]; then
 checktype=1
fi
if [ ! $delim ]; then
 delim=`echo -e "\t"`
fi

if [ "x$url" == "x" -o "x$token" == "x" ]
then
  echo "Usage: send_nrdp -u url -t token"
  exit 1
fi
# detecting curl 
if [[ `which curl` =~ "/curl" ]]
 then curl=1; 
fi
# detecting wget if we don't have curl
if [[ `which wget` =~ "/wget" ]]
then
    wget=1;
fi

if [[ ! $curl && ! $wget ]];
then
  echo "Either curl or wget are required to run $PROGNAME"
  exit 1
fi
checkcount=0
if [ $host ]; then
    xml=""
    # we are not getting piped results
    if [ "$host" == "" ] || [ "$State" == "" ]; then
        echo "You must provide a host -H and State -S"
        exit 2
    fi
    if [ "$service" != "" ]; then
        xml="$xml<checkresult type='service' checktype='$checktype'><servicename>$service</servicename>"
    else
        xml="$xml<checkresult type='host' checktype='$checktype'>"
    fi
    xml="$xml<hostname>$host</hostname><state>$State</state><output>$output</output></checkresult>"
    checkcount=1
fi
# Detect STDIN
########################
if [ ! -t 0 ]; then
    xml=""
    # we know we are being piped results
    IFS=$delim
    
    while read -r line ; do
        arr=($line)
        if [ ${#arr[@]} != 0 ];then
            if [[ ${#arr[@]} < 3 ]] || [[ ${#arr[@]} > 4 ]];then
                echo "ERROR: STDIN must be either 3 or 4 fields long, I found "${#arr[@]}
            else
                if [ ${#arr[@]} == 4 ]; then
                    xml="$xml<checkresult type='service' checktype='$checktype'>
                    <servicename>${arr[1]}</servicename>
                    <hostname>${arr[0]}</hostname>
                    <state>${arr[2]}</state>
                    <output>${arr[3]}</output>"
                else
                    xml="$xml<checkresult type='host' checktype='$checktype'>
                    <hostname>${arr[0]}</hostname>
                    <state>${arr[1]}</state>
                    <output>${arr[2]}</output>"
                fi
                
                xml="$xml</checkresult>"
                checkcount=$[checkcount+1]
            fi
        fi
    done
    IFS=" "
fi
if [ $host ] || [ ! -t 0 ] ;then
    xml="<?xml version='1.0'?><checkresults>$xml</checkresults>"
    send_data "$xml"
    echo "Sent $checkcount checks to $url"
fi
if [ $file ];then
    xml=`cat $file`
    send_data "$xml"
fi
if [ $directory ];then
    #echo "Processing directory..."
    for f in `ls $directory`
    do
      #echo "Processing $f file..."
      # take action on each file. $f store current file name
      xml=`cat $directory/$f`
      #echo $xml
      send_data "$xml" "$directory/$f"
    done
    
fi
lmiltchev wrote:What is your NRDP version?
Last edited by tmcdonald on Tue Dec 15, 2015 10:30 am, edited 1 time in total.
Reason: Please use [code][/code] tags around long output
tmcdonald
Posts: 9117
Joined: Mon Sep 23, 2013 8:40 am

Re: NRDP in Linux - NO REQUEST HANDLER

Post by tmcdonald »

What are the permissions on the "file.xml" file? It may be that the user running the cron does not have read permissions so it can't send the XML within.
Former Nagios employee
sidserra
Posts: 28
Joined: Thu Jul 24, 2014 6:56 am

Re: NRDP in Linux - NO REQUEST HANDLER

Post by sidserra »

Really? Even running as root? In the remote machine, this script creates a xml file and sends it to NRDP server and the NRDP server sends it to the Nagios Server (both in the same machime server). As I wrote, the script runs fine as root or not root users, but only in the shell...

tmcdonald wrote:What are the permissions on the "file.xml" file? It may be that the user running the cron does not have read permissions so it can't send the XML within.
User avatar
lmiltchev
Former Nagios Staff
Posts: 13587
Joined: Mon May 23, 2011 12:15 pm

Re: NRDP in Linux - NO REQUEST HANDLER

Post by lmiltchev »

Can you show what you have in the crontab at the moment? Do you have the "scriptname.sh" that you put together?
Be sure to check out our Knowledgebase for helpful articles and solutions!
sidserra
Posts: 28
Joined: Thu Jul 24, 2014 6:56 am

Re: NRDP in Linux - NO REQUEST HANDLER

Post by sidserra »

More than ever, excuse me my poor English...

I figure out what was happening with the script. The short history: there is a little problem with the script to work in Cron environment. the test executed by bash ("-t" = 0 checks stdin is an interactive shell and "-t" = 1 checks if stdout is an interactive shell) is flawed. Depending on the type of executed tests can return "false" even in an interactive environment, as in the case of cron environment. Then the script uses the logic that if the stdin is not an interactive shell, then only may be getting arguments through pipe. As this process is processed after of the command line parameters, what was happening is that the parameters were processed and recorded in the "xml" variable, but later the parameters were cleared and processed as if a pipe were active. As the pipe had no content, the resulting XML was an empty file. That's why the "invalid xml" message.

When I ran the script from the command line, it worked because all parameters still were being processed, but the test in line 200 did, correctly, the script skip the routine that erased the contents of variable "xml".

So the line 200 looked like this:
if [! PS1 z $]; then
This test is safer. In a shell the variable PS1 defines the type of prompt to be displayed. Therefore, this variable is always defined in an interactive shell. On the other hand, she obviously does not exist in environments without prompt.

To make the script more functional the line 231 was changed too.

Below I posted the whole script with the changes. Now it's possible use it in Crontab with no problems. Don't forget to set chmod of this file like a executable (chmod +x). I put it in the /usr/local/bin and I call it in Cron with the same way posted before here.

Code: Select all

#!/bin/bash
#
# Copyright (c) 2010-2012 Nagios Enterprises, LLC.
# Written by: Scott Wilkerson (nagios@nagios.org)
#
###########################

PROGNAME=$(basename $0)
RELEASE="Revision 0.3"

print_release() {
    echo "$RELEASE"
}
print_usage() {
    echo ""
    echo "$PROGNAME $RELEASE - Send NRPD script for Nagios"
    echo ""
    echo "Usage: send_nrdp.sh -u URL -t token [options]"
    echo ""
    echo "Usage: $PROGNAME -h display help"
    echo ""
}

print_help() {
        print_usage
        echo ""
        echo "This script is used to send NRPD data to a Nagios server"
        echo ""
        echo "Required:"
        echo "    -u","    URL of NRDP server.  Usually http://<IP_ADDRESS>/nrdp/"
        echo "    -t","    Shared token.  Must be the same token set in NRDP Server"
        echo ""
        echo "Options:"
        echo "    Single Check:"
        echo "        -H    host name"
        echo "        -s    service name"
        echo "        -S    State"
        echo "        -o     output"
        echo ""
        echo "    STDIN:"
        echo "        [-d    delimiter] (default -d \"\\t\")"
        echo "        With only the required parameters $PROGNAME is capable of"
        echo "        processing data piped to it either from a file or other"
        echo "        process.  By default, we use \t as the delimiter however this"
        echo "        may be specified with the -d option data should be in the"
        echo "        following formats one entry per line."
        echo "        For Host checks:"
        echo "        hostname    State    output"
        echo "        For Service checks"
        echo "        hostname    servicename    State    output"
        echo ""
        echo "    File:"
        echo "        -f /full/path/to/file"
        echo "        This file will be sent to the NRDP server specified in -u"
        echo "        The file should be an XML file in the following format"
        echo "        ##################################################"
        echo ""
        echo "        <?xml version='1.0'?>"
        echo "        <checkresults>"
        echo "          <checkresult type=\"host\" checktype=\"1\">"
        echo "            <hostname>YOUR_HOSTNAME</hostname>"
        echo "            <state>0</state>"
        echo "            <output>OK|perfdata=1.00;5;10;0</output>"
        echo "          </checkresult>"
        echo "          <checkresult type=\"service\" checktype=\"1\">"
        echo "            <hostname>YOUR_HOSTNAME</hostname>"
        echo "            <servicename>YOUR_SERVICENAME</servicename>"
        echo "            <state>0</state>"
        echo "            <output>OK|perfdata=1.00;5;10;0</output>"
        echo "          </checkresult>"
        echo "        </checkresults>"
        echo "        ##################################################"
        echo ""
        echo "    Directory:"
        echo "        -D /path/to/temp/dir"
        echo "        This is a directory that contains XML files in the format"
        echo "        above.  Additionally, if the -d flag is specified, $PROGNAME"
        echo "        will create temp files here if the server could not be reached."
        echo "        On additional calls with the same -D path, if a connection to"
        echo "        the server is successful, all temp files will be sent."
        exit 0
}

send_data() {
    pdata="token=$token&cmd=submitcheck&XMLDATA=$1"
    if [ ! "x$curl" == "x" ];then
        rslt=`curl -f --silent --insecure -d "$pdata" "$url/"`
        ret=$?
    else
        rslt=`wget -q -O - --post-data="$pdata" "$url/"`
        ret=$?
    fi
    status=`echo $rslt | sed -n 's|.*<status>\(.*\)</status>.*|\1|p'`
    message=`echo $rslt | sed -n 's|.*<message>\(.*\)</message>.*|\1|p'`
    if [ $ret != 0 ];then
        echo "ERROR: could not connect to NRDP server at $url"
        # verify we are not processing the directory already and then write to the directory
        if [ ! "$2" ] && [ $directory ];then
            if [ ! -d "$directory" ];then
                mkdir -p "$directory"
            fi
            # This is where we write to the tmp directory
            echo $xml > `mktemp $directory/nrdp.XXXXXX`
        fi
        exit 1
    fi
    
    if [ "$status" != "0" ];then
        # This means we couldn't connect to NRPD server
        echo "ERROR: The NRDP Server said $message"
        # verify we are not processing the directory already and then write to the directory
        if [ ! "$2" ] && [ $directory ];then
            if [ ! -d "$directory" ];then
                mkdir -p "$directory"
            fi
            # This is where we write to the tmp directory
            echo $xml > `mktemp $directory/nrdp.XXXXXX`
        fi
        
        exit 2
    fi
    
    # If this was a directory call and was successful, remove the file
    if [ $2 ] && [ "$status" == "0" ];then
        rm -f "$2"
    fi
    # If we weren't successful error
    if [ $ret != 0 ];then
        echo "exited with error "$ret
        exit $ret
    fi
}

# Parse parameters

while getopts "u:t:H:s:S:o:f:d:c:D:hv" option
do
  case $option in
    u) url=$OPTARG ;;
    t) token=$OPTARG ;;
    H) host=$OPTARG ;;
    s) service=$OPTARG ;;
    S) State=$OPTARG ;;
    o) output=$OPTARG ;;
    f) file=$OPTARG ;;
    d) delim=$OPTARG ;;
    c) checktype=$OPTARG ;;
    D) directory=$OPTARG ;;
    h) print_help 0;;
    v) print_release
        exit 0 ;;
  esac
done

if [ ! $checktype ]; then
 checktype=1
fi
if [ ! $delim ]; then
 delim=`echo -e "\t"`
fi

if [ "x$url" == "x" -o "x$token" == "x" ]
then
  echo "Usage: send_nrdp -u url -t token"
  exit 1
fi
# detecting curl 
if [[ `which curl` =~ "/curl" ]]
 then curl=1; 
fi
# detecting wget if we don't have curl
if [[ `which wget` =~ "/wget" ]]
then
    wget=1;
fi

if [[ ! $curl && ! $wget ]];
then
  echo "Either curl or wget are required to run $PROGNAME"
  exit 1
fi
checkcount=0
if [ $host ]; then
    xml=""
    # we are not getting piped results
    if [ "$host" == "" ] || [ "$State" == "" ]; then
        echo "You must provide a host -H and State -S"
        exit 2
    fi
    if [ "$service" != "" ]; then
        xml="$xml<checkresult type='service' checktype='$checktype'><servicename>$service</servicename>"
    else
        xml="$xml<checkresult type='host' checktype='$checktype'>"
    fi
    xml="$xml<hostname>$host</hostname><state>$State</state><output>$output</output></checkresult>"
    checkcount=1
fi
# Detect STDIN
########################
if [ ! -z "$PS1" ]; then
    xml=""
    # we know we are being piped results
    IFS=$delim
    
    while read -r line ; do
        arr=($line)
        if [ ${#arr[@]} != 0 ];then
            if [[ ${#arr[@]} < 3 ]] || [[ ${#arr[@]} > 4 ]];then
                echo "ERROR: STDIN must be either 3 or 4 fields long, I found "${#arr[@]}
            else
                if [ ${#arr[@]} == 4 ]; then
                    xml="$xml<checkresult type='service' checktype='$checktype'>
                    <servicename>${arr[1]}</servicename>
                    <hostname>${arr[0]}</hostname>
                    <state>${arr[2]}</state>
                    <output>${arr[3]}</output>"
                else
                    xml="$xml<checkresult type='host' checktype='$checktype'>
                    <hostname>${arr[0]}</hostname>
                    <state>${arr[1]}</state>
                    <output>${arr[2]}</output>"
                fi
                
                xml="$xml</checkresult>"
                checkcount=$[checkcount+1]
            fi
        fi
    done
    IFS=" "
fi
if [ $host ] || [ ! -z "$PS1" ] ;then
    xml="<?xml version='1.0'?><checkresults>$xml</checkresults>"
    send_data "$xml"
    echo "Sent $checkcount checks to $url"
fi
if [ $file ];then
    xml=`cat $file`
    send_data "$xml"
fi
if [ $directory ];then
    #echo "Processing directory..."
    for f in `ls $directory`
    do
      #echo "Processing $f file..."
      # take action on each file. $f store current file name
      xml=`cat $directory/$f`
      #echo $xml
      send_data "$xml" "$directory/$f"
    done
    
fi
lmiltchev wrote:Can you show what you have in the crontab at the moment? Do you have the "scriptname.sh" that you put together?
Last edited by tmcdonald on Tue Dec 15, 2015 10:30 am, edited 1 time in total.
Reason: Please use [code][/code] tags around long output
scottwilkerson
DevOps Engineer
Posts: 19396
Joined: Tue Nov 15, 2011 3:11 pm
Location: Nagios Enterprises
Contact:

Re: NRDP in Linux - NO REQUEST HANDLER

Post by scottwilkerson »

Thanks!
Former Nagios employee
Creator:
ahumandesign.com
enneagrams.com
peter19x
Posts: 119
Joined: Tue Dec 08, 2015 10:16 am

Re: NRDP in Linux - NO REQUEST HANDLER

Post by peter19x »

Just had the same error and you saved my life and soo much time. thanks
Locked