WIP NetworkMap class

Former-commit-id: ae987e5f6f3ec0997746093d20f7dbd5758c9ff1
This commit is contained in:
fbsanchez 2019-03-12 12:05:54 +01:00
parent c6fa365b90
commit d7983bec4e
4 changed files with 237 additions and 114 deletions

View File

@ -29,6 +29,7 @@
require_once $config['homedir'].'/include/graphs/functions_d3.php'; require_once $config['homedir'].'/include/graphs/functions_d3.php';
$progress_task_discovery = (bool) get_parameter('progress_task_discovery', 0); $progress_task_discovery = (bool) get_parameter('progress_task_discovery', 0);
$showmap = (bool) get_parameter('showmap', 0);
if ($progress_task_discovery) { if ($progress_task_discovery) {
$id_task = get_parameter('id', 0); $id_task = get_parameter('id', 0);
@ -72,3 +73,13 @@ if ($progress_task_discovery) {
return; return;
} }
if ($showmap) {
include_once $config['homedir'].'/include/class/NetworkMap.class.php';
$id_task = get_parameter('id', 0);
$map = new NetworkMap(
['id_task' => $id_task]
);
$map->printMap();
}

View File

@ -170,29 +170,41 @@ class NetworkMap
]; ];
if (is_array($options)) { if (is_array($options)) {
// Previously nodes_and_relations.
if (isset($options['graph'])) { if (isset($options['graph'])) {
$this->graph = $options['graph']; $this->graph = $options['graph'];
} }
// String dotmap.
if (isset($options['dot_graph'])) {
$this->dotGraph = $options['dot_graph'];
}
// Array of nodes, agents, virtual, etc.
if (isset($options['nodes'])) { if (isset($options['nodes'])) {
$this->nodes = $options['nodes']; $this->nodes = $options['nodes'];
} }
// Array of relations.
if (isset($options['relations'])) { if (isset($options['relations'])) {
$this->relations = $options['relations']; $this->relations = $options['relations'];
} }
// User interface type. Simple or advanced.
if (isset($options['mode'])) { if (isset($options['mode'])) {
$this->mode = $options['mode']; $this->mode = $options['mode'];
} }
// Map options, check default values above.
// This is only used while generating new maps using
// (generateDotGraph).
if (is_array($options['map_options'])) { if (is_array($options['map_options'])) {
foreach ($options['map_options'] as $k => $v) { foreach ($options['map_options'] as $k => $v) {
$this->mapOptions[$k] = $v; $this->mapOptions[$k] = $v;
} }
} }
// Load from Discovery task. // Load from tmap.
if ($options['id_map']) { if ($options['id_map']) {
$this->idMap = $options['id_map']; $this->idMap = $options['id_map'];
// Update nodes and relations. // Update nodes and relations.
@ -204,6 +216,7 @@ class NetworkMap
$this->createMap(); $this->createMap();
} }
} else { } else {
// Generate from group, task or network.
if ($options['id_group']) { if ($options['id_group']) {
$this->idGroup = $options['id_group']; $this->idGroup = $options['id_group'];
} }
@ -238,22 +251,40 @@ class NetworkMap
*/ */
public function createMap() public function createMap()
{ {
// If exists, load from DB.
if ($this->idMap) { if ($this->idMap) {
$this->loadMap(); $this->loadMap();
return; return;
} }
if ($this->network) { // Simulated map.
$this->nodes = networkmap_get_new_nodes_from_ip_mask( $this->idMap = uniqid();
$this->network // No tmap definition. Paint data.
if ($this->idTask) {
$recon_task = db_get_row_filter(
'trecon_task',
['id_rt' => $networkmap['source_data']]
); );
$this->network = $recon_task['subnet'];
} }
if ($this->idTask) { // Simulate map entry.
// Retrieve data from target task. $this->map = [
$this->loadMap(); 'id' => $this->idMap,
} '__simulated' => 1,
'background' => '',
'background_options' => 0,
'source_period' => 60,
'filter' => $this->mapOptions['map_filter'],
'width' => 900,
'height' => 400,
'center_x' => 450,
'center_y' => 200,
];
$this->graph = $this->generateNetworkMap();
} }
@ -273,33 +304,6 @@ class NetworkMap
// Nodes and relations. // Nodes and relations.
$this->graph = networkmap_process_networkmap($this->idMap); $this->graph = networkmap_process_networkmap($this->idMap);
} else {
// Simulated map.
$this->idMap = uniqid();
// No tmap definition. Paint data.
if ($this->idTask) {
$recon_task = db_get_row_filter(
'trecon_task',
['id_rt' => $networkmap['source_data']]
);
$this->network = $recon_task['subnet'];
}
// Simulate map entry.
$this->map = [
'id' => $this->idMap,
'__simulated' => 1,
'background' => '',
'background_options' => 0,
'source_period' => 60,
'filter' => $this->mapOptions['map_filter'],
'width' => 900,
'height' => 400,
'center_x' => 450,
'center_y' => 200,
];
$this->graph = $this->generateNetworkMap();
} }
} }
@ -330,6 +334,46 @@ class NetworkMap
} }
/**
* Generate a graphviz string structure to be used later.
*
* @return void
*/
public function generateDotGraph()
{
if (!isset($this->dotGraph)) {
// Generate dot file.
$this->dotGraph = networkmap_generate_dot(
get_product_name(),
$this->idGroup,
$this->mapOptions['simple'],
$this->mapOptions['font_size'],
$this->mapOptions['layout'],
$this->mapOptions['nooverlap'],
$this->mapOptions['zoom'],
$this->mapOptions['ranksep'],
$this->mapOptions['center'],
$this->mapOptions['regen'],
$this->mapOptions['pure'],
$this->mapOptions['id'],
$this->mapOptions['show_snmp_modules'],
$this->mapOptions['cut_names'],
$this->mapOptions['relative'],
$this->mapOptions['text_filter'],
$this->network,
$this->mapOptions['dont_show_subgroups'],
// Strict user (strict_user).
false,
// Canvas size (size_canvas).
null,
$this->mapOptions['old_mode'],
$this->mapOptions['map_filter']
);
}
}
/** /**
* Generates a nodes - relationships array using graphviz dot * Generates a nodes - relationships array using graphviz dot
* schema. * schema.
@ -338,6 +382,10 @@ class NetworkMap
*/ */
public function generateNetworkMap() public function generateNetworkMap()
{ {
if (!isset($this->dotGraph)) {
$this->generateDotGraph();
}
/* /*
* Let graphviz place the nodes. * Let graphviz place the nodes.
*/ */
@ -349,56 +397,27 @@ class NetworkMap
break; break;
case 1: case 1:
$filter = 'dot'; $filter = 'dot';
$layout = 'flat'; $layout = 'flat';
break; break;
case 2: case 2:
$filter = 'twopi'; $filter = 'twopi';
$layout = 'radial'; $layout = 'radial';
break; break;
case 3: case 3:
default: default:
$filter = 'neato'; $filter = 'neato';
$layout = 'spring1'; $layout = 'spring1';
break; break;
case 4: case 4:
$filter = 'fdp'; $filter = 'fdp';
$layout = 'spring2'; $layout = 'spring2';
break; break;
} }
$nodes_and_relations = [];
// Generate dot file.
$graph = networkmap_generate_dot(
get_product_name(),
$this->idGroup,
$this->mapOptions['simple'],
$this->mapOptions['font_size'],
$this->mapOptions['layout'],
$this->mapOptions['nooverlap'],
$this->mapOptions['zoom'],
$this->mapOptions['ranksep'],
$this->mapOptions['center'],
$this->mapOptions['regen'],
$this->mapOptions['pure'],
$this->mapOptions['id'],
$this->mapOptions['show_snmp_modules'],
$this->mapOptions['cut_names'],
$this->mapOptions['relative'],
$this->mapOptions['text_filter'],
$this->network,
$this->mapOptions['dont_show_subgroups'],
// Strict user (strict_user).
false,
// Canvas size (size_canvas).
null,
$this->mapOptions['old_mode'],
$this->mapOptions['map_filter']
);
switch (PHP_OS) { switch (PHP_OS) {
case 'WIN32': case 'WIN32':
case 'WINNT': case 'WINNT':
@ -421,7 +440,7 @@ class NetworkMap
$filename_dot .= '_'.$this->idMap.'.dot'; $filename_dot .= '_'.$this->idMap.'.dot';
file_put_contents($filename_dot, $graph); file_put_contents($filename_dot, $this->dotGraph);
switch (PHP_OS) { switch (PHP_OS) {
case 'WIN32': case 'WIN32':
@ -449,13 +468,11 @@ class NetworkMap
$this->idMap, $this->idMap,
$filename_plain, $filename_plain,
$relation_nodes, $relation_nodes,
$graph $this->dotGraph
); );
unlink($filename_plain); unlink($filename_plain);
$id = $this->idMap;
/* /*
* Graphviz section ends here. * Graphviz section ends here.
*/ */
@ -485,7 +502,7 @@ class NetworkMap
$node_center = []; $node_center = [];
foreach ($nodes as $key => $node) { foreach ($nodes as $key => $node) {
$nodes_and_relations['nodes'][$index]['id'] = $node['id']; $nodes_and_relations['nodes'][$index]['id'] = $node['id'];
$nodes_and_relations['nodes'][$index]['id_map'] = $id; $nodes_and_relations['nodes'][$index]['id_map'] = $this->idMap;
$children_count = 0; $children_count = 0;
foreach ($relation_nodes as $relation) { foreach ($relation_nodes as $relation) {
@ -532,7 +549,7 @@ class NetworkMap
$nodes_and_relations['relations'] = []; $nodes_and_relations['relations'] = [];
$index = 0; $index = 0;
foreach ($relation_nodes as $relation) { foreach ($relation_nodes as $relation) {
$nodes_and_relations['relations'][$index]['id_map'] = $id; $nodes_and_relations['relations'][$index]['id_map'] = $this->idMap;
if (($relation['parent_type'] == 'agent') || ($relation['parent_type'] == '')) { if (($relation['parent_type'] == 'agent') || ($relation['parent_type'] == '')) {
$nodes_and_relations['relations'][$index]['id_parent'] = $relation['id_parent']; $nodes_and_relations['relations'][$index]['id_parent'] = $relation['id_parent'];
@ -565,34 +582,33 @@ class NetworkMap
$index++; $index++;
} }
if ($this->idMap > 0) { if ($this->idMap > 0 && (!isset($this->map['__simulated']))) {
enterprise_hook( enterprise_hook(
'save_generate_nodes', 'save_generate_nodes',
[ [
$id, $this->idMap,
$nodes_and_relations, $nodes_and_relations,
] ]
); );
$pandorafms_node = $nodes_and_relations['nodes'][0];
$center = [ $center = [
'x' => $node_center['x'], 'x' => $node_center['x'],
'y' => $node_center['y'], 'y' => $node_center['y'],
]; ];
$networkmap['center_x'] = $center['x']; $this->map['center_x'] = $center['x'];
$networkmap['center_y'] = $center['y']; $this->map['center_y'] = $center['y'];
db_process_sql_update( db_process_sql_update(
'tmap', 'tmap',
[ [
'center_x' => $networkmap['center_x'], 'center_x' => $this->map['center_x'],
'center_y' => $networkmap['center_y'], 'center_y' => $this->map['center_y'],
], ],
['id' => $id] ['id' => $this->idMap]
); );
} else { } else {
$this->map['center_x'] = $center['x']; $this->map['center_x'] = $node_center['x'];
$this->map['center_y'] = $center['y']; $this->map['center_y'] = $node_center['y'];
} }
return $nodes_and_relations; return $nodes_and_relations;
@ -633,11 +649,14 @@ class NetworkMap
{ {
$networkmap = $this->map; $networkmap = $this->map;
$simulate = false;
if (!isset($networkmap['__simulated'])) { if (!isset($networkmap['__simulated'])) {
$networkmap['filter'] = json_decode( $networkmap['filter'] = json_decode(
$networkmap['filter'], $networkmap['filter'],
true true
); );
} else {
$simulate = true;
} }
// Hardcoded. // Hardcoded.
@ -719,7 +738,8 @@ class NetworkMap
$item = networkmap_db_node_to_js_node( $item = networkmap_db_node_to_js_node(
$node, $node,
$count, $count,
$count_item_holding_area $count_item_holding_area,
$simulate
); );
if ($item['deleted']) { if ($item['deleted']) {
continue; continue;
@ -739,7 +759,11 @@ class NetworkMap
// interfaces. // interfaces.
networkmap_clean_relations_for_js($relations); networkmap_clean_relations_for_js($relations);
$links_js = networkmap_links_to_js_links($relations, $nodes_graph); $links_js = networkmap_links_to_js_links(
$relations,
$nodes_graph,
$simulate
);
$array_aux = []; $array_aux = [];
foreach ($links_js as $link_js) { foreach ($links_js as $link_js) {
@ -1404,8 +1428,7 @@ class NetworkMap
$output .= $this->loadController(); $output .= $this->loadController();
$output .= $this->loadAdvancedInterface(); $output .= $this->loadAdvancedInterface();
} else { } else {
// Simple mode, no tmap entries. // Simulated, no tmap entries.
$this->idMap = '0';
$output .= $this->loadMapSkel(); $output .= $this->loadMapSkel();
$output .= $this->loadMapData(); $output .= $this->loadMapData();
$output .= $this->loadController(); $output .= $this->loadController();

View File

@ -471,8 +471,22 @@ function get_networkmaps($id)
} }
function networkmap_db_node_to_js_node($node, &$count, &$count_item_holding_area) /**
{ * Translates node (nodes_and_relations) into JS node.
*
* @param array $node Node.
* @param integer $count Count.
* @param integer $count_item_holding_area Count_item_holding_area.
* @param boolean $simulated Simulated.
*
* @return array JS nodes.
*/
function networkmap_db_node_to_js_node(
$node,
&$count,
&$count_item_holding_area,
$simulated=false
) {
global $config; global $config;
$networkmap = db_get_row('tmap', 'id', $node['id_map']); $networkmap = db_get_row('tmap', 'id', $node['id_map']);
@ -492,7 +506,7 @@ function networkmap_db_node_to_js_node($node, &$count, &$count_item_holding_area
$item = []; $item = [];
$item['id'] = $count; $item['id'] = $count;
if (enterprise_installed()) { if (enterprise_installed() && $simulated === false) {
enterprise_include_once('include/functions_pandora_networkmap.php'); enterprise_include_once('include/functions_pandora_networkmap.php');
$item['id_db'] = $node['id_in_db']; $item['id_db'] = $node['id_in_db'];
} else { } else {
@ -670,29 +684,53 @@ function networkmap_clean_relations_for_js(&$relations)
} }
function networkmap_links_to_js_links($relations, $nodes_graph) /**
{ * Transform networkmap relations into js links.
*
* @param array $relations Relations.
* @param array $nodes_graph Nodes_graph.
* @param boolean $simulated Simulated.
*
* @return array JS relations.
*/
function networkmap_links_to_js_links(
$relations,
$nodes_graph,
$simulated=false
) {
$return = []; $return = [];
if (enterprise_installed()) { if (enterprise_installed() && $simulated === false) {
enterprise_include_once('include/functions_pandora_networkmap.php'); enterprise_include_once('include/functions_pandora_networkmap.php');
} }
$count = 0; $count = 0;
foreach ($relations as $key => $relation) { foreach ($relations as $key => $relation) {
if (($relation['parent_type'] == 1) && ($relation['child_type'] == 1)) { if (($relation['parent_type'] == 1) && ($relation['child_type'] == 1)) {
$id_target_agent = agents_get_agent_id_by_module_id($relation['id_parent_source_data']); $id_target_agent = agents_get_agent_id_by_module_id(
$id_source_agent = agents_get_agent_id_by_module_id($relation['id_child_source_data']); $relation['id_parent_source_data']
);
$id_source_agent = agents_get_agent_id_by_module_id(
$relation['id_child_source_data']
);
$id_target_module = $relation['id_parent_source_data']; $id_target_module = $relation['id_parent_source_data'];
$id_source_module = $relation['id_child_source_data']; $id_source_module = $relation['id_child_source_data'];
} else if (($relation['parent_type'] == 1) && ($relation['child_type'] == 0)) { } else if (($relation['parent_type'] == 1)
$id_target_agent = agents_get_agent_id_by_module_id($relation['id_parent_source_data']); && ($relation['child_type'] == 0)
) {
$id_target_agent = agents_get_agent_id_by_module_id(
$relation['id_parent_source_data']
);
$id_target_module = $relation['id_parent_source_data']; $id_target_module = $relation['id_parent_source_data'];
$id_source_agent = $relation['id_child_source_data']; $id_source_agent = $relation['id_child_source_data'];
} else if (($relation['parent_type'] == 0) && ($relation['child_type'] == 1)) { } else if (($relation['parent_type'] == 0)
&& ($relation['child_type'] == 1)
) {
$id_target_agent = $relation['id_parent_source_data']; $id_target_agent = $relation['id_parent_source_data'];
$id_source_module = $relation['id_child_source_data']; $id_source_module = $relation['id_child_source_data'];
$id_source_agent = agents_get_agent_id_by_module_id($relation['id_child_source_data']); $id_source_agent = agents_get_agent_id_by_module_id(
$relation['id_child_source_data']
);
} else { } else {
$id_target_agent = $relation['id_parent_source_data']; $id_target_agent = $relation['id_parent_source_data'];
$id_source_agent = $relation['id_child_source_data']; $id_source_agent = $relation['id_child_source_data'];
@ -701,7 +739,7 @@ function networkmap_links_to_js_links($relations, $nodes_graph)
$item = []; $item = [];
$item['id'] = $count; $item['id'] = $count;
$count++; $count++;
if (enterprise_installed()) { if (enterprise_installed() && $simulated === false) {
$item['id_db'] = get_relation_id($relation); $item['id_db'] = get_relation_id($relation);
} else { } else {
$item['id_db'] = $key; $item['id_db'] = $key;
@ -720,7 +758,7 @@ function networkmap_links_to_js_links($relations, $nodes_graph)
$item['source'] = -1; $item['source'] = -1;
$item['deleted'] = $relation['deleted']; $item['deleted'] = $relation['deleted'];
if (enterprise_installed()) { if (enterprise_installed() && $simulated === false) {
$target_and_source = []; $target_and_source = [];
$target_and_source = get_id_target_and_source_in_db($relation); $target_and_source = get_id_target_and_source_in_db($relation);
$item['target_id_db'] = (int) $target_and_source['target']; $item['target_id_db'] = (int) $target_and_source['target'];
@ -779,8 +817,12 @@ function networkmap_links_to_js_links($relations, $nodes_graph)
$item['link_color'] = '#FAD403'; $item['link_color'] = '#FAD403';
} }
$agent = agents_get_agent_id_by_module_id($relation['id_parent_source_data']); $agent = agents_get_agent_id_by_module_id(
$agent2 = agents_get_agent_id_by_module_id($relation['id_child_source_data']); $relation['id_parent_source_data']
);
$agent2 = agents_get_agent_id_by_module_id(
$relation['id_child_source_data']
);
foreach ($nodes_graph as $key2 => $node) { foreach ($nodes_graph as $key2 => $node) {
if (isset($node['id_agent'])) { if (isset($node['id_agent'])) {
if ($node['id_agent'] == $agent) { if ($node['id_agent'] == $agent) {
@ -805,7 +847,9 @@ function networkmap_links_to_js_links($relations, $nodes_graph)
$item['link_color'] = '#FAD403'; $item['link_color'] = '#FAD403';
} }
$agent2 = agents_get_agent_id_by_module_id($relation['id_child_source_data']); $agent2 = agents_get_agent_id_by_module_id(
$relation['id_child_source_data']
);
foreach ($nodes_graph as $key2 => $node) { foreach ($nodes_graph as $key2 => $node) {
if (isset($node['id_agent'])) { if (isset($node['id_agent'])) {
if ($node['id_agent'] == $relation['id_parent_source_data']) { if ($node['id_agent'] == $relation['id_parent_source_data']) {
@ -830,7 +874,9 @@ function networkmap_links_to_js_links($relations, $nodes_graph)
$item['link_color'] = '#FAD403'; $item['link_color'] = '#FAD403';
} }
$agent = agents_get_agent_id_by_module_id($relation['id_parent_source_data']); $agent = agents_get_agent_id_by_module_id(
$relation['id_parent_source_data']
);
foreach ($nodes_graph as $key2 => $node) { foreach ($nodes_graph as $key2 => $node) {
if (isset($node['id_agent'])) { if (isset($node['id_agent'])) {
if ($node['id_agent'] == $agent) { if ($node['id_agent'] == $agent) {
@ -848,7 +894,9 @@ function networkmap_links_to_js_links($relations, $nodes_graph)
} }
} }
} }
} else if (($relation['parent_type'] == 3) && ($relation['child_type'] == 3)) { } else if (($relation['parent_type'] == 3)
&& ($relation['child_type'] == 3)
) {
foreach ($nodes_graph as $key2 => $node) { foreach ($nodes_graph as $key2 => $node) {
if ($relation['id_parent'] == $node['id_db']) { if ($relation['id_parent'] == $node['id_db']) {
$agent = $node['id_db']; $agent = $node['id_db'];
@ -860,7 +908,9 @@ function networkmap_links_to_js_links($relations, $nodes_graph)
$agent2 = $node['id_db']; $agent2 = $node['id_db'];
} }
} }
} else if (($relation['parent_type'] == 3) || ($relation['child_type'] == 3)) { } else if (($relation['parent_type'] == 3)
|| ($relation['child_type'] == 3)
) {
if ($relation['parent_type'] == 3) { if ($relation['parent_type'] == 3) {
foreach ($nodes_graph as $key2 => $node) { foreach ($nodes_graph as $key2 => $node) {
if ($relation['id_parent'] == $node['id_db']) { if ($relation['id_parent'] == $node['id_db']) {
@ -898,7 +948,10 @@ function networkmap_links_to_js_links($relations, $nodes_graph)
} }
} }
if ((($item['target'] == -1) || ($item['source'] == -1)) && $relation['parent_type'] == 1 && $relation['child_type'] == 1) { if ((($item['target'] == -1) || ($item['source'] == -1))
&& $relation['parent_type'] == 1
&& $relation['child_type'] == 1
) {
continue; continue;
} }
@ -1112,7 +1165,10 @@ function networkmap_loadfile(
) { ) {
global $config; global $config;
$height_map = db_get_value('height', 'tmap', 'id', $id); $height_map = 200;
if ((int) $id > 0) {
$height_map = db_get_value('height', 'tmap', 'id', $id);
}
$networkmap_nodes = []; $networkmap_nodes = [];

View File

@ -31,3 +31,36 @@ function progress_task_list(id, name, url) {
} }
}); });
} }
function show_map(id, name, url) {
var params = [];
params.push("page=include/ajax/task_list.ajax");
params.push("showmap=1");
params.push("id=" + id);
$("#progress_task")
.empty()
.hide()
.append("<p>Loading map</p>")
.dialog({
title: "Task: " + name,
resizable: true,
draggable: true,
modal: false,
width: 1280,
height: 700
})
.show();
jQuery.ajax({
data: params.join("&"),
type: "POST",
url: (action = url),
dataType: "html",
success: function(data) {
$("#progress_task")
.empty()
.append(data);
}
});
}