From 498a9db9973714f7e7b8ab4e71f57b4e0f07cb89 Mon Sep 17 00:00:00 2001 From: alejandro Date: Mon, 3 Oct 2022 13:33:31 +0200 Subject: [PATCH 001/181] adding new parameter check_type for define types of modules --- pandora_plugins/MySQL/pandora_mysql.pl | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/pandora_plugins/MySQL/pandora_mysql.pl b/pandora_plugins/MySQL/pandora_mysql.pl index ad9c4ebaa4..356db681e0 100644 --- a/pandora_plugins/MySQL/pandora_mysql.pl +++ b/pandora_plugins/MySQL/pandora_mysql.pl @@ -303,6 +303,10 @@ sub parse_config { if ($parametro =~ m/^check\_name\s(.*)/i) { $checks[$plugin_setup{"numchecks"}]{'check_name'} = trim($1); } + + if ($parametro =~ m/^check\_type\s(.*)/i) { + $checks[$plugin_setup{"numchecks"}]{'check_type'} = trim($1); + } if ($parametro =~ m/^check\_schema\s(.*)/i) { $checks[$plugin_setup{"numchecks"}]{'check_schema'} = trim($1); @@ -1015,6 +1019,7 @@ foreach (@checks) { my $check_show = $_->{'show'}; my $return_type = $_->{'return_type'}; my $check_name = $_->{'check_name'}; + my $check_type = $_->{'check_type'}; $result_check = 0; # Process check (System parameters) @@ -1156,7 +1161,7 @@ foreach (@checks) { print_module("MySQL_" . $type . '_' . $check_show, $module_type, $result_check, '', $check_status); } else { if (defined($check_name)) { - print_module("MySQL_" . $type . "_" . $check_name, $module_type, $result_check, '', $check_status); + print_module("MySQL_" . $type . "_" . $check_name, $check_type, $result_check, '', $check_status); } else { print_module("MySQL_" . $type, $module_type, $result_check, '', $check_status); } @@ -1186,3 +1191,4 @@ foreach (@checks) { } # type ne 'unknown' } + From 192754b95c3768294b80cfbb3bdac9fb247d085c Mon Sep 17 00:00:00 2001 From: alejandro Date: Mon, 17 Oct 2022 14:16:59 +0200 Subject: [PATCH 002/181] adding 1st version plugin google sheets --- .../google_sheets/pandora_googlesheet.py | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 pandora_plugins/google_sheets/pandora_googlesheet.py diff --git a/pandora_plugins/google_sheets/pandora_googlesheet.py b/pandora_plugins/google_sheets/pandora_googlesheet.py new file mode 100644 index 0000000000..a6e599b429 --- /dev/null +++ b/pandora_plugins/google_sheets/pandora_googlesheet.py @@ -0,0 +1,47 @@ +import gspread +import argparse +from oauth2client.service_account import ServiceAccountCredentials +from pprint import pprint + +__author__ = "Alejandro Sánchez Carrion" +__copyright__ = "Copyright 2022, PandoraFMS" +__maintainer__ = "Operations department" +__status__ = "Production" +__version__= '1.0' + +info = f""" +Pandora FMS Google Sheets +Version = {__version__} + +Manual execution + +python3 pandora_googlesheets.py --cred --row --column + +""" + +parser = argparse.ArgumentParser(description= info, formatter_class=argparse.RawTextHelpFormatter) +parser.add_argument('--cred', help='') +parser.add_argument('--name', help='') +parser.add_argument('--row', help='',type=int) +parser.add_argument('--column', help='',type=int) + +args = parser.parse_args() + +scope = ["https://spreadsheets.google.com/feeds",'https://www.googleapis.com/auth/spreadsheets',"https://www.googleapis.com/auth/drive.file","https://www.googleapis.com/auth/drive"] +creds = ServiceAccountCredentials.from_json_keyfile_name(args.cred, scope) + +client = gspread.authorize(creds) + +sheet = client.open(args.name).sheet1 # Open the spreadhseet + +data = sheet.get_all_records() # Get a list of all records + +if args.row is not None and args.column==None: + row = sheet.row_values(args.row) # Get a specific row + print(row) +elif args.row ==None and args.column is not None: + col = sheet.col_values(args.column) # Get a specific column + print(col) +elif args.row is not None and args.column is not None: + cell = sheet.cell(args.row,args.column).value # Get the value of a specific cell + print(cell) From 17d7261173e701a49423497688959653a1f3ebd2 Mon Sep 17 00:00:00 2001 From: "alejandro.campos@artica.es" Date: Thu, 20 Oct 2022 13:17:26 +0200 Subject: [PATCH 003/181] implement cluster in open project --- .../extras/delete_files/delete_files.txt | 8 + .../general/first_task/cluster_builder.php | 4 +- .../godmode/agentes/modificar_agente.php | 62 +- pandora_console/include/functions_api.php | 2 +- .../include/functions_treeview.php | 4 +- pandora_console/include/lib/Cluster.php | 906 ++++++++++++ pandora_console/include/lib/ClusterModule.php | 268 ++++ .../lib/ClusterViewer/ClusterManager.php | 767 ++++++++++ .../lib/ClusterViewer/ClusterWizard.php | 1258 +++++++++++++++++ .../operation/agentes/estado_agente.php | 8 +- pandora_console/operation/cluster/cluster.php | 70 + pandora_console/operation/menu.php | 7 +- pandora_console/views/cluster/edit.php | 129 ++ pandora_console/views/cluster/list.php | 132 ++ pandora_console/views/cluster/view.php | 453 ++++++ 15 files changed, 4034 insertions(+), 44 deletions(-) create mode 100644 pandora_console/include/lib/Cluster.php create mode 100644 pandora_console/include/lib/ClusterModule.php create mode 100644 pandora_console/include/lib/ClusterViewer/ClusterManager.php create mode 100644 pandora_console/include/lib/ClusterViewer/ClusterWizard.php create mode 100755 pandora_console/operation/cluster/cluster.php create mode 100644 pandora_console/views/cluster/edit.php create mode 100644 pandora_console/views/cluster/list.php create mode 100644 pandora_console/views/cluster/view.php diff --git a/pandora_console/extras/delete_files/delete_files.txt b/pandora_console/extras/delete_files/delete_files.txt index f9acc8ade4..d092e8629a 100644 --- a/pandora_console/extras/delete_files/delete_files.txt +++ b/pandora_console/extras/delete_files/delete_files.txt @@ -1666,3 +1666,11 @@ godmode/um_client/vendor/sebastian/object-enumerator godmode/um_client/vendor/sebastian godmode/um_client/vendor update_manager_client/resources/styles/pandora.css +enterprise/views/cluster/edit.php +enterprise/views/cluster/list.php +enterprise/views/cluster/view.php +enterprise/include/lib/Cluster.php +enterprise/include/lib/ClusterModule.php +enterprise/include/lib/ClusterViewer/ClusterManager.php +enterprise/include/lib/ClusterViewer/ClusterWizard.php +enterprise/operation/cluster/cluster.php diff --git a/pandora_console/general/first_task/cluster_builder.php b/pandora_console/general/first_task/cluster_builder.php index 3e6fe3dad4..fe14491322 100644 --- a/pandora_console/general/first_task/cluster_builder.php +++ b/pandora_console/general/first_task/cluster_builder.php @@ -68,7 +68,7 @@ ui_print_info_message(['no_close' => true, 'message' => __('There are no cluster if (check_acl($config['id_user'], 0, 'AW')) { ?> -
+
@@ -76,4 +76,4 @@ ui_print_info_message(['no_close' => true, 'message' => __('There are no cluster } ?> - \ No newline at end of file + diff --git a/pandora_console/godmode/agentes/modificar_agente.php b/pandora_console/godmode/agentes/modificar_agente.php index 3b714c277b..bc835af3d7 100644 --- a/pandora_console/godmode/agentes/modificar_agente.php +++ b/pandora_console/godmode/agentes/modificar_agente.php @@ -732,17 +732,15 @@ if ($agents !== false) { } if ($agent['id_os'] == CLUSTER_OS_ID) { - if (enterprise_installed()) { - $cluster = PandoraFMS\Enterprise\Cluster::loadFromAgentId( - $agent['id_agente'] - ); - $url = 'index.php?sec=reporting&sec2='.ENTERPRISE_DIR; - $url .= '/operation/cluster/cluster'; - $url = ui_get_full_url( - $url.'&op=update&id='.$cluster->id() - ); - echo ''.ui_print_truncate_text($agent['alias'], 'agent_medium').''; - } + $cluster = PandoraFMS\Cluster::loadFromAgentId( + $agent['id_agente'] + ); + $url = 'index.php?sec=reporting&sec2='; + $url .= '/operation/cluster/cluster'; + $url = ui_get_full_url( + $url.'&op=update&id='.$cluster->id() + ); + echo ''.ui_print_truncate_text($agent['alias'], 'agent_medium').''; } else { echo '
'; if ($check_aw) { if ($agent['id_os'] == CLUSTER_OS_ID) { - if (enterprise_installed()) { - $cluster = PandoraFMS\Enterprise\Cluster::loadFromAgentId( - $agent['id_agente'] - ); - $url = 'index.php?sec=reporting&sec2='.ENTERPRISE_DIR; - $url .= '/operation/cluster/cluster'; - $url = ui_get_full_url( - $url.'&op=update&id='.$cluster->id() - ); - echo ''.__('Edit').''; - echo ' | '; - } + $cluster = PandoraFMS\Cluster::loadFromAgentId( + $agent['id_agente'] + ); + $url = 'index.php?sec=reporting&sec2='; + $url .= '/operation/cluster/cluster'; + $url = ui_get_full_url( + $url.'&op=update&id='.$cluster->id() + ); + echo ''.__('Edit').''; + echo ' | '; } else { echo ''.__('View').''; - } + $cluster = PandoraFMS\Cluster::loadFromAgentId( + $agent['id_agente'] + ); + $url = 'index.php?sec=reporting&sec2='; + $url .= '/operation/cluster/cluster'; + $url = ui_get_full_url( + $url.'&op=view&id='.$cluster->id() + ); + echo ''.__('View').''; } else { echo 'alias().'".'; + throw new \Exception( + $msg + ); + } + + // Method searchModules returns multiple occurrences. + $module = $module[0]; + $module = $module->toArray(); + break; + } + } + + // Remove specific fields. + unset($module['id_agente_modulo']); + unset($module['id_agente']); + + return $module; + + } + + + /** + * Add an item to the cluster. + * + * @param string $name Target name. + * @param integer $type Item type. + * @param array $definition Module definition. + * + * @return ClusterModule Created module. + * @throws \Exception On error. + */ + public function addItem(string $name, int $type, array $definition) + { + $item = new ClusterModule(); + $item->name($name); + $item->id_cluster($this->id()); + + // Skel values. + $module_skel = $this->getModuleSkel($name); + + // Customize definition. + $definition = array_merge($module_skel, $definition); + + // Store in cluster agent. + $definition['id_agente'] = $this->id_agent(); + + if ($type === MODULE_PREDICTION_CLUSTER_AA) { + $item->item_type('AA'); + } else if ($type === MODULE_PREDICTION_CLUSTER_AP) { + $item->item_type('AP'); + } else { + throw new \Exception(__METHOD__.' error: Invalid item type'); + } + + // Set module definition. + $item->setModule($definition); + + // Default values. + $item->critical_limit(0); + $item->warning_limit(0); + $item->is_critical(0); + + return $item; + } + + + /** + * Add AA module to the cluster. + * + * @param string $name Target name. + * + * @return void + */ + public function addAAModule(string $name) + { + if (empty($this->aaModules[$name]) === true) { + $main_id = $this->clusterStatus->id_agente_modulo(); + + // Register module in agent. + // id_modulo = 0, + // tcp_port = 1, + // prediction_moddule = 6. + // Set thresholds while updating. + $this->aaModules[$name] = $this->addItem( + $name, + MODULE_PREDICTION_CLUSTER_AA, + [ + 'nombre' => $name, + 'id_modulo' => 0, + 'prediction_module' => 6, + 'tcp_port' => 1, + 'id_tipo_modulo' => 1, + 'custom_integer_1' => $this->id(), + 'parent_module_id' => $main_id, + ] + ); + + \db_pandora_audit( + AUDIT_LOG_AGENT_MANAGEMENT, + 'Module '.io_safe_output( + $name + ).' added to cluster'.io_safe_output( + $this->fields['name'] + ).' as Active-Active module' + ); + } + } + + + /** + * Add AP module to the cluster. + * + * @param string $name Target name. + * + * @return void + */ + public function addAPModule(string $name) + { + if (empty($this->apModules[$name]) === true) { + $main_id = $this->clusterStatus->id_agente_modulo(); + + $type = db_get_value( + 'id_tipo_modulo', + 'tagente_modulo', + 'nombre', + $name + ); + + if (empty($type) === true) { + $type = 1; + } + + // Register module in agent. + // id_modulo = 5, + // tcp_port = 1, + // prediction_moddule = 7. + // Set thresholds while updating. + $this->apModules[$name] = $this->addItem( + $name, + MODULE_PREDICTION_CLUSTER_AP, + [ + 'nombre' => $name, + 'id_modulo' => 5, + 'prediction_module' => 7, + 'tcp_port' => 1, + 'id_tipo_modulo' => $type, + 'custom_integer_1' => $this->id(), + 'parent_module_id' => $main_id, + ] + ); + + \db_pandora_audit( + AUDIT_LOG_AGENT_MANAGEMENT, + 'Module '.io_safe_output( + $name + ).' added to cluster'.io_safe_output( + $this->fields['name'] + ).' as Active-Passive module' + ); + } + } + + + /** + * Removes AA module from the cluster. + * + * @param string $name Target name. + * + * @return void + */ + public function removeAAModule(string $name) + { + if (empty($this->aaModules[$name]) === false) { + // Mark item for db elimination. + $this->removedItems[] = [ + 'id' => $this->aaModules[$name]->id(), + 'item_type' => $this->aaModules[$name]->item_type(), + ]; + $this->aaModules[$name]->delete(); + unset($this->aaModules[$name]); + } + } + + + /** + * Removes AP module from the cluster. + * + * @param string $name Target name. + * + * @return void + */ + public function removeAPModule(string $name) + { + if (empty($this->apModules[$name]) === false) { + // Mark item for db elimination. + $this->removedItems[] = [ + 'id' => $this->apModules[$name]->id(), + 'item_type' => $this->apModules[$name]->item_type(), + ]; + $this->apModules[$name]->delete(); + unset($this->apModules[$name]); + } + } + + + /** + * Return found cluster definitions. + * + * @param array $filter Conditions. + * + * @return mixed Array or false. + */ + public static function search(array $filter) + { + return \db_get_all_rows_filter( + 'tcluster', + $filter + ); + } + + + /** + * Operates with group. + * + * @param integer|null $id_group Target group to update. Retrieve group obj + * if null. + * + * @return mixed Void if set, PandoraFMS\Group if argument is null. + */ + public function group(?int $id_group=null) + { + if (is_numeric($id_group) === true && $id_group > 0) { + $this->fields['group'] = new Group($id_group); + } else { + return $this->fields['group']; + } + } + + + /** + * Returns AA modules as nodes for a map if any, if not, retrieves members. + * + * @return array Of PandoraFMS\Networkmap nodes. + */ + public function getNodes() + { + // Parse agents. + $nodes = []; + $node_count = 0; + $parent = $node_count; + $id_node = $node_count++; + $status = \agents_get_status_from_counts($this->agent()->toArray()); + $image = 'images/networkmap/'.os_get_icon($this->agent()->id_os()); + + if (empty($this->aaModules) === true) { + // No AA modules, use members. + $parent = $this->agent()->id_agente(); + + // Add node. + foreach ($this->members as $agent) { + $node = []; + + foreach ($agent->toArray() as $k => $v) { + $node[$k] = $v; + } + + $node['id_agente'] = $agent->id_agente(); + $node['id_parent'] = $parent; + $node['id_node'] = $node_count; + $node['image'] = 'images/networkmap/'.os_get_icon( + $agent->id_os() + ); + $node['status'] = \agents_get_status_from_counts( + $agent->toArray() + ); + + $nodes[$node_count++] = $node; + } + } else { + foreach ($this->aaModules as $cl_item) { + $cl_module = $cl_item->getModule(); + + if ($cl_module === null) { + continue; + } + + foreach ($this->members as $agent) { + $module = $agent->searchModules( + ['nombre' => $cl_module->nombre()] + ); + + if (empty($module) === true) { + // AA Module not found in member. + continue; + } + + // Transform multi array to get first occurrence. + // Warning. Here must only be 1 result. + $module = array_shift($module); + + $node = []; + + $node['type'] = NODE_GENERIC; + $node['label'] = $agent->alias().' » '; + $node['label'] .= $module->nombre(); + $node['id_agente'] = $module->id_agente(); + $node['id_agente_modulo'] = $module->id_agente_modulo(); + $node['id_parent'] = $parent; + $node['id_node'] = $node_count; + $node['image'] = 'images/networkmap/'.os_get_icon( + $agent->id_os() + ); + $node['status'] = $module->getStatus()->last_known_status(); + + $nodes[$node_count++] = $node; + } + } + } + + $nodes[$parent] = $this->agent()->toArray(); + $nodes[$parent] = ($nodes[$parent] + [ + 'id_parent' => $parent, + 'id_node' => $id_node, + 'status' => $status, + 'id_agente' => $this->agent()->id_agente(), + 'image' => $image, + ]); + + return $nodes; + } + + + /** + * Saves current group definition to database. + * + * @return mixed Affected rows of false in case of error. + * @throws \Exception On error. + */ + public function save() + { + $values = $this->fields; + + unset($values['agent']); + $values['group'] = $this->group()->id_grupo(); + if (isset($values['id']) === true && $values['id'] > 0) { + // Update. + $rs = \db_process_sql_update( + 'tcluster', + $values, + ['id' => $this->fields['id']] + ); + + if ($rs === false) { + global $config; + throw new \Exception( + __METHOD__.' error: '.$config['dbconnection']->error + ); + } + + \db_pandora_audit( + AUDIT_LOG_AGENT_MANAGEMENT, + 'Cluster '.io_safe_output($this->fields['name']).' modified' + ); + } else { + // New. + $rs = \db_process_sql_insert( + 'tcluster', + $values + ); + + if ($rs === false) { + global $config; + throw new \Exception( + __METHOD__.' error: '.$config['dbconnection']->error + ); + } + + $this->fields['id'] = $rs; + \db_pandora_audit( + AUDIT_LOG_AGENT_MANAGEMENT, + 'Cluster '.io_safe_output($this->fields['name']).' created' + ); + } + + $this->saveMembers(); + $this->saveItems(); + + return true; + } + + + /** + * Updates entries in tcluster_agent. + * + * @return void + * @throws \Exception On error. + */ + public function saveMembers() + { + $err = __METHOD__.' error: '; + + $values = []; + foreach ($this->members as $agent) { + $values[$agent->id_agente()] = [ + 'id_cluster' => $this->fields['id'], + 'id_agent' => $agent->id_agente(), + ]; + } + + if (empty($values) === true) { + return; + } + + // Clean previous relationships. + $rs = \db_process_sql_delete( + 'tcluster_agent', + [ 'id_cluster' => $this->fields['id'] ] + ); + + foreach ($values as $set) { + // Add current relationships. + $rs = \db_process_sql_insert( + 'tcluster_agent', + $set + ); + + if ($rs === false) { + global $config; + throw new \Exception( + $err.$config['dbconnection']->error + ); + } + } + } + + + /** + * Undocumented function + * + * @return void + */ + public function saveItems() + { + $items = $this->getItems(); + + foreach ($this->removedItems as $item) { + \db_process_sql_delete( + 'tcluster_item', + $item + ); + } + + // Save cluster modules. + foreach ($items as $item) { + $item->save(); + } + + } + + + /** + * Force cluster status module to be executed. + * + * @param boolean $get_informed Throw exception if clusterStatus is null. + * + * @return void + * @throws \Exception On error. + */ + public function force(?bool $get_informed=true) + { + if ($this->clusterStatus === null) { + if ($get_informed === true) { + throw new \Exception( + __METHOD__.' error: Cluster status module does not exist' + ); + } + } else { + $this->clusterStatus->flag(1); + $this->clusterStatus->save(); + } + } + + + /** + * Delete cluster from db. + * + * @return void + * @throws \Exception On error. + */ + public function delete() + { + global $config; + + if ($this->agent() !== null) { + // Delete agent and modules. + $this->agent()->delete(); + } + + // Remove entries from db. + // Table tcluster_agent. + $rs = \db_process_sql_delete( + 'tcluster_agent', + ['id_cluster' => $this->fields['id']] + ); + + if ($rs === false) { + throw new \Exception( + __METHOD__.' error: '.$config['dbconnection']->error + ); + } + + // Table tcluster_item. + $rs = \db_process_sql_delete( + 'tcluster_item', + ['id_cluster' => $this->fields['id']] + ); + + if ($rs === false) { + throw new \Exception( + __METHOD__.' error: '.$config['dbconnection']->error + ); + } + + // Table tcluster. + $rs = \db_process_sql_delete( + 'tcluster', + ['id' => $this->fields['id']] + ); + + if ($rs === false) { + throw new \Exception( + __METHOD__.' error: '.$config['dbconnection']->error + ); + } + + \db_pandora_audit( + AUDIT_LOG_AGENT_MANAGEMENT, + 'Cluster '.io_safe_output($this->fields['name']).' deleted' + ); + + unset($this->aaModules); + unset($this->apModules); + unset($this->fields); + + } + + +} diff --git a/pandora_console/include/lib/ClusterModule.php b/pandora_console/include/lib/ClusterModule.php new file mode 100644 index 0000000000..19e25e6a5d --- /dev/null +++ b/pandora_console/include/lib/ClusterModule.php @@ -0,0 +1,268 @@ + 0) { + try { + parent::__construct('tcluster_item', ['id' => $id]); + } catch (\Exception $e) { + throw new \Exception('ClusterModule id not found.'); + } + + // Get module. + $this->module = Module::search( + [ + 'nombre' => $this->name(), + 'custom_integer_1' => $this->id_cluster(), + ], + 1 + ); + } else { + parent::__construct('tcluster_item'); + + $this->module = new Module(); + } + + } + + + /** + * Returns current object as array. + * + * @return array Of fields. + */ + public function toArray() + { + return $this->fields; + } + + + /** + * Associates a module to this clusterModule. + * + * @param array $params Module parameters. + * + * @return void + */ + public function setModule(array $params) + { + $this->module = new Module(); + foreach ($params as $k => $v) { + $this->module->{$k}($v); + } + } + + + /** + * Associates a module to this clusterModule. + * + * @param PandoraFMS\Module $module Module definition. + * + * @return void + */ + public function setModuleObject(Module $module) + { + $this->module = $module; + } + + + /** + * Returns current module. + * + * @return PandoraFMS\Module Object. + */ + public function getModule() + { + return $this->module; + } + + + /** + * Saves or retrieves value of warning_limit. + * + * @param float|null $value Warning value. + * + * @return mixed Value or empty. + */ + public function warning_limit(?float $value=null) + { + if ($value !== null) { + $this->fields['warning_limit'] = $value; + if ($this->module !== null) { + $this->module->min_warning($value); + } + } else { + return $this->fields['warning_limit']; + } + } + + + /** + * Saves or retrieves value of critical_limit. + * + * @param float|null $value Critical value. + * + * @return mixed Value or empty. + */ + public function critical_limit(?float $value=null) + { + if ($value !== null) { + $this->fields['critical_limit'] = $value; + if ($this->module !== null) { + $this->module->min_critical($value); + } + } else { + return $this->fields['critical_limit']; + } + } + + + /** + * Save ClusterModule. + * + * @return boolean True if success, false if error. + * @throws \Exception On db error. + */ + public function save() + { + $values = $this->fields; + + if ($this->module === null) { + return false; + } + + if (method_exists($this->module, 'save') === false) { + throw new \Exception( + __METHOD__.' error: Cluster module "'.$this->name().'" invalid.' + ); + } + + if (isset($values['id']) === true && $values['id'] > 0) { + // Update. + $rs = \db_process_sql_update( + 'tcluster_item', + $values, + ['id' => $this->fields['id']] + ); + + if ($rs === false) { + global $config; + throw new \Exception( + __METHOD__.' error: '.$config['dbconnection']->error + ); + } + + if ($this->module === null) { + throw new \Exception( + __METHOD__.' error: Cluster module "'.$this->name().'" is not defined' + ); + } + + // Update reference. + $this->module->custom_integer_2($this->fields['id']); + + // Update module. + $this->module->save(); + + return true; + } else { + // New. + $rs = \db_process_sql_insert( + 'tcluster_item', + $values + ); + + if ($rs === false) { + global $config; + throw new \Exception( + __METHOD__.' error: '.$config['dbconnection']->error + ); + } + + $this->fields['id'] = $rs; + + // Update reference. + $this->module->custom_integer_2($this->fields['id']); + + // Update module. + $this->module->save(); + + return true; + } + + return false; + } + + + /** + * Erases this object and its module. + * + * @return void + */ + public function delete() + { + if (method_exists($this->module, 'delete') === true) { + $this->module->delete(); + } + + unset($this->fields); + unset($this->module); + + } + + +} diff --git a/pandora_console/include/lib/ClusterViewer/ClusterManager.php b/pandora_console/include/lib/ClusterViewer/ClusterManager.php new file mode 100644 index 0000000000..884be3f2a7 --- /dev/null +++ b/pandora_console/include/lib/ClusterViewer/ClusterManager.php @@ -0,0 +1,767 @@ + 'noaccess']); + } else { + include 'general/noaccess.php'; + } + + exit; + } + + $this->ajaxController = $ajax_page; + $this->url = $url; + + } + + + /** + * Main program starts here. + * + * @return void + */ + public function run() + { + + $operation = get_parameter('op', ''); + + switch ($operation) { + case 'new': + case 'update': + $this->showClusterEditor($operation); + break; + + case 'view': + $this->showCluster(); + break; + + case 'delete': + $this->deleteCluster(); + break; + + case 'force': + $this->forceCluster(); + break; + + default: + $n_clusters = $this->getCount(); + + if ($n_clusters > 0) { + $this->showList(); + } else { + $this->showWelcome(); + } + break; + } + } + + + /** + * Prints error message + * + * @param string $msg Message. + * + * @return void + */ + public function error(string $msg) + { + if (is_ajax()) { + echo json_encode( + ['error' => $msg] + ); + } else { + ui_print_error_message($msg); + } + } + + + /** + * Loads view 'first tasks' for cluster view. + * Old style. + * + * @return void + */ + public function showWelcome() + { + global $config; + include_once $config['homedir'].'/general/first_task/cluster_builder.php'; + } + + + /** + * Prepares available clusters definition for current users and loads view. + * + * @param string|null $msg Message (if any). + * + * @return void + */ + public function showList(?string $msg='') + { + global $config; + + // Extract data. + $n_clusters = $this->getCount(); + + if ($n_clusters > 0) { + $clusters = $this->getAll(); + } else { + $clusters = []; + } + + View::render( + 'cluster/list', + [ + 'message' => $msg, + 'config' => $config, + 'model' => $this, + 'n_clusters' => $n_clusters, + 'clusters' => $clusters, + ] + ); + } + + + /** + * Show cluster information. + * + * @param string|null $msg Message (if any). + * + * @return void + */ + public function showCluster(?string $msg=null) + { + global $config; + + $err = ''; + $id = get_parameter('id', null); + + try { + $cluster = new Cluster($id); + } catch (\Exception $e) { + $err = ui_print_error_message( + __('Cluster not found: '.$e->getMessage()), + '', + true + ); + } + + if ($cluster->agent()->id_agente() === null) { + // Failed. + $err = ui_print_error_message( + __('Cluster agent not found: '), + '', + true + ); + $critical = true; + } + + View::render( + 'cluster/view', + [ + 'message' => $msg, + 'error' => $err, + 'config' => $config, + 'model' => $this, + 'cluster' => $cluster, + 'critical' => $critical, + ] + ); + } + + + /** + * Removes a cluster from db. + * + * @return void + */ + public function deleteCluster() + { + $msg = ''; + $id = get_parameter('id', null); + + try { + $cluster = new Cluster($id); + $cluster->delete(); + unset($cluster); + } catch (\Exception $e) { + $msg = ui_print_error_message( + __('Error while deleting, reason: %s', $e->getMessage()), + '', + true + ); + } + + if (empty($msg) === true) { + $msg = ui_print_success_message( + __('Cluster successfully deleted.'), + '', + true + ); + } + + $this->showList($msg); + } + + + /** + * Force cluster execution. + * + * @return void + */ + public function forceCluster() + { + $msg = ''; + $id = get_parameter('id', null); + + try { + $cluster = new Cluster($id); + $cluster->force(); + unset($cluster); + } catch (\Exception $e) { + $msg = ui_print_error_message( + __('Error while forcing, reason: %s', $e->getMessage()), + '', + true + ); + } + + if (empty($msg) === true) { + $msg = ui_print_success_message( + __('Cluster successfully forced.'), + '', + true + ); + } + + $this->showCluster($msg); + } + + + /** + * Shows editor for target cluster (or new one). + * + * @param string $operation Current operation. + * + * @return void + */ + public function showClusterEditor(string $operation) + { + + global $config; + if (!check_acl($config['id_user'], 0, 'AW')) { + + db_pandora_audit( + AUDIT_LOG_ACL_VIOLATION, + 'Trying to create clusters' + ); + include 'general/noaccess.php'; + } else { + $wizard = new ClusterWizard( + $this->url, + $operation + ); + + $wizard->run(); + } + } + + + /** + * Returns number of clusters registered. + * + * @return integer + */ + public function getCount() + { + if (isset($this->count) !== true) { + $this->count = $this->getAll('count'); + } + + return $this->count; + } + + + /** + * Return all cluster definitons matching given filters. + * + * @param mixed $fields Fields array or 'count' keyword to retrieve + * count, null or default to use default ones. + * @param array $filter Filters to be applied. + * @param integer $offset Offset (pagination). + * @param integer $limit Limit (pagination). + * @param string $order Sort order. + * @param string $sort_field Sort field. + * + * @return array With all results or false if error. + * @throws \Exception On error. + */ + public static function getAll( + $fields=null, + array $filter=[], + ?int $offset=null, + ?int $limit=null, + ?string $order=null, + ?string $sort_field=null + ) { + $sql_filters = []; + $order_by = ''; + $pagination = ''; + + global $config; + + if (is_array($filter) === false) { + throw new \Exception('[ClusterManager::getAll] Filter must be an array.'); + } + + if (empty($filter['id_group']) === false + && (int) $filter['id_group'] !== 0 + ) { + $sql_filters[] = sprintf( + ' AND tc.`group` = %d', + $filter['id_group'] + ); + } + + if (empty($filter['free_search']) === false) { + $topic = io_safe_input($filter['free_search']); + $sql_filters[] = sprintf( + ' AND (lower(tc.name) like lower("%%%s%%") + OR lower(tc.description) like lower("%%%s%%") ) ', + $topic, + $topic + ); + } + + $count = false; + if (is_array($fields) === false && $fields === 'count') { + $fields = ['tc.*']; + $count = true; + } else if (is_array($fields) === false) { + // Default values. + $fields = [ + 'tc.*', + '(SELECT COUNT(*) FROM `tcluster_agent` WHERE `id_cluster` = tc.`id`) as `nodes`', + 'tas.known_status', + ]; + } + + if (isset($order) === true) { + $dir = 'asc'; + if ($order === 'desc') { + $dir = 'desc'; + }; + + if ($sort_field === 'type') { + $sort_field = 'cluster_type'; + } + + if (in_array( + $sort_field, + [ + 'name', + 'description', + 'group', + 'cluster_type', + 'nodes', + 'known_status', + ] + ) === true + ) { + $order_by = sprintf( + 'ORDER BY `%s` %s', + $sort_field, + $dir + ); + } + } + + if (isset($limit) === true && $limit > 0 + && isset($offset) === true && $offset >= 0 + ) { + $pagination = sprintf( + ' LIMIT %d OFFSET %d ', + $limit, + $offset + ); + } + + $sql = sprintf( + 'SELECT %s + FROM tcluster tc + LEFT JOIN tagente ta + ON tc.id_agent = ta.id_agente + LEFT JOIN tagente_modulo tam + ON tam.id_agente = tc.id_agent + AND tam.nombre = "%s" + LEFT JOIN tagente_estado tas + ON tam.id_agente_modulo=tas.id_agente_modulo + WHERE 1=1 + %s + %s + %s', + join(',', $fields), + io_safe_input('Cluster status'), + join(' ', $sql_filters), + $order_by, + $pagination + ); + + if ($count === true) { + $sql = sprintf('SELECT count(*) as n FROM ( %s ) tt', $sql); + + // Counter.. All data. + return db_get_value_sql($sql); + } + + return db_get_all_rows_sql($sql); + + } + + + /** + * Return data for datatables painting. + * + * @return void + * @throws \Exception On Error. + */ + public function draw() + { + global $config; + + // Datatables offset, limit and order. + $filter = get_parameter('filter', []); + $start = get_parameter('start', 0); + $length = get_parameter('length', $config['block_size']); + $order = get_datatable_order(true); + try { + ob_start(); + + $fields = [ + 'tc.*', + '(SELECT COUNT(*) FROM `tcluster_agent` WHERE `id_cluster` = tc.`id`) as `nodes`', + 'tas.known_status', + ]; + + // Retrieve data. + $data = self::getAll( + // Fields. + $fields, + // Filter. + $filter, + // Offset. + $start, + // Limit. + $length, + // Order. + $order['direction'], + // Sort field. + $order['field'] + ); + + // Retrieve counter. + $count = self::getAll( + 'count', + $filter + ); + + if ($data) { + $data = array_reduce( + $data, + function ($carry, $item) { + global $config; + // Transforms array of arrays $data into an array + // of objects, making a post-process of certain fields. + $tmp = (object) $item; + + $manage = check_acl( + $config['id_user'], + $tmp->group, + 'AW', + true + ); + + $tmp->name = ''.$tmp->name.''; + + if (empty($tmp->group) === true) { + $tmp->group = __('Not set'); + } else { + $tmp->group = ui_print_group_icon( + $tmp->group, + true + ); + } + + // Type. + if ($tmp->cluster_type === 'AA') { + $tmp->type = __('Active-Active'); + } else if ($tmp->cluster_type === 'AP') { + $tmp->type = __('Active-Passive'); + } else { + $tmp->type = __('Unknown'); + } + + // Status. + $tmp->known_status = ui_print_module_status( + $tmp->known_status, + true + ); + + // Options. View. + $tmp->options = ''; + $tmp->options .= html_print_image( + 'images/operation.png', + true, + [ + 'title' => __('View'), + 'class' => 'invert_filter', + ] + ); + $tmp->options .= ''; + + if ($manage) { + // Options. Edit. + $tmp->options .= ''; + $tmp->options .= html_print_image( + 'images/config.png', + true, + [ + 'title' => __('Edit'), + 'class' => 'invert_filter', + ] + ); + $tmp->options .= ''; + + // Options. Delete. + $tmp->options .= ''; + $tmp->options .= html_print_image( + 'images/cross.png', + true, + [ + 'title' => __('Delete'), + 'class' => 'invert_filter', + ] + ); + $tmp->options .= ''; + } + + $carry[] = $tmp; + return $carry; + } + ); + } + + // Datatables format: RecordsTotal && recordsfiltered. + echo json_encode( + [ + 'data' => $data, + 'recordsTotal' => $count, + 'recordsFiltered' => $count, + ] + ); + // Capture output. + $response = ob_get_clean(); + } catch (\Exception $e) { + echo json_encode(['error' => $e->getMessage()]); + exit; + } + + // If not valid, show error with issue. + json_decode($response); + if (json_last_error() == JSON_ERROR_NONE) { + // If valid dump. + echo $response; + } else { + echo json_encode( + ['error' => $response] + ); + } + } + + + /** + * Provides data for wizard. Ajax method. + * + * @return void + */ + public function getAgentsFromGroup() + { + $side = get_parameter('side', null); + $id = get_parameter('id', null); + $group_id = get_parameter('group_id', 0); + $group_recursion = (bool) get_parameter('group_recursion', 0); + + $groups = []; + if ($group_recursion === true) { + $groups = groups_get_children_ids($group_id, true); + } else { + $groups = $group_id; + } + + if ($side === 'left') { + // Available agents. + $agents = agents_get_agents( + [ 'id_grupo' => $groups ], + [ + 'id_agente', + 'alias', + ] + ); + + $agents = array_reduce( + $agents, + function ($carry, $item) { + $carry[$item['id_agente']] = io_safe_output($item['alias']); + return $carry; + } + ); + } else if ($side === 'right') { + // Selected agents. + $cluster = new Cluster($id); + $agents = $cluster->getMembers(); + $agents = array_reduce( + $agents, + function ($carry, $item) use ($groups) { + if (in_array($item->id_grupo(), $groups) === true) { + $carry[$item->id_agente()] = io_safe_output( + $item->alias() + ); + } + + return $carry; + } + ); + } + + if (empty($agents) === true) { + echo '[]'; + } else { + // Dump response. + echo json_encode($agents); + } + } + + + /** + * Returns a goBack form structure. + * + * @return array Form structure. + */ + public function getGoBackForm() + { + $form['form']['action'] = $this->url; + $form['form']['method'] = 'POST'; + $form['form']['id'] = 'go-back-form'; + $form['inputs'] = [ + [ + 'arguments' => [ + 'name' => 'submit', + 'label' => __('Go back'), + 'type' => 'submit', + 'attributes' => 'class="sub cancel"', + 'return' => true, + ], + ], + ]; + + return $form; + } + + +} diff --git a/pandora_console/include/lib/ClusterViewer/ClusterWizard.php b/pandora_console/include/lib/ClusterViewer/ClusterWizard.php new file mode 100644 index 0000000000..50a14d9c85 --- /dev/null +++ b/pandora_console/include/lib/ClusterViewer/ClusterWizard.php @@ -0,0 +1,1258 @@ + 'A-A Modules', + 3 => 'A-A thresholds', + 6 => 'Alerts', + ]; + + /** + * Label set for AP clusters. + * + * @var array + */ + public $APLabels = [ + 2 => 'A-P Modules', + 3 => 'A-P thresholds', + 4 => 'A-P module', + 5 => 'Critical A-P modules', + 6 => 'Alerts', + ]; + + /** + * Variable to store error messages while parsing + * different steps. + * + * @var string + */ + public $errMessages = []; + + /** + * Current operation (New | Update). + * + * @var string + */ + public $operation; + + /** + * Parent url (for go back forms). + * + * @var string + */ + public $parentUrl; + + /** + * Current cluster definition (if any). + * + * @var PandoraFMS\ClusterViewer\Cluster + */ + private $cluster; + + /** + * Current cluster agent definition (if any). + * + * @var array + */ + private $agent; + + + /** + * Builds a Cluster Wizard. + * + * @param string $url Main url. + * @param string $operation Operation (new|update). + */ + public function __construct(string $url, string $operation=null) + { + // Check access. + check_login(); + + ui_require_css_file('wizard'); + ui_require_css_file('discovery'); + + $this->access = 'AW'; + $this->operation = $operation; + $this->url = $url; + $this->parentUrl = $url; + $this->page = (int) get_parameter('page', 0); + $this->id = (int) get_parameter('id', 0); + } + + + /** + * Run wizard. + * + * @return void + * @throws \Exception On error. + */ + public function run() + { + global $config; + + ui_require_css_file('cluster_wizard'); + + $this->operation = get_parameter('op', ''); + $cluster_id = get_parameter('id', ''); + $name = get_parameter('name', ''); + + $this->errMessages = []; + + // Cluster initialization. Load. + $load_success = true; + + try { + if (empty($cluster_id) === false) { + // Load data. + $this->cluster = new Cluster($cluster_id); + + if ($this->cluster->agent()->id_agente() === null) { + $this->errMessages['noagent'] = 'Agent associated to cluster does not exist. Please update to create it.'; + } + + if ($this->cluster->group()->id_grupo() === null) { + throw new \Exception( + 'Group associated to cluster does not exist.' + ); + } + } else if (empty($name) === false) { + $cluster_data = Cluster::search(['name' => $name]); + + if ($cluster_data !== false) { + $init_failed = true; + $this->page--; + throw new \Exception( + __('Cluster already defined, please use another name.') + ); + } + } + } catch (\Exception $e) { + $this->errMessages[] = $e->getMessage(); + $load_success = false; + } + + if (empty($this->cluster) === true) { + // Empty cluster. Initialize. + $this->cluster = new Cluster(); + } else { + // Cluster already exists. Update operation. + $this->operation = 'update'; + } + + try { + // Check user has grants to edit this cluster. + if ($this->operation !== 'new' + && (!check_acl( + $config['id_user'], + $this->cluster->group()->id_grupo(), + 'AW' + )) + ) { + // User has no grants to edit this cluster. + throw new \Exception( + 'You have no permission to edit this cluster.' + ); + } + } catch (\Exception $e) { + $this->errMessages[] = $e->getMessage(); + $load_success = false; + } + + if ($load_success === true) { + if ($this->cluster->id() === null + && $this->page > 1 + ) { + $load_success = false; + $this->errMessages[] = 'Please define this cluster first'; + } else { + try { + // Parse results (previous step). + $status = $this->parseForm(); + } catch (\Exception $e) { + $this->errMessages[] = $e->getMessage(); + if ($this->page > 0) { + $this->page--; + } + } + } + } + + // Get form structure (current page). + $form = $this->getForm($load_success); + + // Force Cluster calculation. Cluster defined. + $this->cluster->force(false); + + View::render( + 'cluster/edit', + [ + 'config' => $config, + 'wizard' => $this, + 'model' => $this, + 'cluster' => $this->cluster, + 'form' => $form, + ] + ); + } + + + /** + * Retrieve page value. + * + * @return integer Page value. + */ + public function getPage() + { + return $this->page; + } + + + /** + * Set page to target value., + * + * @param integer $page New page value. + * + * @return void + */ + public function setPage(int $page) + { + $this->page = $page; + } + + + /** + * Return current operation. + * + * @return string New or Update. + */ + public function getOperation() + { + return $this->operation; + } + + + /** + * Retrieve labels. + * + * @return array With labels (breadcrum). + */ + public function getLabels() + { + $labels = $this->labels; + if ($this->cluster->cluster_type() !== null) { + if ($this->cluster->cluster_type() === 'AA') { + $labels = ($this->labels + $this->AALabels); + } else { + $labels = ($this->labels + $this->APLabels); + } + } + + return $labels; + } + + + /** + * Returns a goBack form structure. + * + * @param boolean $main Go to main page. + * + * @return array Form structure. + */ + public function getGoBackForm(?bool $main=false) + { + $url = $this->url; + + if ($main === false) { + $page = ($this->page - 1); + + if ($page >= 0) { + $extra_url = ''; + if ($this->cluster->id() !== null) { + $extra_url = '&id='.$this->cluster->id(); + if ($this->cluster->cluster_type() === 'AA') { + // Jump from Alerts back to A-A Thresholds. + if ($page === 5) { + $page = 3; + } + } + } + + $url = $this->url.'&op='.$this->operation; + $url .= '&page='.$page.$extra_url; + } + } + + $form['form']['action'] = $url; + $form['form']['method'] = 'POST'; + $form['form']['id'] = 'go-back-form'; + $form['inputs'] = [ + [ + 'arguments' => [ + 'name' => 'submit', + 'label' => __('Go back'), + 'type' => 'submit', + 'attributes' => 'class="sub cancel"', + 'return' => true, + ], + ], + ]; + + return $form; + } + + + /** + * Parse responses from previous steps. + * + * @return void + * @throws \Exception On error. + */ + private function parseForm() + { + global $config; + + // Parse user responses. + if ($this->page <= 0) { + // No previous steps, return OK. + return; + } + + if ($this->page === 1) { + /* + * + * PARSE DEFINITION. + * + */ + + $name = get_parameter('name', ''); + $type = get_parameter('type', null); + $description = get_parameter('description', ''); + $id_group = get_parameter('id_group', ''); + $server_name = get_parameter('server_name', ''); + + if ($name === '' + && $type === null + && $description === '' + && $id_group === '' + && $server_name === '' + ) { + if ($this->cluster->id() === null) { + throw new \Exception( + 'Please fulfill all required fields.' + ); + } + + // Default values, show page. + return; + } + + if (empty($name) === true + || empty($type) === true + || empty($id_group) === true + || empty($server_name) === true + ) { + if (empty($server_name) === true) { + throw new \Exception( + 'Please select a valid Prediction server' + ); + } + + throw new \Exception('Please fulfill all required fields'); + } + + // Verify cluster type is one from the list. + if (in_array($type, ['AA', 'AP']) === false) { + throw new \Exception('Invalid cluster type selected'); + } + + if ($this->cluster->id() === null) { + // Create. + // 1. Create agent. + $this->cluster->agent()->alias($name); + $this->cluster->agent()->comentarios($description); + $this->cluster->agent()->intervalo(300); + $this->cluster->agent()->id_grupo($id_group); + $this->cluster->agent()->id_os(CLUSTER_OS_ID); + $this->cluster->agent()->server_name($server_name); + $this->cluster->agent()->modo(1); + + $this->cluster->agent()->save(); + + if ($this->cluster->agent()->id_agente() === false) { + throw new \Exception( + 'Failed to create agent: '.$config['dbconnection']->error + ); + } + + // 2. Create cluster entry. + $this->cluster->name($name); + $this->cluster->cluster_type($type); + $this->cluster->description($description); + $this->cluster->group($id_group); + $this->cluster->id_agent($this->cluster->agent()->id_agente()); + + $this->cluster->save(); + + if ($this->cluster->id() === null) { + // Delete agent created in previous step. + \agents_delete_agent($this->cluster->agent()->id()); + + throw new \Exception( + 'Failed to create cluster: '.$config['dbconnection']->error + ); + } + + // 3. Create cluster module in agent. + $this->cluster->agent()->addModule( + [ + 'nombre' => io_safe_input('Cluster status'), + 'id_modulo' => 5, + 'prediction_module' => 5, + 'custom_integer_1' => $this->cluster->id(), + 'id_tipo_modulo' => 1, + 'descripcion' => io_safe_input( + 'Cluster status information module' + ), + 'min_warning' => 1, + 'min_critical' => 2, + ] + ); + } else { + // Update. + $this->cluster->name($name); + $this->cluster->cluster_type($type); + $this->cluster->description($description); + $this->cluster->group($id_group); + + $this->cluster->agent()->alias($name); + $this->cluster->agent()->comentarios($description); + $this->cluster->agent()->intervalo(300); + $this->cluster->agent()->id_grupo($id_group); + $this->cluster->agent()->id_os(CLUSTER_OS_ID); + $this->cluster->agent()->server_name($server_name); + $this->cluster->agent()->modo(1); + $this->cluster->agent()->save(); + + // 2. Re link. + $this->cluster->id_agent($this->cluster->agent()->id_agente()); + $this->cluster->save(); + + // If agent has been deleted, recreate module. + if ($this->errMessages['noagent'] !== null) { + // 3. Create cluster module in agent. + $this->cluster->agent()->addModule( + [ + 'nombre' => io_safe_input('Cluster status'), + 'id_modulo' => 5, + 'prediction_module' => 5, + 'custom_integer_1' => $this->cluster->id(), + 'id_tipo_modulo' => 1, + 'descripcion' => io_safe_input( + 'Cluster status information module' + ), + 'min_warning' => 1, + 'min_critical' => 2, + ] + ); + } + + unset($this->errMessages['noagent']); + } + + return; + } + + if ($this->page === 2) { + /* + * + * PARSE MEMBERS. + * + */ + + // Parse responses from page 1. + $agents_selected = get_parameter('selected-select-members', null); + + if ($agents_selected === null) { + // Direct access. + return; + } + + // Clear members. Reparse. + $this->cluster->cleanMembers(); + + // Remove 'None' field. + if (array_search(0, $agents_selected) === 0) { + unset($agents_selected[0]); + } + + if (empty($agents_selected) === true) { + throw new \Exception('No members selected'); + } + + foreach ($agents_selected as $id_agent) { + $agent = $this->cluster->addMember($id_agent); + + \db_pandora_audit( + AUDIT_LOG_AGENT_MANAGEMENT, + 'Agent '.io_safe_output($agent->alias()).' added to cluster '.io_safe_output( + $this->cluster->name() + ) + ); + } + + $this->cluster->save(); + + return; + } + + if ($this->page === 3) { + /* + * + * PARSE AA MODULES. + * + */ + + $aa_modules = get_parameter('selected-select-aa-modules', null); + + if (is_array($aa_modules) === true) { + if ($aa_modules[0] === '0') { + unset($aa_modules[0]); + } + + $current = array_keys($this->cluster->getAAModules()); + $removed = array_diff($current, $aa_modules); + $changes = false; + + foreach ($aa_modules as $m) { + $this->cluster->addAAModule($m); + $changes = true; + } + + foreach ($removed as $m) { + $this->cluster->removeAAModule($m); + $changes = true; + } + + if ($changes === true) { + $this->cluster->save(); + } + } + + return; + } + + if ($this->page === 4) { + /* + * + * PARSE AA THRESHOLDS + * + */ + + $modules = $this->cluster->getAAModules(); + + $changes = false; + + foreach ($modules as $item) { + $value_warning = get_parameter( + 'warning-'.md5($item->name()), + null + ); + + $value_critical = get_parameter( + 'critical-'.md5($item->name()), + null + ); + + if ($value_warning !== null) { + $item->warning_limit($value_warning); + $changes = true; + } + + if ($value_critical !== null) { + $item->critical_limit($value_critical); + $changes = true; + } + } + + if ($changes === true) { + $this->cluster->save(); + } + + if ($this->cluster->cluster_type() === 'AA') { + // Force next page '6' (alerts). + $this->page = 6; + } + + return; + } + + if ($this->page === 5) { + /* + * + * PARSE AP MODULES + * + */ + + if ($this->cluster->cluster_type() === 'AA') { + // Direct access. Accessed by URL. + $this->page = 0; + throw new \Exception( + 'Unavailable page for this cluster type, please follow this wizard.' + ); + } + + $ap_modules = get_parameter('selected-select-ap-modules', null); + if (is_array($ap_modules) === true) { + if ($ap_modules[0] === '0') { + unset($ap_modules[0]); + } + + $current = array_keys($this->cluster->getAPModules()); + $removed = array_diff($current, $ap_modules); + $changes = false; + + foreach ($ap_modules as $m) { + $this->cluster->addAPModule($m); + $changes = true; + } + + foreach ($removed as $m) { + $this->cluster->removeAPModule($m); + $changes = true; + } + + if ($changes === true) { + $this->cluster->save(); + } + } + + return; + } + + if ($this->page === 6) { + /* + * + * PARSE AP MODULES CRITICAL + * + */ + + if ($this->cluster->cluster_type() === 'AA') { + // Direct access. + return; + } + + $modules = $this->cluster->getAPModules(); + $changes = false; + + foreach ($modules as $item) { + $value = get_parameter_switch( + 'switch-'.md5($item->name()), + null + ); + + if ($value !== null) { + // Unchecked. + $item->is_critical($value); + $changes = true; + } + } + + if ($changes === true) { + $this->cluster->save(); + } + + return; + } + + if ($this->page === 7) { + /* + * + * PARSE ALERTS + * + */ + + // There is no need to parse anything. Already managed by alert + // builder. + header('Location: '.$this->url.'&op=view&id='.$this->cluster->id()); + } + + throw new \Exception('Unexpected error'); + } + + + /** + * Retrieves form estructure for current step. + * + * @param boolean $load_success Load process has been success or not. + * + * @return array Form. + */ + private function getForm(?bool $load_success=true) + { + $form = []; + $final = false; + + $extra_url = ''; + if ($this->cluster->id() !== null) { + $extra_url = '&id='.$this->cluster->id(); + } + + $url = $this->url.'&op='.$this->operation; + $target_url .= $url.'&page='.($this->page + 1).$extra_url; + + $form['form'] = [ + 'action' => $target_url, + 'method' => 'POST', + 'extra' => 'autocomplete="false"', + ]; + + if ($load_success === false && $this->page !== 0) { + return []; + } + + if ($this->page === 0) { + /* + * + * Page: Cluster Definition. + * + */ + + // Input cluster name. + $form['inputs'][] = [ + 'label' => ''.__('Cluster name').''.ui_print_help_tip( + __('An agent with the same name of the cluster will be created, as well a special service with the same name'), + true + ), + 'arguments' => [ + 'name' => 'name', + 'value' => $this->cluster->name(), + 'type' => 'text', + 'size' => 25, + 'required' => true, + ], + ]; + + // Input cluster type. + $form['inputs'][] = [ + 'label' => ''.__('Cluster type').''.ui_print_help_tip( + __('AA is a cluster where all members are working. In AP cluster only master member is working'), + true + ), + 'arguments' => [ + 'name' => 'type', + 'selected' => $this->cluster->cluster_type(), + 'type' => 'select', + 'fields' => [ + 'AA' => __('Active - Active'), + 'AP' => __('Active - Pasive'), + ], + 'required' => true, + ], + ]; + + // Input cluster description. + $form['inputs'][] = [ + 'label' => ''.__('Description').'', + 'arguments' => [ + 'name' => 'description', + 'value' => $this->cluster->description(), + 'type' => 'text', + 'size' => 25, + ], + ]; + + // Input Group. + $form['inputs'][] = [ + 'label' => ''.__('Group').''.ui_print_help_tip( + __('Target cluster agent will be stored under this group'), + true + ), + 'arguments' => [ + 'name' => 'id_group', + 'returnAllGroup' => false, + 'privilege' => $this->access, + 'type' => 'select_groups', + 'selected' => $this->cluster->group()->id_grupo(), + 'return' => true, + 'required' => true, + ], + ]; + + // Input. Servername. + $form['inputs'][] = [ + 'label' => ''.__('Prediction server').':'.ui_print_help_tip( + __('You must select a Prediction Server to perform all cluster status calculations'), + true + ), + 'arguments' => [ + 'type' => 'select_from_sql', + 'sql' => sprintf( + 'SELECT name as k, name as v + FROM tserver + WHERE server_type = %d + ORDER BY name', + SERVER_TYPE_PREDICTION + ), + 'name' => 'server_name', + 'selected' => $this->cluster->agent()->server_name(), + 'return' => true, + 'required' => true, + ], + ]; + } else if ($this->page === 1) { + /* + * + * Page: Cluster members. + * + */ + + $all_agents = agents_get_agents( + false, + [ + 'id_agente', + 'alias', + ] + ); + + if ($all_agents === false) { + $all_agents = []; + } + + $all_agents = array_reduce( + $all_agents, + function ($carry, $item) { + $carry[$item['id_agente']] = $item['alias']; + return $carry; + }, + [] + ); + + $selected = $this->cluster->getMembers(); + + $selected = array_reduce( + $selected, + function ($carry, $item) use (&$all_agents) { + $carry[$item->id_agente()] = $item->alias(); + unset($all_agents[$item->id_agente()]); + return $carry; + }, + [] + ); + + $form['inputs'][] = [ + 'arguments' => [ + 'type' => 'select_multiple_filtered', + 'class' => 'w80p mw600px', + 'name' => 'members', + 'available' => $all_agents, + 'selected' => $selected, + 'group_filter' => [ + 'page' => 'operation/cluster/cluster', + 'method' => 'getAgentsFromGroup', + 'id' => $this->cluster->id(), + ], + 'texts' => [ + 'title-left' => 'Available agents', + 'title-right' => 'Selected cluster members', + ], + ], + ]; + } else if ($this->page === 2) { + /* + * + * Page: A-A modules. + * + */ + + $selected = $this->cluster->getAAModules(); + + $selected = array_reduce( + $selected, + function ($carry, $item) { + $name = io_safe_output($item->name()); + $carry[$name] = $name; + return $carry; + }, + [] + ); + + $members = $this->cluster->getMembers(); + + // Agent ids are stored in array keys. + $members = array_keys($members); + + // Get common modules. + $modules = \select_modules_for_agent_group( + // Module group. 0 => All. + 0, + // Agents. + $members, + // Show all modules or common ones. + false, + // Return. + false, + // Group by name. + true + ); + + // Escape html special chars on array keys for select value. + $modules = array_combine( + array_map( + function ($k) { + return htmlspecialchars($k); + }, + array_keys($modules) + ), + $modules + ); + + $selected = array_combine( + array_map( + function ($k) { + return htmlspecialchars($k); + }, + array_keys($selected) + ), + $selected + ); + + $modules = array_diff_key($modules, $selected); + if ($this->cluster->cluster_type() === 'AP') { + $form['inputs'][] = [ + 'arguments' => [ + 'type' => 'select_multiple_filtered', + 'class' => 'w80p mw600px', + 'name' => 'aa-modules', + 'available' => $modules, + 'selected' => $selected, + 'texts' => [ + 'title-left' => 'Available modules (common)', + 'title-right' => 'Selected active-passive modules', + 'filter-item' => 'Filter options by module name', + ], + 'sections' => [ + 'filters' => 1, + 'item-available-filter' => 1, + 'item-selected-filter' => 1, + ], + ], + ]; + } else if ($this->cluster->cluster_type() === 'AA') { + $form['inputs'][] = [ + 'arguments' => [ + 'type' => 'select_multiple_filtered', + 'class' => 'w80p mw600px', + 'name' => 'aa-modules', + 'available' => $modules, + 'selected' => $selected, + 'texts' => [ + 'title-left' => 'Available modules (common)', + 'title-right' => 'Selected active-active modules', + 'filter-item' => 'Filter options by module name', + ], + 'sections' => [ + 'filters' => 1, + 'item-available-filter' => 1, + 'item-selected-filter' => 1, + ], + ], + ]; + } + } else if ($this->page === 3) { + /* + * + * Page: A-A module limits. + * + */ + + $aa_modules = $this->cluster->getAAModules(); + $inputs = []; + foreach ($aa_modules as $module) { + $inputs[] = [ + 'block_id' => 'from-to-threshold', + 'class' => 'flex-row line w100p', + 'direct' => 1, + 'block_content' => [ + [ + 'label' => ''.$module->name().'', + ], + [ + 'label' => ''.__('critical if').'', + 'arguments' => [ + 'name' => 'critical-'.md5($module->name()), + 'type' => 'number', + 'value' => $module->critical_limit(), + 'required' => true, + ], + ], + [ + 'label' => __('% of balanced modules are down (equal or greater).'), + ], + ], + ]; + + $inputs[] = [ + 'block_id' => 'from-to-threshold', + 'class' => 'flex-row line w100p', + 'direct' => 1, + 'block_content' => [ + [ + 'label' => ''.$module->name().'', + ], + [ + 'label' => ''.('warning if').'', + 'arguments' => [ + 'name' => 'warning-'.md5($module->name()), + 'type' => 'number', + 'value' => $module->warning_limit(), + 'required' => true, + ], + ], + [ + 'label' => __('% of balanced modules are down (equal or greater).'), + ], + ], + ]; + + $inputs[] = [ + 'block_id' => 'from-to-threshold', + 'class' => 'flex-row line w100p', + 'direct' => 1, + 'block_content' => [], + ]; + } + + if ($this->cluster->cluster_type() === 'AP') { + $form['inputs'][] = [ + 'label' => __( + 'Please, set thresholds for all active-passive modules'.ui_print_help_tip( + 'If you want your cluster module to be critical when 3 of 6 instances are down, set critical to \'50%\'', + true + ) + ), + 'class' => 'indented', + 'block_content' => $inputs, + ]; + } else if ($this->cluster->cluster_type() === 'AA') { + $form['inputs'][] = [ + 'label' => __( + 'Please, set thresholds for all active-active modules'.ui_print_help_tip( + 'If you want your cluster module to be critical when 3 of 6 instances are down, set critical to \'50%\'', + true + ) + ), + 'class' => 'indented', + 'block_content' => $inputs, + ]; + } + } else if ($this->page === 4) { + /* + * + * Page: A-P modules. + * + */ + + $selected = $this->cluster->getAPModules(); + $aa = $this->cluster->getAAModules(); + + $selected = array_reduce( + $selected, + function ($carry, $item) { + $name = io_safe_output($item->name()); + $carry[$name] = $name; + return $carry; + }, + [] + ); + + $aa = array_reduce( + $aa, + function ($carry, $item) { + $name = io_safe_output($item->name()); + $carry[$name] = $name; + return $carry; + }, + [] + ); + + $members = $this->cluster->getMembers(); + + // Agent ids are stored in array keys. + $members = array_keys($members); + + // Get common modules. + $modules = \select_modules_for_agent_group( + // Module group. 0 => All. + 0, + // Agents. + $members, + // Show all modules or common ones. + true, + // Return. + false, + // Group by name. + true + ); + + // Exclude AA modules from available options. + $modules = array_diff_key($modules, $aa); + + // Exclude already used from available options. + $modules = array_diff_key($modules, $selected); + + $form['inputs'][] = [ + 'arguments' => [ + 'type' => 'select_multiple_filtered', + 'class' => 'w80p mw600px', + 'name' => 'ap-modules', + 'available' => $modules, + 'selected' => $selected, + 'texts' => [ + 'title-left' => 'Available modules (any)', + 'title-right' => 'Selected active-passive modules', + 'filter-item' => 'Filter options by module name', + ], + 'sections' => [ + 'filters' => 1, + 'item-available-filter' => 1, + 'item-selected-filter' => 1, + ], + ], + ]; + } else if ($this->page === 5) { + /* + * + * Page: A-P critical modules. + * + */ + + $ap_modules = $this->cluster->getAPModules(); + $inputs = []; + foreach ($ap_modules as $module) { + $inputs[] = [ + 'label' => $module->name(), + 'arguments' => [ + 'type' => 'switch', + 'name' => 'switch-'.md5($module->name()), + 'value' => $module->is_critical(), + ], + ]; + } + + $form['inputs'][] = [ + 'label' => __( + 'Please, check all active-passive modules critical for this cluster' + ).ui_print_help_tip( + __('If a critical balanced module is going to critical status, then cluster will be critical.'), + true + ), + 'class' => 'indented', + 'block_content' => $inputs, + ]; + } else if ($this->page === 6) { + /* + * + * Page: Alerts. + * + */ + + ob_start(); + global $config; + + $id_agente = $this->cluster->agent()->id_agente(); + $dont_display_alert_create_bttn = true; + include_once $config['homedir'].'/godmode/alerts/alert_list.php'; + include_once $config['homedir'].'/godmode/alerts/alert_list.builder.php'; + + // XXX: Please do not use this kind of thing never more. + $hack = ob_get_clean(); + + // TODO: Alert form. + $form['pre-content'] = $hack; + + $final = true; + } + + // Submit. + $str = __('Next'); + if ($this->cluster->id() !== null) { + $str = __('Update and continue'); + } + + if ($final === true) { + $str = __('Finish'); + } + + // Submit button. + $form['inputs'][] = [ + 'arguments' => [ + 'name' => 'next', + 'label' => $str, + 'type' => 'submit', + 'attributes' => 'class="sub next"', + 'return' => true, + ], + ]; + + return $form; + } + + +} diff --git a/pandora_console/operation/agentes/estado_agente.php b/pandora_console/operation/agentes/estado_agente.php index 0210545a26..dc15caeaa1 100644 --- a/pandora_console/operation/agentes/estado_agente.php +++ b/pandora_console/operation/agentes/estado_agente.php @@ -847,10 +847,10 @@ foreach ($agents as $agent) { if ($agent['id_os'] == CLUSTER_OS_ID) { if (enterprise_installed()) { - $cluster = PandoraFMS\Enterprise\Cluster::loadFromAgentId( + $cluster = PandoraFMS\Cluster::loadFromAgentId( $agent['id_agente'] ); - $url = 'index.php?sec=reporting&sec2='.ENTERPRISE_DIR; + $url = 'index.php?sec=reporting&sec2='; $url .= '/operation/cluster/cluster'; $url = ui_get_full_url( $url.'&op=view&id='.$cluster->id() @@ -866,10 +866,10 @@ foreach ($agents as $agent) { if ($agent['id_os'] == CLUSTER_OS_ID) { if (enterprise_installed()) { - $cluster = PandoraFMS\Enterprise\Cluster::loadFromAgentId( + $cluster = PandoraFMS\Cluster::loadFromAgentId( $agent['id_agente'] ); - $url = 'index.php?sec=reporting&sec2='.ENTERPRISE_DIR; + $url = 'index.php?sec=reporting&sec2='; $url .= '/operation/cluster/cluster'; $url = ui_get_full_url( $url.'&op=update&id='.$cluster->id() diff --git a/pandora_console/operation/cluster/cluster.php b/pandora_console/operation/cluster/cluster.php new file mode 100755 index 0000000000..2cc078ef4b --- /dev/null +++ b/pandora_console/operation/cluster/cluster.php @@ -0,0 +1,70 @@ + '[ClusterManager]'.$e->getMessage() ]); + exit; + } else { + echo '[ClusterManager]'.$e->getMessage(); + } + + // Stop this execution, but continue 'globally'. + return; +} + +// AJAX controller. +if (is_ajax()) { + $method = get_parameter('method'); + + if (method_exists($obj, $method) === true) { + $obj->{$method}(); + } else { + $obj->error('Method not found. [ClusterManager::'.$method.']'); + } + + // Stop any execution. + exit; +} else { + // Run. + $obj->run(); +} diff --git a/pandora_console/operation/menu.php b/pandora_console/operation/menu.php index fb303dd3fa..e933cf91f6 100644 --- a/pandora_console/operation/menu.php +++ b/pandora_console/operation/menu.php @@ -147,7 +147,12 @@ if ($access_console_node === true) { $sub['snmpconsole']['subtype'] = 'nolink'; } - enterprise_hook('cluster_menu'); + if (check_acl($config['id_user'], 0, 'AR')) { + $sub['operation/cluster/cluster']['text'] = __('Cluster View'); + $sub['operation/cluster/cluster']['id'] = 'cluster'; + $sub['operation/cluster/cluster']['refr'] = 0; + } + enterprise_hook('aws_menu'); enterprise_hook('SAP_view'); diff --git a/pandora_console/views/cluster/edit.php b/pandora_console/views/cluster/edit.php new file mode 100644 index 0000000000..393951f470 --- /dev/null +++ b/pandora_console/views/cluster/edit.php @@ -0,0 +1,129 @@ +operation; + +if ($wizard->id !== null) { + $extra .= '&id='.$wizard->id; +} + +$bc[] = [ + 'link' => $wizard->parentUrl, + 'label' => __('Cluster list'), + 'selected' => false, +]; + +$labels = $wizard->getLabels(); +foreach ($labels as $key => $label) { + $bc[] = [ + 'link' => $wizard->url.(($key >= 0) ? $extra.'&page='.$key : ''), + 'label' => __($label), + 'selected' => ($wizard->page == $key), + ]; +} + +$wizard->prepareBreadcrum($bc); + +$header_str = __(ucfirst($wizard->getOperation())).' '; +$header_str .= (($cluster->name() !== null) ? $cluster->name() : __('cluster ')); +$header_str .= ' » '.__($labels[$wizard->page]); + +// Header. +$buttons = []; + +$main_page = ''; +$main_page .= html_print_image( + 'images/list.png', + true, + [ + 'title' => __('Cluster list'), + 'class' => 'invert_filter', + ] +); +$main_page .= ''; + +$buttons = [ + [ + 'active' => false, + 'text' => $main_page, + ], +]; + +if ($cluster !== null) { + if ($cluster->id() !== null) { + $view = ''; + $view .= html_print_image( + 'images/operation.png', + true, + [ + 'title' => __('View this cluster'), + 'class' => 'invert_filter', + ] + ); + $view .= ''; + + $buttons[] = [ + 'active' => false, + 'text' => $view, + ]; + } +} + +ui_print_page_header( + $header_str, + '', + false, + 'cluster_view', + true, + // Buttons. + $buttons, + false, + '', + GENERIC_SIZE_TEXT, + '', + $wizard->printHeader(true) +); + +// Check if any error ocurred. +if (empty($wizard->errMessages) === false) { + foreach ($wizard->errMessages as $msg) { + ui_print_error_message(__($msg)); + } +} + +if (empty($form) === false) { + // Print form (prepared in ClusterWizard). + HTML::printForm($form, false, ($wizard->page < 6)); +} + +// Print always go back button. +HTML::printForm($wizard->getGoBackForm(), false); diff --git a/pandora_console/views/cluster/list.php b/pandora_console/views/cluster/list.php new file mode 100644 index 0000000000..c72f1752a1 --- /dev/null +++ b/pandora_console/views/cluster/list.php @@ -0,0 +1,132 @@ + 'options', + 'class' => 'action_buttons', + ], + ]; + + $column_names = [ + __('Name'), + __('Description'), + __('Group'), + __('Type'), + __('Nodes'), + __('Status'), + __('Options'), + ]; + + $tableId = 'clusters'; + + // Load datatables user interface. + ui_print_datatable( + [ + 'id' => $tableId, + 'class' => 'info_table', + 'style' => 'width: 100%', + 'columns' => $columns, + 'column_names' => $column_names, + 'ajax_url' => $model->ajaxController, + 'ajax_data' => ['method' => 'draw'], + 'no_sortable_columns' => [-1], + 'order' => [ + 'field' => 'known_status', + 'direction' => 'asc', + ], + 'search_button_class' => 'sub filter float-right', + 'form' => [ + 'inputs' => [ + [ + 'label' => __('Filter group'), + 'name' => 'id_group', + 'returnAllGroup' => true, + 'privilege' => 'AR', + 'type' => 'select_groups', + 'return' => true, + 'size' => '250px', + ], + [ + 'label' => __('Free search'), + 'type' => 'text', + 'class' => 'mw250px', + 'id' => 'free_search', + 'name' => 'free_search', + ], + ], + ], + ] + ); +} catch (Exception $e) { + echo $e->getMessage(); +} + +if (check_acl($config['id_user'], 0, 'AW')) { + HTML::printForm( + [ + 'form' => [ + 'method' => 'POST', + 'action' => ui_get_full_url($model->url.'&op=new'), + ], + 'inputs' => [ + [ + 'class' => 'w100p', + 'arguments' => [ + 'name' => 'submit', + 'label' => __('New cluster'), + 'type' => 'submit', + 'attributes' => 'class="sub next"', + 'return' => true, + ], + ], + ], + ] + ); +} diff --git a/pandora_console/views/cluster/view.php b/pandora_console/views/cluster/view.php new file mode 100644 index 0000000000..1742930ad1 --- /dev/null +++ b/pandora_console/views/cluster/view.php @@ -0,0 +1,453 @@ + $model->url, + 'label' => __('Cluster list'), + 'selected' => false, +]; + +$bc[] = [ + 'link' => $model->url.'&op=view&id='.$cluster->id(), + 'label' => __('Cluster details'), + 'selected' => true, +]; + + +$html->prepareBreadcrum($bc); + +// Header. +$main_page = ''; +$main_page .= html_print_image( + 'images/list.png', + true, + [ + 'title' => __('Cluster list'), + 'class' => 'invert_filter', + ] +); +$main_page .= ''; + +$edit = ''; +$edit .= html_print_image( + 'images/setup.png', + true, + [ + 'title' => __('Edit this cluster'), + 'class' => 'invert_filter', + ] +); +$edit .= ''; + +ui_print_page_header( + __('Cluster details').' » '.$cluster->name(), + '', + false, + // Help link. + 'cluster_view', + true, + // Buttons. + [ + [ + 'active' => false, + 'text' => $main_page, + ],[ + 'active' => false, + 'text' => $edit, + ], + ], + false, + '', + GENERIC_SIZE_TEXT, + '', + $html->printHeader(true) +); + + +if (empty($error) === false) { + echo $error; +} + +if (empty($message) === false) { + echo $message; +} + +if ($critical === true) { + // Print always go back button. + HTML::printForm($model->getGoBackForm(), false); + return; +} + + +/* + * + * All this block has been retrieved from 'estado_generalagente.php' as + * described in issue #5755. + * + */ + + + +/* + * + * + * CLUSTER AGENT DETAILS. + * + */ + +// Prepare information for view. +$alive_animation = agents_get_status_animation( + agents_get_interval_status($cluster->agent()->toArray(), false) +); + + +$agent_name = ui_print_agent_name( + $cluster->agent()->id_agente(), + true, + 500, + 'font-size: medium;font-weight:bold', + true, + '', + '', + false, + false +); +$in_planned_downtime = db_get_sql( + 'SELECT executed FROM tplanned_downtime + INNER JOIN tplanned_downtime_agents + ON tplanned_downtime.id = tplanned_downtime_agents.id_downtime + WHERE tplanned_downtime_agents.id_agent = '.$cluster->agent()->id_agente().' AND tplanned_downtime.executed = 1' +); + +if ($cluster->agent()->disabled()) { + if ($in_planned_downtime) { + $agent_name = ''.$agent_name.ui_print_help_tip(__('Disabled'), true); + } else { + $agent_name = ''.$agent_name.''.ui_print_help_tip(__('Disabled'), true); + } +} else if ($cluster->agent()->quiet()) { + if ($in_planned_downtime) { + $agent_name = "".$agent_name.' '.html_print_image('images/dot_blue.png', true, ['border' => '0', 'title' => __('Quiet'), 'alt' => '']); + } else { + $agent_name = "".$agent_name.' '.html_print_image('images/dot_blue.png', true, ['border' => '0', 'title' => __('Quiet'), 'alt' => '']).''; + } +} else { + $agent_name = $agent_name; +} + +if ($in_planned_downtime && !$cluster->agent()->disabled() && !$cluster->agent()->quiet()) { + $agent_name .= ' '.ui_print_help_tip( + __('Agent in scheduled downtime'), + true, + 'images/minireloj-16.png' + ).''; +} else if (($in_planned_downtime && !$cluster->agent()->disabled()) + || ($in_planned_downtime && !$cluster->agent()->quiet()) +) { + $agent_name .= ' '.ui_print_help_tip( + __('Agent in scheduled downtime'), + true, + 'images/minireloj-16.png' + ).''; +} + + +$table_agent_header = '
'; +$table_agent_header .= $agent_name; +$table_agent_header .= '
'; +$table_agent_header .= '
'; +if (!$config['show_group_name']) { + $table_agent_header .= ui_print_group_icon( + $cluster->agent()->id_grupo(), + true, + 'groups_small', + 'padding-right: 6px;' + ); +} + +$table_agent_header .= '
'; + +$status_img = agents_detail_view_status_img( + $cluster->agent()->critical_count(), + $cluster->agent()->warning_count(), + $cluster->agent()->unknown_count(), + $cluster->agent()->total_count(), + $cluster->agent()->notinit_count() +); + +$table_agent_header .= '
'.$status_img.'
'; +$table_agent_header .= '  '; +$table_agent_header .= ''.html_print_image( + 'images/target.png', + true, + [ + 'title' => __('Force cluster status calculation'), + 'alt' => '', + 'class' => 'invert_filter', + + ] +).''; +// Fixed width non interactive charts. +$status_chart_width = 180; +$graph_width = 180; + +$table_agent_graph = '
'; +$table_agent_graph .= graph_agent_status( + $cluster->agent()->id_agente(), + $graph_width, + $graph_width, + true, + false, + false, + true +); +$table_agent_graph .= '
'; + +$table_agent_os = '

'.ui_print_os_icon( + $cluster->agent()->id_os(), + false, + true, + true, + false, + false, + false, + ['title' => __('OS').': '.get_os_name($cluster->agent()->id_os())] +); +$table_agent_os .= (empty($cluster->agent()->os_version()) === true) ? get_os_name((int) $cluster->agent()->id_os()) : $cluster->agent()->os_version().'

'; + + + +$addresses = agents_get_addresses($cluster->agent()->id_agente()); +$address = agents_get_address($cluster->agent()->id_agente()); + +foreach ($addresses as $k => $add) { + if ($add == $address) { + unset($addresses[$k]); + } +} + +if (empty($address) === false) { + $table_agent_ip = '

'.html_print_image( + 'images/world.png', + true, + [ + 'title' => __('IP address'), + 'class' => 'invert_filter', + ] + ); + $table_agent_ip .= ''; + $table_agent_ip .= empty($address) ? ''.__('N/A').'' : $address; + $table_agent_ip .= '

'; +} + +$table_agent_description = '

'.html_print_image( + 'images/list.png', + true, + [ + 'title' => __('Description'), + 'class' => 'invert_filter', + ] +); +$table_agent_description .= ''; +$table_agent_description .= empty( + $cluster->description() +) ? ''.__('N/A').'' : $cluster->description(); +$table_agent_description .= '

'; + +$table_agent_count_modules = reporting_tiny_stats( + $cluster->agent()->toArray(), + true, + 'agent', + // Useless. + ':', + true +); + +$table_agent_version = '

'.html_print_image( + 'images/version.png', + true, + [ + 'title' => __('Agent Version'), + 'class' => 'invert_filter', + ] +); +$table_agent_version .= ''; +$table_agent_version .= empty($cluster->agent()->agent_version()) ? ''.__('Cluster agent').'' : $cluster->agent()->agent_version(); +$table_agent_version .= '

'; + +/* + * + * MAP + * + */ + +$nodes = $cluster->getNodes(); + +$font_size = 20; +$width = '45%'; +$height = '500'; +$node_radius = 40; + +// Generate map. +$map_manager = new NetworkMap( + [ + 'nodes' => $nodes, + 'no_pandora_node' => 1, + 'pure' => 1, + 'map_options' => [ + 'generation_method' => LAYOUT_SPRING1, + 'font_size' => $font_size, + 'node_radius' => $node_radius, + 'height' => $height, + 'width' => '100%', + 'tooltip' => true, + 'size_image' => 50, + 'z_dash' => 0.5, + 'map_filter' => [ + 'node_sep' => 7, + 'node_radius' => 50, + 'x_offs' => 130, + 'y_offs' => -70, + ], + ], + ] +); + + +/* + * + * EVENTS 24h + * + */ + +$table_events = '
'; +$table_events .= '
'; +$table_events .= html_print_image( + 'images/arrow_down_green.png', + true +); +$table_events .= ''; +$table_events .= __('Events (Last 24h)'); +$table_events .= ''; +$table_events .= '
'; +$table_events .= '
'; +$table_events .= graph_graphic_agentevents( + $cluster->agent()->id_agente(), + 95, + 70, + SECONDS_1DAY, + '', + true, + true, + 500 +); +$table_events .= '
'; +$table_events .= '
'; + +?> +
+
+
+ +
+
+
+ +
+ +
+
+
+ +
+
+
+ +
+
+ printMap(); ?> +
+
+
+ +
+ +
+ +
+agent()->id_agente(); +require_once $config['homedir'].'/operation/agentes/estado_monitores.php'; +?> +
+ + + [ + 'action' => $model->url.'&op=view&id='.$cluster->id(), + 'method' => 'POST', + ], + 'inputs' => [ + [ + 'arguments' => [ + 'name' => 'submit', + 'label' => __('Reload'), + 'type' => 'submit', + 'attributes' => 'class="sub cancel"', + 'return' => true, + ], + ], + ], + ], + false +); + +echo '
'; + +// Print always go back button. +HTML::printForm($model->getGoBackForm(), false); From b8c2fe52b55ff34337361ef0cf5f0c28a67eacf4 Mon Sep 17 00:00:00 2001 From: Calvo Date: Tue, 25 Oct 2022 15:33:22 +0200 Subject: [PATCH 004/181] =?UTF-8?q?Added=20ACL=20to=20ap=C3=AC=20get=20tre?= =?UTF-8?q?e=20agents=20plugin=20user=20and=20plugin=20pass?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pandora_console/include/functions_api.php | 24 ++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/pandora_console/include/functions_api.php b/pandora_console/include/functions_api.php index 90935bbc6d..14a71bfdb8 100644 --- a/pandora_console/include/functions_api.php +++ b/pandora_console/include/functions_api.php @@ -652,8 +652,6 @@ $module_field_column_mampping = [ 'module_id_module' => 'id_modulo as module_id_module', 'module_disabled' => 'disabled as module_disabled', 'module_id_export' => 'id_export as module_id_export', - 'module_plugin_user' => 'plugin_user as module_plugin_user', - 'module_plugin_pass' => 'plugin_pass as module_plugin_pass', 'module_plugin_parameter' => 'plugin_parameter as module_plugin_parameter', 'module_id_plugin' => 'id_plugin as module_id_plugin', 'module_post_process' => 'post_process as module_post_process', @@ -805,8 +803,6 @@ function api_get_tree_agents($trash1, $trahs2, $other, $returnType) 'module_id_module', 'module_disabled', 'module_id_export', - 'module_plugin_user', - 'module_plugin_pass', 'module_plugin_parameter', 'module_id_plugin', 'module_post_process', @@ -1015,9 +1011,9 @@ function api_get_tree_agents($trash1, $trahs2, $other, $returnType) $groups = []; } - $groups = str_replace('\n', $returnReplace, $groups); - foreach ($groups as &$group) { + $group = str_replace('\n', $returnReplace, $group); + $group['type_row'] = 'group'; $returnVar[] = $group; @@ -1033,9 +1029,19 @@ function api_get_tree_agents($trash1, $trahs2, $other, $returnType) $agents = []; } - $agents = str_replace('\n', $returnReplace, $agents); + if ((bool) check_acl($config['id_user'], $id_group, 'AW') === true) { + if (array_search('module_plugin_user', $fields) !== false) { + $module_additional_columns .= ' ,plugin_user as module_plugin_user'; + } + + if (array_search('module_plugin_user', $fields) !== false) { + $module_additional_columns .= ' ,plugin_pass as module_plugin_pass'; + } + } foreach ($agents as $index => &$agent) { + $agent = str_replace('\n', $returnReplace, $agent); + $agent['type_row'] = 'agent'; $returnVar[] = $agent; @@ -1062,9 +1068,9 @@ function api_get_tree_agents($trash1, $trahs2, $other, $returnType) $modules = []; } - $modules = str_replace('\n', $returnReplace, $modules); - foreach ($modules as &$module) { + $module = str_replace('\n', $returnReplace, $module); + $module['type_row'] = 'module'; if ($module['module_macros']) { From 6dbc71713a630366095da8f97594468e7c70ec1f Mon Sep 17 00:00:00 2001 From: "alejandro.campos@artica.es" Date: Tue, 25 Oct 2022 15:52:30 +0200 Subject: [PATCH 005/181] add enable modules massive option --- .../godmode/agentes/module_manager.php | 51 ++++++++++++++++++- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/pandora_console/godmode/agentes/module_manager.php b/pandora_console/godmode/agentes/module_manager.php index 6cfa2685b4..89c9ef5c81 100644 --- a/pandora_console/godmode/agentes/module_manager.php +++ b/pandora_console/godmode/agentes/module_manager.php @@ -454,8 +454,6 @@ if ($module_action === 'delete') { } } else if ($module_action === 'disable') { $id_agent_modules_disable = (array) get_parameter('id_delete'); - - $count_correct_delete_modules = 0; $updated_count = 0; foreach ($id_agent_modules_disable as $id_agent_module_disable) { @@ -499,6 +497,52 @@ if ($module_action === 'delete') { ); } } +} else if ($module_action === 'enable') { + $id_agent_modules_enable = (array) get_parameter('id_delete'); + $updated_count = 0; + + foreach ($id_agent_modules_enable as $id_agent_module_enable) { + $sql = sprintf( + 'UPDATE tagente_modulo + SET disabled = 0 + WHERE id_agente_modulo = %d', + $id_agent_module_enable + ); + + $id_agent_changed[] = modules_get_agentmodule_agent($id_agent_module_enable); + $agent_update_result = db_process_sql_update( + 'tagente', + ['update_module_count' => 1], + ['id_agente' => $id_agent_changed] + ); + + if (db_process_sql($sql) !== false && $agent_update_result !== false) { + $updated_count++; + } + } + + $count_modules_to_enable = count($id_agent_modules_enable); + + if ($updated_count === 0) { + ui_print_error_message( + sprintf( + __('There was a problem completing the operation. Applied to 0/%d modules.'), + $count_modules_to_enable + ) + ); + } else { + if ($updated_count == $count_modules_to_enable) { + ui_print_success_message(__('Operation finished successfully.')); + } else { + ui_print_error_message( + sprintf( + __('There was a problem completing the operation. Applied to %d/%d modules.'), + $updated_count, + $count_modules_to_enable + ) + ); + } + } } @@ -1283,6 +1327,7 @@ if (check_acl_one_of_groups($config['id_user'], $all_groups, 'AW')) { html_print_select( [ 'disable' => 'Disable selected modules', + 'enable' => 'Enable selected modules', 'delete' => 'Delete selected modules', ], 'module_action', @@ -1295,6 +1340,8 @@ if (check_acl_one_of_groups($config['id_user'], $all_groups, 'AW')) { false ); + echo '    '; + html_print_submit_button( __('Execute action'), 'submit_modules_action', From 8d611a8e7fd4f2647b241e1faf89138a84e07478 Mon Sep 17 00:00:00 2001 From: "alejandro.campos@artica.es" Date: Wed, 26 Oct 2022 18:25:16 +0200 Subject: [PATCH 006/181] implemented float formatting and option in reports to change visualization format --- pandora_console/extras/mr/60.sql | 6 ++ .../reporting_builder.item_editor.php | 29 +++++++- .../godmode/reporting/reporting_builder.php | 12 ++++ .../godmode/setup/setup_visuals.php | 21 ++++++ .../include/ajax/custom_fields.php | 4 +- pandora_console/include/ajax/module.php | 12 +++- .../include/class/AgentWizard.class.php | 9 ++- .../include/class/Diagnostics.class.php | 8 ++- pandora_console/include/functions.php | 27 ++++---- pandora_console/include/functions_config.php | 13 ++++ pandora_console/include/functions_html.php | 2 +- pandora_console/include/functions_modules.php | 10 +-- .../include/functions_reporting.php | 67 ++++++++++++++----- .../include/functions_reporting_html.php | 22 ++++-- .../include/functions_treeview.php | 10 +-- pandora_console/include/functions_ui.php | 4 +- .../include/functions_visual_map.php | 14 ++-- .../include/graphs/functions_flot.php | 6 +- .../lib/Dashboard/Widgets/module_icon.php | 2 +- .../lib/Dashboard/Widgets/module_value.php | 4 +- .../models/VisualConsole/Items/Group.php | 10 +-- .../models/VisualConsole/Items/Percentile.php | 4 +- .../VisualConsole/Items/StaticGraph.php | 2 +- .../agentes/pandora_networkmap.view.php | 7 +- .../operation/agentes/status_monitor.php | 44 ++++++++---- pandora_console/pandoradb.sql | 2 + .../extensions/intel_dcm_agent_view.php | 14 ++-- 27 files changed, 270 insertions(+), 95 deletions(-) create mode 100644 pandora_console/extras/mr/60.sql diff --git a/pandora_console/extras/mr/60.sql b/pandora_console/extras/mr/60.sql new file mode 100644 index 0000000000..8d662a5fb7 --- /dev/null +++ b/pandora_console/extras/mr/60.sql @@ -0,0 +1,6 @@ +START TRANSACTION; + +ALTER TABLE treport_content ADD COLUMN use_prefix_notation tinyint(1) default '1'; +ALTER TABLE treport_content_template ADD COLUMN use_prefix_notation tinyint(1) default '1'; + +COMMIT; diff --git a/pandora_console/godmode/reporting/reporting_builder.item_editor.php b/pandora_console/godmode/reporting/reporting_builder.item_editor.php index 3cc78b737c..51653d0ce0 100755 --- a/pandora_console/godmode/reporting/reporting_builder.item_editor.php +++ b/pandora_console/godmode/reporting/reporting_builder.item_editor.php @@ -168,6 +168,7 @@ $visual_format = 0; $filter_search = ''; $filter_exclude = ''; +$use_prefix_notation = true; // Added for select fields. $total_time = true; @@ -460,6 +461,7 @@ switch ($action) { $lapse = $item['lapse']; $lapse_calc = $item['lapse_calc']; $visual_format = $item['visual_format']; + $use_prefix_notation = $item['use_prefix_notation']; break; case 'max_value': @@ -475,6 +477,7 @@ switch ($action) { $lapse = $item['lapse']; $lapse_calc = $item['lapse_calc']; $visual_format = $item['visual_format']; + $use_prefix_notation = $item['use_prefix_notation']; break; case 'min_value': @@ -490,6 +493,7 @@ switch ($action) { $lapse = $item['lapse']; $lapse_calc = $item['lapse_calc']; $visual_format = $item['visual_format']; + $use_prefix_notation = $item['use_prefix_notation']; break; case 'sumatory': @@ -503,6 +507,7 @@ switch ($action) { $idAgentModule = $item['id_agent_module']; $period = $item['period']; $uncompressed_module = $item['uncompressed_module']; + $use_prefix_notation = $item['use_prefix_notation']; break; case 'historical_data': @@ -771,6 +776,7 @@ switch ($action) { $show_resume = $item['show_resume']; $show_graph = $item['show_graph']; $order_uptodown = $item['order_uptodown']; + $use_prefix_notation = $item['use_prefix_notation']; $text_agent = ''; if (isset($style['text_agent']) === true @@ -3407,6 +3413,22 @@ $class = 'databox filters'; + + + + + + + + + data[$row][1] = ''.__('Example').' '.date($config['date_f $table_other->data[$row][1] .= html_print_input_text('date_format', $config['date_format'], '', 30, 100, true); $row++; +$decimal_separators = [ + ',' => ',', + '.' => '.' +]; + +$table_other->data[$row][0] = __('Decimal separator'); +$table_other->data[$row][1] = html_print_select( + $decimal_separators, + 'decimal_separator', + $config['decimal_separator'], + '', + '', + '', + true, + false, + false +); + + +$row++; + if ($config['prominent_time'] == 'comparation') { $timestamp = false; $comparation = true; diff --git a/pandora_console/include/ajax/custom_fields.php b/pandora_console/include/ajax/custom_fields.php index 3fd81ec4b0..77e79800aa 100644 --- a/pandora_console/include/ajax/custom_fields.php +++ b/pandora_console/include/ajax/custom_fields.php @@ -429,7 +429,9 @@ if (check_login()) { $table_modules->data[$key][1] = remove_right_zeros( number_format( $value['datos'], - $config['graph_precision'] + $config['graph_precision'], + $config['decimal_separator'], + $config['thousand_separator'] ) ); } else { diff --git a/pandora_console/include/ajax/module.php b/pandora_console/include/ajax/module.php index c43da3e146..8efb03df12 100755 --- a/pandora_console/include/ajax/module.php +++ b/pandora_console/include/ajax/module.php @@ -499,7 +499,9 @@ if (check_login()) { $data[] = remove_right_zeros( number_format( $row[$attr[0]], - $config['graph_precision'] + $config['graph_precision'], + $config['decimal_separator'], + $config['thousand_separator'] ) ); } @@ -507,7 +509,9 @@ if (check_login()) { $data[] = remove_right_zeros( number_format( $row[$attr[0]], - $config['graph_precision'] + $config['graph_precision'], + $config['decimal_separator'], + $config['thousand_separator'] ) ); } @@ -524,7 +528,9 @@ if (check_login()) { $data[] = remove_right_zeros( number_format( $row[$attr[0]], - $config['graph_precision'] + $config['graph_precision'], + $config['decimal_separator'], + $config['thousand_separator'] ) ); } diff --git a/pandora_console/include/class/AgentWizard.class.php b/pandora_console/include/class/AgentWizard.class.php index dc6bd5df5f..2602b9a0c2 100644 --- a/pandora_console/include/class/AgentWizard.class.php +++ b/pandora_console/include/class/AgentWizard.class.php @@ -2546,6 +2546,8 @@ class AgentWizard extends HTML */ private function resultsInterfaceWizard() { + global $config; + $generalInterfaceModules = $this->getInterfacesModules(); $generalInterfaceTables = []; $generalInterfaceModulesUpdated = []; @@ -2759,7 +2761,12 @@ class AgentWizard extends HTML // Format current value with thousands and decimals. if (is_numeric($currentValue) === true) { $decimals = (is_float($currentValue) === true) ? 2 : 0; - $currentValue = number_format($currentValue, $decimals); + $currentValue = number_format( + $currentValue, + $decimals, + $config['decimal_separator'], + $config['thousand_separator'] + ); } // It unit of measure have data, attach to current value. diff --git a/pandora_console/include/class/Diagnostics.class.php b/pandora_console/include/class/Diagnostics.class.php index b8ca6e3690..5215a09aa3 100644 --- a/pandora_console/include/class/Diagnostics.class.php +++ b/pandora_console/include/class/Diagnostics.class.php @@ -986,7 +986,7 @@ class Diagnostics extends Wizard ], 'tablesFragmentationValue' => [ 'name' => __('Tables fragmentation (current value)'), - 'value' => number_format($tFragmentationValue, 2).'%', + 'value' => number_format($tFragmentationValue, 2, $config['decimal_separator'], $config['thousand_separator']).'%', ], 'tablesFragmentationStatus' => [ 'name' => __('Table fragmentation status'), @@ -1121,7 +1121,9 @@ class Diagnostics extends Wizard if ($totalModuleIntervalTime !== false) { $averageTime = number_format( ((int) $totalNetworkModules / (int) $totalModuleIntervalTime), - 3 + 3, + $config['decimal_separator'], + $config['thousand_separator'] ); } @@ -1748,7 +1750,7 @@ class Diagnostics extends Wizard $sizeServerLog = number_format($fileSize); $sizeServerLog = (0 + str_replace(',', '', $sizeServerLog)); - $value = number_format(($fileSize / $mega), 3); + $value = number_format(($fileSize / $mega), 3, $config['decimal_separator'], $config['thousand_separator']); $message = __('You have more than 10 MB of logs'); $status = 0; if ($sizeServerLog <= $tenMega) { diff --git a/pandora_console/include/functions.php b/pandora_console/include/functions.php index ed999553cb..f2363edc71 100644 --- a/pandora_console/include/functions.php +++ b/pandora_console/include/functions.php @@ -219,6 +219,8 @@ function list_files($directory, $stringSearch, $searchHandler, $return=false) */ function format_numeric($number, $decimals=1) { + global $config; + // Translate to float in case there are characters in the string so // fmod doesn't throw a notice $number = (float) $number; @@ -227,17 +229,11 @@ function format_numeric($number, $decimals=1) return 0; } - // Translators: This is separator of decimal point - $dec_point = __('.'); - // Translators: This is separator of decimal point - $thousands_sep = __(','); - - // If has decimals if (fmod($number, 1) > 0) { - return number_format($number, $decimals, $dec_point, $thousands_sep); + return number_format($number, $decimals, $config['decimal_separator'], $config['thousand_separator']); } - return number_format($number, 0, $dec_point, $thousands_sep); + return number_format($number, 0, $config['decimal_separator'], $config['thousand_separator']); } @@ -4084,14 +4080,18 @@ function series_type_graph_array($data, $show_elements_graph) $data_return['legend'][$key] .= remove_right_zeros( number_format( $value['min'], - $config['graph_precision'] + $config['graph_precision'], + $config['decimal_separator'], + $config['thousand_separator'] ) ); $data_return['legend'][$key] .= ' '.__('Max:'); $data_return['legend'][$key] .= remove_right_zeros( number_format( $value['max'], - $config['graph_precision'] + $config['graph_precision'], + $config['decimal_separator'], + $config['thousand_separator'] ) ); $data_return['legend'][$key] .= ' '._('Avg:'); @@ -4099,7 +4099,8 @@ function series_type_graph_array($data, $show_elements_graph) number_format( $value['avg'], $config['graph_precision'], - $config['csv_decimal_separator'] + $config['decimal_separator'], + $config['thousand_separator'] ) ).' '.$str; } @@ -4156,7 +4157,9 @@ function series_type_graph_array($data, $show_elements_graph) $data_return['legend'][$key] .= remove_right_zeros( number_format( $value['data'][0][1], - $config['graph_precision'] + $config['graph_precision'], + $config['decimal_separator'], + $config['thousand_separator'] ) ).' '.$str; } diff --git a/pandora_console/include/functions_config.php b/pandora_console/include/functions_config.php index 958261274a..8d9e4b0b50 100644 --- a/pandora_console/include/functions_config.php +++ b/pandora_console/include/functions_config.php @@ -1467,6 +1467,15 @@ function config_update_config() if (config_update_value('use_data_multiplier', get_parameter('use_data_multiplier', '1'), true) === false) { $error_update[] = __('Use data multiplier'); } + + if (config_update_value('decimal_separator', (string) get_parameter('decimal_separator', '.'), true) === false) { + $error_update[] = __('Decimal separator'); + } else { + $thousand_separator = ((string) get_parameter('decimal_separator', '.') === '.') ? ',' : '.'; + if (config_update_value('thousand_separator', $thousand_separator, true) === false) { + $error_update[] = __('Thousand separator'); + } + } break; case 'net': @@ -3422,6 +3431,10 @@ function config_process_config() config_update_value('module_library_password', ''); } + if (!isset($config['decimal_separator'])) { + config_update_value('decimal_separator', '.'); + } + // Finally, check if any value was overwritten in a form. config_update_config(); } diff --git a/pandora_console/include/functions_html.php b/pandora_console/include/functions_html.php index ef41904c38..a777f4389c 100644 --- a/pandora_console/include/functions_html.php +++ b/pandora_console/include/functions_html.php @@ -1950,7 +1950,7 @@ function html_print_extended_select_for_post_process( $found = false; if ($selected) { - if (array_key_exists(number_format($selected, 14, '.', ','), $fields)) { + if (array_key_exists(number_format($selected, 14, $config['decimal_separator'], $config['thousand_separator']), $fields)) { $found = true; } } diff --git a/pandora_console/include/functions_modules.php b/pandora_console/include/functions_modules.php index 443e482173..59ead9b943 100755 --- a/pandora_console/include/functions_modules.php +++ b/pandora_console/include/functions_modules.php @@ -2589,12 +2589,12 @@ function modules_get_agentmodule_data_for_humans($module) $salida = human_milliseconds_to_string($module['datos']); } } else { - $salida = remove_right_zeros(number_format($module['datos'], $config['graph_precision'])); + $salida = remove_right_zeros(number_format($module['datos'], $config['graph_precision'], $config['decimal_separator'], $config['thousand_separator'])); } break; default: - $salida = remove_right_zeros(number_format($module['datos'], $config['graph_precision'])); + $salida = remove_right_zeros(number_format($module['datos'], $config['graph_precision'], $config['decimal_separator'], $config['thousand_separator'])); break; } break; @@ -2613,12 +2613,12 @@ function modules_get_agentmodule_data_for_humans($module) $salida = human_milliseconds_to_string($module['datos']); } } else { - $salida = remove_right_zeros(number_format($module['datos'], $config['graph_precision'])); + $salida = remove_right_zeros(number_format($module['datos'], $config['graph_precision'], $config['decimal_separator'], $config['thousand_separator'])); } break; default: - $salida = remove_right_zeros(number_format($module['datos'], $config['graph_precision'])); + $salida = remove_right_zeros(number_format($module['datos'], $config['graph_precision'], $config['decimal_separator'], $config['thousand_separator'])); break; } } @@ -2900,7 +2900,7 @@ function modules_get_status($id_agent_module, $db_status, $data, &$status, &$tit } if (is_numeric($data)) { - $title .= ': '.remove_right_zeros(number_format($data, $config['graph_precision'])); + $title .= ': '.remove_right_zeros(number_format($data, $config['graph_precision'], $config['decimal_separator'], $config['thousand_separator'])); } else { $text = io_safe_output($data); diff --git a/pandora_console/include/functions_reporting.php b/pandora_console/include/functions_reporting.php index ab1e64cfcf..cbd6e276a9 100755 --- a/pandora_console/include/functions_reporting.php +++ b/pandora_console/include/functions_reporting.php @@ -1833,14 +1833,24 @@ function reporting_event_top_n( $divisor = get_data_multiplier($units[$key_dt]); - $data['formated_value'] = format_for_graph( - $dt, - 2, - '.', - ',', - $divisor, - $units[$key_dt] - ); + if ((bool) $content['use_prefix_notation'] === false) { + $data['formated_value'] = number_format( + $dt, + 2, + $config['decimal_separator'], + $config['thousand_separator'] + ).' '.$units[$key_dt]; + } else { + $data['formated_value'] = format_for_graph( + $dt, + 2, + '.', + ',', + $divisor, + $units[$key_dt] + ); + } + $data_return[] = $data; } @@ -1901,14 +1911,25 @@ function reporting_event_top_n( $data['agent'] = $an; $data['module'] = $module_name[$key_an]; $data['value'] = $data_top[$key_an]; - $data['formated_value'] = format_for_graph( - $data_top[$key_an], - 2, - '.', - ',', - $divisor, - $units[$key_an] - ); + + if ((bool) $content['use_prefix_notation'] === false) { + $data['formated_value'] = number_format( + $data_top[$key_an], + 2, + $config['decimal_separator'], + $config['thousand_separator'] + ).' '.$units[$key_an]; + } else { + $data['formated_value'] = format_for_graph( + $data_top[$key_an], + 2, + '.', + ',', + $divisor, + $units[$key_an] + ); + } + $data_return[] = $data; } @@ -6925,6 +6946,13 @@ function reporting_value($report, $content, $type, $pdf=false) if (!$config['simple_module_value']) { $formated_value = $value; + } else if ((bool) $content['use_prefix_notation'] === false) { + $formated_value = number_format( + $value, + $config['graph_precision'], + $config['decimal_separator'], + $config['thousand_separator'] + ).' '.$unit; } else { $formated_value = format_for_graph( $value, @@ -7085,6 +7113,13 @@ function reporting_value($report, $content, $type, $pdf=false) ); if (!$config['simple_module_value']) { $formated_value = $value; + } else if ((bool) $content['use_prefix_notation'] === false) { + $formated_value = number_format( + $value, + $config['graph_precision'], + $config['decimal_separator'], + $config['thousand_separator'] + ).' '.$unit; } else { $divisor = get_data_multiplier($unit); diff --git a/pandora_console/include/functions_reporting_html.php b/pandora_console/include/functions_reporting_html.php index 029b0d70b6..27b7037751 100644 --- a/pandora_console/include/functions_reporting_html.php +++ b/pandora_console/include/functions_reporting_html.php @@ -2283,7 +2283,9 @@ function reporting_html_agent_module_status($table, $item, $pdf=0) $row['data_module'] = remove_right_zeros( number_format( $data['data_module'], - $config['graph_precision'] + $config['graph_precision'], + $config['decimal_separator'], + $config['thousand_separator'] ) ); } else { @@ -2776,7 +2778,7 @@ function reporting_html_historical_data($table, $item, $pdf=0) } else { $row = [ $data[__('Date')], - remove_right_zeros(number_format($data[__('Data')], $config['graph_precision'])), + remove_right_zeros(number_format($data[__('Data')], $config['graph_precision'], $config['decimal_separator'], $config['thousand_separator'])), ]; } @@ -2916,7 +2918,9 @@ function reporting_html_last_value($table, $item, $pdf=0) $dataDatos = remove_right_zeros( number_format( $item['data']['datos'], - $config['graph_precision'] + $config['graph_precision'], + $config['decimal_separator'], + $config['thousand_separator'] ) ); } else { @@ -3461,7 +3465,9 @@ function reporting_html_monitor_report($table, $item, $mini, $pdf=0) ).' '.__('OK').': '.remove_right_zeros( number_format( $item['data']['ok']['value'], - $config['graph_precision'] + $config['graph_precision'], + $config['decimal_separator'], + $config['thousand_separator'] ) ).' %

'; @@ -3472,7 +3478,9 @@ function reporting_html_monitor_report($table, $item, $mini, $pdf=0) ).' '.__('Not OK').': '.remove_right_zeros( number_format( $item['data']['fail']['value'], - $config['graph_precision'] + $config['graph_precision'], + $config['decimal_separator'], + $config['thousand_separator'] ) ).' % '.'

'; } @@ -3826,7 +3834,9 @@ function reporting_html_value( remove_right_zeros( number_format( $data[__('Maximun')], - $config['graph_precision'] + $config['graph_precision'], + $config['decimal_separator'], + $config['thousand_separator'] ) ), ]; diff --git a/pandora_console/include/functions_treeview.php b/pandora_console/include/functions_treeview.php index 3fc35f4d84..e230ba54ca 100755 --- a/pandora_console/include/functions_treeview.php +++ b/pandora_console/include/functions_treeview.php @@ -193,7 +193,7 @@ function treeview_printModuleTable($id_module, $server_data=false, $no_head=fals if ($value == '.1.3.6.1.2.1.1.3.0' || $value == '.1.3.6.1.2.1.25.1.1.0') { $data = "".human_milliseconds_to_string($last_data['datos']).''; } else if (is_numeric($last_data['datos'])) { - $data = "".remove_right_zeros(number_format($last_data['datos'], $config['graph_precision'])).''; + $data = "".remove_right_zeros(number_format($last_data['datos'], $config['graph_precision'], $config['decimal_separator'], $config['thousand_separator'])).''; } else { $data = ui_print_truncate_text( io_safe_output($last_data['datos']), @@ -209,7 +209,7 @@ function treeview_printModuleTable($id_module, $server_data=false, $no_head=fals default: if (is_numeric($last_data['datos'])) { - $data = "".remove_right_zeros(number_format($last_data['datos'], $config['graph_precision'])).''; + $data = "".remove_right_zeros(number_format($last_data['datos'], $config['graph_precision'], $config['decimal_separator'], $config['thousand_separator'])).''; } else { $data = ui_print_truncate_text( io_safe_output($last_data['datos']), @@ -232,7 +232,7 @@ function treeview_printModuleTable($id_module, $server_data=false, $no_head=fals if ($value == '.1.3.6.1.2.1.1.3.0' || $value == '.1.3.6.1.2.1.25.1.1.0') { $data = "".human_milliseconds_to_string($last_data['datos']).''; } else if (is_numeric($last_data['datos'])) { - $data = "".remove_right_zeros(number_format($last_data['datos'], $config['graph_precision'])).''; + $data = "".remove_right_zeros(number_format($last_data['datos'], $config['graph_precision'], $config['decimal_separator'], $config['thousand_separator'])).''; } else { $data = ui_print_truncate_text( io_safe_output($last_data['datos']), @@ -248,7 +248,7 @@ function treeview_printModuleTable($id_module, $server_data=false, $no_head=fals default: if (is_numeric($last_data['datos'])) { - $data = "".remove_right_zeros(number_format($last_data['datos'], $config['graph_precision'])).''; + $data = "".remove_right_zeros(number_format($last_data['datos'], $config['graph_precision'], $config['decimal_separator'], $config['thousand_separator'])).''; } else { $data = ui_print_truncate_text( io_safe_output($last_data['datos']), @@ -271,7 +271,7 @@ function treeview_printModuleTable($id_module, $server_data=false, $no_head=fals $data_macro = modules_get_unit_macro($last_data['datos'], $module['unit']); if ($data_macro) { if (is_numeric($data_macro)) { - $last_data_str = "".remove_right_zeros(number_format($data_macro, $config['graph_precision'])).''; + $last_data_str = "".remove_right_zeros(number_format($data_macro, $config['graph_precision'], $config['decimal_separator'], $config['thousand_separator'])).''; } else { $last_data_str = ui_print_truncate_text( io_safe_output($data_macro), diff --git a/pandora_console/include/functions_ui.php b/pandora_console/include/functions_ui.php index 1e9d9f8dd7..dfc5b5e4ea 100755 --- a/pandora_console/include/functions_ui.php +++ b/pandora_console/include/functions_ui.php @@ -6558,10 +6558,10 @@ function ui_print_comments($comments) } else { $rest_time = (time() - $last_comment[0][0]['utimestamp']); $time_last = (($rest_time / 60) / 60); - $comentario = ''.number_format($time_last, 0).'  Hours  ('.$last_comment[0][0]['id_user'].'): '.$last_comment[0][0]['comment'].''; + $comentario = ''.number_format($time_last, 0, $config['decimal_separator'], $config['thousand_separator']).'  Hours  ('.$last_comment[0][0]['id_user'].'): '.$last_comment[0][0]['comment'].''; if (strlen($comentario) > '200px') { - $comentario = ''.number_format($time_last, 0).'  Hours  ('.$last_comment[0][0]['id_user'].'): '.$short_comment.'...'; + $comentario = ''.number_format($time_last, 0, $config['decimal_separator'], $config['thousand_separator']).'  Hours  ('.$last_comment[0][0]['id_user'].'): '.$short_comment.'...'; } } diff --git a/pandora_console/include/functions_visual_map.php b/pandora_console/include/functions_visual_map.php index fce3aabe2d..97b14e4275 100755 --- a/pandora_console/include/functions_visual_map.php +++ b/pandora_console/include/functions_visual_map.php @@ -924,7 +924,7 @@ function visual_map_print_item( $value_text = format_for_graph($module_value, 2); if ($value_text <= 0) { - $value_text = remove_right_zeros(number_format($module_value, $config['graph_precision'])); + $value_text = remove_right_zeros(number_format($module_value, $config['graph_precision'], $config['decimal_separator'], $config['thousand_separator'])); } if (!empty($unit_text)) { @@ -1743,7 +1743,7 @@ function visual_map_print_item( || (modules_is_boolean($layoutData['id_agente_modulo']) && $layoutData['show_last_value'] != 0) ) { if (is_numeric($value)) { - $img_style_title .= '
'.__('Last value: ').remove_right_zeros(number_format($value, $config['graph_precision'])); + $img_style_title .= '
'.__('Last value: ').remove_right_zeros(number_format($value, $config['graph_precision'], $config['decimal_separator'], $config['thousand_separator'])); } else { $img_style_title .= '
'.__('Last value: ').$value; } @@ -1881,13 +1881,13 @@ function visual_map_print_item( echo ''; echo ""; echo ''; - echo "
".remove_right_zeros(number_format($stat_agent_cr, 2)).'%
'; + echo "
".remove_right_zeros(number_format($stat_agent_cr, 2, $config['decimal_separator'], $config['thousand_separator'])).'%
'; echo "
Critical
"; - echo "
".remove_right_zeros(number_format($stat_agent_wa, 2)).'%
'; + echo "
".remove_right_zeros(number_format($stat_agent_wa, 2, $config['decimal_separator'], $config['thousand_separator'])).'%
'; echo "
Warning
"; - echo "
".remove_right_zeros(number_format($stat_agent_ok, 2)).'%
'; + echo "
".remove_right_zeros(number_format($stat_agent_ok, 2, $config['decimal_separator'], $config['thousand_separator'])).'%
'; echo "
Normal
"; - echo "
".remove_right_zeros(number_format($stat_agent_un, 2)).'%
'; + echo "
".remove_right_zeros(number_format($stat_agent_un, 2, $config['decimal_separator'], $config['thousand_separator'])).'%
'; echo "
Unknown
"; echo ''; echo ''; @@ -2462,7 +2462,7 @@ function visual_map_get_simple_value($type, $id_module, $period=SECONDS_1DAY) } else { if (is_numeric($value)) { if ($config['simple_module_value']) { - $value = remove_right_zeros(number_format($value, $config['graph_precision'])); + $value = remove_right_zeros(number_format($value, $config['graph_precision'], $config['decimal_separator'], $config['thousand_separator'])); } } diff --git a/pandora_console/include/graphs/functions_flot.php b/pandora_console/include/graphs/functions_flot.php index 8f5256e757..821b85c4d6 100644 --- a/pandora_console/include/graphs/functions_flot.php +++ b/pandora_console/include/graphs/functions_flot.php @@ -499,11 +499,11 @@ function flot_custom_pie_chart( foreach ($graph_values as $label => $value) { if ($value['value']) { if ($value['value'] > 1000000) { - $legendvalue = sprintf('%sM', remove_right_zeros(number_format(($value['value'] / 1000000), $config['graph_precision']))); + $legendvalue = sprintf('%sM', remove_right_zeros(number_format(($value['value'] / 1000000), $config['graph_precision'], $config['decimal_separator'], $config['thousand_separator']))); } else if ($value['value'] > 1000) { - $legendvalue = sprintf('%sK', remove_right_zeros(number_format(($value['value'] / 1000), $config['graph_precision']))); + $legendvalue = sprintf('%sK', remove_right_zeros(number_format(($value['value'] / 1000), $config['graph_precision'], $config['decimal_separator'], $config['thousand_separator']))); } else { - $legendvalue = remove_right_zeros(number_format($value['value'], $config['graph_precision'])); + $legendvalue = remove_right_zeros(number_format($value['value'], $config['graph_precision'], $config['decimal_separator'], $config['thousand_separator'])); } } else { $legendvalue = __('No data'); diff --git a/pandora_console/include/lib/Dashboard/Widgets/module_icon.php b/pandora_console/include/lib/Dashboard/Widgets/module_icon.php index 3b1adc888b..5523a851ef 100644 --- a/pandora_console/include/lib/Dashboard/Widgets/module_icon.php +++ b/pandora_console/include/lib/Dashboard/Widgets/module_icon.php @@ -555,7 +555,7 @@ class ModuleIconWidget extends Widget // Div value. $output .= '
'; $output .= remove_right_zeros( - number_format($data_module, $config['graph_precision']) + number_format($data_module, $config['graph_precision'], $config['decimal_separator'], $config['thousand_separator']) ); $output .= '
'; diff --git a/pandora_console/include/lib/Dashboard/Widgets/module_value.php b/pandora_console/include/lib/Dashboard/Widgets/module_value.php index 41fdd41663..6577ad3c89 100644 --- a/pandora_console/include/lib/Dashboard/Widgets/module_value.php +++ b/pandora_console/include/lib/Dashboard/Widgets/module_value.php @@ -439,7 +439,9 @@ class ModuleValueWidget extends Widget $dataDatos = remove_right_zeros( number_format( $data_module, - $config['graph_precision'] + $config['graph_precision'], + $config['decimal_separator'], + $config['thousand_separator'] ) ); } else { diff --git a/pandora_console/include/rest-api/models/VisualConsole/Items/Group.php b/pandora_console/include/rest-api/models/VisualConsole/Items/Group.php index 27b400db97..50fca70543 100644 --- a/pandora_console/include/rest-api/models/VisualConsole/Items/Group.php +++ b/pandora_console/include/rest-api/models/VisualConsole/Items/Group.php @@ -397,10 +397,12 @@ final class Group extends Item string $groupName, array $agentStats ): string { - $critical = \number_format($agentStats['critical'], 2).'%'; - $warning = \number_format($agentStats['warning'], 2).'%'; - $normal = \number_format($agentStats['normal'], 2).'%'; - $unknown = \number_format($agentStats['unknown'], 2).'%'; + global $config; + + $critical = \number_format($agentStats['critical'], 2, $config['decimal_separator'], $config['thousand_separator']).'%'; + $warning = \number_format($agentStats['warning'], 2, $config['decimal_separator'], $config['thousand_separator']).'%'; + $normal = \number_format($agentStats['normal'], 2, $config['decimal_separator'], $config['thousand_separator']).'%'; + $unknown = \number_format($agentStats['unknown'], 2, $config['decimal_separator'], $config['thousand_separator']).'%'; $html = '
'; $html .= '
'; diff --git a/pandora_console/include/rest-api/models/VisualConsole/Items/Percentile.php b/pandora_console/include/rest-api/models/VisualConsole/Items/Percentile.php index 19e14f3456..657f73364d 100644 --- a/pandora_console/include/rest-api/models/VisualConsole/Items/Percentile.php +++ b/pandora_console/include/rest-api/models/VisualConsole/Items/Percentile.php @@ -396,8 +396,8 @@ final class Percentile extends Item $data['value'] = (float) \number_format( (float) $moduleValue, (int) $config['graph_precision'], - '.', - '' + $config['decimal_separator'], + $config['thousand_separator'] ); $unit = ''; if ($moduleId !== null && $moduleId !== 0) { diff --git a/pandora_console/include/rest-api/models/VisualConsole/Items/StaticGraph.php b/pandora_console/include/rest-api/models/VisualConsole/Items/StaticGraph.php index adeaa9c29e..4eb1ba3abc 100644 --- a/pandora_console/include/rest-api/models/VisualConsole/Items/StaticGraph.php +++ b/pandora_console/include/rest-api/models/VisualConsole/Items/StaticGraph.php @@ -281,7 +281,7 @@ final class StaticGraph extends Item ) { if (\is_numeric($value)) { $imgTitle .= __('Last value: ').\remove_right_zeros( - \number_format((float) $value, (int) $config['graph_precision']) + \number_format((float) $value, (int) $config['graph_precision'], $config['decimal_separator'], $config['thousand_separator']) ); } else { $imgTitle .= __('Last value: ').$value; diff --git a/pandora_console/operation/agentes/pandora_networkmap.view.php b/pandora_console/operation/agentes/pandora_networkmap.view.php index ac888a13fa..6d118d6e10 100644 --- a/pandora_console/operation/agentes/pandora_networkmap.view.php +++ b/pandora_console/operation/agentes/pandora_networkmap.view.php @@ -2048,7 +2048,12 @@ if (is_ajax() === true) { $array_filter = json_decode($networkmap['filter']); if (isset($array_filter->z_dash)) { - $array_filter->z_dash = number_format($scale, 2); + $array_filter->z_dash = number_format( + $scale, + 2, + $config['decimal_separator'], + $config['thousand_separator'] + ); } $filter = json_encode($array_filter); diff --git a/pandora_console/operation/agentes/status_monitor.php b/pandora_console/operation/agentes/status_monitor.php index 320282e403..b0c7c3eba1 100644 --- a/pandora_console/operation/agentes/status_monitor.php +++ b/pandora_console/operation/agentes/status_monitor.php @@ -1589,7 +1589,7 @@ if (!empty($result)) { if (is_numeric($row['datos'])) { $data[6] = ui_print_status_image( STATUS_MODULE_OK, - __('NORMAL').': '.remove_right_zeros(number_format($row['datos'], $config['graph_precision'])), + __('NORMAL').': '.remove_right_zeros(number_format($row['datos'], $config['graph_precision'], $config['decimal_separator'], $config['thousand_separator'])), true ); } else { @@ -1604,7 +1604,12 @@ if (!empty($result)) { $data[6] = ui_print_status_image( STATUS_MODULE_CRITICAL, __('CRITICAL').': '.remove_right_zeros( - number_format($row['datos'], $config['graph_precision']) + number_format( + $row['datos'], + $config['graph_precision'], + $config['decimal_separator'], + $config['thousand_separator'] + ) ), true ); @@ -1620,7 +1625,12 @@ if (!empty($result)) { $data[6] = ui_print_status_image( STATUS_MODULE_WARNING, __('WARNING').': '.remove_right_zeros( - number_format($row['datos'], $config['graph_precision']) + number_format( + $row['datos'], + $config['graph_precision'], + $config['decimal_separator'], + $config['thousand_separator'] + ) ), true ); @@ -1636,7 +1646,12 @@ if (!empty($result)) { $data[6] = ui_print_status_image( STATUS_MODULE_UNKNOWN, __('UNKNOWN').': '.remove_right_zeros( - number_format($row['datos'], $config['graph_precision']) + number_format( + $row['datos'], + $config['graph_precision'], + $config['decimal_separator'], + $config['thousand_separator'] + ) ), true ); @@ -1652,7 +1667,12 @@ if (!empty($result)) { $data[6] = ui_print_status_image( STATUS_MODULE_NO_DATA, __('NO DATA').': '.remove_right_zeros( - number_format($row['datos'], $config['graph_precision']) + number_format( + $row['datos'], + $config['graph_precision'], + $config['decimal_separator'], + $config['thousand_separator'] + ) ), true ); @@ -1672,7 +1692,7 @@ if (!empty($result)) { if (is_numeric($row['datos'])) { $data[6] = ui_print_status_image( STATUS_MODULE_UNKNOWN, - __('UNKNOWN').' - '.__('Last status').' '.__('NORMAL').': '.remove_right_zeros(number_format($row['datos'], $config['graph_precision'])), + __('UNKNOWN').' - '.__('Last status').' '.__('NORMAL').': '.remove_right_zeros(number_format($row['datos'], $config['graph_precision'], $config['decimal_separator'], $config['thousand_separator'])), true ); } else { @@ -1688,7 +1708,7 @@ if (!empty($result)) { if (is_numeric($row['datos'])) { $data[6] = ui_print_status_image( STATUS_MODULE_UNKNOWN, - __('UNKNOWN').' - '.__('Last status').' '.__('CRITICAL').': '.remove_right_zeros(number_format($row['datos'], $config['graph_precision'])), + __('UNKNOWN').' - '.__('Last status').' '.__('CRITICAL').': '.remove_right_zeros(number_format($row['datos'], $config['graph_precision'], $config['decimal_separator'], $config['thousand_separator'])), true ); } else { @@ -1704,7 +1724,7 @@ if (!empty($result)) { if (is_numeric($row['datos'])) { $data[6] = ui_print_status_image( STATUS_MODULE_UNKNOWN, - __('UNKNOWN').' - '.__('Last status').' '.__('WARNING').': '.remove_right_zeros(number_format($row['datos'], $config['graph_precision'])), + __('UNKNOWN').' - '.__('Last status').' '.__('WARNING').': '.remove_right_zeros(number_format($row['datos'], $config['graph_precision'], $config['decimal_separator'], $config['thousand_separator'])), true ); } else { @@ -1849,12 +1869,12 @@ if (!empty($result)) { if ($value == '.1.3.6.1.2.1.1.3.0' || $value == '.1.3.6.1.2.1.25.1.1.0') { $salida = human_milliseconds_to_string($row['datos']); } else { - $salida = remove_right_zeros(number_format($row['datos'], $config['graph_precision'])); + $salida = remove_right_zeros(number_format($row['datos'], $config['graph_precision'], $config['decimal_separator'], $config['thousand_separator'])); } break; default: - $salida = remove_right_zeros(number_format($row['datos'], $config['graph_precision'])); + $salida = remove_right_zeros(number_format($row['datos'], $config['graph_precision'], $config['decimal_separator'], $config['thousand_separator'])); break; } break; @@ -1866,12 +1886,12 @@ if (!empty($result)) { if ($value == '.1.3.6.1.2.1.1.3.0' || $value == '.1.3.6.1.2.1.25.1.1.0') { $salida = human_milliseconds_to_string($row['datos']); } else { - $salida = remove_right_zeros(number_format($row['datos'], $config['graph_precision'])); + $salida = remove_right_zeros(number_format($row['datos'], $config['graph_precision'], $config['decimal_separator'], $config['thousand_separator'])); } break; default: - $salida = remove_right_zeros(number_format($row['datos'], $config['graph_precision'])); + $salida = remove_right_zeros(number_format($row['datos'], $config['graph_precision'], $config['decimal_separator'], $config['thousand_separator'])); break; } } diff --git a/pandora_console/pandoradb.sql b/pandora_console/pandoradb.sql index 880f77063f..304010ca75 100644 --- a/pandora_console/pandoradb.sql +++ b/pandora_console/pandoradb.sql @@ -1617,6 +1617,7 @@ CREATE TABLE IF NOT EXISTS `treport_content` ( `ipam_ip_not_assigned_to_agent` TINYINT UNSIGNED NOT NULL DEFAULT 0, `macros_definition` TEXT, `render_definition` TEXT, + `use_prefix_notation` TINYINT UNSIGNED NOT NULL DEFAULT 1, PRIMARY KEY(`id_rc`), FOREIGN KEY (`id_report`) REFERENCES treport(`id_report`) ON UPDATE CASCADE ON DELETE CASCADE @@ -3244,6 +3245,7 @@ CREATE TABLE IF NOT EXISTS `treport_content_template` ( `ipam_ip_not_assigned_to_agent` TINYINT UNSIGNED NOT NULL DEFAULT 0, `macros_definition` TEXT, `render_definition` TEXT, + `use_prefix_notation` TINYINT UNSIGNED NOT NULL DEFAULT 1, PRIMARY KEY(`id_rc`) ) ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4; diff --git a/pandora_plugins/intel_dcm/extensions/intel_dcm_agent_view.php b/pandora_plugins/intel_dcm/extensions/intel_dcm_agent_view.php index bdc1186044..737aa70770 100644 --- a/pandora_plugins/intel_dcm/extensions/intel_dcm_agent_view.php +++ b/pandora_plugins/intel_dcm/extensions/intel_dcm_agent_view.php @@ -142,26 +142,26 @@ function main_intel_dcm_agent_view() $sql = "SELECT description FROM tagent_custom_data WHERE id_field = $id_field_derated_power AND id_agent = $id_agent"; $derated_power = db_get_value_sql($sql); - $percent = number_format((($avg_power / $derated_power) * 100), 2); + $percent = number_format((($avg_power / $derated_power) * 100), 2, $config['decimal_separator'], $config['thousand_separator']); $data[0] = ''.__('Power utilization')." $percent%"; $data[0] .= progress_bar($percent, 400, 30, '', 2); $data[0] .= '

'; $data[0] .= ''.__('Current stats').''; $data[0] .= '

'; - $data[0] .= __('Power demand').': '.number_format($avg_power, 2).' Wh'; + $data[0] .= __('Power demand').': '.number_format($avg_power, 2, $config['decimal_separator'], $config['thousand_separator']).' Wh'; $data[0] .= '
'; - $data[0] .= __('Inlet temp').': '.number_format($avg_temp, 2).' ºC'; + $data[0] .= __('Inlet temp').': '.number_format($avg_temp, 2, $config['decimal_separator'], $config['thousand_separator']).' ºC'; $data[0] .= '


'; $data[0] .= ''.__('Last week summary').''; $data[0] .= '

'; - $data[0] .= __('Equipment energy consumed').': '.number_format($mnged_energy, 2).' Wh'; + $data[0] .= __('Equipment energy consumed').': '.number_format($mnged_energy, 2, $config['decimal_separator'], $config['thousand_separator']).' Wh'; $data[0] .= '
'; - $data[0] .= __('Equipment energy bill').': '.number_format($mnged_energy_bill, 2).' €'; + $data[0] .= __('Equipment energy bill').': '.number_format($mnged_energy_bill, 2, $config['decimal_separator'], $config['thousand_separator']).' €'; $data[0] .= '
'; - $data[0] .= __('Calculated cooling energy').': '.number_format($cooling_energy, 2).' Wh'; + $data[0] .= __('Calculated cooling energy').': '.number_format($cooling_energy, 2, $config['decimal_separator'], $config['thousand_separator']).' Wh'; $data[0] .= '
'; - $data[0] .= __('Calculated cooling energy bill').': '.number_format($cooling_energy_bill, 2).' €'; + $data[0] .= __('Calculated cooling energy bill').': '.number_format($cooling_energy_bill, 2, $config['decimal_separator'], $config['thousand_separator']).' €'; // Print avg. power graph $start_date = date('Y-m-d'); From 548308405c2862a268831acc5628178e4db2f0a2 Mon Sep 17 00:00:00 2001 From: Daniel Maya Date: Thu, 27 Oct 2022 09:40:33 +0200 Subject: [PATCH 007/181] #9447 WIP --- pandora_server/util/pandora_manage.pl | 31 +++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/pandora_server/util/pandora_manage.pl b/pandora_server/util/pandora_manage.pl index 17a62f37dc..4ce5d40ae9 100755 --- a/pandora_server/util/pandora_manage.pl +++ b/pandora_server/util/pandora_manage.pl @@ -21,7 +21,7 @@ use JSON qw(decode_json encode_json); use MIME::Base64; use Encode qw(decode encode_utf8); use LWP::Simple; -#use Data::Dumper; +use Data::Dumper; # Default lib dir for RPM and DEB packages BEGIN { push @INC, '/usr/lib/perl5'; } @@ -1144,6 +1144,22 @@ sub help_screen_line($$$){ print "\n\t$option $parameters : $help.\n" unless ($param ne '' && $param ne $option); } +sub test ($) { + my (@item) = @_; + my @args = @ARGV; + my $arg_cont = 2; + my $total = $#args; + + print_log Dumper(@item); + + # print_log "$item[0]{name}\n\n"; + + while ($arg_cont <= $total) { + print_log "$args[$arg_cont]\n\n"; + $arg_cont++; + } +} + ############################################################################### ############################################################################### # CLI FUNCTIONS @@ -7648,9 +7664,16 @@ sub pandora_manage_main ($$$) { cli_delete_profile(); } elsif ($param eq '--create_event') { - param_check($ltotal, 20, 17); - cli_create_event(); - } + my @items = ( + {'type' => 'string', 'name' => 'user'}, + {'type' => 'int', 'name' => 'group'} + ); + + test(\@items); + # param_check($ltotal, 20, 17); + + # cli_create_event(); + } elsif ($param eq '--validate_event') { param_check($ltotal, 8, 7); cli_validate_event(); From a96eb2ce299a1cf122c89e2db3876459526c19b9 Mon Sep 17 00:00:00 2001 From: Calvo Date: Thu, 27 Oct 2022 12:35:31 +0200 Subject: [PATCH 008/181] Hide meta treeview user hash --- pandora_console/include/functions_treeview.php | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/pandora_console/include/functions_treeview.php b/pandora_console/include/functions_treeview.php index 3fc35f4d84..ef7107ae7a 100755 --- a/pandora_console/include/functions_treeview.php +++ b/pandora_console/include/functions_treeview.php @@ -594,10 +594,10 @@ function treeview_printTable($id_agente, $server_data=[], $no_head=false) $hashdata = $user.$pwd_deserialiced['auth_token']; $hashdata = md5($hashdata); - $url = $server_data['server_url'].'/index.php?'.'sec=estado&'.'sec2=operation/agentes/ver_agente&'.'id_agente='.$agent['id_agente'].'&'.'loginhash=auto&'."loginhash_data=$hashdata&".'loginhash_user='.str_rot13($user); + $url = $server_data['server_url'].'/index.php?'.'sec=estado&'.'sec2=operation/agentes/ver_agente&'.'id_agente='.$agent['id_agente']; if ($grants_on_node && (bool) $user_access_node !== false) { - $cellName .= ''.''.$agent['alias'].''; + $cellName .= ''.$agent['alias'].''; } else { $cellName .= ''.$agent['alias'].''; } @@ -703,7 +703,7 @@ function treeview_printTable($id_agente, $server_data=[], $no_head=false) $go_to_agent .= html_print_submit_button(__('Edit cluster'), 'upd_button', false, 'class="sub config"', true); } } else { - $go_to_agent .= ''; + $go_to_agent .= ''; $go_to_agent .= html_print_submit_button(__('Go to agent edition'), 'upd_button', false, 'class="sub config"', true); } @@ -905,5 +905,12 @@ function treeview_printTable($id_agente, $server_data=[], $no_head=false) metaconsole_restore_db(); } - return; + echo " + "; } From eed83616214b4bef4123148522cad6aabee8bf22 Mon Sep 17 00:00:00 2001 From: Calvo Date: Thu, 27 Oct 2022 15:03:50 +0200 Subject: [PATCH 009/181] Check group and profile exist on api add permission user to group --- pandora_console/include/functions_api.php | 26 +++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/pandora_console/include/functions_api.php b/pandora_console/include/functions_api.php index 0f5f01590d..0c9c13839e 100644 --- a/pandora_console/include/functions_api.php +++ b/pandora_console/include/functions_api.php @@ -17185,6 +17185,32 @@ function api_set_add_permission_user_to_group($thrash1, $thrash2, $other, $retur ]; + $group_exist = db_get_value_filter( + 'id_grupo', + 'tgrupo', + [ + 'id_grupo' => $values['id_grupo'], + ] + ); + + if ((bool) $group_exist === false) { + returnError('Selected group does not exist'); + return; + } + + $profile_exist = db_get_value_filter( + 'id_perfil', + 'tperfil', + [ + 'id_perfil' => $values['id_perfil'], + ] + ); + + if ((bool) $profile_exist === false) { + returnError('Selected profile does not exist'); + return; + } + $where_id_up = ['id_up' => $other['data'][4]]; if ($exist_profile === $other['data'][4] && $where_id_up !== null) { $sucessfull_insert = db_process_sql_update('tusuario_perfil', $values, $where_id_up); From 8a43421b49aad8d5ee2a72d44a4a41247de2d35e Mon Sep 17 00:00:00 2001 From: Calvo Date: Thu, 27 Oct 2022 15:18:15 +0200 Subject: [PATCH 010/181] Fix module type validadion on api set create network module --- pandora_console/include/functions_api.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/pandora_console/include/functions_api.php b/pandora_console/include/functions_api.php index 0f5f01590d..8b8c46e7c3 100644 --- a/pandora_console/include/functions_api.php +++ b/pandora_console/include/functions_api.php @@ -3587,6 +3587,19 @@ function api_set_create_network_module($id, $thrash1, $other, $thrash3) // Column 'module_macros' cannot be null. } + $type_exist = db_get_value_filter( + 'id_tipo', + 'ttipo_modulo', + [ + 'id_tipo' => $values['id_tipo_modulo'], + ] + ); + + if ((bool) $type_exist === false) { + returnError('Module type does not exist'); + return; + } + if ($agent_by_alias) { $agents_affected = 0; $idModule = false; From f4693b3cba3f1c3f36272d9d1f7e9852be3398de Mon Sep 17 00:00:00 2001 From: Daniel Maya Date: Mon, 31 Oct 2022 16:59:38 +0100 Subject: [PATCH 011/181] #9447 Added check_value --- pandora_server/util/pandora_manage.pl | 103 ++++++++++++++++++++++---- 1 file changed, 90 insertions(+), 13 deletions(-) diff --git a/pandora_server/util/pandora_manage.pl b/pandora_server/util/pandora_manage.pl index 4ce5d40ae9..19bf26c81d 100755 --- a/pandora_server/util/pandora_manage.pl +++ b/pandora_server/util/pandora_manage.pl @@ -1144,18 +1144,54 @@ sub help_screen_line($$$){ print "\n\t$option $parameters : $help.\n" unless ($param ne '' && $param ne $option); } -sub test ($) { - my (@item) = @_; - my @args = @ARGV; +sub check_values($) { + my ($check) = @_; + use experimental 'smartmatch'; + my $arg_cont = 2; + my $cont = 0; + my @args = @ARGV; my $total = $#args; - print_log Dumper(@item); - - # print_log "$item[0]{name}\n\n"; - while ($arg_cont <= $total) { - print_log "$args[$arg_cont]\n\n"; + # Check type. + if ($check->[$cont]->{'type'} eq 'json') { + my $json_out = eval { decode_json($args[$arg_cont]) }; + if ($@) + { + print "\nValue `$args[$arg_cont]` is an invalid json. \nError:$@\n"; + exit; + } + } + + # Check values. + if (defined($check->[$cont]->{'values'})) { + if (!($args[$arg_cont] ~~ $check->[$cont]->{'values'})) { + print "\nError: value `$args[$arg_cont]` is not valid for $check->[$cont]->{'name'}\n"; + print "\tAvailable options: \t$check->[$cont]->{'values'}->[0]"; + if (defined($check->[$cont]->{'text_extra'}->[0])) { + print " $check->[$cont]->{'text_extra'}->[0]"; + } + print "\n"; + + my $cont_aux = 1; + my $while = 'false'; + while ($while eq 'false') { + if (defined($check->[$cont]->{'values'}->[$cont_aux])) { + print "\t\t\t\t$check->[$cont]->{'values'}->[$cont_aux]"; + if (defined($check->[$cont]->{'text_extra'}->[$cont_aux])) { + print " $check->[$cont]->{'text_extra'}->[$cont_aux]"; + } + print "\n"; + } else { + exit; + } + $cont_aux++; + } + } + } + + $cont++; $arg_cont++; } } @@ -7664,13 +7700,54 @@ sub pandora_manage_main ($$$) { cli_delete_profile(); } elsif ($param eq '--create_event') { - my @items = ( - {'type' => 'string', 'name' => 'user'}, - {'type' => 'int', 'name' => 'group'} + my @fields = ( + {'name' => 'event'}, + { + 'name' => 'event_type', + 'values' => [ + 'unknown','alert_fired','alert_recovered','alert_ceased', + 'alert_manual_validation','recon_host_detected','system', + 'error','new_agent','going_up_warning','going_up_criticalgoing_down_warning', + 'going_down_normal','going_down_critical','going_up_normal','configuration_change' + ] + }, + {'name' => 'group_name'}, + {'name' => 'agent_name'}, + {'name' => 'module_name'}, + { + 'name' => 'event_status', + 'values' => ['0', '1'], + 'text_extra' => ['(New)', '(Validated)'] + }, + { + 'name' => 'severity', + 'values' => ['0', '1', '2', '3', '4', '5', '6'], + 'text_extra' => [ + '(Maintenance)', '(Informational)', '(Normal)', + '(Warning)', '(Critical)', '(Minor)', '(Major)' + ] + }, + {'name' => 'template_name'}, + {'name' => 'user_name'}, + {'name' => 'comment'}, + {'name' => 'source'}, + {'name' => 'id_extra'}, + {'name' => 'tags'}, + {'type' => 'json', 'name' => 'custom_data_json'}, + { + 'name' => 'force_create_agent', + 'values' => ['0', '1'] + }, + {'name' => 'critical_instructions'}, + {'name' => 'warning_instructions'}, + {'name' => 'unknown_instructions'}, + {'name' => 'use_alias'}, + {'name' => 'metaconsole'} ); - test(\@items); - # param_check($ltotal, 20, 17); + param_check($ltotal, 20, 17); + + check_values(\@fields); # cli_create_event(); } From 8971dba9c5f25c9fdb39e319b9f032fb77084ab3 Mon Sep 17 00:00:00 2001 From: Daniel Maya Date: Mon, 31 Oct 2022 17:16:08 +0100 Subject: [PATCH 012/181] #9447 uncomment --- pandora_server/util/pandora_manage.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandora_server/util/pandora_manage.pl b/pandora_server/util/pandora_manage.pl index 19bf26c81d..3a90ea074a 100755 --- a/pandora_server/util/pandora_manage.pl +++ b/pandora_server/util/pandora_manage.pl @@ -7749,7 +7749,7 @@ sub pandora_manage_main ($$$) { check_values(\@fields); - # cli_create_event(); + cli_create_event(); } elsif ($param eq '--validate_event') { param_check($ltotal, 8, 7); From 0ff07d7224dcad2ca44a26be92a2ee581384aca0 Mon Sep 17 00:00:00 2001 From: Daniel Barbero Date: Wed, 2 Nov 2022 16:59:04 +0100 Subject: [PATCH 013/181] add new macro event response group_contact pandora_enterprise#9246 --- pandora_console/include/functions_events.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pandora_console/include/functions_events.php b/pandora_console/include/functions_events.php index 3aa121ec6a..f034e48ca1 100644 --- a/pandora_console/include/functions_events.php +++ b/pandora_console/include/functions_events.php @@ -3721,6 +3721,15 @@ function events_get_response_target( ); } + if (strpos($target, '_group_contact_') !== false) { + $info_groups = groups_get_group_by_id($event['id_grupo']); + $target = str_replace( + '_group_contact_', + (isset($info_groups['contact']) === true) ? $info_groups['contact'] : 'N/A', + $target + ); + } + if (strpos($target, '_event_utimestamp_') !== false) { $target = str_replace( '_event_utimestamp_', From 33b1c0ab8f560664feb21c10bdb8ed6bc24f21df Mon Sep 17 00:00:00 2001 From: Daniel Barbero Date: Thu, 3 Nov 2022 12:00:58 +0100 Subject: [PATCH 014/181] add new filter pandora_enterprise#9135 --- pandora_console/extras/mr/59.sql | 5 + .../godmode/events/event_edit_filter.php | 94 +++++++++++-------- pandora_console/include/ajax/events.php | 7 ++ pandora_console/include/functions_events.php | 11 ++- pandora_console/operation/events/events.php | 18 ++++ pandora_console/pandoradb.sql | 1 + 6 files changed, 98 insertions(+), 38 deletions(-) create mode 100644 pandora_console/extras/mr/59.sql diff --git a/pandora_console/extras/mr/59.sql b/pandora_console/extras/mr/59.sql new file mode 100644 index 0000000000..69f93d9e8a --- /dev/null +++ b/pandora_console/extras/mr/59.sql @@ -0,0 +1,5 @@ +START TRANSACTION; + +ALTER TABLE `tevent_filter` ADD COLUMN `owner_user` INT NOT NULL DEFAULT 0; + +COMMIT; \ No newline at end of file diff --git a/pandora_console/godmode/events/event_edit_filter.php b/pandora_console/godmode/events/event_edit_filter.php index af086d55d7..c796feaa90 100644 --- a/pandora_console/godmode/events/event_edit_filter.php +++ b/pandora_console/godmode/events/event_edit_filter.php @@ -73,6 +73,7 @@ if ($id) { $pagination = $filter['pagination']; $event_view_hr = $filter['event_view_hr']; $id_user_ack = $filter['id_user_ack']; + $owner_user = $filter['owner_user']; $group_rep = $filter['group_rep']; $date_from = str_replace('-', '/', $filter['date_from']); $date_to = str_replace('-', '/', $filter['date_to']); @@ -119,6 +120,7 @@ if ($id) { $pagination = ''; $event_view_hr = ''; $id_user_ack = ''; + $owner_user = ''; $group_rep = ''; $date_from = ''; $date_to = ''; @@ -157,6 +159,7 @@ if ($update || $create) { $pagination = get_parameter('pagination', ''); $event_view_hr = get_parameter('event_view_hr', ''); $id_user_ack = get_parameter('id_user_ack', ''); + $owner_user = get_parameter('owner_user', ''); $group_rep = get_parameter('group_rep', ''); $date_from = get_parameter('date_from', ''); $date_to = get_parameter('date_to', ''); @@ -191,6 +194,7 @@ if ($update || $create) { 'pagination' => $pagination, 'event_view_hr' => $event_view_hr, 'id_user_ack' => $id_user_ack, + 'owner_user' => $owner_user, 'group_rep' => $group_rep, 'tag_with' => $tag_with_json, 'tag_without' => $tag_without_json, @@ -420,7 +424,12 @@ $table->data[9][1] = html_print_input_text( true ); -$table->data[10][0] = ''.__('User ack.').''.' '.ui_print_help_tip(__('Choose between the users who have validated an event. '), true); +$table->data[10][0] = ''.__('User ack.').''; +$table->data[10][0] .= ' '; +$table->data[10][0] .= ui_print_help_tip( + __('Choose between the users who have validated an event. '), + true +); if ($strict_user) { $users = [$config['id_user'] => $config['id_user']]; @@ -442,14 +451,25 @@ $table->data[10][1] = html_print_select( true ); +$table->data[11][0] = ''.__('Owner.').''; +$table->data[11][1] = html_print_select( + $users, + 'owner_user', + $owner_user, + '', + __('Any'), + 0, + true +); + $repeated_sel = [ EVENT_GROUP_REP_ALL => __('All events'), EVENT_GROUP_REP_EVENTS => __('Group events'), EVENT_GROUP_REP_AGENTS => __('Group agents'), EVENT_GROUP_REP_EXTRAIDS => __('Group extra id'), ]; -$table->data[11][0] = ''.__('Repeated').''; -$table->data[11][1] = html_print_select( +$table->data[12][0] = ''.__('Repeated').''; +$table->data[12][1] = html_print_select( $repeated_sel, 'group_rep', $group_rep, @@ -459,11 +479,11 @@ $table->data[11][1] = html_print_select( true ); -$table->data[12][0] = ''.__('Date from').''; -$table->data[12][1] = html_print_input_text('date_from', $date_from, '', 15, 10, true); +$table->data[13][0] = ''.__('Date from').''; +$table->data[13][1] = html_print_input_text('date_from', $date_from, '', 15, 10, true); -$table->data[13][0] = ''.__('Date to').''; -$table->data[13][1] = html_print_input_text('date_to', $date_to, '', 15, 10, true); +$table->data[14][0] = ''.__('Date to').''; +$table->data[14][1] = html_print_input_text('date_to', $date_to, '', 15, 10, true); $tag_with = json_decode($tag_with_json_clean, true); if (empty($tag_with)) { @@ -502,9 +522,9 @@ $remove_with_tag_disabled = empty($tag_with_temp); $add_without_tag_disabled = empty($tags_select_without); $remove_without_tag_disabled = empty($tag_without_temp); -$table->colspan[14][0] = '2'; -$table->data[14][0] = ''.__('Events with following tags').''; -$table->data[15][0] = html_print_select( +$table->colspan[15][0] = '2'; +$table->data[15][0] = ''.__('Events with following tags').''; +$table->data[16][0] = html_print_select( $tags_select_with, 'select_with', '', @@ -518,7 +538,7 @@ $table->data[15][0] = html_print_select( false, 'width: 220px;' ); -$table->data[15][1] = html_print_button( +$table->data[16][1] = html_print_button( __('Add'), 'add_whith', $add_with_tag_disabled, @@ -527,7 +547,7 @@ $table->data[15][1] = html_print_button( true ); -$table->data[16][0] = html_print_select( +$table->data[17][0] = html_print_select( $tag_with_temp, 'tag_with_temp', [], @@ -541,12 +561,12 @@ $table->data[16][0] = html_print_select( false, 'width: 220px; height: 50px;' ); -$table->data[16][0] .= html_print_input_hidden( +$table->data[17][0] .= html_print_input_hidden( 'tag_with', $tag_with_base64, true ); -$table->data[16][1] = html_print_button( +$table->data[17][1] = html_print_button( __('Remove'), 'remove_whith', $remove_with_tag_disabled, @@ -555,9 +575,9 @@ $table->data[16][1] = html_print_button( true ); -$table->colspan[17][0] = '2'; -$table->data[17][0] = ''.__('Events without following tags').''; -$table->data[18][0] = html_print_select( +$table->colspan[18][0] = '2'; +$table->data[18][0] = ''.__('Events without following tags').''; +$table->data[19][0] = html_print_select( $tags_select_without, 'select_without', '', @@ -571,7 +591,7 @@ $table->data[18][0] = html_print_select( false, 'width: 220px;' ); -$table->data[18][1] = html_print_button( +$table->data[19][1] = html_print_button( __('Add'), 'add_whithout', $add_without_tag_disabled, @@ -580,7 +600,7 @@ $table->data[18][1] = html_print_button( true ); -$table->data[19][0] = html_print_select( +$table->data[20][0] = html_print_select( $tag_without_temp, 'tag_without_temp', [], @@ -594,12 +614,12 @@ $table->data[19][0] = html_print_select( false, 'width: 220px; height: 50px;' ); -$table->data[19][0] .= html_print_input_hidden( +$table->data[20][0] .= html_print_input_hidden( 'tag_without', $tag_without_base64, true ); -$table->data[19][1] = html_print_button( +$table->data[20][1] = html_print_button( __('Remove'), 'remove_whithout', $remove_without_tag_disabled, @@ -608,8 +628,8 @@ $table->data[19][1] = html_print_button( true ); -$table->data[20][0] = ''.__('Alert events').''; -$table->data[20][1] = html_print_select( +$table->data[21][0] = ''.__('Alert events').''; +$table->data[21][1] = html_print_select( [ '-1' => __('All'), '0' => __('Filter alert events'), @@ -624,8 +644,8 @@ $table->data[20][1] = html_print_select( ); if (!is_metaconsole()) { - $table->data[21][0] = ''.__('Module search').''; - $table->data[21][1] .= html_print_autocomplete_modules( + $table->data[22][0] = ''.__('Module search').''; + $table->data[22][1] .= html_print_autocomplete_modules( 'module_search', $text_module, false, @@ -637,17 +657,17 @@ if (!is_metaconsole()) { ); } -$table->data[22][0] = ''.__('Source').''; -$table->data[22][1] = html_print_input_text('source', $source, '', 35, 255, true); +$table->data[23][0] = ''.__('Source').''; +$table->data[23][1] = html_print_input_text('source', $source, '', 35, 255, true); -$table->data[23][0] = ''.__('Extra ID').''; -$table->data[23][1] = html_print_input_text('id_extra', $id_extra, '', 11, 255, true); +$table->data[24][0] = ''.__('Extra ID').''; +$table->data[24][1] = html_print_input_text('id_extra', $id_extra, '', 11, 255, true); -$table->data[24][0] = ''.__('Comment').''; -$table->data[24][1] = html_print_input_text('user_comment', $user_comment, '', 35, 255, true); +$table->data[25][0] = ''.__('Comment').''; +$table->data[25][1] = html_print_input_text('user_comment', $user_comment, '', 35, 255, true); -$table->data[25][0] = ''.__('Custom data filter type').''; -$table->data[25][1] = html_print_select( +$table->data[26][0] = ''.__('Custom data filter type').''; +$table->data[26][1] = html_print_select( [ '0' => __('Filter custom data by name field'), '1' => __('Filter custom data by value field'), @@ -660,12 +680,12 @@ $table->data[25][1] = html_print_select( true ); -$table->data[26][0] = ''.__('Custom data').''; -$table->data[26][1] = html_print_input_text('custom_data', $custom_data, '', 35, 255, true); +$table->data[27][0] = ''.__('Custom data').''; +$table->data[27][1] = html_print_input_text('custom_data', $custom_data, '', 35, 255, true); if (is_metaconsole()) { - $table->data[27][0] = ''.__('Id souce event').''; - $table->data[27][1] = html_print_input_text( + $table->data[28][0] = ''.__('Id souce event').''; + $table->data[28][1] = html_print_input_text( 'id_source_event', $id_source_event, '', diff --git a/pandora_console/include/ajax/events.php b/pandora_console/include/ajax/events.php index 5cb86d027e..9de1b29988 100644 --- a/pandora_console/include/ajax/events.php +++ b/pandora_console/include/ajax/events.php @@ -357,6 +357,7 @@ if ($save_event_filter) { $values['pagination'] = get_parameter('pagination'); $values['event_view_hr'] = get_parameter('event_view_hr'); $values['id_user_ack'] = get_parameter('id_user_ack'); + $values['owner_user'] = get_parameter('owner_user'); $values['group_rep'] = get_parameter('group_rep'); $values['tag_with'] = get_parameter('tag_with', io_json_mb_encode([])); $values['tag_without'] = get_parameter( @@ -415,6 +416,7 @@ if ($update_event_filter) { $values['pagination'] = get_parameter('pagination'); $values['event_view_hr'] = get_parameter('event_view_hr'); $values['id_user_ack'] = get_parameter('id_user_ack'); + $values['owner_user'] = get_parameter('owner_user'); $values['group_rep'] = get_parameter('group_rep'); $values['tag_with'] = get_parameter('tag_with', io_json_mb_encode([])); $values['tag_without'] = get_parameter( @@ -481,6 +483,7 @@ if ($get_filter_values) { 'user_comment' => '', 'id_extra' => '', 'id_user_ack' => '', + 'owner_user' => '', 'date_from' => '', 'time_from' => '', 'date_to' => '', @@ -654,6 +657,8 @@ function load_form_filter() { $("#text-event_view_hr").val(val); if (i == 'id_user_ack') $("#id_user_ack").val(val); + if (i == 'owner_user') + $("#owner_user").val(val); if (i == 'group_rep') $("#group_rep").val(val); if (i == 'tag_with') @@ -904,6 +909,7 @@ function save_new_filter() { "pagination" : $("#pagination").val(), "event_view_hr" : $("#text-event_view_hr").val(), "id_user_ack" : $("#id_user_ack").val(), + "owner_user" : $("#owner_user").val(), "group_rep" : $("#group_rep").val(), "tag_with": Base64.decode($("#hidden-tag_with").val()), "tag_without": Base64.decode($("#hidden-tag_without").val()), @@ -981,6 +987,7 @@ function save_update_filter() { "pagination" : $("#pagination").val(), "event_view_hr" : $("#text-event_view_hr").val(), "id_user_ack" : $("#id_user_ack").val(), + "owner_user" : $("#owner_user").val(), "group_rep" : $("#group_rep").val(), "tag_with" : Base64.decode($("#hidden-tag_with").val()), "tag_without" : Base64.decode($("#hidden-tag_without").val()), diff --git a/pandora_console/include/functions_events.php b/pandora_console/include/functions_events.php index 3aa121ec6a..0f41ef9574 100644 --- a/pandora_console/include/functions_events.php +++ b/pandora_console/include/functions_events.php @@ -645,6 +645,7 @@ function events_update_status($id_evento, $status, $filter=null) * 'user_comment' * 'source' * 'id_user_ack' + * 'owner_user' * 'tag_with' * 'tag_without' * 'filter_only_alert' @@ -1153,11 +1154,19 @@ function events_get_all( // Validated or in process by. if (empty($filter['id_user_ack']) === false) { $sql_filters[] = sprintf( - ' AND te.owner_user like lower("%%%s%%") ', + ' AND te.id_usuario like lower("%%%s%%") ', $filter['id_user_ack'] ); } + // Owner by. + if (empty($filter['owner_user']) === false) { + $sql_filters[] = sprintf( + ' AND te.owner_user like lower("%%%s%%") ', + $filter['owner_user'] + ); + } + $tag_names = []; // With following tags. if (empty($filter['tag_with']) === false) { diff --git a/pandora_console/operation/events/events.php b/pandora_console/operation/events/events.php index e95f16b355..a74ffd9eae 100644 --- a/pandora_console/operation/events/events.php +++ b/pandora_console/operation/events/events.php @@ -153,6 +153,10 @@ $id_user_ack = get_parameter( 'filter[id_user_ack]', ($filter['id_user_ack'] ?? '') ); +$owner_user = get_parameter( + 'filter[owner_user]', + ($filter['owner_user'] ?? '') +); $group_rep = get_parameter( 'filter[group_rep]', ($filter['group_rep'] ?? '') @@ -1089,6 +1093,7 @@ if ($loaded_filter !== false && $from_event_graph != 1 && isset($fb64) === false $pagination = $filter['pagination']; $event_view_hr = $filter['event_view_hr']; $id_user_ack = $filter['id_user_ack']; + $owner_user = $filter['owner_user']; $group_rep = $filter['group_rep']; $tag_with = json_decode(io_safe_output($filter['tag_with'])); $tag_without = json_decode(io_safe_output($filter['tag_without'])); @@ -1914,6 +1919,19 @@ $in = '
'; $in .= $data.'
'; $adv_inputs[] = $in; +$data = html_print_select( + $user_users, + 'owner_user', + $owner_user, + '', + __('Any'), + 0, + true +); +$in = '
'; +$in .= $data.'
'; +$adv_inputs[] = $in; + // Only alert events. $data = html_print_select( [ diff --git a/pandora_console/pandoradb.sql b/pandora_console/pandoradb.sql index 48768a9508..08a42f8ad6 100644 --- a/pandora_console/pandoradb.sql +++ b/pandora_console/pandoradb.sql @@ -1258,6 +1258,7 @@ CREATE TABLE IF NOT EXISTS `tevent_filter` ( `time_to` TIME NULL, `custom_data` VARCHAR(500) DEFAULT '', `custom_data_filter_type` TINYINT UNSIGNED DEFAULT 0, + `owner_user` TEXT, PRIMARY KEY (`id_filter`) ) ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4; From ccc2e830f4231ae4219266d36df1c4282476e836 Mon Sep 17 00:00:00 2001 From: Daniel Barbero Date: Thu, 3 Nov 2022 15:12:50 +0100 Subject: [PATCH 015/181] add sound events to metaconsole pandora_enterprise#8854 --- pandora_console/include/ajax/events.php | 2 +- .../include/javascript/pandora_events.js | 14 +++++++------- pandora_console/include/styles/sound_events.css | 3 +++ pandora_console/operation/menu.php | 5 +---- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/pandora_console/include/ajax/events.php b/pandora_console/include/ajax/events.php index 5cb86d027e..b9a863cfcd 100644 --- a/pandora_console/include/ajax/events.php +++ b/pandora_console/include/ajax/events.php @@ -2270,7 +2270,7 @@ if ($drawConsoleSound === true) { ], ], [ - 'label' => __('Time Sound'), + 'label' => __('Sound duration'), 'arguments' => [ 'type' => 'select', 'fields' => $times_sound, diff --git a/pandora_console/include/javascript/pandora_events.js b/pandora_console/include/javascript/pandora_events.js index df84985a37..84be4f824c 100644 --- a/pandora_console/include/javascript/pandora_events.js +++ b/pandora_console/include/javascript/pandora_events.js @@ -920,7 +920,7 @@ function openSoundEventModal(settings) { sound = true; } - test_sound_button(sound); + test_sound_button(sound, settings.urlSound); }); // Play Stop. @@ -977,9 +977,9 @@ function openSoundEventModal(settings) { .show(); } -function test_sound_button(test_sound) { +function test_sound_button(test_sound, urlSound) { if (test_sound === true) { - add_audio(); + add_audio(urlSound); } else { remove_audio(); } @@ -1035,8 +1035,8 @@ function action_events_sound(mode, settings) { } } -function add_audio() { - var sound = "./include/sounds/" + $("#tabs-sound-modal #sound_id").val(); +function add_audio(urlSound) { + var sound = urlSound + $("#tabs-sound-modal #sound_id").val(); $(".actions-sound-modal").append( "
'; $data[1] .= html_print_image('images/file.png', true, ['class' => 'invert_filter'], false, true); @@ -411,11 +408,7 @@ if (($create != '') || ($view != '')) { $data = []; $data[0] = __('Plug-in parameters'); - $data[1] = ''; - if ($locked) { - $data[1] .= html_print_image('images/lock_mc.png', true, ['class' => 'command_advanced_conf lock', 'class' => 'invert_filter']); - } - + $data[1] = ''; $table->data['plugin_parameters'] = $data; $data = []; @@ -484,16 +477,10 @@ if (($create != '') || ($view != '')) { $datam = []; $datam[0] = __('Description')." ($macro_name)"; $datam[0] .= html_print_input_hidden($macro_name_name, $macro_name, true); - $datam[1] = html_print_input_text_extended($macro_desc_name, $macro_desc_value, 'text-'.$macro_desc_name, '', 30, 255, $locked, '', "class='command_macro text_input'", true); - if ($locked) { - $datam[1] .= html_print_image('images/lock_mc.png', true, ['class' => 'command_macro lock', 'class' => 'invert_filter']); - } + $datam[1] = html_print_input_text_extended($macro_desc_name, $macro_desc_value, 'text-'.$macro_desc_name, '', 30, 255, false, '', "class='command_macro text_input'", true); $datam[2] = __('Default value')." ($macro_name)"; - $datam[3] = html_print_input_text_extended($macro_value_name, $macro_value_value, 'text-'.$macro_value_name, '', 30, 255, $locked, '', "class='command_component command_macro text_input'", true); - if ($locked) { - $datam[3] .= html_print_image('images/lock_mc.png', true, ['class' => 'command_macro lock', 'class' => 'invert_filter']); - } + $datam[3] = html_print_input_text_extended($macro_value_name, $macro_value_value, 'text-'.$macro_value_name, '', 30, 255, false, '', "class='command_component command_macro text_input'", true); $table->data['plugin_'.$next_name_number] = $datam; @@ -524,24 +511,15 @@ if (($create != '') || ($view != '')) { $datam = []; $datam[0] = __('Help')." ($macro_name)


"; - $tadisabled = $locked === true ? ' disabled' : ''; $datam[1] = html_print_textarea( $macro_help_name, 6, 100, $macro_help_value, - 'class="command_macro" class="w97p"'.$tadisabled, + 'class="command_macro" class="w97p"', true ); - if ($locked) { - $datam[1] .= html_print_image( - 'images/lock_mc.png', - true, - ['class' => 'command_macro lock invert_filter'] - ); - } - $datam[1] .= '


'; $table->data['plugin_'.$next_name_number] = $datam; @@ -551,15 +529,16 @@ if (($create != '') || ($view != '')) { // Add/Delete buttons $datam = []; - $datam[0] = '
'.''.__('Add macro').''.' '.html_print_image( - 'images/add.png', - true, - ['class' => 'invert_filter'] - ).''; - $datam[0] .= ''; - $datam[0] .= ''; if (!$locked) { + $datam[0] = ''.''.__('Add macro').''.' '.html_print_image( + 'images/add.png', + true, + ['class' => 'invert_filter'] + ).''; + $datam[0] .= ''; + $datam[0] .= ''; + $delete_macro_style = ''; if ($i <= 2) { $delete_macro_style = 'display:none;'; @@ -1002,8 +981,11 @@ ui_require_javascript_file('pandora_modules'); }); update_preview(); } - $('a#add_macro_btn').click(add_macro_click_event); - + + if (locked === 0) { + $('a#add_macro_btn').click(add_macro_click_event); + } + // Delete macro var delete_macro_click_event = function (event) { delete_macro_form('table-form-plugin_'); @@ -1031,45 +1013,12 @@ ui_require_javascript_file('pandora_modules'); } } - var command_click_locked_event = function (event) { - var $element = $(this); - - if (!$element.is('input') || ($element.is('input') && ($element.prop('readonly') || $element.prop('disabled')))) { - if ($element.prop('id') === 'form_parameters') { - var message = '' - + '.\n' + ''; - - if (confirm(message)) { - if ($element.is('input')) { - $element - .prop('readonly', false) - .prop('disabled', false) - .siblings('img.command_advanced_conf.lock') - .remove(); - } - else { - $element - .siblings('input.command_advanced_conf') - .prop('readonly', false) - .prop('disabled', false) - $element.remove(); - } - } - } - else { - alert(""); - } - } - } - var macros_click_locked_event = function (event) { alert(""); } if (locked) { $('a#add_macro_btn').click(add_macro_click_locked_event); - $('.command_advanced_conf').click(command_click_locked_event); - $('.command_macro').click(macros_click_locked_event); } From e10455c90256c82e3fcd11237553a1d82e236d81 Mon Sep 17 00:00:00 2001 From: Daniel Barbero Date: Thu, 10 Nov 2022 16:10:50 +0100 Subject: [PATCH 024/181] new widget datamatrix pandora_enterprise#8619 --- pandora_console/include/ajax/module.php | 20 ++++- pandora_console/include/functions_modules.php | 82 +++++++++++++++++-- .../lib/Dashboard/Widgets/DataMatrix.php | 64 ++++++--------- 3 files changed, 118 insertions(+), 48 deletions(-) diff --git a/pandora_console/include/ajax/module.php b/pandora_console/include/ajax/module.php index f4e8722930..507faff3d6 100755 --- a/pandora_console/include/ajax/module.php +++ b/pandora_console/include/ajax/module.php @@ -26,6 +26,8 @@ * ============================================================================ */ +use PandoraFMS\Enterprise\Metaconsole\Node; + // Begin. if (check_login()) { global $config; @@ -1472,7 +1474,16 @@ if (check_login()) { $date = (get_system_time() - ($time_all_box * $start)); $datelimit = ($date - $time_all_box); foreach ($modules as $key => $value) { - // TODO: tresholds. + if (is_metaconsole() === true) { + try { + $node = new Node((int) $value['id_node']); + $node->connect(); + } catch (\Exception $e) { + // Unexistent agent. + $node->disconnect(); + } + } + $value['thresholds'] = [ 'min_critical' => (empty($value['c_min']) === true) ? null : $value['c_min'], 'max_critical' => (empty($value['c_max']) === true) ? null : $value['c_max'], @@ -1504,8 +1515,9 @@ if (check_login()) { $vdata, $value['thresholds'] ); + $resultData = ''; - if ($vdata !== null && $vdata !== '') { + if ($vdata !== null && $vdata !== '' && $vdata !== false) { if (isset($formatData) === true && (bool) $formatData === true ) { @@ -1535,6 +1547,10 @@ if (check_login()) { }, [] ); + + if (is_metaconsole() === true) { + $node->disconnect(); + } } if (empty($uncompressData) === false) { diff --git a/pandora_console/include/functions_modules.php b/pandora_console/include/functions_modules.php index e8d37d19bc..00ce23070f 100755 --- a/pandora_console/include/functions_modules.php +++ b/pandora_console/include/functions_modules.php @@ -4338,7 +4338,16 @@ function modules_get_regex( } -function get_status_data_modules($id_module, $data, $thresholds) +/** + * Status for data thresholds modules. + * + * @param integer $id_module Module ID. + * @param mixed $data Data int, bool, null, etc. + * @param array $thresholds Array thresholds. + * + * @return array + */ +function get_status_data_modules(int $id_module, $data, $thresholds) { // Check not init. if ($data === false) { @@ -4355,6 +4364,8 @@ function get_status_data_modules($id_module, $data, $thresholds) } } + $thresholds = calculateThreshold($thresholds); + foreach (getStatuses() as $status) { if ($thresholds[$status]['min'] === null && $thresholds[$status]['max'] === null @@ -4369,7 +4380,13 @@ function get_status_data_modules($id_module, $data, $thresholds) || ($thresholds[$status]['min'] <= $data && $thresholds[$status]['max'] >= $data) ) { - return $status; + if ($status === 'critical') { + return ['color' => COL_CRITICAL]; + } else if ($status === 'warning') { + return ['color' => COL_WARNING]; + } else { + return ['color' => COL_NORMAL]; + } } } @@ -4377,6 +4394,61 @@ function get_status_data_modules($id_module, $data, $thresholds) } +/** + * Calculate thresholds. + * + * @param array $thresholds_array + * + * @return array + */ +function calculateThreshold(array $thresholds_array) +{ + $nMax = null; + if ($thresholds_array['min_warning'] !== null) { + $nMax = $thresholds_array['min_warning']; + } else if ($thresholds_array['min_critical'] !== null) { + $nMax = $thresholds_array['min_critical']; + } + + $wMin = null; + if ($thresholds_array['min_warning'] !== null) { + $wMin = $thresholds_array['min_warning']; + } + + $wMax = null; + if ($thresholds_array['max_warning'] !== null) { + $wMax = $thresholds_array['max_warning']; + } + + $cMin = null; + if ($thresholds_array['min_critical'] !== null) { + $cMin = $thresholds_array['min_critical']; + } + + $cMax = null; + if ($thresholds_array['max_critical'] !== null) { + $cMax = $thresholds_array['max_critical']; + } + + $thresholds = [ + 'normal' => [ + 'min' => null, + 'max' => $nMax, + ], + 'warning' => [ + 'min' => $wMin, + 'max' => $wMax, + ], + 'critical' => [ + 'min' => $cMin, + 'max' => $cMax, + ], + ]; + + return $thresholds; +} + + /** * Get status. * @@ -4385,8 +4457,8 @@ function get_status_data_modules($id_module, $data, $thresholds) function getStatuses() { return [ - 'CRITICAL', - 'WARNING', - 'NORMAL', + 'critical', + 'warning', + 'normal', ]; } diff --git a/pandora_console/include/lib/Dashboard/Widgets/DataMatrix.php b/pandora_console/include/lib/Dashboard/Widgets/DataMatrix.php index 7a326a0549..e75d7da9e4 100644 --- a/pandora_console/include/lib/Dashboard/Widgets/DataMatrix.php +++ b/pandora_console/include/lib/Dashboard/Widgets/DataMatrix.php @@ -117,13 +117,6 @@ class DataMatrix extends Widget */ protected $cellId; - /** - * Size. - * - * @var array - */ - private $size; - /** * Construct. @@ -287,21 +280,10 @@ class DataMatrix extends Widget $inputs['inputs']['row1'][] = $vInput; } - if (empty($values['fontColor']) === true) { - $values['fontColor'] = '#2c3e50'; + if (isset($values['formatData']) === false) { + $values['formatData'] = 1; } - $inputs['inputs']['row1'][] = [ - 'label' => __('Font color'), - 'arguments' => [ - 'wrapper' => 'div', - 'name' => 'fontColor', - 'type' => 'color', - 'value' => $values['fontColor'], - 'return' => true, - ], - ]; - // Format Data. $inputs['inputs']['row1'][] = [ 'label' => __('Format Data'), @@ -313,24 +295,6 @@ class DataMatrix extends Widget ], ]; - // Type Label. - $fields = [ - 'module' => __('Module'), - 'agent' => __('Agent'), - 'agent_module' => __('Agent / module'), - ]; - - $inputs['inputs']['row1'][] = [ - 'label' => __('Label'), - 'arguments' => [ - 'type' => 'select', - 'fields' => $fields, - 'name' => 'label', - 'selected' => $values['label'], - 'return' => true, - ], - ]; - if (isset($values['period']) === false) { $values['period'] = SECONDS_1DAY; } @@ -390,6 +354,24 @@ class DataMatrix extends Widget ], ]; + // Type Label. + $fields = [ + 'module' => __('Module'), + 'agent' => __('Agent'), + 'agent_module' => __('Agent / module'), + ]; + + $inputs['inputs']['row2'][] = [ + 'label' => __('Label'), + 'arguments' => [ + 'type' => 'select', + 'fields' => $fields, + 'name' => 'label', + 'selected' => $values['label'], + 'return' => true, + ], + ]; + $inputs['inputs']['row2'][] = [ 'arguments' => [ 'type' => 'select_multiple_modules_filtered_select2', @@ -450,7 +432,7 @@ class DataMatrix extends Widget $agModule ); - $values['formatData'] = \get_parameter_switch('formatData', 0); + $values['formatData'] = \get_parameter_switch('formatData', 1); $values['fontColor'] = \get_parameter('fontColor', '#2c3e50'); $values['label'] = \get_parameter('label', 'module'); @@ -544,7 +526,6 @@ class DataMatrix extends Widget 'ajax_data' => [ 'get_data_dataMatrix' => 1, 'table_id' => $tableId, - 'length' => $this->values['limit'], 'period' => $this->values['period'], 'slice' => $this->values['slice'], 'formatData' => $this->values['formatData'], @@ -556,6 +537,7 @@ class DataMatrix extends Widget 'field' => 'date', 'direction' => 'desc', ], + 'csv' => 0, ] ); } catch (\Exception $e) { @@ -704,7 +686,7 @@ class DataMatrix extends Widget { $size = [ 'width' => (is_metaconsole() === true) ? 1000 : 900, - 'height' => 550, + 'height' => 480, ]; return $size; From 6a173664d4a715be8810c4573cc32b14bc11b79d Mon Sep 17 00:00:00 2001 From: "alejandro.campos@artica.es" Date: Fri, 11 Nov 2022 12:09:03 +0100 Subject: [PATCH 025/181] Removed transactional server --- .../general/first_task/transactional_list.php | 46 ------------------- pandora_console/include/functions_servers.php | 3 -- pandora_console/operation/menu.php | 2 - .../FreeBSD/pandora_server.conf.new | 8 ---- pandora_server/conf/pandora_server.conf.new | 8 ---- .../conf/pandora_server.conf.windows | 8 ---- pandora_server/lib/PandoraFMS/Config.pm | 8 ---- pandora_server/lib/PandoraFMS/Core.pm | 1 - pandora_server/lib/PandoraFMS/Tools.pm | 2 - 9 files changed, 86 deletions(-) delete mode 100644 pandora_console/general/first_task/transactional_list.php diff --git a/pandora_console/general/first_task/transactional_list.php b/pandora_console/general/first_task/transactional_list.php deleted file mode 100644 index c1d9ef2f42..0000000000 --- a/pandora_console/general/first_task/transactional_list.php +++ /dev/null @@ -1,46 +0,0 @@ - - true, 'message' => __('There are no transactions defined yet.') ]); - -if ($networkmaps_write || $networkmaps_manage) { - ?> - -
-
- __('Transactions')]); ?> -
-
-

- -

-
- -
-
-
- {"inventoryserver"} = 1; # default $pa_config->{"webserver"} = 1; # 3.0 $pa_config->{"web_timeout"} = 60; # 6.0SP5 - $pa_config->{"transactionalserver"} = 0; # Default 0, introduced on 6.1 - $pa_config->{"transactional_threshold"} = 2; # Default 2, introduced on 6.1 $pa_config->{"transactional_pool"} = $pa_config->{"incomingdir"} . "/" . "trans"; # Default, introduced on 6.1 $pa_config->{'snmp_logfile'} = "/var/log/pandora_snmptrap.log"; $pa_config->{"network_threads"} = 3; # Fixed default @@ -776,12 +774,6 @@ sub pandora_load_config { elsif ($parametro =~ m/^web_timeout\s+([0-9]*)/i) { $pa_config->{'web_timeout'}= clean_blank($1); } - elsif ($parametro =~ m/^transactionalserver\s+([0-9]*)/i) { - $pa_config->{'transactionalserver'}= clean_blank($1); - } - elsif ($parametro =~ m/^transactional_threshold\s+([0-9]*\.{0,1}[0-9]*)/i) { - $pa_config->{'transactional_threshold'}= clean_blank($1); - } if ($parametro =~ m/^transactional_pool\s(.*)/i) { $tbuf= clean_blank($1); if ($tbuf =~ m/^\.(.*)/){ diff --git a/pandora_server/lib/PandoraFMS/Core.pm b/pandora_server/lib/PandoraFMS/Core.pm index b3c8b2576a..f806908a7b 100644 --- a/pandora_server/lib/PandoraFMS/Core.pm +++ b/pandora_server/lib/PandoraFMS/Core.pm @@ -299,7 +299,6 @@ our @ServerTypes = qw ( icmpserver snmpserver satelliteserver - transactionalserver mfserver syncserver wuxserver diff --git a/pandora_server/lib/PandoraFMS/Tools.pm b/pandora_server/lib/PandoraFMS/Tools.pm index f922e75854..590fdf2020 100755 --- a/pandora_server/lib/PandoraFMS/Tools.pm +++ b/pandora_server/lib/PandoraFMS/Tools.pm @@ -72,7 +72,6 @@ our @EXPORT = qw( SNMPSERVER SATELLITESERVER MFSERVER - TRANSACTIONALSERVER SYNCSERVER SYSLOGSERVER WUXSERVER @@ -2837,7 +2836,6 @@ sub get_server_name { return "ICMPSERVER" if ($server_type eq ICMPSERVER); return "SNMPSERVER" if ($server_type eq SNMPSERVER); return "SATELLITESERVER" if ($server_type eq SATELLITESERVER); - return "TRANSACTIONALSERVER" if ($server_type eq TRANSACTIONALSERVER); return "MFSERVER" if ($server_type eq MFSERVER); return "SYNCSERVER" if ($server_type eq SYNCSERVER); return "WUXSERVER" if ($server_type eq WUXSERVER); From 780e6ac51473280e19c03ad06e22a557fcb698ca Mon Sep 17 00:00:00 2001 From: "alejandro.campos@artica.es" Date: Fri, 11 Nov 2022 12:53:41 +0100 Subject: [PATCH 026/181] Removed transactional server --- pandora_console/extras/mr/59.sql | 6 ++++++ pandora_console/pandoradb.sql | 31 +------------------------------ 2 files changed, 7 insertions(+), 30 deletions(-) create mode 100644 pandora_console/extras/mr/59.sql diff --git a/pandora_console/extras/mr/59.sql b/pandora_console/extras/mr/59.sql new file mode 100644 index 0000000000..e5016f9da1 --- /dev/null +++ b/pandora_console/extras/mr/59.sql @@ -0,0 +1,6 @@ +START TRANSACTION; + +DROP TABLE IF EXISTS `tphase`; +DROP TABLE IF EXISTS `ttransaction`; + +COMMIT; diff --git a/pandora_console/pandoradb.sql b/pandora_console/pandoradb.sql index 89fa418389..78746b9881 100644 --- a/pandora_console/pandoradb.sql +++ b/pandora_console/pandoradb.sql @@ -3410,37 +3410,8 @@ CREATE TABLE IF NOT EXISTS `tmetaconsole_agent` ( ) ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4; -- --------------------------------------------------------------------- --- Table `ttransaction` +-- Table `treset_pass` -- --------------------------------------------------------------------- -CREATE TABLE IF NOT EXISTS `ttransaction` ( - `transaction_id` INT UNSIGNED NOT NULL AUTO_INCREMENT, - `agent_id` INT UNSIGNED NOT NULL, - `group_id` INT UNSIGNED NOT NULL DEFAULT 0, - `description` TEXT, - `name` VARCHAR(250) NOT NULL, - `loop_interval` INT UNSIGNED NOT NULL DEFAULT 40, - `ready` INT UNSIGNED NOT NULL DEFAULT 0, - `running` INT UNSIGNED NOT NULL DEFAULT 0, - PRIMARY KEY (`transaction_id`) -) engine=InnoDB DEFAULT CHARSET=UTF8MB4; - --- --------------------------------------------------------------------- --- Table `tphase` --- --------------------------------------------------------------------- -CREATE TABLE IF NOT EXISTS `tphase`( - `phase_id` INT UNSIGNED NOT NULL AUTO_INCREMENT, - `transaction_id` INT UNSIGNED NOT NULL, - `agent_id` INT UNSIGNED NOT NULL, - `name` VARCHAR(250) NOT NULL, - `idx` INT UNSIGNED NOT NULL, - `dependencies` TEXT, - `enables` TEXT, - `launch` TEXT, - `retries` INT UNSIGNED DEFAULT null, - `timeout` INT UNSIGNED DEFAULT null, - PRIMARY KEY (`phase_id`,`transaction_id`) -) engine=InnoDB DEFAULT CHARSET=UTF8MB4; - CREATE TABLE IF NOT EXISTS `treset_pass` ( `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, `id_user` VARCHAR(255) NOT NULL DEFAULT '', From a357dcfb0d38b39f0531cae1921052c77ad70ef5 Mon Sep 17 00:00:00 2001 From: "alejandro.campos@artica.es" Date: Fri, 11 Nov 2022 13:20:23 +0100 Subject: [PATCH 027/181] updated delete files file --- pandora_console/extras/delete_files/delete_files.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pandora_console/extras/delete_files/delete_files.txt b/pandora_console/extras/delete_files/delete_files.txt index 96223ccd69..90107df226 100644 --- a/pandora_console/extras/delete_files/delete_files.txt +++ b/pandora_console/extras/delete_files/delete_files.txt @@ -1667,3 +1667,13 @@ godmode/um_client/vendor/sebastian godmode/um_client/vendor update_manager_client/resources/styles/pandora.css enterprise/meta/general/upload_head_image.php +general/first_task/transactional_list.php +enterprise/include/ajax/transactional.ajax.php +enterprise/include/class/Transactionalmap.class.php +enterprise/include/help/es/help_transactional_map_phases.php +enterprise/include/javascript/transactional/TransactionalController.js +enterprise/include/functions_transactional.php +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 From 564cd837ae73fc762914eab97a97a6dcc261d0db Mon Sep 17 00:00:00 2001 From: Daniel Maya Date: Mon, 14 Nov 2022 17:43:35 +0100 Subject: [PATCH 028/181] #9292 code refactoring --- .../include/class/SnmpConsole.class.php | 1073 +++++++++++++ pandora_console/include/styles/pandora.css | 13 + .../operation/snmpconsole/snmp_view.php | 1352 +---------------- 3 files changed, 1115 insertions(+), 1323 deletions(-) create mode 100644 pandora_console/include/class/SnmpConsole.class.php diff --git a/pandora_console/include/class/SnmpConsole.class.php b/pandora_console/include/class/SnmpConsole.class.php new file mode 100644 index 0000000000..50ada73852 --- /dev/null +++ b/pandora_console/include/class/SnmpConsole.class.php @@ -0,0 +1,1073 @@ +ajaxController = $ajaxController; + } + + + /** + * Run view + * + * @return void + */ + public function run() + { + global $config; + // Javascript. + ui_require_jquery_file('pandora'); + // CSS. + ui_require_css_file('wizard'); + ui_require_css_file('discovery'); + + $statistics['text'] = ''.html_print_image( + 'images/op_reporting.png', + true, + [ + 'title' => __('Statistics'), + 'class' => 'invert_filter', + ] + ).''; + $list['text'] = ''.html_print_image( + 'images/op_snmp.png', + true, + [ + 'title' => __('List'), + 'class' => 'invert_filter', + ] + ).''; + $list['active'] = true; + + // Header + ui_print_standard_header( + __('SNMP Console'), + 'images/op_snmp.png', + false, + 'snmp_console', + false, + [ + $list, + $statistics, + ], + [ + [ + 'link' => '', + 'label' => __('Monitoring'), + ], + [ + 'link' => '', + 'label' => __('SNMP'), + ], + ] + ); + + // Datatables list. + try { + $checkbox_all = html_print_checkbox( + 'all_validate_box', + 1, + false, + true + ); + + $columns = [ + 'status', + [ + 'text' => 'snmp_agent', + 'class' => 'snmp-td', + ], + [ + 'text' => 'enterprise_string', + 'class' => 'snmp-td', + ], + [ + 'text' => 'count', + 'class' => 'snmp-td', + ], + [ + 'text' => 'trap_subtype', + 'class' => 'snmp-td', + ], + [ + 'text' => 'user_id', + 'class' => 'snmp-td', + ], + [ + 'text' => 'timestamp', + 'class' => 'snmp-td', + ], + 'alert', + 'action', + [ + 'text' => 'm', + 'class' => 'mw60px pdd_0px', + ], + ]; + + $column_names = [ + __('Status'), + __('SNMP Agent'), + __('Enterprise String'), + __('Count'), + __('Trap subtype'), + __('User ID'), + __('Timestamp'), + __('Alert'), + __('Actions'), + [ + 'text' => 'm', + 'extra' => $checkbox_all, + 'class' => 'w20px no-text-imp', + ], + ]; + + $show_alerts = [ + -1 => __('All'), + 0 => __('Not triggered'), + 1 => __('Triggered'), + ]; + + $severities = get_priorities(); + $severities[-1] = __('All'); + + $paginations = [ + $config['block_size'] => __('Default'), + 25 => '25', + 50 => '50', + 100 => '100', + 200 => '200', + 500 => '500', + ]; + + $status_array = [ + -1 => __('All'), + 0 => __('Not validated'), + 1 => __('Validated'), + ]; + + $trap_types = [ + -1 => __('None'), + 0 => __('Cold start (0)'), + 1 => __('Warm start (1)'), + 2 => __('Link down (2)'), + 3 => __('Link up (3)'), + 4 => __('Authentication failure (4)'), + 5 => __('Other'), + ]; + + $this->tableId = 'snmp_console'; + + // Load datatables user interface. + ui_print_datatable( + [ + 'id' => $this->tableId, + 'class' => 'info_table', + 'style' => 'width: 100%', + 'columns' => $columns, + 'column_names' => $column_names, + 'ajax_url' => $this->ajaxController, + 'ajax_data' => ['method' => 'draw'], + 'ajax_postprocces' => 'process_datatables_item(item)', + 'search_button_class' => 'sub filter float-right', + 'no_sortable_columns' => [ + 0, + 7, + 8, + 9, + ], + 'form' => [ + 'class' => 'flex-row', + 'inputs' => [ + [ + 'label' => __('Alert'), + 'type' => 'select', + 'id' => 'filter_alert', + 'name' => 'filter_alert', + 'class' => 'w200px', + 'fields' => $show_alerts, + 'return' => true, + 'selected' => -1, + ], + [ + 'label' => __('Severity'), + 'type' => 'select', + 'id' => 'filter_severity', + 'name' => 'filter_severity', + 'class' => 'w200px', + 'fields' => $severities, + 'return' => true, + 'selected' => -1, + ], + [ + 'label' => __('Free search'), + 'type' => 'text', + 'class' => 'w400px', + 'id' => 'filter_free_search', + 'name' => 'filter_free_search', + ], + [ + 'label' => __('Status'), + 'type' => 'select', + 'id' => 'filter_status', + 'name' => 'filter_status', + 'class' => 'w200px', + 'fields' => $status_array, + 'return' => true, + 'selected' => -1, + ], + [ + 'label' => __('Group by Enterprise String/IP'), + 'type' => 'select', + 'name' => 'filter_group_by', + 'selected' => 0, + 'disabled' => false, + 'return' => true, + 'id' => 'filter_group_by', + 'fields' => [ + 0 => __('No'), + 1 => __('Yes'), + ], + ], + [ + 'label' => __('Max. hours old'), + 'type' => 'text', + 'class' => 'w200px', + 'id' => 'filter_hours_ago', + 'name' => 'filter_hours_ago', + 'value' => '8', + ], + [ + 'label' => __('Trap type'), + 'type' => 'select', + 'id' => 'filter_trap_type', + 'name' => 'filter_trap_type', + 'class' => 'w200px', + 'fields' => $trap_types, + 'return' => true, + 'selected' => -1, + ], + ], + ], + ] + ); + } catch (Exception $e) { + echo $e->getMessage(); + } + + echo '
'; + html_print_submit_button(__('Validate'), 'updatebt', false, 'class="sub ok"'); + echo ' '; + html_print_submit_button(__('Delete'), 'deletebt', false, 'class="sub delete" onClick="javascript:return confirm(\''.__('Are you sure?').'\')"'); + echo '
'; + + echo '
'; + echo '

'.__('Status').'

'; + echo html_print_image( + 'images/pixel_green.png', + true, + [ + 'width' => '20', + 'height' => '20', + ] + ).' - '.__('Validated'); + echo '
'; + echo html_print_image( + 'images/pixel_red.png', + true, + [ + 'width' => '20', + 'height' => '20', + ] + ).' - '.__('Not validated'); + echo '
'; + echo '
'; + echo '

'.__('Alert').'

'; + echo html_print_image( + 'images/pixel_yellow.png', + true, + [ + 'width' => '20', + 'height' => '20', + ] + ).' - '.__('Fired'); + echo '
'; + echo html_print_image( + 'images/pixel_gray.png', + true, + [ + 'width' => '20', + 'height' => '20', + ] + ).' - '.__('Not fired'); + echo '
'; + echo '
'; + echo '

'.__('Action').'

'; + echo html_print_image('images/ok.png', true).' - '.__('Validate'); + echo '
'; + echo html_print_image('images/cross.png', true, ['class' => 'invert_filter']).' - '.__('Delete'); + echo '
'; + echo '
'; + echo '

'.__('Severity').'

'; + foreach (get_priorities() as $num => $name) { + echo ''.$name.''; + echo '
'; + } + + echo '
'; + + // Load own javascript file. + echo $this->loadJS(); + } + + + /** + * Get the data for draw the table. + * + * @return void. + */ + public function draw() + { + global $config; + + // Init data. + $data = []; + // Count of total records. + $count = 0; + // Catch post parameters. + $start = get_parameter('start', 0); + $length = get_parameter('length', $config['block_size']); + + $order = get_datatable_order(true); + $filters = get_parameter('filter', []); + + // Build ranges. + $now = new DateTime(); + $ago = new DateTime(); + $interval = new DateInterval(sprintf('PT%dH', $filters['filter_hours_ago'])); + $ago->sub($interval); + + $date_from_trap = $ago->format('Y/m/d'); + $date_to_trap = $now->format('Y/m/d'); + $time_from_trap = $ago->format('H:i:s'); + $time_to_trap = $now->format('H:i:s'); + + try { + ob_start(); + $data = []; + + $user_groups = users_get_groups($config['id_user'], 'AR', false); + $prea = array_keys($user_groups); + $ids = join(',', $prea); + + $user_in_group_wo_agents = db_get_value_sql('select count(DISTINCT(id_usuario)) from tusuario_perfil where id_usuario ="'.$config['id_user'].'" and id_perfil = 1 and id_grupo in (select id_grupo from tgrupo where id_grupo in ('.$ids.') and id_grupo not in (select id_grupo from tagente))'); + if ($user_in_group_wo_agents == 0) { + $rows = db_get_all_rows_filter( + 'tagente', + ['id_grupo' => array_keys($user_groups)], + ['id_agente'] + ); + $id_agents = []; + foreach ($rows as $row) { + $id_agents[] = $row['id_agente']; + } + + if (!empty($id_agents)) { + $address_by_user_groups = agents_get_addresses($id_agents); + foreach ($address_by_user_groups as $i => $a) { + $address_by_user_groups[$i] = '"'.$a.'"'; + } + } + } else { + $rows = db_get_all_rows_filter( + 'tagente', + [], + ['id_agente'] + ); + $id_agents = []; + foreach ($rows as $row) { + $id_agents[] = $row['id_agente']; + } + + $all_address_agents = agents_get_addresses($id_agents); + foreach ($all_address_agents as $i => $a) { + $all_address_agents[$i] = '"'.$a.'"'; + } + } + + if (empty($address_by_user_groups)) { + $address_by_user_groups = []; + array_unshift($address_by_user_groups, '""'); + } + + if (empty($all_address_agents)) { + $all_address_agents = []; + array_unshift($all_address_agents, '""'); + } + + $sql = 'SELECT * FROM ttrap + WHERE ( + `source` IN ('.implode(',', $address_by_user_groups).") OR + `source`='' OR + `source` NOT IN (".implode(',', $all_address_agents).') + ) + %s + ORDER BY timestamp DESC + LIMIT %d,%d'; + + $whereSubquery = ''; + if ($filters['filter_alert'] != -1) { + $whereSubquery .= ' AND alerted = '.$filters['filter_alert']; + } + + if ($filters['filter_severity'] != -1) { + // There are two special severity values aimed to match two different trap standard severities + // in database: warning/critical and critical/normal. + if ($filters['filter_severity'] != EVENT_CRIT_OR_NORMAL + && $filters['filter_severity'] != EVENT_CRIT_WARNING_OR_CRITICAL + ) { + // Test if enterprise is installed to search oid in text or oid field in ttrap. + if ($config['enterprise_installed']) { + $whereSubquery .= ' AND ( + (alerted = 0 AND severity = '.$filters['filter_severity'].') OR + (alerted = 1 AND priority = '.$filters['filter_severity'].'))'; + } else { + $whereSubquery .= ' AND ( + (alerted = 0 AND 1 = '.$filters['filter_severity'].') OR + (alerted = 1 AND priority = '.$filters['filter_severity'].'))'; + } + } else if ($filters['filter_severity'] === EVENT_CRIT_WARNING_OR_CRITICAL) { + // Test if enterprise is installed to search oid in text or oid field in ttrap. + if ($config['enterprise_installed']) { + $whereSubquery .= ' AND ( + (alerted = 0 AND (severity = '.EVENT_CRIT_WARNING.' OR severity = '.EVENT_CRIT_CRITICAL.')) OR + (alerted = 1 AND (priority = '.EVENT_CRIT_WARNING.' OR priority = '.EVENT_CRIT_CRITICAL.')))'; + } else { + $whereSubquery .= ' AND ( + (alerted = 1 AND (priority = '.EVENT_CRIT_WARNING.' OR priority = '.EVENT_CRIT_CRITICAL.')))'; + } + } else if ($filters['filter_severity'] === EVENT_CRIT_OR_NORMAL) { + // Test if enterprise is installed to search oid in text or oid field in ttrap. + if ($config['enterprise_installed']) { + $whereSubquery .= ' AND ( + (alerted = 0 AND (severity = '.EVENT_CRIT_NORMAL.' OR severity = '.EVENT_CRIT_CRITICAL.')) OR + (alerted = 1 AND (priority = '.EVENT_CRIT_NORMAL.' OR priority = '.EVENT_CRIT_CRITICAL.')))'; + } else { + $whereSubquery .= ' AND ( + (alerted = 1 AND (priority = '.EVENT_CRIT_NORMAL.' OR priority = '.EVENT_CRIT_CRITICAL.')))'; + } + } + } + + if ($filters['filter_status'] != -1) { + $whereSubquery .= ' AND status = '.$filters['filter_status']; + } + + if ($date_from_trap != '') { + if ($time_from_trap != '') { + $whereSubquery .= ' + AND (UNIX_TIMESTAMP(timestamp) > UNIX_TIMESTAMP("'.$date_from_trap.' '.$time_from_trap.'")) + '; + } else { + $whereSubquery .= ' + AND (UNIX_TIMESTAMP(timestamp) > UNIX_TIMESTAMP("'.$date_from_trap.' 23:59:59")) + '; + } + } + + if ($date_to_trap != '') { + if ($time_to_trap) { + $whereSubquery .= ' + AND (UNIX_TIMESTAMP(timestamp) < UNIX_TIMESTAMP("'.$date_to_trap.' '.$time_to_trap.'")) + '; + } else { + $whereSubquery .= ' + AND (UNIX_TIMESTAMP(timestamp) < UNIX_TIMESTAMP("'.$date_to_trap.' 23:59:59")) + '; + } + } + + if ($filters['filter_trap_type'] == 5) { + $whereSubquery .= ' AND type NOT IN (0, 1, 2, 3, 4)'; + } else if ($filters['filter_trap_type'] != -1) { + $whereSubquery .= ' AND type = '.$filters['filter_trap_type']; + } + + if ($filters['filter_group_by']) { + $where_without_group = $whereSubquery; + $whereSubquery .= ' GROUP BY source,oid'; + } + + $sql = sprintf($sql, $whereSubquery, $start, $length); + $sql_count = 'SELECT COUNT(id_trap) FROM ttrap + WHERE ( + source IN ('.implode(',', $address_by_user_groups).") OR + source='' OR + source NOT IN (".implode(',', $all_address_agents).') + ) + %s'; + + $sql_count = sprintf($sql_count, $whereSubquery); + + $traps = db_get_all_rows_sql($sql, true); + $total = (int) db_get_value_sql($sql_count, false, true); + + if (empty($traps) === false) { + $data = $traps; + $data = array_reduce( + $data, + function ($carry, $item) use ($filters, $where_without_group) { + global $config; + // Transforms array of arrays $data into an array + // of objects, making a post-process of certain fields. + $tmp = (object) $item; + + $severity_class = get_priority_class($tmp->severity); + + $status = $tmp->status; + + // Status. + if ($status == 0) { + $tmp->status = html_print_image( + 'images/pixel_red.png', + true, + [ + 'title' => __('Not validated'), + 'width' => '20', + 'height' => '20', + ] + ); + } else { + $tmp->status = html_print_image( + 'images/pixel_green.png', + true, + [ + 'title' => __('Validated'), + 'width' => '20', + 'height' => '20', + ] + ); + } + + // SNMP Agent. + $agent = agents_get_agent_with_ip($tmp->source); + if ($agent === false) { + $tmp->snmp_agent .= ''.$tmp->source.''; + } else { + $tmp->snmp_agent .= ''; + } + + // Enterprise string. + if (empty($tmp->text) === false) { + $enterprise_string = $tmp->text; + } else if (empty($tmp->oid) === false) { + $enterprise_string = $tmp->oid; + } else { + $enterprise_string = __('N/A'); + } + + $tmp->enterprise_string = ''; + + // Count. + if ($filters['filter_group_by']) { + $sql = "SELECT count(*) FROM ttrap WHERE 1=1 + $where_without_group + AND oid='".$tmp->oid."' + AND source='".$tmp->source."'"; + $group_traps = db_get_value_sql($sql); + $tmp->count = '
'.$group_traps.'
'; + } + + // Trap subtype. + $tmp->trap_subtype = '
'; + if (empty($tmp->value) === true) { + $tmp->trap_subtype .= __('N/A'); + } else { + $tmp->trap_subtype .= ui_print_truncate_text($tmp->value, GENERIC_SIZE_TEXT, false); + } + + $tmp->trap_subtype .= '
'; + + // User ID. + $tmp->user_id = '
'; + if (empty($status) === false) { + $tmp->user_id .= ''.substr($tmp->id_usuario, 0, 8).''; + if (!empty($tmp->id_usuario)) { + $tmp->user_id .= ui_print_help_tip(get_user_fullname($tmp->id_usuario), true); + } + } else { + $tmp->user_id .= '--'; + } + + $tmp->user_id .= '
'; + + // Timestamp. + $timestamp = $tmp->timestamp; + $tmp->timestamp = '
'; + $tmp->timestamp .= ''; + $tmp->timestamp .= ui_print_timestamp($timestamp, true); + $tmp->timestamp .= '
'; + + // Use alert severity if fired. + if (empty($tmp->alerted) === false) { + $tmp->alert = html_print_image('images/pixel_yellow.png', true, ['width' => '20', 'height' => '20', 'border' => '0', 'title' => __('Alert fired')]); + } else { + $tmp->alert = html_print_image('images/pixel_gray.png', true, ['width' => '20', 'height' => '20', 'border' => '0', 'title' => __('Alert not fired')]); + } + + // Actions. + $tmp->action = ''; + if ($status != 1) { + $tmp->action .= ''.html_print_image( + 'images/ok.png', + true, + [ + 'border' => '0', + 'title' => __('Validate'), + 'onclick' => 'validate_trap(\''.$tmp->id_trap.'\')', + ] + ).' '; + } + + if ($tmp->source == '') { + if (\user_is_admin()) { + $tmp->action .= ''.html_print_image( + 'images/cross.png', + true, + [ + 'border' => '0', + 'title' => __('Delete'), + 'class' => 'invert_filter', + 'onclick' => 'delete_trap(\''.$tmp->id_trap.'\')', + ] + ).' '; + } + } else { + $tmp->action .= ''.html_print_image( + 'images/cross.png', + true, + [ + 'border' => '0', + 'title' => __('Delete'), + 'class' => 'invert_filter', + 'onclick' => 'delete_trap(\''.$tmp->id_trap.'\')', + ] + ).' '; + } + + $tmp->action .= ''.html_print_image( + 'images/eye.png', + true, + [ + 'alt' => __('Show more'), + 'title' => __('Show more'), + 'class' => 'invert_filter', + ] + ).''; + $tmp->action .= ''.html_print_image('images/edit.png', true, ['alt' => __('SNMP trap editor'), 'title' => __('SNMP trap editor')]).''; + + $tmp->m = html_print_checkbox_extended('snmptrapid[]', $tmp->id_trap, false, false, '', 'class="chk"', true); + + $carry[] = $tmp; + return $carry; + }, + ); + } + + if (empty($data) === true) { + $total = 0; + $data = []; + } + + echo json_encode( + [ + 'data' => $data, + 'recordsTotal' => $total, + 'recordsFiltered' => $total, + ] + ); + // Capture output. + $response = ob_get_clean(); + } catch (Exception $e) { + echo json_encode(['error' => $e->getMessage()]); + exit; + } + + // If not valid, show error with issue. + json_decode($response); + if (json_last_error() === JSON_ERROR_NONE) { + // If valid dump. + echo $response; + } else { + echo json_encode( + ['error' => $response] + ); + } + + exit; + } + + + /** + * Checks if target method is available to be called using AJAX. + * + * @param string $method Target method. + * + * @return boolean True allowed, false not. + */ + public function ajaxMethod(string $method) + { + return in_array($method, $this->AJAXMethods); + } + + + /** + * Delete snmp trap. + * + * @return void + */ + public function deleteTrap() + { + $id_trap = get_parameter('id', 0); + $group_by = (bool) get_parameter('group_by', 0); + + if ($id_trap > 0) { + if ($group_by === true) { + $sql_ids_traps = 'SELECT id_trap, source FROM ttrap WHERE oid IN (SELECT oid FROM ttrap WHERE id_trap = '.$id_trap.') + AND source IN (SELECT source FROM ttrap WHERE id_trap = '.$id_trap.')'; + $ids_traps = db_get_all_rows_sql($sql_ids_traps); + + foreach ($ids_traps as $key => $value) { + $result = db_process_sql_delete('ttrap', ['id_trap' => $value['id_trap']]); + enterprise_hook('snmp_update_forwarded_modules', [$value]); + } + } else { + $forward_info = db_get_row('ttrap', 'id_trap', $id_trap); + $result = db_process_sql_delete('ttrap', ['id_trap' => $id_trap]); + enterprise_hook('snmp_update_forwarded_modules', [$forward_info]); + } + } + } + + + /** + * Delete snmp traps. + * + * @return void + */ + public function deleteTraps() + { + $ids = get_parameter('ids', []); + $group_by = (bool) get_parameter('group_by', false); + + if (empty($ids) === false) { + $string_ids = implode(',', $ids); + if ($group_by === true) { + $sql_ids_traps = 'SELECT id_trap, source FROM ttrap WHERE oid IN (SELECT oid FROM ttrap WHERE id_trap IN ('.$string_ids.')) + AND source IN (SELECT source FROM ttrap WHERE id_trap IN ('.$string_ids.'))'; + $ids_traps = db_get_all_rows_sql($sql_ids_traps); + + $array = array_column($ids_traps, 'id_trap'); + + $delete = sprintf( + 'DELETE FROM `ttrap` WHERE id_trap IN (%s)', + implode(',', $array), + ); + db_process_sql($delete); + + foreach ($ids_traps as $key => $value) { + enterprise_hook('snmp_update_forwarded_modules', [$value]); + } + } else { + $delete = sprintf( + 'DELETE FROM `ttrap` WHERE id_trap IN (%s)', + $string_ids, + ); + db_process_sql($delete); + foreach ($ids as $id_trap) { + enterprise_hook('snmp_update_forwarded_modules', [$id_trap]); + } + } + } + } + + + /** + * Validate snmp trap. + * + * @return void + */ + public function validateTrap() + { + global $config; + + $id_trap = get_parameter('id', 0); + + $values = [ + 'status' => 1, + 'id_usuario' => $config['id_user'], + ]; + + $result = db_process_sql_update('ttrap', $values, ['id_trap' => $id_trap]); + enterprise_hook('snmp_update_forwarded_modules', [$id_trap]); + } + + + /** + * Validate snmp traps. + * + * @return void + */ + public function validateTraps() + { + global $config; + + $ids = get_parameter('ids', []); + + if (empty($ids) === false) { + $update = sprintf( + 'UPDATE ttrap SET `status` = 1, `id_usuario` = "%s" WHERE id_trap IN (%s)', + $config['id_user'], + implode(',', $ids) + ); + db_process_sql($update); + + foreach ($ids as $id_trap) { + enterprise_hook('snmp_update_forwarded_modules', [$id_trap]); + } + } + } + + + /** + * Load Javascript code. + * + * @return string. + */ + public function loadJS() + { + // Nothing for this moment. + ob_start(); + + // Javascript content. + ?> + + sub($interval); - -$date_from_trap = $ago->format('Y/m/d'); -$date_to_trap = $now->format('Y/m/d'); -$time_from_trap = $ago->format('H:i:s'); -$time_to_trap = $now->format('H:i:s'); - -$user_groups = users_get_groups($config['id_user'], $access, false); - -$str_user_groups = ''; -$i = 0; -foreach ($user_groups as $id => $name) { - if ($i == 0) { - $str_user_groups .= $id; +// Control call flow. +try { + // User access and validation is being processed on class constructor. + $controller = new SnmpConsole($ajaxPage); +} catch (Exception $e) { + if ((bool) is_ajax() === true) { + echo json_encode(['error' => '[SnmpConsole]'.$e->getMessage() ]); + exit; } else { - $str_user_groups .= ','.$id; - } - - $i++; -} - -$url = 'index.php?sec=estado&sec2=operation/snmpconsole/snmp_view'; -$url .= '&filter_severity='.$filter_severity.'&filter_fired='.$filter_fired; -$url .= '&free_search_string='.$free_search_string.'&pagination='.$pagination; -$url .= '&offset='.$offset.'&trap_type='.$trap_type.'&group_by='.$group_by; -$url .= '&hours_ago='.$hours_ago.'&pure='.$pure; - -$statistics['text'] = ''.html_print_image( - 'images/op_reporting.png', - true, - [ - 'title' => __('Statistics'), - 'class' => 'invert_filter', - ] -).''; -$list['text'] = ''.html_print_image( - 'images/op_snmp.png', - true, - [ - 'title' => __('List'), - 'class' => 'invert_filter', - ] -).''; -$list['active'] = true; - -if ($config['pure']) { - $fullscreen['text'] = ''.html_print_image( - 'images/normal_screen.png', - true, - [ - 'title' => __('Normal screen'), - 'class' => 'invert_filter', - ] - ).''; -} else { - // Fullscreen. - $fullscreen['text'] = ''.html_print_image( - 'images/full_screen.png', - true, - [ - 'title' => __('Full screen'), - 'class' => 'invert_filter', - ] - ).''; -} - - -// OPERATIONS -// Delete SNMP Trap entry Event. -if (isset($_GET['delete'])) { - $id_trap = (int) get_parameter_get('delete', 0); - if ($id_trap > 0) { - if ($group_by) { - $sql_ids_traps = 'SELECT id_trap, source FROM ttrap WHERE oid IN (SELECT oid FROM ttrap WHERE id_trap = '.$id_trap.') - AND source IN (SELECT source FROM ttrap WHERE id_trap = '.$id_trap.')'; - $ids_traps = db_get_all_rows_sql($sql_ids_traps); - - foreach ($ids_traps as $key => $value) { - $result = db_process_sql_delete('ttrap', ['id_trap' => $value['id_trap']]); - enterprise_hook('snmp_update_forwarded_modules', [$value]); - } - } else { - $forward_info = db_get_row('ttrap', 'id_trap', $id_trap); - $result = db_process_sql_delete('ttrap', ['id_trap' => $id_trap]); - enterprise_hook('snmp_update_forwarded_modules', [$forward_info]); - ui_print_result_message( - $result, - __('Successfully deleted'), - __('Could not be deleted') - ); - } - } -} - -// Check Event. -if (isset($_GET['check'])) { - $id_trap = (int) get_parameter_get('check', 0); - $values = [ - 'status' => 1, - 'id_usuario' => $config['id_user'], - ]; - $result = db_process_sql_update('ttrap', $values, ['id_trap' => $id_trap]); - enterprise_hook('snmp_update_forwarded_modules', [$id_trap]); - - ui_print_result_message( - $result, - __('Successfully updated'), - __('Could not be updated') - ); -} - -// Mass-process DELETE. -if (isset($_POST['deletebt'])) { - $trap_ids = get_parameter_post('snmptrapid', []); - if (is_array($trap_ids)) { - if ($group_by) { - foreach ($trap_ids as $key => $value) { - $sql_ids_traps = 'SELECT id_trap, source FROM ttrap WHERE oid IN (SELECT oid FROM ttrap WHERE id_trap = '.$value.') - AND source IN (SELECT source FROM ttrap WHERE id_trap = '.$value.')'; - $ids_traps = db_get_all_rows_sql($sql_ids_traps); - - foreach ($ids_traps as $key2 => $value2) { - $result = db_process_sql_delete('ttrap', ['id_trap' => $value2['id_trap']]); - enterprise_hook('snmp_update_forwarded_modules', [$value2]); - } - } - } else { - foreach ($trap_ids as $id_trap) { - $forward_info = db_get_row('ttrap', 'id_trap', $id_trap); - db_process_sql_delete('ttrap', ['id_trap' => $id_trap]); - enterprise_hook('snmp_update_forwarded_modules', [$forward_info]); - } - } - } -} - -// Mass-process UPDATE. -if (isset($_POST['updatebt'])) { - $trap_ids = get_parameter_post('snmptrapid', []); - if (is_array($trap_ids)) { - foreach ($trap_ids as $id_trap) { - $sql = sprintf("UPDATE ttrap SET status = 1, id_usuario = '%s' WHERE id_trap = %d", $config['id_user'], $id_trap); - db_process_sql($sql); - enterprise_hook('snmp_update_forwarded_modules', [$id_trap]); - } - } -} - -// All traps. -$all_traps = db_get_all_rows_sql('SELECT DISTINCT source FROM ttrap'); - -if (empty($all_traps)) { - $all_traps = []; -} - -// Set filters. -$agents = []; -$oids = []; -$severities = get_priorities(); -$alerted = [ - __('Not fired'), - __('Fired'), -]; -foreach ($all_traps as $trap) { - $agent = agents_get_agent_with_ip($trap['source']); - $agents[$trap['source']] = $agent !== false ? ($agent['alias'] ? $agent['alias'] : $agent['nombre']) : $trap['source']; - $oid = enterprise_hook('get_oid', [$trap]); - if ($oid === ENTERPRISE_NOT_HOOK) { - $oid = $trap['oid']; - } - - $oids[$oid] = $oid; -} - -$prea = array_keys($user_groups); -$ids = join(',', $prea); -// Cuantos usuarios hay operadores con un grupo que exista y no lo tenga ningun usuario. -$user_in_group_wo_agents = db_get_value_sql('select count(DISTINCT(id_usuario)) from tusuario_perfil where id_usuario ="'.$config['id_user'].'" and id_perfil = 1 and id_grupo in (select id_grupo from tgrupo where id_grupo in ('.$ids.') and id_grupo not in (select id_grupo from tagente))'); - -switch ($config['dbtype']) { - case 'mysql': - case 'postgresql': - if ($user_in_group_wo_agents == 0) { - $rows = db_get_all_rows_filter( - 'tagente', - ['id_grupo' => array_keys($user_groups)], - ['id_agente'] - ); - $id_agents = []; - foreach ($rows as $row) { - $id_agents[] = $row['id_agente']; - } - - if (!empty($id_agents)) { - $address_by_user_groups = agents_get_addresses($id_agents); - foreach ($address_by_user_groups as $i => $a) { - $address_by_user_groups[$i] = '"'.$a.'"'; - } - } - } else { - $rows = db_get_all_rows_filter( - 'tagente', - [], - ['id_agente'] - ); - $id_agents = []; - foreach ($rows as $row) { - $id_agents[] = $row['id_agente']; - } - - $all_address_agents = agents_get_addresses($id_agents); - foreach ($all_address_agents as $i => $a) { - $all_address_agents[$i] = '"'.$a.'"'; - } - } - break; - - default: - // Default. - break; -} - -if (empty($address_by_user_groups)) { - $address_by_user_groups = []; - array_unshift($address_by_user_groups, '""'); -} - -if (empty($all_address_agents)) { - $all_address_agents = []; - array_unshift($all_address_agents, '""'); -} - - -// Make query to extract traps of DB. -switch ($config['dbtype']) { - case 'mysql': - $sql = 'SELECT * - FROM ttrap - WHERE ( - `source` IN ('.implode(',', $address_by_user_groups).") OR - `source`='' OR - `source` NOT IN (".implode(',', $all_address_agents).') - ) - %s - ORDER BY timestamp DESC - LIMIT %d,%d'; - break; - - case 'postgresql': - $sql = 'SELECT * - FROM ttrap - WHERE ( - source IN ('.implode(',', $address_by_user_groups).") OR - source='' OR - source NOT IN (".implode(',', $all_address_agents).') - ) - %s - ORDER BY timestamp DESC - LIMIT %d OFFSET %d'; - break; - - case 'oracle': - $sql = "SELECT * - FROM ttrap - WHERE (source IN ( - SELECT direccion FROM tagente - WHERE id_grupo IN ($str_user_groups) - ) OR source='' OR source NOT IN (SELECT direccion FROM tagente WHERE direccion IS NOT NULL)) %s - ORDER BY timestamp DESC"; - break; - - default: - // Default. - break; -} - -switch ($config['dbtype']) { - case 'mysql': - case 'postgresql': - $sql_all = 'SELECT * - FROM ttrap - WHERE ( - source IN ('.implode(',', $address_by_user_groups).") OR - source='' OR - source NOT IN (".implode(',', $all_address_agents).') - ) - %s - ORDER BY timestamp DESC'; - $sql_count = 'SELECT COUNT(id_trap) - FROM ttrap - WHERE ( - source IN ('.implode(',', $address_by_user_groups).") OR - source='' OR - source NOT IN (".implode(',', $all_address_agents).') - ) - %s'; - break; - - case 'oracle': - $sql_all = "SELECT * - FROM ttrap - WHERE (source IN ( - SELECT direccion FROM tagente - WHERE id_grupo IN ($str_user_groups) - ) OR source='' OR source NOT IN (SELECT direccion FROM tagente WHERE direccion IS NOT NULL)) - %s - ORDER BY timestamp DESC"; - $sql_count = "SELECT COUNT(id_trap) - FROM ttrap - WHERE ( - source IN ( - SELECT direccion FROM tagente - WHERE id_grupo IN ($str_user_groups) - ) OR source='' OR source NOT IN (SELECT direccion FROM tagente WHERE direccion IS NOT NULL)) - %s"; - break; - - default: - // Default. - break; -} - -// $whereSubquery = 'WHERE 1=1'; -$whereSubquery = ''; - -if ($filter_fired != -1) { - $whereSubquery .= ' AND alerted = '.$filter_fired; -} - -if ($free_search_string != '') { - switch ($config['dbtype']) { - case 'mysql': - $whereSubquery .= ' - AND (source LIKE "%'.$free_search_string.'%" OR - oid LIKE "%'.$free_search_string.'%" OR - oid_custom LIKE "%'.$free_search_string.'%" OR - type_custom LIKE "%'.$free_search_string.'%" OR - value LIKE "%'.$free_search_string.'%" OR - value_custom LIKE "%'.$free_search_string.'%" OR - id_usuario LIKE "%'.$free_search_string.'%" OR - text LIKE "%'.$free_search_string.'%" OR - description LIKE "%'.$free_search_string.'%")'; - break; - - case 'postgresql': - case 'oracle': - $whereSubquery .= ' - AND (source LIKE \'%'.$free_search_string.'%\' OR - oid LIKE \'%'.$free_search_string.'%\' OR - oid_custom LIKE \'%'.$free_search_string.'%\' OR - type_custom LIKE \'%'.$free_search_string.'%\' OR - value LIKE \'%'.$free_search_string.'%\' OR - value_custom LIKE \'%'.$free_search_string.'%\' OR - id_usuario LIKE \'%'.$free_search_string.'%\' OR - text LIKE \'%'.$free_search_string.'%\' OR - description LIKE \'%'.$free_search_string.'%\')'; - break; - - default: - // Default. - break; - } -} - -if ($date_from_trap != '') { - if ($time_from_trap != '') { - $whereSubquery .= ' - AND (UNIX_TIMESTAMP(timestamp) > UNIX_TIMESTAMP("'.$date_from_trap.' '.$time_from_trap.'")) - '; - } else { - $whereSubquery .= ' - AND (UNIX_TIMESTAMP(timestamp) > UNIX_TIMESTAMP("'.$date_from_trap.' 23:59:59")) - '; - } -} - -if ($date_to_trap != '') { - if ($time_to_trap) { - $whereSubquery .= ' - AND (UNIX_TIMESTAMP(timestamp) < UNIX_TIMESTAMP("'.$date_to_trap.' '.$time_to_trap.'")) - '; - } else { - $whereSubquery .= ' - AND (UNIX_TIMESTAMP(timestamp) < UNIX_TIMESTAMP("'.$date_to_trap.' 23:59:59")) - '; - } -} - -if ($filter_severity != -1) { - // There are two special severity values aimed to match two different trap standard severities in database: warning/critical and critical/normal. - if ($filter_severity != EVENT_CRIT_OR_NORMAL && $filter_severity != EVENT_CRIT_WARNING_OR_CRITICAL) { - // Test if enterprise is installed to search oid in text or oid field in ttrap. - if ($config['enterprise_installed']) { - $whereSubquery .= ' AND ( - (alerted = 0 AND severity = '.$filter_severity.') OR - (alerted = 1 AND priority = '.$filter_severity.'))'; - } else { - $whereSubquery .= ' AND ( - (alerted = 0 AND 1 = '.$filter_severity.') OR - (alerted = 1 AND priority = '.$filter_severity.'))'; - } - } else if ($filter_severity === EVENT_CRIT_WARNING_OR_CRITICAL) { - // Test if enterprise is installed to search oid in text or oid field in ttrap. - if ($config['enterprise_installed']) { - $whereSubquery .= ' AND ( - (alerted = 0 AND (severity = '.EVENT_CRIT_WARNING.' OR severity = '.EVENT_CRIT_CRITICAL.')) OR - (alerted = 1 AND (priority = '.EVENT_CRIT_WARNING.' OR priority = '.EVENT_CRIT_CRITICAL.')))'; - } else { - $whereSubquery .= ' AND ( - (alerted = 1 AND (priority = '.EVENT_CRIT_WARNING.' OR priority = '.EVENT_CRIT_CRITICAL.')))'; - } - } else if ($filter_severity === EVENT_CRIT_OR_NORMAL) { - // Test if enterprise is installed to search oid in text or oid field in ttrap. - if ($config['enterprise_installed']) { - $whereSubquery .= ' AND ( - (alerted = 0 AND (severity = '.EVENT_CRIT_NORMAL.' OR severity = '.EVENT_CRIT_CRITICAL.')) OR - (alerted = 1 AND (priority = '.EVENT_CRIT_NORMAL.' OR priority = '.EVENT_CRIT_CRITICAL.')))'; - } else { - $whereSubquery .= ' AND ( - (alerted = 1 AND (priority = '.EVENT_CRIT_NORMAL.' OR priority = '.EVENT_CRIT_CRITICAL.')))'; - } - } -} - -if ($filter_status != -1) { - $whereSubquery .= ' AND status = '.$filter_status; -} - -if ($trap_type == 5) { - $whereSubquery .= ' AND type NOT IN (0, 1, 2, 3, 4)'; -} else if ($trap_type != -1) { - $whereSubquery .= ' AND type = '.$trap_type; -} - -// Disable this feature (time will decide if temporarily) in Oracle cause the group by is very confictive. -if ($group_by && $config['dbtype'] != 'oracle') { - $where_without_group = $whereSubquery; - $whereSubquery .= ' GROUP BY source,oid'; -} - -switch ($config['dbtype']) { - case 'mysql': - $sql = sprintf($sql, $whereSubquery, $offset, $pagination); - break; - - case 'postgresql': - $sql = sprintf($sql, $whereSubquery, $pagination, $offset); - break; - - case 'oracle': - $set = []; - $set['limit'] = $pagination; - $set['offset'] = $offset; - $sql = sprintf($sql, $whereSubquery); - $sql = oracle_recode_query($sql, $set); - break; - - default: - // Default. - break; -} - -$sql_all = sprintf($sql_all, $whereSubquery); -$sql_count = sprintf($sql_count, $whereSubquery); - -$table = new stdClass(); -$table->width = '100%'; -$table->cellpadding = 0; -$table->cellspacing = 0; -$table->class = 'databox filters'; -$table->size = []; -$table->size[0] = '120px'; -$table->data = []; - -// Alert status select. -$table->data[1][0] = ''.__('Alert').''; -$table->data[1][1] = html_print_select( - $alerted, - 'filter_fired', - $filter_fired, - '', - __('All'), - '-1', - true -); - -// Block size for pagination select. -$table->data[2][0] = ''.__('Block size for pagination').''; -$paginations[25] = 25; -$paginations[50] = 50; -$paginations[100] = 100; -$paginations[200] = 200; -$paginations[500] = 500; -$table->data[2][1] = html_print_select( - $paginations, - 'pagination', - $pagination, - '', - __('Default'), - $config['block_size'], - true -); - -// Severity select. -$table->data[1][2] = ''.__('Severity').''; -$table->data[1][3] = html_print_select( - $severities, - 'filter_severity', - $filter_severity, - '', - __('All'), - -1, - true -); - -// Status. -$table->data[3][0] = ''.__('Status').''; - -$status_array[-1] = __('All'); -$status_array[0] = __('Not validated'); -$status_array[1] = __('Validated'); -$table->data[3][1] = html_print_select( - $status_array, - 'filter_status', - $filter_status, - '', - '', - '', - true -); - -// Free search (search by all alphanumeric fields). -$table->data[2][3] = ''.__('Free search').''.ui_print_help_tip( - __( - 'Search by any alphanumeric field in the trap. - REMEMBER trap sources need to be searched by IP Address' - ), - true -); -$table->data[2][4] = html_print_input_text( - 'free_search_string', - $free_search_string, - '', - 40, - 0, - true -); - -$table->data[4][0] = ''.__('Max. hours old').''; -$table->data[4][1] = html_print_input( - [ - 'type' => 'number', - 'name' => 'hours_ago', - 'value' => $hours_ago, - 'step' => 1, - 'return' => true, - ] -); - -// Type filter (ColdStart, WarmStart, LinkDown, LinkUp, authenticationFailure, Other). -$table->data[4][3] = ''.__('Trap type').''.ui_print_help_tip(__('Search by trap type'), true); -$trap_types = [ - -1 => __('None'), - 0 => __('Cold start (0)'), - 1 => __('Warm start (1)'), - 2 => __('Link down (2)'), - 3 => __('Link up (3)'), - 4 => __('Authentication failure (4)'), - 5 => __('Other'), -]; -$table->data[4][4] = html_print_select( - $trap_types, - 'trap_type', - $trap_type, - '', - '', - '', - true, - false, - false -); - -// Disable this feature (time will decide if temporarily) in Oracle cause the group by is very confictive. -if ($config['dbtype'] != 'oracle') { - $table->data[3][3] = ''.__('Group by Enterprise String/IP').''; - $table->data[3][4] = __('Yes').' '.html_print_radio_button('group_by', 1, '', $group_by, true).'  '; - $table->data[3][4] .= __('No').' '.html_print_radio_button('group_by', 0, '', $group_by, true); -} - -$filter = '
'; -$filter .= html_print_table($table, true); -$filter .= '
'; -$filter .= html_print_submit_button(__('Update'), 'search', false, 'class="sub upd"', true); -$filter .= '
'; -$filter .= '
'; - -$filter_resume = []; -$filter_resume['filter_fired'] = $alerted[$filter_fired]; -$filter_resume['filter_severity'] = $severities[$filter_severity]; -$filter_resume['pagination'] = $paginations[$pagination]; -$filter_resume['free_search_string'] = $free_search_string; -$filter_resume['filter_status'] = $status_array[$filter_status]; -$filter_resume['group_by'] = $group_by; -$filter_resume['hours_ago'] = $hours_ago; -$filter_resume['trap_type'] = $trap_types[$trap_type]; - -$traps = db_get_all_rows_sql($sql, true); -$trapcount = (int) db_get_value_sql($sql_count, false, true); - -// Re-sort traps by timestamp if history db is enabled. -if ($config['history_db_enabled'] == 1) { - usort( - $traps, - function ($a, $b) { - return strtotime($a['timestamp']) < strtotime($b['timestamp']); - } - ); -} - -// No traps. -if (empty($traps)) { - // Header - ui_print_standard_header( - __('SNMP Console'), - 'images/op_snmp.png', - false, - 'snmp_console', - false, - [ - $list, - $statistics, - ], - [ - [ - 'link' => '', - 'label' => __('Monitoring'), - ], - [ - 'link' => '', - 'label' => __('SNMP'), - ], - ] - ); - - $sql2 = 'SELECT * - FROM ttrap - WHERE ( - `source` IN ('.implode(',', $address_by_user_groups).") OR - `source`='' OR - `source` NOT IN (".implode(',', $all_address_agents).') - ) - AND status = 0 - ORDER BY timestamp DESC'; - $traps2 = db_get_all_rows_sql($sql2); - - if (!empty($traps2)) { - ui_toggle($filter, __('Toggle filter(s)')); - - print_snmp_tags_active_filters($filter_resume); - - ui_print_info_message(['no_close' => true, 'message' => __('There are no SNMP traps in database that contains this filter') ]); - } else { - ui_print_info_message(['no_close' => true, 'message' => __('There are no SNMP traps in database') ]); + echo '[SnmpConsole]'.$e->getMessage(); } + // Stop this execution, but continue 'globally'. return; -} else { - if ($config['pure']) { - echo '
'; +} - echo ''; - - echo '
'; - - ui_require_css_file('pandora_enterprise', ENTERPRISE_DIR.'/include/styles/'); - ui_require_css_file('pandora_dashboard', ENTERPRISE_DIR.'/include/styles/'); - ui_require_css_file('cluetip', 'include/styles/js/'); - - ui_require_jquery_file('countdown'); - ui_require_javascript_file('pandora_dashboard', ENTERPRISE_DIR.'/include/javascript/'); - ui_require_javascript_file('wz_jsgraphics'); - ui_require_javascript_file('pandora_visual_console'); + if (method_exists($controller, $method) === true) { + if ($controller->ajaxMethod($method) === true) { + $controller->{$method}(); + } else { + $controller->error('Unavailable method.'); + } } else { - // Header - ui_print_standard_header( - __('SNMP Console'), - 'images/op_snmp.png', - false, - '', - false, - [ - $fullscreen, - $list, - $statistics, - ], - [ - [ - 'link' => '', - 'label' => __('Monitoring'), - ], - [ - 'link' => '', - 'label' => __('SNMP'), - ], - ] - ); + $controller->error('Method not found. ['.$method.']'); } -} -ui_toggle($filter, __('Toggle filter(s)')); -unset($table); - -print_snmp_tags_active_filters($filter_resume); - -if (($config['dbtype'] == 'oracle') && ($traps !== false)) { - $traps_size = count($traps); - for ($i = 0; $i < $traps_size; $i++) { - unset($traps[$i]['rnum']); - } -} - -$url_snmp = 'index.php?sec=snmpconsole&sec2=operation/snmpconsole/snmp_view'; -$url_snmp .= '&filter_severity='.$filter_severity.'&filter_fired='.$filter_fired; -$url_snmp .= '&filter_status='.$filter_status.'&refresh='.((int) get_parameter('refresh', 0)); -$url_snmp .= '&pure='.$config['pure'].'&trap_type='.$trap_type; -$url_snmp .= '&group_by='.$group_by.'&free_search_string='.$free_search_string; -$url_snmp .= '&hours_ago='.$hours_ago; - -$urlPagination = $url_snmp.'&pagination='.$pagination.'&offset='.$offset; - -ui_pagination($trapcount, $urlPagination, $offset, $pagination); - -echo '
'; - -$table = new StdClass(); -$table->cellpadding = 0; -$table->cellspacing = 0; -$table->width = '100%'; -$table->class = 'databox data'; -$table->head = []; -$table->size = []; -$table->data = []; -$table->align = []; -$table->headstyle = []; - -$table->head[0] = __('Status'); -$table->align[0] = 'center'; -$table->size[0] = '5%'; -$table->headstyle[0] = 'text-align: center'; - -$table->head[1] = __('SNMP Agent'); -$table->align[1] = 'center'; -$table->size[1] = '15%'; -$table->headstyle[1] = 'text-align: center'; - -$table->head[2] = __('Enterprise String'); -$table->align[2] = 'center'; -$table->size[2] = '18%'; -$table->headstyle[2] = 'text-align: center'; - -if ($group_by) { - $table->head[3] = __('Count'); - $table->align[3] = 'center'; - $table->size[3] = '5%'; - $table->headstyle[3] = 'text-align: center'; -} - -$table->head[4] = __('Trap subtype'); -$table->align[4] = 'center'; -$table->size[4] = '10%'; -$table->headstyle[4] = 'text-align: center'; - -$table->head[5] = __('User ID'); -$table->align[5] = 'center'; -$table->size[5] = '10%'; -$table->headstyle[5] = 'text-align: center'; - -$table->head[6] = __('Timestamp'); -$table->align[6] = 'center'; -$table->size[6] = '10%'; -$table->headstyle[6] = 'text-align: center'; - -$table->head[7] = __('Alert'); -$table->align[7] = 'center'; -$table->size[7] = '5%'; -$table->headstyle[7] = 'text-align: center'; - -$table->head[8] = __('Action'); -$table->align[8] = 'center'; -$table->size[8] = '10%'; -$table->headstyle[8] = 'min-width: 125px;text-align: center'; - -$table->head[9] = html_print_checkbox_extended( - 'allbox', - 1, - false, - false, - 'javascript:CheckAll();', - 'class="chk" title="'.__('All').'"', - true -); -$table->align[9] = 'center'; -$table->size[9] = '5%'; -$table->headstyle[9] = 'text-align: center'; - -$table->style[8] = 'background: #F3F3F3; color: #111 !important;'; - -// Skip offset records. -$idx = 0; -if ($traps !== false) { - foreach ($traps as $trap) { - $data = []; - if (empty($trap['description'])) { - $trap['description'] = ''; - } - - $severity = enterprise_hook('get_severity', [$trap]); - if ($severity === ENTERPRISE_NOT_HOOK) { - $severity = $trap['alerted'] == 1 ? $trap['priority'] : 1; - } - - // Status. - if ($trap['status'] == 0) { - $data[0] = html_print_image( - 'images/pixel_red.png', - true, - [ - 'title' => __('Not validated'), - 'width' => '20', - 'height' => '20', - ] - ); - } else { - $data[0] = html_print_image( - 'images/pixel_green.png', - true, - [ - 'title' => __('Validated'), - 'width' => '20', - 'height' => '20', - ] - ); - } - - // Agent matching source address. - $table->cellclass[$idx][1] = get_priority_class($severity); - $agent = agents_get_agent_with_ip($trap['source']); - if ($agent === false) { - if (! check_acl($config['id_user'], 0, 'AR')) { - continue; - } - - $data[1] = ''.$trap['source'].''; - } else { - if (! check_acl($config['id_user'], $agent['id_grupo'], 'AR')) { - continue; - } - - $data[1] = ''; - $data[1] .= ''.$agent['alias'].ui_print_help_tip($trap['source'], true, 'images/tip-blanco.png'); - ''; - } - - // OID. - $table->cellclass[$idx][2] = get_priority_class($severity); - if (! empty($trap['text'])) { - $enterprise_string = $trap['text']; - } else if (! empty($trap['oid'])) { - $enterprise_string = $trap['oid']; - } else { - $enterprise_string = __('N/A'); - } - - $data[2] = ''.$enterprise_string.''; - - // Count. - if ($group_by) { - $sql = "SELECT * FROM ttrap WHERE 1=1 - $where_without_group - AND oid='".$trap['oid']."' - AND source='".$trap['source']."'"; - $group_traps = db_get_all_rows_sql($sql); - $count_group_traps = count($group_traps); - $table->cellclass[$idx][3] = get_priority_class($severity); - $data[3] = ''.$count_group_traps.''; - } - - // Value. - $table->cellclass[$idx][4] = get_priority_class($severity); - if (empty($trap['value'])) { - $data[4] = __('N/A'); - } else { - $data[4] = ui_print_truncate_text($trap['value'], GENERIC_SIZE_TEXT, false); - } - - // User. - $table->cellclass[$idx][5] = get_priority_class($severity); - if (!empty($trap['status'])) { - $data[5] = ''.substr($trap['id_usuario'], 0, 8).''; - if (!empty($trap['id_usuario'])) { - $data[5] .= ui_print_help_tip(get_user_fullname($trap['id_usuario']), true); - } - } else { - $data[5] = '--'; - } - - // Timestamp. - $table->cellclass[$idx][6] = get_priority_class($severity); - $data[6] = ''; - $data[6] .= ui_print_timestamp($trap['timestamp'], true); - $data[6] .= ''; - - // Use alert severity if fired. - if (!empty($trap['alerted'])) { - $data[7] = html_print_image('images/pixel_yellow.png', true, ['width' => '20', 'height' => '20', 'border' => '0', 'title' => __('Alert fired')]); - } else { - $data[7] = html_print_image('images/pixel_gray.png', true, ['width' => '20', 'height' => '20', 'border' => '0', 'title' => __('Alert not fired')]); - } - - // Actions. - $data[8] = ''; - - if (empty($trap['status'])) { - $data[8] .= ''.html_print_image('images/ok.png', true, ['border' => '0', 'title' => __('Validate')]).' '; - } - - if ($trap['source'] == '') { - $is_admin = db_get_value('is_admin', 'tusuario', 'id_user', $config['id_user']); - if ($is_admin) { - $data[8] .= ''.html_print_image( - 'images/cross.png', - true, - [ - 'border' => '0', - 'title' => __('Delete'), - 'class' => 'invert_filter', - ] - ).' '; - } - } else { - $agent_trap_group = db_get_value('id_grupo', 'tagente', 'nombre', $trap['source']); - - $data[8] .= ''.html_print_image( - 'images/cross.png', - true, - [ - 'border' => '0', - 'title' => __('Delete'), - 'class' => 'invert_filter', - ] - ).' '; - } - - $data[8] .= ''.html_print_image( - 'images/eye.png', - true, - [ - 'alt' => __('Show more'), - 'title' => __('Show more'), - 'class' => 'invert_filter', - ] - ).''; - $data[8] .= enterprise_hook('editor_link', [$trap]); - - - $data[9] = html_print_checkbox_extended('snmptrapid[]', $trap['id_trap'], false, false, '', 'class="chk"', true); - - array_push($table->data, $data); - - // Hiden file for description. - $string = ' - - - - - - - - '; - - if ($trap['description'] != '') { - $string .= ' - - - '; - } - - if ($trap['type'] != '') { - $trap_types = [ - -1 => __('None'), - 0 => __('Cold start (0)'), - 1 => __('Warm start (1)'), - 2 => __('Link down (2)'), - 3 => __('Link up (3)'), - 4 => __('Authentication failure (4)'), - 5 => __('Other'), - ]; - - switch ($trap['type']) { - case -1: - $desc_trap_type = __('None'); - break; - - case 0: - $desc_trap_type = __('Cold start (0)'); - break; - - case 1: - $desc_trap_type = __('Warm start (1)'); - break; - - case 2: - $desc_trap_type = __('Link down (2)'); - break; - - case 3: - $desc_trap_type = __('Link up (3)'); - break; - - case 4: - $desc_trap_type = __('Authentication failure (4)'); - break; - - default: - $desc_trap_type = __('Other'); - break; - } - - $string .= ''; - } - - if ($group_by) { - $sql = "SELECT * FROM ttrap WHERE 1=1 - $where_without_group - AND oid='".$trap['oid']."' - AND source='".$trap['source']."'"; - $group_traps = db_get_all_rows_sql($sql); - $count_group_traps = count($group_traps); - - $sql = "SELECT timestamp FROM ttrap WHERE 1=1 - $where_without_group - AND oid='".$trap['oid']."' - AND source='".$trap['source']."' - ORDER BY `timestamp` DESC"; - $last_trap = db_get_value_sql($sql); - - $sql = "SELECT timestamp FROM ttrap WHERE 1=1 - $where_without_group - AND oid='".$trap['oid']."' - AND source='".$trap['source']."' - ORDER BY `timestamp` ASC"; - $first_trap = db_get_value_sql($sql); - - $string .= ' - - - '; - $string .= ' - - - '; - $string .= ' - - - '; - } - - $string .= '
'.''.__('Variable bindings:').''; - - if ($group_by) { - $new_url = 'index.php?sec=snmpconsole&sec2=operation/snmpconsole/snmp_view'; - $new_url .= '&filter_severity='.$filter_severity; - $new_url .= '&filter_fired='.$filter_fired; - $new_url .= '&filter_status='.$filter_status; - $new_url .= '&refresh='.((int) get_parameter('refresh', 0)); - $new_url .= '&pure='.$config['pure']; - $new_url .= '&group_by=0&free_search_string='.$free_search_string; - $new_url .= '&hours_ago='.$hours_ago; - - $string .= ''.__('See more details').''; - } else { - // Print binding vars separately. - $binding_vars = explode("\t", $trap['oid_custom']); - foreach ($binding_vars as $var) { - $string .= $var.'
'; - } - } - - $string .= '
'.''.__('Enterprise String:').' '.$trap['oid'].'
'.''.__('Description:').''.$trap['description'].'
'.__('Trap type:').''.$desc_trap_type.'
'.''.__('Count:').''.$count_group_traps.'
'.''.__('First trap:').''.$first_trap.'
'.''.__('Last trap:').''.$last_trap.'
'; - - $data = [$string]; - // $data = array($trap['description']); - $idx++; - $table->rowclass[$idx] = 'trap_info_'.$trap['id_trap']; - $table->colspan[$idx][0] = 10; - $table->rowstyle[$idx] = 'display: none;'; - array_push($table->data, $data); - - $idx++; - } -} - -// No matching traps. -if ($idx == 0) { - echo '
'.__('No matching traps found').'
'; + // Stop any execution. + exit; } else { - html_print_table($table); + // Run. + $controller->run(); } - -unset($table); - -echo '
'; - -html_print_submit_button(__('Validate'), 'updatebt', false, 'class="sub ok"'); - -echo ' '; -html_print_submit_button(__('Delete'), 'deletebt', false, 'class="sub delete" onClick="javascript:return confirm(\''.__('Are you sure?').'\')"'); - -echo '
'; - - -echo '
'; -echo '

'.__('Status').'

'; -echo html_print_image( - 'images/pixel_green.png', - true, - [ - 'width' => '20', - 'height' => '20', - ] -).' - '.__('Validated'); -echo '
'; -echo html_print_image( - 'images/pixel_red.png', - true, - [ - 'width' => '20', - 'height' => '20', - ] -).' - '.__('Not validated'); -echo '
'; -echo '
'; -echo '

'.__('Alert').'

'; -echo html_print_image( - 'images/pixel_yellow.png', - true, - [ - 'width' => '20', - 'height' => '20', - ] -).' - '.__('Fired'); -echo '
'; -echo html_print_image( - 'images/pixel_gray.png', - true, - [ - 'width' => '20', - 'height' => '20', - ] -).' - '.__('Not fired'); -echo '
'; -echo '
'; -echo '

'.__('Action').'

'; -echo html_print_image('images/ok.png', true).' - '.__('Validate'); -echo '
'; -echo html_print_image('images/cross.png', true, ['class' => 'invert_filter']).' - '.__('Delete'); -echo '
'; -echo '
'; -echo '

'.__('Legend').'

'; -foreach (get_priorities() as $num => $name) { - echo ''.$name.''; - echo '
'; -} - -echo '
'; -echo '
 
'; - -ui_include_time_picker(); -?> - - \ No newline at end of file From 5e510e7e12770a677aac8de9209f3ea0dc20bb84 Mon Sep 17 00:00:00 2001 From: "alejandro.campos@artica.es" Date: Wed, 16 Nov 2022 10:28:50 +0100 Subject: [PATCH 029/181] implemented custom field --- pandora_console/extras/mr/60.sql | 7 ++ .../godmode/agentes/agent_manager.php | 8 +++ .../godmode/agentes/configure_field.php | 70 ++++++++++++++++++- .../godmode/agentes/fields_manager.php | 24 ++++++- pandora_console/pandoradb.sql | 3 + pandora_console/pandoradb_data.sql | 2 +- 6 files changed, 110 insertions(+), 4 deletions(-) create mode 100644 pandora_console/extras/mr/60.sql diff --git a/pandora_console/extras/mr/60.sql b/pandora_console/extras/mr/60.sql new file mode 100644 index 0000000000..40a0a86c4f --- /dev/null +++ b/pandora_console/extras/mr/60.sql @@ -0,0 +1,7 @@ +START TRANSACTION; + +ALTER TABLE `tagent_custom_fields` ADD `is_link_enabled` TINYINT(1) NOT NULL DEFAULT 0; +ALTER TABLE `tagent_custom_fields` ADD COLUMN `link_text` VARCHAR(500) NOT NULL DEFAULT ''; +ALTER TABLE `tagent_custom_fields` ADD COLUMN `link_url` VARCHAR(2048) NOT NULL DEFAULT ''; + +COMMIT; diff --git a/pandora_console/godmode/agentes/agent_manager.php b/pandora_console/godmode/agentes/agent_manager.php index 676a4db993..e5e37e63ea 100644 --- a/pandora_console/godmode/agentes/agent_manager.php +++ b/pandora_console/godmode/agentes/agent_manager.php @@ -872,6 +872,14 @@ foreach ($fields as $field) { true, true ); + } else if ($field['is_link_enabled']) { + $link_text = $field['link_text']; + + if ($field['link_text'] === '') { + $link_text = $field['link_url']; + } + + $data_field[1] = ''.$link_text.''; } else { $data_field[1] = html_print_textarea( 'customvalue_'.$field['id_field'], diff --git a/pandora_console/godmode/agentes/configure_field.php b/pandora_console/godmode/agentes/configure_field.php index 7ef0fe042a..281c4a7447 100755 --- a/pandora_console/godmode/agentes/configure_field.php +++ b/pandora_console/godmode/agentes/configure_field.php @@ -30,6 +30,10 @@ $display_on_front = (bool) get_parameter('display_on_front', 0); $is_password_type = (bool) get_parameter('is_password_type', 0); $is_combo_enable = (bool) get_parameter('is_combo_enable', 0); $combo_values = (string) get_parameter('combo_values', ''); +$is_link_enabled = (bool) get_parameter('is_link_enabled', 0); +$link_text = (string) get_parameter('link_text', ''); +$link_url = (string) get_parameter('link_url', ''); + // Header. if ($id_field) { $field = db_get_row_filter('tagent_custom_fields', ['id_field' => $id_field]); @@ -38,6 +42,9 @@ if ($id_field) { $is_password_type = $field['is_password_type']; $combo_values = $field['combo_values'] ? $field['combo_values'] : ''; $is_combo_enable = $config['is_combo_enable']; + $is_link_enabled = $field['is_link_enabled']; + $link_text = $field['link_text']; + $link_url = $field['link_url']; ui_print_page_header(__('Update agent custom field'), 'images/custom_field.png', false, '', true, ''); } else { ui_print_page_header(__('Create agent custom field'), 'images/custom_field.png', false, '', true, ''); @@ -128,6 +135,39 @@ $table->data[4][1] = html_print_textarea( true ); +$table->data[5][0] = __('Link type'); +$table->data[5][1] = html_print_checkbox_switch_extended( + 'is_link_enabled', + 1, + $is_link_enabled, + false, + '', + '', + true +); + +$table->rowstyle[6] = 'display: none;'; +$table->data[6][0] = __('Link text'); +$table->data[6][1] = html_print_textarea( + 'link_text', + 3, + 65, + io_safe_output($link_text), + '', + true +); + +$table->rowstyle[7] = 'display: none;'; +$table->data[7][0] = __('Link URL'); +$table->data[7][1] = html_print_textarea( + 'link_url', + 3, + 65, + io_safe_output($link_url), + '', + true +); + echo '
'; html_print_table($table); echo '
'; @@ -167,7 +207,35 @@ $(document).ready (function () { }); } - + if ($('input[type=checkbox][name=is_link_enabled]').is(":checked") === true) { + $('#configure_field-6').show(); + $('#configure_field-7').show(); + $('#configure_field-1').hide(); + $('#configure_field-3').hide(); + } else { + $('#configure_field-6').hide(); + $('#configure_field-7').hide(); + $('#configure_field-1').show(); + $('#configure_field-3').show(); + } + + // if ( $('input[type=checkbox][name=is_link_enabled]').val() === 1) { + + //} + $('input[type=checkbox][name=is_link_enabled]').change(function () { + if( $(this).is(":checked") ){ + $('#configure_field-6').show(); + $('#configure_field-7').show(); + $('#configure_field-1').hide(); + $('#configure_field-3').hide(); + } else{ + $('#configure_field-6').hide(); + $('#configure_field-7').hide(); + $('#configure_field-1').show(); + $('#configure_field-3').show(); + } + }); + $('input[type=checkbox][name=is_combo_enable]').change(function () { if( $(this).is(":checked") ){ $('#configure_field-4').show(); diff --git a/pandora_console/godmode/agentes/fields_manager.php b/pandora_console/godmode/agentes/fields_manager.php index 960ed62776..3f0212388d 100644 --- a/pandora_console/godmode/agentes/fields_manager.php +++ b/pandora_console/godmode/agentes/fields_manager.php @@ -38,14 +38,26 @@ $display_on_front = (int) get_parameter('display_on_front', 0); $is_password_type = (int) get_parameter('is_password_type', 0); $combo_values = (string) get_parameter('combo_values', ''); $combo_value_selected = (string) get_parameter('combo_value_selected', ''); +$is_link_enabled = (bool) get_parameter('is_link_enabled', 0); +$link_text = (string) get_parameter('link_text', ''); +$link_url = (string) get_parameter('link_url', ''); + +if ($is_link_enabled === true && $link_url !== '') { + $parsed_url = parse_url($link_url); + if (empty($parsed_url['scheme']) === true) { + $link_url = 'http://'.ltrim($link_url, '/'); + } +} // Create field. if ($create_field) { // Check if name field is empty. - if ($name == '') { + if ($name === '') { ui_print_error_message(__('The name must not be empty')); } else if ($name == db_get_value('name', 'tagent_custom_fields', 'name', $name)) { ui_print_error_message(__('The name must be unique')); + } else if ($is_link_enabled === true && $link_url === '') { + ui_print_error_message(__('The link URL must not be empty')); } else { $result = db_process_sql_insert( 'tagent_custom_fields', @@ -54,6 +66,9 @@ if ($create_field) { 'display_on_front' => $display_on_front, 'is_password_type' => $is_password_type, 'combo_values' => $combo_values, + 'is_link_enabled' => $is_link_enabled, + 'link_text' => $link_text, + 'link_url' => $link_url, ] ); ui_print_success_message(__('Field successfully created')); @@ -63,12 +78,17 @@ if ($create_field) { // Update field. if ($update_field) { // Check if name field is empty. - if ($name != '') { + if ($name !== '' + && ($is_link_enabled === false || ($is_link_enabled === true && $link_url !== '')) + ) { $values = [ 'name' => $name, 'display_on_front' => $display_on_front, 'is_password_type' => $is_password_type, 'combo_values' => $combo_values, + 'is_link_enabled' => $is_link_enabled, + 'link_text' => $link_text, + 'link_url' => $link_url, ]; $result = db_process_sql_update('tagent_custom_fields', $values, ['id_field' => $id_field]); diff --git a/pandora_console/pandoradb.sql b/pandora_console/pandoradb.sql index 89fa418389..df51e426ff 100644 --- a/pandora_console/pandoradb.sql +++ b/pandora_console/pandoradb.sql @@ -2103,6 +2103,9 @@ CREATE TABLE IF NOT EXISTS `tagent_custom_fields` ( `display_on_front` TINYINT NOT NULL DEFAULT 0, `is_password_type` TINYINT NOT NULL DEFAULT 0, `combo_values` TEXT , + `is_link_enabled` TINYINT(1) NOT NULL DEFAULT 0, + `link_text` VARCHAR(500) NOT NULL DEFAULT '', + `link_url` VARCHAR(2048) NOT NULL DEFAULT '', PRIMARY KEY (`id_field`) ) ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4; diff --git a/pandora_console/pandoradb_data.sql b/pandora_console/pandoradb_data.sql index 369fab0092..fca70188ef 100644 --- a/pandora_console/pandoradb_data.sql +++ b/pandora_console/pandoradb_data.sql @@ -1189,7 +1189,7 @@ INSERT INTO `tplugin` (`id`, `name`, `description`, `max_timeout`, `execute`, `p INSERT INTO `tplugin` (`id`, `name`, `description`, `max_timeout`, `max_retries`, `execute`, `net_dst_opt`, `net_port_opt`, `user_opt`, `pass_opt`, `plugin_type`, `macros`, `parameters`, `no_delete`) VALUES (9,'Packet Loss','Checks for dropped packages after X seconds of testing. It returns % of dropped packets. It uses ping flood mode to launch 50 consecutive pings to a remote destination. On local, stable networks, value should be 0. ',30,0,'/usr/share/pandora_server/util/plugin/packet_loss.sh','','','','',0,'{\"1\":{\"macro\":\"_field1_\",\"desc\":\"Test time\",\"help\":\"\",\"value\":\"8\",\"hide\":\"\"},\"2\":{\"macro\":\"_field2_\",\"desc\":\"Target IP\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"}}','_field1_ _field2_', 1); -INSERT INTO `tagent_custom_fields` VALUES (1,'Serial Number',0,0,''),(2,'Department',0,0,''),(3,'Additional ID',0,0,''),(4,'eHorusID',0,0,''); +INSERT INTO `tagent_custom_fields` VALUES (1,'Serial Number',0,0,'',0,'',''),(2,'Department',0,0,'',0,'',''),(3,'Additional ID',0,0,'',0,'',''),(4,'eHorusID',0,0,'',0,'',''); INSERT INTO `ttag` VALUES (1,'network','Network equipment','http://artica.es','','',''),(2,'critical','Critical modules','','','',''),(3,'dmz','DMZ Network Zone','','','',''),(4,'performance','Performance anda capacity modules','','','',''),(5,'configuration','','','','',''); From 4118a46b9fc340ac5b7fd0b45267bf0d64b557ef Mon Sep 17 00:00:00 2001 From: Daniel Barbero Date: Fri, 18 Nov 2022 14:04:54 +0100 Subject: [PATCH 030/181] add new filter search events pandora_enterprise#9135 --- pandora_console/extras/mr/59.sql | 3 +- .../godmode/events/event_edit_filter.php | 21 +++++++++ pandora_console/include/ajax/events.php | 7 +++ pandora_console/include/functions_events.php | 45 ++++++++++++++----- pandora_console/include/styles/events.css | 5 +++ pandora_console/operation/events/events.php | 23 ++++++++-- pandora_console/pandoradb.sql | 1 + 7 files changed, 90 insertions(+), 15 deletions(-) diff --git a/pandora_console/extras/mr/59.sql b/pandora_console/extras/mr/59.sql index 69f93d9e8a..b78fda6904 100644 --- a/pandora_console/extras/mr/59.sql +++ b/pandora_console/extras/mr/59.sql @@ -1,5 +1,6 @@ START TRANSACTION; -ALTER TABLE `tevent_filter` ADD COLUMN `owner_user` INT NOT NULL DEFAULT 0; +ALTER TABLE `tevent_filter` ADD COLUMN `owner_user` TEXT; +ALTER TABLE `tevent_filter` ADD COLUMN `not_search` INT NOT NULL DEFAULT 0; COMMIT; \ No newline at end of file diff --git a/pandora_console/godmode/events/event_edit_filter.php b/pandora_console/godmode/events/event_edit_filter.php index c796feaa90..302c75e46b 100644 --- a/pandora_console/godmode/events/event_edit_filter.php +++ b/pandora_console/godmode/events/event_edit_filter.php @@ -66,6 +66,7 @@ if ($id) { $severity = explode(',', $filter['severity']); $status = $filter['status']; $search = $filter['search']; + $not_search = $filter['not_search']; $text_agent = $filter['text_agent']; $id_agent = $filter['id_agent']; $text_module = $filter['text_module']; @@ -116,6 +117,7 @@ if ($id) { $severity = ''; $status = ''; $search = ''; + $not_search = 0; $text_agent = ''; $pagination = ''; $event_view_hr = ''; @@ -142,6 +144,7 @@ if ($update || $create) { $severity = implode(',', get_parameter('severity', -1)); $status = get_parameter('status', ''); $search = get_parameter('search', ''); + $not_search = get_parameter_switch('not_search', 0); $text_agent = get_parameter('text_agent', ''); $id_agent = (int) get_parameter('id_agent'); $text_module = get_parameter('text_module', ''); @@ -188,6 +191,7 @@ if ($update || $create) { 'severity' => $severity, 'status' => $status, 'search' => $search, + 'not_search' => $not_search, 'text_agent' => $text_agent, 'id_agent_module' => $id_agent_module, 'id_agent' => $id_agent, @@ -380,6 +384,15 @@ $table->data[6][1] = html_print_input_text( 255, true ); +$table->data[6][1] .= ' '.html_print_checkbox_switch( + 'not_search', + $not_search, + $not_search, + true, + false, + 'checked_slide_events(this);', + true +); $table->data[7][0] = ''.__('Agent search').''; $params = []; @@ -747,6 +760,14 @@ $(document).ready( function() { }); +function checked_slide_events(element) { + var value = $("#checkbox-"+element.name).val(); + if (value == 0) { + $("#checkbox-"+element.name).val(1); + } else { + $("#checkbox-"+element.name).val(0); + } +} function click_button_remove_tag(what_button) { if (what_button == "with") { diff --git a/pandora_console/include/ajax/events.php b/pandora_console/include/ajax/events.php index 9de1b29988..9ad3eda6fc 100644 --- a/pandora_console/include/ajax/events.php +++ b/pandora_console/include/ajax/events.php @@ -351,6 +351,7 @@ if ($save_event_filter) { $values['severity'] = implode(',', get_parameter('severity', -1)); $values['status'] = get_parameter('status'); $values['search'] = get_parameter('search'); + $values['not_search'] = get_parameter('not_search'); $values['text_agent'] = get_parameter('text_agent'); $values['id_agent'] = get_parameter('id_agent'); $values['id_agent_module'] = get_parameter('id_agent_module'); @@ -410,6 +411,7 @@ if ($update_event_filter) { $values['severity'] = implode(',', get_parameter('severity', -1)); $values['status'] = get_parameter('status'); $values['search'] = get_parameter('search'); + $values['not_search'] = get_parameter('not_search'); $values['text_agent'] = get_parameter('text_agent'); $values['id_agent'] = get_parameter('id_agent'); $values['id_agent_module'] = get_parameter('id_agent_module'); @@ -645,6 +647,8 @@ function load_form_filter() { $("#status").val(val); if (i == 'search') $('#text-search').val(val); + if (i == 'not_search') + $('#checkbox-not_search').val(val); if (i == 'text_agent') $('input[name=text_agent]').val(val); if (i == 'id_agent') @@ -903,6 +907,7 @@ function save_new_filter() { "severity" : $("#severity").val(), "status" : $("#status").val(), "search" : $("#text-search").val(), + "not_search" : $("#checkbox-not_search").val(), "text_agent" : $("#text_id_agent").val(), "id_agent" : $('input:hidden[name=id_agent]').val(), "id_agent_module" : $('input:hidden[name=module_search_hidden]').val(), @@ -981,6 +986,7 @@ function save_update_filter() { "severity" : $("#severity").val(), "status" : $("#status").val(), "search" : $("#text-search").val(), + "not_search" : $("#checkbox-not_search").val(), "text_agent" : $("#text_id_agent").val(), "id_agent" : $('input:hidden[name=id_agent]').val(), "id_agent_module" : $('input:hidden[name=module_search_hidden]').val(), @@ -2424,6 +2430,7 @@ if ($get_events_fired) { 'severity' => -1, 'status' => -1, 'search' => '', + 'not_search' => 0, 'text_agent' => '', 'id_agent' => 0, 'id_agent_module' => 0, diff --git a/pandora_console/include/functions_events.php b/pandora_console/include/functions_events.php index 795488529d..ab54ca0389 100644 --- a/pandora_console/include/functions_events.php +++ b/pandora_console/include/functions_events.php @@ -640,6 +640,7 @@ function events_update_status($id_evento, $status, $filter=null) * 'status' * 'agent_alias' * 'search' + * 'not_search' * 'id_extra' * 'id_source_event' * 'user_comment' @@ -1059,16 +1060,40 @@ function events_get_all( $custom_data_search = 'te.custom_data'; } - $sql_filters[] = vsprintf( - ' AND (lower(ta.alias) like lower("%%%s%%") - OR te.id_evento like "%%%s%%" - OR lower(te.evento) like lower("%%%s%%") - OR lower(te.user_comment) like lower("%%%s%%") - OR lower(te.id_extra) like lower("%%%s%%") - OR lower(te.source) like lower("%%%s%%") - OR lower('.$custom_data_search.') like lower("%%%s%%") )', - array_fill(0, 7, $filter['search']) - ); + $not_search = ''; + $nexo = 'OR'; + $array_search = [ + 'te.id_evento', + 'lower(te.evento)', + 'lower(te.user_comment)', + 'lower(te.id_extra)', + 'lower(te.source)', + 'lower('.$custom_data_search.')', + ]; + if (isset($filter['not_search']) === true + && empty($filter['not_search']) === false + ) { + $not_search = 'NOT'; + $nexo = 'AND'; + } else { + $array_search[] = 'lower(ta.alias)'; + } + + $sql_search = ' AND ('; + foreach ($array_search as $key => $field) { + $sql_search .= sprintf( + '%s %s %s like lower("%%%s%%")', + ($key === 0) ? '' : $nexo, + $field, + $not_search, + $filter['search'] + ); + $sql_search .= ' '; + } + + $sql_search .= ' )'; + + $sql_filters[] = $sql_search; } // Free search exclude. diff --git a/pandora_console/include/styles/events.css b/pandora_console/include/styles/events.css index 32317e3e4c..2f43d50beb 100644 --- a/pandora_console/include/styles/events.css +++ b/pandora_console/include/styles/events.css @@ -140,6 +140,11 @@ form.flex-row div.filter_input.filter_input_switch .p-slider { width: 30px; } +form .filter_input_not_search .p-switch { + flex: 0 1 30px; + margin: 0; +} + fieldset { margin: 0 auto; } diff --git a/pandora_console/operation/events/events.php b/pandora_console/operation/events/events.php index a74ffd9eae..566fcb26d8 100644 --- a/pandora_console/operation/events/events.php +++ b/pandora_console/operation/events/events.php @@ -122,6 +122,10 @@ $search = get_parameter( 'filter[search]', ($filter['search'] ?? '') ); +$not_search = get_parameter( + 'filter[not_search]', + 0 +); $text_agent = get_parameter( 'filter[text_agent]', ($filter['text_agent'] ?? '') @@ -1080,6 +1084,7 @@ if ($loaded_filter !== false && $from_event_graph != 1 && isset($fb64) === false $severity = $filter['severity']; $status = $filter['status']; $search = $filter['search']; + $not_search = $filter['not_search']; $text_agent = $filter['text_agent']; $id_agent = $filter['id_agent']; $id_agent_module = $filter['id_agent_module']; @@ -1692,7 +1697,17 @@ $inputs[] = $in; // Free search. $data = html_print_input_text('search', $search, '', '', 255, true); -$in = '
'; +// Search recursive groups. +$data .= html_print_checkbox_switch( + 'not_search', + $not_search, + $not_search, + true, + false, + 'checked_slide_events(this);', + true +); +$in = ''; $inputs[] = $in; @@ -1732,7 +1747,7 @@ $data = html_print_checkbox_switch( $search_recursive_groups, true, false, - 'search_in_secondary_groups(this);', + 'checked_slide_events(this);', true ); @@ -1754,7 +1769,7 @@ $data = html_print_checkbox_switch( $search_secondary_groups, true, false, - 'search_in_secondary_groups(this);', + 'checked_slide_events(this);', true ); @@ -3066,7 +3081,7 @@ $(document).ready( function() { }); -function search_in_secondary_groups(element) { +function checked_slide_events(element) { var value = $("#checkbox-"+element.name).val(); if (value == 0) { $("#checkbox-"+element.name).val(1); diff --git a/pandora_console/pandoradb.sql b/pandora_console/pandoradb.sql index cd4e192407..517fb5cb03 100644 --- a/pandora_console/pandoradb.sql +++ b/pandora_console/pandoradb.sql @@ -1238,6 +1238,7 @@ CREATE TABLE IF NOT EXISTS `tevent_filter` ( `severity` TEXT, `status` INT NOT NULL DEFAULT -1, `search` TEXT, + `not_search` INT NOT NULL DEFAULT 0, `text_agent` TEXT, `id_agent` INT DEFAULT 0, `id_agent_module` INT DEFAULT 0, From 182181310266edf0ef98fdbdf88c444e5d71ad6c Mon Sep 17 00:00:00 2001 From: Kevin Date: Fri, 18 Nov 2022 14:53:50 +0100 Subject: [PATCH 031/181] added dependency checks, improved format --- pandora_agents/unix/plugins/autodiscover | 111 ++++++++++++----------- 1 file changed, 56 insertions(+), 55 deletions(-) diff --git a/pandora_agents/unix/plugins/autodiscover b/pandora_agents/unix/plugins/autodiscover index aff73a0244..03b2c3d76d 100644 --- a/pandora_agents/unix/plugins/autodiscover +++ b/pandora_agents/unix/plugins/autodiscover @@ -12,32 +12,34 @@ # ################################################### -from sys import argv -from sys import path -from sys import stderr -from sys import exit -from subprocess import Popen -from subprocess import PIPE -from subprocess import DEVNULL -from subprocess import getstatusoutput -import psutil +try: + from sys import argv + from sys import stderr + from sys import exit + from subprocess import Popen + from subprocess import PIPE + from subprocess import DEVNULL + from subprocess import getstatusoutput + import psutil +except ModuleNotFoundError as err: + print("{} error: {}. Exiting...".format(argv[0], err), file=stderr) + exit(1) -global module_list module_list = [] -version = "1.1" +VERSION = "1.2" ######################################################################################### # Powershell class ######################################################################################### class PSCheck: - @staticmethod + @staticmethod def check_service(servicename, option=False, memcpu=False): """Check services with powershell by parsing their DisplayName. Returns a dict\ - list with the name of the service and a boolean with its status.\n + list with the name of the service and a boolean with its status.\n Requires service name (case insensitive).""" pscall = Popen(["powershell", "Get-Service", "-Name", "'*"+ str(servicename) + "*'", - "|", "Select-Object", "-ExpandProperty", "Name"], + "|", "Select-Object", "-ExpandProperty", "Name"], stdout=PIPE, stdin=DEVNULL, stderr=DEVNULL, universal_newlines=True) result = pscall.communicate() result = str(result[0]).strip().split("\n") @@ -50,15 +52,15 @@ class PSCheck: procname = PSCheck.get_serviceprocess(element) # Get process status parstatus = PSCheck.getstatus(element) - if memcpu == True and parstatus == 1: + if memcpu and parstatus == 1: usage = get_memcpu(str(procname), str(element)) output += usage # Generate module with name and status parent = service_module(str(element), parstatus) output += parent - if option == True: + if option: children = PSCheck.getchildren(element, memcpu) - if type(children) == list and len(children) > 1: + if isinstance(children, list) and len(children) > 1: for child in children: output += child else: @@ -66,7 +68,6 @@ class PSCheck: else: next - #if output != '': if output and element and procname: return ({"name" : element, "process" : procname, "modules": output}) else: @@ -84,22 +85,22 @@ class PSCheck: status = PSCheck.getstatus(child) kids += service_module(str(child), status, "Service " + str(servicename) + " - Status") if status: - if memcpu == True: + if memcpu: kidsusage = get_memcpu(str(child)) for usage in kidsusage: kids += usage else: next - return (kids) + return kids @staticmethod def getstatus(servicename): """Gets the status of a given Windows service""" running = Popen(["powershell", "Get-Service", "-Name '" + str(servicename) + - "' |", "Select-Object", "-ExpandProperty", "Status"], - stdout=PIPE, stdin=DEVNULL, stderr=DEVNULL, universal_newlines=True) + "' |", "Select-Object", "-ExpandProperty", "Status"], + stdout=PIPE, stdin=DEVNULL, stderr=DEVNULL, universal_newlines=True) status = running.communicate()[0].strip() - return (int(status == "Running")) + return int(status == "Running") @staticmethod def get_serviceprocess(servicename): @@ -108,7 +109,7 @@ class PSCheck: srv_pid = service.pid() process = psutil.Process(srv_pid) proc_name = process.name() - return (proc_name) + return proc_name ######################################################################################### @@ -124,13 +125,13 @@ def service_module(name, value, parent=None): "module_parent" : parent, }] #print ("service_module END "+str(now(0,1))) - return (module) + return module -def get_memcpu (process, servicename): +def get_memcpu (process, servicename=None): """Creates a module for Memory and CPU for a given process. Returns a list of dictionaries.""" modules = [] if process: - if servicename != None: + if servicename is not None: parentname = servicename else: parentname = process @@ -147,7 +148,7 @@ def get_memcpu (process, servicename): "unit" : "%", "module_parent" : "Service "+ parentname + " - Status", }] - return (modules) + return modules def proc_percentbyname(procname): ############# 03/03/2020 """Gets Memory and CPU usage for a given process. Returns a list.""" @@ -165,7 +166,7 @@ def proc_percentbyname(procname): ############# 03/03/2020 except psutil.NoSuchProcess: next #print ("proc_percentbyname END "+str(now(0,1))) - return ([sum(memory),sum(cpu)]) + return [sum(memory),sum(cpu)] def win_service(servicelist, option=False, memcpu=False): """Creates modules for Windows servers.""" @@ -173,7 +174,7 @@ def win_service(servicelist, option=False, memcpu=False): for srvc in servicelist: if srvc and len(srvc) > 2: output = PSCheck.check_service(srvc, option, memcpu) - if output != None and output["modules"]: + if output is not None and output["modules"]: modules += PSCheck.check_service(srvc.strip(), option, memcpu)["modules"] module_list.append(srvc) #winprocess = output["name"] @@ -197,9 +198,9 @@ def lnx_service(services_list, memcpu=False): if sysctl == 0: ### Systemd available syscall = Popen(["systemctl", "show", "-pLoadState", "-pActiveState", srvc], stdout=PIPE, - stdin=DEVNULL, universal_newlines=True) + stdin=DEVNULL, universal_newlines=True) result = syscall.communicate() - srvstatus= result[0].strip().lower().split("\n") + srvstatus = result[0].strip().lower().split("\n") if srvstatus[0] == "loadstate=not-found": next else: @@ -212,7 +213,7 @@ def lnx_service(services_list, memcpu=False): elif sysctl != 0 and servic == 0: ### Systemd not available, switch to service command syscall = Popen(["service", srvc, "status"], stdout=PIPE, - stdin=DEVNULL, stderr=DEVNULL, universal_newlines=True) + stdin=DEVNULL, stderr=DEVNULL, universal_newlines=True) result = syscall.communicate()[0].lower() if "is running" in result: modules += service_module(srvc, 1) @@ -223,15 +224,15 @@ def lnx_service(services_list, memcpu=False): else: next else: - print ("No systemd or service commands available. Exiting...", file=stderr) + print("No systemd or service commands available. Exiting...", file=stderr) exit() if status: module_list.append(srvc) - if memcpu == True: + if memcpu: modules += get_memcpu(srvc, None) for m in modules: - print_module (m, 1) + print_module(m, 1) ######################################################################################### @@ -339,7 +340,7 @@ def print_module(module, str_flag=False): #### Print flag if str_flag is not False: - print (module_xml) + print(module_xml) return (module_xml) @@ -362,7 +363,7 @@ def main(): "postfix", "mysqld", "postgres", "oracle", "mongod"] discover(OS, service_list) else: - print ("OS not recognized. Exiting...", file=stderr) + print("OS not recognized. Exiting...", file=stderr) exit() def discover(osyst, servicelist): @@ -383,24 +384,24 @@ def discover(osyst, servicelist): elif osyst == "Linux": lnx_service(servicelist, memcpu) else: - print ("\nPandora FMS Autodiscovery plugin v{}".format(version)) - print ("Checks the status of the services in list and monitors CPU and Memory for each of them.\n") - print ("Usage:") - print ("{} [options] [--usage]".format(argv[0])) - print ("--help") - print ("\tPrints this help screen") - print ("--default") - print ("\tRuns this tool with default monitoring.") - print ("\tServices monitored by default for {}:".format(osyst)) - print ("\t",", ".join(servicelist)) - print ("--list \"\"") - print ("\tReplaces default services for a given list (comma-separated)") + print("\nPandora FMS Autodiscovery plugin v{}".format(VERSION)) + print("Checks the status of the services in list and monitors CPU and Memory for each of them.\n") + print("Usage:") + print("{} [options] [--usage]".format(argv[0])) + print("--help") + print("\tPrints this help screen") + print("--default") + print("\tRuns this tool with default monitoring.") + print("\tServices monitored by default for {}:".format(osyst)) + print("\t", ", ".join(servicelist)) + print("--list \"\"") + print("\tReplaces default services for a given list (comma-separated)") if osyst == "Windows": - print ("\tEach element of the list will be treated as a regexp, but they must be over 2 characters.") - print ("\tElements under 2 characters will be discarded.") - print ("--usage") - print ("\tAdds modules for CPU and Memory usage per service/process (optional, can take some time).\n") + print("\tEach element of the list will be treated as a regexp, but they must be over 2 characters.") + print("\tElements under 2 characters will be discarded.") + print("--usage") + print("\tAdds modules for CPU and Memory usage per service/process (optional, can take some time).\n") ##### RUN #### -main() \ No newline at end of file +main() From 14745a962568b00985bd4487b93daad8c7aca158 Mon Sep 17 00:00:00 2001 From: Luis Date: Mon, 21 Nov 2022 09:23:31 +0100 Subject: [PATCH 032/181] WIP:Prepare download control --- pandora_console/include/functions.php | 30 +++++++++ .../include/javascript/pandora_ui.js | 65 +++++++++++++++++++ pandora_console/include/php_to_js_values.php | 4 ++ 3 files changed, 99 insertions(+) diff --git a/pandora_console/include/functions.php b/pandora_console/include/functions.php index ed999553cb..4facfad081 100644 --- a/pandora_console/include/functions.php +++ b/pandora_console/include/functions.php @@ -6269,3 +6269,33 @@ function arrayOutputSorting($sort, $sortField) } }; } + + +function setCookieToken($cookieName, $cookieValue, $httpOnly=true, $secure=false) +{ + // See: http://stackoverflow.com/a/1459794/59087 + // See: http://shiflett.org/blog/2006/mar/server-name-versus-http-host + // See: http://stackoverflow.com/a/3290474/59087 + setcookie( + $cookieName, + $cookieValue, + 2147483647, + // expires January 1, 2038 + '/', + // your path + $_SERVER['HTTP_HOST'], + // your domain + $secure, + // Use true over HTTPS + $httpOnly + // Set true for $AUTH_COOKIE_NAME + ); +} + + +function setDownloadCookieToken() +{ + $token = 'downloadToken'; + + setCookieToken($token, $_GET[$token], false, false); +} diff --git a/pandora_console/include/javascript/pandora_ui.js b/pandora_console/include/javascript/pandora_ui.js index ecb23827d9..30e7ee32ee 100644 --- a/pandora_console/include/javascript/pandora_ui.js +++ b/pandora_console/include/javascript/pandora_ui.js @@ -763,3 +763,68 @@ function getGroupIcon(id_group, img_container) { } }); } + +/* Prepare download control */ +function getCookie(name) { + var parts = document.cookie.split(name + "="); + if (parts.length == 2) + return parts + .pop() + .split(";") + .shift(); +} + +function expireCookie(cName) { + document.cookie = + encodeURIComponent(cName) + + "=deleted; expires=" + + new Date(0).toUTCString(); +} + +function setCursor(buttonStyle, button) { + button.css("cursor", buttonStyle); +} + +function setFormToken(button) { + var downloadToken = new Date().getTime(); + button.append(" 'forced_title_layer', 'class' => 'forced_title_layer', ' set_js_value('absolute_homeurl', ui_get_full_url(false, false, false, false)); set_js_value('homeurl', $config['homeurl']); set_js_value('homedir', $config['homedir'].'/'); +// Prevent double request message. +set_js_value('prepareDownloadTitle', __('Generating content')); +set_js_value('prepareDownloadMsg', __('Generating content, please wait')); + // ====================================================================== From c56787c459214be739f4f5317c3b5714e8712506 Mon Sep 17 00:00:00 2001 From: "alejandro.campos@artica.es" Date: Mon, 21 Nov 2022 09:55:35 +0100 Subject: [PATCH 033/181] visual fix --- pandora_console/godmode/agentes/configure_field.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pandora_console/godmode/agentes/configure_field.php b/pandora_console/godmode/agentes/configure_field.php index 281c4a7447..9303a645cf 100755 --- a/pandora_console/godmode/agentes/configure_field.php +++ b/pandora_console/godmode/agentes/configure_field.php @@ -219,9 +219,6 @@ $(document).ready (function () { $('#configure_field-3').show(); } - // if ( $('input[type=checkbox][name=is_link_enabled]').val() === 1) { - - //} $('input[type=checkbox][name=is_link_enabled]').change(function () { if( $(this).is(":checked") ){ $('#configure_field-6').show(); @@ -241,19 +238,23 @@ $(document).ready (function () { $('#configure_field-4').show(); dialog_message("#message_no_set_password"); $('#configure_field-1').hide(); + $('#configure_field-5').hide(); } else{ $('#configure_field-4').hide(); $('#configure_field-1').show(); + $('#configure_field-5').show(); } }); $('input[type=checkbox][name=is_password_type]').change(function () { if( $(this).is(":checked")){ dialog_message("#message_no_set_combo"); $('#configure_field-3').hide(); + $('#configure_field-5').hide(); } else{ $('#configure_field-3').show(); + $('#configure_field-5').show(); } }); }); From 5910002e9d32855c5ab601ac47354565f2a1e13e Mon Sep 17 00:00:00 2001 From: sergio Date: Mon, 21 Nov 2022 18:01:53 +0100 Subject: [PATCH 034/181] #9833 Fixed general user search in open --- pandora_console/operation/search_results.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pandora_console/operation/search_results.php b/pandora_console/operation/search_results.php index 9951ec528e..650bda0c36 100644 --- a/pandora_console/operation/search_results.php +++ b/pandora_console/operation/search_results.php @@ -18,7 +18,8 @@ require_once $config['homedir'].'/include/functions_reporting.php'; enterprise_include('operation/reporting/custom_reporting.php'); $searchAgents = $searchAlerts = $searchModules = check_acl($config['id_user'], 0, 'AR'); -$searchUsers = $searchPolicies = (check_acl($config['id_user'], 0, 'AR') && enterprise_installed()); +$searchUsers = (check_acl($config['id_user'], 0, 'AR')); +$searchPolicies = (check_acl($config['id_user'], 0, 'AR') && enterprise_installed()); $searchReports = $searchGraphs = check_acl($config['id_user'], 0, 'RR'); $searchMaps = check_acl($config['id_user'], 0, 'VR'); $searchMain = true; From 195e3cdd3f7e840dd5e3ea6d1b0a15ed44a6305a Mon Sep 17 00:00:00 2001 From: Shinichi Matsumoto Date: Tue, 22 Nov 2022 03:59:01 +0000 Subject: [PATCH 035/181] collection is not updated if the md5 file size of collection is 0 If the md5 file in collection has size 0, delete it. Set $local_collection_md5 to "Size 0", which is impossible for md5, and let $remote_collection_md5 be adopted. --- pandora_agents/unix/pandora_agent | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pandora_agents/unix/pandora_agent b/pandora_agents/unix/pandora_agent index 1c91f31f38..a4d71094e8 100755 --- a/pandora_agents/unix/pandora_agent +++ b/pandora_agents/unix/pandora_agent @@ -2403,6 +2403,11 @@ sub check_collections () { if (open (MD5_FILE, "< $ConfDir/collections/$collection_md5_file")) { $local_collection_md5 = ; close MD5_FILE; + if ( ! defined ($local_collection_md5) ) { + log_message ('Collection', "Size of $ConfDir/collections/$collection_md5_file is 0"); + unlink ("$ConfDir/collections/$collection_md5_file"); + $local_collection_md5 = "Size 0"; + } } else { log_message ('Collection', "Could not open dir $ConfDir/collections/$collection_md5_file"); next; From 767624b0c38ef02357778d0df353a6d655559dc9 Mon Sep 17 00:00:00 2001 From: "alejandro.campos@artica.es" Date: Tue, 22 Nov 2022 11:50:07 +0100 Subject: [PATCH 036/181] implemented link type custom field --- pandora_console/extras/mr/60.sql | 2 -- .../godmode/agentes/agent_manager.php | 29 +++++++++++++--- .../godmode/agentes/configurar_agente.php | 27 +++++++++++++-- .../godmode/agentes/configure_field.php | 34 ------------------- .../godmode/agentes/fields_manager.php | 19 +---------- .../agentes/estado_generalagente.php | 13 +++++++ pandora_console/pandoradb.sql | 2 -- pandora_console/pandoradb_data.sql | 2 +- 8 files changed, 65 insertions(+), 63 deletions(-) diff --git a/pandora_console/extras/mr/60.sql b/pandora_console/extras/mr/60.sql index 40a0a86c4f..bf1ff4131a 100644 --- a/pandora_console/extras/mr/60.sql +++ b/pandora_console/extras/mr/60.sql @@ -1,7 +1,5 @@ START TRANSACTION; ALTER TABLE `tagent_custom_fields` ADD `is_link_enabled` TINYINT(1) NOT NULL DEFAULT 0; -ALTER TABLE `tagent_custom_fields` ADD COLUMN `link_text` VARCHAR(500) NOT NULL DEFAULT ''; -ALTER TABLE `tagent_custom_fields` ADD COLUMN `link_url` VARCHAR(2048) NOT NULL DEFAULT ''; COMMIT; diff --git a/pandora_console/godmode/agentes/agent_manager.php b/pandora_console/godmode/agentes/agent_manager.php index e5e37e63ea..b35dab9574 100644 --- a/pandora_console/godmode/agentes/agent_manager.php +++ b/pandora_console/godmode/agentes/agent_manager.php @@ -873,13 +873,34 @@ foreach ($fields as $field) { true ); } else if ($field['is_link_enabled']) { - $link_text = $field['link_text']; + list($link_text, $link_url) = json_decode($custom_value, true); - if ($field['link_text'] === '') { - $link_text = $field['link_url']; + if (json_last_error() !== JSON_ERROR_NONE) { + $link_text = ''; + $link_url = ''; } - $data_field[1] = ''.$link_text.''; + $data_field[1] = ''.__('Link text:').''; + $data_field[1] .= '
'; + $data_field[1] .= html_print_textarea( + 'customvalue_'.$field['id_field'].'[]', + 2, + 65, + $link_text, + 'class="min-height-30px', + true + ); + $data_field[1] .= '
'; + $data_field[1] .= ''.__('Link URL:').''; + $data_field[1] .= '
'; + $data_field[1] .= html_print_textarea( + 'customvalue_'.$field['id_field'].'[]', + 2, + 65, + $link_url, + 'class="min-height-30px', + true + ); } else { $data_field[1] = html_print_textarea( 'customvalue_'.$field['id_field'], diff --git a/pandora_console/godmode/agentes/configurar_agente.php b/pandora_console/godmode/agentes/configurar_agente.php index f873795ae6..2fd9fa8948 100644 --- a/pandora_console/godmode/agentes/configurar_agente.php +++ b/pandora_console/godmode/agentes/configurar_agente.php @@ -238,7 +238,15 @@ if ($create_agent) { $field_values = []; foreach ($fields as $field) { - $field_values[$field['id_field']] = (string) get_parameter_post('customvalue_'.$field['id_field'], ''); + $field_value = get_parameter_post('customvalue_'.$field['id_field'], ''); + + if ($field['is_link_enabled']) { + $field_value = json_encode($field_value); + } else { + $field_value = (string) $field_value; + } + + $field_values[$field['id_field']] = $field_value; } // Check if agent exists (BUG WC-50518-2). @@ -999,7 +1007,22 @@ if ($update_agent) { $field_values = []; foreach ($fields as $field) { - $field_values[$field['id_field']] = (string) get_parameter_post('customvalue_'.$field['id_field'], ''); + $field_value = get_parameter_post('customvalue_'.$field['id_field'], ''); + + if ($field['is_link_enabled']) { + if ($field_value[1] !== '') { + $parsed_url = parse_url($field_value[1]); + if (empty($parsed_url['scheme']) === true) { + $field_value[1] = 'http://'.ltrim($field_value[1], '/'); + } + } + + $field_value = json_encode($field_value); + } else { + $field_value = (string) $field_value; + } + + $field_values[$field['id_field']] = $field_value; } foreach ($field_values as $key => $value) { diff --git a/pandora_console/godmode/agentes/configure_field.php b/pandora_console/godmode/agentes/configure_field.php index 9303a645cf..f7c80c832c 100755 --- a/pandora_console/godmode/agentes/configure_field.php +++ b/pandora_console/godmode/agentes/configure_field.php @@ -31,8 +31,6 @@ $is_password_type = (bool) get_parameter('is_password_type', 0); $is_combo_enable = (bool) get_parameter('is_combo_enable', 0); $combo_values = (string) get_parameter('combo_values', ''); $is_link_enabled = (bool) get_parameter('is_link_enabled', 0); -$link_text = (string) get_parameter('link_text', ''); -$link_url = (string) get_parameter('link_url', ''); // Header. if ($id_field) { @@ -43,8 +41,6 @@ if ($id_field) { $combo_values = $field['combo_values'] ? $field['combo_values'] : ''; $is_combo_enable = $config['is_combo_enable']; $is_link_enabled = $field['is_link_enabled']; - $link_text = $field['link_text']; - $link_url = $field['link_url']; ui_print_page_header(__('Update agent custom field'), 'images/custom_field.png', false, '', true, ''); } else { ui_print_page_header(__('Create agent custom field'), 'images/custom_field.png', false, '', true, ''); @@ -146,28 +142,6 @@ $table->data[5][1] = html_print_checkbox_switch_extended( true ); -$table->rowstyle[6] = 'display: none;'; -$table->data[6][0] = __('Link text'); -$table->data[6][1] = html_print_textarea( - 'link_text', - 3, - 65, - io_safe_output($link_text), - '', - true -); - -$table->rowstyle[7] = 'display: none;'; -$table->data[7][0] = __('Link URL'); -$table->data[7][1] = html_print_textarea( - 'link_url', - 3, - 65, - io_safe_output($link_url), - '', - true -); - echo ''; html_print_table($table); echo '
'; @@ -208,26 +182,18 @@ $(document).ready (function () { } if ($('input[type=checkbox][name=is_link_enabled]').is(":checked") === true) { - $('#configure_field-6').show(); - $('#configure_field-7').show(); $('#configure_field-1').hide(); $('#configure_field-3').hide(); } else { - $('#configure_field-6').hide(); - $('#configure_field-7').hide(); $('#configure_field-1').show(); $('#configure_field-3').show(); } $('input[type=checkbox][name=is_link_enabled]').change(function () { if( $(this).is(":checked") ){ - $('#configure_field-6').show(); - $('#configure_field-7').show(); $('#configure_field-1').hide(); $('#configure_field-3').hide(); } else{ - $('#configure_field-6').hide(); - $('#configure_field-7').hide(); $('#configure_field-1').show(); $('#configure_field-3').show(); } diff --git a/pandora_console/godmode/agentes/fields_manager.php b/pandora_console/godmode/agentes/fields_manager.php index 3f0212388d..608b6b1f65 100644 --- a/pandora_console/godmode/agentes/fields_manager.php +++ b/pandora_console/godmode/agentes/fields_manager.php @@ -39,15 +39,6 @@ $is_password_type = (int) get_parameter('is_password_type', 0); $combo_values = (string) get_parameter('combo_values', ''); $combo_value_selected = (string) get_parameter('combo_value_selected', ''); $is_link_enabled = (bool) get_parameter('is_link_enabled', 0); -$link_text = (string) get_parameter('link_text', ''); -$link_url = (string) get_parameter('link_url', ''); - -if ($is_link_enabled === true && $link_url !== '') { - $parsed_url = parse_url($link_url); - if (empty($parsed_url['scheme']) === true) { - $link_url = 'http://'.ltrim($link_url, '/'); - } -} // Create field. if ($create_field) { @@ -56,8 +47,6 @@ if ($create_field) { ui_print_error_message(__('The name must not be empty')); } else if ($name == db_get_value('name', 'tagent_custom_fields', 'name', $name)) { ui_print_error_message(__('The name must be unique')); - } else if ($is_link_enabled === true && $link_url === '') { - ui_print_error_message(__('The link URL must not be empty')); } else { $result = db_process_sql_insert( 'tagent_custom_fields', @@ -67,8 +56,6 @@ if ($create_field) { 'is_password_type' => $is_password_type, 'combo_values' => $combo_values, 'is_link_enabled' => $is_link_enabled, - 'link_text' => $link_text, - 'link_url' => $link_url, ] ); ui_print_success_message(__('Field successfully created')); @@ -78,17 +65,13 @@ if ($create_field) { // Update field. if ($update_field) { // Check if name field is empty. - if ($name !== '' - && ($is_link_enabled === false || ($is_link_enabled === true && $link_url !== '')) - ) { + if ($name !== '') { $values = [ 'name' => $name, 'display_on_front' => $display_on_front, 'is_password_type' => $is_password_type, 'combo_values' => $combo_values, 'is_link_enabled' => $is_link_enabled, - 'link_text' => $link_text, - 'link_url' => $link_url, ]; $result = db_process_sql_update('tagent_custom_fields', $values, ['id_field' => $id_field]); diff --git a/pandora_console/operation/agentes/estado_generalagente.php b/pandora_console/operation/agentes/estado_generalagente.php index 91714803f9..742e55adf5 100755 --- a/pandora_console/operation/agentes/estado_generalagente.php +++ b/pandora_console/operation/agentes/estado_generalagente.php @@ -546,6 +546,19 @@ foreach ($fields as $field) { if ($custom_value[0]['is_password_type']) { $data[1] = '••••••••'; + } else if ($field['is_link_enabled'] === '1') { + list($link_text, $link_url) = json_decode($custom_value[0]['description'], true); + + if (json_last_error() !== JSON_ERROR_NONE) { + $link_text = ''; + $link_url = ''; + } + + if ($link_text === '') { + $link_text = $link_url; + } + + $data[1] = ''.$link_text.''; } else { $data[1] = $custom_value[0]['description']; } diff --git a/pandora_console/pandoradb.sql b/pandora_console/pandoradb.sql index df51e426ff..87a1428702 100644 --- a/pandora_console/pandoradb.sql +++ b/pandora_console/pandoradb.sql @@ -2104,8 +2104,6 @@ CREATE TABLE IF NOT EXISTS `tagent_custom_fields` ( `is_password_type` TINYINT NOT NULL DEFAULT 0, `combo_values` TEXT , `is_link_enabled` TINYINT(1) NOT NULL DEFAULT 0, - `link_text` VARCHAR(500) NOT NULL DEFAULT '', - `link_url` VARCHAR(2048) NOT NULL DEFAULT '', PRIMARY KEY (`id_field`) ) ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4; diff --git a/pandora_console/pandoradb_data.sql b/pandora_console/pandoradb_data.sql index fca70188ef..611f11453c 100644 --- a/pandora_console/pandoradb_data.sql +++ b/pandora_console/pandoradb_data.sql @@ -1189,7 +1189,7 @@ INSERT INTO `tplugin` (`id`, `name`, `description`, `max_timeout`, `execute`, `p INSERT INTO `tplugin` (`id`, `name`, `description`, `max_timeout`, `max_retries`, `execute`, `net_dst_opt`, `net_port_opt`, `user_opt`, `pass_opt`, `plugin_type`, `macros`, `parameters`, `no_delete`) VALUES (9,'Packet Loss','Checks for dropped packages after X seconds of testing. It returns % of dropped packets. It uses ping flood mode to launch 50 consecutive pings to a remote destination. On local, stable networks, value should be 0. ',30,0,'/usr/share/pandora_server/util/plugin/packet_loss.sh','','','','',0,'{\"1\":{\"macro\":\"_field1_\",\"desc\":\"Test time\",\"help\":\"\",\"value\":\"8\",\"hide\":\"\"},\"2\":{\"macro\":\"_field2_\",\"desc\":\"Target IP\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"}}','_field1_ _field2_', 1); -INSERT INTO `tagent_custom_fields` VALUES (1,'Serial Number',0,0,'',0,'',''),(2,'Department',0,0,'',0,'',''),(3,'Additional ID',0,0,'',0,'',''),(4,'eHorusID',0,0,'',0,'',''); +INSERT INTO `tagent_custom_fields` VALUES (1,'Serial Number',0,0,'',0),(2,'Department',0,0,'',0),(3,'Additional ID',0,0,'',0),(4,'eHorusID',0,0,'',0); INSERT INTO `ttag` VALUES (1,'network','Network equipment','http://artica.es','','',''),(2,'critical','Critical modules','','','',''),(3,'dmz','DMZ Network Zone','','','',''),(4,'performance','Performance anda capacity modules','','','',''),(5,'configuration','','','','',''); From fcd918d00b9015a5b4cd2eadb9887fe93875de39 Mon Sep 17 00:00:00 2001 From: Daniel Maya Date: Thu, 24 Nov 2022 15:49:11 +0100 Subject: [PATCH 037/181] #9851 Fixed background image size --- pandora_console/general/login_page.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandora_console/general/login_page.php b/pandora_console/general/login_page.php index 6d7a9864ce..bb9fa19185 100755 --- a/pandora_console/general/login_page.php +++ b/pandora_console/general/login_page.php @@ -91,7 +91,7 @@ $login_body_class = ''; // Overrides the default background with the defined by the user. if (!empty($config['login_background'])) { $background_url = 'images/backgrounds/'.$config['login_background']; - $login_body_style = "style=\"background:linear-gradient(74deg, rgba(2, 2, 2, 0.333) 36%, transparent 36%), url('".$background_url."');\""; + $login_body_style = "style=\"background-size: 100% 100% !important;background:linear-gradient(74deg, rgba(2, 2, 2, 0.333) 36%, transparent 36%), url('".$background_url."');\""; } // Support for Internet Explorer and Microsoft Edge browsers From d6af3c7121dd47a00cfa9212f088f434a1266fdb Mon Sep 17 00:00:00 2001 From: SHIMIZU Hiroki Date: Mon, 28 Nov 2022 11:40:45 +0900 Subject: [PATCH 038/181] On pandora_server/util/plugin/pandora_snmp_bandwidth.pl fixed typo (bandwith -> bandwidth) added new condition to determine if SNMP has a 64-bit counter fixed a bug that bandwidth utilization was not output when bandwidth utilization was 0% --- .../util/plugin/pandora_snmp_bandwidth.pl | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pandora_server/util/plugin/pandora_snmp_bandwidth.pl b/pandora_server/util/plugin/pandora_snmp_bandwidth.pl index 3eb2b4fb53..8b5d505116 100755 --- a/pandora_server/util/plugin/pandora_snmp_bandwidth.pl +++ b/pandora_server/util/plugin/pandora_snmp_bandwidth.pl @@ -2,7 +2,7 @@ # ################################################################################ # -# Bandwith usage plugin +# Bandwidth usage plugin # # Requirements: # snmpget @@ -55,7 +55,7 @@ Where OPTIONS could be: [EXTRA] -ifIndex Target interface to retrieve, if not specified, total - bandwith will be reported. + bandwidth will be reported. -uniqid Use custom temporary file name. -inUsage Show only input usage (in percentage) - 1, or not 0. -outUsage Show only output usage (in percentage) - 1, or not 0. @@ -492,9 +492,9 @@ $config->{'tmp_separator'} = ';' if empty($config->{'tmp_separator'}); $config->{'tmp'} = (($^O =~ /win/)?$ENV{'TMP'}:'/tmp') if empty($config->{'tmp'}); # Create unique name for tmp and log file for host -my $filename = $config->{'tmp'}.'/pandora_bandwith_'.$config->{'host'}; +my $filename = $config->{'tmp'}.'/pandora_bandwidth_'.$config->{'host'}; if (!empty($config->{'uniqid'})) { - $filename = $config->{'tmp'}.'/pandora_bandwith_'.$config->{'uniqid'}; + $filename = $config->{'tmp'}.'/pandora_bandwidth_'.$config->{'uniqid'}; } # Replace every dot for underscore $filename =~ tr/./_/; @@ -511,7 +511,7 @@ if ( defined($sysobjectid->{'error'}) || $sysobjectid->{'data'} eq '' ) { # Check SNMP x64 interfaces my $walk64 = snmp_walk({%{$config}, 'oid' => '.1.3.6.1.2.1.31.1.1.1.6'}); -if ( $walk64 =~ 'No Such Instance currently exists at this OID' || $walk64 =~ 'No more variables left in this MIB View') { +if ( $walk64 =~ 'No Such Instance currently exists at this OID' || $walk64 =~ 'No more variables left in this MIB View' || $walk64 =~ 'No Such Object available on this agent at this OID') { $config->{'use_x64'} = 0; } else { $config->{'use_x64'} = 1; @@ -556,15 +556,15 @@ my $j = 0; my $k = 0; foreach my $iface (keys %{$analysis_tree}) { # Calculate summary; - if (is_enabled($analysis_tree->{$iface}{'bandwidth'})) { + if (is_enabled($analysis_tree->{$iface}{'bandwidth'}) || $analysis_tree->{$iface}{'bandwidth'} == 0) { $bandwidth = $analysis_tree->{$iface}{'bandwidth'}; $i++; } - if (is_enabled($analysis_tree->{$iface}{'inUsage'})) { + if (is_enabled($analysis_tree->{$iface}{'inUsage'}) || $analysis_tree->{$iface}{'inUsage'} == 0) { $inUsage = $analysis_tree->{$iface}{'inUsage'}; $j++; } - if (is_enabled($analysis_tree->{$iface}{'outUsage'})) { + if (is_enabled($analysis_tree->{$iface}{'outUsage'}) || $analysis_tree->{$iface}{'inUsage'} == 0) { $outUsage = $analysis_tree->{$iface}{'outUsage'}; $k++; } From 695f457a09ff13cd1ab3f2405fe5aa1c80c127ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Gonz=C3=A1lez?= <79-jose.gonzalez@users.noreply.brutus.artica.es> Date: Mon, 28 Nov 2022 07:47:47 +0000 Subject: [PATCH 039/181] Fix issue with Database Lock. --- pandora_console/include/functions_db.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/pandora_console/include/functions_db.php b/pandora_console/include/functions_db.php index 83b972ca75..2ec5486766 100644 --- a/pandora_console/include/functions_db.php +++ b/pandora_console/include/functions_db.php @@ -2313,7 +2313,13 @@ function db_get_lock(string $lockname, int $expiration_time=86400) :?int } if ($lock_status === false) { - return null; + db_pandora_audit( + AUDIT_LOG_SYSTEM, + 'Issue in Database Lock', + 'system' + ); + + return (int) null; } return (int) $lock_status; From 57bd23f94c84f274e7888b94c3dba5722e3d4fb4 Mon Sep 17 00:00:00 2001 From: Daniel Maya Date: Tue, 29 Nov 2022 16:45:44 +0100 Subject: [PATCH 040/181] #9873 Fixed images --- .../include/rest-api/models/VisualConsole/Item.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pandora_console/include/rest-api/models/VisualConsole/Item.php b/pandora_console/include/rest-api/models/VisualConsole/Item.php index be075d5e75..c132be2885 100644 --- a/pandora_console/include/rest-api/models/VisualConsole/Item.php +++ b/pandora_console/include/rest-api/models/VisualConsole/Item.php @@ -2296,6 +2296,7 @@ class Item extends CachedModel false ); + $aux_images = $all_images; foreach ($all_images as $image_file) { $image_file = substr($image_file, 0, (strlen($image_file) - 4)); @@ -2311,7 +2312,11 @@ class Item extends CachedModel continue; } - $result[$image_file] = $image_file; + // Check the 4 images. + $array_images = preg_grep('/'.$image_file.'(_ok|_bad|_warning)*\./', $aux_images); + if (count($array_images) >= 4) { + $result[$image_file] = $image_file; + } } } From c45505954683a005b85c997a9ac6ca9fd49d9148 Mon Sep 17 00:00:00 2001 From: Enrique Martin Date: Thu, 1 Dec 2022 16:47:44 +0100 Subject: [PATCH 041/181] Added metaconsole_access_node value to new_user API function --- pandora_console/include/functions_api.php | 1 + 1 file changed, 1 insertion(+) diff --git a/pandora_console/include/functions_api.php b/pandora_console/include/functions_api.php index 8d2061d3c7..1e9b083f19 100644 --- a/pandora_console/include/functions_api.php +++ b/pandora_console/include/functions_api.php @@ -9528,6 +9528,7 @@ function api_set_new_user($id, $thrash2, $other, $thrash3) $values['default_event_filter'] = $other['data'][10]; $values['section'] = $other['data'][11]; $values['session_time'] = $other['data'][12]; + $values['metaconsole_access_node'] = $other['data'][13]; if (empty($password) === true) { returnError('Password cannot be empty.'); From 028176e58dcd7850792827539f414b525cd48d12 Mon Sep 17 00:00:00 2001 From: KANAYAMA Akihiro Date: Fri, 2 Dec 2022 16:20:21 +0900 Subject: [PATCH 042/181] Fixed const UNKNOWN_DUPLEX Changed the condition to switch x86 or x64 Added conditions in sub prepare_tree when snmp_get returns empty array Fixed "Calculate summary" to sum up each value Adjusted indents --- .../util/plugin/pandora_snmp_bandwidth.pl | 67 +++++++++---------- 1 file changed, 33 insertions(+), 34 deletions(-) diff --git a/pandora_server/util/plugin/pandora_snmp_bandwidth.pl b/pandora_server/util/plugin/pandora_snmp_bandwidth.pl index 8b5d505116..9b28848b48 100755 --- a/pandora_server/util/plugin/pandora_snmp_bandwidth.pl +++ b/pandora_server/util/plugin/pandora_snmp_bandwidth.pl @@ -66,7 +66,7 @@ e.g. -v is equal to -version, -c to -community, etc. EO_HELP use constant { - UNKNOWN_DUPLEX => 0, + UNKNOWN_DUPLEX => 1, HALF_DUPLEX => 2, FULL_DUPLEX => 3, }; @@ -133,9 +133,9 @@ sub update_config_key ($) { if ($arg eq 'inUsage') { return "inUsage"; } - if ($arg eq 'outUsage') { - return "outUsage"; - } + if ($arg eq 'outUsage') { + return "outUsage"; + } } ################################################################################ @@ -188,7 +188,7 @@ sub prepare_tree { my $inOctets = snmp_get(\%inOctets_call); if (ref($inOctets) eq "HASH") { - if ($inOctets->{'data'} eq '') { + if (! exists($inOctets->{'data'}) || $inOctets->{'data'} eq '') { $inOctets = 0; } else { $inOctets = int $inOctets->{'data'}; @@ -198,18 +198,18 @@ sub prepare_tree { next; } - my %outOctets_call = %{$config}; - if (is_enabled($config->{'use_x64'})) { - $outOctets_call{'oid'} = $config->{'oid_base'}; - $outOctets_call{'oid'} .= $config->{'x64_indexes'}{'outOctets'}.$ifIndex; - } else { - $outOctets_call{'oid'} = $config->{'oid_base'}; - $outOctets_call{'oid'} .= $config->{'x86_indexes'}{'outOctets'}.$ifIndex; - } + my %outOctets_call = %{$config}; + if (is_enabled($config->{'use_x64'})) { + $outOctets_call{'oid'} = $config->{'oid_base'}; + $outOctets_call{'oid'} .= $config->{'x64_indexes'}{'outOctets'}.$ifIndex; + } else { + $outOctets_call{'oid'} = $config->{'oid_base'}; + $outOctets_call{'oid'} .= $config->{'x86_indexes'}{'outOctets'}.$ifIndex; + } my $outOctets = snmp_get(\%outOctets_call); if (ref($outOctets) eq "HASH") { - if ($outOctets->{'data'} eq '') { + if (! exists($outOctets->{'data'}) || $outOctets->{'data'} eq '') { $outOctets = 0; } else { $outOctets = int $outOctets->{'data'}; @@ -220,28 +220,27 @@ sub prepare_tree { } my %duplex_call = %{$config}; - if (is_enabled($config->{'use_x64'})) { - $duplex_call{'oid'} = $config->{'oid_base'}; - $duplex_call{'oid'} .= $config->{'x64_indexes'}{'duplex'}.$ifIndex; - } else { - $duplex_call{'oid'} = $config->{'oid_base'}; - $duplex_call{'oid'} .= $config->{'x86_indexes'}{'duplex'}.$ifIndex; - } + if (is_enabled($config->{'use_x64'})) { + $duplex_call{'oid'} = $config->{'oid_base'}; + $duplex_call{'oid'} .= $config->{'x64_indexes'}{'duplex'}.$ifIndex; + } else { + $duplex_call{'oid'} = $config->{'oid_base'}; + $duplex_call{'oid'} .= $config->{'x86_indexes'}{'duplex'}.$ifIndex; + } my $duplex = snmp_get(\%duplex_call); if (ref($duplex) eq "HASH") { - if ($duplex->{'data'} eq '') { + if (! exists($duplex->{'data'}) || $duplex->{'data'} eq '') { $duplex = 0; } else { $duplex = int $duplex->{'data'}; } - } else { # Ignore, cannot retrieve inOctets. next; } - my %speed = %{$config}; + my %speed = %{$config}; if (is_enabled($config->{'use_x64'})) { $speed{'oid'} = $config->{'oid_base'}; $speed{'oid'} .= $config->{'x64_indexes'}{'ifSpeed'}.$ifIndex; @@ -511,7 +510,7 @@ if ( defined($sysobjectid->{'error'}) || $sysobjectid->{'data'} eq '' ) { # Check SNMP x64 interfaces my $walk64 = snmp_walk({%{$config}, 'oid' => '.1.3.6.1.2.1.31.1.1.1.6'}); -if ( $walk64 =~ 'No Such Instance currently exists at this OID' || $walk64 =~ 'No more variables left in this MIB View' || $walk64 =~ 'No Such Object available on this agent at this OID') { +if ( $walk64 !~ /.*\.[0-9]+ = Counter64: [0-9]+/ ) { $config->{'use_x64'} = 0; } else { $config->{'use_x64'} = 1; @@ -557,34 +556,34 @@ my $k = 0; foreach my $iface (keys %{$analysis_tree}) { # Calculate summary; if (is_enabled($analysis_tree->{$iface}{'bandwidth'}) || $analysis_tree->{$iface}{'bandwidth'} == 0) { - $bandwidth = $analysis_tree->{$iface}{'bandwidth'}; + $bandwidth += $analysis_tree->{$iface}{'bandwidth'}; $i++; } if (is_enabled($analysis_tree->{$iface}{'inUsage'}) || $analysis_tree->{$iface}{'inUsage'} == 0) { - $inUsage = $analysis_tree->{$iface}{'inUsage'}; + $inUsage += $analysis_tree->{$iface}{'inUsage'}; $j++; } if (is_enabled($analysis_tree->{$iface}{'outUsage'}) || $analysis_tree->{$iface}{'inUsage'} == 0) { - $outUsage = $analysis_tree->{$iface}{'outUsage'}; + $outUsage += $analysis_tree->{$iface}{'outUsage'}; $k++; } } if ($j > 0 && is_enabled($config->{'inUsage'})) { - $inUsage /= $j; - print sprintf("%.9f\n", $inUsage); + $inUsage /= $j; + print sprintf("%.9f\n", $inUsage); } elsif ($k > 0 && is_enabled($config->{'outUsage'})) { - $outUsage /= $k; - print sprintf("%.9f\n", $outUsage); + $outUsage /= $k; + print sprintf("%.9f\n", $outUsage); } if ($i > 0 && !is_enabled($config->{'inUsage'}) && !is_enabled($config->{'outUsage'}) ) { - $bandwidth /= $i; - print sprintf("%.9f\n", $bandwidth); + $bandwidth /= $i; + print sprintf("%.9f\n", $bandwidth); } logger($config, 'info', "Plugin ends") if (is_enabled($config->{'debug'})); From d525cb594c67c6450f6d8fa911bb01b905636e84 Mon Sep 17 00:00:00 2001 From: Calvo Date: Fri, 2 Dec 2022 09:42:24 +0100 Subject: [PATCH 043/181] WIP: Download wait message --- .../godmode/reporting/reporting_builder.php | 2 +- .../include/class/ModuleTemplates.class.php | 3 +- pandora_console/include/functions.php | 41 +++++++--------- .../include/functions_reporting_xml.php | 2 + pandora_console/include/functions_ui.php | 5 +- .../include/graphs/export_data.php | 3 ++ .../include/graphs/flot/pandora.flot.js | 1 + .../include/javascript/pandora_ui.js | 47 +++++++++++-------- pandora_console/operation/events/events.php | 2 +- .../operation/events/export_csv.php | 1 + pandora_console/vendor/mpdf/mpdf/src/Mpdf.php | 2 + 11 files changed, 60 insertions(+), 49 deletions(-) diff --git a/pandora_console/godmode/reporting/reporting_builder.php b/pandora_console/godmode/reporting/reporting_builder.php index 60b1601dc0..5357bdad13 100755 --- a/pandora_console/godmode/reporting/reporting_builder.php +++ b/pandora_console/godmode/reporting/reporting_builder.php @@ -1055,7 +1055,7 @@ switch ($action) { ] ); $data[2] .= ''; - $data[3] = ''; + $data[3] = ''; $data[3] .= html_print_image( 'images/xml.png', true, diff --git a/pandora_console/include/class/ModuleTemplates.class.php b/pandora_console/include/class/ModuleTemplates.class.php index ba67142560..782d3bb82d 100644 --- a/pandora_console/include/class/ModuleTemplates.class.php +++ b/pandora_console/include/class/ModuleTemplates.class.php @@ -506,6 +506,7 @@ class ModuleTemplates extends HTML header('Content-Disposition: attachment; filename='.preg_replace('/\s/', '_', $fileName).'.csv'); header('Pragma: no-cache'); header('Expires: 0'); + setDownloadCookieToken(); // Clean up output buffering while (@ob_end_clean()) { @@ -931,7 +932,7 @@ class ModuleTemplates extends HTML ] ); $data[3] = ''.html_print_image('images/cross.png', true, ['title' => __('Delete'), 'class' => 'invert_filter']).''; - $data[3] .= ''.html_print_image('images/csv.png', true, ['title' => __('Export to CSV'), 'class' => 'invert_filter']).''; + $data[3] .= ''.html_print_image('images/csv.png', true, ['title' => __('Export to CSV'), 'class' => 'invert_filter']).''; array_push($table->data, $data); } diff --git a/pandora_console/include/functions.php b/pandora_console/include/functions.php index 4facfad081..3ee1815e08 100644 --- a/pandora_console/include/functions.php +++ b/pandora_console/include/functions.php @@ -6271,31 +6271,22 @@ function arrayOutputSorting($sort, $sortField) } -function setCookieToken($cookieName, $cookieValue, $httpOnly=true, $secure=false) -{ - // See: http://stackoverflow.com/a/1459794/59087 - // See: http://shiflett.org/blog/2006/mar/server-name-versus-http-host - // See: http://stackoverflow.com/a/3290474/59087 - setcookie( - $cookieName, - $cookieValue, - 2147483647, - // expires January 1, 2038 - '/', - // your path - $_SERVER['HTTP_HOST'], - // your domain - $secure, - // Use true over HTTPS - $httpOnly - // Set true for $AUTH_COOKIE_NAME - ); -} - - +/** + * Get dowload started cookie from js and set ready cokkie for download ready comntrol. + * + * @return + */ function setDownloadCookieToken() { - $token = 'downloadToken'; - - setCookieToken($token, $_GET[$token], false, false); + $download_cookie = get_cookie('downloadToken', false); + if ($download_cookie === false) { + return; + } else { + setcookie( + 'downloadReady', + $download_cookie, + (time() + 15), + '/' + ); + } } diff --git a/pandora_console/include/functions_reporting_xml.php b/pandora_console/include/functions_reporting_xml.php index 196027e90c..9b733c40d3 100644 --- a/pandora_console/include/functions_reporting_xml.php +++ b/pandora_console/include/functions_reporting_xml.php @@ -46,6 +46,8 @@ function reporting_xml_get_report($report, $filename, $return=false) // Download if marked to download. if ($filename !== false) { + // Cookie for download control. + setDownloadCookieToken(); header('Content-Type: application/xml; charset=UTF-8'); header('Content-Disposition: attachment; filename="'.$filename.'.xml"'); } diff --git a/pandora_console/include/functions_ui.php b/pandora_console/include/functions_ui.php index 6ae90f29ef..ae346f1783 100755 --- a/pandora_console/include/functions_ui.php +++ b/pandora_console/include/functions_ui.php @@ -3540,6 +3540,9 @@ function ui_print_datatable(array $parameters) titleAttr: "'.__('Export current page to CSV').'", title: "export_'.$parameters['id'].'_current_page_'.date('Y-m-d').'", fieldSeparator: "'.$config['csv_divider'].'", + action: function ( e, dt, node, config ) { + blockResubmit(node); + }, exportOptions : { modifier : { // DataTables core @@ -3547,7 +3550,7 @@ function ui_print_datatable(array $parameters) page : "All", search : "applied" }'.$export_columns.' - } + }, } ] : [], lengthMenu: '.json_encode($pagination_options).', diff --git a/pandora_console/include/graphs/export_data.php b/pandora_console/include/graphs/export_data.php index a3c42577be..17b59b2baa 100644 --- a/pandora_console/include/graphs/export_data.php +++ b/pandora_console/include/graphs/export_data.php @@ -51,6 +51,9 @@ $default_filename = 'data_exported - '.date($config['date_format']); $filename = (string) get_parameter('filename', $default_filename); $filename = io_safe_output($filename); +// Set cookie for download control. +setDownloadCookieToken(); + /* * $data = array( * 'head' => array(,,...,), diff --git a/pandora_console/include/graphs/flot/pandora.flot.js b/pandora_console/include/graphs/flot/pandora.flot.js index 16e1b31a82..8084d4d6b3 100644 --- a/pandora_console/include/graphs/flot/pandora.flot.js +++ b/pandora_console/include/graphs/flot/pandora.flot.js @@ -2716,6 +2716,7 @@ function pandoraFlotArea( $("#menu_export_csv_" + graph_id).click(function(e) { e.preventDefault(); + blockResubmit($(this)); plot.exportDataCSV(); var es_firefox = navigator.userAgent.toLowerCase().indexOf("firefox") > -1; diff --git a/pandora_console/include/javascript/pandora_ui.js b/pandora_console/include/javascript/pandora_ui.js index 30e7ee32ee..1d9db8e328 100644 --- a/pandora_console/include/javascript/pandora_ui.js +++ b/pandora_console/include/javascript/pandora_ui.js @@ -456,8 +456,7 @@ function load_modal(settings) { // Function that shows a dialog box to confirm closures of generic manners. // The modal id is random. // eslint-disable-next-line no-unused-vars -function confirmDialog(settings) { - var randomStr = uniqId(); +function confirmDialog(settings, idDialog = uniqId()) { var hideOkButton = ""; var hideCancelButton = ""; @@ -487,11 +486,11 @@ function confirmDialog(settings) { if (typeof settings.message == "function") { $("body").append( - '
' + settings.message() + "
" + '
' + settings.message() + "
" ); } else { $("body").append( - '
' + settings.message + "
" + '
' + settings.message + "
" ); } @@ -542,8 +541,8 @@ function confirmDialog(settings) { buttons.unshift(newButton); } - $("#confirm_" + randomStr); - $("#confirm_" + randomStr) + $("#confirm_" + idDialog); + $("#confirm_" + idDialog) .dialog({ open: settings.open, title: settings.title, @@ -785,10 +784,11 @@ function setCursor(buttonStyle, button) { button.css("cursor", buttonStyle); } -function setFormToken(button) { +function setToken() { var downloadToken = new Date().getTime(); - button.append("'.html_print_image( + $csv['text'] = ''.html_print_image( 'images/csv.png', true, [ diff --git a/pandora_console/operation/events/export_csv.php b/pandora_console/operation/events/export_csv.php index 20856b707e..4b91f36e6d 100644 --- a/pandora_console/operation/events/export_csv.php +++ b/pandora_console/operation/events/export_csv.php @@ -150,6 +150,7 @@ $now = date('Y-m-d'); // Download header. header('Content-type: text/txt'); header('Content-Disposition: attachment; filename="export_events_'.$now.'.csv"'); +setDownloadCookieToken(); try { $fb64 = get_parameter('fb64', null); diff --git a/pandora_console/vendor/mpdf/mpdf/src/Mpdf.php b/pandora_console/vendor/mpdf/mpdf/src/Mpdf.php index 2c60309f83..ffe70a1f64 100644 --- a/pandora_console/vendor/mpdf/mpdf/src/Mpdf.php +++ b/pandora_console/vendor/mpdf/mpdf/src/Mpdf.php @@ -9478,6 +9478,8 @@ class Mpdf implements \Psr\Log\LoggerAwareInterface function Output($name = '', $dest = '') { $this->logger->debug(sprintf('PDF generated in %.6F seconds', microtime(true) - $this->time0), ['context' => LogContext::STATISTICS]); + // Set cokie token to indicate download is ready. + setDownloadCookieToken(); // Finish document if necessary if ($this->state < 3) { From e0afcd0b859d6fefb0f6e2d0a11a58500aa9395c Mon Sep 17 00:00:00 2001 From: Calvo Date: Fri, 2 Dec 2022 13:12:58 +0100 Subject: [PATCH 044/181] WIP: Download wait message. datatables --- pandora_console/include/functions_ui.php | 12 ++++++++ .../include/javascript/buttons.html5.min.js | 29 +------------------ .../include/javascript/pandora_ui.js | 11 ++++--- 3 files changed, 18 insertions(+), 34 deletions(-) diff --git a/pandora_console/include/functions_ui.php b/pandora_console/include/functions_ui.php index ae346f1783..1f547342d7 100755 --- a/pandora_console/include/functions_ui.php +++ b/pandora_console/include/functions_ui.php @@ -3542,6 +3542,8 @@ function ui_print_datatable(array $parameters) fieldSeparator: "'.$config['csv_divider'].'", action: function ( e, dt, node, config ) { blockResubmit(node); + // Call the default csvHtml5 action method to create the CSV file + $.fn.dataTable.ext.buttons.csvHtml5.action.call(this, e, dt, node, config); }, exportOptions : { modifier : { @@ -3674,6 +3676,16 @@ function ui_print_datatable(array $parameters) $js .= '$(".datatables_thead_tr").css("height", 0);'; } + if (isset($parameters['csv']) === true) { + $js."'$('#".$table_id."').on( 'buttons-processing', function ( e, indicator ) { + if ( indicator ) { + console.log('a'); + } + else { + console.log('b'); + }"; + } + $js .= '});'; $js .= ''; diff --git a/pandora_console/include/javascript/buttons.html5.min.js b/pandora_console/include/javascript/buttons.html5.min.js index deee7fee68..c65fb2737a 100644 --- a/pandora_console/include/javascript/buttons.html5.min.js +++ b/pandora_console/include/javascript/buttons.html5.min.js @@ -5,31 +5,4 @@ FileSaver.js (1.3.3) - MIT license Copyright © 2016 Eli Grey - http://eligrey.com */ -(function(f){"function"===typeof define&&define.amd?define(["jquery","datatables.net","datatables.net-buttons"],function(g){return f(g,window,document)}):"object"===typeof exports?module.exports=function(g,p,z,t){g||(g=window);p&&p.fn.dataTable||(p=require("datatables.net")(g,p).$);p.fn.dataTable.Buttons||require("datatables.net-buttons")(g,p);return f(p,g,g.document,z,t)}:f(jQuery,window,document)})(function(f,g,p,z,t,w){function A(a){for(var b="";0<=a;)b=String.fromCharCode(a%26+65)+b,a=Math.floor(a/ -26)-1;return b}function E(a,b){y===w&&(y=-1===C.serializeToString(f.parseXML(F["xl/worksheets/sheet1.xml"])).indexOf("xmlns:r"));f.each(b,function(b,c){if(f.isPlainObject(c))b=a.folder(b),E(b,c);else{if(y){var d=c.childNodes[0],e,h=[];for(e=d.attributes.length-1;0<=e;e--){var m=d.attributes[e].nodeName;var k=d.attributes[e].nodeValue;-1!==m.indexOf(":")&&(h.push({name:m,value:k}),d.removeAttribute(m))}e=0;for(m=h.length;e'+c),c=c.replace(/_dt_b_namespace_token_/g,":"),c=c.replace(/xmlns:NS[\d]+="" NS[\d]+:/g,""));c=c.replace(/<([^<>]*?) xmlns=""([^<>]*?)>/g,"<$1 $2>");a.file(b,c)}})}function r(a,b,d){var c=a.createElement(b);d&&(d.attr&&f(c).attr(d.attr),d.children&&f.each(d.children,function(a,b){c.appendChild(b)}),null!==d.text&&d.text!==w&&c.appendChild(a.createTextNode(d.text))); -return c}function L(a,b){var d=a.header[b].length;a.footer&&a.footer[b].length>d&&(d=a.footer[b].length);for(var c=0,f=a.body.length;cd&&(d=e);if(401*a[1]?!0:!1};try{var C=new XMLSerializer,y}catch(a){}var F={"_rels/.rels":'', -"xl/_rels/workbook.xml.rels":'',"[Content_Types].xml":'', -"xl/workbook.xml":'', -"xl/worksheets/sheet1.xml":'',"xl/styles.xml":''}, -K=[{match:/^\-?\d+\.\d%$/,style:60,fmt:function(a){return a/100}},{match:/^\-?\d+\.?\d*%$/,style:56,fmt:function(a){return a/100}},{match:/^\-?\$[\d,]+.?\d*$/,style:57},{match:/^\-?£[\d,]+.?\d*$/,style:58},{match:/^\-?€[\d,]+.?\d*$/,style:59},{match:/^\-?\d+$/,style:65},{match:/^\-?\d+\.\d{2}$/,style:66},{match:/^\([\d,]+\)$/,style:61,fmt:function(a){return-1*a.replace(/[\(\)]/g,"")}},{match:/^\([\d,]+\.\d{2}\)$/,style:62,fmt:function(a){return-1*a.replace(/[\(\)]/g,"")}},{match:/^\-?[\d,]+$/,style:63}, -{match:/^\-?[\d,]+\.\d{2}$/,style:64}];v.ext.buttons.copyHtml5={className:"buttons-copy buttons-html5",text:function(a){return a.i18n("buttons.copy","Copy")},action:function(a,b,d,c){this.processing(!0);var g=this;a=I(b,c);var e=b.buttons.exportInfo(c),h=H(c),m=a.str;d=f("
").css({height:1,width:1,overflow:"hidden",position:"fixed",top:0,left:0});e.title&&(m=e.title+h+h+m);e.messageTop&&(m=e.messageTop+h+h+m);e.messageBottom&&(m=m+h+h+e.messageBottom);c.customize&&(m=c.customize(m,c,b));c=f("