Initial commit, first functionality implemented :-)
authorAlexander Barton <alex@barton.de>
Sun, 13 Dec 2009 17:28:01 +0000 (18:28 +0100)
committerAlexander Barton <alex@barton.de>
Sun, 13 Dec 2009 17:28:01 +0000 (18:28 +0100)
Nagios3 tools nagios-submit-host and nagios-submit-service are
implemented as well as the NagCollect webservice (nagcollect.php).
But the client component is lacking ...

INSTALL [new file with mode: 0644]
Makefile [new file with mode: 0644]
README [new file with mode: 0644]
client/bin/nagcollect [new file with mode: 0755]
server/bin/nagios-submit-host [new file with mode: 0755]
server/bin/nagios-submit-service [new file with mode: 0755]
server/etc/nagcollect.keys [new file with mode: 0644]
server/etc/system.cfg [new file with mode: 0644]
server/web/nagcollect.php [new file with mode: 0644]

diff --git a/INSTALL b/INSTALL
new file mode 100644 (file)
index 0000000..e0d5c5d
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,30 @@
+
+             NagCollect: Nagios Data Collector for Passive Checks
+              Copyright (c)2009 Alexander Barton, alex@barton.de
+
+                                   INSTALL
+
+
+Server
+~~~~~~
+
+1. Run "make install-server".
+
+2. Adjust /etc/nagios3/system.cfg and your Nagios3 templates.
+
+3. Use visudo(8) to add the following to your /etc/sudoers file:
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ALL=(nagios) NOPASSWD: /usr/local/sbin/nagios-submit-host, \
+                        /usr/local/sbin/nagios-submit-service
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+4. Configure client keys in /etc/nagios3/nagcollect.keys.
+
+
+Client
+~~~~~~
+
+1. Run "make install-client".
+
+2. Make sure /usr/local/sbin/nagcollect is run periodically with a valid key.
diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..8a1ed0a
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,36 @@
+#
+# NagCollect -- Nagios Data Collector for Passive Checks
+# Copyright (c)2009 Alexander Barton, alex@barton.de
+#
+
+all:
+
+install:
+       @echo " ** Use make targets 'install-client', 'install-server' and 'install-all'"
+       @echo " ** to install client and/or server components!"
+
+install-all: install-server install-client
+
+install-server:
+       install -d -o nagios -g nagios -m 750 \
+               /var/lib/nagios3/collect
+       [ -r /etc/nagios3/system.cfg ] || \
+        install -D -o nagios -g root -m 640 -p \
+               server/etc/system.cfg /etc/nagios3/system.cfg
+       [ -r /etc/nagios3/nagcollect.keys ] || \
+        install -D -o nagios -g www-data -m 640 -p \
+               server/etc/nagcollect.keys /etc/nagios3/nagcollect.keys
+       install -D -o root -g root -m 755 -p \
+               server/bin/nagios-submit-host /usr/local/sbin/nagios-submit-host
+       install -D -o root -g root -m 755 -p \
+               server/bin/nagios-submit-service /usr/local/sbin/nagios-submit-service
+       install -D -o root -g root -m 644 -p \
+               server/web/nagcollect.php /var/www/nagcollect.php
+
+install-client:
+       install -D -o 0 -g 0 -m 755 -p \
+               client/bin/nagcollect /usr/local/sbin/nagcollect
+
+.PHONY: all install-server install-client
+
+# -eof-
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..17f85bb
--- /dev/null
+++ b/README
@@ -0,0 +1,12 @@
+
+             NagCollect: Nagios Data Collector for Passive Checks
+              Copyright (c)2009 Alexander Barton, alex@barton.de
+
+                                   README
+
+
+NagCollect is a bunch of PHP and shell scripts to enhance Nagios3 to better
+handle passive host and service checks. It consists of some scripts that must
+be installed on the server and others that must run on the clients.
+
+See the file INSTALL for details.
diff --git a/client/bin/nagcollect b/client/bin/nagcollect
new file mode 100755 (executable)
index 0000000..1f845c7
--- /dev/null
@@ -0,0 +1,20 @@
+#!/bin/bash
+#
+# NagCollect -- Nagios Data Collector for Passive Checks
+# Copyright (c)2009 Alexander Barton, alex@barton.de
+#
+
+if [ "$1" = "--help" -o "$1" = "-h" -o $# -lt 5 -o $# -gt 6 ]; then
+       echo "Usage: $0 <server-url> <key> <host> <status> <service> [<text>]"
+       exit 1
+fi
+
+curl --insecure --include \
+       --data-urlencode "key=$2" \
+       --data-urlencode "host=$3" \
+       --data-urlencode "status=$4" \
+       --data-urlencode "service=$5" \
+       --data-urlencode "text=$6" \
+       "$1"
+
+# -eof-
diff --git a/server/bin/nagios-submit-host b/server/bin/nagios-submit-host
new file mode 100755 (executable)
index 0000000..40c991c
--- /dev/null
@@ -0,0 +1,59 @@
+#!/bin/sh
+# nagios-submit-host -- Submit passive host check result
+# 2009-12-11, alex@barton.de
+
+NAME=`basename "$0"`
+CREATE=
+
+Usage() {
+       echo "$NAME [-c] <host> <code> [<text>]"; echo
+       echo "  -c      create new host, if necessary"
+       echo "  <host>  Nagios host ID"
+       echo "  <code>  Status code: 0=OK, 1=Warning, 2=Error, 3=Unknown"
+       echo "  <text>  Optional status message"
+       echo; exit 1
+}
+
+Error() {
+       echo "$NAME: $*"
+       exit 1
+}
+
+[ -r "/etc/nagios3/system.cfg" ] || Error "Can't read /etc/nagios3/system.cfg!"
+. /etc/nagios3/system.cfg 
+
+# Validate command line arguments
+if [ "$1" = "-c" ]; then
+       CREATE=1; shift
+fi
+[ $# -ge 2 -a $# -le 3 ] || Usage
+[ "$2" = 0 -o "$2" = "1" -o "$2" = "2" -o "$2" = "3" ] || Usage
+
+# Validate configuration
+[ -w "$CMDFILE" ] || Error "Can't write to \"$CMDFILE\"!"
+
+time_t=`date +%s`
+host="$1"
+code="$2"
+text="${3:-}"
+
+grep -E "^[[:space:]]+host_name[[:space:]]+${host}\$" "$CFGDIR"/*.cfg >/dev/null 2>&1
+if [ $? -ne 0 ]; then
+       # Host not configured!
+       [ -n "$CREATE" ] || Error "Host \"$host\" not configured!?"
+       echo "Creating new Nagios host configuration for \"$host\" ..."
+       cfg="$CFGDIR/_host_$host.cfg"
+       cat >"$cfg" <<EOF
+define host {
+       use             ${HOST_TEMPLATE_PASSIVE}
+       host_name       $host
+}
+EOF
+       chmod "$CFG_MODE" "$cfg" || Error "chmod(1) failed!"
+       echo "Reloading Nagios configuration ..."
+       "$RCFILE" reload || Error "Failed to reload Nagios configuration!"
+       sleep 1
+fi
+
+cmd="[$time_t] PROCESS_HOST_CHECK_RESULT;$host;$code;$text"
+echo "$cmd" >>"$CMDFILE"
diff --git a/server/bin/nagios-submit-service b/server/bin/nagios-submit-service
new file mode 100755 (executable)
index 0000000..91ae86d
--- /dev/null
@@ -0,0 +1,72 @@
+#!/bin/sh
+# nagios-submit-service -- Submit passive service check result
+# 2009-12-11, alex@barton.de
+
+NAME=`basename "$0"`
+CREATE=
+
+Usage() {
+       echo "$NAME [-c] <host> <service> <code> [<text>]"; echo
+       echo "  -c         create new service, if necessary"
+       echo "  <host>     Nagios host ID"
+       echo "  <service>  Nagios service ID"
+       echo "  <code>     Status code: 0=OK, 1=Warning, 2=Error, 3=Unknown"
+       echo "  <text>     Optional status message"
+       echo; exit 1
+}
+
+Error() {
+       echo "$NAME: $*"
+       exit 1
+}
+
+[ -r "/etc/nagios3/system.cfg" ] || Error "Can't read /etc/nagios3/system.cfg!"
+. /etc/nagios3/system.cfg 
+
+# Validate command line arguments
+if [ "$1" = "-c" ]; then
+       CREATE=1; shift
+fi
+[ $# -ge 3 -a $# -le 4 ] || Usage
+[ "$3" = 0 -o "$3" = "1" -o "$3" = "2" -o "$3" = "3" ] || Usage
+
+# Validate configuration
+[ -w "$CMDFILE" ] || Error "Can't write to \"$CMDFILE\"!"
+
+time_t=`date +%s`
+host="$1"
+service="$2"
+code="$3"
+text="${4:-}"
+
+cfg=`grep -lE "^[[:space:]]+host_name[[:space:]]+${host}\$" "$CFGDIR"/*.cfg`
+[ -n "$cfg" ] || Error "Host \"$host\" not configured!?"
+
+case "$service" in
+       *"_p")
+               # Passive service check; does it exist already?
+               grep -E "^[[:space:]]+service_description[[:space:]]+${service}\$" \
+                       "$cfg" >/dev/null 2>&1
+               if [ $? -ne 0 ]; then
+                       [ -n "$CREATE" ] || \
+                               Error "Service \"$service\" not configured on \"$host\"!?"
+                       echo "Creating new Nagios host configuration for \"$host\" ..."
+                       cat >>"$cfg" <<EOF
+
+define service {
+       use                     ${SERVICE_TEMPLATE_PASSIVE}
+       service_description     $service
+       check_command           ${SERVICE_PASSIVE_CMD}
+       host                    $host
+}
+EOF
+                       chmod "$CFG_MODE" "$cfg" || Error "chmod(1) failed!"
+                       echo "Reloading Nagios configuration ..."
+                       "$RCFILE" reload || Error "Failed to reload Nagios configuration!"
+                       sleep 1
+               fi
+               ;;
+esac
+
+cmd="[$time_t] PROCESS_SERVICE_CHECK_RESULT;$host;$service;$code;$text"
+echo "$cmd" >>"$CMDFILE"
diff --git a/server/etc/nagcollect.keys b/server/etc/nagcollect.keys
new file mode 100644 (file)
index 0000000..332e03d
--- /dev/null
@@ -0,0 +1,3 @@
+# /etc/nagios3/nagcollect.keys
+# Keys allowed by the NagCollect PHP script, one key per line.
+# Empty lines and lines beginning with '#' are ignored.
diff --git a/server/etc/system.cfg b/server/etc/system.cfg
new file mode 100644 (file)
index 0000000..863fa7f
--- /dev/null
@@ -0,0 +1,12 @@
+# /etc/nagios3/system.cfg
+# Configuration file read by NagCollect tools
+
+CFGDIR="/etc/nagios3/conf.d"
+CMDFILE="/var/lib/nagios3/rw/nagios.cmd"
+RCFILE="/etc/init.d/nagios3"
+
+CFG_MODE="640"
+
+HOST_TEMPLATE_PASSIVE="generic-passive-host"
+SERVICE_TEMPLATE_PASSIVE="generic-passive-service"
+SERVICE_PASSIVE_CMD="check_passive"
diff --git a/server/web/nagcollect.php b/server/web/nagcollect.php
new file mode 100644 (file)
index 0000000..308b0c9
--- /dev/null
@@ -0,0 +1,94 @@
+<?php
+/*
+ * NagCollect -- Nagios Data Collector for Passive Checks
+ * Copyright (c)2009 Alexander Barton, alex@barton.de
+ */
+
+define(KEY, 'qw90nm');
+
+function nagiosSubmitHost($host, $status, $text = null)
+{
+       $params  = escapeshellarg($host);
+       $params .= ' ' . escapeshellarg($status);
+       if ($text)
+               $params .= ' ' . escapeshellarg($text);
+       $cmd = 'sudo -u nagios /usr/local/sbin/nagios-submit-host -c ' . $params;
+       exec($cmd, $output, $result);
+       if ($result != 0)
+               error_log("submit-host=$result: " . $output[0]);
+       return ($result == 0);
+}
+
+function nagiosSubmitService($host, $service, $status, $text = null)
+{
+       $params  = escapeshellarg($host);
+       $params .= ' ' . escapeshellarg($service);
+       $params .= ' ' . escapeshellarg($status);
+       if ($text)
+               $params .= ' ' . escapeshellarg($text);
+       $cmd = 'sudo -u nagios /usr/local/sbin/nagios-submit-service -c ' . $params;
+       exec($cmd, $output, $result);
+       if ($result != 0)
+               error_log("submit-service=$result: " . $output[0]);
+       return ($result == 0);
+}
+
+function processRequest($args)
+{
+       // Check that this is a valid (POST-) request
+       if (!isset($args['host']) || !isset($args['status']))
+               return 400;
+
+       // Make sure the authorizsation key is correct
+       if (!isset($args['key']) || $args['key'] != KEY)
+               return 401;
+
+       $host = $args['host'];
+       $status = $args['status'];
+
+       $service = isset($args['service']) ? $args['service'] : null;
+       $text = isset($args['text']) ? $args['text'] : null;
+
+       if (!$service) {
+               // Host Update
+               if (!nagiosSubmitHost($host, $status, $text))
+                       return 500;
+       } else {
+               // Service Update
+               if (!nagiosSubmitHost($host, 0, 'Received passive service check'))
+                       return 500;
+               if (!nagiosSubmitService($host, $service, $status, $text))
+                       return 500;
+       }
+       return 200;
+}
+
+function getHttpStatusText($status)
+{
+       switch ($status) {
+               case 200:       return "OK";
+               case 400:       return "Bad Request";
+               case 401:       return "Unauthorized";
+               case 500:       return "Internal Server Error";
+               default:        return "Unknown";
+       }
+}
+
+$httpStatus = processRequest($_POST);
+$httpStatusText = getHttpStatusText($httpStatus);
+
+$statusText = $httpStatus . ' - ' . $httpStatusText;
+
+header("HTTP/1.0 $httpStatus $ttpStatusText");
+
+?><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+       "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+<head>
+       <meta http-equiv="Content-type" content="text/html; charset=utf-8">
+       <title>NagCollect: <?php echo $statusText ?></title>
+</head>
+<body id="nagcollect">
+<h1><?php echo $statusText ?></h1>
+</body>
+</html>