#!/bin/perl

### CONFIGURE THIS FOR YOUR INSTALLATION ###
$nagiosConfig = "/usr/local/nagios/etc/nagios.cfg";
$batchCheckServiceDescription = "ssh";
### SHOULDN'T NEED TO MODIFY ANYTHING BELOW HERE ###

#
# make_batch_dependencies v1.0 - koreth-nagios@midwinter.com 2003/01/17
#
# Generates service dependencies for a list of hosts whose services are
# checked with the batch_by_ssh script.  All the batched services are
# assumed to depend on the service that runs batch_by_ssh.
#
# Usage:
#	make_batch_dependencies [hostname ...]
#
# See batch_by_ssh for information about the configuration options used
# by this script.
#

use English;

#
# Given a hash of name/value pairs for a batch service, populate our internal
# data structures.
#
sub slurpBatchService {
	local($values);
	local($hostnames);
	local($hostGroup);
	local($serviceNames);
	local($batchType);
	local($commands,$services);
	local($command,$service);
	$values = $_[0];

	$batchType = $$values{"batch_type"};
	$command = $$values{"batch_command"};
	$service = $$values{"service_description"};

	# Don't touch non-batch entries.
	return if $command eq "";

	# Don't touch other batch mechanisms' entries.
	return if $batchType ne "" and $batchType ne "ssh";

	# Combine the host and hostgroup lists into a big list of hostnames.
	$hostnames = $$values{"host_name"};
	if ($$values{"hostgroup_name"} ne "") {
		foreach $hostGroup (split(/,/,$$values{"hostgroup_name"})) {
			foreach $member (split(/,/,$hostGroups{$hostGroup})) {
				$hostnames = $hostnames . "," . $member;
			}
		}
		$hostnames =~ s/^,//;
	}

	# For each host, add the command and description to its hash.
	foreach $host (split(/,/,$hostnames)) {
		$commandsByHost{$host}{$service} = $command;
	}
}

#
# Given a hash of host values, populate our internal data structures if
# appropriate.  We extract the host address and any user variables.
#
sub slurpHost {
	local($values);
	local($hostname);

	$values = $_[0];
	$hostname = $$values{"host_name"};

	if ($hostname ne "" and $$values{"address"} ne "")
	{
		$hostAddresses{$hostname} = $$values{"address"};
	}

	foreach $key (keys %{$values}) {
		# Is this key a macro name?
		if ($key =~ m/^(\$.*\$)$/) {
			$hostMacros{$hostname}{$key} = $$values{$key};
		}
	}
}

#
# Given an object type name and a hash of config items, populate our internal
# data structures if appropriate.
#
sub slurpObject {
	local($objectType);
	local($values);

	$objectType = $_[0];
	$values = $_[1];

	# If this object uses a template, copy the template's values.
	if ($$values{"use"} ne "") {
		local($template);

		$template = $templates{$objectType}{$$values{"use"}};
		foreach $key (keys %{$template}) {
			next if $key =~ m/^(register|use|name|)$/;
			if (! defined($$values{$key})) {
				$$values{$key} = $$template{$key};
			}
		}

		undef $$values{"use"};
	}

	# Stash template objects away
	if ($$values{"name"} ne "") {
		$templates{$objectType}{$$values{"name"}} = $values;
	}
	
	# Ignore non-registered objects
	return if $$values{"register"} eq "0";

	if ($objectType eq "command")
	{
		$checkCommands{$$values{"command_name"}} =
			$$values{"command_line"};
	}

	if ($objectType eq "host")
	{
		&slurpHost($values);
	}

	if ($objectType eq "hostgroup")
	{
		$hostGroups{$$values{"hostgroup_name"}} = $$values{"members"};
	}

	if ($objectType eq "service")
	{
		&slurpBatchService($values);
	}
}


#
# Read a Nagios object config file and slurp up any relevant entries.
# For now this is just check commands and host addresses.
#
# $_[0] = path of object config file.
#
sub slurpObjectConfig {
	local($objectType);

	$objectType = "";
	$argValues = undef;

	open(CONFIG, "<$_[0]") or &doExit("CRITICAL", 2, "$_[0]: $!");
	while (<CONFIG>) {
		chomp;

		# Trim off our magic pseudo-comment token (needed because
		# Nagios complains if it sees unknown keywords)
		$_ =~ s/^\s*#\<\>//;

		# Trim whitespace and comments
		$_ =~ s/^\s+//;
		$_ =~ s/;.*//;
		$_ =~ s/\s+$//;
		next if /^[#;]/;

		if ($objectType ne "") {
			if (m/^\}/) {
				&slurpObject($objectType, $argValues);

				$inObject = 0;
				$objectType = "";
				$argValues = undef;
				next;
			}

			# Remember the key and value.
			if (m/^(\S+)\s+(.*)/) {
				$$argValues{$1} = $2;
			}
		}

		if (m/^define\s+([^\s{]+)/) {
			$objectType = $1;
		}
	}

	close CONFIG;
}


#
# Read the Nagios config file to find the list of object config files, and
# scan each of those for check command definitions.
#
open(NAGIOS, "<$nagiosConfig") or &doExit("CRITICAL", 2, "$nagiosConfig: $!");
while (<NAGIOS>) {
	if (m/^\s*cfg_file=\s*(.*)\s*$/) {
		&slurpObjectConfig($1);
	}
}
close NAGIOS;

if ($#ARGV < 0) {
	@ARGV = keys %commandsByHost;
}

#
# Now loop through the hosts and, for each one, print a dependency definition
# for each batch service on that host.
#
foreach $host (@ARGV) {
	foreach $service (keys %{$commandsByHost{$host}}) {
		print "define servicedependency {\n";
		print "\thost_name\t\t\t$host\n";
		print "\tservice_description\t\t$batchCheckServiceDescription\n";
		print "\tdependent_host_name\t\t$host\n";
		print "\tdependent_service_description\t$service\n";
		print "\texecution_failure_criteria\tn\n";
		print "\tnotification_failure_criteria\tw,u,c\n";
		print "}\n\n";
	}
}
