2009-03-05 Sancho Lerena <slerena@artica.es>

* bin/pandora_network: Better management of snmpget binary call, using
	a config setup variable and checking it in startup.
	
	* pandora_server.conf: new options added (snmpget, UDP multicast)
	
	* Config.pm: New options managed (snmpget), new version updated (3.0-dev)
	
	* DB.pm: Fixed two issues that makes me some problems on undefined values.
	
	* Tools.pm: New function to manage numerical data.
	
	* util/plugin/multicast.pl: Fixed plugin for multicast check.
	


git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1508 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
This commit is contained in:
slerena 2009-03-04 17:15:39 +00:00
parent e6550a5f03
commit e709f07fff
9 changed files with 193 additions and 70 deletions

View File

@ -1,3 +1,18 @@
2009-03-05 Sancho Lerena <slerena@artica.es>
* bin/pandora_network: Better management of snmpget binary call, using
a config setup variable and checking it in startup.
* pandora_server.conf: new options added (snmpget, UDP multicast)
* Config.pm: New options managed (snmpget), new version updated (3.0-dev)
* DB.pm: Fixed two issues that makes me some problems on undefined values.
* Tools.pm: New function to manage numerical data.
* util/plugin/multicast.pl: Fixed plugin for multicast check.
2009-03-04 Ramon Novoa <rnovoa@artica.es>
* lib/PandoraFMS/DB.pm: Fixed alert recovery custom fields.

View File

