2008-06-13 Sancho Lerena <slerena@artica.es>

* conf/pandora_server.conf: Added new internal MTA feature config tokens .
    
    * pandora_server_installer: Copy default plugins to /usr/share/pandora/util
    
    * Config.pm: New MTA feature tokens, and added event when starting server.
    
    * DB.pm: Changes in execute_alert function (now passes several hash refs).
    Alerts and events now use new format of events. Add support for new inter-
    nal MTA/SMTP alert feature. Discovered and FIXED a very annoying bug on
    need_update usage in write_state function that was making a HUGE 
    degradation when too many non-init modules in network server.
        
    * Tools.pm: Added pandora_sendmail() function. Needs Mail::Sendmail dep.
    
    * All servers: Support for pandora_shutdown notify on event database.
    
    * pandora_snmpconsole: Updated SNMP alert mechanism. Need to be tested!.
    
    * pandora_recon: Now generate an event when discover a new host.
    
    * util/pandora_db.pl: Added support to automatically delete events.



git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@859 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
This commit is contained in:
slerena 2008-06-13 16:42:35 +00:00
parent 3149b2e7df
commit 9920b0609f
14 changed files with 406 additions and 133 deletions

View File

@ -1,3 +1,28 @@
2008-06-13 Sancho Lerena <slerena@artica.es>
* conf/pandora_server.conf: Added new internal MTA feature config tokens .
* pandora_server_installer: Copy default plugins to /usr/share/pandora/util
* Config.pm: New MTA feature tokens, and added event when starting server.
* DB.pm: Changes in execute_alert function (now passes several hash refs).
Alerts and events now use new format of events. Add support for new inter-
nal MTA/SMTP alert feature. Discovered and FIXED a very annoying bug on
need_update usage in write_state function that was making a HUGE
degradation when too many non-init modules in network server.
* Tools.pm: Added pandora_sendmail() function. Needs Mail::Sendmail dep.
* All servers: Support for pandora_shutdown notify on event database.
* pandora_snmpconsole: Updated SNMP alert mechanism. Need to be tested!.
* pandora_recon: Now generate an event when discover a new host.
* util/pandora_db.pl: Added support to automatically delete events.
2008-06-12 Manuel Arostegui <marostegui@artica.es>
* pandora_snmpconsole: Removed "/var/run/pandora" we are

View File

