diff --git a/pandora_console/extras/mr/57.sql b/pandora_console/extras/mr/57.sql index 5b3f4d9648..5369c7a46f 100644 --- a/pandora_console/extras/mr/57.sql +++ b/pandora_console/extras/mr/57.sql @@ -1,5 +1,6 @@ START TRANSACTION; +ALTER TABLE `tmap` ADD COLUMN `refresh_time` INT UNSIGNED NOT NULL DEFAULT 0; ALTER TABLE `tplanned_downtime` ADD COLUMN `cron_interval_from` VARCHAR(100) DEFAULT ''; ALTER TABLE `tplanned_downtime` ADD COLUMN `cron_interval_to` VARCHAR(100) DEFAULT ''; diff --git a/pandora_console/godmode/wizards/HostDevices.class.php b/pandora_console/godmode/wizards/HostDevices.class.php index cf4f6fe87b..a851c62c8c 100755 --- a/pandora_console/godmode/wizards/HostDevices.class.php +++ b/pandora_console/godmode/wizards/HostDevices.class.php @@ -941,6 +941,7 @@ class HostDevices extends Wizard 'return' => true, 'class' => 'discovery_list_input', 'simple_multiple_options' => true, + 'required' => true, ] ); @@ -1001,6 +1002,7 @@ class HostDevices extends Wizard $("#text-interval_text").val(10); $("#hidden-interval").val('.$interval.'); $("#interval_units").val('.$unit.'); + $("#interval_units").trigger("change"); } }).change(); diff --git a/pandora_console/include/class/CustomNetScan.class.php b/pandora_console/include/class/CustomNetScan.class.php index bb0b420f1e..f6af0ded74 100644 --- a/pandora_console/include/class/CustomNetScan.class.php +++ b/pandora_console/include/class/CustomNetScan.class.php @@ -594,6 +594,7 @@ class CustomNetScan extends Wizard $("#text-interval_text").val(10); $("#hidden-interval").val('.$interval.'); $("#interval_units").val('.$unit.'); + $("#interval_units").trigger("change"); } }).change(); '; diff --git a/pandora_console/include/class/NetworkMap.class.php b/pandora_console/include/class/NetworkMap.class.php index 8122369495..db1b12fec9 100644 --- a/pandora_console/include/class/NetworkMap.class.php +++ b/pandora_console/include/class/NetworkMap.class.php @@ -2102,39 +2102,91 @@ class NetworkMap $i++; } - if (!$this->relations) { - // Search for relations. - foreach ($this->nodes as $k => $item) { - $target = $this->calculateRelations($k); + // Search for relations. + foreach ($this->nodes as $k => $item) { + $target = $this->calculateRelations($k); - // Adopt all orphan nodes but pandora one. - if (empty($target)) { - if (isset($this->noPandoraNode) === false - || $this->noPandoraNode == false - ) { - if ($item['id_node'] != 0) { - $rel = []; - $rel['id_parent'] = 0; - $rel['id_child'] = $item['id_node']; - $rel['parent_type'] = NODE_PANDORA; - $rel['child_type'] = $item['node_type']; - $rel['id_child_source_data'] = $item['id_source_data']; + // Adopt all orphan nodes but pandora one. + if (empty($target) === true) { + if (isset($this->noPandoraNode) === false + || $this->noPandoraNode == false + ) { + if ($item['id_node'] != 0) { + $rel = []; + $rel['id_parent'] = 0; + $rel['id_child'] = $item['id_node']; + $rel['parent_type'] = NODE_PANDORA; + $rel['child_type'] = $item['node_type']; + $rel['id_child_source_data'] = $item['id_source_data']; - $orphans[] = $rel; - } - } - } else { - // Flattern edges. - foreach ($target as $rel) { - $edges[] = $rel; + $orphans[] = $rel; } } + } else { + // Flattern edges. + foreach ($target as $rel) { + $edges[] = $rel; + } } - } else { - $edges = $this->relations; } if (is_array($edges)) { + $array_aux = $edges; + $target_aux = $edges; + foreach ($edges as $key => $rel) { + foreach ($array_aux as $key2 => $rel2) { + if ($key2 <= $key) { + continue; + } + + if ($rel['child_type'] == 1 && $rel['parent_type'] == 1 + && $rel2['child_type'] == 1 && $rel2['parent_type'] == 1 + ) { + if ($rel['id_parent'] == $rel2['id_parent'] && $rel['id_child'] == $rel2['id_child']) { + if ($rel['id_parent_source_data'] == $rel2['id_parent_source_data']) { + if (modules_get_agentmodule_type($rel['id_child_source_data']) === 6) { + unset($target_aux[$key]); + } else if (modules_get_agentmodule_type($rel2['id_child_source_data']) === 6) { + unset($target_aux[$key2]); + } + } else if ($rel['id_child_source_data'] == $rel2['id_child_source_data']) { + if (modules_get_agentmodule_type($rel['id_parent_source_data']) === 6) { + unset($target_aux[$key]); + } else if (modules_get_agentmodule_type($rel2['id_parent_source_data']) === 6) { + unset($target_aux[$key2]); + } + } + } else if ($rel['id_parent'] == $rel2['id_child'] && $rel['id_child'] == $rel2['id_parent']) { + if ($rel['id_parent_source_data'] == $rel2['id_child_source_data'] + && $rel['id_child_source_data'] == $rel2['id_parent_source_data'] + ) { + unset($target_aux[$key2]); + continue; + } + + if ($rel['id_parent_source_data'] == $rel2['id_child_source_data']) { + if (modules_get_agentmodule_type($rel['id_child_source_data']) === 6) { + unset($target_aux[$key]); + } else if (modules_get_agentmodule_type($rel2['id_parent_source_data']) === 6) { + unset($target_aux[$key2]); + } + } else if ($rel['id_child_source_data'] == $rel2['id_parent_source_data']) { + if (modules_get_agentmodule_type($rel['id_parent_source_data']) === 6) { + unset($target_aux[$key]); + } else if (modules_get_agentmodule_type($rel2['id_child_source_data']) === 6) { + unset($target_aux[$key2]); + } + } + } + } + } + } + + $edges = []; + foreach ($target_aux as $key => $value) { + $edges[] = $value; + } + foreach ($edges as $rel) { $graph .= $this->createDotEdge( [ @@ -2628,6 +2680,79 @@ class NetworkMap } + /** + * Regenerates a nodes - relationships array using graphviz dot + * schema and stores nodes&relations into $this->graph. + * + * @return object + */ + public function recalculateCoords() + { + global $config; + + include_once 'include/functions_os.php'; + + $map_filter = $this->mapOptions['map_filter']; + + /* + * Let graphviz place the nodes. + */ + + if ($map_filter['empty_map']) { + $this->generateEmptyDotGraph(); + } else if (!isset($this->dotGraph)) { + $this->generateDotGraph(); + } + + $graph = $this->calculateCoords(); + + if (is_array($graph) === true) { + $nodes = $graph['nodes']; + } else { + return []; + } + + $nodes_aux = []; + + // Prepare graph nodes. + foreach ($nodes as $id => $coords) { + $node_tmp['id'] = $id; + + $source = $this->getNodeData($id); + + $node_tmp['type'] = $source['node_type']; + $node_tmp['x'] = $coords['x']; + $node_tmp['y'] = $coords['y']; + + switch ($node_tmp['type']) { + case NODE_AGENT: + $node_tmp['source_data'] = $source['id_agente']; + break; + + case NODE_MODULE: + $node_tmp['source_data'] = $source['id_agente_modulo']; + break; + + case NODE_PANDORA: + $node_tmp['source_data'] = 0; + $node_center['x'] = ($coords['x'] - MAP_X_CORRECTION); + $node_center['y'] = ($coords['y'] - MAP_Y_CORRECTION); + break; + + case NODE_GENERIC: + default: + $node_tmp['source_data'] = $source['id_source']; + break; + } + + $nodes_aux[$index] = $node_tmp; + $index++; + } + + return $nodes_aux; + } + + /** * Transform node information into JS data. * @@ -2799,7 +2924,6 @@ class NetworkMap $output .= "var add_node_menu = '".__('Add node')."';\n"; $output .= "var set_center_menu = '".__('Set center')."';\n"; $output .= "var refresh_menu = '".__('Refresh')."';\n"; - $output .= "var refresh_holding_area_menu = '".__('Refresh Holding area')."';\n"; $output .= "var ok_button = '".__('Proceed')."';\n"; $output .= "var message_to_confirm = '".__('Resetting the map will delete all customizations you have done, including manual relationships between elements, new items, etc.')."';\n"; $output .= "var warning_message = '".__('WARNING')."';\n"; @@ -3066,8 +3190,8 @@ class NetworkMap $table->data['template_row']['node_target'] = ''; $table->data['template_row']['edit'] = ''; - $table->data['template_row']['edit'] .= ''.html_print_image('images/config.png', true, ['class' => 'invert_filter']).''; - + $table->data['template_row']['edit'] .= ''; + // '.html_print_image('images/config.png', true, ['class' => 'invert_filter']).''; $table->data['template_row']['edit'] .= ''.html_print_image('images/delete.png', true, ['class' => 'invert_filter']).''; $table->colspan['no_relations']['0'] = 5; @@ -3278,7 +3402,7 @@ class NetworkMap $table->data[1][1] = html_print_select( $list_networkmaps, 'networkmap_to_link', - '', + 0, '', '', 0, @@ -3318,6 +3442,10 @@ class NetworkMap */ public function loadController(?bool $return=true) { + if (isset($this->mapOptions['refresh_time']) === false) { + $this->mapOptions['refresh_time'] = 0; + } + $output = ''; if ($this->useTooltipster @@ -3359,13 +3487,34 @@ class NetworkMap node_radius: node_radius, holding_area_dimensions: networkmap_holding_area_dimensions, url_background_grid: url_background_grid, + refresh_time: '.$this->mapOptions['refresh_time'].', font_size: '.$this->mapOptions['font_size'].', base_url_homedir: "'.ui_get_full_url(false).'" }); init_drag_and_drop(); init_minimap(); function_open_minimap(); - + + if ('.$this->mapOptions['refresh_time'].' > 0) { + var startCountDown = function (duration, cb) { + $("div.vc-countdown").countdown("destroy"); + if (!duration) return; + var t = new Date(); + t.setTime(t.getTime() + duration * 1000); + $("div.vc-countdown").countdown({ + until: t, + format: "MS", + layout: "(%M%nn%M:%S%nn%S '.__('Until refresh').') ", + alwaysExpire: true, + onExpiry: function () { + refresh(); + } + }); + } + + startCountDown('.($this->mapOptions['refresh_time']).', false); + } + $(document.body).on("mouseleave", ".context-menu-list", function(e) { @@ -3504,6 +3653,10 @@ class NetworkMap $output .= ' style="width: '.$this->mapOptions['width'].'px; height: '.$this->mapOptions['height'].'px;position: relative; overflow: hidden; background: #FAFAFA">'; } + $output .= ''; + $output .= '
'; $output .= ' $row['id']] - ); + // Agent <-> Agent. + if ((int) $row['parent_type'] === 0 && (int) $row['child_type'] === 0) { + // Delete the duplicate row. + db_process_sql_delete( + 'trel_item', + ['id' => $row['id']] + ); + } else { + // Agent <-> Module or Module <-> Agent or Module <-> Module. + if ($pre_parent_source === (int) $row['id_parent_source_data'] + && $pre_child_source === (int) $row['id_child_source_data'] + ) { + // Delete the duplicate row. + db_process_sql_delete( + 'trel_item', + ['id' => $row['id']] + ); + } else { + $pre_parent_source = (int) $row['id_parent_source_data']; + $pre_child_source = (int) $row['id_child_source_data']; + } + } } else { - $pre_parent = $row['id_parent']; - $pre_child = $row['id_child']; + $pre_parent = (int) $row['id_parent']; + $pre_child = (int) $row['id_child']; + if ((int) $row['parent_type'] === 1 || (int) $row['child_type'] === 1) { + $pre_parent_source = (int) $row['id_parent_source_data']; + $pre_child_source = (int) $row['id_child_source_data']; + } } } - db_process_sql($sql_duplicate_links); - do { db_clean_cache(); $sql_duplicate_links_parent_as_children = ' - SELECT id, id_parent, id_child + SELECT * FROM trel_item t1 WHERE t1.deleted = 0 AND t1.id_child IN ( SELECT t2.id_parent @@ -2765,14 +2786,51 @@ function networkmap_clean_duplicate_links($id) if (($row['id'] != $row2['id']) && ($row['id_child'] == $row2['id_parent']) && ($row['id_parent'] == $row2['id_child']) + && ($row['parent_type'] == $row2['child_type']) + && ($row['child_type'] == $row2['parent_type']) ) { - db_process_sql_delete( - 'trel_item', - ['id' => $row2['id']] - ); + // Agent <-> Agent. + if ((int) $row2['parent_type'] === 0 && (int) $row2['child_type'] === 0) { + db_process_sql_delete( + 'trel_item', + ['id' => $row2['id']] + ); - $found = true; - break; + $found = true; + break; + } else { + // Agent <-> Module or Module <-> Agent or Module <-> Module. + if ((int) $row['id_child_source_data'] === (int) $row2['id_parent_source_data'] + && (int) $row['id_parent_source_data'] === (int) $row2['id_child_source_data'] + ) { + db_process_sql_delete( + 'trel_item', + ['id' => $row2['id']] + ); + + $found = true; + break; + } + } + } else { + // Si no son del mismo tipo pero hay un parent_type = 0 y child_type = 0 borrar. + if ((int) $row['parent_type'] === 0 && (int) $row['child_type'] === 0) { + db_process_sql_delete( + 'trel_item', + ['id' => $row['id']] + ); + + $found = true; + break; + } else if ((int) $row2['parent_type'] === 0 && (int) $row2['child_type'] === 0) { + db_process_sql_delete( + 'trel_item', + ['id' => $row2['id']] + ); + + $found = true; + break; + } } } @@ -3020,53 +3078,96 @@ function networkmap_delete_link( function erase_node($id) { $node = db_get_row('titem', 'id', $id['id']); + if ($node['type'] !== '2') { + $return = db_process_sql_update( + 'titem', + ['deleted' => 1], + [ + 'id' => (int) $node['id'], + 'id_map' => (int) $node['id_map'], + ] + ); - $return = db_process_sql_update( - 'titem', - ['deleted' => 1], - ['id' => $node['id']] - ); + db_process_sql_update( + 'trel_item', + ['deleted' => 1], + [ + 'id_parent' => (int) $node['id'], + 'id_map' => (int) $node['id_map'], + ] + ); - db_process_sql_update( - 'trel_item', - ['deleted' => 1], - ['id_parent' => (int) $node['id']] - ); + db_process_sql_update( + 'trel_item', + ['deleted' => 1], + [ + 'id_child' => (int) $node['id'], + 'id_map' => (int) $node['id_map'], + ] + ); - db_process_sql_update( - 'trel_item', - ['deleted' => 1], - ['id_child' => (int) $node['id']] - ); + $node_modules = db_get_all_rows_filter( + 'titem', + [ + 'id_map' => $node['id_map'], + 'type' => 1, + ] + ); - $node_modules = db_get_all_rows_filter( - 'titem', - [ - 'id_map' => $node['id_map'], - 'type' => 1, - ] - ); + foreach ($node_modules as $node_module) { + $style = json_decode($node_module['style'], true); - foreach ($node_modules as $node_module) { - $style = json_decode($node_module['style'], true); - - if ($style['id_agent'] == $node['source_data']) { - db_process_sql_update( - 'titem', - ['deleted' => 1], - ['id' => $node_module['id']] - ); - db_process_sql_update( - 'trel_item', - ['deleted' => 1], - ['id_parent_source_data' => (int) $node_module['source_data']] - ); - db_process_sql_update( - 'trel_item', - ['deleted' => 1], - ['id_child_source_data' => (int) $node_module['source_data']] - ); + if ($style['id_agent'] == $node['source_data']) { + db_process_sql_update( + 'titem', + ['deleted' => 1], + [ + 'id' => (int) $node_module['id'], + 'id_map' => (int) $node_module['id_map'], + ] + ); + db_process_sql_update( + 'trel_item', + ['deleted' => 1], + [ + 'id_parent_source_data' => (int) $node_module['source_data'], + 'id_map' => (int) $node_module['id_map'], + ] + ); + db_process_sql_update( + 'trel_item', + ['deleted' => 1], + [ + 'id_child_source_data' => (int) $node_module['source_data'], + 'id_map' => (int) $node_module['id_map'], + ] + ); + } } + } else { + $return = db_process_sql_delete( + 'titem', + [ + 'id' => (int) $node['id'], + 'id_map' => (int) $node['id_map'], + ] + ); + + db_process_sql_delete( + 'trel_item', + [ + 'parent_type' => 2, + 'id_map' => (int) $node['id_map'], + ] + ); + + db_process_sql_delete( + 'trel_item', + [ + 'child_type' => 2, + 'id_map' => (int) $node['id_map'], + ] + ); } if ($return === false) { @@ -3504,6 +3605,7 @@ function update_node($node, $holding_area_x, $holding_area_y) $values = []; $values['x'] = $node['x']; $values['y'] = $node['y']; + $values['refresh'] = 0; if ($node['state'] === 'holding_area') { $networkmap_node = db_get_row_filter( @@ -3526,14 +3628,9 @@ function update_node($node, $holding_area_x, $holding_area_y) ) { // Inside holding area. $return['state'] = 'holding_area'; + $values['refresh'] = 1; } else { // The user move the node out the holding area. - db_process_sql_update( - 'titem', - ['refresh' => 0], - ['id' => $node['id_db']] - ); - $return['state'] = ''; } } @@ -4053,6 +4150,7 @@ function add_agent_node_in_option($id_networkmap, $id_agent, $x, $y) function networkmap_get_new_nodes_and_links($networkmap, $x, $y) { $id_networkmap = $networkmap['id']; + $id_recon = $networkmap['source_data']; $map_filter = $networkmap['filter']; if (is_array($map_filter) === false) { @@ -4060,11 +4158,11 @@ function networkmap_get_new_nodes_and_links($networkmap, $x, $y) } if ((int) $networkmap['source'] === SOURCE_TASK) { - $agents = get_discovery_agents($networkmap, true); + $agents = get_discovery_agents($id_recon, true); } else if ((int) $networkmap['source'] === SOURCE_NETWORK) { // Network map, based on direct network. $agents = networkmap_get_nodes_from_ip_mask( - $networkmap['source_data'], + $id_recon, true ); } else { @@ -4274,290 +4372,291 @@ function networkmap_get_new_nodes_and_links($networkmap, $x, $y) } } - // Get L2 interface relations. - $interfaces = modules_get_interfaces( - $node['source_data'], + // foreach ($interfaces as $interface) { + // $relations = modules_get_relations( + // ['id_module' => $interface['id_agente_modulo']] + // ); + // if (empty($relations) === true) { + // $relations = []; + // } + // foreach ($relations as $relation) { + // Get the links althought they are deleted (for to + // avoid to add) + // Check if the module is ping. + // if (modules_get_agentmodule_type($relation['module_a']) === '6') { + // The pings modules are not exist as interface + // the link is with the agent. + // $node_a = db_get_value_filter( + // 'id', + // 'titem', + // [ + // 'source_data' => modules_get_agentmodule_agent( + // $relation['module_a'] + // ), + // 'id_map' => $id_networkmap, + // ] + // ); + // } else { + // $node_a = db_get_value_filter( + // 'id', + // 'titem', + // [ + // 'source_data' => $relation['module_a'], + // 'type' => 1, + // 'id_map' => $id_networkmap, + // ] + // ); + // } + // Check if the module is ping. + // if (modules_get_agentmodule_type($relation['module_b']) == 6) { + // The pings modules are not exist as interface + // the link is with the agent. + // $node_b = db_get_value_filter( + // 'id', + // 'titem', + // [ + // 'source_data' => modules_get_agentmodule_agent( + // $relation['module_b'] + // ), + // 'id_map' => $id_networkmap, + // ] + // ); + // } else { + // $node_b = db_get_value_filter( + // 'id', + // 'titem', + // [ + // 'source_data' => $relation['module_b'], + // 'type' => 1, + // 'id_map' => $id_networkmap, + // ] + // ); + // } + // $exist = db_get_row_filter( + // 'trel_item', + // [ + // 'id_map' => $id_networkmap, + // 'id_parent_source_data' => $relation['module_a'], + // 'id_child_source_data' => $relation['module_b'], + // 'deleted' => 0, + // ] + // ); + // $exist_reverse = db_get_row_filter( + // 'trel_item', + // [ + // 'id_map' => $id_networkmap, + // 'id_parent_source_data' => $relation['module_b'], + // 'id_child_source_data' => $relation['module_a'], + // 'deleted' => 0, + // ] + // ); + // if (empty($exist) && empty($exist_reverse)) { + // Create the nodes for interfaces + // Ag1 ----- I1 ------ I2 ----- Ag2 + // * 2 interfaces nodes + // * 3 relations + // * I1 between I2 + // * Ag1 between I1 + // * Ag2 between I2 + // + // But check if it exists the relations + // agent between interface. + // if ($interface['id_agente_modulo'] == $relation['module_a']) { + // $agent_a = $interface['id_agente']; + // $agent_b = modules_get_agentmodule_agent( + // $relation['module_b'] + // ); + // } else { + // $agent_a = modules_get_agentmodule_agent( + // $relation['module_a'] + // ); + // $agent_b = $interface['id_agente']; + // } + // $item_a = db_get_value( + // 'id', + // 'titem', + // 'source_data', + // $agent_a + // ); + // $item_b = db_get_value( + // 'id', + // 'titem', + // 'source_data', + // $agent_b + // ); + // hd('----------------------', true); + // hd($agent_a, true); + // hd($agent_b, true); + // foreach ($interfaces as $interface) { + // $relations = modules_get_relations( + // ['id_module' => $interface['id_agente_modulo']] + // ); + // if (empty($relations) === true) { + // $relations = []; + // } + // foreach ($relations as $relation) {hd($item_a. '<->'. $item_b, true); + // hd('----------------------', true); + // continue; + // $exist_node_interface1 = db_get_row_filter( + // 'titem', + // [ + // 'id_map' => $id_networkmap, + // 'type' => 0, + // 'source_data' => $relation['module_a'], + // ] + // ); + // if (empty($exist_node_interface1) === true) { + // Crete the interface node + // and create the relation between agent and + // interface. + // $style = []; + // $style['id_agent'] = $agent_a; + // $style['shape'] = 'circle'; + // $style['image'] = 'images/mod_snmp_proc.png'; + // $style['width'] = 50; + // $style['height'] = 16; + // $style['label'] = modules_get_agentmodule_name($relation['module_a']); + // $id_int1 = db_process_sql_insert( + // 'titem', + // [ + // 'id_map' => $id_networkmap, + // 'x' => 666, + // 'y' => 666, + // 'z' => 0, + // 'deleted' => 0, + // 'type' => 1, + // 'refresh' => 0, + // 'source' => 0, + // 'source_data' => $relation['module_a'], + // 'style' => json_encode($style), + // ] + // ); + // $node_interface1 = db_get_row_filter( + // 'titem', + // [ + // 'id_map' => $id_networkmap, + // 'type' => 1, + // 'id' => $id_int1, + // ] + // ); + // $node_agent1 = db_get_value( + // 'id', + // 'titem', + // 'source_data', + // $agent_a + // ); + // db_process_sql_insert( + // 'trel_item', + // [ + // 'id_map' => $id_networkmap, + // 'id_parent' => $node_agent1, + // 'id_child' => $node_interface1, + // 'id_parent-source_data' => $agent_a, + // 'id_child-source_data' => $relation['module_a'], + // 'parent_type' => 0, + // 'child_type' => 1, + // ] + // ); + // } else { + // $node_interface1 = $exist_node_interface1; + // } + // $exist_node_interface2 = db_get_row_filter( + // 'titem', + // [ + // 'id_map' => $id_networkmap, + // 'type' => 1, + // 'source_data' => $relation['module_b'], + // ] + // ); + // if (empty($exist_node_interface2) === true) { + // Crete the interface node + // and create the relation between agent and + // interface. + // $style = []; + // $style['id_agent'] = $agent_a; + // $style['shape'] = 'circle'; + // $style['image'] = 'images/mod_snmp_proc.png'; + // $style['width'] = 50; + // $style['height'] = 16; + // $style['label'] = modules_get_agentmodule_name($relation['module_b']); + // $id_int2 = db_process_sql_insert( + // 'titem', + // [ + // 'id_map' => $id_networkmap, + // 'x' => 666, + // 'y' => 666, + // 'z' => 0, + // 'deleted' => 0, + // 'type' => 1, + // 'refresh' => 0, + // 'source' => 0, + // 'source_data' => $relation['module_b'], + // 'style' => json_encode($style), + // ] + // ); + // $node_interface2 = db_get_row_filter( + // 'titem', + // [ + // 'id_map' => $id_networkmap, + // 'type' => 1, + // 'id' => $id_int1, + // ] + // ); + // $node_agent1 = db_get_value( + // 'id', + // 'titem', + // 'source_data', + // $agent_a + // ); + // db_process_sql_insert( + // 'trel_item', + // [ + // 'id_map' => $id_networkmap, + // 'id_parent' => $node_agent1, + // 'id_child' => $node_interface1, + // 'id_parent-source_data' => $agent_a, + // 'id_child-source_data' => $relation['module_b'], + // 'parent_type' => 0, + // 'child_type' => 1, + // ] + // ); + // } else { + // $node_interface2 = $exist_node_interface2; + // } + // if (empty($node_interface1) === false && empty($node_interface2) === false) { + // if (is_array($node_interface1) === true) { + // $node_interface1 = $node_interface1['id']; + // } + // if (is_array($node_interface2) === true) { + // $node_interface2 = $node_interface2['id']; + // } + // db_process_sql_insert( + // 'trel_item', + // [ + // 'id_map' => $id_networkmap, + // 'id_parent' => $node_interface2, + // 'id_child' => $node_interface1, + // 'id_parent_source_data' => $relation['module_b'], + // 'id_child_source_data' => $relation['module_a'], + // 'parent_type' => 1, + // 'child_type' => 1, + // ] + // ); + // } + // } + // } + // } + $relations = modules_get_relations( [ - 'id_agente', - 'id_agente_modulo', + 'id_agent' => $node['source_data'], + 'networkmap' => true, ] ); - if (empty($interfaces) === true) { - $interfaces = []; - } - - foreach ($interfaces as $interface) { - $relations = modules_get_relations( - ['id_module' => $interface['id_agente_modulo']] - ); - if (empty($relations) === true) { - $relations = []; - } - - foreach ($relations as $relation) { - // Get the links althought they are deleted (for to - // avoid to add) - // Check if the module is ping. - if (modules_get_agentmodule_type($relation['module_a']) === '6') { - // The pings modules are not exist as interface - // the link is with the agent. - $node_a = db_get_value_filter( - 'id', - 'titem', - [ - 'source_data' => modules_get_agentmodule_agent( - $relation['module_a'] - ), - 'id_map' => $id_networkmap, - ] - ); - } else { - $node_a = db_get_value_filter( - 'id', - 'titem', - [ - 'source_data' => $relation['module_a'], - 'type' => 1, - 'id_map' => $id_networkmap, - ] - ); - } - - // Check if the module is ping. - if (modules_get_agentmodule_type($relation['module_b']) == 6) { - // The pings modules are not exist as interface - // the link is with the agent. - $node_b = db_get_value_filter( - 'id', - 'titem', - [ - 'source_data' => modules_get_agentmodule_agent( - $relation['module_b'] - ), - 'id_map' => $id_networkmap, - ] - ); - } else { - $node_b = db_get_value_filter( - 'id', - 'titem', - [ - 'source_data' => $relation['module_b'], - 'type' => 1, - 'id_map' => $id_networkmap, - ] - ); - } - - $exist = db_get_row_filter( - 'trel_item', - [ - 'id_map' => $id_networkmap, - 'id_parent_source_data' => $relation['module_a'], - 'id_child_source_data' => $relation['module_b'], - 'deleted' => 0, - ] - ); - - $exist_reverse = db_get_row_filter( - 'trel_item', - [ - 'id_map' => $id_networkmap, - 'id_parent_source_data' => $relation['module_b'], - 'id_child_source_data' => $relation['module_a'], - 'deleted' => 0, - ] - ); - - if (empty($exist) && empty($exist_reverse)) { - // Create the nodes for interfaces - // Ag1 ----- I1 ------ I2 ----- Ag2 - // * 2 interfaces nodes - // * 3 relations - // * I1 between I2 - // * Ag1 between I1 - // * Ag2 between I2 - // - // But check if it exists the relations - // agent between interface. - if ($interface['id_agente_modulo'] == $relation['module_a']) { - $agent_a = $interface['id_agente']; - $agent_b = modules_get_agentmodule_agent( - $relation['module_b'] - ); - } else { - $agent_a = modules_get_agentmodule_agent( - $relation['module_a'] - ); - $agent_b = $interface['id_agente']; - } - - $exist_node_interface1 = db_get_row_filter( - 'titem', - [ - 'id_map' => $id_networkmap, - 'type' => 1, - 'source_data' => $relation['module_a'], - ] - ); - - if (empty($exist_node_interface1) === true) { - // Crete the interface node - // and create the relation between agent and - // interface. - $style = []; - $style['id_agent'] = $agent_a; - $style['shape'] = 'circle'; - $style['image'] = 'images/mod_snmp_proc.png'; - $style['width'] = 50; - $style['height'] = 16; - $style['label'] = modules_get_agentmodule_name($relation['module_a']); - $id_int1 = db_process_sql_insert( - 'titem', - [ - 'id_map' => $id_networkmap, - 'x' => 666, - 'y' => 666, - 'z' => 0, - 'deleted' => 0, - 'type' => 1, - 'refresh' => 0, - 'source' => 0, - 'source_data' => $relation['module_a'], - 'style' => json_encode($style), - ] - ); - $node_interface1 = db_get_row_filter( - 'titem', - [ - 'id_map' => $id_networkmap, - 'type' => 1, - 'id' => $id_int1, - ] - ); - - $node_agent1 = db_get_value( - 'id', - 'titem', - 'source_data', - $agent_a - ); - - db_process_sql_insert( - 'trel_item', - [ - 'id_map' => $id_networkmap, - 'id_parent' => $node_agent1, - 'id_child' => $node_interface1, - 'id_parent-source_data' => $agent_a, - 'id_child-source_data' => $relation['module_a'], - 'parent_type' => 0, - 'child_type' => 1, - ] - ); - } else { - $node_interface1 = $exist_node_interface1; - } - - $exist_node_interface2 = db_get_row_filter( - 'titem', - [ - 'id_map' => $id_networkmap, - 'type' => 1, - 'source_data' => $relation['module_b'], - ] - ); - - if (empty($exist_node_interface2) === true) { - // Crete the interface node - // and create the relation between agent and - // interface. - $style = []; - $style['id_agent'] = $agent_a; - $style['shape'] = 'circle'; - $style['image'] = 'images/mod_snmp_proc.png'; - $style['width'] = 50; - $style['height'] = 16; - $style['label'] = modules_get_agentmodule_name($relation['module_b']); - $id_int2 = db_process_sql_insert( - 'titem', - [ - 'id_map' => $id_networkmap, - 'x' => 666, - 'y' => 666, - 'z' => 0, - 'deleted' => 0, - 'type' => 1, - 'refresh' => 0, - 'source' => 0, - 'source_data' => $relation['module_b'], - 'style' => json_encode($style), - ] - ); - - $node_interface2 = db_get_row_filter( - 'titem', - [ - 'id_map' => $id_networkmap, - 'type' => 1, - 'id' => $id_int1, - ] - ); - - $node_agent1 = db_get_value( - 'id', - 'titem', - 'source_data', - $agent_a - ); - - db_process_sql_insert( - 'trel_item', - [ - 'id_map' => $id_networkmap, - 'id_parent' => $node_agent1, - 'id_child' => $node_interface1, - 'id_parent-source_data' => $agent_a, - 'id_child-source_data' => $relation['module_b'], - 'parent_type' => 0, - 'child_type' => 1, - ] - ); - } else { - $node_interface2 = $exist_node_interface2; - } - - if (empty($node_interface1) === false && empty($node_interface2) === false) { - if (is_array($node_interface1) === true) { - $node_interface1 = $node_interface1['id']; - } - - if (is_array($node_interface2) === true) { - $node_interface2 = $node_interface2['id']; - } - - db_process_sql_insert( - 'trel_item', - [ - 'id_map' => $id_networkmap, - 'id_parent' => $node_interface2, - 'id_child' => $node_interface1, - 'id_parent_source_data' => $relation['module_b'], - 'id_child_source_data' => $relation['module_a'], - 'parent_type' => 1, - 'child_type' => 1, - ] - ); - } - } - } - } - - $relations = modules_get_relations(['id_agent' => $node['source_data']]); if ($relations === false) { $relations = []; } + // Relations Module <-> Module. foreach ($relations as $key => $relation) { $module_a = $relation['module_a']; $agent_a = modules_get_agentmodule_agent($module_a); @@ -4584,58 +4683,26 @@ function networkmap_get_new_nodes_and_links($networkmap, $x, $y) ); if (empty($exist) === true && empty($exist_reverse) === true) { - $style = []; - $style['id_agent'] = $agent_a; - $style['shape'] = 'circle'; - $style['image'] = 'images/mod_snmp_proc.png'; - $style['width'] = 50; - $style['height'] = 16; - $style['label'] = modules_get_agentmodule_name($module_a); - $id_int1 = db_process_sql_insert( + $item_a = db_get_value( + 'id', 'titem', - [ - 'id_map' => $id_networkmap, - 'x' => 666, - 'y' => 666, - 'z' => 0, - 'deleted' => 0, - 'type' => 1, - 'refresh' => 0, - 'source' => 0, - 'source_data' => $module_a, - 'style' => json_encode($style), - ] + 'source_data', + $agent_a ); - $style = []; - $style['id_agent'] = $agent_b; - $style['shape'] = 'circle'; - $style['image'] = 'images/mod_snmp_proc.png'; - $style['width'] = 50; - $style['height'] = 16; - $style['label'] = modules_get_agentmodule_name($module_b); - $id_int2 = db_process_sql_insert( + $item_b = db_get_value( + 'id', 'titem', - [ - 'id_map' => $id_networkmap, - 'x' => 666, - 'y' => 666, - 'z' => 0, - 'deleted' => 0, - 'type' => 1, - 'refresh' => 0, - 'source' => 0, - 'source_data' => $module_b, - 'style' => json_encode($style), - ] + 'source_data', + $agent_b ); db_process_sql_insert( 'trel_item', [ 'id_map' => $id_networkmap, - 'id_parent' => $id_int1, - 'id_child' => $id_int2, + 'id_parent' => $item_a, + 'id_child' => $item_b, 'id_parent_source_data' => $module_a, 'id_child_source_data' => $module_b, 'parent_type' => 1, @@ -4644,6 +4711,30 @@ function networkmap_get_new_nodes_and_links($networkmap, $x, $y) ); } } + + // Get L2 interface relations. + $interfaces = modules_get_interfaces( + $node['source_data'], + [ + 'id_agente', + 'id_agente_modulo', + ] + ); + if (empty($interfaces) === true) { + $interfaces = []; + } + + // hd('interfaces', true); + // foreach ($interfaces as $interface) { + // $relations = modules_get_relations( + // ['id_module' => $interface['id_agente_modulo']] + // ); + // if (empty($relations) === true) { + // $relations = []; + // } + // foreach ($relations as $relation) { + // } + // } } } diff --git a/pandora_console/include/javascript/functions_pandora_networkmap.js b/pandora_console/include/javascript/functions_pandora_networkmap.js index fb88c9f3e5..4882ccad2b 100644 --- a/pandora_console/include/javascript/functions_pandora_networkmap.js +++ b/pandora_console/include/javascript/functions_pandora_networkmap.js @@ -192,7 +192,8 @@ function delete_link( source_module_id, target_id, target_module_id, - id_link + id_link, + table_row = null ) { var params = []; params.push("delete_link=1"); @@ -241,8 +242,22 @@ function delete_link( draw_elements_graph(); init_drag_and_drop(); set_positions_graph(); + + if (typeof table_row !== "undefined" && table_row !== null) { + $(`#relations_table-template_row_${table_row}`).animate( + { backgroundColor: "#e6e6e6" }, + 500, + function() { + $(`#relations_table-template_row_${table_row}`).remove(); + const rowCount = $(".relation_link_row").length; + if (rowCount === 0) { + $("#relations_table-no_relations").show(); + $(`#update_relations_button`).remove(); + } + } + ); + } } - $("#dialog_node_edit").dialog("close"); } }); } @@ -378,11 +393,7 @@ function change_shape(id_db_node) { }) .on("click", selected_node) .on("dblclick", function(d) { - if (d.type == 3) { - move_to_networkmap(d); - } else { - edit_node(d, true); - } + edit_node(d, true); }) .on("contextmenu", function(d) { show_menu("node", d); @@ -419,11 +430,7 @@ function change_shape(id_db_node) { }) .on("click", selected_node) .on("dblclick", function(d) { - if (d.type == 3) { - move_to_networkmap(d); - } else { - edit_node(d, true); - } + edit_node(d, true); }) .on("contextmenu", function(d) { show_menu("node", d); @@ -446,11 +453,7 @@ function change_shape(id_db_node) { }) .on("click", selected_node) .on("dblclick", function(d) { - if (d.type == 3) { - move_to_networkmap(d); - } else { - edit_node(d, true); - } + edit_node(d, true); }) .on("contextmenu", function(d) { show_menu("node", d); @@ -487,11 +490,7 @@ function change_shape(id_db_node) { }) .on("click", selected_node) .on("dblclick", function(d) { - if (d.type == 3) { - move_to_networkmap(d); - } else { - edit_node(d, true); - } + edit_node(d, true); }) .on("contextmenu", function(d) { show_menu("node", d); @@ -515,11 +514,7 @@ function change_shape(id_db_node) { }) .on("click", selected_node) .on("dblclick", function(d) { - if (d.type == 3) { - move_to_networkmap(d); - } else { - edit_node(d, true); - } + edit_node(d, true); }) .on("contextmenu", function(d) { show_menu("node", d); @@ -556,11 +551,7 @@ function change_shape(id_db_node) { }) .on("click", selected_node) .on("dblclick", function(d) { - if (d.type == 3) { - move_to_networkmap(d); - } else { - edit_node(d, true); - } + edit_node(d, true); }) .on("contextmenu", function(d) { show_menu("node", d); @@ -607,6 +598,10 @@ function update_link(row_index, id_link) { $(".edit_icon_progress_" + row_index).css("display", ""); $(".edit_icon_" + row_index).css("display", "none"); + $(".edit_icon_" + row_index).css("display", "none"); + + let result = false; + var params = []; params.push("update_link=1"); params.push("networkmap_id=" + networkmap_id); @@ -621,6 +616,7 @@ function update_link(row_index, id_link) { data: params.join("&"), dataType: "json", type: "POST", + async: false, url: window.base_url_homedir + "/ajax.php", success: function(data) { $(".edit_icon_progress_" + row_index).css("display", "none"); @@ -726,11 +722,14 @@ function update_link(row_index, id_link) { draw_elements_graph(); init_drag_and_drop(); set_positions_graph(); + result = data["id_db_link"]; } else { $(".edit_icon_fail_" + row_index).css("display", ""); } } }); + + return result; } function delete_link_from_id(index) { @@ -826,51 +825,81 @@ function edit_node(data_node, dblClick) { "update_node_name(" + node_selected.id_db + ");" ); - var params = []; - params.push("get_agent_info=1"); - params.push("id_agent=" + node_selected["id_agent"]); - params.push("page=operation/agentes/pandora_networkmap.view"); - - jQuery.ajax({ - data: params.join("&"), - dataType: "json", - type: "POST", - url: window.base_url_homedir + "/ajax.php", - success: function(data) { + if (node_selected.type === "3") { + $("#node_details-0-0").html("Link to map"); + if (node_selected.networkmap_id > 0) { $("#node_details-0-1").html( - '' + - data["alias"] + + $( + `#edit_networkmap_to_link option[value='${node_selected.networkmap_id}']` + ).text() + "" ); - - var addresses = ""; - if (data["adressess"] instanceof Array) { - for (var i; i < data["adressess"].length; i++) { - addresses += data["adressess"][i] + "
"; - } - } else { - for (var address in data["adressess"]) { - addresses += address + "
"; - } - } - $("#node_details-1-1").html(addresses); - $("#node_details-2-1").html(data["os"]); - $("#node_details-3-1").html(data["group"]); - - $("[aria-describedby=dialog_node_edit]").css({ top: "200px" }); - $("#foot").css({ - top: parseInt( - $("[aria-describedby=dialog_node_edit]").css("height") + - $("[aria-describedby=dialog_node_edit]").css("top") - ), - position: "relative" - }); - - get_interface_data_to_table(node_selected, selected_links); + } else { + $("#node_details-0-1").html( + $( + `#edit_networkmap_to_link option[value='${node_selected.networkmap_id}']` + ).text() + ); } - }); + + $("#node_details-1").hide(); + $("#node_details-2").hide(); + $("#node_details-3").hide(); + } else { + $("#node_details-0-0").html("Agent"); + $("#node_details-1").show(); + $("#node_details-2").show(); + $("#node_details-3").show(); + + var params = []; + params.push("get_agent_info=1"); + params.push("id_agent=" + node_selected["id_agent"]); + params.push("page=operation/agentes/pandora_networkmap.view"); + + jQuery.ajax({ + data: params.join("&"), + dataType: "json", + type: "POST", + url: window.base_url_homedir + "/ajax.php", + success: function(data) { + $("#node_details-0-1").html( + '' + + data["alias"] + + "" + ); + + var addresses = ""; + if (data["adressess"] instanceof Array) { + for (var i; i < data["adressess"].length; i++) { + addresses += data["adressess"][i] + "
"; + } + } else { + for (var address in data["adressess"]) { + addresses += address + "
"; + } + } + $("#node_details-1-1").html(addresses); + $("#node_details-2-1").html(data["os"]); + $("#node_details-3-1").html(data["group"]); + + $("[aria-describedby=dialog_node_edit]").css({ top: "200px" }); + $("#foot").css({ + top: parseInt( + $("[aria-describedby=dialog_node_edit]").css("height") + + $("[aria-describedby=dialog_node_edit]").css("top") + ), + position: "relative" + }); + + get_interface_data_to_table(node_selected, selected_links); + } + }); + } $("#dialog_node_edit").dialog( "option", @@ -887,6 +916,7 @@ function edit_node(data_node, dblClick) { $("input[name='edit_name_fictional_node']").val(node_selected.text); // It doesn't eval the possible XSS so it's ok $("#node_options-fictional_node_networkmap_link").css("display", ""); $("#edit_networkmap_to_link").val(node_selected.networkmap_id); + $("#edit_networkmap_to_link").trigger("change"); $("#node_options-fictional_node_update_button").css("display", ""); $("#node_options-node_name").css("display", "none"); $("#node_options-node_update_button").css("display", "none"); @@ -957,6 +987,7 @@ function get_interface_data_to_table(node_selected, selected_links) { function load_interfaces(selected_links) { //Clean $("#relations_table .relation_link_row").remove(); + $("#update_relations_button").remove(); //Show the no relations $("#relations_table-loading").css("display", "none"); $("#relations_table-no_relations").css("display", ""); @@ -969,6 +1000,7 @@ function load_interfaces(selected_links) { $(template_relation_row).css("display", ""); $(template_relation_row).attr("class", "relation_link_row"); + $(template_relation_row).attr("id", `relations_table-template_row_${i}`); $("select[name='interface_source']", template_relation_row) .attr("name", "interface_source_" + i) @@ -989,11 +1021,6 @@ function load_interfaces(selected_links) { "class", "edit_icon_fail_" + i ); - $(".edit_icon_link", template_relation_row) - .attr("class", "edit_icon_link_" + i) - .click(function() { - update_link(i, link_each.id_db); - }); var params3 = []; params3.push("get_intefaces=1"); @@ -1093,6 +1120,17 @@ function load_interfaces(selected_links) { "align", "center" ); + $("#relations_table-template_row-edit", template_relation_row).css({ + display: "flex", + "align-items": "center", + "justify-content": "center" + }); + + $( + "#relations_table-template_row-edit .delete_icon", + template_relation_row + ).attr("id", `delete_icon_${i}`); + $( "#relations_table-template_row-edit .delete_icon", template_relation_row @@ -1109,6 +1147,8 @@ function load_interfaces(selected_links) { link_each.id_module_end + "," + link_each.id_db + + "," + + i + ");" ); $("#relations_table tbody").append(template_relation_row); @@ -1119,6 +1159,42 @@ function load_interfaces(selected_links) { template_relation_row = null; }); + + if (selected_links.length > 0) { + $("#relations_table") + .parent() + .append( + `
+ +
` + ); + + $("#update_relations_button").click(function() { + jQuery.each(selected_links, function(i, link_each) { + const new_id_db = update_link(i, link_each.id_db); + if (new_id_db !== false) { + selected_links[i]["id_db"] = new_id_db; + $(`#delete_icon_${i}`).attr( + "href", + "javascript: " + + "delete_link(" + + link_each.source.id_db + + "," + + link_each.id_module_start + + "," + + link_each.target.id_db + + "," + + link_each.id_module_end + + "," + + new_id_db + + "," + + i + + ");" + ); + } + }); + }); + } } function add_node() { @@ -1303,11 +1379,6 @@ function function_close_minimap() { function delete_nodes() { var selection = d3.selectAll(".node_selected"); selection.each(function(d) { - //Avoid to delete pandora node center - if (d.id_agent == 0) { - return; - } - var params = []; params.push("id=" + d.id_db); params.push("delete_node=1"); @@ -1973,17 +2044,14 @@ function show_menu(item, data) { }; } - // Avoid deletion if Pandora FMS node. - if (data.type != 2) { - items_list["delete"] = { - name: delete_menu, - icon: "delete", - disabled: false, - callback: function(key, options) { - delete_nodes(); - } - }; - } + items_list["delete"] = { + name: delete_menu, + icon: "delete", + disabled: false, + callback: function(key, options) { + delete_nodes(); + } + }; $.contextMenu("destroy"); $.contextMenu({ @@ -2030,15 +2098,7 @@ function show_menu(item, data) { icon: "refresh", disabled: false, callback: function(key, options) { - update_networkmap(); - } - }; - items_list["refresh_holding_area"] = { - name: refresh_holding_area_menu, - icon: "refresh_holding_area", - disabled: false, - callback: function(key, options) { - refresh_holding_area(); + refresh(); } }; items_list["restart_map"] = { @@ -2398,6 +2458,99 @@ function refresh_holding_area() { }); } +function refresh() { + $("#spinner_networkmap").css("display", "flex"); + var holding_pos_x = d3.select("#holding_area_" + networkmap_id).attr("x"); + var holding_pos_y = d3.select("#holding_area_" + networkmap_id).attr("y"); + + var pos_x = parseInt(holding_pos_x) + parseInt(node_radius); + var pos_y = parseInt(holding_pos_y) + parseInt(node_radius); + + var params = []; + params.push("refresh_holding_area=1"); + params.push("id=" + networkmap_id); + params.push("x=" + pos_x); + params.push("y=" + pos_y); + params.push("page=operation/agentes/pandora_networkmap.view"); + $.ajax({ + data: { + page: "operation/agentes/pandora_networkmap.view", + refresh_holding_area: 1, + id: networkmap_id, + x: pos_x, + y: pos_y + }, + dataType: "json", + type: "POST", + url: window.base_url_homedir + "/ajax.php", + success: function(data) { + if (data["correct"]) { + const array_nodes = data["holding_area"]["nodes"]; + let array_links = data["holding_area"]["links"]; + jQuery.each(graph.links, function(j, g_link) { + for (var i = 0; i < array_links.length; i++) { + if (g_link["id_db"] == array_links[i]["id_db"]) { + array_links.splice(i, 1); + } + } + }); + + let location = ""; + if ($("#main").height()) { + location = `index.php?sec=network&sec2=operation/agentes/pandora_networkmap&tab=view&id_networkmap=${networkmap_id}`; + } else { + location = `index.php?sec=network&sec2=operation/agentes/pandora_networkmap&tab=view&pure=1&id_networkmap=${networkmap_id}`; + } + + if (array_nodes.length === 0 && array_links.length === 0) { + update_networkmap(); + $("#spinner_networkmap").css("display", "none"); + startCountDown(refresh_time); + } else { + if (array_nodes.length > 0) { + $.ajax({ + data: { + page: "operation/agentes/pandora_networkmap.view", + refresh_map: 1, + id: networkmap_id + }, + dataType: "json", + type: "POST", + url: window.base_url_homedir + "/ajax.php", + success: function(data) { + $("#spinner_networkmap").css("display", "none"); + window.location = location; + } + }); + } else if (array_links.length > 0) { + $("#spinner_networkmap").css("display", "none"); + window.location = location; + } + } + } + }, + error: function(e) { + $("#spinner_networkmap").css("display", "none"); + } + }); +} + +function startCountDown(duration) { + $("div.vc-countdown").countdown("destroy"); + if (!duration) return; + var t = new Date(); + t.setTime(t.getTime() + duration * 1000); + $("div.vc-countdown").countdown({ + until: t, + format: "MS", + layout: "(%M%nn%M:%S%nn%S Until refreshed) ", + alwaysExpire: true, + onExpiry: function() { + refresh(); + } + }); +} + function restart_map() { $( "
false, + 'text' => ''.html_print_image( + 'images/op_network.png', + true, + [ + 'title' => __('View map'), + 'class' => 'invert_filter', + ] + ).'', + ]; +} + // Header. ui_print_standard_header( __('Network maps editor'), @@ -207,7 +225,7 @@ ui_print_standard_header( false, 'network_map_enterprise_edit', false, - [], + $button, [ [ 'link' => '', @@ -434,6 +452,19 @@ if ($not_found) { $table->data['kval'][0] = __('Default ideal node separation'); $table->data['kval'][1] = html_print_input_text('kval', $kval, '', 5, 10, true, $disabled_source, false, $itemClass).ui_print_help_tip(__('Only fdp. Default ideal node separation in the layout. By default 0.3'), true); + $table->data['refresh'][0] = __('Refresh'); + $table->data['refresh'][1] = html_print_extended_select_for_time( + 'refresh_time', + $refresh_time, + '', + '', + '0', + false, + true, + false, + false + ); + echo '
'; html_print_table($table); @@ -613,9 +644,9 @@ $(document).ready(function() { event.preventDefault(); } -}); - + }); + $("#refresh_time_units").trigger("change"); }); diff --git a/pandora_console/operation/agentes/pandora_networkmap.php b/pandora_console/operation/agentes/pandora_networkmap.php index 91204eb11e..9c57ad033f 100644 --- a/pandora_console/operation/agentes/pandora_networkmap.php +++ b/pandora_console/operation/agentes/pandora_networkmap.php @@ -288,6 +288,8 @@ if ($new_networkmap || $save_networkmap) { $mindist = get_parameter('mindist', '1.0'); $kval = get_parameter('kval', '0.3'); + $refresh_time = get_parameter('refresh_time', '300'); + $values = []; $values['name'] = $name; $values['id_group'] = $id_group; @@ -297,6 +299,7 @@ if ($new_networkmap || $save_networkmap) { $values['id_user'] = $config['id_user']; $values['description'] = $description; $values['id_group_map'] = $id_group_map; + $values['refresh_time'] = $refresh_time; switch ($method) { case 'twopi': @@ -473,6 +476,8 @@ else if ($update_networkmap || $copy_networkmap || $delete) { $offset_y = get_parameter('pos_y', 0); $scale_z = get_parameter('scale_z', 0.5); + $refresh_time = get_parameter('refresh_time', '300'); + $values = []; $values['name'] = $name; $values['id_group'] = $id_group; @@ -481,6 +486,8 @@ else if ($update_networkmap || $copy_networkmap || $delete) { $description = get_parameter('description', ''); $values['description'] = $description; + $values['refresh_time'] = $refresh_time; + $dont_show_subgroups = (int) get_parameter('dont_show_subgroups', 0); $node_radius = (int) get_parameter('node_radius', 40); $row = db_get_row('tmap', 'id', $id); @@ -751,7 +758,11 @@ switch ($tab) { } if ($network_map['id_group'] > 0) { - $nodes = db_get_all_rows_sql('SELECT style FROM titem WHERE id_map = '.$network_map['id'].' AND deleted = 0'); + $nodes = db_get_all_rows_sql( + 'SELECT style + FROM titem + WHERE id_map = '.$network_map['id'].' AND deleted = 0 AND type <> 2' + ); $count = 0; foreach ($nodes as $node) { $node_style = json_decode($node['style'], true); @@ -763,7 +774,7 @@ switch ($tab) { $count = db_get_value_sql( 'SELECT COUNT(*) FROM titem - WHERE id_map = '.$network_map['id'].' AND deleted = 0 AND type = 0' + WHERE id_map = '.$network_map['id'].' AND deleted = 0 AND type <> 2' ); } @@ -780,8 +791,7 @@ switch ($tab) { $data['nodes'] = __('Pending to generate'); } } else { - $data['nodes'] = ($network_map['id_group'] == 0) ? ($count - 1) : $count; - // PandoraFMS node is not an agent + $data['nodes'] = $count; } $data['groups'] = ui_print_group_icon($network_map['id_group_map'], true); diff --git a/pandora_console/operation/agentes/pandora_networkmap.view.php b/pandora_console/operation/agentes/pandora_networkmap.view.php index de7ef79c77..ac888a13fa 100644 --- a/pandora_console/operation/agentes/pandora_networkmap.view.php +++ b/pandora_console/operation/agentes/pandora_networkmap.view.php @@ -76,6 +76,43 @@ if (is_ajax() === true) { $get_networkmap_from_fictional = (bool) get_parameter('get_networkmap_from_fictional', false); $get_reset_map_form = (bool) get_parameter('get_reset_map_form', false); $reset_map = (bool) get_parameter('reset_map', false); + $refresh_map = (bool) get_parameter('refresh_map', false); + + if ($refresh_map) { + $id_map = get_parameter('id'); + + include_once $config['homedir'].'/include/class/NetworkMap.class.php'; + + $map_manager = new NetworkMap( + ['id_map' => $id_map] + ); + + $filter = json_decode($map_manager->map['filter'], true); + $z_dash = $filter['z_dash']; + + $nodes = $map_manager->recalculateCoords(); + + foreach ($nodes as $key => $value) { + if ($value['type'] == 0 || $value['type'] == 2) { + $node['x'] = ($value['x'] + ($map_manager->map['center_x'] / 2) / $z_dash); + $node['y'] = ($value['y'] + ($map_manager->map['center_y'] / 2) / $z_dash); + $node['refresh'] = 0; + + db_process_sql_update( + 'titem', + $node, + [ + 'source_data' => $value['source_data'], + 'id_map' => $id_map, + ] + ); + } + } + + echo $id_map; + + return; + } if ($get_reset_map_form) { $map_id = get_parameter('map_id'); @@ -937,6 +974,7 @@ if (is_ajax() === true) { } if ($refresh_holding_area) { + ob_start(); $networkmap_id = (int) get_parameter('id', 0); $x = (int) get_parameter('x', 666); $y = (int) get_parameter('y', 666); @@ -944,12 +982,11 @@ if (is_ajax() === true) { $return['correct'] = false; $return['holding_area'] = []; - // ACL for the network map + // ACL for the network map. $id_group = db_get_value('id_group', 'tmap', 'id', $networkmap_id); // $networkmap_read = check_acl ($config['id_user'], $id_group, "MR"); $networkmap_write = check_acl($config['id_user'], $id_group, 'MW'); $networkmap_manage = check_acl($config['id_user'], $id_group, 'MM'); - if (!$networkmap_write && !$networkmap_manage) { db_pandora_audit( AUDIT_LOG_ACL_VIOLATION, @@ -966,6 +1003,8 @@ if (is_ajax() === true) { $return['holding_area'] = $data; } + ob_end_clean(); + echo json_encode($return); return; @@ -2268,6 +2307,10 @@ if ($networkmap === false) { ] ).'', ]; + $buttons['test'] = [ + 'active' => false, + 'text' => '
', + ]; } else { if (!$dash_mode) { $buttons['screen'] = [ @@ -2292,6 +2335,21 @@ if ($networkmap === false) { ] ).'', ]; + $buttons['option'] = [ + 'active' => false, + 'text' => ''.html_print_image( + 'images/setup.png', + true, + [ + 'title' => __('Options'), + 'class' => 'invert_filter', + ] + ).'', + ]; + $buttons['test'] = [ + 'active' => false, + 'text' => '
', + ]; } } @@ -2311,8 +2369,15 @@ if ($networkmap === false) { include_once $config['homedir'].'/include/class/NetworkMap.class.php'; + $filter = json_decode($networkmap['filter'], true); + $zoom = $filter['z_dash']; + $map_manager = new NetworkMap( - [ 'id_map' => $networkmap['id']] + [ + 'id_map' => $networkmap['id'], + 'center_x' => $networkmap['center_x'], + 'center_y' => $networkmap['center_y'], + ] ); $map_manager->printMap(); diff --git a/pandora_console/pandoradb.sql b/pandora_console/pandoradb.sql index 8e794fb15d..13b22090ed 100644 --- a/pandora_console/pandoradb.sql +++ b/pandora_console/pandoradb.sql @@ -2322,6 +2322,7 @@ CREATE TABLE IF NOT EXISTS `tmap` ( `generated` INT UNSIGNED NOT NULL DEFAULT 0, `filter` TEXT, `id_group_map` INT UNSIGNED NOT NULL DEFAULT 0, + `refresh_time` INT UNSIGNED NOT NULL DEFAULT 0, PRIMARY KEY(`id`) ) ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4; diff --git a/pandora_server/lib/PandoraFMS/Recon/Base.pm b/pandora_server/lib/PandoraFMS/Recon/Base.pm index 5fa1dd8d1c..00f778e9e4 100644 --- a/pandora_server/lib/PandoraFMS/Recon/Base.pm +++ b/pandora_server/lib/PandoraFMS/Recon/Base.pm @@ -42,7 +42,7 @@ use constant { DISCOVERY_DEPLOY_AGENTS => 9, DISCOVERY_APP_SAP => 10, DISCOVERY_APP_DB2 => 11, - DISCOVERY_APP_MICROSOFT_SQL_SERVER => 12, + DISCOVERY_APP_MICROSOFT_SQL_SERVER => 12, DISCOVERY_REVIEW => 0, DISCOVERY_STANDARD => 1, DISCOVERY_RESULTS => 2, @@ -151,6 +151,9 @@ sub new { # Found parents. parents => {}, + # Port counts for each switch. + ports => {}, + # Route cache. routes => [], default_gw => undef, @@ -366,14 +369,17 @@ sub add_iface($$$) { ################################################################################ # Discover connectivity from address forwarding tables. ################################################################################ -sub aft_connectivity($$) { - my ($self, $switch) = @_; +sub aft_connectivity($$$) { + my ($self, $switch, $single_port) = @_; my (%mac_temp, @aft_temp); return unless ($self->is_snmp_discovered($switch)); $self->enable_vlan_cache(); + # Fill port counts if needed. + $self->fill_port_counts($switch); + # Get the address forwarding table (AFT) of each switch. my @aft; foreach my $mac ($self->snmp_get_value_array($switch, $DOT1DTPFDBADDRESS)) { @@ -392,7 +398,7 @@ sub aft_connectivity($$) { $host_if_name = defined($host_if_name) ? $host_if_name : 'Host Alive'; # Get the interface associated to the port were we found the MAC address. - my $switch_if_name = $self->get_if_from_aft($switch, $aft_mac); + my $switch_if_name = $self->get_if_from_aft($switch, $aft_mac, $single_port); next unless defined($switch_if_name) and ($switch_if_name ne ''); # Do not connect a host to a switch twice using the same interface. @@ -771,13 +777,29 @@ sub get_iface($$) { ################################################################################ # Get an interface name from an AFT entry. Returns undef on error. ################################################################################ -sub get_if_from_aft($$$) { - my ($self, $switch, $mac) = @_; +sub get_if_from_aft($$$$) { + my ($self, $switch, $mac, $single_port) = @_; # Get the port associated to the MAC. my $port = $self->snmp_get_value($switch, "$DOT1DTPFDBPORT." . mac_to_dec($mac)); return '' unless defined($port); + # Are we looking for interfaces with a single port entry? + if ($single_port == 1 && + defined($self->{'ports'}->{$switch}) && + defined($self->{'ports'}->{$switch}->{$port}) && + $self->{'ports'}->{$switch}->{$port} > 1) { + return ''; + } + + # Are we looking for interfaces with multiple port entries? + if ($single_port == 0 && + defined($self->{'ports'}->{$switch}) && + defined($self->{'ports'}->{$switch}->{$port}) && + $self->{'ports'}->{$switch}->{$port} <= 1) { + return ''; + } + # Get the interface index associated to the port. my $if_index = $self->snmp_get_value($switch, "$DOT1DBASEPORTIFINDEX.$port"); return '' unless defined($if_index); @@ -936,6 +958,24 @@ sub get_mac_from_ip($$) { $self->call('message', "Found MAC $mac for host $host in the local ARP cache.", 5); } +################################################################################ +# Find out the number of entries for each port on the given switch. +################################################################################ +sub fill_port_counts($$) { + my ($self, $switch) = @_; + + return if (defined($self->{'ports'}->{$switch})); + + # List all the ports. + foreach my $port ($self->snmp_get_value_array($switch, $DOT1DTPFDBPORT)) { + if (!defined($self->{'ports'}->{$switch}->{$port})) { + $self->{'ports'}->{$switch}->{$port} = 1; + } else { + $self->{'ports'}->{$switch}->{$port} += 1; + } + } +} + ################################################################################ # Get a port number from an AFT entry. Returns undef on error. ################################################################################ @@ -1992,11 +2032,20 @@ sub scan($) { $self->call('message', "[2/6] Finding address forwarding table connectivity...", 3); $self->{'c_network_name'} = ''; $self->{'step'} = STEP_AFT; - ($progress, $step) = (50, 10.0 / scalar(@hosts)); # From 50% to 60%. + ($progress, $step) = (50, (10.0 / scalar(@hosts)) / 2.0); # From 50% to 60%. + + # Connect hosts on ports where there are no other hosts. for (my $i = 0; defined($hosts[$i]); $i++) { $self->call('update_progress', $progress); $progress += $step; - $self->aft_connectivity($hosts[$i]); + $self->aft_connectivity($hosts[$i], 1); + } + + # Connect hosts on ports even if they're shared by other hosts. + for (my $i = 0; defined($hosts[$i]); $i++) { + $self->call('update_progress', $progress); + $progress += $step; + $self->aft_connectivity($hosts[$i], 0); } # Connect hosts that are still unconnected using traceroute.