diff --git a/pandora_server/ChangeLog b/pandora_server/ChangeLog index 1fa6d8da5a..6d67d37c07 100644 --- a/pandora_server/ChangeLog +++ b/pandora_server/ChangeLog @@ -1,3 +1,29 @@ +2007-03-29 Sancho Lerena + + * pandora_config.pm: Now stores $pa_config->{'server_id'} + available for any function in Pandora FMS Server. + + * pandora_db.pm: Several verbosity level adjustements in logger + functions in all code. Some debug code purged. Alert code now + should store group correctly in events. Renamed + "processed_by_server" field from tagente_estado by "running_by", + updated some code. pandora_updateserver() now stores also server + version. + + * pandora_network.pm: pandora_serverkeepaliver now run more + exactly and does not apply any delay. Module selection now uses + utimestamp AND the new running_by to know that other instance of + server is currently running this module. TCP code has moved to + function pandora_query_tcp() -code cleanup-. UDP code deleted + (doesn't work, and never used!). Fixed important bug in ICMP Proc + that causes constant FLIPFLOP in monitors since last commit. Fixed + also a problem from that version updating status timestamp. Lastry + field only be used now for checking 24hr without updating tdata + table. + + * pandora_server.conf: Updated some text and formatting, more + clear now. + 2007-03-23 Sancho Lerena * pandora_tools.pm: Added sqlWrap function to manage quotes. diff --git a/pandora_server/bin/pandora_config.pm b/pandora_server/bin/pandora_config.pm index 26b161ad74..9a3da60435 100755 --- a/pandora_server/bin/pandora_config.pm +++ b/pandora_server/bin/pandora_config.pm @@ -37,7 +37,7 @@ our @EXPORT = qw( pandora_help_screen # version: Defines actual version of Pandora Server for this module only my $pandora_version = "1.3-dev"; -my $pandora_build="PS070312"; +my $pandora_build="PS070328"; our $VERSION = $pandora_version; # Setup hash @@ -140,8 +140,8 @@ sub pandora_loadconfig { $pa_config->{"reconserver"}=0; $pa_config->{"servermode"}=""; $pa_config->{"network_threads"}=10; # Fixed default - $pa_config->{"keepalive"}=60; # 200 Seconds initially for server keepalive - $pa_config->{"keepalive_orig"}=$pa_config->{"keepalive"}; + $pa_config->{"keepalive"}=60; # 60 Seconds initially for server keepalive + $pa_config->{"keepalive_orig"} = $pa_config->{"keepalive"}; # Check for UID0 if ($> == 0){ printf " [W] It is not a good idea running Pandora FMS Server as root user, please DON'T DO IT!\n"; @@ -285,9 +285,10 @@ sub pandora_loadconfig { logger ($pa_config, "Launching $parametro $pa_config->{'version'} $pa_config->{'build'}", 0); my $config_options = "Logfile at ".$pa_config->{"logfile"}.", Basepath is ".$pa_config->{"basepath"}.", Checksum is ".$pa_config->{"pandora_check"}.", Master is ".$pa_config->{"pandora_master"}.", SNMP Console is ".$pa_config->{"snmpconsole"}.", Server Threshold at ".$pa_config->{"server_threshold"}." sec, verbosity at ".$pa_config->{"verbosity"}.", Alert Threshold at $pa_config->{'alert_threshold'}, ServerName is '".$pa_config->{'servername'}.$pa_config->{"servermode"}."'"; logger ($pa_config, "Config options: $config_options"); + my $dbh; # Check valid Database variables and update server status eval { - my $dbh = DBI->connect("DBI:mysql:pandora:$pa_config->{'dbhost'}:3306", $pa_config->{'dbuser'}, $pa_config->{'dbpass'}, { RaiseError => 1, AutoCommit => 1 }); + $dbh = DBI->connect("DBI:mysql:pandora:$pa_config->{'dbhost'}:3306", $pa_config->{'dbuser'}, $pa_config->{'dbpass'}, { RaiseError => 1, AutoCommit => 1 }); pandora_updateserver ($pa_config, $pa_config->{'servername'},1, $opmode, $dbh); # Alive status }; if ($@) { @@ -297,6 +298,9 @@ sub pandora_loadconfig { exit; } print " [*] Pandora FMS Server [".$pa_config->{'servername'}.$pa_config->{"servermode"}."] is running and operative \n"; + $pa_config->{'server_id'} = dame_server_id ($pa_config, $pa_config->{'servername'}.$pa_config->{"servermode"}, $dbh); + + # Dump all errors to errorlog # DISABLED in DEBUGMODE # ENABLE FOR PRODUCTION diff --git a/pandora_server/bin/pandora_db.pm b/pandora_server/bin/pandora_db.pm index 5460505795..3454298e2c 100644 --- a/pandora_server/bin/pandora_db.pm +++ b/pandora_server/bin/pandora_db.pm @@ -96,7 +96,7 @@ sub pandora_calcula_alerta (%$$$$$$) { $id_agente = dame_agente_id($pa_config, $nombre_agente, $dbh); $id_modulo = dame_modulo_id($pa_config, $tipo_modulo,$dbh); $id_agente_modulo = dame_agente_modulo_id($pa_config, $id_agente,$id_modulo,$nombre_modulo,$dbh); - logger($pa_config, "DEBUG: calcula_alerta() Calculado id_agente_modulo a $id_agente_modulo",5); + logger($pa_config, "DEBUG: calcula_alerta() Calculado id_agente_modulo a $id_agente_modulo",6); # If any alert from this combinatio of agent/module my $query_idag = "select * from talerta_agente_modulo where id_agente_modulo = '$id_agente_modulo'"; @@ -166,7 +166,6 @@ sub pandora_calcula_alerta (%$$$$$$) { my $err; my $flag; my $fecha_limite = DateCalc($fecha_ultima_alerta,"+ $time_threshold seconds",\$err); $flag = Date_Cmp($fecha_actual,$fecha_limite); - # DEBUG print "actual $fecha_actual limite $fecha_limite flag $flag times_fired $times_fired internal_counter $internal_counter \n"; # Check timer threshold for this alert if ( $flag >= 0 ) { # Out limits !, reset $times_fired, but do not write to # database until a real alarm was fired @@ -219,7 +218,6 @@ sub pandora_calcula_alerta (%$$$$$$) { # database until a real alarm was fired my $query_idag = "update talerta_agente_modulo set times_fired = 0, internal_counter = 0 where id_aam = $id_aam "; $dbh->do($query_idag); - # DEBUG print "SQL $query_idag \n"; } } } # While principal @@ -247,7 +245,7 @@ sub execute_alert (%$$$$$$$$$$) { my $alert_name = $_[9]; my $dbh = $_[10]; - if (($command == "") && ($alert_name == "")){ + if (($command eq "") && ($alert_name eq "")){ # Get values for commandline, reading from talerta. my $query_idag = "select * from talerta where id_alerta = '$id_alert'"; my $idag = $dbh->prepare($query_idag); @@ -293,7 +291,7 @@ sub execute_alert (%$$$$$$$$$$) { } my $evt_descripcion = "Alert fired ($agent $alert_name) $field1 $field2"; my $id_agente = dame_agente_id($pa_config,$agent,$dbh); - pandora_event($pa_config, $evt_descripcion, 0, $id_agente, $dbh); + pandora_event($pa_config, $evt_descripcion, dame_grupo_agente($pa_config, $id_agente, $dbh), $id_agente, $dbh); } @@ -334,7 +332,7 @@ sub pandora_writestate (%$$$$$$$) { my $s_idag = $dbh->prepare($query_idag); $s_idag ->execute; if ($s_idag->rows == 0) { - logger( $pa_config, "ERROR Cannot find agenteModulo $id_agente_modulo",6); + logger( $pa_config, "ERROR Cannot find agenteModulo $id_agente_modulo",4); logger( $pa_config, "ERROR: SQL Query is $query_idag ",10); } else { @data = $s_idag->fetchrow_array(); } my $module_interval = $data[7]; @@ -356,19 +354,17 @@ sub pandora_writestate (%$$$$$$$) { } # $id_agente is agent ID to update ".dame_nombreagente_agentemodulo ($id_agente_modulo)." # Let's see if there is any entry at tagente_estado table - my $idages = "select * from tagente_estado where id_agente_modulo = $id_agente_modulo"; + my $idages = "SELECT * from tagente_estado WHERE id_agente_modulo = $id_agente_modulo"; my $s_idages = $dbh->prepare($idages); $s_idages ->execute; $datos = $dbh->quote($datos); # Parse data entry for adecuate SQL representation. my $query_act; # OJO que dentro de una llave solo tiene existencia en esa llave !! if ($s_idages->rows == 0) { # Doesnt exist entry in table, lets make the first entry logger($pa_config, "Create entry in tagente_estado for module $nombre_modulo",4); - $query_act = "insert into tagente_estado (id_agente_modulo, datos, timestamp, estado, cambio, id_agente, last_try, utimestamp, current_interval, processed_by_server) values ($id_agente_modulo,$datos,'$timestamp','$estado','1',$id_agente,'$timestamp',$utimestamp, $module_interval, '$server_name')"; # Cuando se hace un insert, siempre hay un cambio de estado - + $query_act = "INSERT INTO tagente_estado (id_agente_modulo, datos, timestamp, estado, cambio, id_agente, last_try, utimestamp, current_interval, running_by) VALUES ($id_agente_modulo,$datos,'$timestamp','$estado','1',$id_agente,'$timestamp',$utimestamp, $module_interval, 0)"; # Cuando se hace un insert, siempre hay un cambio de estado } else { # There are an entry in table already @data = $s_idages->fetchrow_array(); - # Se supone que $data[5](estado) ( nos daria el estado ANTERIOR, podriamos leerlo - # ($c1,$c2,$c3...) $i_dages->fetchrow_array(); y luego hacer referencia a $c6 p.e + # Se supone que $data[5](estado) ( nos daria el estado ANTERIOR # For xxxx_PROC type (boolean / monitor), create an event if state has changed if (( $data[5] != $estado) && ($tipo_modulo =~ /proc/) ) { # Cambio de estado detectado ! @@ -386,10 +382,10 @@ sub pandora_writestate (%$$$$$$$) { pandora_event($pa_config, $descripcion, $id_grupo, $id_agente, $dbh); } if ($needs_update == 1) { - $query_act = "update tagente_estado set utimestamp = '$utimestamp', datos = $datos, cambio = '$cambio', timestamp = '$timestamp', estado = '$estado', id_agente = $id_agente, last_try = '$timestamp', current_interval = '$module_interval', processed_by_server = '$server_name' where id_agente_modulo = '$id_agente_modulo'"; + $query_act = "update tagente_estado set utimestamp = '$utimestamp', datos = $datos, cambio = '$cambio', timestamp = '$timestamp', estado = '$estado', id_agente = $id_agente, last_try = '$timestamp', current_interval = '$module_interval', running_by = 0 where id_agente_modulo = '$id_agente_modulo'"; } else { # dont update last_try field, that it's the field # we use to check last update time in database - $query_act = "update tagente_estado set utimestamp = '$utimestamp', datos = $datos, cambio = '$cambio', timestamp = '$timestamp', estado = '$estado', id_agente = $id_agente, current_interval = '$module_interval', processed_by_server = '$server_name' where id_agente_modulo = '$id_agente_modulo'"; + $query_act = "update tagente_estado set utimestamp = '$utimestamp', datos = $datos, cambio = '$cambio', timestamp = '$timestamp', estado = '$estado', id_agente = $id_agente, current_interval = '$module_interval', running_by = 0 where id_agente_modulo = '$id_agente_modulo'"; } } my $a_idages = $dbh->prepare($query_act); @@ -757,7 +753,7 @@ sub pandora_writedata (%$$$$$$$$$$){ } else { # Id AgenteModulo DOESNT exist, it could need to be created... if (dame_learnagente($pa_config, $id_agente,$dbh) eq "1"){ # Try to write a module and agent_module definition for that datablock - logger( $pa_config, "Pandora_insertdata will create module (learnmode) for agent $nombre_agente",5); + logger( $pa_config, "Pandora_insertdata will create module (learnmode) for agent $nombre_agente",6); crea_agente_modulo ($pa_config, $nombre_agente, $tipo_modulo, $nombre_modulo, $max, $min, $descripcion, $dbh); $id_agente_modulo = dame_agente_modulo_id ($pa_config, $id_agente, $id_modulo, $nombre_modulo, $dbh); $needscreate = 1; # Really needs to be created @@ -795,7 +791,7 @@ sub pandora_writedata (%$$$$$$$$$$){ # Detect changes between stored data and adquired data. if ($data[2] ne $datos){ $needsupdate=1; - logger( $pa_config, "Updating data for $nombre_modulo after compare with tagente_data: new($datos) ne old($data[2])",4); + logger( $pa_config, "Updating data for $nombre_modulo after compare with tagente_data: new($datos) ne old($data[2])",5); } else { # Data in DB is the same, but could be older (more than 1 # day ). Should check this against last_try field, who is @@ -830,18 +826,18 @@ sub pandora_writedata (%$$$$$$$$$$){ if ($datos > $max) { $datos = $max; $outlimit=1; - logger($pa_config,"DEBUG: MAX Value reached ($max) for agent $nombre_agente / $nombre_modulo",2); + logger($pa_config,"DEBUG: MAX Value reached ($max) for agent $nombre_agente / $nombre_modulo",6); } if ($datos < $min) { $datos = $min; $outlimit = 1; - logger($pa_config, "DEBUG: MIN Value reached ($min) for agent $nombre_agente / $nombre_modulo",2); + logger($pa_config, "DEBUG: MIN Value reached ($min) for agent $nombre_agente / $nombre_modulo",6); } } $query = "insert into tagente_datos (id_agente_modulo, datos,timestamp, utimestamp, id_agente) VALUES ($id_agente_modulo, $datos, '$timestamp', $utimestamp, $id_agente)"; } # If data is out of limits, do not insert into database (Thanks for David Villanueva for his words) if ($outlimit == 0){ - logger($pa_config, "DEBUG: pandora_insertdata Calculado id_agente_modulo a $id_agente_modulo",4); + logger($pa_config, "DEBUG: pandora_insertdata Calculado id_agente_modulo a $id_agente_modulo",6); logger($pa_config, "DEBUG: pandora_insertdata SQL : $query",10); $dbh->do($query); # Makes insertion in database } @@ -853,14 +849,15 @@ fin_DB_insert_datos: ## SUB pandora_serverkeepalive (pa_config, status, dbh) ## Update server status ########################################################################## -sub pandora_serverkeepaliver (%$) { +sub pandora_serverkeepaliver (%$$) { my $pa_config= $_[0]; my $opmode = $_[1]; # 0 dataserver, 1 network server, 2 snmp console, 3 recon server my $dbh = $_[2]; + my $pandorasuffix; my @data; - - if ($pa_config->{"keepalive"} <= 0){ + my $temp = $pa_config->{"keepalive"} - $pa_config->{"server_threshold"}; + if ($temp <= 0){ my $timestamp = &UnixDate("today","%Y-%m-%d %H:%M:%S"); my $temp = $pa_config->{"keepalive_orig"} * 2; # Down if keepalive x 2 seconds unknown my $fecha_limite = DateCalc($timestamp,"- $temp seconds",\$err); @@ -873,7 +870,8 @@ sub pandora_serverkeepaliver (%$) { while (@data = $s_idag->fetchrow_array()){ if ($data[3] != 0){ # only if it's currently not down # Update server data - my $sql_update = "update tserver set status = 0 where id_server = $data[0]"; + my $version_data = $pa_config->{"version"}." (P) ".$pa_config->{"build"}; + my $sql_update = "UPDATE tserver SET status = 0, version = '".$version_data."' WHERE id_server = $data[0]"; $dbh->do($sql_update); pandora_event($pa_config, "Server ".$data[1]." going Down", 0, 0, $dbh); logger( $pa_config, "Server ".$data[1]." going Down ",1); @@ -883,9 +881,9 @@ sub pandora_serverkeepaliver (%$) { $s_idag->finish(); # Update my server pandora_updateserver ($pa_config, $pa_config->{'servername'}, 1, $opmode, $dbh); - $pa_config->{"keepalive"}=$pa_config->{"keepalive_orig"}; + $pa_config->{"keepalive"} = $pa_config->{"keepalive_orig"}; } - $pa_config->{"keepalive"}=$pa_config->{"keepalive"}-$pa_config->{"server_threshold"}; + $pa_config->{"keepalive"} = $pa_config->{"keepalive"} - $pa_config->{"server_threshold"}; } ########################################################################## @@ -912,7 +910,8 @@ sub pandora_updateserver (%$$$) { my $id_server = dame_server_id($pa_config, $servername.$pandorasuffix, $dbh); if ($id_server == -1){ # Must create a server entry - my $sql_server = "insert into tserver (name,description) values ('$servername".$pandorasuffix."','Autocreated at startup')"; + my $version_data = $pa_config->{"version"}." (P) ".$pa_config->{"build"}; + my $sql_server = "INSERT INTO tserver (name,description,version) VALUES ('$servername".$pandorasuffix."','Autocreated at startup','$version_data')"; $dbh->do($sql_server); $id_server = dame_server_id($pa_config, $pa_config->{'servername'}.$pandorasuffix, $dbh); } @@ -928,14 +927,15 @@ sub pandora_updateserver (%$$$) { } # Update server data my $timestamp = &UnixDate("today","%Y-%m-%d %H:%M:%S"); + my $version_data = $pa_config->{"version"}." (P) ".$pa_config->{"build"}; if ($opmode == 0){ - $sql_update = "update tserver set status = 1, laststart = '$timestamp', keepalive = '$timestamp', recon_server = 0, snmp_server = 0, network_server = 0, data_server = 1, master = $pa_config->{'pandora_master'}, checksum = $pa_config->{'pandora_check'} where id_server = $id_server"; + $sql_update = "update tserver set version = '$version_data', status = 1, laststart = '$timestamp', keepalive = '$timestamp', recon_server = 0, snmp_server = 0, network_server = 0, data_server = 1, master = $pa_config->{'pandora_master'}, checksum = $pa_config->{'pandora_check'} where id_server = $id_server"; } elsif ($opmode == 1){ - $sql_update = "update tserver set status = 1, laststart = '$timestamp', keepalive = '$timestamp', recon_server = 0, snmp_server = 0, network_server = 1, data_server = 0, master = $pa_config->{'pandora_master'}, checksum = 0 where id_server = $id_server"; + $sql_update = "update tserver set version = '$version_data', status = 1, laststart = '$timestamp', keepalive = '$timestamp', recon_server = 0, snmp_server = 0, network_server = 1, data_server = 0, master = $pa_config->{'pandora_master'}, checksum = 0 where id_server = $id_server"; } elsif ($opmode == 2) { - $sql_update = "update tserver set status = 1, laststart = '$timestamp', keepalive = '$timestamp', recon_server = 0, snmp_server = 1, network_server = 0, data_server = 0, master = $pa_config->{'pandora_master'}, checksum = 0 where id_server = $id_server"; + $sql_update = "update tserver set version = '$version_data', status = 1, laststart = '$timestamp', keepalive = '$timestamp', recon_server = 0, snmp_server = 1, network_server = 0, data_server = 0, master = $pa_config->{'pandora_master'}, checksum = 0 where id_server = $id_server"; } elsif ($opmode == 3) { - $sql_update = "update tserver set status = 1, laststart = '$timestamp', keepalive = '$timestamp', recon_server = 1, snmp_server = 0, network_server = 0, data_server = 0, master = $pa_config->{'pandora_master'}, checksum = 0 where id_server = $id_server"; + $sql_update = "update tserver set version = '$version_data', status = 1, laststart = '$timestamp', keepalive = '$timestamp', recon_server = 1, snmp_server = 0, network_server = 0, data_server = 0, master = $pa_config->{'pandora_master'}, checksum = 0 where id_server = $id_server"; } $dbh->do($sql_update); } @@ -1088,11 +1088,11 @@ sub dame_server_id (%$$) { my $id_server;my @data; # Get serverid - my $query_idag = "select * from tserver where name = '$name'"; + my $query_idag = "SELECT * FROM tserver WHERE name = '$name' "; my $s_idag = $dbh->prepare($query_idag); $s_idag ->execute; if ($s_idag->rows == 0) { - logger ($pa_config, "ERROR dame_server_id(): Cannot find server called $name. Returning -1",10); + logger ($pa_config, "ERROR dame_server_id(): Cannot find server called $name. Returning -1",4); logger ($pa_config, "ERROR: SQL Query is $query_idag ",10); $data[0]=-1; } else { @data = $s_idag->fetchrow_array(); } @@ -1194,8 +1194,8 @@ sub dame_agente_nombre (%$$) { my $s_idag = $dbh->prepare($query_idag); $s_idag ->execute; if ($s_idag->rows == 0) { - logger($pa_config, "ERROR dame_agente_nombre(): Cannot find agent with id $id_agente",1); - logger($pa_config, "ERROR: SQL Query is $query_idag ",2); + logger($pa_config, "ERROR dame_agente_nombre(): Cannot find agent with id $id_agente",4); + logger($pa_config, "ERROR: SQL Query is $query_idag ",10); } else { @data = $s_idag->fetchrow_array(); } $nombre_agente = $data[1]; $s_idag->finish(); @@ -1274,8 +1274,8 @@ sub dame_nombreagente_agentemodulo (%$$) { my $s_idag = $dbh->prepare($query_idag); $s_idag ->execute; if ($s_idag->rows == 0) { - logger($pa_config, "ERROR dame_nombreagente_agentemodulo(): Cannot find id_agente_modulo $id_agentemodulo",1); - logger($pa_config, "ERROR: SQL Query is $query_idag ",2); + logger($pa_config, "ERROR dame_nombreagente_agentemodulo(): Cannot find id_agente_modulo $id_agentemodulo",3); + logger($pa_config, "ERROR: SQL Query is $query_idag ",10); $id_agente = -1; } else { @data = $s_idag->fetchrow_array(); @@ -1349,8 +1349,8 @@ sub dame_id_tipo_modulo (%$$) { my $s_idag = $dbh->prepare($query_idag); $s_idag ->execute; if ($s_idag->rows == 0) { - logger($pa_config, "ERROR dame_id_tipo_modulo(): Cannot find id_agente_modulo $id_agente_modulo",1); - logger($pa_config, "ERROR: SQL Query is $query_idag ",2); + logger($pa_config, "ERROR dame_id_tipo_modulo(): Cannot find id_agente_modulo $id_agente_modulo",4); + logger($pa_config, "ERROR: SQL Query is $query_idag ",10); $tipo ="-1"; } else { @data = $s_idag->fetchrow_array(); @@ -1422,8 +1422,8 @@ sub dame_desactivado (%$$) { my $s_idag = $dbh->prepare($query_idag); $s_idag ->execute; if ($s_idag->rows == 0) { - logger($pa_config, "ERROR dame_desactivado(): Cannot find agente $id_agente",1); - logger($pa_config, "ERROR: SQL Query is $query_idag ",2); + logger($pa_config, "ERROR dame_desactivado(): Cannot find agente $id_agente",4); + logger($pa_config, "ERROR: SQL Query is $query_idag ",10); $desactivado = -1; } else { @data = $s_idag->fetchrow_array(); @@ -1494,7 +1494,7 @@ sub crea_agente_modulo (%$$$$$$$) { } elsif ($min eq "") { $query = "insert into tagente_modulo (id_agente,id_tipo_modulo,nombre,min,descripcion) values ($agente_id,$modulo_id,'$nombre_modulo',$min,'$descripcion (*)')"; } - logger( $pa_config, "DEBUG: Query for autocreate : $query ",3); + logger( $pa_config, "DEBUG: Query for autocreate : $query ",6); $dbh->do($query); } diff --git a/pandora_server/bin/pandora_network.pl b/pandora_server/bin/pandora_network.pl index 015329d4ba..7070c23de9 100755 --- a/pandora_server/bin/pandora_network.pl +++ b/pandora_server/bin/pandora_network.pl @@ -3,7 +3,7 @@ # Pandora FMS Network Server ########################################################################## # Copyright (c) 2006-2007 Sancho Lerena, slerena@gmail.com -# +# (c) 2006-2007 Artica Soluciones Tecnologicas S.L # 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 @@ -20,8 +20,8 @@ use strict; use warnings; -use Date::Manip; # Needed to manipulate DateTime formats of input, output and compare -use Time::Local; # DateTime basic manipulation +use Date::Manip; # Needed to manipulate DateTime formats of input, output and compare +use Time::Local; # DateTime basic manipulation use Net::Ping; # For ICMP latency use Time::HiRes; # For high precission timedate functions (Net::Ping) use IO::Socket; # For TCP/UDP access @@ -83,13 +83,9 @@ my $dbhost = $pa_config{'dbhost'}; my $dbh = DBI->connect("DBI:mysql:pandora:$dbhost:3306", $pa_config{'dbuser'}, $pa_config{'dbpass'}, { RaiseError => 1, AutoCommit => 1 }); while (1) { - pandora_serverkeepaliver (\%pa_config,1,$dbh); + pandora_serverkeepaliver (\%pa_config, 1, $dbh); threads->yield; - if ($pa_config{"server_threshold"} < 10){ - sleep (10); - } else { - sleep ($pa_config{"server_threshold"}); - } + sleep ($pa_config{"server_threshold"}); } #------------------------------------------------------------------------------------ @@ -140,7 +136,7 @@ sub pandora_network_subsystem { my $max; my $min; my $module_interval; my $nombre; my $tcp_port; my $tcp_rcv; my $tcp_send; my $snmp_oid; my $snmp_community; my $ip_target; my $id_module_group; - my $timestamp_viejo; # Stores timestamp from tagente_estado table + my $timestamp_old; # Stores timestamp from tagente_estado table my $id_agente_estado; # ID from tagente_estado table my $estado_cambio; # store tagente_estado cambio field my $estado_estado; # Store tagente_estado estado field @@ -158,9 +154,8 @@ sub pandora_network_subsystem { my $query_sql; my $query_sql2; my $query_sql3; my $exec_sql; my $exec_sql2; my $exec_sql3; my $buffer; - + my $running; - $server_id = dame_server_id($pa_config, $pa_config->{'servername'}."_Net", $dbh); while ( 1 ) { logger ($pa_config,"Loop in Network Module Subsystem",10); @@ -205,7 +200,7 @@ sub pandora_network_subsystem { $agent_interval = $sql_data2[7]; $agent_disabled = $sql_data2[12]; $agent_osdata =$sql_data2[8]; - + # Second: Checkout for agent_modules with type = X # (network modules) and owned by our selected agent @@ -219,8 +214,6 @@ sub pandora_network_subsystem { # 32 for SNMP PROC # 0 for the rest: TCP DATA, TCP DATA_INC and TCP DATA_STRING # SNMP DATA, SNMP DATA_STRING - - if ($nettype == 111){ # icmp proc high lat $query_sql = "select * from tagente_modulo where id_tipo_modulo = 6 AND (module_interval = 0 OR module_interval > 100) AND id_agente = $id_agente"; $nettypedesc="ICMP PROC HighLatency"; @@ -241,17 +234,15 @@ sub pandora_network_subsystem { $nettypedesc="SNMP DataInc Low Latency"; } elsif ($nettype == 12){ #icmp data $query_sql = "select * from tagente_modulo where id_tipo_modulo = 7 AND id_agente = $id_agente"; - $nettypedesc="ICMP PROC Low Latency"; - $nettypedesc="TCP/UDP"; + $nettypedesc="ICMP DATA (Latency)"; } elsif ($nettype == 32){ #snmp proc $query_sql = "select * from tagente_modulo where id_tipo_modulo = 18 AND id_agente = $id_agente"; - $nettypedesc="ICMP PROC Low Latency"; - $nettypedesc="TCP/UDP"; + $nettypedesc="SNMP PROC"; } elsif ($nettype == 0){ # TCP DATA, TCP DATA_INC and TCP DATA_STRING, UDP PROC # SNMP DATA, SNMP DATA_STRING $query_sql = "select * from tagente_modulo where ( id_tipo_modulo = 8 OR id_tipo_modulo = 10 OR id_tipo_modulo =11 OR id_tipo_modulo = 12 OR id_tipo_modulo = 15 OR id_tipo_modulo = 17 ) AND id_agente = $id_agente"; - $nettypedesc="TCPData, TCPDataInc, TCPString, UDPProc, SNMPData, SNMPString"; + $nettypedesc="TCPData, TCPDataInc, TCPString, SNMPData, SNMPString"; } $exec_sql = $dbh->prepare($query_sql); $exec_sql ->execute; @@ -280,37 +271,37 @@ sub pandora_network_subsystem { $exec_sql3 ->execute; if ($exec_sql3->rows > 0) { # Exist entry in tagente_estado @sql_data3 = $exec_sql3->fetchrow_array(); - $timestamp_viejo = $sql_data3[7]; # Now use last_try (for network agents) + $timestamp_old = $sql_data3[8]; # Now use utimestamp $id_agente_estado = $sql_data3[0]; $estado_cambio = $sql_data3[4]; $estado_estado = $sql_data3[5]; + $running = $sql_data3[11]; } else { $id_agente_estado = -1; $estado_estado = -1; } $exec_sql3->finish(); # if timestamp of tagente_modulo + module_interval <= timestamp actual, exec module - my $fecha_estatus = ParseDate($timestamp_viejo); - my $fecha_mysql = &UnixDate("today","%Y-%m-%d %H:%M:%S"); # If we need to updat - my $fecha_actual = ParseDate( $fecha_mysql ); - my $err; my $fecha_flag; - my $fecha_limite = DateCalc($fecha_estatus,"+ $module_interval seconds",\$err); - # Comprobar que est�por encima (sumando esta) del minimo de alertas - # Comprobar que est�por debajo (sumando esta) del m�imo de alertas - $fecha_flag = Date_Cmp($fecha_actual,$fecha_limite); - if (( $fecha_flag >= 0) || ($flag == 1)) { # Exec module, we are out time limit ! - # thread - # my $threadid = threads->new( \&exec_network_module, $id_agente, $id_agente_estado, $id_tipo_modulo, $fecha_mysql, $nombre, $min, $max, $agent_interval, $tcp_port, $tcp_send, $tcp_rcv, $snmp_community, $snmp_oid, $ip_target, $module_result, $module_data, $estado_cambio, $estado_estado, $agent_name, $agent_osdata, $id_agente_modulo, $pa_config, $dbh); - # $threadid->detach; + + my $current_timestamp = &UnixDate("today","%s"); + my $err; + my $limit1_timestamp = $timestamp_old + $module_interval; + my $limit2_timestamp = $timestamp_old + ($module_interval*2); + + if ( ($limit2_timestamp < $current_timestamp) || (($running == 0) && ( $limit1_timestamp < $current_timestamp)) || ($flag == 1) ) { # Exec module, we are out time limit ! if ($flag == 1){ # Reset flag to 0 - $query_sql3 = "update tagente_modulo set flag=0 where id_agente_modulo = $id_agente_modulo"; + $query_sql3 = "UPDATE tagente_modulo SET flag=0 WHERE id_agente_modulo = $id_agente_modulo"; $exec_sql3 = $dbh->prepare($query_sql3); $exec_sql3 ->execute; $exec_sql3->finish(); } - logger ($pa_config, "Network Module Subsystem ($nettypedesc): Exec Netmodule '$nombre'",5); - exec_network_module( $id_agente, $id_agente_estado, $id_tipo_modulo, $fecha_mysql, $nombre, $min, $max, $agent_interval, $tcp_port, $tcp_send, $tcp_rcv, $snmp_community, $snmp_oid, $ip_target, $module_result, $module_data, $estado_cambio, $estado_estado, $agent_name, $agent_osdata, $id_agente_modulo, $pa_config, $dbh); - + # Update running_by flag + $query_sql3 = "UPDATE tagente_estado SET running_by = ".$pa_config->{'server_id'}." WHERE id_agente_modulo = $id_agente_modulo"; + $exec_sql3 = $dbh->prepare($query_sql3); + $exec_sql3 ->execute; + $exec_sql3->finish(); + logger ($pa_config, "Network Module Subsystem ($nettypedesc): Exec Netmodule '$nombre' ID $id_agente_modulo ",4); + exec_network_module( $id_agente, $id_agente_estado, $id_tipo_modulo, $nombre, $min, $max, $agent_interval, $tcp_port, $tcp_send, $tcp_rcv, $snmp_community, $snmp_oid, $ip_target, $module_result, $module_data, $estado_cambio, $estado_estado, $agent_name, $agent_osdata, $id_agente_modulo, $pa_config, $dbh); } # Timelimit if } # while $exec_sql->finish(); @@ -325,7 +316,6 @@ sub pandora_network_subsystem { ############################################################################## # pandora_ping_icmp (destination, timeout) - Do a ICMP scan, 1 if alive, 0 if not ############################################################################## - sub pandora_ping_icmp { my $p; my $dest = $_[0]; @@ -341,31 +331,88 @@ sub pandora_ping_icmp { } } -############################################################################## -# pandora_ping_udp (destination, timeout, port ) - Do a UDP, 1 if alive, 0 if not -############################################################################## - -sub pandora_ping_udp { - my $p; - my $dest = $_[0]; - my $l_timeout = $_[1]; - my $tcp_port = $_[2]; - - if (($tcp_port < 65536) && ($tcp_port > 0)){ - $p = Net::Ping->new("udp",$l_timeout); - my $udp_return; - my $udp_reply; - my $udp_ip; - ($udp_return, $udp_reply, $udp_ip) = $p->ping ($dest,$l_timeout); - if ($udp_return) { - # Return value - return 1; - } else { - return 0; +########################################################################## +# SUB pandora_query_tcp (pa_config, tcp_port. ip_target, result, data, tcp_send, +# tcp_rcv, id_tipo_module, dbh) +# Makes a call to TCP modules to get a value. +########################################################################## +sub pandora_query_tcp { + my $pa_config = $_[0]; + my $tcp_port = $_[1]; + my $ip_target = $_[2]; + my $module_result = $_[3]; + my $module_data = $_[4]; + my $tcp_send = $_[5]; + my $tcp_rcv = $_[6]; + my $id_tipo_modulo = $_[7]; + my $dbh = $_[8]; + + my $temp; my $temp2; + my $tam; + + my $handle=IO::Socket::INET->new( + Proto=>"tcp", + PeerAddr=>$ip_target, + Timeout=>$pa_config->{'networktimeout'}, + PeerPort=>$tcp_port, + Blocking=>0 ); # Non blocking !!, very important ! + + if (defined($handle)){ + if ($tcp_send ne ""){ # its Expected to sending data ? + # Send data + $handle->autoflush(1); + $tcp_send =~ s/\^M/\r\n/g; + # Replace Carriage rerturn and line feed + $handle->send($tcp_send); + } + # we expect to receive data ? + if (($tcp_rcv ne "") || ($id_tipo_modulo == 10) || ($id_tipo_modulo ==8) || ($id_tipo_modulo == 11)) { + # Receive data, non-blocking !!!! (VERY IMPORTANT!) + $temp2 = ""; + for ($tam=0; $tam<($pa_config->{'networktimeout'}/2); $tam++){ + $handle->recv($temp,16000,0x40); + $temp2 = $temp2.$temp; + if ($temp ne ""){ + $tam++; # If doesnt receive data, increase counter + } + sleep(1); + } + if ($id_tipo_modulo == 9){ # only for TCP Proc + if ($temp2 =~ /$tcp_rcv/i){ # String match ! + $module_data = 1; + $module_result = 0; + } else { + $module_data = 0; + $module_result = 0; + } + } elsif ($id_tipo_modulo == 10 ){ # TCP String (no int conversion)! + $module_data = $temp2; + $module_result =0; + } else { # TCP Data numeric (inc or data) + if ($temp2 ne ""){ + if ($temp2 =~ /[A-Za-z\.\,\-\/\\\(\)\[\]]/){ + $module_result=1; # init + $module_data = 0; # invalid data + } else { + $module_data = int($temp2); + $module_result = 0; # Successful + } + } + $module_result = 0; # Successful + } + } else { # No expected data to receive, if connected and tcp_proc type successful + if ($id_tipo_modulo == 9){ # TCP Proc + $module_result = 0; + $module_data = 1; + } + } + $handle->close(); + } else { # Cannot connect (open sock failed) + $module_result = 1; # Fail + if ($id_tipo_modulo == 9){ # TCP Proc + $module_result = 0; + $module_data = 0; # Failed, but data exists } - $p->close(); - } else { - return 0; } } @@ -382,11 +429,11 @@ sub pandora_query_snmp { my $dbh = $_[5]; my $output =""; $ENV{'MIBS'}="ALL"; #Load all available MIBs - my $SESSION = new SNMP::Session (DestHost => $snmp_target, + my $SESSION = new SNMP::Session (DestHost => $snmp_target, Community => $snmp_community, Version => 1); if ((!defined($SESSION))&& ($snmp_community != "") && ($snmp_oid != "")) { - logger($pa_config, "SNMP ERROR SESSION", 4); + logger($pa_config, "SNMP ERROR SESSION for Target $snmp_target ", 4); $_[4]="1"; } else { # Perl uses different OID syntax than SNMPWALK or PHP's SNMP @@ -405,10 +452,9 @@ sub pandora_query_snmp { $perl_oid = $local_oid.".".$local_oid_idx; } } - my $OIDLIST = new SNMP::VarList([$perl_oid]); # Pass the VarList to getnext building an array of the output - my @OIDINFO = $SESSION->getnext($OIDLIST); + my @OIDINFO = $SESSION->getnext($OIDLIST); $output = $OIDINFO[0]; if ((!defined($output)) || ($output eq "")){ $_[4]="1"; @@ -416,8 +462,6 @@ sub pandora_query_snmp { $_[4]="0"; } } - # Too much DEBUG for me :-) - # logger($pa_config, "SNMP RESULT $snmp_oid $snmp_target - > $output \n",10); return $output; } @@ -429,26 +473,26 @@ sub exec_network_module { my $id_agente = $_[0]; my $id_agente_estado = $_[1]; my $id_tipo_modulo= $_[2]; - my $fecha_mysql= $_[3]; - my $nombre= $_[4]; - my $min= $_[5]; - my $max= $_[6]; - my $agent_interval= $_[7]; - my $tcp_port = $_[8]; - my $tcp_send = $_[9]; - my $tcp_rcv = $_[10]; - my $mysnmp_community = $_[11]; - my $mysnmp_oid = $_[12]; - my $ip_target = $_[13]; - my $module_result = $_[14]; - my $module_data = $_[15]; - my $estado_cambio = $_[16]; - my $estado_estado = $_[17]; - my $agent_name = $_[18]; - my $agent_osdata = $_[19]; - my $id_agente_modulo = $_[20]; - my $pa_config = $_[21]; - my $dbh = $_[22]; + my $nombre= $_[3]; + my $min= $_[4]; + my $max= $_[5]; + my $agent_interval= $_[6]; + my $tcp_port = $_[7]; + my $tcp_send = $_[8]; + my $tcp_rcv = $_[9]; + my $mysnmp_community = $_[10]; + my $mysnmp_oid = $_[11]; + my $ip_target = $_[12]; + my $module_result = $_[13]; + my $module_data = $_[14]; + my $estado_cambio = $_[15]; + my $estado_estado = $_[16]; + my $agent_name = $_[17]; + my $agent_osdata = $_[18]; + my $id_agente_modulo = $_[19]; + my $pa_config = $_[20]; + my $dbh = $_[21]; + my $error = "1"; my $query_sql2; my $temp=0; my $tam; my $temp2; @@ -457,13 +501,12 @@ sub exec_network_module { # ICMP Modules # ------------ if ($id_tipo_modulo == 6){ # ICMP (Connectivity only: Boolean) - $temp = pandora_ping_icmp ($ip_target, $pa_config->{'networktimeout'}); if ($temp == 1 ){ $module_result = 0; # Successful $module_data = 1; } else { - $module_result = 0; # Error, cannot connect + $module_result = 1; # Error, cannot connect $module_data = 0; } } elsif ($id_tipo_modulo == 7){ # ICMP (data for latency in ms) @@ -517,82 +560,12 @@ sub exec_network_module { # ---------- } elsif (($id_tipo_modulo == 8) || ($id_tipo_modulo == 9) || ($id_tipo_modulo == 10) || ($id_tipo_modulo == 11)) { # TCP Module if (($tcp_port < 65536) && ($tcp_port > 0)){ # Port check - my $handle=IO::Socket::INET->new( - Proto=>"tcp", - PeerAddr=>$ip_target, - Timeout=>$pa_config->{'networktimeout'}, - PeerPort=>$tcp_port, - Blocking=>0 ); - if (defined($handle)){ - if ($tcp_send ne ""){ # its Expected to sending data ? - # Send data - $handle->autoflush(1); - $tcp_send =~ s/\^M/\r\n/g; # Replace Carriage rerturn and line feed de los guevos - $handle->send($tcp_send); - } - if (($tcp_rcv ne "") || ($id_tipo_modulo == 10) || ($id_tipo_modulo ==8) || ($id_tipo_modulo == 11)) { # its Expected to receive data ? - # Receive data, non-blocking !!!! (VERY IMPORTANT!) - for ($tam=0; $tam<($pa_config->{'networktimeout'}/2); $tam++){ - $handle->recv($temp,16000,0x40); - $temp2 = $temp2.$temp; - if ($temp ne ""){ - $tam++; # If doesnt receive data, increase counter - } - sleep(1); - } - if ($id_tipo_modulo == 9){ # only for TCP Proc - if ($temp2 =~ /$tcp_rcv/i){ # String match ! - $module_data = 1; - $module_result =0; - } else { - $module_data = 0; - $module_result =0; - } - - } elsif ($id_tipo_modulo == 10 ){ # TCP String (no int conversion)! - $module_data = $temp2; - $module_result =0; - } else { # TCP Data numeric (inc or data) - if ($temp2 ne ""){ - if ($temp2 =~ /[A-Za-z\.\,\-\/\\\(\)\[\]]/){ - $module_result=1; # init - $module_data = 0; # invalid data - } else { - $module_data = int($temp2); - $module_result = 0; # Successful - } - } - $module_result = 0; # Successful - } - } else { # No expected data to receive, if connected and tcp_proc type successful - if ($id_tipo_modulo == 9){ # TCP Proc - $module_result = 0; - $module_data = 1; - } - } - $handle->close(); - } else { # Cannot connect (open sock failed) - $module_result = 1; # Fail - if ($id_tipo_modulo == 9){ # TCP Proc - $module_result = 0; - $module_data = 0; # Failed, but data exists - } - } + pandora_query_tcp ($pa_config, $tcp_port, $ip_target, \$module_result, \$module_data, $tcp_send, $tcp_rcv, $id_tipo_modulo, $dbh) } else { - $module_result = 1; + $module_result = 1; } - } elsif ($id_tipo_modulo == 12){ # UDP Proc - if (pandora_ping_udp ($ip_target, $pa_config->{"networktimeout"}, $tcp_port) == 1){ - $module_result = 0; - $module_data = 1; - } else { - $module_result = 0; # Cannot connect - $module_data = 0; - } - } + } # -------------------------------------------------------- - # module_generic_data_inc (part, timestamp, agent_name) - # recreate hash for module_generic functions # -------------------------------------------------------- if ($module_result == 0) { my %part; @@ -601,36 +574,36 @@ sub exec_network_module { $part{'data'}[0]=$module_data; $part{'max'}[0]=$max; $part{'min'}[0]=$min; - + my $timestamp = &UnixDate("today","%Y-%m-%d %H:%M:%S"); my $tipo_modulo = dame_nombretipomodulo_idagentemodulo($pa_config, $id_tipo_modulo,$dbh); if (($tipo_modulo eq 'remote_snmp') || ($tipo_modulo eq 'remote_icmp') || ($tipo_modulo eq 'remote_tcp') || ($tipo_modulo eq 'remote_udp')) { - module_generic_data($pa_config, \%part,$fecha_mysql,$agent_name,$tipo_modulo,$dbh); + module_generic_data($pa_config, \%part,$timestamp,$agent_name,$tipo_modulo,$dbh); } elsif ($tipo_modulo =~ /\_inc/ ) { - module_generic_data_inc($pa_config, \%part,$fecha_mysql,$agent_name,$tipo_modulo,$dbh); + module_generic_data_inc($pa_config, \%part,$timestamp,$agent_name,$tipo_modulo,$dbh); } elsif ($tipo_modulo =~ /\_string/) { - module_generic_data_string($pa_config, \%part,$fecha_mysql,$agent_name,$tipo_modulo,$dbh); + module_generic_data_string($pa_config, \%part,$timestamp,$agent_name,$tipo_modulo,$dbh); } elsif ($tipo_modulo =~ /\_proc/){ - module_generic_proc($pa_config, \%part,$fecha_mysql,$agent_name,$tipo_modulo,$dbh); + module_generic_proc($pa_config, \%part,$timestamp,$agent_name,$tipo_modulo,$dbh); } else { - logger ($pa_config, "Problem with unknown module type '$tipo_modulo'",0); + logger ($pa_config, "Problem with unknown module type '$tipo_modulo'", 0); goto skipdb_execmod; } # Update agent last contact # Insert Pandora version as agent version - pandora_lastagentcontact ($pa_config,$fecha_mysql,$agent_name,$agent_osdata,$pa_config->{'version'},$agent_interval,$dbh); - } else { + pandora_lastagentcontact ($pa_config, $timestamp, $agent_name, $agent_osdata, $pa_config->{'version'}, $agent_interval, $dbh); + } else { # $module_result != 0) # Modules who cannot connect or something go bad, update last_try field my $timestamp = &UnixDate("today","%Y-%m-%d %H:%M:%S"); - my $query_act = "update tagente_estado set last_try = '$timestamp' where id_agente_estado = $id_agente_estado "; + my $utimestamp = &UnixDate("today","%s"); + my $query_act = "UPDATE tagente_estado SET utimestamp = $utimestamp, timestamp = '$timestamp', last_try = '$timestamp' WHERE id_agente_estado = $id_agente_estado "; my $a_idages = $dbh->prepare($query_act); $a_idages->execute; $a_idages->finish(); } - skipdb_execmod: #$dbh->disconnect(); } diff --git a/pandora_server/conf/pandora_server.conf b/pandora_server/conf/pandora_server.conf index e00e32cd06..59841624a4 100755 --- a/pandora_server/conf/pandora_server.conf +++ b/pandora_server/conf/pandora_server.conf @@ -3,65 +3,86 @@ ################################################################################### # Servername: Name of this server +# if not given, it takes localhost. It's preferable to setup one +# because machine name could change by some reason. + servername localhost # incomingdir: Defines directory where incoming data packets are stored # You could set directory relative to base path or absolute, starting with / + incomingdir /opt/pandora_server/data_in # log_file: Main logfile for pandora_server # You could set file relative to base path or absolute, starting with / + log_file /opt/pandora_server/log/pandora_server.log # Error logfile: aux logfile for pandora_server errors (in Daemon mode) # You could set file relative to base path or absolute, starting with / + errorlog_file /opt/pandora_server/log/pandora_server.error # dbuser: Database user name (pandora by default) + dbuser pandora # daemon: Runs in daemon mode (background) if 1, if 0 runs in foreground # this could be setup on command line with -D option -# NEW in pandora 1.2, default is 0 + # daemon 1 # dbpass: Database password + dbpass pandora # dbhost: Database hostname or IP address + dbhost localhost # verbosity: level of detail on errors/messages (0 default, 1 verbose, 2 debug.... 10 noisy) # -v in command line (verbose) or -d (debug) -verbosity 9 -# Server Threshold: defines number of seconds of main loop (in sec) -server_threshold 5 +verbosity 4 # Alert threshold + alert_threshold 60 # Master Server, 1 if master server (normal mode), 0 for slave mode (slave in multi-server setup) + master 1 # Check datafiles using a MD5 hash, 1 to check (default), 0 to ignore .checksum + checksum 0 # Activate Pandora SNMP console (depending on snmptrapd) # only available on Pandora Network server + snmpconsole 1 # Activate (1) Pandora Network Server + networkserver 1 # Activate (1) Pandora Data Server + dataserver 1 # Activate (1) Pandora FMS Recon server + reconserver 1 # Network timeout (in seconds) for timeout in network connections for Network agents + network_timeout 5 # Server keepalive (in seconds) -server_keepalive 45 + +server_keepalive 90 + +# Server Threshold: defines number of seconds of main loop (in sec) + +server_threshold 5 +