From 60e9cb839edbf3f4df0505c915b8de1104f4937c Mon Sep 17 00:00:00 2001 From: slerena Date: Wed, 4 Mar 2009 17:15:39 +0000 Subject: [PATCH] 2009-03-05 Sancho Lerena * 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 --- pandora_server/ChangeLog | 15 +++++ pandora_server/bin/pandora_network | 25 ++++++- pandora_server/bin/pandora_plugin | 86 +++++++++++++++++-------- pandora_server/bin/pandora_server | 1 + pandora_server/conf/pandora_server.conf | 14 ++++ pandora_server/lib/PandoraFMS/Config.pm | 21 ++++-- pandora_server/lib/PandoraFMS/DB.pm | 23 +++++-- pandora_server/lib/PandoraFMS/Tools.pm | 36 ++++++----- pandora_server/util/plugin/multicast.pl | 42 ++++++++---- 9 files changed, 193 insertions(+), 70 deletions(-) diff --git a/pandora_server/ChangeLog b/pandora_server/ChangeLog index 07054d2080..893677c410 100644 --- a/pandora_server/ChangeLog +++ b/pandora_server/ChangeLog @@ -1,3 +1,18 @@ +2009-03-05 Sancho Lerena + + * 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 * lib/PandoraFMS/DB.pm: Fixed alert recovery custom fields. diff --git a/pandora_server/bin/pandora_network b/pandora_server/bin/pandora_network index 490ed5c13b..3acd35cd78 100755 --- a/pandora_server/bin/pandora_network +++ b/pandora_server/bin/pandora_network @@ -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; } diff --git a/pandora_server/bin/pandora_plugin b/pandora_server/bin/pandora_plugin index de026d1724..63549592b5 100755 --- a/pandora_server/bin/pandora_plugin +++ b/pandora_server/bin/pandora_plugin @@ -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); } diff --git a/pandora_server/bin/pandora_server b/pandora_server/bin/pandora_server index fed240bc90..da5218ae00 100755 --- a/pandora_server/bin/pandora_server +++ b/pandora_server/bin/pandora_server @@ -35,6 +35,7 @@ use threads::shared; use PandoraFMS::Config; use PandoraFMS::Tools; use PandoraFMS::DB; +enterprise_load (); # Queue management my @pending_task : shared; diff --git a/pandora_server/conf/pandora_server.conf b/pandora_server/conf/pandora_server.conf index 789a2cbb44..66c8c37167 100755 --- a/pandora_server/conf/pandora_server.conf +++ b/pandora_server/conf/pandora_server.conf @@ -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 + + diff --git a/pandora_server/lib/PandoraFMS/Config.pm b/pandora_server/lib/PandoraFMS/Config.pm index 94ba9c1773..b9ee24a54c 100644 --- a/pandora_server/lib/PandoraFMS/Config.pm +++ b/pandora_server/lib/PandoraFMS/Config.pm @@ -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); } diff --git a/pandora_server/lib/PandoraFMS/DB.pm b/pandora_server/lib/PandoraFMS/DB.pm index 86608a6080..0954303b38 100644 --- a/pandora_server/lib/PandoraFMS/DB.pm +++ b/pandora_server/lib/PandoraFMS/DB.pm @@ -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; } diff --git a/pandora_server/lib/PandoraFMS/Tools.pm b/pandora_server/lib/PandoraFMS/Tools.pm index 6f12732d80..40c5777e46 100644 --- a/pandora_server/lib/PandoraFMS/Tools.pm +++ b/pandora_server/lib/PandoraFMS/Tools.pm @@ -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. diff --git a/pandora_server/util/plugin/multicast.pl b/pandora_server/util/plugin/multicast.pl index f8e5d6ca48..3034e288ee 100755 --- a/pandora_server/util/plugin/multicast.pl +++ b/pandora_server/util/plugin/multicast.pl @@ -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; } +