@ -116,15 +116,6 @@ while (1) {
#------------------------------------------------------------------------------------
#------------------------------------------------------------------------------------
########################################################################################
# pandora_shutdown ()
# Close system
########################################################################################
sub pandora_shutdown {
logger (\%pa_config,"Pandora FMS Network Server Shutdown by signal ",0);
print " [*] Shutting down Pandora FMS Network Server (received signal)...\n";
exit;
}
##########################################################################
# SUB pandora_network_subsystem
@ -226,16 +217,16 @@ sub pandora_network_producer ($) {
AND
tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo
AND (
(tagente_estado.last_execution_try + tagente_estado.current_interval) < UNIX_TIMESTAMP()
((tagente_estado.last_execution_try + tagente_estado.current_interval) < UNIX_TIMESTAMP())
OR
tagente_modulo.flag = 1
)
ORDER BY
last_execution_try ASC ";
last_execution_try ASC ";
} else {
# Query for MASTER SERVER !
$query1 = "SELECT
DISTINCT(tagente_modulo.id_agente_modulo), tagente_modulo.flag
DISTINCT(tagente_modulo.id_agente_modulo), tagente_modulo.flag, tagente_estado.last_execution_try
FROM
tagente, tagente_modulo, tagente_estado, tserver
WHERE
@ -251,9 +242,13 @@ sub pandora_network_producer ($) {
tagente_modulo.id_tipo_modulo < 19
AND
tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo
AND
((tagente_estado.last_execution_try + tagente_estado.current_interval) < UNIX_TIMESTAMP() OR tagente_modulo.flag = 1 )
ORDER BY last_execution_try ASC";
AND (
((tagente_estado.last_execution_try + tagente_estado.current_interval) < UNIX_TIMESTAMP() )
OR
tagente_modulo.flag = 1
)
ORDER BY
last_execution_try ASC";
}
$exec_sql1 = $dbh->prepare($query1);
$exec_sql1 ->execute;
@ -457,9 +452,9 @@ sub pandora_query_snmp (%$$$$) {
my $snmp_target = $_[3];
# $_[4] contains error var.
my $output ="";
my $snmp_timeout = 1000 * 1000 * $pa_config->{"snmp_timeout"};
my $snmp_retries = $pa_config->{'snmp_checks'};
my $output ="";
my $snmp_timeout = 1000 * 1000 * $pa_config->{"snmp_timeout"};
my $snmp_retries = $pa_config->{'snmp_checks'};
my $SESSION;
# Locking for SNMP call. SNMP is not thread safe !!
{
@ -467,13 +462,16 @@ sub pandora_query_snmp (%$$$$) {
$SESSION = new SNMP::Session (DestHost => $snmp_target,
Timeout => $snmp_timeout,
Retries => $snmp_retries,
Community => $snmp_community,
Version => 1);
Community => $snmp_community,
Version => 1);
}
if ($SESSION->{ErrorStr}) {
logger($pa_config, "SNMP ERROR SESSION for Target $snmp_target ".$SESSION->{ErrorStr}, 2);
if ((!defined($SESSION)) || ($SESSION->{ErrorStr})) {
logger($pa_config, "SNMP ERROR SESSION for Target $snmp_target ".$SESSION->{ErrorStr}, 2);
$_[4] = "1";
undef ($SESSION);
if (defined($SESSION)){
undef ($SESSION);
}
return 0;
}
my $oid = SNMP::translateObj($snmp_oid);
@ -482,10 +480,10 @@ sub pandora_query_snmp (%$$$$) {
lock $snmp_lock;
$output = $SESSION->get($oid);
}
if ((!defined($SESSION)) || (!defined($output)) || ($output eq "") || ($SESSION->{ErrorStr})) {
if ((!defined($output)) || ($output eq "")) {
logger($pa_config, "SNMP ERROR SNMPGET for Target $snmp_target ".$SESSION->{ErrorStr}, 2);
$_[4] = "1";
undef ($SESSION);
undef ($SESSION);
return 0;
}
$_[4] = "0";
@ -628,7 +626,6 @@ sub exec_network_module {
}
}
# Write data section
my $timestamp = &UnixDate("today","%Y-%m-%d %H:%M:%S");
my $utimestamp = &UnixDate("today","%s");
@ -642,7 +639,7 @@ sub exec_network_module {
$part{'max'}[0] = $max;
$part{'min'}[0] = $min;
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')) {
if (($tipo_modulo eq 'remote_snmp') || ($tipo_modulo eq 'remote_icmp') || ($tipo_modulo eq 'remote_tcp')) {
module_generic_data ($pa_config, \%part, $timestamp, $agent_name, $tipo_modulo, $dbh);
}
elsif ($tipo_modulo =~ /\_inc/ ) {
@ -661,19 +658,31 @@ sub exec_network_module {
# Update agent last contact
# Insert Pandora version as agent version
pandora_lastagentcontact ($pa_config, $timestamp, $agent_name, $pa_config->{'servername'}.$pa_config->{"servermode"}, $pa_config->{'version'}, -1, $dbh);
}
if ($module_result != 0) {
} else {
if ($module_interval == 0){
$module_interval = dame_intervalo ($pa_config, $id_agente, $dbh);
}
# Modules who cannot connect or something go bad, update last_execution_try field
logger ($pa_config, "Cannot obtain exec Network Module $nombre from agent $agent_name", 4);
my $query_act = "UPDATE tagente_estado SET current_interval = $module_interval, last_execution_try = $utimestamp WHERE id_agente_modulo = $id_agente_modulo ";
logger ($pa_config, "Cannot obtain exec Network Module $nombre from agent $agent_name", 3);
my $query_act = "UPDATE tagente_estado SET current_interval = ($module_interval*5), last_execution_try = $utimestamp WHERE id_agente_modulo = $id_agente_modulo ";
my $a_idages = $dbh->prepare($query_act);
$a_idages->execute;
$a_idages->finish();
}
}
########################################################################################
# pandora_shutdown ()
# Close system
########################################################################################
sub pandora_shutdown {
logger (\%pa_config,"Pandora FMS Server '".$pa_config{'servername'}.$pa_config{"servermode"}."' Shutdown by signal ",0);
print " [*] Shutting down ".$pa_config{'servername'}.$pa_config{"servermode"} ."(received signal)...\n";
pandora_event (\%pa_config, $pa_config{'servername'}.$pa_config{"servermode"}." going Down", 0,
0, 4, 0, 0, "system", $dbh);
exit;
}

View File

@ -106,12 +106,14 @@ while (1) {
########################################################################################
# pandora_shutdown ()
# Close system on a received signal
# Close system
########################################################################################
sub pandora_shutdown {
logger (\%pa_config,"Pandora FMS Plugin Server Shutdown by signal ",0);
print " [*] Shutting down Pandora FMS Plugin Server (received signal)...\n";
exit;
logger (\%pa_config,"Pandora FMS Server '".$pa_config{'servername'}.$pa_config{"servermode"}."' Shutdown by signal ",0);
print " [*] Shutting down ".$pa_config{'servername'}.$pa_config{"servermode"} ."(received signal)...\n";
pandora_event (\%pa_config, $pa_config{'servername'}.$pa_config{"servermode"}." going Down", 0,
0, 4, 0, 0, "system", $dbh);
exit;
}
##########################################################################

View File

@ -106,15 +106,18 @@ while (1) {
########################################################################################
# pandora_shutdown ()
# Close system on a received signal
# Close system
########################################################################################
sub pandora_shutdown {
logger (\%pa_config,"Pandora FMS Prediction Server Shutdown by signal ",0);
print " [*] Shutting down Pandora FMS Prediction Server (received signal)...\n";
exit;
logger (\%pa_config,"Pandora FMS Server '".$pa_config{'servername'}.$pa_config{"servermode"}."' Shutdown by signal ",0);
print " [*] Shutting down ".$pa_config{'servername'}.$pa_config{"servermode"} ."(received signal)...\n";
pandora_event (\%pa_config, $pa_config{'servername'}.$pa_config{"servermode"}." going Down", 0,
0, 4, 0, 0, "system", $dbh);
exit;
}
sub pandora_prediction_consumer ($$) {
my $pa_config = $_[0];
my $thread_id = $_[1];

View File

@ -43,6 +43,10 @@ $| = 0;
my %pa_config;
$SIG{'TERM'} = 'pandora_shutdown';
$SIG{'INT'} = 'pandora_shutdown';
# Inicio del bucle principal de programa
pandora_init(\%pa_config, "Pandora FMS Recon server");
@ -190,15 +194,16 @@ sub pandora_exec_task {
$list_ip = $list_ip." ".$target_ip;
$list_host = $list_host." ".resolv_ip2name($target_ip_resolved);
# If has a network profile, create agent and modules
my $agent_id;
if ($task_ncprofile > 0){
# Create address, agent and more...
my $target_ip_id = pandora_task_create_address ($pa_config, $dbh, $id_task, $target_ip);
my $agent_id = pandora_task_create_agent($pa_config, $dbh, $target_ip, $target_ip_id, $task_group, $network_server_assigned, $target_ip_resolved);
$agent_id = pandora_task_create_agent($pa_config, $dbh, $target_ip, $target_ip_id, $task_group, $network_server_assigned, $target_ip_resolved);
pandora_task_create_agentmodules($pa_config, $dbh, $agent_id, $task_ncprofile, $target_ip);
}
my $title = "[RECON] New host [$target_ip_resolved] detected on network [$target_network]";
# Always create event about this detected IP
pandora_event ($pa_config, $title, $task_group, 0, $dbh);
pandora_event ($pa_config, $title,$task_group, $agent_id, 2, 0, 0, 'recon_host_detected', $dbh);
}
}
my $progress = ceil($position / ($total_hosts / 100));
@ -360,7 +365,7 @@ sub pandora_task_create_agent {
my $name = $_[6];
logger($pa_config,"Recon Server: Creating agent for ip $target_ip ",2);
my $query_sql2 = "INSERT INTO tagente (nombre, direccion, comentarios, id_grupo, id_os, agent_type, id_server, intervalo) VALUES ('$name', '$target_ip', 'Autogenerated by Pandora FMS Recon Server', $id_group, 11, 1, $id_server, 300)";
my $query_sql2 = "INSERT INTO tagente (nombre, direccion, comentarios, id_grupo, id_os, id_network_server, intervalo) VALUES ('$name', '$target_ip', 'Autogenerated by Pandora FMS Recon Server', $id_group, 11, $id_server, 300)";
$dbh->do ($query_sql2);
my $lastid = $dbh->{'mysql_insertid'};
my $query_sql3 = "INSERT INTO taddress_agent (id_a, id_agent) values ($target_ip_id, $lastid)";
@ -435,3 +440,14 @@ sub pandora_task_create_agentmodules {
$exec_sql->finish();
}
########################################################################################
# pandora_shutdown ()
# Close system
########################################################################################
sub pandora_shutdown {
logger (\%pa_config,"Pandora FMS Server '".$pa_config{'servername'}.$pa_config{"servermode"}."' Shutdown by signal ",0);
print " [*] Shutting down ".$pa_config{'servername'}.$pa_config{"servermode"} ."(received signal)...\n";
pandora_event (\%pa_config, $pa_config{'servername'}.$pa_config{"servermode"}." going Down", 0,
0, 4, 0, 0, "system", $dbh);
exit;
}

View File

@ -100,12 +100,14 @@ while (1) {
########################################################################################
# pandora_shutdown ()
# Close system on a received signal
# Close system
########################################################################################
sub pandora_shutdown {
logger (\%pa_config,"Pandora FMS Data Server Shutdown by signal ",0);
print " [*] Shutting down Pandora FMS Data Server (received signal)...\n";
exit;
logger (\%pa_config,"Pandora FMS Server '".$pa_config{'servername'}.$pa_config{"servermode"}."' Shutdown by signal ",0);
print " [*] Shutting down ".$pa_config{'servername'}.$pa_config{"servermode"} ."(received signal)...\n";
pandora_event (\%pa_config, $pa_config{'servername'}.$pa_config{"servermode"}." going Down", 0,
0, 4, 0, 0, "system", $dbh);
exit;
}
###############################################################################

View File

@ -38,6 +38,9 @@ $| = 0;
my %pa_config;
$SIG{'TERM'} = 'pandora_shutdown';
$SIG{'INT'} = 'pandora_shutdown';
# Inicio del bucle principal de programa
pandora_init(\%pa_config,"Pandora SNMP Console");
# Read config file for Global variables
@ -255,10 +258,21 @@ sub calcula_alerta_snmp {
# The new alert is between last valid time + threshold and between max/min limit to alerts in this gap of time.
$times_fired++;
$internal_counter++;
# ---------> EXECUTE ALERT <---------------
logger($pa_config,"Executing SNMP Trap alert for $agent - $alert_data",2);
execute_alert ($pa_config, $id_alert, $field1, $field2, $field3,
$trap_agente, $timestamp, $alert_data, "", "", "", 1, $dbh);
# Create a hash for passing to execute_alert
my %data_alert;
$data_alert{'id_aam'} = 0;
$data_alert{'id_agente_modulo'} = 0;
$data_alert{'id_alerta'} = $id_alert;
$data_alert{'al_campo1'} = $field1;
$data_alert{'al_campo2'} = $field2;
$data_alert{'al_campo3'} = $field3;
$data_alert{'descripcion'} = $description;
# Execute alert
execute_alert ($pa_config, \%data_alert, $agent, $id_group, $agent, $trap_agente, 1, $dbh);
# Now update the new value for times_fired, alert_fired, internal_counter and last_fired for this alert.
my $query_idag2 = "update talert_snmp set times_fired = $times_fired, last_fired = '$ahora_mysql', internal_counter = $internal_counter where id_as = $id_as ";
$dbh->do($query_idag2);
@ -288,3 +302,15 @@ $trap_agente, $timestamp, $alert_data, "", "", "", 1, $dbh);
} # if
$s_idag->finish();
}
########################################################################################
# pandora_shutdown ()
# Close system
########################################################################################
sub pandora_shutdown {
logger (\%pa_config,"Pandora FMS Server '".$pa_config{'servername'}.$pa_config{"servermode"}."' Shutdown by signal ",0);
print " [*] Shutting down ".$pa_config{'servername'}.$pa_config{"servermode"} ."(received signal)...\n";
pandora_event (\%pa_config, $pa_config{'servername'}.$pa_config{"servermode"}." going Down", 0,
0, 4, 0, 0, "system", $dbh);
exit;
}

View File

@ -79,10 +79,66 @@ my $wmiwebloc = Win32::OLE->new('WbemScripting.SWbemLocator') ||
my $wmi = $wmiwebloc->ConnectServer($computer,$wmipath,$user,$pwd);
# New samples
# Process executing (return PID)
# SELECT ProcessId FROM Win32_Process WHERE Caption = "spoolsv.exe"
# Service State of a service (Running or Stopped)
# SELECT State FROM Win32_Service WHERE Name = "Eventlog"
# CPU de CPU0
# SELECT LoadPercentage from Win32_Processor WHERE DeviceID = "CPU0"
# Available memory (bytes)
# SELECT AvailableBytes from Win32_PerfRawData_PerfOS_Memory
# Available cache memory (bytes)
# SELECT CacheBytes from Win32_PerfRawData_PerfOS_Memory
# AvgDiskBytesPerTransfer
# DiskReadsPersec
# DiskTransfersPersec
# FreeMegabytes
# SELECT * from Win32_PerfRawData_PerfDisk_LogicalDisk WHERE Name = "F:"
# FragmentedDatagramsPersec
# FragmentationFailures
# DatagramsReceivedPersec
# DatagramsSentPersec
# SELECT * from Win32_PerfFormattedData_Tcpip_IP
my $colItems = $wmi->ExecQuery ("SELECT State FROM Win32_Service WHERE Name = 'Eventlog'");
foreach my $objItem (in $colItems){
print $objItem->{State};
print "\n";
}
# get all the service objects
my @services = in $wmi->InstancesOf("Win32_Service");
# Take 10 first services
for (my $a=0;$a<10;$a++){
print "Service ", $services[$a]->Name, " is ", $services[$a]->Status, "\n";
}
}
#------------------------------------------------------------------------------------
#------------------------------------------------------------------------------------
#------------------------------------------------------------------------------------
#--------------------- Main Perl Code below this line-----------------------
#------------------------------------------------------------------------------------
#------------------------------------------------------------------------------------
#------------------------------------------------------------------------------------
########################################################################################
# pandora_shutdown ()
# Close system
########################################################################################
sub pandora_shutdown {
logger (\%pa_config,"Pandora FMS Server '".$pa_config{'servername'}.$pa_config{"servermode"}."' Shutdown by signal ",0);
print " [*] Shutting down ".$pa_config{'servername'}.$pa_config{"servermode"} ."(received signal)...\n";
pandora_event (\%pa_config, $pa_config{'servername'}.$pa_config{"servermode"}." going Down", 0,
0, 4, 0, 0, "system", $dbh);
exit;
}

View File

@ -151,3 +151,16 @@ wmi_timeout 10
# wmi_threads: Specify number of WMI server threads for processing WMI remote calls
wmi_threads 3
# mta_address: External Mailer (MTA) IP Address to be used by Pandora FMS internal email capabilities
# mta_address 192.168.50.1
mta_address localhost
# mta_port: MTA port (default 25)
# mta_port 25
# mta_user: MTA User (if needed for auth)
# mta_pass: MTA Pass (if needed for auth)
# mta_auth: MTA Auth system (if needed, support: LOGIN PLAIN CRAM-MD5 DIGEST-MD)

View File

@ -182,6 +182,14 @@ sub pandora_loadconfig {
$pa_config->{"compound_max_depth"} = 5; # Maximum nested compound alert depth. Not in config file.
$pa_config->{"dataserver_threads"} = 3; # Introduced on 2.0
# Internal MTA for alerts, each server need its own config.
$pa_config->{"mta_address"} = '127.0.0.1'; # Introduced on 2.0
$pa_config->{"mta_port"} = '25'; # Introduced on 2.0
$pa_config->{"mta_user"} = ''; # Introduced on 2.0
$pa_config->{"mta_pass"} = ''; # Introduced on 2.0
$pa_config->{"mta_auth"} = 'none'; # Introduced on 2.0 (Support LOGIN PLAIN CRAM-MD5 DIGEST-MD)
$pa_config->{"mta_from"} = 'pandora@localhost'; # Introduced on 2.0
# Check for UID0
if ($pa_config->{"quiet"} != 0){
if ($> == 0){
@ -249,6 +257,27 @@ sub pandora_loadconfig {
$pa_config->{"errorlogfile"} = $tbuf;
}
}
# MTA setup (2.0)
elsif ($parametro =~ m/^mta_user\s(.*)/i) {
$pa_config->{'mta_user'}= clean_blank($1);
}
elsif ($parametro =~ m/^mta_pass\s(.*)/i) {
$pa_config->{'mta_pass'}= clean_blank($1);
}
elsif ($parametro =~ m/^mta_address\s(.*)/i) {
$pa_config->{'mta_address'}= clean_blank($1);
}
elsif ($parametro =~ m/^mta_port\s(.*)/i) {
$pa_config->{'mta_port'}= clean_blank($1);
}
elsif ($parametro =~ m/^mta_auth\s(.*)/i) {
$pa_config->{'mta_auth'}= clean_blank($1);
}
elsif ($parametro =~ m/^mta_from\s(.*)/i) {
$pa_config->{'mta_from'}= clean_blank($1);
}
elsif ($parametro =~ m/^snmp_logfile\s(.*)/i) {
$pa_config->{'snmp_logfile'}= clean_blank($1);
}
@ -474,6 +503,8 @@ sub pandora_loadconfig {
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);
pandora_event ($pa_config, $pa_config->{'servername'}.$pa_config->{"servermode"}." going UP", 0,
0, 3, 0, 0, "system", $dbh);
}

View File

@ -257,7 +257,8 @@ sub pandora_process_alert (%$$$$$%$$) {
# Generate an event
pandora_event ($pa_config, "Alert ceased (" .
$alert_data->{'descripcion'} . ")", $id_group,
$id_agent, $dbh);
$id_agent, $alert_data->{'priority'}, $alert_data->{'id_aam'}, $alert_data->{'id_agente_modulo'},
"alert_recovered", $dbh);
return;
}
@ -269,12 +270,8 @@ sub pandora_process_alert (%$$$$$%$$) {
internal_counter = 0 WHERE id_aam = " .
$alert_data->{'id_aam'});
execute_alert ($pa_config, $timestamp, $alert_data->{'id_alerta'},
$id_agent, $id_group, $alert_data->{'al_campo1'},
$alert_data->{'al_f2_recovery'},
$alert_data->{'al_f3_recovery'}, $agent_name,
$module_data, '', '', $alert_data->{'descripcion'}, 1,
$dbh);
execute_alert ($pa_config, $alert_data, $id_agent, $id_group, $agent_name,
$module_data, 0, $dbh);
return;
}
@ -308,11 +305,8 @@ sub pandora_process_alert (%$$$$$%$$) {
$alert_data->{'internal_counter'} . " WHERE id_aam = " .
$alert_data->{'id_aam'});
execute_alert ($pa_config, $timestamp, $alert_data->{'id_alerta'},
$id_agent, $id_group, $alert_data->{'al_campo1'},
$alert_data->{'al_campo2'}, $alert_data->{'al_campo3'},
$agent_name, $module_data, '', '',
$alert_data->{'descripcion'}, 1, $dbh);
execute_alert ($pa_config, $alert_data, $id_agent, $id_group, $agent_name,
$module_data, 1, $dbh);
return;
}
}
@ -459,55 +453,67 @@ sub pandora_generate_compound_alerts (%$$$$$$$) {
}
##########################################################################
## SUB execute_alert (pa_config, timestamp, id_alert, id_agent, id_group,
## field1, field2, field3, agent, data, command, alert_name, alert_description,
## create_event, dbh)
## SUB execute_alert
## Do a execution of given alert with this parameters
##########################################################################
sub execute_alert (%$$$$$$$$$$$$$$$) {
my $pa_config = $_[0];
my $timestamp = $_[1];
my $id_alert = $_[2];
my $id_agent = $_[3];
my $id_group = $_[4];
my $field1 = $_[5];
my $field2 = $_[6];
my $field3 = $_[7];
my $agent = $_[8];
my $data = $_[9];
my $command = $_[10];
my $alert_name = $_[11];
my $alert_description = $_[12];
my $create_event = $_[13];
my $dbh = $_[14];
my $data_alert = $_[1];
my $id_agent = $_[2];
my $id_group = $_[3];
my $agent = $_[4];
my $data = $_[5];
my $alert_mode = $_[6]; # 0 is recovery, 1 is normal
my $dbh = $_[7];
# Some variable init
my $create_event = 1;
my $command = "";
my $alert_name = "";
my $field1;
my $field2;
my $field3;
my $id_alert = $data_alert->{'id_alerta'};
my $id_agent_module = $data_alert->{'id_agente_modulo'};
my $timestamp = &UnixDate ("today", "%Y-%m-%d %H:%M:%S"); # string timestamp
my $alert_description = $data_alert->{'descripcion'};
# Compound only
if ($id_alert == 1){
return;
}
if ($alert_mode == 1){
$field1 = $data_alert->{'al_campo1'};
$field2 = $data_alert->{'al_campo2'};
$field3 = $data_alert->{'al_campo3'};
} else {
$field1 = $data_alert->{'al_campo1'};
$field2 = $data_alert->{'al_f2_recovery'};
$field3 = $data_alert->{'al_f3_recovery'};
}
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);
$idag ->execute;
my @datarow;
if ($idag->rows != 0) {
while (@datarow = $idag->fetchrow_array()) {
$command = $datarow[2];
$alert_name = $datarow[1];
}
# Get values for commandline, reading from talerta.
my $query_idag = "SELECT * FROM talerta WHERE id_alerta = '$id_alert'";
my $idag = $dbh->prepare($query_idag);
$idag ->execute;
my @datarow;
if ($idag->rows != 0) {
while (@datarow = $idag->fetchrow_array()) {
$command = $datarow[2];
$alert_name = $datarow[1];
}
$idag->finish();
}
$idag->finish();
logger($pa_config, "Alert ($alert_name) TRIGGERED for $agent",2);
if ($id_alert != 3){ # id_alerta 3 is reserved for internal audit system
if ($id_alert > 4) { # Skip internal alerts
$command =~ s/_field1_/"$field1"/ig;
$command =~ s/_field2_/"$field2"/ig;
$command =~ s/_field3_/"$field3"/ig;
$command=~ s/_agent_/$agent/ig;
$command =~ s/_agent_/$agent/ig;
$command =~ s/_timestamp_/$timestamp/ig;
$command =~ s/_data_/$data/ig;
# Clean up some "tricky" characters
@ -522,19 +528,34 @@ sub execute_alert (%$$$$$$$$$$$$$$$) {
}
};
if ($@){
logger($pa_config, "WARNING: Alert command don't retun from execution. ( $command )", 0 );
logger($pa_config, "ERROR Code: $@",1);
logger($pa_config, "WARNING: Alert command don't return from execution. ( $command )", 0 );
logger($pa_config, "ERROR Code: $@",2);
}
} else { # id_alerta = 3, is a internal system audit
} elsif ($id_alert == 3) { # id_alerta = 3, is a internal system audit
logger($pa_config, "Internal audit lauch for agent name $agent",3);
$field1 =~ s/_agent_/$agent/ig;
$field1 =~ s/_timestamp_/$timestamp/ig;
$field1 =~ s/_data_/$data/ig;
pandora_audit ($pa_config, $field1, $agent, "Alert ($alert_description)", $dbh);
}
$create_event = 0;
} elsif ($id_alert == 2) { # email
$field3 =~ s/_agent_/$agent/ig;
$field3 =~ s/_timestamp_/$timestamp/ig;
$field3 =~ s/_data_/$data/ig;
pandora_sendmail ( $pa_config, $field1, $field2, $field3);
} elsif ($id_alert == 4) { # internal event
$create_event = 1;
}
if ($create_event == 1){
my $evt_descripcion = "Alert fired ($alert_description)";
pandora_event ($pa_config, $evt_descripcion, $id_group, $id_agent, $dbh);
if ($alert_mode == 0){ # recovery
pandora_event ($pa_config, $evt_descripcion, $id_group, $id_agent, $data_alert->{'priority'}, $data_alert->{'id_aam'},
$data_alert->{'id_agente_modulo'}, 'alert_recovered', $dbh);
} else {
pandora_event ($pa_config, $evt_descripcion, $id_group, $id_agent, $data_alert->{'priority'}, $data_alert->{'id_aam'},
$data_alert->{'id_agente_modulo'}, 'alert_fired', $dbh);
}
}
}
@ -552,7 +573,7 @@ sub pandora_writestate (%$$$$$$$) {
my $nombre_agente = $_[1];
my $tipo_modulo = $_[2]; # passed as string
my $nombre_modulo = $_[3];
my $datos = $_[4]; # Careful: Dont pass a hash, only a single value
my $datos = $_[4]; # Careful: This don't reference a hash, only a single value
my $estado = $_[5];
my $dbh = $_[6];
my $needs_update = $_[7];
@ -562,7 +583,7 @@ sub pandora_writestate (%$$$$$$$) {
# Get current timestamp / unix numeric time
my $timestamp = &UnixDate ("today", "%Y-%m-%d %H:%M:%S"); # string timestamp
my $utimestamp = &UnixDate($timestamp,"%s"); # convert from human to integer
my $utimestamp = &UnixDate($timestamp, "%s"); # convert from human to integer
# Get server id
my $server_name = $pa_config->{'servername'}.$pa_config->{"servermode"};
@ -574,15 +595,15 @@ sub pandora_writestate (%$$$$$$$) {
my $id_agente = dame_agente_id ($pa_config, $nombre_agente, $dbh);
my $id_modulo = dame_modulo_id ($pa_config, $tipo_modulo, $dbh);
my $id_agente_modulo = dame_agente_modulo_id($pa_config, $id_agente, $id_modulo, $nombre_modulo, $dbh);
if (($id_agente == -1) || ($id_agente_modulo == -1)) {
return 0;
}
my $id_grupo = dame_grupo_agente($pa_config, $id_agente,$dbh);
my $id_grupo = dame_grupo_agente($pa_config, $id_agente,$dbh);
# Seek for agent_interval or module_interval
my $query_idag = "SELECT * FROM tagente_modulo WHERE id_agente = $id_agente AND id_agente_modulo = " . $id_agente_modulo;;
my $query_idag = "SELECT * FROM tagente_modulo WHERE id_agente = $id_agente AND id_agente_modulo = " . $id_agente_modulo;
my $s_idag = $dbh->prepare($query_idag);
$s_idag ->execute;
if ($s_idag->rows == 0) {
@ -591,6 +612,7 @@ sub pandora_writestate (%$$$$$$$) {
} else {
@data = $s_idag->fetchrow_array();
}
my $id_module_type = $data[2];
my $module_interval = $data[7];
if ($module_interval == 0){
@ -612,28 +634,42 @@ sub pandora_writestate (%$$$$$$$) {
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, running_by, last_execution_try) VALUES ($id_agente_modulo,$datos,'$timestamp','$estado','1',$id_agente,'$timestamp',$utimestamp, $module_interval, $id_server, $utimestamp)"; # Cuando se hace un insert, siempre hay un cambio de estado
} else { # There are an entry in table already
@data = $s_idages->fetchrow_array();
if ( $data[11] == 0){
$needs_update = 1;
}
# Se supone que $data[5](estado) ( nos daria el estado ANTERIOR
# For xxxx_PROC type (boolean / monitor), create an event if state has changed
# For xxxx_PROC type (boolean / monitor), create an event if state has changed
if (( $data[5] != $estado) && ( ($tipo_modulo =~/keep_alive/) || ($tipo_modulo =~ /proc/)) ) {
# Cambio de estado detectado !
$cambio = 1;
$needs_update = 1;
# Este seria el momento oportuno de probar a saltar la alerta si estuviera definida
# Makes an event entry, only if previous state changes, if new state, doesnt give any alert
my $descripcion;
if ( $estado == 0) {
$descripcion = "Monitor ($nombre_modulo) goes up ";
}
if ( $estado == 1) {
$descripcion = "Monitor ($nombre_modulo) goes down";
}
pandora_event ($pa_config, $descripcion, $id_grupo, $id_agente, $dbh);
# Makes an event entry, only if previous state changes, if new state, doesnt give any alert
my $descripcion;
my $event_type;
if ( $estado == 0) {
$descripcion = "Monitor ($nombre_modulo) goes up ";
$event_type = "monitor_up";
}
if ( $estado == 1) {
$descripcion = "Monitor ($nombre_modulo) goes down";
$event_type = "monitor_down";
}
pandora_event ($pa_config, $descripcion, $id_grupo,
$id_agente, 2, 0, $id_agente_modulo,
$event_type, $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', running_by = $id_server, last_execution_try = $utimestamp WHERE id_agente_modulo = $id_agente_modulo";
} else { # dont update last_try field, that it's the field
@ -759,7 +795,8 @@ sub module_generic_proc (%$$$$$) {
if (ref($a_min) eq "HASH") {
$a_min = "";
}
pandora_writedata($pa_config, $a_timestamp,$agent_name,$module_type,$a_name,$a_datos,$a_max,$a_min,$a_desc,$dbh, \$bUpdateDatos);
pandora_writedata ($pa_config, $a_timestamp, $agent_name, $module_type, $a_name,
$a_datos, $a_max, $a_min, $a_desc, $dbh, \$bUpdateDatos);
# Check for status: <1 state 1 (Bad), >= 1 state 0 (Good)
# Calculamos su estado
@ -1126,7 +1163,7 @@ sub pandora_writedata (%$$$$$$$$$$){
$datos = $dbh->quote($datos);
$timestamp = $dbh->quote($timestamp);
# Parse data entry for adecuate SQL representation.
$query = "INSERT INTO tagente_datos (id_agente_modulo, datos, timestamp, utimestamp, id_agente) VALUES ($id_agente_modulo, $datos, $timestamp, $utimestamp, $id_agente)";
$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
if ($outlimit == 0){
logger($pa_config, "DEBUG: pandora_insertdata Calculado id_agente_modulo a $id_agente_modulo",6);
@ -1170,7 +1207,11 @@ sub pandora_serverkeepaliver (%$$) {
$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);
pandora_event ($pa_config, "Server ".$data[1]." going Down", 0,
0, 4, 0, 0, "system", $dbh);
logger( $pa_config, "Server ".$data[1]." going Down ",1);
}
}
@ -1235,7 +1276,6 @@ sub pandora_updateserver (%$$$) {
if ($s_idag->rows != 0) {
if (@data = $s_idag->fetchrow_array()){
if ($data[3] == 0){ # If down, update to get up the server
pandora_event($pa_config, "Server ".$data[1]." going UP", 0, 0, $dbh);
logger( $pa_config, "Server ".$data[1]." going UP ",1);
}
# Update server data
@ -1293,25 +1333,31 @@ sub pandora_lastagentcontact (%$$$$$$) {
}
##########################################################################
## SUB pandora_event (pa_config, evento, id_grupo, id_agente, dbh)
## SUB pandora_event
## Write in internal audit system an entry.
## Params: config_hash, event_title, group, agent_id, severity, id_alertam
## id_agentmodule, event_type (from a set, as string), db_handle
##########################################################################
sub pandora_event (%$$$$) {
my $pa_config = $_[0];
my $evento = $_[1];
my $id_grupo = $_[2];
my $id_agente = $_[3];
my $dbh = $_[4];
my $timestamp = &UnixDate("today","%Y-%m-%d %H:%M:%S");
sub pandora_event (%$$$$$$$$) {
my $pa_config = $_[0];
my $evento = $_[1];
my $id_grupo = $_[2];
my $id_agente = $_[3];
my $severity = $_[4]; # new in 2.0
my $id_alert_am = $_[5]; # new in 2.0
my $id_agentmodule = $_[6]; # new in 2.0
my $event_type = $_[7]; # new in 2.0
my $dbh = $_[8];
my $timestamp = &UnixDate("today","%Y-%m-%d %H:%M:%S");
my $utimestamp; # integer version of timestamp
$utimestamp = &UnixDate($timestamp,"%s"); # convert from human to integer
$evento = $dbh->quote($evento);
$timestamp = $dbh->quote($timestamp);
my $query = "INSERT INTO tevento (id_agente, id_grupo, evento, timestamp, estado, utimestamp) VALUES ($id_agente, $id_grupo, $evento, $timestamp, 0, $utimestamp)";
logger ($pa_config,"EVENT Insertion: $query", 5);
$dbh->do($query);
$evento = $dbh->quote($evento);
$event_type = $dbh->quote($event_type);
$timestamp = $dbh->quote($timestamp);
my $query = "INSERT INTO tevento (id_agente, id_grupo, evento, timestamp, estado, utimestamp, event_type, id_agentmodule, id_alert_am, criticity) VALUES ($id_agente, $id_grupo, $evento, $timestamp, 0, $utimestamp, $event_type, $id_agentmodule, $id_alert_am, $severity)";
$dbh->do($query);
}
##########################################################################

View File

@ -21,6 +21,7 @@ use warnings;
use Time::Local;
use Date::Manip; # Needed to manipulate DateTime formats of input, output and compare
use POSIX qw(setsid);
use Mail::Sendmail; # New in 2.0. Used to sendmail internally, without external scripts
require Exporter;
@ -36,6 +37,7 @@ our @EXPORT = qw(
sqlWrap
is_numeric
clean_blank
pandora_sendmail
);
@ -68,6 +70,41 @@ sub pandora_daemonize {
# Pandora other General functions |
# -------------------------------------------+
##########################################################################
# SUB pandora_sendmail
# Send a mail, connecting directly to MTA
# param1 - config hash
# param2 - Destination email addres
# param3 - Email subject
# param4 - Email Message body
##########################################################################
sub pandora_sendmail { # added in 2.0 version
my $pa_config = $_[0];
my $to_address = $_[1];
my $subject = $_[2];
my $message = $_[3];
my %mail = ( To => $to_address,
Message => $message,
Subject => $subject,
Smtp => $pa_config->{"mta_address"},
Port => $pa_config->{"mta_port"},
From => $pa_config->{"mta_from"},
);
if ($pa_config->{"mta_user"} ne ""){
$mail{auth} = {user=>$config->{"mta_user"}, password=>$config->{"mta_pass"}, method=>$config->{"mta_auth"}, required=>0 }
}
eval {
sendmail(%mail);
};
if ($@){
logger ($pa_config, "[ERROR] Sending email to $to_address with subject $subject", 1);
logger ($pa_config, "ERROR Code: $@", 4);
}
}
##########################################################################
# SUB is_numeric
# Return TRUE if given argument is numeric

View File

@ -60,6 +60,7 @@ else
ln -s /usr/local/bin/pandora_export /usr/bin/pandora_export
mkdir /usr/share/pandora
cp -R util /usr/share/pandora
cp -R plugin /usr/share/pandora
echo "perl /usr/share/pandora/util/pandora_db /etc/pandora/pandora_server.conf" > /etc/cron.daily/pandora_purge_db
chmod +x /etc/cron.daily/pandora_purge_db
rm output

View File

@ -84,9 +84,15 @@ sub pandora_purgedb {
my $timestamp = &UnixDate("today","%Y-%m-%d %H:%M:%S");
my $limit_access = DateCalc("today","-24 hours",\$err);
$limit_access = &UnixDate($limit_access,"%Y-%m-%d %H:%M:%S");
print "[PURGE] Deleting old access data... \n";
print "[PURGE] Deleting old access data (More than 24hr) \n";
$dbh->do("DELETE FROM tagent_access WHERE timestamp < '$limit_access'");
my $limit_event = DateCalc("today","-$config_days_purge days",\$err);
$limit_event = &UnixDate($limit_event,"%Y-%m-%d %H:%M:%S");
print "[PURGE] Deleting old event data (More than $config_days_purge days)... \n";
$dbh->do("DELETE FROM tevent WHERE timestamp < '$limit_event'");
print "[PURGE] Deleting old data... \n";
# Lets insert the last value on $limit_timestamp + 1 minute for each id_agente_modulo
my $query_idag = "select count(distinct(id_agente_modulo)) from tagente_datos where timestamp < '$limit_timestamp'";