From 2a4fad4c62306c05523618f21f833283fa78ef1c Mon Sep 17 00:00:00 2001 From: ramonn Date: Mon, 18 Apr 2011 16:42:18 +0000 Subject: [PATCH] 2011-04-18 Ramon Novoa * lib/PandoraFMS/SNMPServer.pm, lib/PandoraFMS/NetworkServer.pm, lib/PandoraFMS/DB.pm, lib/PandoraFMS/Core.pm: Adding support for Oracle. The main loop works now. git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@4244 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f --- pandora_server/ChangeLog | 8 +++ pandora_server/lib/PandoraFMS/Core.pm | 38 +++++++----- pandora_server/lib/PandoraFMS/DB.pm | 60 +++++++++++++++---- .../lib/PandoraFMS/NetworkServer.pm | 4 +- pandora_server/lib/PandoraFMS/SNMPServer.pm | 2 +- 5 files changed, 83 insertions(+), 29 deletions(-) diff --git a/pandora_server/ChangeLog b/pandora_server/ChangeLog index a4ea2de907..f514753cfa 100644 --- a/pandora_server/ChangeLog +++ b/pandora_server/ChangeLog @@ -1,3 +1,11 @@ +2011-04-18 Ramon Novoa + + * lib/PandoraFMS/SNMPServer.pm, + lib/PandoraFMS/NetworkServer.pm, + lib/PandoraFMS/DB.pm, + lib/PandoraFMS/Core.pm: Adding support for Oracle. The main loop + works now. + 2011-04-14 Dario Rodriguez * util/tentacle_serverd: Changed get_pid function now also checks diff --git a/pandora_server/lib/PandoraFMS/Core.pm b/pandora_server/lib/PandoraFMS/Core.pm index 4290a725b2..ce2c67af9e 100644 --- a/pandora_server/lib/PandoraFMS/Core.pm +++ b/pandora_server/lib/PandoraFMS/Core.pm @@ -915,9 +915,7 @@ sub pandora_update_server ($$$$$;$$) { my $server_id = db_insert ($dbh, 'id_server', 'INSERT INTO tserver (name, server_type, description, version, threads, queued_modules) VALUES (?, ?, ?, ?, ?, ?)', $server_name, $server_type, 'Autocreated at startup', $pa_config->{'version'} . ' (P) ' . $pa_config->{'build'}, $num_threads, $queue_size); - $server = get_db_single_row ($dbh, 'SELECT * FROM tserver - WHERE id_server = ?', - $server_id); + $server = get_db_single_row ($dbh, 'SELECT * FROM tserver WHERE id_server = ?', $server_id); if (! defined ($server)) { logger($pa_config, "Server '" . $pa_config->{'servername'} . "' not found.", 3); return; @@ -1103,7 +1101,7 @@ sub pandora_audit ($$$$$) { my $utimestamp = time(); my $timestamp = strftime ("%Y-%m-%d %H:%M:%S", localtime($utimestamp)); - db_do($dbh, 'INSERT INTO tsesion (' . db_reserved_word ('ID_usuario') .', ' . db_reserved_word ('IP_origen') . ', accion, fecha, descripcion, utimestamp) + db_do($dbh, 'INSERT INTO tsesion (id_usuario, ip_origen, accion, fecha, descripcion, utimestamp) VALUES (?, ?, ?, ?, ?, ?)', 'SYSTEM', $name, $action , $timestamp , $description , $utimestamp); db_disconnect($dbh) if ($disconnect == 1); @@ -1359,7 +1357,7 @@ sub pandora_module_keep_alive_nd { AND tagente.disabled = 0 AND tagente_modulo.id_tipo_modulo = 100 AND tagente_modulo.disabled = 0 - AND (tagente_estado.datos = \'1\' OR tagente_estado.datos = \'\') + AND (' . db_text ('tagente_estado.datos') . ' = \'1\' OR ' . db_text ('tagente_estado.datos') . '= \'\') AND tagente_modulo.id_agente_modulo = tagente_estado.id_agente_modulo AND ( tagente_estado.utimestamp + (tagente.intervalo * 2) < UNIX_TIMESTAMP())'); @@ -1916,7 +1914,7 @@ sub pandora_server_statistics ($$) { my $lag_row; # Get all servers with my name (each server only refresh it's own stats) - my @servers = get_db_rows ($dbh, 'SELECT * FROM tserver WHERE name = "'.$pa_config->{'servername'}.'"'); + my @servers = get_db_rows ($dbh, 'SELECT * FROM tserver WHERE name = ?', $pa_config->{'servername'}); # For each server, update stats: Simple. foreach my $server (@servers) { @@ -2028,11 +2026,14 @@ sub pandora_group_statistics ($$) { $group = $group_row->{'id_grupo'}; $agents_unknown = get_db_value ($dbh, "SELECT COUNT(*) FROM tagente WHERE id_grupo = $group AND disabled = 0 AND ultimo_contacto < NOW() - (intervalo *2)"); + $agents_unknown = 0 unless defined ($agents_unknown); $agents = get_db_value ($dbh, "SELECT COUNT(*) FROM tagente WHERE id_grupo = $group AND disabled = 0"); + $agents = 0 unless defined ($agents); $modules = get_db_value ($dbh, "SELECT COUNT(tagente_estado.id_agente_estado) FROM tagente_estado, tagente, tagente_modulo WHERE tagente.id_grupo = $group AND tagente.disabled = 0 AND tagente_estado.id_agente = tagente.id_agente AND tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo AND tagente_modulo.disabled = 0"); - + $modules = 0 unless defined ($modules); + # Following threelines gets critical/warning modules, skipping the unknown. By default # we consider status (ok, warning, critical) as a separate status from unknown. @@ -2043,24 +2044,31 @@ sub pandora_group_statistics ($$) { # $warning = get_db_value ($dbh, "SELECT COUNT(tagente_estado.id_agente_estado) FROM tagente_estado, tagente, tagente_modulo WHERE tagente.id_grupo = $group AND tagente.disabled = 0 AND tagente_estado.id_agente = tagente.id_agente AND tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo AND tagente_modulo.disabled = 0 AND estado = 2 AND ((tagente_modulo.id_tipo_modulo NOT IN (21,22,23,100) AND utimestamp > ( UNIX_TIMESTAMP() - (current_interval * 2))) OR (tagente_modulo.id_tipo_modulo IN (21,22,23,100)))"); $normal = get_db_value ($dbh, "SELECT COUNT(tagente_estado.id_agente_estado) FROM tagente_estado, tagente, tagente_modulo WHERE tagente.id_grupo = $group AND tagente.disabled = 0 AND tagente_estado.id_agente = tagente.id_agente AND tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo AND tagente_modulo.disabled = 0 AND estado = 0 AND (utimestamp != 0 OR tagente_modulo.id_tipo_modulo IN (21,22,23)) AND (utimestamp >= ( UNIX_TIMESTAMP() - (current_interval * 2)) OR tagente_modulo.id_tipo_modulo IN (21,22,23,100))"); - + $normal = 0 unless defined ($normal); + $critical = get_db_value ($dbh, "SELECT COUNT(tagente_estado.id_agente_estado) FROM tagente_estado, tagente, tagente_modulo WHERE tagente.id_grupo = $group AND tagente.disabled = 0 AND tagente_estado.id_agente = tagente.id_agente AND tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo AND tagente_modulo.disabled = 0 AND estado = 1 AND (utimestamp >= ( UNIX_TIMESTAMP() - (current_interval * 2)) OR tagente_modulo.id_tipo_modulo IN (21,22,23,100))"); - + $critical = 0 unless defined ($critical); + $warning = get_db_value ($dbh, "SELECT COUNT(tagente_estado.id_agente_estado) FROM tagente_estado, tagente, tagente_modulo WHERE tagente.id_grupo = $group AND tagente.disabled = 0 AND tagente_estado.id_agente = tagente.id_agente AND tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo AND tagente_modulo.disabled = 0 AND estado = 2 AND (utimestamp >= ( UNIX_TIMESTAMP() - (current_interval * 2)) OR tagente_modulo.id_tipo_modulo IN (21,22,23,100))"); - + $warning = 0 unless defined ($warning); + $unknown = get_db_value ($dbh, "SELECT COUNT(tagente_estado.id_agente_estado) FROM tagente_estado, tagente, tagente_modulo WHERE tagente.id_grupo = $group AND tagente.disabled = 0 AND tagente.id_agente = tagente_estado.id_agente AND tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo AND tagente_modulo.disabled = 0 AND tagente_modulo.id_tipo_modulo NOT IN (21,22,23,100) AND utimestamp < ( UNIX_TIMESTAMP() - (current_interval * 2)) AND utimestamp != 0"); - + $unknown = 0 unless defined ($unknown); + $non_init = get_db_value ($dbh, "SELECT COUNT(tagente_estado.id_agente_estado) FROM tagente_estado, tagente, tagente_modulo WHERE tagente.id_grupo = $group AND tagente.disabled = 0 AND tagente.id_agente = tagente_estado.id_agente AND tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo AND tagente_modulo.disabled = 0 AND tagente_modulo.id_tipo_modulo NOT IN (21,22,23) AND utimestamp = 0"); - + $non_init = 0 unless defined ($non_init); + $alerts = get_db_value ($dbh, "SELECT COUNT(talert_template_modules.id) FROM talert_template_modules, tagente_modulo, tagente_estado, tagente WHERE tagente.id_grupo = $group AND tagente_modulo.id_agente = tagente.id_agente AND tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo AND tagente_modulo.disabled = 0 AND tagente.disabled = 0 AND talert_template_modules.id_agent_module = tagente_modulo.id_agente_modulo"); - + $alerts = 0 unless defined ($alerts); + $alerts_fired = get_db_value ($dbh, "SELECT COUNT(talert_template_modules.id) FROM talert_template_modules, tagente_modulo, tagente_estado, tagente WHERE tagente.id_grupo = $group AND tagente_modulo.id_agente = tagente.id_agente AND tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo AND tagente_modulo.disabled = 0 AND tagente.disabled = 0 AND talert_template_modules.id_agent_module = tagente_modulo.id_agente_modulo AND times_fired > 0"); - + $alerts_fired = 0 unless defined ($alerts_fired); + # Update the record. db_do ($dbh, "DELETE FROM tgroup_stat WHERE id_group = $group"); - db_do ($dbh, "INSERT INTO tgroup_stat (id_group, modules, normal, critical, warning, unknown, `non-init`, alerts, alerts_fired, agents, agents_unknown, utimestamp) VALUES ($group, $modules, $normal, $critical, $warning, $unknown, $non_init, $alerts, $alerts_fired, $agents, $agents_unknown, UNIX_TIMESTAMP())"); + db_do ($dbh, "INSERT INTO tgroup_stat (id_group, modules, normal, critical, warning, unknown, " . db_reserved_word ('non-init') . ", alerts, alerts_fired, agents, agents_unknown, utimestamp) VALUES ($group, $modules, $normal, $critical, $warning, $unknown, $non_init, $alerts, $alerts_fired, $agents, $agents_unknown, UNIX_TIMESTAMP())"); } diff --git a/pandora_server/lib/PandoraFMS/DB.pm b/pandora_server/lib/PandoraFMS/DB.pm index bdb4a98774..07b6df1b39 100644 --- a/pandora_server/lib/PandoraFMS/DB.pm +++ b/pandora_server/lib/PandoraFMS/DB.pm @@ -36,6 +36,7 @@ our @EXPORT = qw( db_process_update db_reserved_word db_string + db_text db_update get_action_id get_agent_id @@ -84,9 +85,20 @@ sub db_connect ($$$$$$) { $RDBMS = 'postgresql'; # Connect to PostgreSQL - my $dbh = DBI->connect("DBI:Pg:dbname=$db_name;host=$db_host;port=5432", $db_user, $db_pass); + my $dbh = DBI->connect("DBI:Pg:dbname=$db_name;host=$db_host;port=5432", $db_user, $db_pass, { RaiseError => 1, AutoCommit => 1 }); return undef unless defined ($dbh); + return $dbh; + } elsif ($rdbms eq 'oracle') { + $RDBMS = 'oracle'; + + # Connect to Oracle + my $dbh = DBI->connect("DBI:Oracle:dbname=$db_name;host=$db_host;port=1521;sid=pandora", $db_user, $db_pass, { RaiseError => 1, AutoCommit => 1 }); + return undef unless defined ($dbh); + + # Set date format + $dbh->do("ALTER SESSION SET NLS_TIMESTAMP_FORMAT='YYYY-MM-DD HH24:MI:SS'"); + return $dbh; } @@ -302,21 +314,22 @@ sub get_db_value ($$;@) { ########################################################################## sub get_db_single_row ($$;@) { my ($dbh, $query, @values) = @_; + my @rows; # Cache statements my $sth = $dbh->prepare_cached($query); $sth->execute(@values); - # No results - if ($sth->rows == 0) { + # Save returned rows + while (my $row = $sth->fetchrow_hashref()) { $sth->finish(); - return undef; + return {map { lc ($_) => $row->{$_} } keys (%{$row})} if ($RDBMS eq 'oracle'); + return $row; } - - my $row = $sth->fetchrow_hashref(); + $sth->finish(); - return $row; + return undef; } ########################################################################## @@ -333,7 +346,11 @@ sub get_db_rows ($$;@) { # Save returned rows while (my $row = $sth->fetchrow_hashref()) { - push (@rows, $row); + if ($RDBMS eq 'oracle') { + push (@rows, {map { lc ($_) => $row->{$_} } keys (%{$row})}); + } else { + push (@rows, $row); + } } $sth->finish(); @@ -354,7 +371,16 @@ sub db_insert ($$$;@) { } # PostgreSQL elsif ($RDBMS eq 'postgresql') { - $insert_id = get_db_value ($dbh, $query . ' RETURNING ' . db_reserved_word ($index), undef, @values); + $insert_id = get_db_value ($dbh, $query . ' RETURNING ' . db_reserved_word ($index), @values); + } + # Oracle + elsif ($RDBMS eq 'oracle') { + my $sth = $dbh->prepare($query . ' RETURNING ' . db_reserved_word (uc ($index)) . ' INTO ?'); + for (my $i = 0; $i <= $#values; $i++) { + $sth->bind_param ($i+1, $values[$i]); + } + $sth->bind_param_inout($#values + 2, \$insert_id, 99); + $sth->execute (); } return $insert_id; @@ -458,7 +484,7 @@ sub db_reserved_word ($) { return '`' . $reserved_word . '`' if ($RDBMS eq 'mysql'); # PostgreSQL - return '"' . $reserved_word . '"' if ($RDBMS eq 'postgresql'); + return '"' . $reserved_word . '"' if ($RDBMS eq 'postgresql' || $RDBMS eq 'oracle'); return $reserved_word; } @@ -470,7 +496,19 @@ sub db_string ($) { my $string = shift; # MySQL and PostgreSQL - return "'" . $string . "'" if ($RDBMS eq 'mysql' || $RDBMS eq 'postgresql'); + #return "'" . $string . "'" if ($RDBMS eq 'mysql' || $RDBMS eq 'postgresql' || $RDBMS eq 'oracle'); + + return "'" . $string . "'"; +} + +########################################################################## +## Convert TEXT to string when necessary +########################################################################## +sub db_text ($) { + my $string = shift; + + #return $string; + return " dbms_lob.substr(" . $string . ", 4000, 1)" if ($RDBMS eq 'oracle'); return $string; } diff --git a/pandora_server/lib/PandoraFMS/NetworkServer.pm b/pandora_server/lib/PandoraFMS/NetworkServer.pm index 96ca2c7013..c09efa0d99 100644 --- a/pandora_server/lib/PandoraFMS/NetworkServer.pm +++ b/pandora_server/lib/PandoraFMS/NetworkServer.pm @@ -99,7 +99,7 @@ sub data_producer ($) { AND tagente_modulo.disabled = 0 AND tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo AND (tagente_modulo.flag = 1 OR ((tagente_estado.last_execution_try + tagente_estado.current_interval) < UNIX_TIMESTAMP())) - ORDER BY tagente_modulo.flag DESC, time_left DESC, last_execution_try ASC ', $pa_config->{'servername'}); + ORDER BY tagente_modulo.flag DESC, time_left DESC, tagente_estado.last_execution_try ASC ', $pa_config->{'servername'}); } else { @rows = get_db_rows ($dbh, 'SELECT DISTINCT(tagente_modulo.id_agente_modulo), tagente_modulo.flag, tagente_estado.last_execution_try, UNIX_TIMESTAMP() - tagente_estado.current_interval - tagente_estado.last_execution_try AS time_left, last_execution_try FROM tagente, tagente_modulo, tagente_estado @@ -111,7 +111,7 @@ sub data_producer ($) { AND tagente_modulo.id_tipo_modulo < 19 AND tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo AND (tagente_modulo.flag = 1 OR ((tagente_estado.last_execution_try + tagente_estado.current_interval) < UNIX_TIMESTAMP())) - ORDER BY tagente_modulo.flag DESC, time_left DESC, last_execution_try ASC', $pa_config->{'servername'}); + ORDER BY tagente_modulo.flag DESC, time_left DESC, tagente_estado.last_execution_try ASC', $pa_config->{'servername'}); } foreach my $row (@rows) { diff --git a/pandora_server/lib/PandoraFMS/SNMPServer.pm b/pandora_server/lib/PandoraFMS/SNMPServer.pm index e545defad1..da9bcc7937 100644 --- a/pandora_server/lib/PandoraFMS/SNMPServer.pm +++ b/pandora_server/lib/PandoraFMS/SNMPServer.pm @@ -80,7 +80,7 @@ sub pandora_snmptrapd { eval { # Connect to the DB - my $dbh = db_connect ('mysql', $pa_config->{'dbname'}, $pa_config->{'dbhost'}, + my $dbh = db_connect ($pa_config->{'dbengine'}, $pa_config->{'dbname'}, $pa_config->{'dbhost'}, 3306, $pa_config->{'dbuser'}, $pa_config->{'dbpass'}); $self->setDBH ($dbh);