From 067b7a821f0980c2741b9ef65ca0fb19ed23f012 Mon Sep 17 00:00:00 2001 From: Calvo Date: Tue, 13 Sep 2022 12:31:09 +0200 Subject: [PATCH 01/12] WIP:Move inventory to open --- pandora_server/lib/PandoraFMS/Core.pm | 272 ++++++++++++++++++++ pandora_server/lib/PandoraFMS/DataServer.pm | 3 +- 2 files changed, 273 insertions(+), 2 deletions(-) diff --git a/pandora_server/lib/PandoraFMS/Core.pm b/pandora_server/lib/PandoraFMS/Core.pm index 589d409357..35a8b6869a 100644 --- a/pandora_server/lib/PandoraFMS/Core.pm +++ b/pandora_server/lib/PandoraFMS/Core.pm @@ -4987,6 +4987,278 @@ sub process_inc_abs_data ($$$$$$) { return $diff; } +################################################################################ +################################################################################ +## Inventory XML data +################################################################################ +################################################################################ + + +################################################################################ +# Process inventory data, creating the module if necessary. +################################################################################ +sub process_inventory_data ($$$$$$$) { + my ($pa_config, $data, $server_id, $agent_name, + $interval, $timestamp, $dbh) = @_; + + foreach my $inventory (@{$data->{'inventory'}}) { + + # Process inventory modules + foreach my $module_data (@{$inventory->{'inventory_module'}}) { + + my $module_name = get_tag_value ($module_data, 'name', ''); + + # Unnamed module + next if ($module_name eq ''); + + # Process inventory data + my $data_list = ''; + foreach my $list (@{$module_data->{'datalist'}}) { + + # Empty list + next unless defined ($list->{'data'}); + + foreach my $data (@{$list->{'data'}}) { + $data_list .= $data . "\n"; + } + } + + next if ($data_list eq ''); + process_inventory_module_data ($pa_config, $data_list, $server_id, $agent_name, $module_name, $interval, $timestamp, $dbh); + } + } +} + +################################################################################ +# Process inventory module data, creating the module if necessary. +################################################################################ +sub process_inventory_module_data ($$$$$$$$) { + my ($pa_config, $data, $server_id, $agent_name, + $module_name, $interval, $timestamp, $dbh) = @_; + + logger ($pa_config, "Processing inventory module '$module_name' for agent '$agent_name'.", 10); + + # Get agent data + my $agent = get_db_single_row ($dbh, + 'SELECT * FROM tagente WHERE nombre = ?', safe_input($agent_name)); + if (! defined ($agent)) { + logger ($pa_config, "Agent '$agent_name' not found for inventory module '$module_name'.", 3); + return; + } + + # Parse the timestamp and process the module + if ($timestamp !~ /(\d+)\/(\d+)\/(\d+) +(\d+):(\d+):(\d+)/ && + $timestamp !~ /(\d+)\-(\d+)\-(\d+) +(\d+):(\d+):(\d+)/) { + logger($pa_config, "Invalid timestamp '$timestamp' from module '$module_name' agent '$agent_name'.", 3); + return; + } + my $utimestamp; + eval { + $utimestamp = strftime("%s", $6, $5, $4, $3, $2 - 1, $1 - 1900); + }; + if ($@) { + logger($pa_config, "Invalid timestamp '$timestamp' from module '$module_name' agent '$agent_name'.", 3); + return; + } + + # Get module data or create it if it does not exist + my $inventory_module = get_db_single_row ($dbh, + 'SELECT tagent_module_inventory.*, tmodule_inventory.name + FROM tagent_module_inventory, tmodule_inventory + WHERE tagent_module_inventory.id_module_inventory = tmodule_inventory.id_module_inventory + AND id_agente = ? AND name = ?', + $agent->{'id_agente'}, safe_input($module_name)); + + + + if (! defined ($inventory_module)) { + # Get the module + my $module_id = get_db_value ($dbh, + 'SELECT id_module_inventory FROM tmodule_inventory WHERE name = ? AND id_os = ?', + safe_input($module_name), $agent->{'id_os'}); + return unless defined ($module_id); + + my $id_agent_module_inventory = 0; + # Update the module data + + $id_agent_module_inventory = db_insert ($dbh, 'id_agent_module_inventory', + "INSERT INTO tagent_module_inventory (id_agente, id_module_inventory, + ${RDBMS_QUOTE}interval${RDBMS_QUOTE}, data, timestamp, utimestamp, flag) + VALUES (?, ?, ?, ?, ?, ?, ?)", + $agent->{'id_agente'}, $module_id, $interval, safe_input($data), $timestamp, $utimestamp, 0); + + + return unless ($id_agent_module_inventory > 0); + + db_do ($dbh, + 'INSERT INTO tagente_datos_inventory (id_agent_module_inventory, data, timestamp, utimestamp) + VALUES (?, ?, ?, ?)', + $id_agent_module_inventory, safe_input($data), $timestamp, $utimestamp); + + return; + } + + process_inventory_module_diff($pa_config, safe_input($data), + $inventory_module, $timestamp, $utimestamp, $dbh, $interval); +} + +################################################################################ +# Searching differences between incoming module and stored module, +# creating/updating module and event +################################################################################ +sub process_inventory_module_diff ($$$$$$;$) { + my ($pa_config, $incoming_data, $inventory_module, $timestamp, $utimestamp, $dbh, $interval) = @_; + + my $stored_data = $inventory_module->{'data'}; + my $agent_id = $inventory_module->{'id_agente'}; + my $stored_utimestamp = $inventory_module->{'utimestamp'}; + my $agent_module_inventory_id = $inventory_module->{'id_agent_module_inventory'}; + my $module_inventory_id = $inventory_module->{'id_module_inventory'}; + + + process_inventory_alerts($pa_config, $incoming_data, + $inventory_module, $timestamp, $utimestamp, $dbh, $interval); + + # If there were any changes generate an event and save the new data + if (decode('UTF-8', $stored_data) ne $incoming_data) { + my $inventory_db = $stored_data; + my $inventory_new = $incoming_data; + my @inventory = split('\n', $inventory_new); + my $diff_new = ""; + my $diff_delete = ""; + + foreach my $inv (@inventory) { + my $inv_clean = quotemeta($inv); + if($inventory_db =~ m/$inv_clean/) { + $inventory_db =~ s/$inv_clean//g; + $inventory_new =~ s/$inv_clean//g; + } + else { + $diff_new .= "$inv\n"; + } + } + + # If any register is in the stored yet, we store as deleted + $inventory_db =~ s/\n\n*/\n/g; + $inventory_db =~ s/^\n//g; + + $diff_delete = $inventory_db; + + if($diff_new ne "") { + $diff_new = " NEW: '$diff_new' "; + } + if($diff_delete ne "") { + $diff_delete = " DELETED: '$diff_delete' "; + } + + db_do ($dbh, 'INSERT INTO tagente_datos_inventory (id_agent_module_inventory, data, timestamp, utimestamp) VALUES (?, ?, ?, ?)', + $agent_module_inventory_id, $incoming_data, $timestamp, $utimestamp); + + # Do not generate an event the first time the module runs + if ($stored_utimestamp != 0) { + my $inventory_changes_blacklist = pandora_get_config_value ($dbh, 'inventory_changes_blacklist'); + my $inventory_module_blocked = 0; + + if($inventory_changes_blacklist ne "") { + foreach my $inventory_id_excluded (split (',', $inventory_changes_blacklist)) { + # If the inventory_module_id is in the blacklist, the change will not be processed + if($inventory_module->{'id_module_inventory'} == $inventory_id_excluded) { + logger ($pa_config, "Inventory change omitted on inventory #$inventory_id_excluded due be on the changes blacklist", 10); + $inventory_module_blocked = 1; + } + } + } + + # If the inventory_module_id is in the blacklist, the change will not be processed + if ($inventory_module_blocked == 0) { + my $inventory_module_name = get_db_value ($dbh, "SELECT name FROM tmodule_inventory WHERE id_module_inventory = ?", $module_inventory_id); + return unless defined ($inventory_module_name); + + my $agent_name = get_agent_name ($dbh, $agent_id); + return unless defined ($agent_name); + + my $agent_alias = get_agent_alias ($dbh, $agent_id); + return unless defined ($agent_alias); + + my $group_id = get_agent_group ($dbh, $agent_id); + + + + $stored_data =~ s/ / /g; + $incoming_data =~ s/ / /g; + + my @values_stored = split(' ', $stored_data); + my @finalc_stored = (); + my @values_incoming = split(' ', $incoming_data); + my @finalc_incoming = (); + my @finalc_compare_added = (); + my @finalc_compare_deleted = (); + my @finalc_compare_updated = (); + my @finalc_compare_updated_del = (); + my @finalc_compare_updated_add = (); + my $temp_compare = (); + my $final_d = ''; + my $final_a = ''; + my $final_u = ''; + + + + foreach my $i (0 .. $#values_stored) { + $finalc_stored[$i] = $values_stored[$i]; + + if ( grep $_ eq $values_stored[$i], @values_incoming ) { + + } else { + # Use 'safe_output' to avoid double encode the entities when creating the event with 'pandora_event' + $final_d .= "DELETED RECORD: ".safe_output($values_stored[$i])."\n"; + } + } + + foreach my $i (0 .. $#values_incoming) { + $finalc_incoming[$i] = $values_incoming[$i]; + + if ( grep $_ eq $values_incoming[$i], @values_stored ) { + + } else { + # Use 'safe_output' to avoid double encode the entities when creating the event with 'pandora_event' + $final_a .= "NEW RECORD: ".safe_output($values_incoming[$i])."\n"; + } + } + + # foreach my $i (0 .. $#finalc_compare_deleted) { + # $finalc_compare_updated_del[$i] = split(';', $finalc_compare_deleted[$i]); + # $finalc_compare_updated_add[$i] = split(';', $finalc_compare_added[$i]); + # if($finalc_compare_updated_del[$i] ~~ @finalc_compare_updated_add){ + # $finalc_compare_updated[$i] = $finalc_compare_updated_del[$i]; + # } + # $finalc_compare_updated[$i] =~ s/DELETED RECORD:/UPDATED RECORD:/g; + # $finalc_compare_updated[$i] =~ s/NEW RECORD://g; + # } + + + pandora_event ($pa_config, "Configuration change:\n".$final_d.$final_a." for agent '" . safe_output($agent_alias) . "' module '" . safe_output($inventory_module_name) . "'.", $group_id, $agent_id, 0, 0, 0, "configuration_change", 0, $dbh); + } + } + } + + # Update the module data + if (defined($interval)) { + db_do ($dbh, 'UPDATE tagent_module_inventory + SET'. $RDBMS_QUOTE . 'interval' . + $RDBMS_QUOTE . '=?, data=?, timestamp=?, utimestamp=? + WHERE id_agent_module_inventory=?', + $interval, $incoming_data, $timestamp, + $utimestamp, $agent_module_inventory_id); + + } + else { + db_do ($dbh, 'UPDATE tagent_module_inventory + SET data = ?, timestamp = ?, utimestamp = ? + WHERE id_agent_module_inventory = ?', + $incoming_data, $timestamp, $utimestamp, $agent_module_inventory_id); + } +} + sub log4x_get_severity_num($) { my ($data_object) = @_; my $data = $data_object->{'severity'}; diff --git a/pandora_server/lib/PandoraFMS/DataServer.pm b/pandora_server/lib/PandoraFMS/DataServer.pm index 209859e9a1..e53692170e 100644 --- a/pandora_server/lib/PandoraFMS/DataServer.pm +++ b/pandora_server/lib/PandoraFMS/DataServer.pm @@ -628,8 +628,7 @@ sub process_xml_data ($$$$$) { # Process inventory modules - enterprise_hook('process_inventory_data', [$pa_config, $data, $server_id, $agent_name, - $interval, $timestamp, $dbh]); + process_inventory_data($pa_config, $data, $server_id, $agent_name, $interval, $timestamp, $dbh); # Process log modules enterprise_hook('process_log_data', [$pa_config, $data, $server_id, $agent_name, From da0dad0148623b456c3a40ecb7b1759d52116b17 Mon Sep 17 00:00:00 2001 From: Calvo Date: Wed, 14 Sep 2022 18:12:39 +0200 Subject: [PATCH 02/12] WIP:Move inventory to open --- .../godmode/agentes/configurar_agente.php | 19 +- .../godmode/agentes/inventory_manager.php | 262 ++++ pandora_console/godmode/menu.php | 4 +- .../modules/manage_inventory_modules.php | 387 ++++++ .../modules/manage_inventory_modules_form.php | 153 +++ .../include/functions_inventory.php | 1147 +++++++++++++++++ pandora_console/include/functions_menu.php | 2 +- .../include/functions_planned_downtimes.php | 3 +- .../include/functions_reporting_html.php | 1 + pandora_console/include/functions_ui.php | 256 ++++ .../operation/agentes/agent_inventory.php | 281 ++++ .../operation/agentes/ver_agente.php | 18 +- .../operation/inventory/inventory.php | 551 ++++++++ pandora_console/operation/menu.php | 6 +- pandora_server/bin/pandora_server | 3 + pandora_server/lib/PandoraFMS/Core.pm | 545 ++++---- .../lib/PandoraFMS/InventoryServer.pm | 267 ++++ 17 files changed, 3626 insertions(+), 279 deletions(-) create mode 100644 pandora_console/godmode/agentes/inventory_manager.php create mode 100644 pandora_console/godmode/modules/manage_inventory_modules.php create mode 100644 pandora_console/godmode/modules/manage_inventory_modules_form.php create mode 100644 pandora_console/include/functions_inventory.php create mode 100644 pandora_console/operation/agentes/agent_inventory.php create mode 100755 pandora_console/operation/inventory/inventory.php create mode 100644 pandora_server/lib/PandoraFMS/InventoryServer.pm diff --git a/pandora_console/godmode/agentes/configurar_agente.php b/pandora_console/godmode/agentes/configurar_agente.php index a1ebc7ce7f..208eed59a0 100644 --- a/pandora_console/godmode/agentes/configurar_agente.php +++ b/pandora_console/godmode/agentes/configurar_agente.php @@ -451,7 +451,20 @@ if ($id_agente) { // Inventory. - $inventorytab = enterprise_hook('inventory_tab'); + $inventorytab['text'] = ''.html_print_image( + 'images/page_white_text.png', + true, + [ + 'title' => __('Inventory'), + 'class' => 'invert_filter', + ] + ).''; + + if ($tab == 'inventory') { + $inventorytab['active'] = true; + } else { + $inventorytab['active'] = false; + } if ($inventorytab == -1) { $inventorytab = ''; @@ -2354,6 +2367,10 @@ switch ($tab) { include 'agent_wizard.php'; break; + case 'inventory': + include 'inventory_manager.php'; + break; + default: if (enterprise_hook('switch_agent_tab', [$tab])) { // This will make sure that blank pages will have at least some diff --git a/pandora_console/godmode/agentes/inventory_manager.php b/pandora_console/godmode/agentes/inventory_manager.php new file mode 100644 index 0000000000..b477d7e923 --- /dev/null +++ b/pandora_console/godmode/agentes/inventory_manager.php @@ -0,0 +1,262 @@ + $id_agente, + 'id_module_inventory' => $id_module_inventory, + ] + ); + + if (!$if_exists) { + $values = [ + 'id_agente' => $id_agente, + 'id_module_inventory' => $id_module_inventory, + 'target' => $target, + 'interval' => $interval, + 'username' => $username, + 'password' => $password, + 'custom_fields' => $custom_fields_enabled && !empty($custom_fields) ? base64_encode(json_encode($custom_fields)) : '', + ]; + + $result = db_process_sql_insert('tagent_module_inventory', $values); + + if ($result) { + ui_print_success_message(__('Successfully added inventory module')); + } else { + ui_print_error_message(__('Error adding inventory module')); + } + } else { + ui_print_error_message(__('The inventory of the module already exists')); + } + + // Remove inventory module from agent +} else if ($delete_inventory_module) { + $result = db_process_sql_delete( + 'tagent_module_inventory', + ['id_agent_module_inventory' => $delete_inventory_module] + ); + + if ($result) { + ui_print_success_message(__('Successfully deleted inventory module')); + } else { + ui_print_error_message(__('Error deleting inventory module')); + } + + // Update inventory module +} else if ($force_inventory_module) { + $result = db_process_sql_update('tagent_module_inventory', ['flag' => 1], ['id_agent_module_inventory' => $force_inventory_module]); + + if ($result) { + ui_print_success_message(__('Successfully forced inventory module')); + } else { + ui_print_error_message(__('Error forcing inventory module')); + } + + // Update inventory module +} else if ($update_inventory_module) { + $values = [ + 'target' => $target, + 'interval' => $interval, + 'username' => $username, + 'password' => $password, + 'custom_fields' => $custom_fields_enabled && !empty($custom_fields) ? base64_encode(json_encode($custom_fields)) : '', + ]; + + $result = db_process_sql_update('tagent_module_inventory', $values, ['id_agent_module_inventory' => $id_agent_module_inventory, 'id_agente' => $id_agente]); + + if ($result) { + ui_print_success_message(__('Successfully updated inventory module')); + } else { + ui_print_error_message(__('Error updating inventory module')); + } +} + +// Load inventory module data for updating +if ($load_inventory_module) { + $sql = 'SELECT * FROM tagent_module_inventory WHERE id_module_inventory = '.$load_inventory_module; + $row = db_get_row_sql($sql); + + if (!empty($row)) { + $id_agent_module_inventory = $row['id_agent_module_inventory']; + $id_module_inventory = $row['id_module_inventory']; + $target = $row['target']; + $interval = $row['interval']; + $username = $row['username']; + $password = io_output_password($row['password']); + $custom_fields = []; + + if (!empty($row['custom_fields'])) { + try { + $custom_fields = array_map( + function ($field) { + if ($field['secure']) { + $field['value'] = io_output_password($field['value']); + } + + return $field; + }, + json_decode(base64_decode($row['custom_fields']), true) + ); + $custom_fields_enabled = true; + } catch (Exception $e) { + } + } + } else { + ui_print_error_message(__('Inventory module error')); + include 'general/footer.php'; + + return; + } +} else { + $target = $direccion_agente; + $interval = (string) SECONDS_1HOUR; + $username = ''; + $password = ''; + $custom_fields_enabled = false; + $custom_fields = []; +} + +// Inventory module configuration +$form_buttons = ''; +if ($load_inventory_module) { + $form_buttons .= html_print_input_hidden('id_agent_module_inventory', $id_agent_module_inventory, true); + $form_buttons .= html_print_submit_button(__('Update'), 'update_inventory_module', false, 'class="sub next"', true); +} else { + $form_buttons .= html_print_submit_button(__('Add'), 'add_inventory_module', false, 'class="sub next"', true); +} + +echo ui_get_inventory_module_add_form( + 'index.php?sec=estado&sec2=godmode/agentes/configurar_agente&tab=inventory&id_agente='.$id_agente, + $form_buttons, + $load_inventory_module, + $id_os, + $target, + $interval, + $username, + $password, + $custom_fields_enabled, + $custom_fields +); + +// Inventory module list +$sql = sprintf( + 'SELECT * + FROM tmodule_inventory, tagent_module_inventory + WHERE tagent_module_inventory.id_agente = %d + AND tmodule_inventory.id_module_inventory = tagent_module_inventory.id_module_inventory + ORDER BY name', + $id_agente +); +$result = db_process_sql($sql); +if (db_get_num_rows($sql) == 0) { + echo ' '; +} else { + $table->width = '100%'; + $table->class = 'databox filters'; + $table->data = []; + $table->head = []; + $table->styleTable = 'margin-top: 20px;'; + $table->head[0] = "".__('P.').''; + $table->head[1] = __('Name'); + $table->head[2] = __('Description'); + $table->head[3] = __('Target'); + $table->head[4] = __('Interval'); + $table->head[5] = __('Actions'); + $table->align = []; + $table->align[5] = 'left'; + + foreach ($result as $row) { + $data = []; + + $sql = sprintf('SELECT id_policy FROM tpolicy_modules_inventory WHERE id = %d', $row['id_policy_module_inventory']); + $id_policy = db_get_value_sql($sql); + + if ($id_policy) { + $policy = policies_get_policy($id_policy); + $data[0] = ''; + $data[0] .= html_print_image('images/policies_mc.png', true, ['border' => '0', 'title' => $policy['name']]); + $data[0] .= ''; + } else { + $data[0] = ''; + } + + $data[1] = ''.$row['name'].''; + $data[2] = $row['description']; + $data[3] = $row['target']; + $data[4] = human_time_description_raw($row['interval']); + // Delete module + $data[5] = ''; + $data[5] .= html_print_image('images/cross.png', true, ['border' => '0', 'title' => __('Delete'), 'class' => 'invert_filter']); + $data[5] .= '  '; + // Update module + $data[5] .= ''; + $data[5] .= html_print_image('images/config.png', true, ['border' => '0', 'title' => __('Update'), 'class' => 'invert_filter']); + $data[5] .= '  '; + // Force refresh module + $data[5] .= ''; + $data[5] .= html_print_image('images/target.png', true, ['border' => '0', 'title' => __('Force'), 'class' => 'invert_filter']).''; + array_push($table->data, $data); + } + + html_print_table($table); +} diff --git a/pandora_console/godmode/menu.php b/pandora_console/godmode/menu.php index d63595d553..7ba9973eed 100644 --- a/pandora_console/godmode/menu.php +++ b/pandora_console/godmode/menu.php @@ -180,7 +180,9 @@ if ($access_console_node === true) { $sub2['godmode/modules/manage_network_components']['id'] = 'Network components'; $sub['templates']['sub2'] = $sub2; - enterprise_hook('inventory_submenu'); + $sub['godmode/modules/manage_inventory_modules']['text'] = __('Inventory modules'); + $sub['godmode/modules/manage_inventory_modules']['id'] = 'Inventory modules'; + enterprise_hook('autoconfiguration_menu'); enterprise_hook('agent_repository_menu'); } diff --git a/pandora_console/godmode/modules/manage_inventory_modules.php b/pandora_console/godmode/modules/manage_inventory_modules.php new file mode 100644 index 0000000000..0eb4807beb --- /dev/null +++ b/pandora_console/godmode/modules/manage_inventory_modules.php @@ -0,0 +1,387 @@ +'.__('metaconsole').''; + } else { + $url = __('any node'); + } + + ui_print_warning_message( + __( + 'This console is not manager of this environment, please manage this feature from centralized manager console. Go to %s to manage it.', + $url + ) + ); + } +} + +$is_windows = strtoupper(substr(PHP_OS, 0, 3)) == 'WIN'; +if ($is_windows) { + ui_print_error_message(__('Not supported in Windows systems')); +} + +// Initialize variables. +$offset = (int) get_parameter('offset'); +$create_module_inventory = (bool) get_parameter('create_module_inventory'); +$update_module_inventory = (bool) get_parameter('update_module_inventory'); +$delete_inventory_module = (int) get_parameter('delete_inventory_module'); +$multiple_delete = (bool) get_parameter('multiple_delete', 0); +$id_module_inventory = (int) get_parameter('id_module_inventory'); +$name = (string) get_parameter('name'); +$description = (string) get_parameter('description'); +$id_os = (int) get_parameter('id_os'); +if ($id_os == 0) { + $id_os = 'NULL'; +} + +$interpreter = (string) get_parameter('interpreter'); +$code = (string) get_parameter('code'); +$code = base64_encode(str_replace("\r", '', html_entity_decode($code, ENT_QUOTES))); +$format = (string) get_parameter('format'); +$block_mode = (int) get_parameter('block_mode', 0); + +// Create inventory module. +if ($create_module_inventory === true) { + $values = [ + 'name' => $name, + 'description' => $description, + 'id_os' => $id_os, + 'interpreter' => $interpreter, + 'code' => $code, + 'data_format' => $format, + 'block_mode' => $block_mode, + ]; + + $result = (bool) inventory_create_inventory_module($values); + + $auditMessage = ((bool) $result === true) ? sprintf('Create inventory module #%s', $result) : 'Fail try to create inventory module'; + db_pandora_audit( + AUDIT_LOG_MODULE_MANAGEMENT, + $auditMessage + ); + + ui_print_result_message( + (bool) $result, + __('Successfully created inventory module'), + __('Error creating inventory module') + ); + + // Update inventory module. +} else if ($update_module_inventory === true) { + $values = [ + 'name' => $name, + 'description' => $description, + 'id_os' => $id_os, + 'interpreter' => $interpreter, + 'code' => $code, + 'data_format' => $format, + 'block_mode' => $block_mode, + ]; + + $result = inventory_update_inventory_module($id_module_inventory, $values); + + $auditMessage = ((bool) $result === true) ? 'Update inventory module' : 'Fail try to update inventory module'; + db_pandora_audit( + AUDIT_LOG_MODULE_MANAGEMENT, + sprintf('%s #%s', $auditMessage, $id_module_inventory) + ); + + ui_print_result_message( + (bool) $result, + __('Successfully updated inventory module'), + __('Error updating inventory module') + ); + + // Delete inventory module. +} else if ($delete_inventory_module === true) { + $result = db_process_sql_delete( + 'tmodule_inventory', + ['id_module_inventory' => $delete_inventory_module] + ); + + $auditMessage = ((bool) $result === true) ? 'Delete inventory module' : 'Fail try to delete inventory module'; + db_pandora_audit( + AUDIT_LOG_MODULE_MANAGEMENT, + sprintf('%s #%s', $auditMessage, $id_module_inventory) + ); + + ui_print_result_message( + (bool) $result, + __('Successfully deleted inventory module'), + __('Error deleting inventory module') + ); + + if (is_metaconsole() === true) { + $setups = db_get_all_rows_in_table('tmetaconsole_setup'); + foreach ($setups as $key => $setup) { + if (metaconsole_connect($setup) == NOERR) { + $result = db_process_sql_delete( + 'tmodule_inventory', + ['id_module_inventory' => $delete_inventory_module] + ); + + $auditMessage = ((bool) $result === true) ? 'Delete inventory module' : 'Fail try to delete inventory module'; + db_pandora_audit( + AUDIT_LOG_MODULE_MANAGEMENT, + sprintf('%s #%s', $auditMessage, $id_module_inventory) + ); + + ui_print_result_message( + (bool) $result, + $setup['server_name'].': '.__('Successfully deleted inventory module'), + $setup['server_name'].': '.__('Error deleting inventory module') + ); + } + + metaconsole_restore_db(); + } + } +} else if ($multiple_delete) { + $ids = (array) get_parameter('delete_multiple', []); + + foreach ($ids as $id) { + $result = db_process_sql_delete('tmodule_inventory', ['id_module_inventory' => $id]); + + if ($result === false) { + break; + } + } + + if ($result !== false) { + $result = true; + } else { + $result = false; + } + + $str_ids = implode(',', $ids); + $auditMessage = ($result === true) ? 'Multiple delete inventory module' : 'Fail try to delete inventory module'; + db_pandora_audit( + AUDIT_LOG_MODULE_MANAGEMENT, + sprintf('%s :%s', $auditMessage, $str_ids) + ); + + ui_print_result_message( + $result, + __('Successfully multiple deleted'), + __('Not deleted. Error deleting multiple data') + ); + + $id = 0; + + if (is_metaconsole()) { + $setups = db_get_all_rows_in_table('tmetaconsole_setup'); + foreach ($setups as $key => $setup) { + if (metaconsole_connect($setup) == NOERR) { + foreach ($ids as $id) { + $result_node = db_process_sql_delete('tmodule_inventory', ['id_module_inventory' => $id]); + + if ($result_node === false) { + break; + } + } + + if ($result_node !== false) { + $result_node = true; + } else { + $result_node = false; + } + + $str_ids = implode(',', $ids); + $auditMessage = ($result_node === true) ? 'Multiple delete inventory module' : 'Fail try to delete inventory module'; + db_pandora_audit( + AUDIT_LOG_MODULE_MANAGEMENT, + sprintf('%s :%s', $auditMessage, $str_ids) + ); + + ui_print_result_message( + $result_node, + $setup['server_name'].': '.__('Successfully multiple deleted'), + $setup['server_name'].': '.__('Not deleted. Error deleting multiple data') + ); + } + + metaconsole_restore_db(); + } + } +} + +$total_modules = db_get_sql('SELECT COUNT(*) FROM tmodule_inventory'); + +$table = new stdClass(); +$table->width = '100%'; +$table->class = 'info_table'; +$table->size = []; +$table->size[0] = '140px'; +$table->align = []; +$table->align[2] = 'left'; +$table->align[4] = 'left'; +$table->data = []; +$table->head = []; +$table->head[0] = __('Name'); +$table->head[1] = __('Description'); +$table->head[2] = __('OS'); +$table->head[3] = __('Interpreter'); + +if ($management_allowed === true) { + $table->head[4] = __('Action').html_print_checkbox('all_delete', 0, false, true, false); +} + +$result = inventory_get_modules_list($offset); + +if ($result === false) { + ui_print_info_message(['no_close' => true, 'message' => __('No inventory modules defined') ]); +} else { + $status = ''; + $begin = true; + while ($row = array_shift($result)) { + $data = []; + $begin = false; + if ($management_allowed === true) { + $data[0] = ''.$row['name'].''; + } else { + $data[0] = ''.$row['name'].''; + } + + $data[1] = $row['description']; + if ($row['os_name'] == null) { + $data[2] = html_print_image('images/agent.png', true, ['border' => '0', 'alt' => __('Agent'), 'title' => __('Agent'), 'height' => '18', 'class' => 'invert_filter']); + } else { + $data[2] = ui_print_os_icon($row['id_os'], false, true); + } + + if ($row['interpreter'] == '') { + $data[3] = __('Local module'); + } else { + $data[3] = __('Remote/Local'); + } + + if ($management_allowed === true) { + // Update module. + $data[4] = ''; + $data[4] .= html_print_image('images/config.png', true, ['border' => '0', 'title' => __('Update'), 'class' => 'invert_filter']).''; + + // Delete module. + $data[4] .= ''; + $data[4] .= html_print_image('images/cross.png', true, ['border' => '0', 'title' => __('Delete'), 'class' => 'invert_filter']); + $data[4] .= '  '; + $data[4] .= html_print_checkbox_extended('delete_multiple[]', $row['id_module_inventory'], false, false, '', 'class="check_delete"', true); + } + + array_push($table->data, $data); + } + + echo "
"; + html_print_input_hidden('multiple_delete', 1); + ui_pagination($total_modules, 'index.php?sec='.$sec.'&sec2=godmode/modules/manage_inventory_modules', $offset); + html_print_table($table); + ui_pagination($total_modules, 'index.php?sec='.$sec.'&sec2=godmode/modules/manage_inventory_modules', $offset, 0, false, 'offset', true, 'pagination-bottom'); + echo "
"; + if ($management_allowed === true) { + html_print_submit_button(__('Delete'), 'delete_btn', false, 'class="sub delete"'); + } + + echo '
'; + echo '
'; +} + +if ($management_allowed === true) { + echo '
'; + echo '
'; + html_print_input_hidden('create_module_inventory', 1); + html_print_submit_button(__('Create'), 'crt', false, 'class="sub next"'); + echo '
'; + echo '
'; +} + + +if (is_metaconsole() === true) { + enterprise_hook('close_meta_frame'); + echo ''; +} + +?> + diff --git a/pandora_console/godmode/modules/manage_inventory_modules_form.php b/pandora_console/godmode/modules/manage_inventory_modules_form.php new file mode 100644 index 0000000000..1d5f6a4f9a --- /dev/null +++ b/pandora_console/godmode/modules/manage_inventory_modules_form.php @@ -0,0 +1,153 @@ +width = '100%'; +$table->class = 'databox filters'; +$table->style = []; +$table->style[0] = 'font-weight: bold'; +$table->data = []; +$table->data[0][0] = ''.__('Name').''; +$table->data[0][1] = html_print_input_text('name', $name, '', 45, 100, true, $disabled); +$table->data[1][0] = ''.__('Description').''; +$table->data[1][1] = html_print_input_text('description', $description, '', 60, 500, true); +$table->data[2][0] = ''.__('OS').''; +$table->data[2][1] = html_print_select_from_sql( + 'SELECT id_os, name FROM tconfig_os ORDER BY name', + 'id_os', + $id_os, + '', + '', + '', + $return = true +); + +$table->data[3][0] = ''.__('Interpreter').''; +$table->data[3][1] = html_print_input_text('interpreter', $interpreter, '', 25, 100, true); +$table->data[3][1] .= ui_print_help_tip(__('Left blank for the LOCAL inventory modules'), true); + +$table->data['block_mode'][0] = ''.__('Block Mode').''; +$table->data['block_mode'][1] = html_print_checkbox('block_mode', 1, $block_mode, true); + +$table->data[4][0] = ''.__('Format').''; +$table->data[4][0] .= ui_print_help_tip(__('separate fields with ').SEPARATOR_COLUMN, true); +$table->data[4][1] = html_print_input_text('format', $data_format, '', 50, 100, true); + +$table->data[5][0] = ''.__('Code').''; +$table->data[5][0] .= ui_print_help_tip(__("Here is placed the script for the REMOTE inventory modules Local inventory modules don't use this field").SEPARATOR_COLUMN, true); + +$table->data[5][1] = html_print_textarea('code', 25, 80, base64_decode($code), '', true); + +echo '
'; + +html_print_table($table); +if ($id_module_inventory) { + html_print_input_hidden('update_module_inventory', 1); + html_print_input_hidden('id_module_inventory', $id_module_inventory); +} else { + html_print_input_hidden('create_module_inventory', 1); +} + +echo '
'; +if ($id_module_inventory) { + html_print_submit_button(__('Update'), 'submit', false, 'class="sub next"'); +} else { + html_print_submit_button(__('Create'), 'submit', false, 'class="sub upd"'); +} + +echo '
'; +echo '
'; + +if (defined('METACONSOLE')) { + enterprise_hook('close_meta_frame'); +} diff --git a/pandora_console/include/functions_inventory.php b/pandora_console/include/functions_inventory.php new file mode 100644 index 0000000000..2ac322a4fe --- /dev/null +++ b/pandora_console/include/functions_inventory.php @@ -0,0 +1,1147 @@ + 0) { + $data_row = db_get_row_sql( + 'SELECT data, timestamp + FROM tagente_datos_inventory + WHERE utimestamp <= '.$utimestamp.' + AND id_agent_module_inventory = '.$row['id_agent_module_inventory'].' ORDER BY utimestamp DESC' + ); + if ($data_row !== false) { + $row['data'] = $data_row['data']; + $row['timestamp'] = $data_row['timestamp']; + } + } + + if (!$order_by_agent) { + $agent_name = db_get_value('alias', 'tagente', 'id_agente', $row['id_agente']); + + $out_csv .= __('Agent alias').' --> '.io_safe_output($agent_name)."\n"; + $out_csv .= __('Timestamp').' = '.$row['timestamp']."\n"; + $out_csv .= io_safe_output($row['data_format'])."\n"; + + // Filter data by search string. + if ($inventory_search_string !== '') { + $str = io_safe_output($row['data']); + $matches = []; + $re = '/.*'.$inventory_search_string.'.*\n/m'; + if (preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0)) { + // Print the entire match result. + foreach ($matches as $match) { + $out_csv .= $match[0]; + } + + $out_csv .= "\n\n"; + } + } else { + $out_csv .= io_safe_output($row['data'])."\n\n"; + } + } else { + $agent_name = db_get_value('alias', 'tagente', 'id_agente', $row['id_agente']); + $agent_inventory_temp = []; + $agent_inventory[$agent_name][] = [ + 'name' => $row['name'], + 'data_formtat' => $row['data_format'], + 'data' => $row['data'], + ]; + } + } + + if ($order_by_agent) { + if (empty($agent_inventory) === false) { + foreach ($agent_inventory as $alias => $agent_data) { + $out_csv .= __('Agent alias').' --> '.io_safe_output($alias)."\n"; + $out_csv .= __('Timestamp').' = '.$row['timestamp']."\n"; + + foreach ($agent_data as $data) { + $out_csv .= io_safe_output($data['name'])."\n"; + $out_csv .= io_safe_output($data['data_format'])."\n"; + + // Filter data by search string. + if ($inventory_search_string !== '') { + $str = io_safe_output($data['data']); + $matches = []; + $re = '/.*'.$inventory_search_string.'.*\n/m'; + if (preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0)) { + // Print the entire match result. + foreach ($matches as $match) { + $out_csv .= $match[0]; + } + + $out_csv .= "\n\n"; + } + } else { + $out_csv .= io_safe_output($row['data'])."\n\n"; + } + } + } + } + } + } + + if ($export_csv) { + $name_file = 'inventory_'.md5( + $inventory_module_name.$utimestamp.$inventory_search_string + ).'.csv'; + file_put_contents( + $config['attachment_store'].'/'.$name_file, + $out_csv + ); + + echo "".__('Get CSV file').''; + return; + } else if ($return_mode === 'csv') { + return $out_csv; + } else if ($return_mode === 'hash') { + if ($utimestamp > 0) { + $timestamp = db_get_value_sql( + "SELECT timestamp + FROM tagente_datos_inventory + WHERE utimestamp = $utimestamp" + ); + } else { + $timestamp = db_get_value_sql( + 'SELECT timestamp + FROM tagente_datos_inventory + WHERE utimestamp = + (SELECT MAX(tagente_datos_inventory.utimestamp) + FROM tagente_datos_inventory, tmodule_inventory, + tagent_module_inventory + WHERE '.implode(' AND ', $where).' + AND tmodule_inventory.id_module_inventory = tagent_module_inventory.id_module_inventory + AND tagent_module_inventory.id_agent_module_inventory = tagente_datos_inventory.id_agent_module_inventory)' + ); + } + + $out_array = []; + foreach ($rows as $k => $row) { + $out_array[$k]['timestamp'] = $timestamp; + $out_array[$k]['id_module_inventory'] = $row['id_module_inventory']; + $out_array[$k]['id_os'] = $row['id_os']; + $out_array[$k]['name'] = io_safe_output($row['name']); + $out_array[$k]['description'] = io_safe_output($row['description']); + $out_array[$k]['interpreter'] = $row['interpreter']; + $out_array[$k]['id_agent_module_inventory'] = $row['id_agent_module_inventory']; + $out_array[$k]['id_agente'] = $row['id_agente']; + $agent_name = db_get_value('alias', 'tagente', 'id_agente', $row['id_agente']); + $out_array[$k]['agent_name'] = $agent_name; + $out_array[$k]['target'] = $row['target']; + $out_array[$k]['interval'] = $row['interval']; + $out_array[$k]['username'] = $row['username']; + + $items = explode(';', io_safe_output($row['data_format'])); + + $data = []; + if (empty($row['data']) === false) { + $data_rows = explode("\n", io_safe_output($row['data'])); + $data = []; + foreach ($data_rows as $data_row) { + $cells = explode(';', $data_row); + + $temp_row = []; + $i = 0; + foreach ($cells as $cell) { + $temp_row[$items[$i]] = $cell; + $i++; + } + + $data[] = $temp_row; + } + } + + $out_array[$k]['data'] = $data; + $out_array[$k]['timestamp'] = io_safe_output($row['timestamp']); + $out_array[$k]['flag'] = io_safe_output($row['flag']); + } + + return $out_array; + } else if ($return_mode === 'array') { + $out_array = []; + foreach ($rows as $k => $row) { + $out_array[$k]['id_module_inventory'] = $row['id_module_inventory']; + $out_array[$k]['id_os'] = $row['id_os']; + $out_array[$k]['name'] = io_safe_output($row['name']); + $out_array[$k]['description'] = io_safe_output($row['description']); + $out_array[$k]['interpreter'] = $row['interpreter']; + $out_array[$k]['data_format'] = $row['data_format']; + $out_array[$k]['id_agent_module_inventory'] = $row['id_agent_module_inventory']; + $out_array[$k]['id_agente'] = $row['id_agente']; + $out_array[$k]['target'] = $row['target']; + $out_array[$k]['interval'] = $row['interval']; + $out_array[$k]['username'] = $row['username']; + $out_array[$k]['data'] = ''; + $out_array[$k]['timestamp'] = io_safe_output($row['timestamp']); + $out_array[$k]['flag'] = io_safe_output($row['flag']); + } + + if (empty($out_array) === true) { + return __('No data found'); + } + + return $out_array; + } + + $idModuleInventory = null; + + $rowTable = 1; + + // Timestamp filter only allowed in nodes for performance. + if (is_metaconsole() === false) { + if ($utimestamp > 0) { + $timestamp = db_get_value_sql( + "SELECT timestamp + FROM tagente_datos_inventory + WHERE utimestamp = $utimestamp" + ); + } else { + $timestamp = db_get_value_sql( + 'SELECT timestamp + FROM tagente_datos_inventory + WHERE utimestamp = + (SELECT MAX(tagente_datos_inventory.utimestamp) + FROM tagente_datos_inventory, tmodule_inventory, + tagent_module_inventory + WHERE '.implode(' AND ', $where).' + AND tmodule_inventory.id_module_inventory = tagent_module_inventory.id_module_inventory + AND tagent_module_inventory.id_agent_module_inventory = tagente_datos_inventory.id_agent_module_inventory)' + ); + } + } + + // TODO: Workaround. + $timestamp = 'Last'; + if (!$order_by_agent) { + $countRows = 0; + foreach ($rows as $row) { + // Check for not show more elements that allowed in config. + if ($countRows >= (int) $config['meta_num_elements']) { + break; + } + + $countRows++; + + // Continue. + if (is_metaconsole() === false && $utimestamp > 0) { + $data_row = db_get_row_sql( + "SELECT data, timestamp + FROM tagente_datos_inventory + WHERE utimestamp <= '".$utimestamp."' + AND id_agent_module_inventory = ".$row['id_agent_module_inventory'].' ORDER BY utimestamp DESC' + ); + if ($data_row !== false) { + $row['data'] = $data_row['data']; + $row['timestamp'] = $data_row['timestamp']; + } else { + // Continue to next row in case there is no data for that timestamp. + continue; + } + } + + if ($idModuleInventory != $row['id_module_inventory']) { + if (isset($table) === true) { + $out .= "
"; + $out .= html_print_table($table, true); + $out .= '
'; + unset($table); + $rowTable = 1; + } + + $table = new stdClass(); + $table->width = '100%'; + $table->align = []; + $table->cellpadding = 0; + $table->cellspacing = 0; + $table->class = 'info_table inventory_tables'; + $table->head = []; + $table->head[0] = ''.$row['name'].' '.html_print_image('images/timestamp.png', true, ['title' => __('Timestamp'), 'style' => 'vertical-align:middle']).' ('.$timestamp.')'; + $table->headstyle[0] = 'text-align:center'; + + $subHeadTitles = explode(';', io_safe_output($row['data_format'])); + + $table->head_colspan = []; + $table->head_colspan[0] = (2 + count($subHeadTitles)); + $total_fields = count($subHeadTitles); + $table->rowspan = []; + + $table->data = []; + + $iterator = 1; + + $table->data[0][0] = __('Agent'); + foreach ($subHeadTitles as $titleData) { + $table->data[0][$iterator] = $titleData; + $iterator++; + } + + $table->data[0][] = __('Timestamp'); + $iterator++; + } + + // Setting for link the agent with the proper server. + if (is_metaconsole() === true && empty($node) === false) { + $loginHash = metaconsole_get_servers_url_hash($node); + $urlToAgent = sprintf( + '%sindex.php?sec=estado&sec2=operation/agentes/ver_agente&id_agente=%s%s', + $node['server_url'], + $row['id_agente'], + $loginHash + ); + } else { + $urlToAgent = sprintf( + 'index.php?sec=estado&sec2=operation/agentes/ver_agente&id_agente=%s', + $row['id_agente'] + ); + } + + $agent_name = db_get_value_sql( + 'SELECT alias + FROM tagente + WHERE id_agente = '.$row['id_agente'] + ); + + $table->data[$rowTable][0] = html_print_anchor( + [ + 'href' => $urlToAgent, + 'content' => ''.$agent_name.'', + ], + true + ); + + $arrayDataRowsInventory = explode(SEPARATOR_ROW, io_safe_output($row['data'])); + // SPLIT DATA IN ROWS + // Remove the empty item caused by a line ending with a new line. + $len = count($arrayDataRowsInventory); + if (end($arrayDataRowsInventory) == '') { + $len--; + unset($arrayDataRowsInventory[$len]); + } + + $iterator1 = 0; + $numRowHasNameAgent = $rowTable; + + $rowPair = true; + $iterator = 0; + foreach ($arrayDataRowsInventory as $dataRowInventory) { + if ($rowPair === true) { + $table->rowclass[$iterator] = 'rowPair'; + } else { + $table->rowclass[$iterator] = 'rowOdd'; + } + + $rowPair = !$rowPair; + $iterator++; + + // Because SQL query extract all rows (row1;row2;row3...) and only I want the row has + // the search string. + if ($inventory_search_string && preg_match('/'.io_safe_output($inventory_search_string).'/', ($dataRowInventory)) == 0) { + continue; + } + + if ($rowTable > $numRowHasNameAgent) { + $table->data[$rowTable][0] = ''; + } + + $arrayDataColumnInventory = explode(SEPARATOR_COLUMN, $dataRowInventory); + // SPLIT ROW IN COLUMNS. + $iterator2 = 1; + + foreach ($arrayDataColumnInventory as $dataColumnInventory) { + $table->data[$rowTable][$iterator2] = $dataColumnInventory; + $iterator2++; + } + + // Fill unfilled cells with empty string. + $countArray = count($arrayDataColumnInventory); + for ($i = 0; $i < ($total_fields - $countArray); $i++) { + $table->data[$rowTable][$iterator2] = ''; + $iterator2++; + } + + $table->data[$rowTable][$iterator2] = $row['timestamp']; + + $iterator1++; + + $rowTable++; + if ($rowPair === true) { + $table->rowclass[$rowTable] = 'rowPair'; + } else { + $table->rowclass[$rowTable] = 'rowOdd'; + } + } + + if ($rowPair === true) { + $table->rowclass[$iterator] = 'rowPair'; + } else { + $table->rowclass[$iterator] = 'rowOdd'; + } + + $rowPair = !$rowPair; + if ($rowPair) { + $table->rowclass[($iterator + 1)] = 'rowPair'; + } else { + $table->rowclass[($iterator + 1)] = 'rowOdd'; + } + + if ($iterator1 > 5) { + // PRINT COUNT TOTAL. + $table->data[$rowTable][0] = ''; + $table->data[$rowTable][1] = ''.__('Total').': '.$iterator1; + $countSubHeadTitles = count($subHeadTitles); + for ($row_i = 2; $row_i <= $countSubHeadTitles; $row_i++) { + $table->data[$rowTable][$row_i] = ''; + } + + $rowTable++; + } + + $idModuleInventory = $row['id_module_inventory']; + } + } else { + $agent_data = []; + foreach ($rows as $row) { + $agent_data[$row['id_agente']][] = $row; + } + + foreach ($agent_data as $id_agent => $rows) { + $agent_name = db_get_value_sql( + 'SELECT alias + FROM tagente + WHERE id_agente = '.$id_agent + ); + + $out .= '
'; + $out .= '
'.$agent_name.'
'; + $out .= '
'; + + foreach ($rows as $row) { + if ($utimestamp > 0) { + $data_row = db_get_row_sql( + "SELECT data, timestamp + FROM tagente_datos_inventory + WHERE utimestamp <= '".$utimestamp."' + AND id_agent_module_inventory = ".$row['id_agent_module_inventory'].' ORDER BY utimestamp DESC' + ); + + if ($data_row !== false) { + $row['data'] = $data_row['data']; + $row['timestamp'] = $data_row['timestamp']; + } else { + continue; + } + } + + $table = new stdClass(); + $table->colspan = []; + if ($idModuleInventory != $row['id_module_inventory']) { + $table->width = '98%'; + $table->align = []; + $table->styleTable = 'margin:0 auto; text-align:left;'; + $table->cellpadding = 0; + $table->cellspacing = 0; + $table->class = 'databox data'; + $table->head = []; + $table->head[0] = $row['name'].' - ('.$timestamp.')'; + $table->headstyle[0] = 'text-align:center'; + + $subHeadTitles = explode(';', io_safe_output($row['data_format'])); + + $table->head_colspan = []; + $table->head_colspan[0] = (2 + count($subHeadTitles)); + $total_fields = count($subHeadTitles); + $table->rowspan = []; + + $table->data = []; + + $iterator = 0; + + foreach ($subHeadTitles as $titleData) { + $table->data[0][$iterator] = $titleData; + $iterator++; + } + + $table->data[0][] = __('Timestamp'); + $iterator++; + } + + $rowTable = 1; + + $arrayDataRowsInventory = explode(SEPARATOR_ROW, io_safe_output($row['data'])); + // SPLIT DATA IN ROWS + // Remove the empty item caused by a line ending with a new line. + $len = count($arrayDataRowsInventory); + if (end($arrayDataRowsInventory) == '') { + $len--; + unset($arrayDataRowsInventory[$len]); + } + + $iterator1 = 0; + $rowPair = true; + + foreach ($arrayDataRowsInventory as $dataRowInventory) { + if ($rowPair === true) { + $table->rowclass[$iterator] = 'rowPair'; + } else { + $table->rowclass[$iterator] = 'rowOdd'; + } + + $rowPair = !$rowPair; + $iterator++; + + // Because SQL query extract all rows (row1;row2;row3...) and only I want the row has + // the search string. + if ($inventory_search_string && preg_match('/'.io_safe_output($inventory_search_string).'/', ($dataRowInventory)) == 0) { + continue; + } + + if ($rowTable > $numRowHasNameAgent) { + $table->data[$rowTable][0] = ''; + } + + $arrayDataColumnInventory = explode(SEPARATOR_COLUMN, $dataRowInventory); + // SPLIT ROW IN COLUMNS. + $iterator2 = 0; + + foreach ($arrayDataColumnInventory as $dataColumnInventory) { + $table->data[$rowTable][$iterator2] = $dataColumnInventory; + $iterator2++; + } + + // Fill unfilled cells with empty string. + $countArrayDataColumnInventory = count($arrayDataColumnInventory); + for ($i = 0; $i < ($total_fields - $countArrayDataColumnInventory); $i++) { + $table->data[$rowTable][$iterator2] = ''; + $iterator2++; + } + + $table->data[$rowTable][$iterator2] = $row['timestamp']; + + $iterator1++; + + $rowTable++; + if ($rowPair === true) { + $table->rowclass[$rowTable] = 'rowPair'; + } else { + $table->rowclass[$rowTable] = 'rowOdd'; + } + } + + if ($iterator1 > 5) { + // PRINT COUNT TOTAL. + $table->data[$rowTable][0] = ''; + $table->data[$rowTable][1] = ''.__('Total').': '.$iterator1; + $countSubHeadTitles = count($subHeadTitles); + for ($row_i = 2; $row_i <= $countSubHeadTitles; $row_i++) { + $table->data[$rowTable][$row_i] = ''; + } + + $rowTable++; + } + + $idModuleInventory = $row['id_module_inventory']; + + if (isset($table) === true) { + $out .= html_print_table($table, true); + } + + $out .= '
'; + } + + $out .= '
'; + $out .= '
'; + $out .= '
'; + $out .= '
'; + } + + return $out; + } + + if (isset($table) === true) { + $out .= html_print_table($table, true); + $out .= ui_pagination($count, $url, $offset, 0, true); + } + + return $out; +} + + +function inventory_get_dates($module_inventory_name, $inventory_agent, $inventory_id_group) +{ + $sql = 'SELECT tagente_datos_inventory.utimestamp, + tagente_datos_inventory.timestamp + FROM tmodule_inventory, tagent_module_inventory, + tagente_datos_inventory, tagente + WHERE + tmodule_inventory.id_module_inventory = tagent_module_inventory.id_module_inventory + AND tagente_datos_inventory.id_agent_module_inventory = tagent_module_inventory.id_agent_module_inventory + AND tagente.id_agente = tagent_module_inventory.id_agente'; + + if ($inventory_agent != 0) { + $sql .= ' AND tagent_module_inventory.id_agente IN ('."'".implode(',', (array) $inventory_agent)."'".')'; + } + + if ($inventory_id_group != 0) { + $sql .= " AND tagente.id_grupo = $inventory_id_group"; + } + + if (is_string($module_inventory_name) === true + && $module_inventory_name != 'all' + ) { + $sql .= " AND tmodule_inventory.name IN ('".str_replace(',', "','", $module_inventory_name)."')"; + } + + $sql .= ' ORDER BY tagente_datos_inventory.utimestamp DESC'; + + $dates_raw = db_get_all_rows_sql($sql); + + if ($dates_raw == false) { + return []; + } + + $dates = []; + foreach ($dates_raw as $date) { + $dates[$date['utimestamp']] = $date['timestamp']; + } + + return $dates; +} + + +function inventory_get_agents($filter=false, $fields=false) +{ + $inventory_agents_id = db_get_all_rows_sql( + 'SELECT DISTINCT(id_agente) + FROM tagent_module_inventory' + ); + + if ($inventory_agents_id == false) { + $inventory_agents_id = []; + return []; + } + + $ids = []; + foreach ($inventory_agents_id as $ia) { + $ids[] = $ia['id_agente']; + } + + $filter['id_agente'] = $ids; + + $agents = agents_get_agents($filter, $fields); + + if ($agents === false) { + $agents = []; + } + + return $agents; +} + + +function inventory_get_changes( + $id_agent, + $module_names, + $start_utimestamp, + $end_utimestamp, + $return_mode=false +) { + global $config; + + $any_inventory_modules = false; + if (empty($module_names)) { + $any_inventory_modules = true; + } else if (((string) ($module_names[0])) === '0') { + $any_inventory_modules = true; + } + + $module_names = (array) $module_names; + + if ($id_agent[0] == -1) { + // Any agent + $sql = sprintf( + "SELECT evento, utimestamp + FROM tevento + WHERE utimestamp >= %d + AND utimestamp <= %d + AND event_type = 'configuration_change'", + $start_utimestamp, + $end_utimestamp + ); + } else { + $sql = sprintf( + "SELECT evento, utimestamp + FROM tevento + WHERE id_agente IN (%s) + AND utimestamp >= %d + AND utimestamp <= %d + AND event_type = 'configuration_change'", + implode(',', (array) $id_agent), + $start_utimestamp, + $end_utimestamp + ); + } + + $events = db_get_all_rows_sql($sql); + + if ($events === false) { + return ERR_NODATA; + } + + $inventory_changes = []; + $are_data = false; + + foreach ($events as $k => $event) { + $changes = io_safe_output($event['evento']); + $changes = explode("\n", $changes); + + $check = preg_match( + '/agent \'(.*)\' module \'(.*)\'/', + end($changes), + $matches + ); + + $agent_name = $matches[1]; + $module_name = $matches[2]; + + if (!$any_inventory_modules) { + if (!in_array($module_name, $module_names)) { + continue; + } + } + + $are_data = true; + + $inventory_changes[$k]['agent_name'] = $matches[1]; + $inventory_changes[$k]['module_name'] = $module_name; + $inventory_changes[$k]['utimestamp'] = $event['utimestamp']; + $changes[0] = str_replace('Configuration changes (', '', $changes[0]); + + unset($changes[(count($changes) - 1)]); + $state = ''; + foreach ($changes as $ch) { + if (preg_match('/NEW RECORD: (.*)/', $ch)) { + $ch = preg_replace('/NEW RECORD: /', '', $ch); + $ch = preg_replace('/^\'/', '', $ch); + $ch = '
'.$ch.'
'; + $state = 'new'; + } + + if (preg_match('/\s*DELETED RECORD: (.*)/', $ch)) { + $ch = preg_replace('/\s*DELETED RECORD/', '', $ch); + $ch = preg_replace('/^\'/', '', $ch); + $ch = '
'.$ch.'
'; + $state = 'deleted'; + } + + $inventory_changes[$k][$state][] = $ch; + } + } + + if ($are_data === false) { + if ($return_mode !== false) { + switch ($return_mode) { + case 'array': + return ERR_NODATA; + + break; + default: + return __('No changes found'); + break; + } + } + + return ERR_NODATA; + } + + switch ($return_mode) { + case 'csv': + $out_csv = ''; + foreach ($inventory_changes as $ic) { + $out_csv .= __('Agent').SEPARATOR_COLUMN_CSV.$ic['agent_name']."\n"; + $out_csv .= __('Module').SEPARATOR_COLUMN_CSV.$ic['module_name']."\n"; + $out_csv .= __('Date').SEPARATOR_COLUMN_CSV.date($config['date_format'], $ic['utimestamp'])."\n"; + if (isset($ic['new'])) { + foreach ($ic['new'] as $icc) { + $out_csv .= __('Added').SEPARATOR_COLUMN_CSV.$icc."\n"; + } + } + + if (isset($ic['deleted'])) { + foreach ($ic['deleted'] as $icc) { + $out_csv .= __('Deleted').SEPARATOR_COLUMN_CSV.$icc."\n"; + } + } + } + return $out_csv; + + break; + case 'array': + $out_array = []; + + foreach ($inventory_changes as $k => $ic) { + $out_array[$k]['agent'] = $ic['agent_name']; + $out_array[$k]['module'] = $ic['module_name']; + $out_array[$k]['date'] = date($config['date_format'], $ic['utimestamp']); + + if (isset($ic['new'])) { + foreach ($ic['new'] as $icc) { + $out_array[$k]['added'][] = $icc; + } + } + + if (isset($ic['deleted'])) { + foreach ($ic['deleted'] as $icc) { + $out_array[$k]['deleted'][] = $icc; + } + } + } + + if (empty($out_array)) { + return ERR_NODATA; + } + return $out_array; + + break; + } + + $out = ''; + foreach ($inventory_changes as $ic) { + $out .= ''; + } + + $out .= '
'; + + unset($table); + $table->width = '98%'; + $table->style[0] = 'text-align:50%'; + $table->style[1] = 'text-align:50%'; + + $table->data[0][0] = ''.__('Agent').': '.$ic['agent_name']; + $table->data[0][1] = ''.__('Module').': '.$ic['module_name']; + + $timestamp = date($config['date_format'], $ic['utimestamp']); + + $table->colspan[1][0] = 2; + $table->data[1][0] = '
('.$timestamp.')
'; + $row = 2; + + if (isset($ic['new'])) { + foreach ($ic['new'] as $icc) { + $table->colspan[$row][0] = 2; + $table->data[$row][0] = ''.__('Added').': '.$icc; + $row++; + } + } + + if (isset($ic['deleted'])) { + foreach ($ic['deleted'] as $icc) { + $table->colspan[$row][0] = 2; + $table->data[$row][0] = ''.__('Deleted').': '.$icc; + $row++; + } + } + + $out .= html_print_table($table, true); + + $out .= '
'; + + return $out; +} + + +/** + * Get a list with inventory modules + * + * @param mixed An integer can be place here to get a response + * to paginate. If this parameter is false, return full list + * + * @return array with inventory modules (paginated or not) + */ +function inventory_get_modules_list($offset=false) +{ + global $config; + + $filter = []; + if (is_numeric($offset)) { + $filter['limit'] = $config['block_size']; + $filter['offset'] = $offset; + } + + return db_get_all_rows_filter( + 'tmodule_inventory LEFT JOIN tconfig_os + ON tmodule_inventory.id_os = tconfig_os.id_os', + $filter, + [ + 'tmodule_inventory.id_module_inventory', + 'tmodule_inventory.name', + 'tmodule_inventory.description', + 'tmodule_inventory.interpreter', + 'tconfig_os.name AS os_name', + 'tconfig_os.id_os', + ] + ); +} + + +/** + * Validate the modules inventory + * + * @param array with inventory modules data. + * + * @return boolean True if the values are valid + */ +function inventory_validate_inventory_module($values) +{ + return !(empty($values['name']) || empty($values['id_os']) || + empty($values['data_format']) + ); +} + + +/** + * Insert the module inventory data into database + * + * @param array with inventory modules data. + * + * @return boolean False if values are invalid or cannot put it on database + */ +function inventory_create_inventory_module($values) +{ + if (!inventory_validate_inventory_module($values)) { + return false; + } + + return db_process_sql_insert('tmodule_inventory', $values); +} + + +/** + * Update the module inventory data into database + * + * @param int ID inventory module + * @param array with inventory modules data. + * + * @return boolean False if values are invalid or cannot put it on database + */ +function inventory_update_inventory_module($id_module_inventory, $values) +{ + if (!inventory_validate_inventory_module($values)) { + return false; + } + + return db_process_sql_update( + 'tmodule_inventory', + $values, + ['id_module_inventory' => $id_module_inventory] + ); +} + + +/** + * Returns inventory module names given agent id. + * + * @param integer $id_agent + * @param string $all + * @param integer $server_id + * @param string $server_name + * @return void + */ +function inventory_get_agent_modules($id_agent, $all='all', $server_id=0, $server_name=null) +{ + global $config; + + if ($config['metaconsole']) { + $server_id = metaconsole_get_id_server($server_name); + } + + switch ($all) { + default: + case 'all': + $enabled = '1 = 1'; + break; + case 'enabled': + $enabled = 'disabled = 0'; + break; + } + + if (is_array($id_agent)) { + $count_id_agent = count(($id_agent)); + $id_agent = implode(',', $id_agent); + } else { + $count_id_agent = 1; + } + + $sql = 'SELECT t1.id_module_inventory, name + FROM tmodule_inventory t1, tagent_module_inventory t2 + WHERE t1.id_module_inventory = t2.id_module_inventory + AND id_agente IN ('.$id_agent.') AND ( + SELECT count(name) + FROM tmodule_inventory t3, tagent_module_inventory t4 + WHERE t3.id_module_inventory = t4.id_module_inventory + AND t3.name = t1.name + AND t4.id_agente IN ('.$id_agent.')) = ('.$count_id_agent.') + ORDER BY name'; + + // Only in template editor from metaconsole. + if ($config['metaconsole']) { + $server_data = metaconsole_get_connection_by_id($server_id); + + if ($server_data === false) { + return ''; + } + + $modules = []; + + // Establishes connection. + if (metaconsole_load_external_db($server_data) !== NOERR) { + return ''; + } + + $modules = db_get_all_rows_sql($sql); + + if ($modules == false) { + $modules = []; + } + + $result = []; + foreach ($modules as $module) { + $result[$module['name']] = io_safe_output($module['name']); + } + + // Restore DB connection. + metaconsole_restore_db(); + } else { + $modules = db_get_all_rows_sql($sql); + + if ($modules == false) { + $modules = []; + } + + $result = []; + foreach ($modules as $module) { + $result[$module['name']] = io_safe_output($module['name']); + } + } + + return $result; +} diff --git a/pandora_console/include/functions_menu.php b/pandora_console/include/functions_menu.php index d9c86aa66a..a2e8356e3a 100644 --- a/pandora_console/include/functions_menu.php +++ b/pandora_console/include/functions_menu.php @@ -487,7 +487,7 @@ function menu_add_extras(&$menu) $menu_extra['gusuarios']['sub']['godmode/users/configure_profile']['text'] = __('Configure profile'); $menu_extra['gmodules']['sub']['godmode/modules/manage_network_templates_form']['text'] = __('Module templates management'); - $menu_extra['gmodules']['sub']['enterprise/godmode/modules/manage_inventory_modules_form']['text'] = __('Inventory modules management'); + $menu_extra['gmodules']['sub']['godmode/modules/manage_inventory_modules_form']['text'] = __('Inventory modules management'); $menu_extra['gagente']['sub']['godmode/agentes/configurar_agente']['text'] = __('Agents management'); diff --git a/pandora_console/include/functions_planned_downtimes.php b/pandora_console/include/functions_planned_downtimes.php index e8c4344c05..38ee77a422 100644 --- a/pandora_console/include/functions_planned_downtimes.php +++ b/pandora_console/include/functions_planned_downtimes.php @@ -24,7 +24,8 @@ global $config; * Include the usual functions */ require_once $config['homedir'].'/include/functions_ui.php'; -// enterprise_include_once('include/functions_inventory.php'); + + function planned_downtimes_check_dates($type_execution='once', $type_periodicity='', $datetime_from=false, $datetime_to=false, $periodically_time_from=false, $periodically_time_to=false, $periodically_day_from=false, $periodically_day_to=false) { global $config; diff --git a/pandora_console/include/functions_reporting_html.php b/pandora_console/include/functions_reporting_html.php index 03070811cf..3a1861b48b 100644 --- a/pandora_console/include/functions_reporting_html.php +++ b/pandora_console/include/functions_reporting_html.php @@ -38,6 +38,7 @@ require_once $config['homedir'].'/include/functions_alerts.php'; require_once $config['homedir'].'/include/functions_users.php'; enterprise_include_once('include/functions_metaconsole.php'); enterprise_include_once('include/functions_inventory.php'); +require_once $config['homedir'].'/include/functions_inventory.php'; require_once $config['homedir'].'/include/functions_forecast.php'; require_once $config['homedir'].'/include/functions_ui.php'; require_once $config['homedir'].'/include/functions_netflow.php'; diff --git a/pandora_console/include/functions_ui.php b/pandora_console/include/functions_ui.php index d30171eba3..7ecc5763ff 100755 --- a/pandora_console/include/functions_ui.php +++ b/pandora_console/include/functions_ui.php @@ -6783,3 +6783,259 @@ function ui_print_spinner(string $text='Loading', bool $return=false) echo $output; } } + + +function ui_get_inventory_module_add_form( + $form_action, + $form_buttons='', + $inventory_module_id=0, + $os_id=false, + $target=false, + $interval=3600, + $username='', + $password='', + $custom_fields_enabled=false, + $custom_fields=[] +) { + $table = new stdClass(); + $table->id = 'inventory-module-form'; + $table->width = '100%'; + $table->class = 'databox filters'; + $table->style['module-title'] = 'font-weight: bold;'; + $table->style['interval-title'] = 'font-weight: bold;'; + $table->style['target-title'] = 'font-weight: bold;'; + $table->style['chkbx-custom-fields-title'] = 'font-weight: bold;'; + $table->style['username-title'] = 'font-weight: bold;'; + $table->style['password-title'] = 'font-weight: bold;'; + $table->rowstyle = []; + $table->rowstyle['hidden-custom-field-row'] = 'display: none;'; + $table->colspan = []; + $table->colspan['custom-fields-row'] = []; + $table->colspan['custom-fields-row']['custom-fields-column'] = 4; + $table->data = []; + + $row = []; + $row['module-title'] = __('Module'); + if (empty($inventory_module_id)) { + if (empty($os_id)) { + $sql = 'SELECT mi.id_module_inventory AS id, mi.name AS name, co.name AS os + FROM tmodule_inventory mi, tconfig_os co + WHERE co.id_os = mi.id_os + ORDER BY co.name, mi.name'; + $inventory_modules_raw = db_get_all_rows_sql($sql); + + $inventory_modules = []; + foreach ($inventory_modules_raw as $im) { + $inventory_modules[$im['id']] = [ + 'name' => $im['name'], + 'optgroup' => $im['os'], + ]; + } + } else { + $sql = sprintf( + 'SELECT id_module_inventory AS id, name + FROM tmodule_inventory + WHERE id_os = %d + ORDER BY name', + $os_id + ); + $inventory_modules_raw = db_get_all_rows_sql($sql); + + $inventory_modules = []; + foreach ($inventory_modules_raw as $im) { + $inventory_modules[$im['id']] = $im['name']; + } + } + + $row['module-input'] = html_print_select($inventory_modules, 'id_module_inventory', 0, '', __('Select inventory module'), 0, true, false, false); + } else { + $row['module-input'] = db_get_sql('SELECT name FROM tmodule_inventory WHERE id_module_inventory = '.$inventory_module_id); + } + + $row['interval-title'] = __('Interval'); + $row['interval-input'] = html_print_extended_select_for_time('interval', $interval, '', '', '', false, true); + + $table->data['first-row'] = $row; + + $row = []; + + if ($target !== false) { + $row['target-title'] = __('Target'); + $row['target-input'] = html_print_input_text('target', $target, '', 25, 40, true); + } + + $row['chkbx-custom-fields-title'] = __('Use custom fields'); + $row['chkbx-custom-fields-input'] = html_print_checkbox('custom_fields_enabled', 1, $custom_fields_enabled, true); + + $table->data['second-row'] = $row; + + $row = []; + $row['username-title'] = __('Username'); + $row['username-input'] = html_print_input_text('username', $username, '', 25, 40, true); + $row['password-title'] = __('Password'); + $row['password-input'] = html_print_input_password('password', $password, '', 25, 40, true); + + $table->data['userpass-row'] = $row; + + $row = []; + $row['hidden-title'] = ''; + $row['hidden-input'] = html_print_input_hidden('hidden-custom-field-name', '', true); + $row['hidden-input'] .= html_print_input_hidden('hidden-custom-field-is-secure', 0, true); + $row['hidden-input'] .= html_print_input_text('hidden-custom-field-input', '', '', 25, 40, true); + $row['hidden-input'] .= ' '; + $row['hidden-input'] .= html_print_image( + 'images/cross.png', + true, + [ + 'border' => '0', + 'title' => __('Remove'), + 'style' => 'cursor: pointer;', + 'class' => 'remove-custom-field invert_filter', + ] + ); + + $table->data['hidden-custom-field-row'] = $row; + + if ($custom_fields_enabled) { + foreach ($custom_fields as $i => $field) { + $row = []; + $row['title'] = ''.$field['name'].''; + $row['input'] = html_print_input_hidden( + 'custom_fields['.$i.'][name]', + $field['name'], + true + ); + $row['input'] .= html_print_input_hidden( + 'custom_fields['.$i.'][secure]', + $field['secure'], + true + ); + if ($field['secure']) { + $row['input'] .= html_print_input_password( + 'custom_fields['.$i.'][value]', + $field['value'], + '', + 25, + 40, + true + ); + } else { + $row['input'] .= html_print_input_text( + 'custom_fields['.$i.'][value]', + $field['value'], + '', + 25, + 40, + true + ); + } + + $row['input'] .= ' '; + $row['input'] .= html_print_image( + 'images/cross.png', + true, + [ + 'border' => '0', + 'title' => __('Remove'), + 'style' => 'cursor: pointer;', + 'class' => 'remove-custom-field invert_filter', + ] + ); + + $table->data['custom-field-row-'.$i] = $row; + } + } + + $row = []; + $row['custom-fields-column'] = ''.__('Field name').''.'  '.html_print_input_text('field-name', '', '', 25, 40, true).'   '.html_print_checkbox('field-is-password', 1, false, true).__("It's a password").'   '.html_print_button(__('Add field'), 'add-field', false, '', 'class="sub add"', true); + + $table->data['custom-fields-row'] = $row; + + ob_start(); + + echo '
'; + echo html_print_table($table); + echo '
'; + echo $form_buttons; + echo '
'; + echo '
'; + + ?> + + + width = '100%'; +$table->class = 'databox filters'; +$table->size = []; +$table->data = []; + +$table->data[0][0] = __('Module'); +$table->data[0][1] = html_print_select_from_sql( + $sqlModuleInventoryAgentView, + 'module_inventory_agent_view', + $module, + 'javascript:this.form.submit();', + __('All'), + 0, + true +); + +$table->data[0][2] = __('Date'); +$table->data[0][3] = html_print_select( + $utimestampSelectValues, + 'utimestamp', + $utimestamp, + 'javascript:this.form.submit();', + __('Now'), + 0, + true +); + +$table->data[0][4] = __('Search'); +$table->data[0][5] = html_print_input_text('search_string', $search_string, '', 25, 0, true); +$table->data[0][6] = html_print_submit_button(__('Search'), 'search_button', false, 'class="sub wand"', true); + +// Show filters table. +echo sprintf( + '
%s
', + $id_agente, + html_print_table($table, true) +); + +unset($table); + +$idModuleInventory = null; +$rowTable = 1; +$printedTables = 0; + +// Inventory module data. +foreach ($rows as $row) { + if ($utimestamp > 0) { + $data_row = db_get_row_sql( + "SELECT data, timestamp + FROM tagente_datos_inventory + WHERE utimestamp <= '".$utimestamp."' + AND id_agent_module_inventory = ".$row['id_agent_module_inventory'].' + ORDER BY utimestamp DESC' + ); + if ($data_row !== false) { + $row['data'] = $data_row['data']; + $row['timestamp'] = $data_row['timestamp']; + } + } + + if ($idModuleInventory != $row['id_module_inventory']) { + if (isset($table) === true && $rowTable > 1) { + html_print_table($table); + unset($table); + $rowTable = 1; + $printedTables++; + } + + $table = new StdClass(); + $table->width = '98%'; + $table->align = []; + $table->cellpadding = 4; + $table->cellspacing = 4; + $table->class = 'databox filters'; + $table->head = []; + $table->head[0] = $row['name'].' - ('.date($config['date_format'], $row['utimestamp']).')'; + + if ((bool) $row['block_mode'] === true) { + $table->head[0] .= '   '.html_print_image( + 'images/op_inventory.menu.png', + true, + [ + 'alt' => __('Diff view'), + 'title' => __('Diff view'), + 'style' => 'vertical-align: middle; opacity: 0.8;', + ] + ).''; + } + + $subHeadTitles = explode(';', io_safe_output($row['data_format'])); + + $table->head_colspan = []; + $table->head_colspan[0] = (1 + count($subHeadTitles)); + $total_fields = count($subHeadTitles); + $table->rowspan = []; + + $table->data = []; + + $iterator = 0; + + foreach ($subHeadTitles as $titleData) { + $table->data[0][$iterator] = $titleData; + $table->cellstyle[0][$iterator] = 'background: #373737; color: #FFF;'; + + $iterator++; + } + } + + if ($row['block_mode']) { + $rowTable++; + $table->data[$rowTable][0] = '
'.$row['data'].'
'; + } else { + $arrayDataRowsInventory = explode(SEPARATOR_ROW, io_safe_output($row['data'])); + // SPLIT DATA IN ROWS + // Remove the empty item caused by a line ending with a new line. + $len = count($arrayDataRowsInventory); + if (end($arrayDataRowsInventory) == '') { + $len--; + unset($arrayDataRowsInventory[$len]); + } + + $iterator1 = 0; + $numRowHasNameAgent = $rowTable; + + $rowPair = true; + $iterator = 0; + foreach ($arrayDataRowsInventory as $dataRowInventory) { + $table->rowclass[$iterator] = ($rowPair === true) ? 'rowPair' : 'rowOdd'; + $rowPair = !$rowPair; + $iterator++; + + // Because SQL query extract all rows (row1;row2;row3...) and only I want the row has + // the search string. + if ($search_string && preg_match('/'.io_safe_output($search_string).'/i', io_safe_output($dataRowInventory)) == 0) { + continue; + } + + if ($rowTable > $numRowHasNameAgent) { + $table->data[$rowTable][0] = ''; + } + + $arrayDataColumnInventory = explode(SEPARATOR_COLUMN, $dataRowInventory); + // SPLIT ROW IN COLUMNS. + $iterator2 = 0; + foreach ($arrayDataColumnInventory as $dataColumnInventory) { + $table->data[$rowTable][$iterator2] = $dataColumnInventory; + $iterator2++; + } + + $iterator1++; + $rowTable++; + } + + if ($iterator1 > 5) { + // PRINT COUNT TOTAL. + $table->data[$rowTable][0] = ''.__('Total').': '.$iterator1; + $rowTable++; + } + } + + $idModuleInventory = $row['id_module_inventory']; +} + +if (isset($table) === true && $rowTable > 1) { + html_print_table($table); + $printedTables++; +} + +if ($printedTables === 0) { + echo "
".__('No data found.').'
'; +} diff --git a/pandora_console/operation/agentes/ver_agente.php b/pandora_console/operation/agentes/ver_agente.php index 3c4eebb991..c728cdc773 100644 --- a/pandora_console/operation/agentes/ver_agente.php +++ b/pandora_console/operation/agentes/ver_agente.php @@ -1437,8 +1437,20 @@ if ($tab === 'alert') { // Inventory. $inventoryCount = db_get_num_rows('SELECT id_agent_module_inventory FROM tagent_module_inventory WHERE id_agente = '.$agent['id_agente']); -$inventorytab = enterprise_hook('inventory_tab'); -if ($inventorytab == -1 || $inventoryCount === 0) { +$inventorytab['text'] = ''.html_print_image( + 'images/page_white_text.png', + true, + [ + 'class' => 'invert_filter', + 'title' => __('Inventory'), + ] +).''; + +if ($tab == 'inventory') { + $inventorytab['active'] = true; +} else { + $inventorytab['active'] = false; +}if ($inventorytab == -1 || $inventoryCount === 0) { $inventorytab = ''; } @@ -1968,7 +1980,7 @@ switch ($tab) { break; case 'inventory': - enterprise_include('operation/agentes/agent_inventory.php'); + include 'operation/agentes/agent_inventory.php'; break; case 'collection': diff --git a/pandora_console/operation/inventory/inventory.php b/pandora_console/operation/inventory/inventory.php new file mode 100755 index 0000000000..0a1cd508bd --- /dev/null +++ b/pandora_console/operation/inventory/inventory.php @@ -0,0 +1,551 @@ + 0) { + $sql .= ' WHERE id_grupo = '.$inventory_id_group; + } else { + $user_groups = implode(',', array_keys(users_get_groups($config['id_user']))); + + // Avoid errors if there are no groups. + if (empty($user_groups) === true) { + $user_groups = '"0"'; + } + + $sql .= ' WHERE id_grupo IN ('.$user_groups.')'; + } + + $result = db_get_all_rows_sql($sql); + if ($result !== false) { + foreach ($result as $row) { + $agents[$row['id_agente']] = $row['nombre']; + } + } + + $agents_select = $agents; + + if (strlen($inventory_agent) == 0) { + $inventory_id_agent = -1; + $inventory_agent = __('All'); + } else if ($inventory_agent == __('All')) { + $inventory_id_agent = 0; + } else { + $sql = 'SELECT id_agente + FROM tagente + WHERE nombre LIKE "'.$inventory_agent.'"'; + + $result = db_get_all_rows_sql($sql); + $inventory_id_agent = $result[0]['id_agente']; + } + + // Single agent selected. + if ($inventory_id_agent > 0 && isset($agents[$inventory_id_agent]) === true) { + $agents = [$inventory_id_agent => $agents[$inventory_id_agent]]; + } + + $agents_ids = array_keys($agents); + if (count($agents_ids) > 0) { + $inventory_data = inventory_get_data( + $agents_ids, + $inventory_module, + $utimestamp, + $inventory_search_string, + $export, + false, + $order_by_agent + ); + + if ((int) $inventory_data === ERR_NODATA) { + $inventory_data = ''; + } + } + + return; + } + + return; +} + +global $config; + +check_login(); + + +$is_metaconsole = is_metaconsole(); + +if ($is_metaconsole === true) { + open_meta_frame(); +} + +if (! check_acl($config['id_user'], 0, 'AR') && ! check_acl($config['id_user'], 0, 'AW')) { + db_pandora_audit( + AUDIT_LOG_ACL_VIOLATION, + 'Trying to access Inventory' + ); + include 'general/noaccess.php'; + return; +} + +require_once $config['homedir'].'/include/functions_users.php'; +require_once $config['homedir'].'/include/functions_inventory.php'; + +// Header. +ui_print_standard_header( + __('Inventory'), + 'images/op_inventory.png', + false, + '', + false, + [], + [ + [ + 'link' => '', + 'label' => __('Monitoring'), + ], + ] +); + +$inventory_id_agent = (int) get_parameter('agent_id', -1); +$inventory_agent = (string) get_parameter('agent', ''); +if (strlen($inventory_agent) == 0) { + $inventory_id_agent = -1; + $inventory_agent = __('All'); +} else if ($inventory_agent == __('All')) { + $inventory_id_agent = 0; +} + +$inventory_module = get_parameter('module_inventory_general_view'); +$inventory_id_group = (int) get_parameter('id_group'); +$inventory_search_string = (string) get_parameter('search_string'); +$order_by_agent = (bool) get_parameter('order_by_agent'); +$export = (string) get_parameter('export'); +$utimestamp = (int) get_parameter('utimestamp'); +$submit_filter = (bool) get_parameter('submit_filter'); + +$pagination_url_parameters = [ + 'inventory_id_agent' => $inventory_id_agent, + 'inventory_agent' => $inventory_agent, + 'inventory_id_group' => $inventory_id_group, +]; + +$noFilterSelected = false; +// Get variables. +if ($is_metaconsole === true) { + $nodes_connection = metaconsole_get_connections(); + $id_server = (int) get_parameter('id_server', 0); + $pagination_url_parameters['id_server'] = $id_server; + + if ($inventory_id_agent > 0) { + $inventory_id_server = (int) get_parameter('id_server_agent', -1); + $pagination_url_parameters['inventory_id_server'] = $inventory_id_server; + + if ($inventory_id_server !== -1) { + $id_server = $inventory_id_server; + $pagination_url_parameters['id_server'] = $id_server; + } + } + + // No filter selected. + $noFilterSelected = $inventory_id_agent === -1 && $inventory_id_group === 0 && $id_server === 0; +} + +if ($is_metaconsole === true) { + if ($id_server > 0) { + $connection = metaconsole_get_connection_by_id($id_server); + $agents_node = metaconsole_get_agents_servers($connection['server_name'], $inventory_id_group); + $node = metaconsole_get_servers($id_server); + + if (metaconsole_connect($connection) !== NOERR) { + ui_print_error_message( + __('There was a problem connecting with the node') + ); + } + + $sql = 'SELECT DISTINCT name as indexname, name + FROM tmodule_inventory, tagent_module_inventory + WHERE tmodule_inventory.id_module_inventory = tagent_module_inventory.id_module_inventory'; + if ($inventory_id_agent > 0) { + $sql .= ' AND id_agente = '.$inventory_id_agent; + } + + $result_module = db_get_all_rows_sql($sql); + if ($submit_filter === true) { + $inventory_data .= inventory_get_data( + array_keys($agents_node), + $inventory_module, + $utimestamp, + $inventory_search_string, + $export, + false, + $order_by_agent, + $node, + $pagination_url_parameters + ); + } + + // Restore db connection. + metaconsole_restore_db(); + } else { + $result_module = []; + foreach ($nodes_connection as $key => $server) { + $agents_node = metaconsole_get_agents_servers($server['server_name'], $inventory_id_group); + $connection = metaconsole_get_connection($server['server_name']); + if (metaconsole_connect($connection) !== NOERR) { + continue; + } + + $sql = 'SELECT DISTINCT name as indexname, name + FROM tmodule_inventory, tagent_module_inventory + WHERE tmodule_inventory.id_module_inventory = tagent_module_inventory.id_module_inventory'; + if ($inventory_id_agent > 0) { + $sql .= ' AND id_agente = '.$inventory_id_agent; + } + + $result = db_get_all_rows_sql($sql); + + if ($result !== false) { + $result_module = array_merge($result_module, $result); + if ($submit_filter === true) { + // Get the data. + $result_data = inventory_get_data( + array_keys($agents_node), + $inventory_module, + $utimestamp, + $inventory_search_string, + $export, + false, + $order_by_agent, + $server, + $pagination_url_parameters + ); + if ($result_data !== ERR_NODATA) { + $inventory_data .= $result_data; + } + } + } + + // Restore db connection. + metaconsole_restore_db(); + } + } + + $fields = []; + foreach ($result_module as $row) { + $id = array_shift($row); + $value = array_shift($row); + $fields[$id] = $value; + } +} + +$agent_a = (bool) check_acl($config['id_user'], 0, 'AR'); +$agent_w = (bool) check_acl($config['id_user'], 0, 'AW'); +$access = ($agent_a === true) ? 'AR' : (($agent_w === true) ? 'AW' : 'AR'); + +if (is_metaconsole() === true) { + $filteringFunction = 'active_inventory_submit()'; + ui_print_info_message(['no_close' => true, 'message' => __('You must select at least one filter.'), 'force_class' => 'select_one_filter']); + ?> + + '; + +$table = new stdClass(); +$table->width = '100%'; +$table->class = 'databox filters'; +$table->size = []; +$table->size[0] = '120px'; +$table->cellpadding = 0; +$table->cellspacing = 0; +$table->data = []; +$table->rowspan[0][4] = 2; + +if ($is_metaconsole === true) { + // Node select. + $nodes = []; + foreach ($nodes_connection as $row) { + $nodes[$row['id']] = $row['server_name']; + } + + $table->data[-1][0] = ''.__('Server').''; + $table->data[-1][1] = html_print_select($nodes, 'id_server', $id_server, $filteringFunction, __('All'), 0, true, false, true, '', false, 'min-width: 250px; max-width: 300px;'); +} + +// Group select. +$table->data[0][0] = ''.__('Group').''; + +$table->data[0][1] = '
'; +$table->data[0][1] .= html_print_select_groups( + $config['id_user'], + $access, + true, + 'id_group', + $inventory_id_group, + $filteringFunction, + '', + '1', + true, + false, + true, + '', + false +); +$table->data[0][1] .= '
'; + +// Module selected. +$table->data[0][2] = ''.__('Module').''; + +if ($is_metaconsole === true) { + $table->data[0][3] = html_print_select($fields, 'module_inventory_general_view', $inventory_module, $filteringFunction, __('All'), 0, true, false, true, '', false, 'min-width: 194px; max-width: 200px;'); +} else { + $sql = 'SELECT name as indexname, name + FROM tmodule_inventory, tagent_module_inventory + WHERE tmodule_inventory.id_module_inventory = tagent_module_inventory.id_module_inventory'; + if ($inventory_id_agent > 0) { + $sql .= ' AND id_agente = '.$inventory_id_agent; + } + + $table->data[0][3] = html_print_select_from_sql($sql, 'module_inventory_general_view', $inventory_module, '', __('All'), 'all', true, false, false); +} + + +// Button of submit. +$table->data[0][4] = html_print_submit_button(__('Search'), 'submit_filter', $noFilterSelected, "class='sub search'", true); + +// Agent select. +if ($is_metaconsole === false) { + $agents = []; + $sql = 'SELECT id_agente, nombre FROM tagente'; + if ($inventory_id_group > 0) { + $sql .= ' WHERE id_grupo = '.$inventory_id_group; + } else { + $user_groups = implode(',', array_keys(users_get_groups($config['id_user']))); + + // Avoid errors if there are no groups. + if (empty($user_groups) === true) { + $user_groups = '"0"'; + } + + $sql .= ' WHERE id_grupo IN ('.$user_groups.')'; + } + + $result = db_get_all_rows_sql($sql); + if ($result) { + foreach ($result as $row) { + $agents[$row['id_agente']] = $row['nombre']; + } + } +} + +$table->data[1][0] = ''.__('Agent').''; + +$params = []; +$params['return'] = true; +$params['show_helptip'] = true; +$params['input_name'] = 'agent'; +$params['value'] = $inventory_agent; +$params['selectbox_id'] = 'module_inventory_general_view'; +$params['javascript_is_function_select'] = true; +$params['javascript_function_action_after_select'] = 'this.form.submit'; +$params['use_hidden_input_idagent'] = true; +$params['print_hidden_input_idagent'] = true; +$params['hidden_input_idagent_id'] = 'hidden-autocomplete_id_agent'; +$params['hidden_input_idagent_name'] = 'agent_id'; +$params['hidden_input_idagent_value'] = $inventory_id_agent; +if ($is_metaconsole === true) { + $params['print_input_id_server'] = true; + $params['input_id_server_id'] = 'hidden-autocomplete_id_server'; + $params['input_id_server_name'] = 'id_server_agent'; + $params['input_id_server_value'] = $inventory_id_server; + $params['metaconsole_enabled'] = true; +} + +$table->data[1][1] = ui_print_agent_autocomplete_input($params); + +// String search_string. +$table->data[1][2] = ''.__('Search').''; +$table->data[1][3] = html_print_input_text('search_string', $inventory_search_string, '', 25, 0, true, false, false, '', '', $filteringFunction, 'off', false, $filteringFunction); + +// Date filter. In Metaconsole has not reason for show. +if (is_metaconsole() === false) { + $table->data[2][0] = ''.__('Date').''; + $dates = inventory_get_dates($inventory_module, $inventory_agent, $inventory_id_group); + $table->data[2][1] = html_print_select($dates, 'utimestamp', $utimestamp, '', __('Last'), 0, true); +} + +// Order by agent filter. +$table->data[2][2] = ''.__('Order by agent').''; + +$table->data[2][3] = html_print_checkbox('order_by_agent', 1, $order_by_agent, true, false, ''); + +html_print_table($table); + +echo ''; + +// No agent selected or no search performed. +if ($inventory_id_agent < 0 || $submit_filter === false) { + echo ' '; + + return; +} + +if ($is_metaconsole === false) { + // Single agent selected. + if ($inventory_id_agent > 0 && isset($agents[$inventory_id_agent]) === true) { + $agents = [$inventory_id_agent => $agents[$inventory_id_agent]]; + } + + $agents_ids = array_keys($agents); + if (count($agents_ids) > 0) { + $inventory_data = inventory_get_data( + $agents_ids, + $inventory_module, + $utimestamp, + $inventory_search_string, + $export, + false, + $order_by_agent, + '', + $pagination_url_parameters + ); + } + + if (count($agents_ids) === 0 || (int) $inventory_data === ERR_NODATA) { + ui_print_info_message(['no_close' => true, 'message' => __('No data found.') ]); + echo ' '; + + return; + } + + echo "'; + echo "'; + ?> + + true, 'message' => __('No data found.') ]); + } else { + echo $inventory_data; + } + + close_meta_frame(); +} + +ui_require_jquery_file('pandora.controls'); +ui_require_jquery_file('ajaxqueue'); +ui_require_jquery_file('bgiframe'); +?> + + diff --git a/pandora_console/operation/menu.php b/pandora_console/operation/menu.php index 1e3eae4c8a..49c2400088 100644 --- a/pandora_console/operation/menu.php +++ b/pandora_console/operation/menu.php @@ -73,7 +73,11 @@ if ($access_console_node === true) { $sub['view']['sub2'] = $sub2; - enterprise_hook('inventory_menu'); + if (check_acl($config['id_user'], 0, 'AR') || check_acl($config['id_user'], 0, 'AW')) { + $sub['operation/inventory/inventory']['text'] = __('Inventory'); + $sub['operation/inventory/inventory']['id'] = 'Inventory'; + $sub['operation/inventory/inventory']['refr'] = 0; + } if ($config['activate_netflow']) { $sub['network_traffic'] = [ diff --git a/pandora_server/bin/pandora_server b/pandora_server/bin/pandora_server index ce091872e2..5275829422 100755 --- a/pandora_server/bin/pandora_server +++ b/pandora_server/bin/pandora_server @@ -40,6 +40,7 @@ use PandoraFMS::WMIServer; use PandoraFMS::PluginServer; use PandoraFMS::PredictionServer; use PandoraFMS::WebServer; +use PandoraFMS::InventoryServer; # Constants for Win32 services. use constant WIN32_SERVICE_STOPPED => 0x01; @@ -157,6 +158,8 @@ sub pandora_startup () { push (@Servers, new PandoraFMS::PluginServer (\%Config, $DBH)); push (@Servers, new PandoraFMS::PredictionServer (\%Config, $DBH)); push (@Servers, new PandoraFMS::WebServer (\%Config, $DBH)); + push (@Servers, new PandoraFMS::InventoryServer (\%Config, $DBH)); + } else { # Metaconsole service modules are run by the prediction server push (@Servers, new PandoraFMS::PredictionServer (\%Config, $DBH)); diff --git a/pandora_server/lib/PandoraFMS/Core.pm b/pandora_server/lib/PandoraFMS/Core.pm index 35a8b6869a..5d01eadf67 100644 --- a/pandora_server/lib/PandoraFMS/Core.pm +++ b/pandora_server/lib/PandoraFMS/Core.pm @@ -278,6 +278,8 @@ our @EXPORT = qw( notification_set_targets notification_get_users notification_get_groups + process_inventory_data + process_inventory_module_diff ); # Some global variables @@ -4987,277 +4989,6 @@ sub process_inc_abs_data ($$$$$$) { return $diff; } -################################################################################ -################################################################################ -## Inventory XML data -################################################################################ -################################################################################ - - -################################################################################ -# Process inventory data, creating the module if necessary. -################################################################################ -sub process_inventory_data ($$$$$$$) { - my ($pa_config, $data, $server_id, $agent_name, - $interval, $timestamp, $dbh) = @_; - - foreach my $inventory (@{$data->{'inventory'}}) { - - # Process inventory modules - foreach my $module_data (@{$inventory->{'inventory_module'}}) { - - my $module_name = get_tag_value ($module_data, 'name', ''); - - # Unnamed module - next if ($module_name eq ''); - - # Process inventory data - my $data_list = ''; - foreach my $list (@{$module_data->{'datalist'}}) { - - # Empty list - next unless defined ($list->{'data'}); - - foreach my $data (@{$list->{'data'}}) { - $data_list .= $data . "\n"; - } - } - - next if ($data_list eq ''); - process_inventory_module_data ($pa_config, $data_list, $server_id, $agent_name, $module_name, $interval, $timestamp, $dbh); - } - } -} - -################################################################################ -# Process inventory module data, creating the module if necessary. -################################################################################ -sub process_inventory_module_data ($$$$$$$$) { - my ($pa_config, $data, $server_id, $agent_name, - $module_name, $interval, $timestamp, $dbh) = @_; - - logger ($pa_config, "Processing inventory module '$module_name' for agent '$agent_name'.", 10); - - # Get agent data - my $agent = get_db_single_row ($dbh, - 'SELECT * FROM tagente WHERE nombre = ?', safe_input($agent_name)); - if (! defined ($agent)) { - logger ($pa_config, "Agent '$agent_name' not found for inventory module '$module_name'.", 3); - return; - } - - # Parse the timestamp and process the module - if ($timestamp !~ /(\d+)\/(\d+)\/(\d+) +(\d+):(\d+):(\d+)/ && - $timestamp !~ /(\d+)\-(\d+)\-(\d+) +(\d+):(\d+):(\d+)/) { - logger($pa_config, "Invalid timestamp '$timestamp' from module '$module_name' agent '$agent_name'.", 3); - return; - } - my $utimestamp; - eval { - $utimestamp = strftime("%s", $6, $5, $4, $3, $2 - 1, $1 - 1900); - }; - if ($@) { - logger($pa_config, "Invalid timestamp '$timestamp' from module '$module_name' agent '$agent_name'.", 3); - return; - } - - # Get module data or create it if it does not exist - my $inventory_module = get_db_single_row ($dbh, - 'SELECT tagent_module_inventory.*, tmodule_inventory.name - FROM tagent_module_inventory, tmodule_inventory - WHERE tagent_module_inventory.id_module_inventory = tmodule_inventory.id_module_inventory - AND id_agente = ? AND name = ?', - $agent->{'id_agente'}, safe_input($module_name)); - - - - if (! defined ($inventory_module)) { - # Get the module - my $module_id = get_db_value ($dbh, - 'SELECT id_module_inventory FROM tmodule_inventory WHERE name = ? AND id_os = ?', - safe_input($module_name), $agent->{'id_os'}); - return unless defined ($module_id); - - my $id_agent_module_inventory = 0; - # Update the module data - - $id_agent_module_inventory = db_insert ($dbh, 'id_agent_module_inventory', - "INSERT INTO tagent_module_inventory (id_agente, id_module_inventory, - ${RDBMS_QUOTE}interval${RDBMS_QUOTE}, data, timestamp, utimestamp, flag) - VALUES (?, ?, ?, ?, ?, ?, ?)", - $agent->{'id_agente'}, $module_id, $interval, safe_input($data), $timestamp, $utimestamp, 0); - - - return unless ($id_agent_module_inventory > 0); - - db_do ($dbh, - 'INSERT INTO tagente_datos_inventory (id_agent_module_inventory, data, timestamp, utimestamp) - VALUES (?, ?, ?, ?)', - $id_agent_module_inventory, safe_input($data), $timestamp, $utimestamp); - - return; - } - - process_inventory_module_diff($pa_config, safe_input($data), - $inventory_module, $timestamp, $utimestamp, $dbh, $interval); -} - -################################################################################ -# Searching differences between incoming module and stored module, -# creating/updating module and event -################################################################################ -sub process_inventory_module_diff ($$$$$$;$) { - my ($pa_config, $incoming_data, $inventory_module, $timestamp, $utimestamp, $dbh, $interval) = @_; - - my $stored_data = $inventory_module->{'data'}; - my $agent_id = $inventory_module->{'id_agente'}; - my $stored_utimestamp = $inventory_module->{'utimestamp'}; - my $agent_module_inventory_id = $inventory_module->{'id_agent_module_inventory'}; - my $module_inventory_id = $inventory_module->{'id_module_inventory'}; - - - process_inventory_alerts($pa_config, $incoming_data, - $inventory_module, $timestamp, $utimestamp, $dbh, $interval); - - # If there were any changes generate an event and save the new data - if (decode('UTF-8', $stored_data) ne $incoming_data) { - my $inventory_db = $stored_data; - my $inventory_new = $incoming_data; - my @inventory = split('\n', $inventory_new); - my $diff_new = ""; - my $diff_delete = ""; - - foreach my $inv (@inventory) { - my $inv_clean = quotemeta($inv); - if($inventory_db =~ m/$inv_clean/) { - $inventory_db =~ s/$inv_clean//g; - $inventory_new =~ s/$inv_clean//g; - } - else { - $diff_new .= "$inv\n"; - } - } - - # If any register is in the stored yet, we store as deleted - $inventory_db =~ s/\n\n*/\n/g; - $inventory_db =~ s/^\n//g; - - $diff_delete = $inventory_db; - - if($diff_new ne "") { - $diff_new = " NEW: '$diff_new' "; - } - if($diff_delete ne "") { - $diff_delete = " DELETED: '$diff_delete' "; - } - - db_do ($dbh, 'INSERT INTO tagente_datos_inventory (id_agent_module_inventory, data, timestamp, utimestamp) VALUES (?, ?, ?, ?)', - $agent_module_inventory_id, $incoming_data, $timestamp, $utimestamp); - - # Do not generate an event the first time the module runs - if ($stored_utimestamp != 0) { - my $inventory_changes_blacklist = pandora_get_config_value ($dbh, 'inventory_changes_blacklist'); - my $inventory_module_blocked = 0; - - if($inventory_changes_blacklist ne "") { - foreach my $inventory_id_excluded (split (',', $inventory_changes_blacklist)) { - # If the inventory_module_id is in the blacklist, the change will not be processed - if($inventory_module->{'id_module_inventory'} == $inventory_id_excluded) { - logger ($pa_config, "Inventory change omitted on inventory #$inventory_id_excluded due be on the changes blacklist", 10); - $inventory_module_blocked = 1; - } - } - } - - # If the inventory_module_id is in the blacklist, the change will not be processed - if ($inventory_module_blocked == 0) { - my $inventory_module_name = get_db_value ($dbh, "SELECT name FROM tmodule_inventory WHERE id_module_inventory = ?", $module_inventory_id); - return unless defined ($inventory_module_name); - - my $agent_name = get_agent_name ($dbh, $agent_id); - return unless defined ($agent_name); - - my $agent_alias = get_agent_alias ($dbh, $agent_id); - return unless defined ($agent_alias); - - my $group_id = get_agent_group ($dbh, $agent_id); - - - - $stored_data =~ s/&#x20;/ /g; - $incoming_data =~ s/&#x20;/ /g; - - my @values_stored = split(' ', $stored_data); - my @finalc_stored = (); - my @values_incoming = split(' ', $incoming_data); - my @finalc_incoming = (); - my @finalc_compare_added = (); - my @finalc_compare_deleted = (); - my @finalc_compare_updated = (); - my @finalc_compare_updated_del = (); - my @finalc_compare_updated_add = (); - my $temp_compare = (); - my $final_d = ''; - my $final_a = ''; - my $final_u = ''; - - - - foreach my $i (0 .. $#values_stored) { - $finalc_stored[$i] = $values_stored[$i]; - - if ( grep $_ eq $values_stored[$i], @values_incoming ) { - - } else { - # Use 'safe_output' to avoid double encode the entities when creating the event with 'pandora_event' - $final_d .= "DELETED RECORD: ".safe_output($values_stored[$i])."\n"; - } - } - - foreach my $i (0 .. $#values_incoming) { - $finalc_incoming[$i] = $values_incoming[$i]; - - if ( grep $_ eq $values_incoming[$i], @values_stored ) { - - } else { - # Use 'safe_output' to avoid double encode the entities when creating the event with 'pandora_event' - $final_a .= "NEW RECORD: ".safe_output($values_incoming[$i])."\n"; - } - } - - # foreach my $i (0 .. $#finalc_compare_deleted) { - # $finalc_compare_updated_del[$i] = split(';', $finalc_compare_deleted[$i]); - # $finalc_compare_updated_add[$i] = split(';', $finalc_compare_added[$i]); - # if($finalc_compare_updated_del[$i] ~~ @finalc_compare_updated_add){ - # $finalc_compare_updated[$i] = $finalc_compare_updated_del[$i]; - # } - # $finalc_compare_updated[$i] =~ s/DELETED RECORD:/UPDATED RECORD:/g; - # $finalc_compare_updated[$i] =~ s/NEW RECORD://g; - # } - - - pandora_event ($pa_config, "Configuration change:\n".$final_d.$final_a." for agent '" . safe_output($agent_alias) . "' module '" . safe_output($inventory_module_name) . "'.", $group_id, $agent_id, 0, 0, 0, "configuration_change", 0, $dbh); - } - } - } - - # Update the module data - if (defined($interval)) { - db_do ($dbh, 'UPDATE tagent_module_inventory - SET'. $RDBMS_QUOTE . 'interval' . - $RDBMS_QUOTE . '=?, data=?, timestamp=?, utimestamp=? - WHERE id_agent_module_inventory=?', - $interval, $incoming_data, $timestamp, - $utimestamp, $agent_module_inventory_id); - - } - else { - db_do ($dbh, 'UPDATE tagent_module_inventory - SET data = ?, timestamp = ?, utimestamp = ? - WHERE id_agent_module_inventory = ?', - $incoming_data, $timestamp, $utimestamp, $agent_module_inventory_id); - } -} sub log4x_get_severity_num($) { my ($data_object) = @_; @@ -7400,6 +7131,278 @@ sub notification_get_groups { return @results; } +################################################################################ +################################################################################ +## Inventory XML data +################################################################################ +################################################################################ + + +################################################################################ +# Process inventory data, creating the module if necessary. +################################################################################ +sub process_inventory_data ($$$$$$$) { + my ($pa_config, $data, $server_id, $agent_name, + $interval, $timestamp, $dbh) = @_; + + foreach my $inventory (@{$data->{'inventory'}}) { + + # Process inventory modules + foreach my $module_data (@{$inventory->{'inventory_module'}}) { + + my $module_name = get_tag_value ($module_data, 'name', ''); + + # Unnamed module + next if ($module_name eq ''); + + # Process inventory data + my $data_list = ''; + foreach my $list (@{$module_data->{'datalist'}}) { + + # Empty list + next unless defined ($list->{'data'}); + + foreach my $data (@{$list->{'data'}}) { + $data_list .= $data . "\n"; + } + } + + next if ($data_list eq ''); + process_inventory_module_data ($pa_config, $data_list, $server_id, $agent_name, $module_name, $interval, $timestamp, $dbh); + } + } +} + +################################################################################ +# Process inventory module data, creating the module if necessary. +################################################################################ +sub process_inventory_module_data ($$$$$$$$) { + my ($pa_config, $data, $server_id, $agent_name, + $module_name, $interval, $timestamp, $dbh) = @_; + + logger ($pa_config, "Processing inventory module '$module_name' for agent '$agent_name'.", 10); + + # Get agent data + my $agent = get_db_single_row ($dbh, + 'SELECT * FROM tagente WHERE nombre = ?', safe_input($agent_name)); + if (! defined ($agent)) { + logger ($pa_config, "Agent '$agent_name' not found for inventory module '$module_name'.", 3); + return; + } + + # Parse the timestamp and process the module + if ($timestamp !~ /(\d+)\/(\d+)\/(\d+) +(\d+):(\d+):(\d+)/ && + $timestamp !~ /(\d+)\-(\d+)\-(\d+) +(\d+):(\d+):(\d+)/) { + logger($pa_config, "Invalid timestamp '$timestamp' from module '$module_name' agent '$agent_name'.", 3); + return; + } + my $utimestamp; + eval { + $utimestamp = strftime("%s", $6, $5, $4, $3, $2 - 1, $1 - 1900); + }; + if ($@) { + logger($pa_config, "Invalid timestamp '$timestamp' from module '$module_name' agent '$agent_name'.", 3); + return; + } + + # Get module data or create it if it does not exist + my $inventory_module = get_db_single_row ($dbh, + 'SELECT tagent_module_inventory.*, tmodule_inventory.name + FROM tagent_module_inventory, tmodule_inventory + WHERE tagent_module_inventory.id_module_inventory = tmodule_inventory.id_module_inventory + AND id_agente = ? AND name = ?', + $agent->{'id_agente'}, safe_input($module_name)); + + + + if (! defined ($inventory_module)) { + # Get the module + my $module_id = get_db_value ($dbh, + 'SELECT id_module_inventory FROM tmodule_inventory WHERE name = ? AND id_os = ?', + safe_input($module_name), $agent->{'id_os'}); + return unless defined ($module_id); + + my $id_agent_module_inventory = 0; + # Update the module data + + $id_agent_module_inventory = db_insert ($dbh, 'id_agent_module_inventory', + "INSERT INTO tagent_module_inventory (id_agente, id_module_inventory, + ${RDBMS_QUOTE}interval${RDBMS_QUOTE}, data, timestamp, utimestamp, flag) + VALUES (?, ?, ?, ?, ?, ?, ?)", + $agent->{'id_agente'}, $module_id, $interval, safe_input($data), $timestamp, $utimestamp, 0); + + + return unless ($id_agent_module_inventory > 0); + + db_do ($dbh, + 'INSERT INTO tagente_datos_inventory (id_agent_module_inventory, data, timestamp, utimestamp) + VALUES (?, ?, ?, ?)', + $id_agent_module_inventory, safe_input($data), $timestamp, $utimestamp); + + return; + } + + process_inventory_module_diff($pa_config, safe_input($data), + $inventory_module, $timestamp, $utimestamp, $dbh, $interval); +} + +################################################################################ +# Searching differences between incoming module and stored module, +# creating/updating module and event +################################################################################ +sub process_inventory_module_diff ($$$$$$;$) { + my ($pa_config, $incoming_data, $inventory_module, $timestamp, $utimestamp, $dbh, $interval) = @_; + + my $stored_data = $inventory_module->{'data'}; + my $agent_id = $inventory_module->{'id_agente'}; + my $stored_utimestamp = $inventory_module->{'utimestamp'}; + my $agent_module_inventory_id = $inventory_module->{'id_agent_module_inventory'}; + my $module_inventory_id = $inventory_module->{'id_module_inventory'}; + + + enterprise_hook('process_inventory_alerts', [$pa_config, $incoming_data, + $inventory_module, $timestamp, $utimestamp, $dbh, $interval]); + + # If there were any changes generate an event and save the new data + if (decode('UTF-8', $stored_data) ne $incoming_data) { + my $inventory_db = $stored_data; + my $inventory_new = $incoming_data; + my @inventory = split('\n', $inventory_new); + my $diff_new = ""; + my $diff_delete = ""; + + foreach my $inv (@inventory) { + my $inv_clean = quotemeta($inv); + if($inventory_db =~ m/$inv_clean/) { + $inventory_db =~ s/$inv_clean//g; + $inventory_new =~ s/$inv_clean//g; + } + else { + $diff_new .= "$inv\n"; + } + } + + # If any register is in the stored yet, we store as deleted + $inventory_db =~ s/\n\n*/\n/g; + $inventory_db =~ s/^\n//g; + + $diff_delete = $inventory_db; + + if($diff_new ne "") { + $diff_new = " NEW: '$diff_new' "; + } + if($diff_delete ne "") { + $diff_delete = " DELETED: '$diff_delete' "; + } + + db_do ($dbh, 'INSERT INTO tagente_datos_inventory (id_agent_module_inventory, data, timestamp, utimestamp) VALUES (?, ?, ?, ?)', + $agent_module_inventory_id, $incoming_data, $timestamp, $utimestamp); + + # Do not generate an event the first time the module runs + if ($stored_utimestamp != 0) { + my $inventory_changes_blacklist = pandora_get_config_value ($dbh, 'inventory_changes_blacklist'); + my $inventory_module_blocked = 0; + + if($inventory_changes_blacklist ne "") { + foreach my $inventory_id_excluded (split (',', $inventory_changes_blacklist)) { + # If the inventory_module_id is in the blacklist, the change will not be processed + if($inventory_module->{'id_module_inventory'} == $inventory_id_excluded) { + logger ($pa_config, "Inventory change omitted on inventory #$inventory_id_excluded due be on the changes blacklist", 10); + $inventory_module_blocked = 1; + } + } + } + + # If the inventory_module_id is in the blacklist, the change will not be processed + if ($inventory_module_blocked == 0) { + my $inventory_module_name = get_db_value ($dbh, "SELECT name FROM tmodule_inventory WHERE id_module_inventory = ?", $module_inventory_id); + return unless defined ($inventory_module_name); + + my $agent_name = get_agent_name ($dbh, $agent_id); + return unless defined ($agent_name); + + my $agent_alias = get_agent_alias ($dbh, $agent_id); + return unless defined ($agent_alias); + + my $group_id = get_agent_group ($dbh, $agent_id); + + + + $stored_data =~ s/&#x20;/ /g; + $incoming_data =~ s/&#x20;/ /g; + + my @values_stored = split(' ', $stored_data); + my @finalc_stored = (); + my @values_incoming = split(' ', $incoming_data); + my @finalc_incoming = (); + my @finalc_compare_added = (); + my @finalc_compare_deleted = (); + my @finalc_compare_updated = (); + my @finalc_compare_updated_del = (); + my @finalc_compare_updated_add = (); + my $temp_compare = (); + my $final_d = ''; + my $final_a = ''; + my $final_u = ''; + + + + foreach my $i (0 .. $#values_stored) { + $finalc_stored[$i] = $values_stored[$i]; + + if ( grep $_ eq $values_stored[$i], @values_incoming ) { + + } else { + # Use 'safe_output' to avoid double encode the entities when creating the event with 'pandora_event' + $final_d .= "DELETED RECORD: ".safe_output($values_stored[$i])."\n"; + } + } + + foreach my $i (0 .. $#values_incoming) { + $finalc_incoming[$i] = $values_incoming[$i]; + + if ( grep $_ eq $values_incoming[$i], @values_stored ) { + + } else { + # Use 'safe_output' to avoid double encode the entities when creating the event with 'pandora_event' + $final_a .= "NEW RECORD: ".safe_output($values_incoming[$i])."\n"; + } + } + + # foreach my $i (0 .. $#finalc_compare_deleted) { + # $finalc_compare_updated_del[$i] = split(';', $finalc_compare_deleted[$i]); + # $finalc_compare_updated_add[$i] = split(';', $finalc_compare_added[$i]); + # if($finalc_compare_updated_del[$i] ~~ @finalc_compare_updated_add){ + # $finalc_compare_updated[$i] = $finalc_compare_updated_del[$i]; + # } + # $finalc_compare_updated[$i] =~ s/DELETED RECORD:/UPDATED RECORD:/g; + # $finalc_compare_updated[$i] =~ s/NEW RECORD://g; + # } + + + pandora_event ($pa_config, "Configuration change:\n".$final_d.$final_a." for agent '" . safe_output($agent_alias) . "' module '" . safe_output($inventory_module_name) . "'.", $group_id, $agent_id, 0, 0, 0, "configuration_change", 0, $dbh); + } + } + } + + # Update the module data + if (defined($interval)) { + db_do ($dbh, 'UPDATE tagent_module_inventory + SET'. $RDBMS_QUOTE . 'interval' . + $RDBMS_QUOTE . '=?, data=?, timestamp=?, utimestamp=? + WHERE id_agent_module_inventory=?', + $interval, $incoming_data, $timestamp, + $utimestamp, $agent_module_inventory_id); + + } + else { + db_do ($dbh, 'UPDATE tagent_module_inventory + SET data = ?, timestamp = ?, utimestamp = ? + WHERE id_agent_module_inventory = ?', + $incoming_data, $timestamp, $utimestamp, $agent_module_inventory_id); + } +} + # End of function declaration # End of defined Code diff --git a/pandora_server/lib/PandoraFMS/InventoryServer.pm b/pandora_server/lib/PandoraFMS/InventoryServer.pm new file mode 100644 index 0000000000..f0c92a7fd3 --- /dev/null +++ b/pandora_server/lib/PandoraFMS/InventoryServer.pm @@ -0,0 +1,267 @@ +package PandoraFMS::InventoryServer; + +########################################################################## +# Pandora FMS Inventory Server. +########################################################################## +# Copyright (c) 2007-2021 Artica Soluciones Tecnologicas S.L +# This code is not free or OpenSource. Please don't redistribute. +########################################################################## + +use strict; +use warnings; + +use threads; +use threads::shared; +use Thread::Semaphore; + +use File::Temp qw(tempfile unlink0); +use POSIX qw(strftime); +use HTML::Entities; +use MIME::Base64; +use JSON; + +# UTF-8 flags control with I/O for multibyte characters +use open ":utf8"; + +# Default lib dir for RPM and DEB packages +BEGIN { push @INC, '/usr/lib/perl5'; } + +use PandoraFMS::Tools; +use PandoraFMS::DB; +use PandoraFMS::Core; +use PandoraFMS::ProducerConsumerServer; + +# Inherits from PandoraFMS::ProducerConsumerServer +our @ISA = qw(PandoraFMS::ProducerConsumerServer); + +# Global variables +my @TaskQueue :shared; +my %PendingTasks :shared; +my $Sem :shared; +my $TaskSem :shared; + +######################################################################################## +# Inventory Server class constructor. +######################################################################################## +sub new ($$;$) { + my ($class, $config, $dbh) = @_; + + return undef unless $config->{'inventoryserver'} == 1; + + # Initialize semaphores and queues + @TaskQueue = (); + %PendingTasks = (); + $Sem = Thread::Semaphore->new; + $TaskSem = Thread::Semaphore->new (0); + + # Call the constructor of the parent class + my $self = $class->SUPER::new($config, INVENTORYSERVER, \&PandoraFMS::InventoryServer::data_producer, \&PandoraFMS::InventoryServer::data_consumer, $dbh); + + bless $self, $class; + return $self; +} + +############################################################################### +# Run. +############################################################################### +sub run ($) { + my $self = shift; + my $pa_config = $self->getConfig (); + + print_message ($pa_config, " [*] Starting " . $pa_config->{'rb_product_name'} . " Inventory Server.", 1); + $self->setNumThreads ($pa_config->{'inventory_threads'}); + $self->SUPER::run (\@TaskQueue, \%PendingTasks, $Sem, $TaskSem); +} + +############################################################################### +# Data producer. +############################################################################### +sub data_producer ($) { + my $self = shift; + my ($pa_config, $dbh) = ($self->getConfig (), $self->getDBH ()); + + my @tasks; + my @rows; + + if (pandora_is_master($pa_config) == 0) { + if ($pa_config->{'dbengine'} ne 'oracle') { + @rows = get_db_rows ($dbh, + 'SELECT tagent_module_inventory.id_agent_module_inventory, tagent_module_inventory.flag, tagent_module_inventory.timestamp + FROM tagente, tagent_module_inventory, tmodule_inventory + WHERE tagente.server_name = ? + AND tmodule_inventory.id_module_inventory = tagent_module_inventory.id_module_inventory + AND tmodule_inventory.id_os IS NOT NULL + AND tagente.id_agente = tagent_module_inventory.id_agente + AND tagent_module_inventory.target <> \'\' + AND tagente.disabled = 0 + AND (tagent_module_inventory.timestamp = \'1970-01-01 00:00:00\' + OR UNIX_TIMESTAMP(tagent_module_inventory.timestamp) + tagent_module_inventory.interval < UNIX_TIMESTAMP() + OR tagent_module_inventory.flag = 1) + ORDER BY tagent_module_inventory.timestamp ASC', + $pa_config->{'servername'}); + } + else { + @rows = get_db_rows ($dbh, + 'SELECT tagent_module_inventory.id_agent_module_inventory, tagent_module_inventory.flag, tagent_module_inventory.timestamp + FROM tagente, tagent_module_inventory, tmodule_inventory + WHERE tagente.server_name = ? + AND tmodule_inventory.id_module_inventory = tagent_module_inventory.id_module_inventory + AND tmodule_inventory.id_os IS NOT NULL + AND tagente.id_agente = tagent_module_inventory.id_agente + AND tagent_module_inventory.target IS NOT NULL + AND tagente.disabled = 0 + AND (tagent_module_inventory.timestamp = \'1970-01-01 00:00:00\' + OR UNIX_TIMESTAMP(tagent_module_inventory.timestamp) + tagent_module_inventory.' . ${RDBMS_QUOTE} . 'interval' . ${RDBMS_QUOTE} . '< UNIX_TIMESTAMP() + OR tagent_module_inventory.flag = 1) + ORDER BY tagent_module_inventory.timestamp ASC', + $pa_config->{'servername'}); + } + } + else { + if ($pa_config->{'dbengine'} ne 'oracle') { + @rows = get_db_rows ($dbh, + 'SELECT tagent_module_inventory.id_agent_module_inventory, tagent_module_inventory.flag, tagent_module_inventory.timestamp + FROM tagente, tagent_module_inventory, tmodule_inventory + WHERE (server_name = ? OR server_name = ANY(SELECT name FROM tserver WHERE status <> 1 AND server_type = ?)) + AND tmodule_inventory.id_module_inventory = tagent_module_inventory.id_module_inventory + AND tmodule_inventory.id_os IS NOT NULL + AND tagente.id_agente = tagent_module_inventory.id_agente + AND tagent_module_inventory.target <> \'\' + AND tagente.disabled = 0 + AND (tagent_module_inventory.timestamp = \'1970-01-01 00:00:00\' + OR UNIX_TIMESTAMP(tagent_module_inventory.timestamp) + tagent_module_inventory.interval < UNIX_TIMESTAMP() + OR tagent_module_inventory.flag = 1) + ORDER BY tagent_module_inventory.timestamp ASC', + $pa_config->{'servername'}, INVENTORYSERVER); + } + else { + @rows = get_db_rows ($dbh, + 'SELECT tagent_module_inventory.id_agent_module_inventory, tagent_module_inventory.flag, tagent_module_inventory.timestamp + FROM tagente, tagent_module_inventory, tmodule_inventory + WHERE (server_name = ? OR server_name = ANY(SELECT name FROM tserver WHERE status <> 1 AND server_type = ?)) + AND tmodule_inventory.id_module_inventory = tagent_module_inventory.id_module_inventory + AND tmodule_inventory.id_os IS NOT NULL + AND tagente.id_agente = tagent_module_inventory.id_agente + AND tagent_module_inventory.target IS NOT NULL + AND tagente.disabled = 0 + AND (tagent_module_inventory.timestamp = \'1970-01-01 00:00:00\' + OR UNIX_TIMESTAMP(tagent_module_inventory.timestamp) + tagent_module_inventory.' . ${RDBMS_QUOTE} . 'interval' . ${RDBMS_QUOTE} . ' < UNIX_TIMESTAMP() + OR tagent_module_inventory.flag = 1) + ORDER BY tagent_module_inventory.timestamp ASC', + $pa_config->{'servername'}, INVENTORYSERVER); + } + } + + foreach my $row (@rows) { + + # Reset forced execution flag + if ($row->{'flag'} == 1) { + db_do ($dbh, 'UPDATE tagent_module_inventory SET flag = 0 WHERE id_agent_module_inventory = ?', $row->{'id_agent_module_inventory'}); + } + + push (@tasks, $row->{'id_agent_module_inventory'}); + } + + return @tasks; +} + +############################################################################### +# Data consumer. +############################################################################### +sub data_consumer ($$) { + my ($self, $module_id) = @_; + my ($pa_config, $dbh) = ($self->getConfig (), $self->getDBH ()); + + my $timeout = $pa_config->{'inventory_timeout'}; + + # Get inventory module data + my $module = get_db_single_row ($dbh, + 'SELECT * FROM tagent_module_inventory, tmodule_inventory + WHERE tagent_module_inventory.id_agent_module_inventory = ? + AND tagent_module_inventory.id_module_inventory = tmodule_inventory.id_module_inventory', + $module_id); + + # No code to run + return if ($module->{'interpreter'} eq ''); + + # Save script in a temporary file + my ($fh, $temp_file) = tempfile(); + $fh->print (decode_base64($module->{'code'})); + close ($fh); + set_file_permissions($pa_config, $temp_file, "0777"); + + # Run the script + my $command = $module->{'interpreter'} . ' ' . $temp_file . ' "' . $module->{'target'} . '"'; + + # Try to read the custom fields to use them as arguments into the command + if (defined($module->{'custom_fields'}) && $module->{'custom_fields'} ne '') { + my $decoded_cfields; + + eval { + $decoded_cfields = decode_json (decode_base64 ($module->{'custom_fields'})); + }; + if ($@) { + logger($pa_config, "Failed to encode received inventory data", 10); + } + + if (!defined ($decoded_cfields)) { + logger ($pa_config, "Remote inventory module ".$module->{'name'}." has failed because the custom fields can't be read", 6); + unlink ($temp_file); + return; + } + + foreach my $field (@{$decoded_cfields}) { + if ($field->{'secure'}) { + $command .= ' "' . pandora_output_password($pa_config, $field->{'value'}) . '"'; + } + else { + $command .= ' "' . $field->{'value'} . '"'; + } + } + } + # Add the default user/password arguments to the command + else { + # Initialize macros. + my %macros = ( + '_agentcustomfield_\d+_' => undef, + ); + + my $wmi_user = safe_output(subst_column_macros($module->{"username"}, \%macros, $pa_config, $dbh, undef, $module)); + my $wmi_pass = safe_output(pandora_output_password($pa_config, subst_column_macros($module->{"password"}, \%macros, $pa_config, $dbh, undef, $module))); + $command .= ' "' . $wmi_user . '" "' . $wmi_pass . '"'; + } + + logger ($pa_config, "Inventory execution command $command", 10); + my $data = `$command 2>$DEVNULL`; + + # Check for errors + if ($? != 0) { + logger ($pa_config, "Remote inventory module ".$module->{'name'}." has failed with error level $?", 6); + unlink ($temp_file); + return; + } + + unlink ($temp_file); + my $utimestamp = time (); + my $timestamp = strftime ("%Y-%m-%d %H:%M:%S", localtime ($utimestamp)); + eval { + $data = encode_entities ($data, "'<>&"); + }; + if ($@) { + logger($pa_config, "Failed to encode received inventory data", 10); + return; + } + + # Get previous data from the database + my $inventory_module = get_db_single_row ($dbh, + 'SELECT * FROM tagent_module_inventory + WHERE id_agent_module_inventory = ?', + $module_id); + return unless defined ($inventory_module); + + process_inventory_module_diff($pa_config, $data, + $inventory_module, $timestamp, $utimestamp, $dbh); +} + +1; +__END__ From 72e2b623b990d7c7f29d2fb0cf8f63049e88bde2 Mon Sep 17 00:00:00 2001 From: Calvo Date: Fri, 16 Sep 2022 11:45:03 +0200 Subject: [PATCH 03/12] Move inventory to open --- pandora_console/godmode/agentes/inventory_manager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandora_console/godmode/agentes/inventory_manager.php b/pandora_console/godmode/agentes/inventory_manager.php index b477d7e923..09336ec88b 100644 --- a/pandora_console/godmode/agentes/inventory_manager.php +++ b/pandora_console/godmode/agentes/inventory_manager.php @@ -27,7 +27,7 @@ if (! check_acl($config['id_user'], 0, 'AW')) { global $direccion_agente, $id_agente, $id_os; // include_once ($config['homedir'].'/'.ENTERPRISE_DIR.'/include/functions_policies.php'); -enterprise_include_once('include/functions_ui.php'); +require_once $config['homedir'].'/include/functions_ui.php'; // Initialize data $add_inventory_module = (boolean) get_parameter('add_inventory_module'); From b46f9c9319f7a72263d413f548b04433cd8e937b Mon Sep 17 00:00:00 2001 From: Calvo Date: Thu, 22 Dec 2022 12:47:03 +0100 Subject: [PATCH 04/12] Move inventory to open --- pandora_agents/pc/FreeBSD/pandora_agent.conf | 2 +- pandora_agents/pc/Linux/pandora_agent.conf | 2 +- pandora_agents/shellscript/linux/pandora_agent.conf | 2 +- pandora_agents/shellscript/mac_osx/pandora_agent.conf | 2 +- pandora_agents/unix/FreeBSD/pandora_agent.conf | 2 +- pandora_agents/unix/Linux/pandora_agent.conf | 2 +- pandora_agents/unix/NetBSD/pandora_agent.conf | 2 +- pandora_console/extras/delete_files/delete_files.txt | 7 +++++++ pandora_console/godmode/agentes/inventory_manager.php | 1 + .../godmode/modules/manage_inventory_modules.php | 8 +++++++- .../godmode/modules/manage_inventory_modules_form.php | 1 - pandora_server/FreeBSD/pandora_server.conf.new | 4 ++-- pandora_server/NetBSD/pandora_server.conf.new | 4 ++-- pandora_server/conf/pandora_server.conf.new | 4 ++-- pandora_server/conf/pandora_server.conf.windows | 4 ++-- 15 files changed, 30 insertions(+), 17 deletions(-) diff --git a/pandora_agents/pc/FreeBSD/pandora_agent.conf b/pandora_agents/pc/FreeBSD/pandora_agent.conf index 9e90282e7d..5c4b8d90d8 100644 --- a/pandora_agents/pc/FreeBSD/pandora_agent.conf +++ b/pandora_agents/pc/FreeBSD/pandora_agent.conf @@ -207,6 +207,6 @@ module_end module_plugin grep_log /var/log/auth.log Syslog sshd -# Plugin for inventory on the agent (Only Enterprise) +# Plugin for invenotry on the agent. # module_plugin inventory 1 cpu ram video nic hd cdrom software diff --git a/pandora_agents/pc/Linux/pandora_agent.conf b/pandora_agents/pc/Linux/pandora_agent.conf index 94491a8855..c4ae8e3a37 100644 --- a/pandora_agents/pc/Linux/pandora_agent.conf +++ b/pandora_agents/pc/Linux/pandora_agent.conf @@ -269,7 +269,7 @@ module_plugin grep_log /var/log/syslog Syslog ssh #module_description Used memory in KB postprocessed to be in MB #module_end -# Plugin for inventory on the agent (Only Enterprise) +# Plugin for invenotry on the agent. # module_plugin inventory 1 cpu ram video nic hd cdrom software init_services filesystem users process ip route diff --git a/pandora_agents/shellscript/linux/pandora_agent.conf b/pandora_agents/shellscript/linux/pandora_agent.conf index bc7dc2b2c0..fc91b88018 100644 --- a/pandora_agents/shellscript/linux/pandora_agent.conf +++ b/pandora_agents/shellscript/linux/pandora_agent.conf @@ -164,5 +164,5 @@ module_end module_plugin grep_log /var/log/syslog Syslog ssh -# Plugin for inventory on the agent (Only Enterprise) +# Plugin for invenotry on the agent. # module_plugin inventory 1 cpu ram video nic hd cdrom software diff --git a/pandora_agents/shellscript/mac_osx/pandora_agent.conf b/pandora_agents/shellscript/mac_osx/pandora_agent.conf index 7bf2d86d38..0794549fa4 100644 --- a/pandora_agents/shellscript/mac_osx/pandora_agent.conf +++ b/pandora_agents/shellscript/mac_osx/pandora_agent.conf @@ -379,6 +379,6 @@ module_end #module_plugin grep_log /var/log/syslog Syslog ssh -# Plugin for inventory on the agent (Only Enterprise) +# Plugin for invenotry on the agent. # module_plugin inventory 1 cpu ram video nic hd cdrom software diff --git a/pandora_agents/unix/FreeBSD/pandora_agent.conf b/pandora_agents/unix/FreeBSD/pandora_agent.conf index 587157ebc7..21ab70feaf 100644 --- a/pandora_agents/unix/FreeBSD/pandora_agent.conf +++ b/pandora_agents/unix/FreeBSD/pandora_agent.conf @@ -272,7 +272,7 @@ module_plugin pandora_df_free module_plugin grep_log /var/log/auth.log Syslog sshd -# Plugin for inventory on the agent (Only Enterprise) +# Plugin for invenotry on the agent. # module_plugin inventory 1 cpu ram video nic hd cdrom software init_services filesystem users route # Log collection modules. Only for enterprise version, this will collect log files for forensic analysis. diff --git a/pandora_agents/unix/Linux/pandora_agent.conf b/pandora_agents/unix/Linux/pandora_agent.conf index 48dcd5eae0..cd3e430712 100644 --- a/pandora_agents/unix/Linux/pandora_agent.conf +++ b/pandora_agents/unix/Linux/pandora_agent.conf @@ -269,7 +269,7 @@ module_plugin pandora_netusage # Service autodiscovery plugin module_plugin autodiscover --default -# Plugin for inventory on the agent (Only Enterprise) +# Plugin for invenotry on the agent. #module_plugin inventory 1 cpu ram video nic hd cdrom software init_services filesystem users route # Log collection modules. Only for enterprise version, this will collect log files for forensic analysis. diff --git a/pandora_agents/unix/NetBSD/pandora_agent.conf b/pandora_agents/unix/NetBSD/pandora_agent.conf index 7947d9d2e3..d3cf44f62a 100644 --- a/pandora_agents/unix/NetBSD/pandora_agent.conf +++ b/pandora_agents/unix/NetBSD/pandora_agent.conf @@ -232,6 +232,6 @@ module_end module_plugin grep_log /var/log/auth.log Syslog sshd -# Plugin for inventory on the agent (Only Enterprise) +# Plugin for invenotry on the agent. # module_plugin inventory 1 cpu ram video nic hd cdrom software diff --git a/pandora_console/extras/delete_files/delete_files.txt b/pandora_console/extras/delete_files/delete_files.txt index 9f37940896..b129e30635 100644 --- a/pandora_console/extras/delete_files/delete_files.txt +++ b/pandora_console/extras/delete_files/delete_files.txt @@ -1685,3 +1685,10 @@ enterprise/operation/agentes/manage_transmap.php enterprise/operation/agentes/manage_transmap_creation.php enterprise/operation/agentes/manage_transmap_creation_phases_data.php enterprise/operation/agentes/transactional_map.php +enterprise/godmode/agentes/inventory_manager.php +enterprise/operation/agentes/agent_inventory.php +enterprise/godmode/modules/manage_inventory_modules.php +enterprise/godmode/modules/manage_inventory_modules_form.php +enterprise/operation/inventory/inventory.php + + diff --git a/pandora_console/godmode/agentes/inventory_manager.php b/pandora_console/godmode/agentes/inventory_manager.php index 09336ec88b..b8d8014545 100644 --- a/pandora_console/godmode/agentes/inventory_manager.php +++ b/pandora_console/godmode/agentes/inventory_manager.php @@ -211,6 +211,7 @@ $result = db_process_sql($sql); if (db_get_num_rows($sql) == 0) { echo ' '; } else { + $table = new stdClass(); $table->width = '100%'; $table->class = 'databox filters'; $table->data = []; diff --git a/pandora_console/godmode/modules/manage_inventory_modules.php b/pandora_console/godmode/modules/manage_inventory_modules.php index 0eb4807beb..cc358ccc67 100644 --- a/pandora_console/godmode/modules/manage_inventory_modules.php +++ b/pandora_console/godmode/modules/manage_inventory_modules.php @@ -87,10 +87,12 @@ if ($id_os == 0) { } $interpreter = (string) get_parameter('interpreter'); +$script_mode = (string) get_parameter('script_mode'); $code = (string) get_parameter('code'); $code = base64_encode(str_replace("\r", '', html_entity_decode($code, ENT_QUOTES))); $format = (string) get_parameter('format'); $block_mode = (int) get_parameter('block_mode', 0); +$script_path = (string) get_parameter('script_path'); // Create inventory module. if ($create_module_inventory === true) { @@ -102,6 +104,8 @@ if ($create_module_inventory === true) { 'code' => $code, 'data_format' => $format, 'block_mode' => $block_mode, + 'script_mode' => $script_mode, + 'script_path' => $script_path, ]; $result = (bool) inventory_create_inventory_module($values); @@ -128,6 +132,8 @@ if ($create_module_inventory === true) { 'code' => $code, 'data_format' => $format, 'block_mode' => $block_mode, + 'script_mode' => $script_mode, + 'script_path' => $script_path, ]; $result = inventory_update_inventory_module($id_module_inventory, $values); @@ -289,7 +295,7 @@ if ($result === false) { $data = []; $begin = false; if ($management_allowed === true) { - $data[0] = ''.$row['name'].''; + $data[0] = ''.$row['name'].''; } else { $data[0] = ''.$row['name'].''; } diff --git a/pandora_console/godmode/modules/manage_inventory_modules_form.php b/pandora_console/godmode/modules/manage_inventory_modules_form.php index 8e151ce0b5..a955979672 100644 --- a/pandora_console/godmode/modules/manage_inventory_modules_form.php +++ b/pandora_console/godmode/modules/manage_inventory_modules_form.php @@ -153,7 +153,6 @@ $table->data[7][0] .= ui_print_help_tip(__("Here is placed the script for the RE $table->data[7][1] = html_print_textarea('code', 25, 80, base64_decode($code), '', true); - echo '
'; diff --git a/pandora_server/FreeBSD/pandora_server.conf.new b/pandora_server/FreeBSD/pandora_server.conf.new index bbd58b5cff..8127795339 100644 --- a/pandora_server/FreeBSD/pandora_server.conf.new +++ b/pandora_server/FreeBSD/pandora_server.conf.new @@ -387,11 +387,11 @@ web_threads 1 # Uncomment to perform web checks with LWP instead of CURL. #web_engine lwp -# Enable (1) or disable (0) Pandora FMS Inventory Server (PANDORA FMS ENTERPRISE ONLY). +# Enable (1) or disable (0) Pandora FMS Inventory Server. inventoryserver 1 -# Number of threads for the Web Server (PANDORA FMS ENTERPRISE ONLY). +# Number of threads for the Inventory Server. inventory_threads 1 diff --git a/pandora_server/NetBSD/pandora_server.conf.new b/pandora_server/NetBSD/pandora_server.conf.new index f5c2e79275..1a7fae6877 100644 --- a/pandora_server/NetBSD/pandora_server.conf.new +++ b/pandora_server/NetBSD/pandora_server.conf.new @@ -379,11 +379,11 @@ web_threads 1 # Uncomment to perform web checks with LWP instead of CURL. #web_engine lwp -# Enable (1) or disable (0) Pandora FMS Inventory Server (PANDORA FMS ENTERPRISE ONLY). +# Enable (1) or disable (0) Pandora FMS Inventory Server. inventoryserver 1 -# Number of threads for the Web Server (PANDORA FMS ENTERPRISE ONLY). +# Number of threads for the Inventory Server. inventory_threads 1 diff --git a/pandora_server/conf/pandora_server.conf.new b/pandora_server/conf/pandora_server.conf.new index 8332becd62..0c74e476dc 100644 --- a/pandora_server/conf/pandora_server.conf.new +++ b/pandora_server/conf/pandora_server.conf.new @@ -466,11 +466,11 @@ web_timeout 60 # Uncomment to perform web checks with LWP instead of CURL. #web_engine lwp -# Enable (1) or disable (0) Pandora FMS Inventory Server (PANDORA FMS ENTERPRISE ONLY). +# Enable (1) or disable (0) Pandora FMS Inventory Server. inventoryserver 1 -# Number of threads for the Web Server (PANDORA FMS ENTERPRISE ONLY). +# Number of threads for the Inventory Server. inventory_threads 1 diff --git a/pandora_server/conf/pandora_server.conf.windows b/pandora_server/conf/pandora_server.conf.windows index efed94ed52..0a2fcdb978 100644 --- a/pandora_server/conf/pandora_server.conf.windows +++ b/pandora_server/conf/pandora_server.conf.windows @@ -384,11 +384,11 @@ web_threads 1 # Uncomment to perform web checks with LWP instead of CURL. #web_engine lwp -# Enable (1) or disable (0) Pandora FMS Inventory Server (PANDORA FMS ENTERPRISE ONLY). +# Enable (1) or disable (0) Pandora FMS Inventory Server. inventoryserver 1 -# Number of threads for the Web Server (PANDORA FMS ENTERPRISE ONLY). +# Number of threads for the Inventory Server. inventory_threads 1 From 4b8902b605d7cd34a6c89a7e0801898b02efb149 Mon Sep 17 00:00:00 2001 From: Calvo Date: Thu, 22 Dec 2022 17:12:16 +0100 Subject: [PATCH 05/12] Fix agents conf typo --- pandora_agents/pc/FreeBSD/pandora_agent.conf | 2 +- pandora_agents/pc/Linux/pandora_agent.conf | 2 +- pandora_agents/shellscript/linux/pandora_agent.conf | 2 +- pandora_agents/shellscript/mac_osx/pandora_agent.conf | 2 +- pandora_agents/unix/FreeBSD/pandora_agent.conf | 2 +- pandora_agents/unix/Linux/pandora_agent.conf | 2 +- pandora_agents/unix/NetBSD/pandora_agent.conf | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/pandora_agents/pc/FreeBSD/pandora_agent.conf b/pandora_agents/pc/FreeBSD/pandora_agent.conf index 5c4b8d90d8..486163d697 100644 --- a/pandora_agents/pc/FreeBSD/pandora_agent.conf +++ b/pandora_agents/pc/FreeBSD/pandora_agent.conf @@ -207,6 +207,6 @@ module_end module_plugin grep_log /var/log/auth.log Syslog sshd -# Plugin for invenotry on the agent. +# Plugin for inventory on the agent. # module_plugin inventory 1 cpu ram video nic hd cdrom software diff --git a/pandora_agents/pc/Linux/pandora_agent.conf b/pandora_agents/pc/Linux/pandora_agent.conf index c4ae8e3a37..ad2d9ff756 100644 --- a/pandora_agents/pc/Linux/pandora_agent.conf +++ b/pandora_agents/pc/Linux/pandora_agent.conf @@ -269,7 +269,7 @@ module_plugin grep_log /var/log/syslog Syslog ssh #module_description Used memory in KB postprocessed to be in MB #module_end -# Plugin for invenotry on the agent. +# Plugin for inventory on the agent. # module_plugin inventory 1 cpu ram video nic hd cdrom software init_services filesystem users process ip route diff --git a/pandora_agents/shellscript/linux/pandora_agent.conf b/pandora_agents/shellscript/linux/pandora_agent.conf index fc91b88018..5fab196ef4 100644 --- a/pandora_agents/shellscript/linux/pandora_agent.conf +++ b/pandora_agents/shellscript/linux/pandora_agent.conf @@ -164,5 +164,5 @@ module_end module_plugin grep_log /var/log/syslog Syslog ssh -# Plugin for invenotry on the agent. +# Plugin for inventory on the agent. # module_plugin inventory 1 cpu ram video nic hd cdrom software diff --git a/pandora_agents/shellscript/mac_osx/pandora_agent.conf b/pandora_agents/shellscript/mac_osx/pandora_agent.conf index 0794549fa4..c3c55b7967 100644 --- a/pandora_agents/shellscript/mac_osx/pandora_agent.conf +++ b/pandora_agents/shellscript/mac_osx/pandora_agent.conf @@ -379,6 +379,6 @@ module_end #module_plugin grep_log /var/log/syslog Syslog ssh -# Plugin for invenotry on the agent. +# Plugin for inventory on the agent. # module_plugin inventory 1 cpu ram video nic hd cdrom software diff --git a/pandora_agents/unix/FreeBSD/pandora_agent.conf b/pandora_agents/unix/FreeBSD/pandora_agent.conf index 21ab70feaf..594a7a377c 100644 --- a/pandora_agents/unix/FreeBSD/pandora_agent.conf +++ b/pandora_agents/unix/FreeBSD/pandora_agent.conf @@ -272,7 +272,7 @@ module_plugin pandora_df_free module_plugin grep_log /var/log/auth.log Syslog sshd -# Plugin for invenotry on the agent. +# Plugin for inventory on the agent. # module_plugin inventory 1 cpu ram video nic hd cdrom software init_services filesystem users route # Log collection modules. Only for enterprise version, this will collect log files for forensic analysis. diff --git a/pandora_agents/unix/Linux/pandora_agent.conf b/pandora_agents/unix/Linux/pandora_agent.conf index cd3e430712..5916bba912 100644 --- a/pandora_agents/unix/Linux/pandora_agent.conf +++ b/pandora_agents/unix/Linux/pandora_agent.conf @@ -269,7 +269,7 @@ module_plugin pandora_netusage # Service autodiscovery plugin module_plugin autodiscover --default -# Plugin for invenotry on the agent. +# Plugin for inventory on the agent. #module_plugin inventory 1 cpu ram video nic hd cdrom software init_services filesystem users route # Log collection modules. Only for enterprise version, this will collect log files for forensic analysis. diff --git a/pandora_agents/unix/NetBSD/pandora_agent.conf b/pandora_agents/unix/NetBSD/pandora_agent.conf index d3cf44f62a..a5d99933a9 100644 --- a/pandora_agents/unix/NetBSD/pandora_agent.conf +++ b/pandora_agents/unix/NetBSD/pandora_agent.conf @@ -232,6 +232,6 @@ module_end module_plugin grep_log /var/log/auth.log Syslog sshd -# Plugin for invenotry on the agent. +# Plugin for inventory on the agent. # module_plugin inventory 1 cpu ram video nic hd cdrom software From fd59061800702c512c6df32a80714413b20ecb72 Mon Sep 17 00:00:00 2001 From: Calvo Date: Thu, 22 Dec 2022 17:43:49 +0100 Subject: [PATCH 06/12] Fix wrong link to inventory modules form --- pandora_console/godmode/modules/manage_inventory_modules.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandora_console/godmode/modules/manage_inventory_modules.php b/pandora_console/godmode/modules/manage_inventory_modules.php index cc358ccc67..9116c022ca 100644 --- a/pandora_console/godmode/modules/manage_inventory_modules.php +++ b/pandora_console/godmode/modules/manage_inventory_modules.php @@ -295,7 +295,7 @@ if ($result === false) { $data = []; $begin = false; if ($management_allowed === true) { - $data[0] = ''.$row['name'].''; + $data[0] = ''.$row['name'].''; } else { $data[0] = ''.$row['name'].''; } From 8f53ec448f4729a0b96280a03210906ed8dc4fd1 Mon Sep 17 00:00:00 2001 From: Calvo Date: Thu, 22 Dec 2022 17:48:37 +0100 Subject: [PATCH 07/12] Fix button delete inventory modules --- pandora_console/godmode/modules/manage_inventory_modules.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandora_console/godmode/modules/manage_inventory_modules.php b/pandora_console/godmode/modules/manage_inventory_modules.php index 9116c022ca..e81fa05cd9 100644 --- a/pandora_console/godmode/modules/manage_inventory_modules.php +++ b/pandora_console/godmode/modules/manage_inventory_modules.php @@ -151,7 +151,7 @@ if ($create_module_inventory === true) { ); // Delete inventory module. -} else if ($delete_inventory_module === true) { +} else if ((bool) $delete_inventory_module === true) { $result = db_process_sql_delete( 'tmodule_inventory', ['id_module_inventory' => $delete_inventory_module] From f8b3183ad36a9d46eb1819f5e4ac7b8f2f04ef7e Mon Sep 17 00:00:00 2001 From: Calvo Date: Tue, 27 Dec 2022 13:02:03 +0100 Subject: [PATCH 08/12] Moved inventory blacklist to open --- .../godmode/setup/setup_general.php | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/pandora_console/godmode/setup/setup_general.php b/pandora_console/godmode/setup/setup_general.php index 93a3d64a27..c5d611e59b 100644 --- a/pandora_console/godmode/setup/setup_general.php +++ b/pandora_console/godmode/setup/setup_general.php @@ -350,6 +350,87 @@ $table->data[$i++][1] = html_print_textarea( true ); +// Inventory changes blacklist. +$table->data[$i][0] = __('Inventory changes blacklist'); + +$inventory_changes_blacklist_id = get_parameter( + 'inventory_changes_blacklist', + $config['inventory_changes_blacklist'] +); + +if (!is_array($inventory_changes_blacklist_id)) { + $inventory_changes_blacklist_id = explode( + ',', + $inventory_changes_blacklist_id + ); +} + +$inventory_modules = db_get_all_rows_sql( + 'SELECT mi.id_module_inventory, mi.name module_inventory_name, os.name os_name + FROM tmodule_inventory mi, tconfig_os os + WHERE os.id_os = mi.id_os' +); + +$inventory_changes_blacklist = []; +$inventory_changes_blacklist_out = []; + +foreach ($inventory_modules as $inventory_module) { + if (in_array($inventory_module['id_module_inventory'], $inventory_changes_blacklist_id)) { + $inventory_changes_blacklist[$inventory_module['id_module_inventory']] = $inventory_module['module_inventory_name'].' ('.$inventory_module['os_name'].')'; + } else { + $inventory_changes_blacklist_out[$inventory_module['id_module_inventory']] = $inventory_module['module_inventory_name'].' ('.$inventory_module['os_name'].')'; + } +} + +$select_out = html_print_select( + $inventory_changes_blacklist_out, + 'inventory_changes_blacklist_out[]', + '', + '', + '', + '', + true, + true, + true, + '', + false, + 'width:200px' +); +$arrows = ' '; +$select_in = html_print_select( + $inventory_changes_blacklist, + 'inventory_changes_blacklist[]', + '', + '', + '', + '', + true, + true, + true, + '', + false, + 'width:200px' +); + +$table_ichanges = ' + + + + + + + + + + +
'.__('Out of black list').''.__('In black list').'
'.$select_out.' + '.html_print_image('images/darrowright.png', true, ['id' => 'right_iblacklist', 'alt' => __('Push selected modules into blacklist'), 'title' => __('Push selected modules into blacklist'), 'class' => 'invert_filter']).' +

+ '.html_print_image('images/darrowleft.png', true, ['id' => 'left_iblacklist', 'alt' => __('Pop selected modules out of blacklist'), 'title' => __('Pop selected modules out of blacklist'), 'class' => 'invert_filter']).' +
'.$select_in.'
'; + +$table->data[$i++][1] = $table_ichanges; + $table->data[$i][0] = __('Referer security'); $table->data[$i++][1] = html_print_checkbox_switch( 'referer_security', From 0e2829eca0294da4571496b4712f319308fe353a Mon Sep 17 00:00:00 2001 From: Calvo Date: Wed, 28 Dec 2022 18:28:03 +0100 Subject: [PATCH 09/12] Fix inventory blacklist js --- .../godmode/setup/setup_general.php | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/pandora_console/godmode/setup/setup_general.php b/pandora_console/godmode/setup/setup_general.php index 4d76d9f7d6..f0bbc77339 100644 --- a/pandora_console/godmode/setup/setup_general.php +++ b/pandora_console/godmode/setup/setup_general.php @@ -896,5 +896,58 @@ $(document).ready (function () { }) $('input#button-email_test').click(perform_email_test); + + $("#right_iblacklist").click (function () { + jQuery.each($("select[name='inventory_changes_blacklist_out[]'] option:selected"), function (key, value) { + imodule_name = $(value).html(); + if (imodule_name != ) { + id_imodule = $(value).attr('value'); + $("select[name='inventory_changes_blacklist[]']") + .append( + $("") + .val(id_imodule) + .html('' + imodule_name + '') + ); + $("#inventory_changes_blacklist_out") + .find("option[value='" + id_imodule + "']").remove(); + $("#inventory_changes_blacklist") + .find("option[value='']").remove(); + if($("#inventory_changes_blacklist_out option").length == 0) { + $("select[name='inventory_changes_blacklist_out[]']") + .append( + $("") + .val('') + .html('') + ); + } + } + }); + }); + $("#left_iblacklist").click (function () { + jQuery.each($("select[name='inventory_changes_blacklist[]'] option:selected"), function (key, value) { + imodule_name = $(value).html(); + if (imodule_name != ) { + id_imodule = $(value).attr('value'); + $("select[name='inventory_changes_blacklist_out[]']") + .append( + $("") + .val('') + .html('') + ); + } + } + }); + }); }); From 867749f9d3f97ed4101fa18489dad8f287ecc476 Mon Sep 17 00:00:00 2001 From: Calvo Date: Thu, 29 Dec 2022 18:14:43 +0100 Subject: [PATCH 10/12] Fix inventory blacklist open --- pandora_console/godmode/setup/setup_general.php | 6 ++++++ pandora_console/include/functions_config.php | 10 +++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/pandora_console/godmode/setup/setup_general.php b/pandora_console/godmode/setup/setup_general.php index f0bbc77339..b846b89728 100644 --- a/pandora_console/godmode/setup/setup_general.php +++ b/pandora_console/godmode/setup/setup_general.php @@ -949,5 +949,11 @@ $(document).ready (function () { } }); }); + + $("#submit-update_button").click(function () { + $('#inventory_changes_blacklist option').map(function(){ + $(this).prop('selected', true); + }); + }); }); diff --git a/pandora_console/include/functions_config.php b/pandora_console/include/functions_config.php index f7b85e5137..01a7e78ffc 100644 --- a/pandora_console/include/functions_config.php +++ b/pandora_console/include/functions_config.php @@ -395,6 +395,11 @@ function config_update_config() if (config_update_value('email_password', io_input_password(get_parameter('email_password')), true) === false) { $error_update[] = __('Email password'); } + + $inventory_changes_blacklist = get_parameter('inventory_changes_blacklist', []); + if (config_update_value('inventory_changes_blacklist', implode(',', $inventory_changes_blacklist), true) === false) { + $error_update[] = __('Inventory changes blacklist'); + } break; case 'enterprise': @@ -458,11 +463,6 @@ function config_update_config() if (config_update_value('sap_license', get_parameter('sap_license'), true) === false) { $error_update[] = __('SAP/R3 Plugin Licence'); } - - $inventory_changes_blacklist = get_parameter('inventory_changes_blacklist', []); - if (config_update_value('inventory_changes_blacklist', implode(',', $inventory_changes_blacklist), true) === false) { - $error_update[] = __('Inventory changes blacklist'); - } } break; From 19fe7ffe73b57b1712885bcf77d4f742c46dc337 Mon Sep 17 00:00:00 2001 From: Calvo Date: Fri, 30 Dec 2022 15:04:07 +0100 Subject: [PATCH 11/12] Fix minor bug --- pandora_console/godmode/setup/setup_general.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pandora_console/godmode/setup/setup_general.php b/pandora_console/godmode/setup/setup_general.php index b846b89728..db8c218708 100644 --- a/pandora_console/godmode/setup/setup_general.php +++ b/pandora_console/godmode/setup/setup_general.php @@ -924,13 +924,14 @@ $(document).ready (function () { }); }); $("#left_iblacklist").click (function () { + debugger; jQuery.each($("select[name='inventory_changes_blacklist[]'] option:selected"), function (key, value) { imodule_name = $(value).html(); if (imodule_name != ) { id_imodule = $(value).attr('value'); $("select[name='inventory_changes_blacklist_out[]']") .append( - $("") .val(id_imodule) .html('' + imodule_name + '') ); From c8bbf1e2dce2ac947f838f9615dc339f25a785db Mon Sep 17 00:00:00 2001 From: Calvo Date: Thu, 5 Jan 2023 08:56:07 +0100 Subject: [PATCH 12/12] Fix minor bug --- pandora_console/godmode/setup/setup_general.php | 1 - 1 file changed, 1 deletion(-) diff --git a/pandora_console/godmode/setup/setup_general.php b/pandora_console/godmode/setup/setup_general.php index db8c218708..fa889f3071 100644 --- a/pandora_console/godmode/setup/setup_general.php +++ b/pandora_console/godmode/setup/setup_general.php @@ -924,7 +924,6 @@ $(document).ready (function () { }); }); $("#left_iblacklist").click (function () { - debugger; jQuery.each($("select[name='inventory_changes_blacklist[]'] option:selected"), function (key, value) { imodule_name = $(value).html(); if (imodule_name != ) {