diff --git a/pandora_console/general/first_task/service_list.php b/pandora_console/general/first_task/service_list.php index 94f1003b6f..f3b816c006 100755 --- a/pandora_console/general/first_task/service_list.php +++ b/pandora_console/general/first_task/service_list.php @@ -12,20 +12,19 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. global $config; -global $agent_w; check_login(); ui_require_css_file('first_task'); ?> true, 'message' => __('There are no services defined yet.') ]); ?> - - +
__('Services')]); ?>
-

+

+

-

- +

diff --git a/pandora_console/include/db/mysql.php b/pandora_console/include/db/mysql.php index 8b7c81c9f9..3f0ddf967c 100644 --- a/pandora_console/include/db/mysql.php +++ b/pandora_console/include/db/mysql.php @@ -732,19 +732,23 @@ function mysql_db_format_array_where_clause_sql($values, $join='AND', $prefix=fa } } - if (is_null($value)) { - $query .= sprintf('%s IS NULL', $field); + if ($value === null) { + $not = (($negative === true) ? 'NOT' : ''); + $query .= sprintf('%s IS %s NULL', $field, $negative); } else if (is_int($value) || is_bool($value)) { - $query .= sprintf('%s = %d', $field, $value); + $not = (($negative === true) ? '!' : ''); + $query .= sprintf('%s %s= %d', $field, $not, $value); } else if (is_float($value) || is_double($value)) { - $query .= sprintf('%s = %f', $field, $value); + $not = (($negative === true) ? ' !' : ''); + $query .= sprintf('%s %s= %f', $field, $not, $value); } else if (is_array($value)) { - $not = $negative ? ' NOT ' : ''; - $query .= sprintf('%s %sIN ("%s")', $field, $not, implode('", "', $value)); + $not = (($negative === true) ? 'NOT' : ''); + $query .= sprintf('%s %s IN ("%s")', $field, $not, implode('", "', $value)); } else { if ($value === '') { - // Search empty string - $query .= sprintf("%s = ''", $field); + // Search empty string. + $not = (($negative === true) ? '!' : ''); + $query .= sprintf("%s %s= ''", $field, $not); } else if ($value[0] == '>') { $value = substr($value, 1, (strlen($value) - 1)); $query .= sprintf("%s > '%s'", $field, $value); @@ -757,9 +761,11 @@ function mysql_db_format_array_where_clause_sql($values, $join='AND', $prefix=fa $query .= sprintf("%s < '%s'", $field, $value); } } else if ($value[0] == '%') { - $query .= sprintf("%s LIKE '%s'", $field, $value); + $not = (($negative === true) ? ' NOT ' : ''); + $query .= sprintf("%s %s LIKE '%s'", $field, $not, $value); } else { - $query .= sprintf("%s = '%s'", $field, $value); + $not = (($negative === true) ? '!' : ''); + $query .= sprintf("%s %s= '%s'", $field, $not, $value); } } diff --git a/pandora_console/include/functions.php b/pandora_console/include/functions.php index 9cbb3a91fb..50a449d470 100644 --- a/pandora_console/include/functions.php +++ b/pandora_console/include/functions.php @@ -1552,9 +1552,14 @@ function enterprise_hook($function_name, $parameters=false) /** - * TODO: Document enterprise functions + * Include an enterprise file. + * + * @param string $filename Enterprise file to be included. + * @param array $variables Variables to be exported, as [varname => value]. + * + * @return mixed */ -function enterprise_include($filename) +function enterprise_include($filename, $variables=[]) { global $config; @@ -1576,6 +1581,10 @@ function enterprise_include($filename) } if (file_exists($filepath)) { + if (is_array($variables) === true) { + extract($variables); + } + include $filepath; return true; } @@ -1587,11 +1596,12 @@ function enterprise_include($filename) /** * Includes a file from enterprise section. * - * @param string $filename Target file. + * @param string $filename Enterprise file to be included. + * @param array $variables Variables to be exported, as [varname => value]. * * @return mixed Result code. */ -function enterprise_include_once($filename) +function enterprise_include_once($filename, $variables=[]) { global $config; @@ -1613,6 +1623,10 @@ function enterprise_include_once($filename) } if (file_exists($filepath)) { + if (is_array($variables) === true) { + extract($variables); + } + include_once $filepath; return true; } diff --git a/pandora_console/include/functions_html.php b/pandora_console/include/functions_html.php index d934c7815d..6eabde142f 100644 --- a/pandora_console/include/functions_html.php +++ b/pandora_console/include/functions_html.php @@ -915,7 +915,25 @@ function html_print_select( ui_require_javascript_file('select2.min'); } - $output .= ''; + $output .= ''; } if ($return) { @@ -1331,8 +1349,14 @@ function html_print_select_multiple_modules_filtered(array $data):string 'include/javascript/', true ); + ui_require_css_file( + 'multiselect_filtered', + 'include/styles/', + true + ); } else { ui_require_javascript_file('multiselect_filtered'); + ui_require_css_file('multiselect_filtered'); } $uniqId = $data['uniqId']; @@ -1417,7 +1441,7 @@ function html_print_select_multiple_modules_filtered(array $data):string // Force_serialized. false, // Meta_fields. - $data['mMetaFields'] + ($data['mMetaFields'] ?? is_metaconsole()) ); if ((empty($agents)) === true || $agents == -1) { @@ -1464,12 +1488,16 @@ function html_print_select_multiple_modules_filtered(array $data):string ] ); - $all_modules = select_modules_for_agent_group( - $data['mModuleGroup'], - explode(',', $data['mAgents']), - $data['mShowCommonModules'], - false - ); + if ($data['mAgents'] !== null) { + $all_modules = select_modules_for_agent_group( + $data['mModuleGroup'], + explode(',', $data['mAgents']), + $data['mShowCommonModules'], + false + ); + } else { + $all_modules = []; + } if ($data['mShowSelectedOtherGroups']) { $selected_modules_ids = explode(',', $data['mModules']); diff --git a/pandora_console/include/javascript/multiselect_filtered.js b/pandora_console/include/javascript/multiselect_filtered.js index 7976158740..358dadcd68 100644 --- a/pandora_console/include/javascript/multiselect_filtered.js +++ b/pandora_console/include/javascript/multiselect_filtered.js @@ -217,7 +217,12 @@ function fmModuleChange(uniqId) { if (data) { jQuery.each(data, function(id, value) { var option = $("") - .attr("value", value["id_agente_modulo"]) + .attr( + "value", + value["id_node"] + ? value["id_node"] + "|" + value["id_agente_modulo"] + : value["id_agente_modulo"] + ) .html(value["nombre"]); $("#filtered-module-modules-" + uniqId).append(option); }); diff --git a/pandora_console/include/javascript/pandora_dashboards.js b/pandora_console/include/javascript/pandora_dashboards.js index d5bea39443..faebcaa499 100644 --- a/pandora_console/include/javascript/pandora_dashboards.js +++ b/pandora_console/include/javascript/pandora_dashboards.js @@ -388,7 +388,7 @@ function initialiceLayout(data) { dashboardId: data.dashboardId, widgetId: widgetId }, - width: widgetId == 14 ? 750 : 450, + width: widgetId == 14 || widgetId == 2 ? 750 : 450, maxHeight: 600, minHeight: 400 }, diff --git a/pandora_console/include/lib/Agent.php b/pandora_console/include/lib/Agent.php index 0063b071b8..c71d8415ce 100644 --- a/pandora_console/include/lib/Agent.php +++ b/pandora_console/include/lib/Agent.php @@ -219,8 +219,19 @@ class Agent extends Entity if ($rs === false) { global $config; + $error = $config['dbconnection']->error; + if (empty($error) === true) { + if (empty($updates['intervalo']) === true) { + $error = 'Missing agent interval'; + } else if (empty($updates['id_group']) === true) { + $error = 'Missing id_group'; + } else if (empty($updates['id_group']) === true) { + $error = 'Missing id_group'; + } + } + throw new \Exception( - __METHOD__.' error: '.$config['dbconnection']->error + __METHOD__.' error: '.$error ); } diff --git a/pandora_console/include/lib/Dashboard/Widgets/agent_module.php b/pandora_console/include/lib/Dashboard/Widgets/agent_module.php index a06a730141..618e1c0537 100644 --- a/pandora_console/include/lib/Dashboard/Widgets/agent_module.php +++ b/pandora_console/include/lib/Dashboard/Widgets/agent_module.php @@ -35,6 +35,7 @@ use PandoraFMS\Module; */ class AgentModuleWidget extends Widget { + const MODULE_SEPARATOR = '|-|-|-|'; /** * Name widget. @@ -299,10 +300,33 @@ class AgentModuleWidget extends Widget $values['mShowCommonModules'] = \get_parameter( 'filtered-module-show-common-modules-'.$this->cellId ); - $values['mModules'] = \get_parameter( - 'filtered-module-modules-'.$this->cellId + $values['mModules'] = explode( + ',', + \get_parameter( + 'filtered-module-modules-'.$this->cellId + ) ); + if (is_metaconsole() === true) { + $values['mModules'] = implode( + self::MODULE_SEPARATOR, + array_reduce( + $values['mModules'], + function ($carry, $item) { + $d = explode('|', $item); + if (isset($d[1]) === true) { + $carry[] = $d[1]; + } else { + $carry[] = $item; + } + + return $carry; + }, + [] + ) + ); + } + return $values; } @@ -612,15 +636,34 @@ class AgentModuleWidget extends Widget } // Extract info all modules selected. - $target_modules = explode(',', $this->values['mModules']); - $all_modules = Module::search( - ['id_agente_modulo' => $target_modules] + $target_modules = explode( + self::MODULE_SEPARATOR, + $this->values['mModules'] ); + if (is_metaconsole() === true + && $this->values['mShowCommonModules'] === '0' + ) { + $all_modules = $target_modules; + } else { + $all_modules = Module::search( + ['id_agente_modulo' => $target_modules] + ); + } + if ($all_modules !== null) { $reduceAllModules = array_reduce( $all_modules, function ($carry, $item) { - $carry[$item->name()] = null; + if ($item === null) { + return $carry; + } + + if (is_object($item) === true) { + $carry[$item->name()] = null; + } else { + $carry[$item] = null; + } + return $carry; } ); @@ -653,12 +696,24 @@ class AgentModuleWidget extends Widget $visualData[$agent_id]['agent_name'] = $agent->name(); $visualData[$agent_id]['agent_alias'] = $agent->alias(); - $modules = $agent->searchModules( - ['id_agente_modulo' => $target_modules] - ); + if (is_metaconsole() === true + && $this->values['mShowCommonModules'] === '1' + ) { + $modules = $agent->searchModules( + ['id_agente_modulo' => $target_modules] + ); + } else { + $modules = $agent->searchModules( + ['nombre' => array_keys($reduceAllModules)] + ); + } $visualData[$agent_id]['modules'] = $reduceAllModules; foreach ($modules as $module) { + if ($module === null) { + continue; + } + if ((bool) is_metaconsole() === true) { $reduceAllModules[$module->name()] = null; } diff --git a/pandora_console/include/lib/Module.php b/pandora_console/include/lib/Module.php index 18f4366d3c..d2a5956e8c 100644 --- a/pandora_console/include/lib/Module.php +++ b/pandora_console/include/lib/Module.php @@ -88,7 +88,8 @@ class Module extends Entity * @param array $params Search parameters (fields from tagente_modulo). * @param integer $limit Limit results to N rows. * - * @return array|null of PandoraFMS\Module found or null if not found. + * @return object|array|null PandoraFMS\Module found if limited, array of Modules + * or null if not found. * @throws \Exception On error. */ public static function search( @@ -160,13 +161,24 @@ class Module extends Entity $obj->{$k}($v); } - if ($obj->nombre() === 'delete_pending') { + if ($obj->nombre() === 'delete_pending' + || $obj->nombre() === 'pendingdelete' + ) { return null; } // Customize certain fields. - $obj->status = new ModuleStatus($obj->id_agente_modulo()); - $obj->moduleType = new ModuleType($obj->id_tipo_modulo()); + try { + $obj->status = new ModuleStatus($obj->id_agente_modulo()); + } catch (\Exception $e) { + $obj->status = null; + } + + try { + $obj->moduleType = new ModuleType($obj->id_tipo_modulo()); + } catch (\Exception $e) { + $obj->moduleType = null; + } // Include some enterprise dependencies. enterprise_include_once('include/functions_config_agents.php'); diff --git a/pandora_console/include/styles/alert.css b/pandora_console/include/styles/alert.css index 92bcc5d2df..a5f505c81d 100644 --- a/pandora_console/include/styles/alert.css +++ b/pandora_console/include/styles/alert.css @@ -133,6 +133,7 @@ div.target { display: flex; flex-direction: column; width: 100%; + box-sizing: border-box; } div.target.flex { border: 2px dashed #ddd; diff --git a/pandora_console/include/styles/meta_dashboards.css b/pandora_console/include/styles/meta_dashboards.css index 658ca58609..f75afafa93 100644 --- a/pandora_console/include/styles/meta_dashboards.css +++ b/pandora_console/include/styles/meta_dashboards.css @@ -1,11 +1,13 @@ div#page { width: auto; } - +li#select_multiple_modules_filtered { + width: 650px; + margin: 0 auto; +} .networkconsole { height: 100%; } - .networkconsole svg { height: 100%; } @@ -21,11 +23,9 @@ div#page { right: 50px; top: 20px; } - .select-dashboard-width { width: 110%; } - #menu_tab li.nomn form#form-select-dashboard { margin-top: 0px !important; } diff --git a/pandora_console/include/styles/wizard.css b/pandora_console/include/styles/wizard.css index 0e85defc80..e47bc9d2ca 100644 --- a/pandora_console/include/styles/wizard.css +++ b/pandora_console/include/styles/wizard.css @@ -31,12 +31,20 @@ ul.wizard.inline li { margin-bottom: 0; } -ul.wizard li > label:not(.p-switch) { +ul.wizard li > label:not(.p-switch):first-of-type { width: 250px; vertical-align: top; display: inline-block; } +ul.wizard li > label:not(.p-switch):not(:first-of-type) { + margin-left: 1em; +} + +.select2.select2-container { + min-width: 200px; +} + ul.wizard li > textarea { width: 600px; height: 15em; diff --git a/pandora_console/operation/agentes/ver_agente.php b/pandora_console/operation/agentes/ver_agente.php index 52083168e3..094ce9c65c 100644 --- a/pandora_console/operation/agentes/ver_agente.php +++ b/pandora_console/operation/agentes/ver_agente.php @@ -27,6 +27,8 @@ * ============================================================================ */ +use PandoraFMS\Enterprise\Metaconsole\Node; + global $config; require_once 'include/functions_gis.php'; @@ -48,6 +50,7 @@ if (is_ajax()) { $get_agent_status_tooltip = (bool) get_parameter('get_agent_status_tooltip'); $get_agents_group_json = (bool) get_parameter('get_agents_group_json'); $get_modules_group_json = (bool) get_parameter('get_modules_group_json'); + $filter_modules_group_json = (bool) get_parameter('filter_modules_group_json'); $get_modules_group_value_name_json = (bool) get_parameter('get_modules_group_value_name_json'); $get_agent_modules_json_for_multiple_agents = (bool) get_parameter('get_agent_modules_json_for_multiple_agents'); $get_agent_modules_alerts_json_for_multiple_agents = (bool) get_parameter('get_agent_modules_alerts_json_for_multiple_agents'); @@ -191,9 +194,14 @@ if (is_ajax()) { if ($get_modules_group_json) { $id_group = (int) get_parameter('id_module_group', 0); - $id_agents = get_parameter('id_agents'); + $id_agents = get_parameter('id_agents', null); $selection = get_parameter('selection'); + if ($id_agents === null) { + echo '[]'; + return; + } + if ((bool) is_metaconsole() === true) { if (count($id_agents) > 0) { $rows = db_get_all_rows_sql( @@ -255,26 +263,49 @@ if (is_ajax()) { } $modules = []; - $i = 1; foreach ($final_modules as $module_name => $occurrences) { if ($occurrences === $nodes_consulted) { // Module already present in ALL nodes. $modules[] = [ - 'id_agente_modulo' => ($i++), + 'id_agente_modulo' => $module_name, 'nombre' => $module_name, ]; } } } else { // All modules. - $modules = array_reduce( - $modules[$tserver], - function ($carry, $item) { - $carry[] = $item; - return $carry; - }, - [] - ); + $return = []; + $nodes = []; + foreach ($agents as $tserver => $id_agents) { + try { + $nodes[$tserver] = new Node($tserver); + } catch (Exception $e) { + hd($e); + } + + $return = array_reduce( + $modules[$tserver], + function ($carry, $item) use ($tserver, $nodes) { + $t = []; + foreach ($item as $k => $v) { + $t[$k] = $v; + } + + $t['id_node'] = $tserver; + if ($nodes[$tserver] !== null) { + $t['nombre'] = io_safe_output( + $nodes[$tserver]->server_name().' » '.$t['nombre'] + ); + } + + $carry[] = $t; + return $carry; + }, + $return + ); + } + + $modules = $return; } echo json_encode($modules); @@ -283,6 +314,103 @@ if (is_ajax()) { } } + if ($filter_modules_group_json) { + $modules = (array) get_parameter('modules', []); + $existing_modules = []; + + $avoid_duplicates = []; + foreach ($modules as $def) { + $data = explode('|', $def); + if (is_metaconsole() === true) { + $id_node = (int) $data[0]; + $id_agent = db_get_value( + 'id_tagente', + 'tmetaconsole_agent', + 'id_agente', + (int) $data[1] + ); + + $mod = explode(' » ', $data[2]); + $module_name = $mod[1]; + if (empty($module_name) === true) { + // Common modules. + $id_agent = db_get_value( + 'id_tagente', + 'tmetaconsole_agent', + 'id_agente', + (int) $data[0] + ); + + $id_node = db_get_value( + 'id_tmetaconsole_setup', + 'tmetaconsole_agent', + 'id_agente', + (int) $data[0] + ); + + $module_name = $data[1]; + } + } else { + $id_agent = $data[0]; + $module_name = $data[1]; + } + + if ($id_agent === false) { + continue; + } + + try { + if (is_metaconsole() === true) { + $node = new Node($id_node); + $node->connect(); + } + + $module = PandoraFMS\Module::search( + [ + 'id_agente' => $id_agent, + 'nombre' => $module_name, + ], + 1 + ); + + if ($module !== null) { + $text = ''; + $id = ''; + if ($node !== null) { + $text = $node->server_name().' » '; + $id = $node->id().'|'; + } + + $text .= $module->agent()->alias().' » '.$module->nombre(); + + $id .= $module->id_agente_modulo(); + if ($avoid_duplicates[$id] === 1) { + continue; + } + + $avoid_duplicates[$id] = 1; + $existing_modules[] = [ + 'id' => $id, + 'text' => io_safe_output($text), + ]; + } + + + if (is_metaconsole() === true) { + $node->disconnect(); + } + } catch (Exception $e) { + if ($node !== null) { + $node->disconnect(); + } + + continue; + } + } + + echo json_encode($existing_modules); + } + if ($get_modules_group_value_name_json) { $id_agents = get_parameter('id_agents'); $selection = get_parameter('selection');