1213 lines
34 KiB
Perl
Executable File
1213 lines
34 KiB
Perl
Executable File
#!/usr/bin/perl -s
|
|
################################################################################
|
|
#
|
|
# Copyright (c) 2007-2023 Pandora FMS.
|
|
#
|
|
# n2p.pl Reads Nagios 2.x configuration files and replicates the setup
|
|
# using an installed Pandora FMS 1.3.
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; version 2 of the License.
|
|
#
|
|
# This program 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.
|
|
#
|
|
################################################################################
|
|
|
|
package n2p;
|
|
|
|
# All variables have to be declared
|
|
use strict 'vars';
|
|
|
|
use DBI;
|
|
|
|
# DB connection info
|
|
my $dbh;
|
|
my $db_name = "pandora";
|
|
my $db_host = "localhost";
|
|
my $db_port = "3306";
|
|
my $db_user = "pandora";
|
|
my $db_pass = "pandora";
|
|
|
|
# Program version
|
|
my $n2p_version = "0.1";
|
|
my $n2p_build = "071214";
|
|
|
|
# Pandora FMS version
|
|
my $pandora_version = "1.3";
|
|
|
|
# Report file
|
|
my $report_file = "n2p.html";
|
|
|
|
# Found hosts
|
|
my %hosts;
|
|
|
|
# Found host templates
|
|
my %host_templates;
|
|
|
|
# Found groups
|
|
my %groups;
|
|
|
|
# Found services
|
|
my %services;
|
|
|
|
# Found service templates
|
|
my %service_templates;
|
|
|
|
# Found commands
|
|
my %commands;
|
|
|
|
################################################################################
|
|
## SUB write_log
|
|
## Write log messages.
|
|
################################################################################
|
|
sub write_log {
|
|
|
|
if (defined ($::v)) {
|
|
print ("$_[0]\n");
|
|
}
|
|
}
|
|
|
|
################################################################################
|
|
## SUB print_help
|
|
## Print help screen.
|
|
################################################################################
|
|
sub print_help {
|
|
|
|
print ("Usage: $0 [options] <nagios_cfg_file> [nagios_cfg_file] ...\n\n");
|
|
print ("Reads Nagios 2.x configuration files and replicates the setup using an installed Pandora FMS 1.3.\n\n");
|
|
print ("Options:\n\t-a Enable alerts.\n");
|
|
print ("\t-h Generate an HTML report.\n");
|
|
print ("\t-s Simulate, do not change Pandora FMS's database.\n");
|
|
print ("\t-u Undo any changes done to Pandora FMS's database.\n");
|
|
print ("\t-v Be verbose.\n\n");
|
|
}
|
|
|
|
################################################################################
|
|
## SUB write_report
|
|
## Write a report containing all the information collected from Nagios
|
|
## configuration files.
|
|
## TODO: Write Pandora FMS agent and module information.
|
|
################################################################################
|
|
sub write_report {
|
|
my $i;
|
|
my $name;
|
|
my $object;
|
|
my $class = 1;
|
|
|
|
open (FILE_HANDLER, ">$report_file") || die ("Error opening file $report_file for writing.");
|
|
|
|
print FILE_HANDLER
|
|
'<html>
|
|
<style>
|
|
<!--
|
|
* {font-size: 8pt;}
|
|
body {text-align: left; background-color: #f9f9f9;}
|
|
h1, h2 {font: bold 1em Arial, Sans-serif; text-transform: uppercase; color: #786; padding-bottom: 4px; padding-top: 7px;}
|
|
h1 {font-size: 18px; text-align: center; font-weight: bold;}
|
|
h2 {font-size: 15px;}
|
|
a {color: #486787;text-decoration: none;}
|
|
a:hover {color: #003a3a; text-decoration: underline;}
|
|
th {color: #fff; background-color: #786;}
|
|
td.data1 {background-color: #f9f9f9;}
|
|
td.data2 {background-color: #efefef;}
|
|
ul {list-style: none; line-height: 24px; padding: 0px 0px 0px 0px; margin: 0px 0px 0px 0px;}
|
|
.bold {font-weight: bold;}
|
|
-->
|
|
</style>
|
|
|
|
<head>
|
|
<title>n2p Report</title>
|
|
</head>
|
|
|
|
<body>
|
|
<h1>n2p Report</h1>
|
|
<h2><a name="index"></a>Index</h2>
|
|
<p>
|
|
<ul class="bold">
|
|
<li><a href="#host_templates">Host Templates</a></li>
|
|
<li><a href="#hosts">Hosts</a></li>
|
|
<li><a href="#groups">Groups</a></li>
|
|
<li><a href="#service_templates">Service Templates</a></li>
|
|
<li><a href="#services">Services</a></li>
|
|
<li><a href="#commands">Commands</a></li>
|
|
</ul>
|
|
</p>
|
|
<h2><a name="host_templates"></a>Host Templates</h2>
|
|
<p>
|
|
<table border="0">
|
|
<tr>
|
|
<th>Template Name</th>
|
|
<th>Inherits from</th>
|
|
<th>Check Command</th>
|
|
<th>Check Interval (s)</th>
|
|
<th>Notification</th>
|
|
<th>Notification Interval (s)</th>
|
|
</tr>';
|
|
# Host templates
|
|
while (($name, $object) = each (%host_templates)){
|
|
$class = $class == 1 ? 2 : 1;
|
|
print FILE_HANDLER "
|
|
<tr>
|
|
<td class=\"data$class\"><a name=\"host_template_$name\"></a>$name</td>
|
|
<td class=\"data$class\">$object->{'use'}</td>
|
|
<td class=\"data$class\">$object->{'check_command'}</td>
|
|
<td class=\"data$class\">$object->{'check_interval'}</td>
|
|
<td class=\"data$class\">$object->{'notification'}</td>
|
|
<td class=\"data$class\">$object->{'notification_interval'}</td>
|
|
<tr>";
|
|
}
|
|
|
|
print FILE_HANDLER
|
|
'</table>
|
|
<a href="#index" class="bold">Index</a></li>
|
|
</p>
|
|
<h2><a name="hosts"></a>Hosts</h2>
|
|
<p>
|
|
<table border="0">
|
|
<tr>
|
|
<th>Host Name</th>
|
|
<th>Alias</th>
|
|
<th>Address</th>
|
|
<th>Inherits from</th>
|
|
<th>Check Command</th>
|
|
<th>Check Interval (s)</th>
|
|
<th>Group</th>
|
|
<th>Network Server</th>
|
|
<th>Notification</th>
|
|
<th>Notification Interval (s)</th>
|
|
</tr>';
|
|
# Hosts
|
|
while (($name, $object) = each (%hosts)){
|
|
$class = $class == 1 ? 2 : 1;
|
|
print FILE_HANDLER "
|
|
<tr>
|
|
<td class=\"data$class\"><a name=\"host_$name\"></a>$name</td>
|
|
<td class=\"data$class\">$object->{'alias'}</td>
|
|
<td class=\"data$class\">$object->{'address'}</td>
|
|
<td class=\"data$class\"><a href=\"#host_template_$object->{'use'}\">$object->{'use'}</a></td>
|
|
<td class=\"data$class\"><a href=\"#command_$object->{'check_command'}\">$object->{'check_command'}</a></td>
|
|
<td class=\"data$class\">$object->{'check_interval'}</td>
|
|
<td class=\"data$class\"><a href=\"#group_$object->{'group_name'}\">$object->{'group_name'}</a></td>
|
|
<td class=\"data$class\">$object->{'network_server_id'}</td>
|
|
<td class=\"data$class\">$object->{'notification'}</td>
|
|
<td class=\"data$class\">$object->{'notification_interval'}</td>
|
|
<tr>";
|
|
}
|
|
|
|
print FILE_HANDLER
|
|
'</table>
|
|
<a href="#index" class="bold">Index</a></li>
|
|
</p>
|
|
<h2><a name="groups"></a>Groups</h2>
|
|
<p>
|
|
<table border="0">
|
|
<tr>
|
|
<th>Group Name</th>
|
|
<th>Alias</th>
|
|
<th>Members</th>
|
|
</tr>';
|
|
# Groups
|
|
while (($name, $object) = each (%groups)){
|
|
$class = $class == 1 ? 2 : 1;
|
|
print FILE_HANDLER "
|
|
<tr>
|
|
<td class=\"data$class\"><a name=\"group_$name\"></a>$name</td>
|
|
<td class=\"data$class\">$object->{'alias'}</td>
|
|
<td class=\"data$class\">$object->{'members'}</td>
|
|
<tr>";
|
|
}
|
|
|
|
print FILE_HANDLER
|
|
'</table>
|
|
<a href="#index" class="bold">Index</a></li>
|
|
</p>
|
|
<h2><a name="service_templates"></a>Service Templates</h2>
|
|
<p>
|
|
<table border="0">
|
|
<tr>
|
|
<th>Template Name</th>
|
|
<th>Inherits from</th>
|
|
<th>Notification</th>
|
|
<th>Notification Interval (s)</th>
|
|
</tr>';
|
|
# Service templates
|
|
while (($name, $object) = each (%service_templates)){
|
|
$class = $class == 1 ? 2 : 1;
|
|
print FILE_HANDLER "
|
|
<tr>
|
|
<td class=\"data$class\"><a name=\"service_template_$name\"></a>$name</td>
|
|
<td class=\"data$class\">$object->{'use'}</td>
|
|
<td class=\"data$class\">$object->{'notification'}</td>
|
|
<td class=\"data$class\">$object->{'notification_interval'}</td>
|
|
<tr>";
|
|
}
|
|
|
|
print FILE_HANDLER
|
|
'</table>
|
|
<a href="#index" class="bold">Index</a></li>
|
|
</p>
|
|
<h2><a name="services"></a>Services</h2>
|
|
<p>
|
|
<table border="0">
|
|
<tr>
|
|
<th>Command Name</th>
|
|
<th>Inherits from</th>
|
|
<th>Arguments</th>
|
|
<th>Hosts</th>
|
|
<th>Notification</th>
|
|
<th>Notification Interval (s)</th>
|
|
</tr>';
|
|
# Services
|
|
while (($name, $object) = each (%services)){
|
|
$class = $class == 1 ? 2 : 1;
|
|
print FILE_HANDLER "
|
|
<tr>
|
|
<td class=\"data$class\"><a href=\"#command_$name\">$name</a></td>
|
|
<td class=\"data$class\"><a href=\"#service_template_$object->{'use'}\">$object->{'use'}</a></td>
|
|
<td class=\"data$class\">$object->{'arguments'}</td>
|
|
<td class=\"data$class\">$object->{'host_name'}</td>
|
|
<td class=\"data$class\">$object->{'notification'}</td>
|
|
<td class=\"data$class\">$object->{'notification_interval'}</td>
|
|
<tr>";
|
|
}
|
|
|
|
print FILE_HANDLER
|
|
'</table>
|
|
<a href="#index" class="bold">Index</a></li>
|
|
</p>
|
|
<h2><a name="commands"></a>Commands</h2>
|
|
<p>
|
|
<table border="0">
|
|
<tr>
|
|
<th>Command Name</th>
|
|
<th>Command Line</th>
|
|
</tr>';
|
|
# Commands
|
|
while (($name, $object) = each (%commands)){
|
|
$class = $class == 1 ? 2 : 1;
|
|
print FILE_HANDLER "
|
|
<tr>
|
|
<td class=\"data$class\"><a name=\"command_$name\"></a>$name</td>
|
|
<td class=\"data$class\">$object->{'command_line'}</td>
|
|
<tr>";
|
|
}
|
|
|
|
print FILE_HANDLER
|
|
'</table>
|
|
<a href="#index" class="bold">Index</a></li>
|
|
</p>
|
|
</body>
|
|
</html>';
|
|
|
|
}
|
|
|
|
################################################################################
|
|
## SUB read_config
|
|
## Parse a Nagios configuration file.
|
|
################################################################################
|
|
sub read_config {
|
|
my $line;
|
|
my $var;
|
|
|
|
open (FILE_HANDLER, $_[0]) || die ("Error opening file " . $_[0] . "for reading.");
|
|
|
|
# Search for object definitions
|
|
while ($line = <FILE_HANDLER>) {
|
|
|
|
# Comment
|
|
if ($line =~ /^[ \t]*#.*/) {
|
|
next;
|
|
}
|
|
|
|
# Definition
|
|
if ($line =~ /[ \t]*define[ \t]+(\w+)[ \t]*{.*/i) {
|
|
|
|
$var = uc ($1);
|
|
|
|
# Host definition
|
|
if ($var eq 'HOST') {
|
|
write_log ("\tReading host definition...");
|
|
read_host ();
|
|
}
|
|
|
|
# Host group definition
|
|
if ($var eq 'HOSTGROUP') {
|
|
write_log ("\tReading group definition...");
|
|
read_group ();
|
|
}
|
|
|
|
# Service definition
|
|
if ($var eq 'SERVICE') {
|
|
write_log ("\tReading service definition...");
|
|
read_service ();
|
|
}
|
|
|
|
# Command definition
|
|
if ($var eq 'COMMAND') {
|
|
write_log ("\tReading command definition...");
|
|
read_command ();
|
|
}
|
|
}
|
|
}
|
|
|
|
close (FILE_HANDLER);
|
|
}
|
|
|
|
################################################################################
|
|
## SUB read_host
|
|
## Read and store a host definition.
|
|
################################################################################
|
|
sub read_host {
|
|
my $line;
|
|
my $var;
|
|
my $address = '';
|
|
my $alias = '';
|
|
my $check_command = '';
|
|
# Default interval for Host Alive modules will be 5 minutes
|
|
my $check_interval = 300;
|
|
my $host_name = '';
|
|
my $name = '';
|
|
my $notification = '';
|
|
# Default interval for alerts will be 5 minutes
|
|
my $notification_interval = 300;
|
|
my $use = '';
|
|
|
|
while ($line = <FILE_HANDLER>) {
|
|
|
|
# End of host definition
|
|
if ($line =~ /[ \t]*}.*/) {
|
|
|
|
# A host template
|
|
if ($name ne '') {
|
|
|
|
write_log ("\t\tFound host template $name" . ($use eq '' ? '' : " (inherits from $use)"));
|
|
|
|
$host_templates{$name} = {
|
|
"address" => $address,
|
|
"alias" => $alias,
|
|
"check_command" => $check_command,
|
|
"check_interval" => $check_interval,
|
|
"notification" => $notification,
|
|
"notification_interval" => $notification_interval,
|
|
"use" => $use,
|
|
};
|
|
}
|
|
# A host
|
|
else{
|
|
write_log ("\t\tFound host $host_name" . ($use eq '' ? '' : " (inherits from $use)"));
|
|
|
|
$hosts{$host_name} = {
|
|
"address" => $address,
|
|
"alias" => $alias,
|
|
"check_command" => $check_command,
|
|
"check_interval" => $check_interval,
|
|
# Group All will be used by default
|
|
"group_name" => 'All',
|
|
"id" => -1,
|
|
# Network servers will be assigned later
|
|
"network_server_id" => -1,
|
|
"notification" => $notification,
|
|
"notification_interval" => $notification_interval,
|
|
"use" => $use,
|
|
};
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
# Host variables
|
|
if ($line =~ /[ \t]*(\S+)[ \t]+(\S+).*/) {
|
|
|
|
$var = uc ($1);
|
|
|
|
if ($var eq "ADDRESS") {
|
|
$address = $2;
|
|
}
|
|
elsif ($var eq "ALIAS") {
|
|
$alias = $2;
|
|
}
|
|
elsif ($var eq "CHECK_COMMAND") {
|
|
$check_command = $2;
|
|
}
|
|
elsif ($var eq "CHECK_INTERVAL") {
|
|
# Pandora FMS needs seconds
|
|
$check_interval = 60 * $2;
|
|
}
|
|
elsif ($var eq "HOST_NAME") {
|
|
$host_name = $2;
|
|
}
|
|
elsif ($var eq "NAME") {
|
|
$name = $2;
|
|
}
|
|
elsif ($var eq "NOTIFICATIONS_ENABLED") {
|
|
$notification = $2;
|
|
}
|
|
elsif ($var eq "NOTIFICATION_INTERVAL") {
|
|
# Pandora FMS needs seconds
|
|
$notification_interval = 60 * $2;
|
|
}
|
|
# Inheritance has to be resolved now to allow
|
|
# value overriding
|
|
elsif ($var eq "USE") {
|
|
$use = $2;
|
|
|
|
$check_command = $host_templates{$use}->{'check_command'};
|
|
$check_interval = $host_templates{$use}->{'check_interval'};
|
|
$notification = $host_templates{$use}->{'notification'};
|
|
$notification_interval = $host_templates{$use}->{'notification_interval'};
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
################################################################################
|
|
## SUB read_group
|
|
## Read and store a group definition.
|
|
################################################################################
|
|
sub read_group {
|
|
my $line;
|
|
my $var;
|
|
my $alias = '';
|
|
my $hostgroup_name = '';
|
|
my $members = '';
|
|
|
|
while ($line = <FILE_HANDLER>) {
|
|
|
|
# End of group definition
|
|
if ($line =~ /[ \t]*}.*/) {
|
|
|
|
write_log ("\t\tFound group $hostgroup_name");
|
|
|
|
$groups{$hostgroup_name} = {
|
|
"alias" => $alias,
|
|
"id" => -1,
|
|
"members" => $members,
|
|
};
|
|
|
|
return;
|
|
}
|
|
|
|
# Host group variables
|
|
if ($line =~ /[ \t]*(\S+)[ \t]+(\S+).*/) {
|
|
|
|
$var = uc ($1);
|
|
|
|
if ($var eq "ALIAS") {
|
|
$alias = $2;
|
|
}
|
|
elsif ($var eq "HOSTGROUP_NAME") {
|
|
$hostgroup_name = $2;
|
|
}
|
|
elsif ($var eq "MEMBERS") {
|
|
$members = $2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
################################################################################
|
|
## SUB read_service
|
|
## Read and store a service definition.
|
|
################################################################################
|
|
sub read_service {
|
|
my $line;
|
|
my $var;
|
|
my $arguments = '';
|
|
my @argument_array;
|
|
my $check_command = '';
|
|
my $description = '';
|
|
my $host_name = '';
|
|
my $name = '';
|
|
my $notification = '';
|
|
# Default interval for alerts will be 5 minutes
|
|
my $notification_interval = 300;
|
|
my $use = '';
|
|
|
|
while ($line = <FILE_HANDLER>) {
|
|
|
|
# End of service definition
|
|
if ($line =~ /[ \t]*}.*/) {
|
|
|
|
# A service template
|
|
if ($name ne '') {
|
|
|
|
write_log ("\t\tFound service template $name" . ($use eq '' ? '' : " (inherits from $use)"));
|
|
|
|
$service_templates{$name} = {
|
|
"notification" => $notification,
|
|
"notification_interval" => $notification_interval,
|
|
"use" => $use,
|
|
};
|
|
}
|
|
# A service
|
|
else{
|
|
write_log ("\t\tFound service $check_command for hosts $host_name " . ($use eq '' ? '' : " (inherits from $use)"));
|
|
|
|
$services{$check_command} = {
|
|
"arguments" => $arguments,
|
|
"description" => $description,
|
|
"host_name" => $host_name,
|
|
"notification" => $notification,
|
|
"notification_interval" => $notification_interval,
|
|
"use" => $use,
|
|
};
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
# Service variables
|
|
if ($line =~ /[ \t]*(\S+)[ \t]+(\S+).*/) {
|
|
|
|
$var = uc ($1);
|
|
|
|
if ($var eq "CHECK_COMMAND") {
|
|
@argument_array = split (/!/, $2);
|
|
$check_command = shift (@argument_array);
|
|
$arguments = join (/!/, @argument_array);
|
|
}
|
|
elsif ($var eq "HOST_NAME") {
|
|
$host_name = $2;
|
|
}
|
|
elsif ($var eq "NAME") {
|
|
$name = $2;
|
|
}
|
|
elsif ($var eq "NOTIFICATIONS_ENABLED") {
|
|
$notification = $2;
|
|
}
|
|
elsif ($var eq "NOTIFICATION_INTERVAL") {
|
|
# Pandora FMS needs seconds
|
|
$notification_interval = 60 * $2;
|
|
}
|
|
elsif ($var eq "SERVICE_DESCRIPTION") {
|
|
$description = $2;
|
|
}
|
|
# Inheritance has to be resolved now to allow
|
|
# value overriding
|
|
elsif ($var eq "USE") {
|
|
$use = $2;
|
|
|
|
$notification = $service_templates{$use}->{'notification'};
|
|
$notification_interval = $service_templates{$use}->{'notification_interval'};
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
################################################################################
|
|
## SUB read_command
|
|
## Read and store a command definition.
|
|
################################################################################
|
|
sub read_command {
|
|
my $line;
|
|
my $var;
|
|
my $command_line = '';
|
|
my $command_name = '';
|
|
|
|
while ($line = <FILE_HANDLER>) {
|
|
|
|
# End of command definition
|
|
if ($line =~ /[ \t]*}.*/) {
|
|
|
|
write_log ("\t\tFound command $command_name");
|
|
|
|
$commands{$command_name} = {
|
|
"command_line" => $command_line,
|
|
};
|
|
|
|
return;
|
|
}
|
|
|
|
# Command variables
|
|
if ($line =~ /[ \t]*(\S+)[ \t]+(.*)/) {
|
|
|
|
$var = uc ($1);
|
|
|
|
if ($var eq "COMMAND_LINE") {
|
|
$command_line = $2;
|
|
}
|
|
elsif ($var eq "COMMAND_NAME") {
|
|
$command_name = $2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
################################################################################
|
|
## SUB configure_db
|
|
## Configure Pandora FMS's database.
|
|
################################################################################
|
|
sub configure_db {
|
|
|
|
# Configure groups first
|
|
write_log ("Configuring groups...");
|
|
configure_db_groups ();
|
|
|
|
# Update host with the corresponding group information
|
|
update_host_group_name ();
|
|
|
|
# Update host information with a Pandora FMS network server
|
|
write_log ("Assigning network servers...");
|
|
update_host_network_server_id ();
|
|
|
|
# Configure hosts
|
|
write_log ("Configuring hosts...");
|
|
configure_db_hosts ();
|
|
|
|
# Configure modules and alerts
|
|
write_log ("Configuring modules...");
|
|
configure_db_modules ();
|
|
}
|
|
|
|
################################################################################
|
|
## SUB configure_db_hosts
|
|
## Configure Pandora FMS network agents.
|
|
################################################################################
|
|
sub configure_db_hosts {
|
|
my $host;
|
|
my $host_name;
|
|
my $host_id;
|
|
my $group_id;
|
|
my $sth_insert;
|
|
my @data;
|
|
|
|
# SQL Insert agent
|
|
$sth_insert = $dbh->prepare ("INSERT INTO tagente (nombre, direccion, comentarios, id_grupo, modo, intervalo, id_os, os_version, agent_version, disabled, agent_type, id_server) VALUES (?, ?, ?, ?, 0, ?, 11, 'Net', '$pandora_version', 0, 1, 2)") || die ("Error preparing statement: " . $sth_insert->errstr);
|
|
|
|
# Parse hosts
|
|
while (($host_name, $host) = each (%hosts)) {
|
|
|
|
# Check that the host does not exist
|
|
if (get_host_id ($host_name) != -1) {
|
|
die ("Error: host $host_name already exists");
|
|
}
|
|
|
|
# Create the host
|
|
write_log ("\tCreating host $host_name...");
|
|
|
|
# Group does not exist, should not happen
|
|
$group_id = get_group_id ($host->{'group_name'});
|
|
if ($group_id == -1) {
|
|
die ("Error: Group " . $host->{'group_name'} . " does not exists");
|
|
}
|
|
|
|
$sth_insert->execute ($host_name, $host->{'address'}, $host->{'alias'}, $group_id, $host->{'check_interval'}) || die ("Error executing statement: " . $sth_insert->errstr);
|
|
|
|
# Read and store the host id for later use
|
|
$host_id = get_host_id ($host_name);
|
|
$hosts{$host_name}->{'id'} = $host_id;
|
|
}
|
|
}
|
|
|
|
################################################################################
|
|
## SUB configure_db_groups
|
|
## Configure groups.
|
|
################################################################################
|
|
sub configure_db_groups {
|
|
my $group;
|
|
my $group_id;
|
|
my $group_name;
|
|
my $sth_insert;
|
|
my $sth_select;
|
|
my @data;
|
|
|
|
# SQL Insert group
|
|
$sth_insert = $dbh->prepare ("INSERT INTO tgrupo (nombre, icon, parent, disabled) VALUES (?, 'computer', '0', '0')") || die ("Error preparing statement: " . $sth_insert->errstr);
|
|
|
|
# Parse groups
|
|
while (($group_name, $group) = each (%groups)) {
|
|
|
|
# Check that the group does not exist
|
|
if (get_group_id ($group_name) != -1) {
|
|
die ("\tError: group $group_name already exists");
|
|
}
|
|
|
|
# Create the group
|
|
write_log ("\tCreating group $group_name...");
|
|
$sth_insert->execute ($group_name) || die ("Error executing statement: " . $sth_insert->errstr);
|
|
|
|
# Read and store the group id for later use
|
|
$group_id = get_group_id ($group_name);
|
|
$groups{$group_name}->{'id'} = $group_id;
|
|
}
|
|
}
|
|
|
|
################################################################################
|
|
## SUB configure_db_modules
|
|
## Configure modules for each host.
|
|
################################################################################
|
|
sub configure_db_modules {
|
|
my $host;
|
|
my $host_name;
|
|
my @host_array;
|
|
my $service;
|
|
my $service_name;
|
|
|
|
# Configure check_command service module for each host
|
|
while (($host_name, $host) = each (%hosts)) {
|
|
|
|
configure_db_guess_module ($host->{'check_command'}, $host_name, $host->{'notification'}, $host->{'notification_interval'});
|
|
}
|
|
|
|
# Configure other services
|
|
while (($service_name, $service) = each (%services)) {
|
|
|
|
# Configure modules for all hosts defined in service
|
|
@host_array = split (/,/, $service->{'host_name'});
|
|
|
|
foreach $host_name (@host_array) {
|
|
configure_db_guess_module ($service_name, $host_name, $service->{'notification'}, $service->{'notification_interval'});
|
|
}
|
|
}
|
|
}
|
|
|
|
################################################################################
|
|
## SUB configure_db_guess_module
|
|
## Guess and configure the appropiate Pandora FMS module given a Nagios service.
|
|
################################################################################
|
|
sub configure_db_guess_module {
|
|
my $service = $_[0];
|
|
my $agent_address;
|
|
my $host_id;
|
|
my $host_name = $_[1];
|
|
my $notification = $_[2];
|
|
my $alert_interval = $_[3];
|
|
my $module_id;
|
|
my $sth_mod;
|
|
my $sth_state;
|
|
|
|
# Host does not exist, should not happen
|
|
if (! defined ($hosts{$host_name})) {
|
|
die ("Agent $host_name does not exist");
|
|
}
|
|
|
|
# Command does not exist
|
|
if (! defined ($commands{$service})) {
|
|
write_log ("\tCommand $service does not exist, skipping...");
|
|
return;
|
|
}
|
|
|
|
$agent_address = $hosts{$host_name}->{'address'};
|
|
$host_id = $hosts{$host_name}->{'id'};
|
|
|
|
# SQL Insert module
|
|
$sth_mod = $dbh->prepare ("INSERT INTO tagente_modulo (id_agente, id_tipo_modulo, descripcion, nombre, max, min, module_interval, tcp_port, tcp_send, tcp_rcv, ip_target, id_module_group, flag, id_modulo) VALUES (?, ?, ?, ?, 0, 0, ?, ?, ?, ?, ?, ?, 0, 0)") || die ("Error preparing statement: " . $sth_mod->errstr);
|
|
|
|
# SQL Without an entry in tagente_estado a module will not work
|
|
$sth_state = $dbh->prepare ("INSERT INTO tagente_estado (id_agente_modulo) VALUES (?)") || die ("Error preparing statement: " . $sth_state->errstr);
|
|
|
|
$service = uc ($service);
|
|
if ($service eq "CHECK-HOST-ALIVE") {
|
|
|
|
# Host Alive
|
|
write_log ("\tAdding Host Alive module to host $host_name...");
|
|
|
|
$sth_mod->execute ($host_id, 6, 'Check if host is alive using ICMP ping check.', 'Host Alive', 120, 0, '', '', $agent_address, 2) || die ("Error executing statement: " . $sth_mod->errstr);
|
|
|
|
# Get the module id
|
|
$module_id = get_module_id ('Host Alive', $host_id);
|
|
|
|
# Module not found, should not happen
|
|
if ($module_id == -1) {
|
|
die ("Module Host Alive for agent $host_id not found");
|
|
}
|
|
|
|
# Create an entry for the module in tagente_estado
|
|
$sth_state->execute ($module_id) || die ("Error executing statement: " . $sth_mod->errstr);
|
|
|
|
# Create an alert if necessary
|
|
if ($notification == 1 && defined ($::a)) {
|
|
write_log ("\t\tAdding alert (type 3) to module...");
|
|
configure_db_alert ($module_id, "Host seems to be down", "Host seems to be down", $alert_interval);
|
|
}
|
|
}
|
|
elsif ($service eq "CHECK_HTTP") {
|
|
|
|
# Check HTTP Server
|
|
write_log ("\tAdding Check HTTP Server module to host $host_name...");
|
|
|
|
$sth_mod->execute ($host_id, 9, 'Test APACHE2 HTTP service remotely (Protocol response, not only openport)', 'Check HTTP Server', 120, 80, 'GET / HTTP/1.0^M^M', 'HTTP/1.1 200 OK', $agent_address, 3) || die ("Error executing statement: " . $sth_mod->errstr);
|
|
|
|
# Get the module id
|
|
$module_id = get_module_id ('Check HTTP Server', $host_id);
|
|
|
|
# Module not found, should not happen
|
|
if ($module_id == -1) {
|
|
die ("Module Check HTTP Server for agent $host_id not found");
|
|
}
|
|
|
|
# Create an entry for the module in tagente_estado
|
|
$sth_state->execute ($module_id) || die ("Error executing statement: " . $sth_mod->errstr);
|
|
|
|
# Create an alert if necessary
|
|
if ($notification == 1 && defined ($::a)) {
|
|
write_log ("\t\tAdding alert (type 3) to module...");
|
|
configure_db_alert ($module_id, "HTTP Server seems to be down", "HTTP Server seems to be down", $alert_interval);
|
|
}
|
|
}
|
|
elsif ($service eq "CHECK_FTP") {
|
|
|
|
# Check FTP Server
|
|
write_log ("\tAdding Check FTP Server module to host $host_name...");
|
|
|
|
$sth_mod->execute ($host_id, 9, 'Check FTP protocol, not only check port.', 'Check FTP Server', 120, 21, 'QUIT', '221', $agent_address, 3) || die ("Error executing statement: " . $sth_mod->errstr);
|
|
|
|
# Get the module id
|
|
$module_id = get_module_id ('Check FTP Server', $host_id);
|
|
|
|
# Module not found, should not happen
|
|
if ($module_id == -1) {
|
|
die ("Module Check FTP Server for agent $host_id not found");
|
|
}
|
|
|
|
# Create an entry for the module in tagente_estado
|
|
$sth_state->execute ($module_id) || die ("Error executing statement: " . $sth_mod->errstr);
|
|
|
|
# Create an alert if necessary
|
|
if ($notification == 1 && defined ($::a)) {
|
|
write_log ("\t\tAdding alert (type 3) to module...");
|
|
configure_db_alert ($module_id, "FTP Server seems to be down", "FTP Server seems to be down", $alert_interval);
|
|
}
|
|
}
|
|
else {
|
|
write_log ("\tUnknown service $service for host $host_name...");
|
|
|
|
# Do not generate an alert for an unknown service
|
|
$notification = 0;
|
|
}
|
|
|
|
}
|
|
|
|
################################################################################
|
|
## SUB configure_db_alert
|
|
## Configure an alert for a given module.
|
|
## TODO: Add more alert types.
|
|
################################################################################
|
|
sub configure_db_alert {
|
|
my $module_id = $_[0];
|
|
my $alert_desc = $_[1];
|
|
my $alert_text = $_[2];
|
|
my $alert_interval = $_[3];
|
|
my $sth_alert;
|
|
|
|
# SQL Insert alert
|
|
$sth_alert = $dbh->prepare ("INSERT INTO talerta_agente_modulo (id_agente_modulo, id_alerta, descripcion, dis_max, dis_min, time_threshold, max_alerts, alert_text) VALUES (?, ?, ?, ?, ?, ?, ?, ?)") || die ("Error preparing statement: " . $sth_alert->errstr);
|
|
|
|
# Insert alert
|
|
$sth_alert->execute ($module_id, 3, $alert_desc, 1, 1, $alert_interval, 1, $alert_text) || die ("Error executing statement: " . $sth_alert->errstr);
|
|
}
|
|
|
|
################################################################################
|
|
## SUB update_host_group_name
|
|
## Assigns to each host the corresponding group information.
|
|
################################################################################
|
|
sub update_host_group_name {
|
|
my $group;
|
|
my $group_name;
|
|
my $member;
|
|
my @members;
|
|
|
|
while (($group_name, $group) = each (%groups)) {
|
|
|
|
# Read members
|
|
@members = split (/,/, $group->{'members'});
|
|
|
|
# Assume we are parsing a valid Nagios config file,
|
|
# no need to check whether a group member really exists or not
|
|
foreach $member (@members) {
|
|
$hosts{$member}->{'group_name'} = $group_name;
|
|
}
|
|
}
|
|
}
|
|
|
|
################################################################################
|
|
## SUB update_host_network_server_id
|
|
## Assigns a Pandora FMS network server to each group.
|
|
################################################################################
|
|
sub update_host_network_server_id {
|
|
my $i;
|
|
my $host;
|
|
my $host_name;
|
|
my $group;
|
|
my $group_name;
|
|
my $member;
|
|
my @members;
|
|
my @servers;
|
|
my @data;
|
|
my $sth;
|
|
|
|
# SQL Get a list of Pandora FMS network servers
|
|
$sth = $dbh->prepare ("SELECT id_server FROM tserver WHERE network_server = 1") || die ("Error preparing statement: " . $sth->errstr);
|
|
|
|
|
|
$sth->execute () || die ("Error executing statement: " . $sth->errstr);
|
|
while (@data = $sth->fetchrow_array ()) {
|
|
push (@servers, $data[0]);
|
|
}
|
|
|
|
# No network server found, this should not happen
|
|
if ($#servers == -1) {
|
|
die ("Error: no network servers found");
|
|
}
|
|
|
|
# Assign a network server to each group
|
|
$i = 0;
|
|
while (($group_name, $group) = each (%groups)) {
|
|
|
|
# Read members
|
|
@members = split (/,/, $group->{'members'});
|
|
|
|
write_log ("\tGroup $group_name assigned to network server $servers[$i]");
|
|
|
|
# Assume we are parsing a valid Nagios config file,
|
|
# no need to check whether a group member really exists or not
|
|
foreach $member (@members) {
|
|
$hosts{$member}->{'network_server_id'} = $servers[$i];
|
|
}
|
|
|
|
# Balance network server load
|
|
$i++;
|
|
if ($i > $#servers) {
|
|
$i = $#servers > 0 ? $i % $#servers : 0;
|
|
}
|
|
}
|
|
|
|
# Assign a network server to hosts with no assigned group
|
|
while (($host_name, $host) = each (%hosts)) {
|
|
|
|
if ($host->{'network_server_id'} == -1) {
|
|
write_log ("\tHost $host_name assigned to network server $servers[$i]");
|
|
$host->{'network_server_id'} = $servers[$i];
|
|
}
|
|
}
|
|
}
|
|
|
|
################################################################################
|
|
## SUB roll_back
|
|
## Undo any changes done to the DB.
|
|
################################################################################
|
|
sub roll_back {
|
|
my $host;
|
|
my $host_id;
|
|
my $host_name;
|
|
my $group;
|
|
my $group_name;
|
|
my $sth_del_host;
|
|
my $sth_del_group;
|
|
my $sth_del_module;
|
|
my $sth_del_state;
|
|
my $sth_del_alert;
|
|
my $sth_sel;
|
|
my @data;
|
|
|
|
write_log("Rolling back...");
|
|
|
|
# SQL Delete hosts
|
|
$sth_del_host = $dbh->prepare ("DELETE FROM tagente WHERE nombre = ?") || die ("Error preparing statement: " . $sth_del_host->errstr);
|
|
|
|
# SQL Delete groups
|
|
$sth_del_group = $dbh->prepare ("DELETE FROM tgrupo WHERE nombre = ?") || die ("Error preparing statement: " . $sth_del_group->errstr);
|
|
|
|
# SQL Delete modules
|
|
$sth_del_module = $dbh->prepare ("DELETE FROM tagente_modulo WHERE id_agente_modulo = ?") || die ("Error preparing statement: " . $sth_del_module->errstr);
|
|
$sth_del_state = $dbh->prepare ("DELETE FROM tagente_estado WHERE id_agente_modulo = ?") || die ("Error preparing statement: " . $sth_del_state->errstr);
|
|
|
|
# SQL Delete alerts associated with a module
|
|
$sth_del_alert = $dbh->prepare ("DELETE FROM talerta_agente_modulo WHERE id_agente_modulo = ?") || die ("Error preparing statement: " . $sth_del_alert->errstr);
|
|
|
|
# SQL Get all modules associated with an agent
|
|
$sth_sel = $dbh->prepare ("SELECT id_agente_modulo FROM tagente_modulo WHERE id_agente = ?") || die ("Error preparing statement: " . $sth_sel->errstr);
|
|
|
|
# Delete hosts
|
|
while (($host_name, $host) = each (%hosts)) {
|
|
|
|
write_log("\tDeleting host $host_name...");
|
|
|
|
# Get all modules associated with the host
|
|
$host_id = get_host_id ($host_name);
|
|
if ($host_id == -1) {
|
|
next;
|
|
}
|
|
|
|
$sth_sel->execute ($host_id) || die ("Error executing statement: " . $sth_sel->errstr);
|
|
|
|
# Delete alerts and modules
|
|
write_log("\t\tDeleting alerts and modules associated with host...");
|
|
|
|
while (@data = $sth_sel->fetchrow_array ()) {
|
|
$sth_del_alert->execute ($data[0]) || die ("Error executing statement: " . $sth_del_alert->errstr);
|
|
$sth_del_module->execute ($data[0]) || die ("Error executing statement: " . $sth_del_module->errstr);
|
|
$sth_del_state->execute ($data[0]) || die ("Error executing statement: " . $sth_del_state->errstr);
|
|
}
|
|
|
|
# Delete host
|
|
$sth_del_host->execute ($host_name) || die ("Error executing statement: " . $sth_del_host->errstr);
|
|
}
|
|
|
|
# Delete groups
|
|
while (($group_name, $group) = each (%groups)) {
|
|
|
|
write_log("\tDeleting group $group_name...");
|
|
|
|
$sth_del_group->execute ($group_name) || die ("Error executing statement: " . $sth_del_group->errstr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
################################################################################
|
|
## SUB get_host_id
|
|
## Get the id of a host given its name.
|
|
################################################################################
|
|
sub get_host_id {
|
|
my $name = $_[0];
|
|
my $sth;
|
|
my @data;
|
|
|
|
# SQL Get host id
|
|
$sth = $dbh->prepare ("SELECT id_agente FROM tagente WHERE nombre = ?") || die ("Error preparing statement: " . $sth->errstr);
|
|
|
|
$sth->execute ($name) || die ("Error executing statement: " . $sth->errstr);
|
|
|
|
# Agent not found
|
|
if ($sth->rows == 0) {
|
|
return -1;
|
|
}
|
|
|
|
@data = $sth->fetchrow_array ();
|
|
|
|
# Return id
|
|
return $data[0];
|
|
}
|
|
|
|
################################################################################
|
|
## SUB get_group_id
|
|
## Get the id of a group given its name.
|
|
################################################################################
|
|
sub get_group_id {
|
|
my $name = $_[0];
|
|
my $sth;
|
|
my @data;
|
|
|
|
# SQL Get group id
|
|
$sth = $dbh->prepare ("SELECT id_grupo FROM tgrupo WHERE nombre = ?") || die ("Error preparing statement: " . $sth->errstr);
|
|
|
|
$sth->execute ($name) || die ("Error executing statement: " . $sth->errstr);
|
|
|
|
# Group not found
|
|
if ($sth->rows == 0) {
|
|
return -1;
|
|
}
|
|
|
|
@data = $sth->fetchrow_array ();
|
|
|
|
# Return id
|
|
return $data[0];
|
|
}
|
|
|
|
################################################################################
|
|
## SUB get_module_group_id
|
|
## Get the id of a module_group given its name.
|
|
################################################################################
|
|
sub get_module_group_id {
|
|
my $name = $_[0];
|
|
my $sth;
|
|
my @data;
|
|
|
|
# SQL Get group id
|
|
$sth = $dbh->prepare ("SELECT id_mg FROM tmodule_group WHERE name = ?") || die ("Error preparing statement: " . $sth->errstr);
|
|
|
|
$sth->execute ($name) || die ("Error executing statement: " . $sth->errstr);
|
|
|
|
# Group not found
|
|
if ($sth->rows == 0) {
|
|
return -1;
|
|
}
|
|
|
|
@data = $sth->fetchrow_array ();
|
|
|
|
# Return id
|
|
return $data[0];
|
|
}
|
|
|
|
################################################################################
|
|
## SUB get_module_id
|
|
## Get the id of a module given its name and the id of the host.
|
|
################################################################################
|
|
sub get_module_id {
|
|
my $name = $_[0];
|
|
my $host_id = $_[1];
|
|
my $sth;
|
|
my @data;
|
|
|
|
# SQL Get module id
|
|
$sth = $dbh->prepare ("SELECT id_agente_modulo FROM tagente_modulo WHERE id_agente = ? AND nombre = ?") || die ("Error preparing statement: " . $sth->errstr);
|
|
|
|
$sth->execute ($host_id, $name) || die ("Error executing statement: " . $sth->errstr);
|
|
|
|
# Module not found
|
|
if ($sth->rows == 0) {
|
|
return -1;
|
|
}
|
|
|
|
@data = $sth->fetchrow_array ();
|
|
|
|
# Return id
|
|
return $data[0];
|
|
}
|
|
|
|
################################################################################
|
|
# Main
|
|
################################################################################
|
|
|
|
my $file;
|
|
|
|
# Check command line arguments
|
|
if ($#ARGV < 0) {
|
|
print_help ();
|
|
exit;
|
|
}
|
|
|
|
# Check that all files exist
|
|
foreach $file (@ARGV) {
|
|
if (! -f $file) {
|
|
die "File \'$file\' does not exist.";
|
|
}
|
|
}
|
|
|
|
# Check connection to the DB
|
|
$dbh = DBI->connect ("DBI:mysql:$db_name:$db_host:$db_port", $db_user, $db_pass) || die "Error connecting to the database.";
|
|
|
|
# Parse Nagios configuration files
|
|
foreach $file (@ARGV) {
|
|
write_log ("Reading file $file...");
|
|
read_config ($file);
|
|
}
|
|
|
|
# Simulation, do now write any changes to the DB
|
|
if (defined ($::s)) {
|
|
$dbh->disconnect ();
|
|
write_log ("Done.");
|
|
exit;
|
|
}
|
|
|
|
# Roll back and undo any changes
|
|
if (defined ($::u)) {
|
|
roll_back ();
|
|
}
|
|
# Configure Pandora's DB
|
|
else {
|
|
configure_db ();
|
|
if (defined ($::h)) {
|
|
write_log ("Generating report...");
|
|
write_report ();
|
|
}
|
|
}
|
|
|
|
$dbh->disconnect ();
|
|
write_log ("Done.");
|