#!/usr/bin/perl -w

# COPYRIGHT:
#
# This software is Copyright (c) 2008 NETWAYS GmbH, Tobias Redel
#                                <support@netways.de>
#
# (Except where explicitly superseded by other copyright notices)
#
#
# LICENSE:
#
# This work is made available to you under the terms of Version 2 of
# the GNU General Public License. A copy of that license should have
# been provided with this software, but in any event can be snarfed
# from http://www.fsf.org.
#
# This work is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301 or visit their web page on the internet at
# http://www.fsf.org.
#
#
# CONTRIBUTION SUBMISSION POLICY:
#
# (The following paragraph is not intended to limit the rights granted
# to you to modify and distribute this software under the terms of
# the GNU General Public License and is only of importance to you if
# you choose to contribute your changes and enhancements to the
# community by submitting them to NETWAYS GmbH.)
#
# By intentionally submitting any modifications, corrections or
# derivatives to this work, or any other work intended for use with
# this Software, to NETWAYS GmbH, you confirm that
# you are the copyright holder for those contributions and you grant
# NETWAYS GmbH a nonexclusive, worldwide, irrevocable,
# royalty-free, perpetual, license to use, copy, create derivative
# works based on those contributions, and sublicense and distribute
# those contributions and any derivatives thereof.
#
# Nagios and the Nagios logo are registered trademarks of Ethan Galstad.


=head1 NAME


submit_event_data.pl - A script for collecting performance data from other
                       Nagios nodes

=head1 SYNOPSIS

submit_event_data.pl -H <hosts>
                     -l  <local-dir>
                     -r <remote-dir>
                     -x <nagios external command interface>
                     [-u| --user <username>]
                     [-s|--sleep <seconds>]
                     [-c|--config  <configfile>]
                     [-h|--help]
                     [-v|--version]

A script for collecting performance data from other Nagios nodes.
This will make sense in environments with distributed monitoring ;-) 

=head1 OPTIONS

=over

=item -H | --hosts <hosts or ips>

Hostnames or ip addresses of the hosts to check for data. A comma separated list...

=item -l | --local-dir <local-dir>

Where will the performance data be stored?

=item -r | --remote-dir <remote-dir>

Target directordy on the remote host

=item -x | --xternal <nagios external command interface>

Path to Nagios' External Command Interface, e.g. /usr/local/nagios/var/rw/nagios.cmd

=item -u | --user <username>

Username for login on hosts

=item -s | --sleep <seconds>

Time to sleep after recieving data from hosts. Default is 60 seconds

=item -c | --config <configfile>

Path to configuration file. When choosing this options, -H, -l and -r not needed

=item -h|--help

Print help message and exit

=item -v|--version

Print version an exit

=cut


use strict;
use Getopt::Long qw(:config no_ignore_case bundling);
use Pod::Usage;
use threads;


# version string
my $version = '0.1';

# get command-line parameters
my ($hosts, $local_dir, $remote_dir, $external_command_interface, $username, $sleep, $config_file, $help, $showVersion);
GetOptions(
   "H|hosts=s"		=> \$hosts,
   "l|local-dir=s"	=> \$local_dir,
   "r|remote-dir=s"	=> \$remote_dir,
   "x|xternal=s"	=> \$external_command_interface,
   "u|user=s"		=> \$username,
   "s|sleep=i"		=> \$sleep,
   "c|config=s"		=> \$config_file,
   "h|help"     	=> \$help,
   "v|version"  	=> \$showVersion
);



# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * #
# should print help?
# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * #

if ($help) { pod2usage(1); }

# configuration by options or config file?
if ($config_file) {
	# source config file
} else {
	if (!$hosts || !$local_dir || !$remote_dir || !$external_command_interface) { pod2usage(1); }	
}



# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * #
# check a few things
# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * #

my @nodes = split(',', $hosts);

# $local_dir exists?
if (! -d $local_dir) { print "ERROR: can't locate directory '$local_dir'"; exit 1; }
if (! -e $external_command_interface) { print "ERROR: no external Commandfile found '$external_command_interface'"; exit 1; }
	
# login on remote host possible and $remote_dir exists?
foreach (@nodes) {
	my $cmd = "ssh -o PasswordAuthentication=no "; if ($username) { $cmd .= $username."@"; } $cmd .= $_." \"ls -d $remote_dir\" 2>/dev/null";
	my $val = system($cmd);
	
	if ($val != 0) {
		if ($val == 512) {
			print "ERROR: Can't locate directory $remote_dir on $_\n"
		} elsif ($val == 65280) {
			print "ERROR: Can't login on $_\n";
		} else {
			print "ERROR: Unknown error during connection / test\n";
		}
		exit 1;
	}
}
	

# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * #
# now, we're ready to run
# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * #

# function for getting files from host
sub get_files {
	my $node = shift;

	my $cmd = "rsync --remove-source-files -az -e ssh "; if ($username) { $cmd .= $username."@"; } $cmd .= "$node:$remote_dir/*.* $local_dir";
	my $val = system($cmd);

	if ($val != 0) { print "ERROR: data sync with $node failed!\n"}

}

# function for processing files to nagios
sub process_files {
	# open $local_dir and search after all possible files to proceed
    opendir(DIR, $remote_dir) || die "can't opendir $remote_dir: $!";
    	while((my $val = readdir(DIR))) {
     		if ($val ne "." && $val ne ".." && $val =~ /\./) {
     			my $cmd =  "[".time()."] PROCESS_FILE;$local_dir/$val;1\n";
     			qx(echo "$cmd" > $external_command_interface);
     		}
		}
    	closedir DIR;		
}

# set up all needed vars
my %thread_handle;
my $counter = '0';

# set up $sleep (if not specified)
if (!$sleep) { $sleep = '60'; }

# start thread for processing files to nagios
$thread_handle{$counter} = threads->create(\&process_files);
$counter++;

# start thread for each remote host
foreach(@nodes) {
	$thread_handle{$counter} = threads->create(\&get_files, $_);
	$counter++;
}

# retrieve results from threads
$counter = '0';
foreach(@nodes) {
	$thread_handle{$counter}->join();
	$counter++;
}