@ -62,6 +62,13 @@ pandora_loadconfig (\%pa_config,1);
# Audit server starting
pandora_audit (\%pa_config, "Pandora FMS Network Daemon starting", "SYSTEM", "System");
# Check for snmpget
if (! -e $pa_config{"snmpget"}) {
print " [E] ".$pa_config{"snmpget"}." not found. Pandora FMS Network cannot run without it.\n\n";
exit;
}
# Thread startup
if ($pa_config{"verbosity"} > 4){
@ -102,10 +109,20 @@ my $dbh = DBI->connect("DBI:mysql:$dbname:$dbhost:3306",
$pa_config{'dbpass'},
{ RaiseError => 1, AutoCommit => 1 });
my $counter_status_report = 0;
my $counter_status_loops = (30 / $pa_config{"server_threshold"}) + 1;
while (1) {
pandora_serverkeepaliver (\%pa_config, 1, $dbh);
enterprise_hook('mcast_status_report', [\%pa_config, $dbh]);
# Only call this each 30 loops
if ($counter_status_report > $counter_status_loops ){
enterprise_hook('mcast_status_report', [\%pa_config, $dbh]);
$counter_status_report = 0;
} else {
$counter_status_report++;
}
threads->yield;
sleep ($pa_config{"server_threshold"});
}
@ -476,8 +493,12 @@ sub pandora_query_snmp (%$$$$$) {
my $snmp_timeout = $pa_config->{"snmp_timeout"};
my $snmp_retries = $pa_config->{'snmp_checks'};
# TODO: Alternative version if command is not available or user select a new switch
# with "use internal SNMP" option. At this moment, due to locks() external snmp is much faster
$_[5] = 0;
my $output = `snmpget -v $snmp_version -r $snmp_retries -t $snmp_timeout -OUevqt -c $snmp_community $snmp_target $snmp_oid`;
my $snmpget_cmd = $pa_config->{"snmpget"};
my $output = `$snmpget_cmd -v $snmp_version -r $snmp_retries -t $snmp_timeout -OUevqt -c $snmp_community $snmp_target $snmp_oid`;
if ($output eq ""){
$_[5] = 1;
}

View File

@ -52,16 +52,12 @@ my %pa_config;
$SIG{'TERM'} = 'pandora_shutdown';
$SIG{'INT'} = 'pandora_shutdown';
# Alarm signal management
$SIG{'ALRM'} = sub { }; # Do nothing just trap
# Inicio del bucle principal de programa
pandora_init(\%pa_config, "Pandora FMS Plugin Server");
# Check for pandora_exec
my $pandora_exec = "pandora_exec";
if (system("$pandora_exec > /dev/null 2>&1") != 256) {
print " [E] $pandora_exec not found.\n\n";
exit;
}
# Read config file for Global variables
pandora_loadconfig (\%pa_config, 4);
@ -176,6 +172,8 @@ sub pandora_plugin_consumer ($$) {
if ($@){
logger ($pa_config, "[ERROR] Plugin Task for module $data_id_agent_module causes a system exception", 0);
logger ($pa_config, "ERROR Code: $@", 1);
# Mark module status as executed
update_on_error ($pa_config, $data_id_agent_module, $dbh);
}
# Remove from queue. If catch an error, probably data is
@ -297,14 +295,8 @@ sub exec_plugin_module {
my $agent_module; # hash container for tagente_modulo record
my $plugin; # hash container for tplugin
# Get a full hash for agent_plugin record reference ($agent_module)
my $query_sql = "SELECT * FROM tagente_modulo WHERE id_agente_modulo = $id_am";
my $exec_sql = $dbh->prepare($query_sql);
$exec_sql ->execute;
# TODO: Do a check for void result ! (Gives a DBD::mysql::st execute failed: MySQL server has gone away at /usr/local/bin/pandora_plugin line 304)
$agent_module = $exec_sql->fetchrow_hashref;
#
$agent_module = get_db_free_row ("SELECT * FROM tagente_modulo WHERE id_agente_modulo = $id_am", $dbh);
# Get a full hash for plugin record reference ($plugin)
$query_sql = "SELECT * FROM tplugin WHERE id = ".$agent_module->{'id_plugin'};
@ -343,19 +335,63 @@ sub exec_plugin_module {
$plugin_command = $plugin_command . " ". $agent_module->{'plugin_parameter'};
}
# Final command line execution is stored at "plugin_command"
$plugin_command = decode_entities($plugin_command);
logger ($pa_config, "Executing AM # $id_am plugin command '$plugin_command'", 9);
# Final command line execution is stored at "plugin_command"
$module_data = `$pandora_exec $timeout $plugin_command`;
if ($module_data eq "") {
alarm ($timeout);
eval {
$module_data = `$plugin_command`;
};
if ($@){
logger ($pa_config, "Error $@ executing plugin $plugin_command", 2);
# Trapped error or timeout
update_on_error ($pa_config, $id_am, $dbh);
undef $plugin;
undef $agent_module;
return;
}
}
# Nagios compatible plugin ?
if ($plugin->{'plugin_type'} == 1){
# OK —exit code 0—indicates a service is working properly.
# WARNING —exit code 1—indicates a service is in warning state.
# CRITICAL —exit code 2—indicates a service is in critical state.
# UNKNOWN —exit code 3—indicates a service is in unknown state.
# In Pandora, this will be translated as:
# CRITICAL = 0, WARNING = -1, OK = 1
my $errorlevel = ($? >> 8);
if ($errorlevel == 0){
$module_data = 1; #OK
}
elsif ($errorlevel == 1){
$module_data = -1; # WARNING
}
elsif ($errorlevel == 2){
$module_data = 0; # CRITICAL
}
elsif ($errorlevel == 3){ # UNKNOWN
update_on_error ($pa_config, $id_am, $dbh);
undef $plugin;
undef $agent_module;
return;
}
} else {
# No output
if ($module_data eq "") {
update_on_error ($pa_config, $id_am, $dbh);
undef $plugin;
undef $agent_module;
return;
}
}
# Get current timestamp
my $timestamp = &UnixDate("today","%Y-%m-%d %H:%M:%S");
my $utimestamp = &UnixDate("today","%s");
@ -364,13 +400,12 @@ sub exec_plugin_module {
$part{'name'}[0] = $agent_module->{'nombre'};
$part{'description'}[0] = "";
$part{'data'}[0] = $module_data;
my $tipo_modulo = dame_nombretipomodulo_idagentemodulo ($pa_config, $agent_module->{'id_tipo_modulo'}, $dbh);
my $tipo_modulo = dame_nombretipomodulo_idagentemodulo ($pa_config, $agent_module->{'id_tipo_modulo'}, $dbh);
# 1 - generic_data
# 2 - generic_proc
# 3 - generic_data_string
# 4 - generic_data_inc
# 19, 20 - image
if (1 == $agent_module->{'id_tipo_modulo'}) {
module_generic_data ($pa_config, \%part, $timestamp, $agent_name, $tipo_modulo, $dbh);
@ -381,13 +416,10 @@ sub exec_plugin_module {
elsif (3 == $agent_module->{'id_tipo_modulo'}) {
module_generic_data_string ($pa_config, \%part, $timestamp, $agent_name, $tipo_modulo, $dbh);
}
# Generic_proc
elsif (2 == $agent_module->{'id_tipo_modulo'}) {
module_generic_proc ($pa_config, \%part, $timestamp, $agent_name, $tipo_modulo, $dbh);
}
elsif ( (19 == $agent_module->{'id_tipo_modulo'}) || (20 == $agent_module->{'id_tipo_modulo'}) ) {
module_generic_image ($pa_config, \%part, $timestamp, $agent_name, $tipo_modulo, $dbh);
}
else { # Unknown module!, this IS a problem
logger ($pa_config, "Plugin Server Problem with unknown module type '$tipo_modulo'", 0);
}

View File

@ -35,6 +35,7 @@ use threads::shared;
use PandoraFMS::Config;
use PandoraFMS::Tools;
use PandoraFMS::DB;
enterprise_load ();
# Queue management
my @pending_task : shared;

View File

@ -181,6 +181,10 @@ mta_address localhost
xprobe2 /usr/bin/xprobe2
# snmpget: Needed to do SNMP checks. By default is on /usr/bin/snmpget
snmpget /usr/bin/snmpget
# Default group id for new agents created with Pandora FMS Data Server
autocreate_group 2
@ -194,3 +198,13 @@ autocreate 1
max_log_size 65536
# Send XML over Multicast channels async uptades on events and sync full tree
# info of tagged items (With custom ID) (only enterprise).
# mcast_status_port 22222
# mcast_status_group 224.1.1.1
# mcast_change_port 11111
# mcast_change_group 224.1.1.1

View File

@ -38,8 +38,8 @@ our @EXPORT = qw(
# There is no global vars, all variables (setup) passed as hash reference
# version: Defines actual version of Pandora Server for this module only
my $pandora_version = "2.1-dev";
my $pandora_build="PS090126";
my $pandora_version = "3.0-dev";
my $pandora_build="PS090305";
our $VERSION = $pandora_version." ".$pandora_build;
# Setup hash
@ -194,20 +194,24 @@ sub pandora_loadconfig {
# Xprobe2 for recon OS fingerprinting (optional feature to detect OS)
$pa_config->{"xprobe2"} = "/usr/bin/xprobe2";
# Snmpget for snmpget system command (optional)
$pa_config->{"snmpget"} = "/usr/bin/snmpget";
$pa_config->{'autocreate_group'} = 2;
$pa_config->{'autocreate'} = 1;
# max log size (bytes)
$pa_config->{'max_log_size'} = 1048576; # 1MB by default
$pa_config->{'max_log_size'} = 32000;
# Multicast status report
$pa_config->{'mcast_status_group'} = '226.1.1.2';
$pa_config->{'mcast_status_port'} = '2000';
$pa_config->{'mcast_status_group'} = '';
$pa_config->{'mcast_status_port'} = '';
# Multicast change report
$pa_config->{'mcast_change_group'} = '226.1.1.2';
$pa_config->{'mcast_change_port'} = '2000';
$pa_config->{'mcast_change_group'} = '';
$pa_config->{'mcast_change_port'} = '';
# Check for UID0
if ($pa_config->{"quiet"} != 0){
@ -408,6 +412,9 @@ sub pandora_loadconfig {
elsif ($parametro =~ m/^xprobe2\s(.*)/i) {
$pa_config->{'xprobe2'}= clean_blank($1);
}
elsif ($parametro =~ m/^snmpget\s(.*)/i) {
$pa_config->{'snmpget'}= clean_blank($1);
}
elsif ($parametro =~ m/^autocreate\s([0-9*]*)/i) {
$pa_config->{'autocreate'}= clean_blank($1);
}

View File

@ -887,12 +887,16 @@ sub pandora_accessupdate (%$$) {
my $dbh = $_[2];
my $err;
if ($id_agent != -1){
my $intervalo = dame_intervalo ($pa_config, $id_agent, $dbh);
my $utimestamp = &UnixDate("today","%s");
my $query2 = "INSERT INTO tagent_access (id_agent, utimestamp) VALUES ($id_agent,'$utimestamp')";
$dbh->do($query2);
}
if (!defined($id_agent)){
return -1;
}
if ($id_agent != -1){
my $intervalo = dame_intervalo ($pa_config, $id_agent, $dbh);
my $utimestamp = &UnixDate("today","%s");
my $query2 = "INSERT INTO tagent_access (id_agent, utimestamp) VALUES ($id_agent,'$utimestamp')";
$dbh->do($query2);
}
}
##########################################################################
@ -2072,6 +2076,11 @@ sub dame_intervalo (%$$) {
my $tipo = 0;
my @data;
if (!defined($id_agente)){
return 0;
}
# Calculate agent ID using select by its name
my $query_idag = "select * from tagente where id_agente = ".$id_agente;
my $s_idag = $dbh->prepare($query_idag);
@ -2082,8 +2091,8 @@ sub dame_intervalo (%$$) {
$tipo = 0;
} else {
@data = $s_idag->fetchrow_array();
$tipo= $data[7];
}
$tipo= $data[7];
$s_idag->finish();
return $tipo;
}

View File

@ -173,23 +173,20 @@ sub pandora_sendmail { # added in 2.0 version
##########################################################################
sub is_numeric {
$x = $_[0];
if (!defined ($x)){
my $val = $_[0];
if (!defined($val)){
return 0;
}
if ($x eq ""){
return 0;
}
# Integer ?
if ($x =~ /^-?\d/) {
return 1;
}
# Float ?
if ($x =~ /^-?\d*\./){
return 1;
}
# If not, this thing is not a number
return 0;
my $DIGITS = qr{ \d+ (?: [.] \d*)? | [.] \d+ }xms;
my $SIGN = qr{ [+-] }xms;
my $NUMBER = qr{ ($SIGN?) ($DIGITS) }xms;
if ( $val !~ /^${NUMBER}$/ ) {
return 0; #Non-numeric
} else {
return 1; #Numeric
}
}
##########################################################################
@ -242,6 +239,10 @@ sub logger {
my $param2= $_[2];
my $verbose_level = 2; # if parameter not passed, verbosity is 2
if (!defined $pa_config->{"verbosity"}){
$pa_config->{"verbosity"} = 0;
}
if (defined $param2){
if (is_numeric($param2)){
$verbose_level = $param2;
@ -322,9 +323,12 @@ sub float_equal {
# enterprise_hook ().
##########################################################################
sub enterprise_load () {
eval { require PandoraFMS::Enterprise; };
eval {
require PandoraFMS::Enterprise;
};
}
##########################################################################
# sub enterprise_hook ($function_name, \@arguments)
# Tries to call a PandoraEnterprise function. Returns undef if unsuccessful.

View File

@ -6,6 +6,8 @@ use Getopt::Long;
# Sample usage: ./multicast.pl -g 239.255.255.255 -p 1234 -t 30
my ($group,$port,$timeout);
$timeout = 10;
GetOptions(
"h" => sub { help() },
"help" => sub { help() },
@ -14,21 +16,38 @@ GetOptions(
"t=i" => \$timeout
);
if(!$timeout){
$timeout=5
};
alarm($timeout);
$SIG{ALRM} = sub {print "0"; exit 1; };
$SIG{ALRM} = sub { die_return_timeout(); };
my $sock = IO::Socket::Multicast->new(Proto=>'udp', LocalPort=>$port);
$sock->mcast_add($group) || die "0";
#die_return(); };
my $data;
next unless $sock->recv($data,1024);
print "1";
exit 0;
sub die_return {
print "0";
exit 1;
}
sub die_return_timeout {
print "0";
exit -1;
}
my $sock;
eval {
while (!defined($sock)){
$sock = IO::Socket::Multicast->new(Proto=>'udp', LocalPort=>$port);
}
$sock->mcast_add($group) || die_return();
my $data;
next unless $sock->recv($data,1);
print "1";
exit 0;
};
if ($@){
die_return_timeout();
}
sub help {
print "\nPandora FMS Plugin for Check Multicast\n\n";
@ -36,3 +55,4 @@ sub help {
print "Sample usage: ./multicast.pl -g 239.255.255.255 -p 1234 -t 10 \n\n";
exit -1;
}