From 4854d4b2df9d4a131a888b2f1d51bccf3c9e6075 Mon Sep 17 00:00:00 2001 From: fbsanchez <fborja.sanchez@artica.es> Date: Fri, 29 Mar 2019 20:31:55 +0100 Subject: [PATCH 01/31] WIP atomic JS map Former-commit-id: 95736d11295948e5dc20aefcf1293b7882729588 --- .../include/class/NetworkMap.class.php | 122 ++++++++++++------ 1 file changed, 82 insertions(+), 40 deletions(-) diff --git a/pandora_console/include/class/NetworkMap.class.php b/pandora_console/include/class/NetworkMap.class.php index 17133d4d65..ecb92a59a7 100644 --- a/pandora_console/include/class/NetworkMap.class.php +++ b/pandora_console/include/class/NetworkMap.class.php @@ -34,9 +34,9 @@ enterprise_include_once('include/functions_networkmap.php'); enterprise_include_once('include/functions_discovery.php'); // Avoid node overlapping. -define('GRAPHVIZ_RADIUS_CONVERSION_FACTOR', 20); -define('MAP_X_CORRECTION', 600); -define('MAP_Y_CORRECTION', 150); +define('GRAPHVIZ_CONVERSION_FACTOR', 30); +define('MAP_X_CORRECTION', 0); +define('MAP_Y_CORRECTION', 0); /** @@ -319,6 +319,8 @@ class NetworkMap // Default mapOptions values. // Defines the command to generate positions. $this->mapOptions['generation_method'] = LAYOUT_SPRING1; + // Use fixed positions defined (X,Y) per node. + $this->mapOptions['fixed_positions'] = 0; $this->mapOptions['width'] = $config['networkmap_max_width']; $this->mapOptions['height'] = $config['networkmap_max_width']; $this->mapOptions['simple'] = 0; @@ -999,23 +1001,25 @@ class NetworkMap case NODE_GENERIC: // Handmade ones. // Add also parent relationship. - $parent_id = $node['id_parent']; + if (isset($node['id_parent'])) { + $parent_id = $node['id_parent']; - if ((int) $parent_id > 0) { - $parent_node = $this->getNodeData( - (int) $parent_id, - 'id_node' - ); - } + if ((int) $parent_id >= 0) { + $parent_node = $this->getNodeData( + (int) $parent_id, + 'id_node' + ); + } - // Store relationship. - if ($parent_node) { - $relations[] = [ - 'id_parent' => $parent_node, - 'parent_type' => NODE_GENERIC, - 'id_child' => $node['id_node'], - 'child_type' => NODE_GENERIC, - ]; + // Store relationship. + if ($parent_node !== null) { + $relations[] = [ + 'id_parent' => $parent_node, + 'parent_type' => NODE_GENERIC, + 'id_child' => $node['id_node'], + 'child_type' => NODE_GENERIC, + ]; + } } break; @@ -1233,8 +1237,13 @@ class NetworkMap $url = 'none'; $parent = $data['parent']; $font_size = $this->mapOptions['font_size']; - $radius = $this->mapOptions['map_filter']['node_radius']; - $radius /= GRAPHVIZ_RADIUS_CONVERSION_FACTOR; + if (isset($data['radius'])) { + $radius = $data['radius']; + } else { + $radius = $this->mapOptions['map_filter']['node_radius']; + } + + $radius /= GRAPHVIZ_CONVERSION_FACTOR; if (strlen($label) > 16) { $label = ui_print_truncate_text($label, 16, false, true, false); @@ -1632,7 +1641,7 @@ class NetworkMap $node[$k] = $v; } - $node['style']['label'] = $node['name']; + $node['style']['label'] = $node['label']; $node['style']['shape'] = 'circle'; $item['color'] = self::getColorByStatus($node['status']); break; @@ -1660,6 +1669,11 @@ class NetworkMap $count_item_holding_area++; } + // Propagate styles. + foreach ($node['style'] as $k => $v) { + $item[$k] = $v; + } + // Node image. $item['image_url'] = ''; $item['image_width'] = 0; @@ -1679,6 +1693,7 @@ class NetworkMap $item['text'] = io_safe_output($node['style']['label']); $item['shape'] = $node['style']['shape']; $item['map_id'] = $node['id_map']; + if (!isset($node['style']['id_networkmap']) || $node['style']['id_networkmap'] == '' || $node['style']['id_networkmap'] == 0 @@ -1694,8 +1709,6 @@ class NetworkMap $item['image'] = $item['image_url']; $item['image_height'] = 52; $item['image_width'] = 52; - $item['width'] = $this->mapOptions['map_filter']['node_radius']; - $item['height'] = $this->mapOptions['map_filter']['node_radius']; } $return[] = $item; @@ -2148,8 +2161,8 @@ class NetworkMap if (preg_match('/^graph.*$/', $line) != 0) { // Graph definition. $fields = explode(' ', $line); - $this->map['width'] = ($fields[2] * 10 * GRAPHVIZ_RADIUS_CONVERSION_FACTOR); - $this->map['height'] = ($fields[3] * 10 * GRAPHVIZ_RADIUS_CONVERSION_FACTOR); + $this->map['width'] = ($fields[2] * GRAPHVIZ_CONVERSION_FACTOR); + $this->map['height'] = ($fields[3] * GRAPHVIZ_CONVERSION_FACTOR); if ($this->map['width'] > $config['networkmap_max_width']) { $this->map['width'] = $config['networkmap_max_width']; @@ -2162,8 +2175,8 @@ class NetworkMap // Node. $fields = explode(' ', $line); $id = $fields[1]; - $nodes[$id]['x'] = (($fields[2] * $this->mapOptions['map_filter']['node_radius']) - $this->mapOptions['map_filter']['rank_sep'] * GRAPHVIZ_RADIUS_CONVERSION_FACTOR); - $nodes[$id]['y'] = (($fields[3] * $this->mapOptions['map_filter']['node_radius']) - $this->mapOptions['map_filter']['rank_sep'] * GRAPHVIZ_RADIUS_CONVERSION_FACTOR); + $nodes[$id]['x'] = ($fields[2] * GRAPHVIZ_CONVERSION_FACTOR); + $nodes[$id]['y'] = ($fields[3] * GRAPHVIZ_CONVERSION_FACTOR); } else if (preg_match('/^edge.*$/', $line) != 0 && empty($this->relations) === true ) { @@ -2401,7 +2414,14 @@ class NetworkMap * Calculate X,Y positions. */ - $graph = $this->calculateCoords(); + if (!$this->mapOptions['fixed_positions']) { + $graph = $this->calculateCoords(); + } else { + // Set by user. + $graph['nodes'] = $this->rawNodes; + $this->map['width'] = $this->mapOptions['width']; + $this->map['height'] = $this->mapOptions['height']; + } if (is_array($graph) === true) { $nodes = $graph['nodes']; @@ -2501,6 +2521,10 @@ class NetworkMap $style['image'] = $node_tmp['image']; $style['width'] = $node_tmp['width']; $style['height'] = $node_tmp['height']; + $style['radius'] = max( + $style['width'], + $style['height'] + ); $style['label'] = $node_tmp['text']; $node_tmp['style'] = json_encode($style); @@ -2676,6 +2700,7 @@ class NetworkMap $nodes = []; } + $this->nodes = $nodes; $nodes_js = $this->nodesToJS($nodes); $output .= 'networkmap.nodes = ('.json_encode($nodes_js).");\n"; @@ -2685,6 +2710,7 @@ class NetworkMap $relations = []; } + $this->relations = $relations; $links_js = $this->edgeToJS($relations); $output .= 'networkmap.links = ('.json_encode($links_js).");\n"; @@ -3220,17 +3246,25 @@ class NetworkMap if (enterprise_installed() && $this->useTooltipster ) { + $nodes_js = $this->nodesToJS($this->nodes); + $links_js = $this->edgeToJS($this->relations); + $output .= '<script type="text/javascript"> - var nodes = networkmap.nodes; - var arrows = networkmap.links; - var width = networkmap_dimensions[0]; - var height = networkmap_dimensions[1]; - var font_size = '.$this->mapOptions['font_size'].'; - var custom_params = '.json_encode($this->tooltipParams).'; - var controller = null; - var homedir = "'.ui_get_full_url(false).'" $(function() { - controller = new SimpleMapController("#simple_map"); + controller = new SimpleMapController({ + map_width: '.$this->map['width'].', + map_height: '.$this->map['height'].', + id: "'.$this->idMap.'", + target: "#simple_map", + nodes: '.json_encode($nodes_js).', + arrows: '.json_encode($links_js).', + center_x: '.$this->map['center_x'].', + center_y: '.$this->map['center_y'].', + z_dash: '.$this->map['filter']['z_dash'].', + font_size: '.$this->mapOptions['font_size'].', + homedir: "'.ui_get_full_url(false).'", + custom_params: '.json_encode($this->tooltipParams).' + }); controller.init_map(); }); </script>'; @@ -3315,9 +3349,17 @@ class NetworkMap $output .= '<div id="simple_map" data-id="'.$this->idMap.'" '; $output .= 'style="border: 1px #ddd solid;'; - $output .= ' width:'.$this->mapOptions['width']; - $output .= ' ;height:'.$this->mapOptions['height'].'">'; - $output .= '<svg id="svg'.$this->idMap.'" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" pointer-events="all" width="'.$this->mapOptions['width'].'" height="'.$this->mapOptions['height'].'px">'; + + if ($this->fullSize) { + $output .= ' width:100%'; + $output .= ' ;height: 100%">'; + $output .= '<svg id="svg'.$this->idMap.'" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" pointer-events="all" width="100%" height="100%">'; + } else { + $output .= ' width:'.$this->mapOptions['width'].'px'; + $output .= ' ;height:'.$this->mapOptions['height'].'px">'; + $output .= '<svg id="svg'.$this->idMap.'" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" pointer-events="all" width="'.$this->mapOptions['width'].'" height="'.$this->mapOptions['height'].'px">'; + } + $output .= '</svg>'; $output .= '</div>'; } else { From b0a6ea74151aa2901a3ff690f2b7db3c1f638b8c Mon Sep 17 00:00:00 2001 From: fbsanchez <fborja.sanchez@artica.es> Date: Fri, 29 Mar 2019 20:52:51 +0100 Subject: [PATCH 02/31] WIP atomic JS map. Minor fix to keep working Former-commit-id: fee809008311942f1d9ad14aea70ba78e3d6eb3a --- .../include/class/NetworkMap.class.php | 57 +++++++++++++------ 1 file changed, 40 insertions(+), 17 deletions(-) diff --git a/pandora_console/include/class/NetworkMap.class.php b/pandora_console/include/class/NetworkMap.class.php index ecb92a59a7..825ace8ae6 100644 --- a/pandora_console/include/class/NetworkMap.class.php +++ b/pandora_console/include/class/NetworkMap.class.php @@ -191,6 +191,20 @@ class NetworkMap */ public $relations; + /** + * Private nodes converted to JS. + * + * @var array + */ + private $nodesJS; + + /** + * Private relations converted to JS. + * + * @var array + */ + private $relationsJS; + /** * Include a Pandora (or vendor) node or not. * @@ -1604,6 +1618,11 @@ class NetworkMap $node['style'] = json_decode($node['style'], true); } + // Propagate styles. + foreach ($node['style'] as $k => $v) { + $item[$k] = $v; + } + $item['type'] = $node['type']; $item['fixed'] = true; $item['x'] = (int) $node['x']; @@ -1643,7 +1662,13 @@ class NetworkMap $node['style']['label'] = $node['label']; $node['style']['shape'] = 'circle'; - $item['color'] = self::getColorByStatus($node['status']); + if (isset($source_data['color'])) { + $item['color'] = $source_data['color']; + } else { + $item['color'] = self::getColorByStatus( + $node['status'] + ); + } break; } @@ -1669,11 +1694,6 @@ class NetworkMap $count_item_holding_area++; } - // Propagate styles. - foreach ($node['style'] as $k => $v) { - $item[$k] = $v; - } - // Node image. $item['image_url'] = ''; $item['image_width'] = 0; @@ -2700,9 +2720,13 @@ class NetworkMap $nodes = []; } - $this->nodes = $nodes; - $nodes_js = $this->nodesToJS($nodes); - $output .= 'networkmap.nodes = ('.json_encode($nodes_js).");\n"; + $this->nodesJS = $this->nodesToJS($nodes); + $output .= 'networkmap.nodes = ('.json_encode($this->nodesJS).");\n"; + + // Clean. + unset($this->nodes); + unset($this->rawNodes); + unset($this->nodeMapping); // Translate edges to js links. $relations = $this->graph['relations']; @@ -2710,9 +2734,11 @@ class NetworkMap $relations = []; } - $this->relations = $relations; - $links_js = $this->edgeToJS($relations); - $output .= 'networkmap.links = ('.json_encode($links_js).");\n"; + $this->relationsJS = $this->edgeToJS($relations); + $output .= 'networkmap.links = ('.json_encode($this->relationsJS).");\n"; + + // Clean. + unset($this->relations); $output .= ' //////////////////////////////////////////////////////////////////// @@ -3246,9 +3272,6 @@ class NetworkMap if (enterprise_installed() && $this->useTooltipster ) { - $nodes_js = $this->nodesToJS($this->nodes); - $links_js = $this->edgeToJS($this->relations); - $output .= '<script type="text/javascript"> $(function() { controller = new SimpleMapController({ @@ -3256,8 +3279,8 @@ class NetworkMap map_height: '.$this->map['height'].', id: "'.$this->idMap.'", target: "#simple_map", - nodes: '.json_encode($nodes_js).', - arrows: '.json_encode($links_js).', + nodes: '.json_encode($this->nodesJS).', + arrows: '.json_encode($this->relationsJS).', center_x: '.$this->map['center_x'].', center_y: '.$this->map['center_y'].', z_dash: '.$this->map['filter']['z_dash'].', From 11b2fbc2459f816bf4b560479b710ad8c97cf135 Mon Sep 17 00:00:00 2001 From: fbsanchez <fborja.sanchez@artica.es> Date: Tue, 2 Apr 2019 16:25:29 +0200 Subject: [PATCH 03/31] WIP db Former-commit-id: 3c231b9d90dc6c9fae5e7e398e829c8c28ffeed9 --- pandora_console/extras/mr/27.sql | 11 ++++++++++ .../godmode/wizards/Wizard.main.php | 7 ++++++- .../include/class/NetworkMap.class.php | 1 + pandora_console/include/constants.php | 20 +++++++++++++++++-- pandora_console/pandoradb.sql | 1 + pandora_console/pandoradb_data.sql | 7 +++---- pandora_server/lib/PandoraFMS/Recon/Base.pm | 8 +++++--- 7 files changed, 45 insertions(+), 10 deletions(-) create mode 100644 pandora_console/extras/mr/27.sql diff --git a/pandora_console/extras/mr/27.sql b/pandora_console/extras/mr/27.sql new file mode 100644 index 0000000000..5dc8a47d2f --- /dev/null +++ b/pandora_console/extras/mr/27.sql @@ -0,0 +1,11 @@ +START TRANSACTION; + +ALTER TABLE `trecon_script` ADD COLUMN `type` int NOT NULL default 0; + +UPDATE trecon_script SET `type` = 1 WHERE `name`="Discovery.Application.VMware"; +UPDATE trecon_script SET `type` = 2 WHERE `name`="Discovery.Application.MySQL"; +UPDATE trecon_script SET `type` = 3 WHERE `name`="Discovery.Application.Oracle"; +UPDATE trecon_script SET `type` = 100 WHERE `name`="Discovery.Cloud"; +UPDATE trecon_script SET `type` = 101 WHERE `name`="Discovery.Cloud.RDS"; + +COMMIT; \ No newline at end of file diff --git a/pandora_console/godmode/wizards/Wizard.main.php b/pandora_console/godmode/wizards/Wizard.main.php index 022402a8d1..d8a829e277 100644 --- a/pandora_console/godmode/wizards/Wizard.main.php +++ b/pandora_console/godmode/wizards/Wizard.main.php @@ -601,8 +601,13 @@ class Wizard } if (is_array($input['block_content']) === true) { + $label = ''; + if (isset($input['label'])) { + $label = $input['label']; + } + // Print independent block of inputs. - $output .= '<li id="'.$input['block_id'].'" class="'.$class.'">'; + $output .= '<li id="'.$input['block_id'].'" class="'.$class.'">'.$label; $output .= '<ul class="wizard">'; foreach ($input['block_content'] as $input) { $output .= $this->printBlock($input, $return); diff --git a/pandora_console/include/class/NetworkMap.class.php b/pandora_console/include/class/NetworkMap.class.php index 825ace8ae6..dba51499f4 100644 --- a/pandora_console/include/class/NetworkMap.class.php +++ b/pandora_console/include/class/NetworkMap.class.php @@ -2439,6 +2439,7 @@ class NetworkMap } else { // Set by user. $graph['nodes'] = $this->rawNodes; + $graph['relations'] = $this->relations; $this->map['width'] = $this->mapOptions['width']; $this->map['height'] = $this->mapOptions['height']; } diff --git a/pandora_console/include/constants.php b/pandora_console/include/constants.php index ea18c90d3f..ceb48d1d0f 100644 --- a/pandora_console/include/constants.php +++ b/pandora_console/include/constants.php @@ -583,8 +583,24 @@ define('NETWORKMAP_DEFAULT_HEIGHT', 800); // Discovery task types. define('DISCOVERY_HOSTDEVICES', 0); define('DISCOVERY_HOSTDEVICES_CUSTOM', 1); -define('DISCOVERY_CLOUD_AWS', 10); -define('DISCOVERY_APP_VMWARE', 100); +define('DISCOVERY_CLOUD_AWS', 2); +define('DISCOVERY_APP_VMWARE', 3); +define('DISCOVERY_APP_MYSQL', 4); +define('DISCOVERY_APP_ORACLE', 5); +define('DISCOVERY_CLOUD_AWS_EC2', 6); +define('DISCOVERY_CLOUD_AWS_RDS', 7); + + +// Discovery types matching definition. +define('DISCOVERY_SCRIPT_HOSTDEVICES_CUSTOM', 0); +// Standard applications. +define('DISCOVERY_SCRIPT_APP_VMWARE', 1); +define('DISCOVERY_SCRIPT_APP_MYSQL', 2); +define('DISCOVERY_SCRIPT_APP_ORACLE', 3); +// Cloud environments. +define('DISCOVERY_SCRIPT_CLOUD_AWS', 100); +define('DISCOVERY_SCRIPT_CLOUD_AWS_EC2', 101); +define('DISCOVERY_SCRIPT_CLOUD_AWS_RDS', 102); // Discovery task descriptions. define('CLOUDWIZARD_AWS_DESCRIPTION', 'Discovery.Cloud.AWS.EC2'); diff --git a/pandora_console/pandoradb.sql b/pandora_console/pandoradb.sql index 0ecc9b8f5d..d7c87538af 100644 --- a/pandora_console/pandoradb.sql +++ b/pandora_console/pandoradb.sql @@ -962,6 +962,7 @@ CREATE TABLE IF NOT EXISTS `trecon_script` ( `description` TEXT, `script` varchar(250) default '', `macros` TEXT, + `type` int NOT NULL default 0, PRIMARY KEY (`id_recon_script`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/pandora_console/pandoradb_data.sql b/pandora_console/pandoradb_data.sql index ee4ad45c06..4e30bdef7e 100644 --- a/pandora_console/pandoradb_data.sql +++ b/pandora_console/pandoradb_data.sql @@ -1135,10 +1135,9 @@ INSERT INTO `treport_custom_sql` (`id`, `name`, `sql`) VALUES (3, 'Monitoring&#x INSERT INTO `treport_custom_sql` (`id`, `name`, `sql`) VALUES (4, 'Group view', 'select t1.nombre, (select count(t3.id_agente) from tagente as t3 where t1.id_grupo = t3.id_grupo) as agents, (SELECT COUNT(t4.id_agente) FROM tagente as t4 WHERE t4.id_grupo = t1.id_grupo AND t4.disabled = 0 AND t4.ultimo_contacto < NOW() - (intervalo / (1/2))) as agent_unknown, (SELECT COUNT(tagente_estado.id_agente_estado) FROM tagente_estado, tagente, tagente_modulo WHERE tagente.id_grupo = t1.id_grupo AND tagente.disabled = 0 AND tagente.id_agente = tagente_estado.id_agente AND tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo AND tagente_modulo.disabled = 0 AND utimestamp > 0 AND tagente_modulo.id_tipo_modulo NOT IN(21,22,23,24,100) AND (UNIX_TIMESTAMP(NOW()) - tagente_estado.utimestamp) >= (tagente_estado.current_interval / (1/2))) as monitor_unknow, (SELECT COUNT(tagente_estado.id_agente_estado) FROM tagente_estado, tagente, tagente_modulo WHERE tagente.id_grupo = t1.id_grupo AND tagente.disabled = 0 AND tagente.id_agente = tagente_estado.id_agente AND tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo AND tagente_modulo.disabled = 0 AND tagente_modulo.id_tipo_modulo NOT IN (21,22,23,24) AND utimestamp = 0) as monitor_no_init, (SELECT COUNT(tagente_estado.id_agente_estado) FROM tagente_estado, tagente, tagente_modulo WHERE tagente.id_grupo = t1.id_grupo AND tagente.disabled = 0 AND tagente_estado.id_agente = tagente.id_agente AND tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo AND tagente_modulo.disabled = 0 AND estado = 0 AND ((UNIX_TIMESTAMP(NOW()) - tagente_estado.utimestamp) < (tagente_estado.current_interval / (1/2)) OR (tagente_modulo.id_tipo_modulo IN(21,22,23,24,100))) AND (utimestamp > 0 OR (tagente_modulo.id_tipo_modulo IN(21,22,23,24)))) as monitor_ok, (SELECT COUNT(tagente_estado.id_agente_estado) FROM tagente_estado, tagente, tagente_modulo WHERE tagente.id_grupo = t1.id_grupo AND tagente.disabled = 0 AND tagente_estado.id_agente = tagente.id_agente AND tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo AND tagente_modulo.disabled = 0 AND estado = 1 AND ((UNIX_TIMESTAMP(NOW()) - tagente_estado.utimestamp) < (tagente_estado.current_interval / (1/2)) OR (tagente_modulo.id_tipo_modulo IN(21,22,23,24,100))) AND utimestamp > 0) as monitor_critical, (SELECT COUNT(talert_template_modules.id) FROM talert_template_modules, tagente_modulo, tagente_estado, tagente WHERE tagente.id_grupo = t1.id_grupo AND tagente_modulo.id_agente = tagente.id_agente AND tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo AND tagente_modulo.disabled = 0 AND tagente.disabled = 0 AND talert_template_modules.id_agent_module = tagente_modulo.id_agente_modulo AND times_fired > 0) as monitor_alert_fired from tgrupo as t1 where 0 < (select count(t2.id_agente) from tagente as t2 where t1.id_grupo = t2.id_grupo)'); -- trecon scripts -INSERT INTO `trecon_script` VALUES (2,'IPMI Recon','Specific Pandora FMS Intel DCM Discovery (c) Artica ST 2011 <info@artica.es>

Usage: ./ipmi-recon.pl <task_id> <group_id> <create_incident_flag> <custom_field1> <custom_field2> <custom_field3> <custom_field4>

* custom_field1 = Network i.e.: 192.168.100.0/24
* custom_field2 = Username
* custom_field3 = Password
* custom_field4 = Additional parameters i.e.: -D LAN_2_0','/usr/share/pandora_server/util/recon_scripts/ipmi-recon.pl','{\"1\":{\"macro\":\"_field1_\",\"desc\":\"Network\",\"help\":\"i.e.: 192.168.100.0/24\",\"value\":\"\",\"hide\":\"\"},\"2\":{\"macro\":\"_field2_\",\"desc\":\"Username\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"3\":{\"macro\":\"_field3_\",\"desc\":\"Password\",\"help\":\"\",\"value\":\"\",\"hide\":\"1\"},\"4\":{\"macro\":\"_field4_\",\"desc\":\"Additional parameters\",\"help\":\"Optional additional parameters such as -D LAN_2_0 to use IPMI ver 2.0 instead of 1.5.  These options will also be passed to the IPMI plugin when the current values are read.\",\"value\":\"\",\"hide\":\"\"}}'); -INSERT INTO `trecon_script` VALUES (5,'WMI Recon Script','This script is used to automatically gather host information via WMI.
Available parameters:

* Network = network to scan (e.g. 192.168.100.0/24).
* WMI auth = comma separated list of WMI authentication tokens in the format username%password (e.g. Administrador%pass).

See the documentation for more information.','/usr/share/pandora_server/util/recon_scripts/wmi-recon.pl','{\"1\":{\"macro\":\"_field1_\",\"desc\":\"Network\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"2\":{\"macro\":\"_field2_\",\"desc\":\"WMI auth\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"}}'); -INSERT INTO `trecon_script` (`name`,`description`,`script`,`macros`) VALUES ('Discovery.Application.VMware', 'Discovery Application script to monitor VMware technologies (ESXi, VCenter, VSphere)', '/usr/share/pandora_server/util/recon_scripts/vmware-plugin.pl', '{"1":{"macro":"_field1_","desc":"Configuration file","help":"","value":"","hide":""}}'); -INSERT INTO `trecon_script` (`name`,`description`,`script`,`macros`) VALUES ('Discovery.Cloud', 'Discovery Cloud script to monitor Cloud technologies (AWS.EC2, AWS.S3, AWS.RDS, RDS,ȊWS.EKS)', '/usr/share/pandora_server/util/recon_scripts/pcm_client.pl', '{"1":{"macro":"_field1_","desc":"Configuration file","help":"","value":"","hide":""}}'); +INSERT INTO `trecon_script` (`type`,`name`,`description`,`script`,`macros`) VALUES (0, 'IPMI Recon','Specific Pandora FMS Intel DCM Discovery (c) Artica ST 2011 <info@artica.es>

Usage: ./ipmi-recon.pl <task_id> <group_id> <create_incident_flag> <custom_field1> <custom_field2> <custom_field3> <custom_field4>

* custom_field1 = Network i.e.: 192.168.100.0/24
* custom_field2 = Username
* custom_field3 = Password
* custom_field4 = Additional parameters i.e.: -D LAN_2_0','/usr/share/pandora_server/util/recon_scripts/ipmi-recon.pl','{\"1\":{\"macro\":\"_field1_\",\"desc\":\"Network\",\"help\":\"i.e.: 192.168.100.0/24\",\"value\":\"\",\"hide\":\"\"},\"2\":{\"macro\":\"_field2_\",\"desc\":\"Username\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"3\":{\"macro\":\"_field3_\",\"desc\":\"Password\",\"help\":\"\",\"value\":\"\",\"hide\":\"1\"},\"4\":{\"macro\":\"_field4_\",\"desc\":\"Additional parameters\",\"help\":\"Optional additional parameters such as -D LAN_2_0 to use IPMI ver 2.0 instead of 1.5.  These options will also be passed to the IPMI plugin when the current values are read.\",\"value\":\"\",\"hide\":\"\"}}'); +INSERT INTO `trecon_script` (`type`,`name`,`description`,`script`,`macros`) VALUES (1, 'Discovery.Application.VMware', 'Discovery Application script to monitor VMware technologies (ESXi, VCenter, VSphere)', '/usr/share/pandora_server/util/recon_scripts/vmware-plugin.pl', '{"1":{"macro":"_field1_","desc":"Configuration file","help":"","value":"","hide":""}}'); +INSERT INTO `trecon_script` (`type`,`name`,`description`,`script`,`macros`) VALUES (100,'Discovery.Cloud', 'Discovery Cloud script to monitor Cloud technologies (AWS.EC2, AWS.S3, AWS.RDS, RDS,ȊWS.EKS)', '/usr/share/pandora_server/util/recon_scripts/pcm_client.pl', '{"1":{"macro":"_field1_","desc":"Configuration file","help":"","value":"","hide":""}}'); INSERT INTO `tplugin` (`id`, `name`, `description`, `max_timeout`, `execute`, `plugin_type`, `macros`, `parameters`) VALUES (1,'IPMI Plugin','Plugin to get IPMI monitors from a IPMI Device.',0,'/usr/share/pandora_server/util/plugin/ipmi-plugin.pl',0,'{\"1\":{\"macro\":\"_field1_\",\"desc\":\"Target IP\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"2\":{\"macro\":\"_field2_\",\"desc\":\"Username\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"3\":{\"macro\":\"_field3_\",\"desc\":\"Password\",\"help\":\"\",\"value\":\"\",\"hide\":\"true\"},\"4\":{\"macro\":\"_field4_\",\"desc\":\"Sensor\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"5\":{\"macro\":\"_field5_\",\"desc\":\"Additional Options\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"}}','-h _field1_ -u _field2_ -p _field3_ -s _field4_ -- _field5_'); diff --git a/pandora_server/lib/PandoraFMS/Recon/Base.pm b/pandora_server/lib/PandoraFMS/Recon/Base.pm index 393734bc85..5885e36611 100644 --- a/pandora_server/lib/PandoraFMS/Recon/Base.pm +++ b/pandora_server/lib/PandoraFMS/Recon/Base.pm @@ -194,6 +194,8 @@ sub new { # Perform some sanity checks. die("No subnet was specified.") unless defined($self->{'subnets'}); + $self = bless($self, $class); + # Check SNMP params id SNMP is enabled if ($self->{'snmp_enabled'}) { @@ -240,7 +242,7 @@ sub new { # Disable SNMP scans if no community was given. if (ref($self->{'communities'}) ne "ARRAY" || scalar(@{$self->{'communities'}}) == 0) { $self->{'snmp_enabled'} = 0; - $self->call('message', "There is not any SNMP community configured.", 5); + $self->call('message', "There is no SNMP community configured.", 5); } } @@ -270,7 +272,7 @@ sub new { $self->{'snmp_security_level'} = ''; } - return bless($self, $class); + return $self; } ######################################################################################## @@ -1540,7 +1542,7 @@ sub snmp_get($$$) { my %output_hash; foreach my $vlan (@vlans) { my $command = $self->snmp_get_command($device, $oid, $community, $vlan); - foreach my $line (`$vlan`) { + foreach my $line (`$command`) { $output_hash{$line} = 1; } } From 798a2aad162aa91459991ad87173ba827921015f Mon Sep 17 00:00:00 2001 From: fbsanchez <fborja.sanchez@artica.es> Date: Wed, 3 Apr 2019 18:13:19 +0200 Subject: [PATCH 04/31] WIP discovery F3 Former-commit-id: 19570468cf4de9f600ab9a01468d1e59c69e6939 --- pandora_console/extras/mr/27.sql | 11 ++- .../wizards/DiscoveryTaskList.class.php | 43 ++++++--- pandora_console/include/constants.php | 8 +- pandora_console/include/styles/wizard.css | 4 +- pandora_console/pandoradb.sql | 1 + pandora_console/pandoradb_data.sql | 5 +- .../lib/PandoraFMS/DiscoveryServer.pm | 94 +++++++++++++++++- .../lib/PandoraFMS/Recon/Applications | 1 + pandora_server/lib/PandoraFMS/Recon/Base.pm | 96 ++++++++++++++++++- pandora_server/lib/PandoraFMS/Recon/Cloud | 1 + pandora_server/lib/PandoraFMS/Recon/Util.pm | 80 +++++++++++----- 11 files changed, 292 insertions(+), 52 deletions(-) create mode 120000 pandora_server/lib/PandoraFMS/Recon/Applications create mode 120000 pandora_server/lib/PandoraFMS/Recon/Cloud diff --git a/pandora_console/extras/mr/27.sql b/pandora_console/extras/mr/27.sql index 5dc8a47d2f..f419521005 100644 --- a/pandora_console/extras/mr/27.sql +++ b/pandora_console/extras/mr/27.sql @@ -1,11 +1,12 @@ START TRANSACTION; ALTER TABLE `trecon_script` ADD COLUMN `type` int NOT NULL default 0; +ALTER TABLE `trecon_task` ADD COLUMN `type` int NOT NULL default 0; + +UPDATE `trecon_script` SET `type` = 1 WHERE `name`="Discovery.Application.VMware"; +UPDATE `trecon_script` SET `type` = 2 WHERE `name`="Discovery.Cloud"; +UPDATE `trecon_script` SET `type` = 3 WHERE `name` LIKE "IPAM%Recon"; +UPDATE `trecon_script` SET `type` = 4 WHERE `name` LIKE "IPMI%Recon"; -UPDATE trecon_script SET `type` = 1 WHERE `name`="Discovery.Application.VMware"; -UPDATE trecon_script SET `type` = 2 WHERE `name`="Discovery.Application.MySQL"; -UPDATE trecon_script SET `type` = 3 WHERE `name`="Discovery.Application.Oracle"; -UPDATE trecon_script SET `type` = 100 WHERE `name`="Discovery.Cloud"; -UPDATE trecon_script SET `type` = 101 WHERE `name`="Discovery.Cloud.RDS"; COMMIT; \ No newline at end of file diff --git a/pandora_console/godmode/wizards/DiscoveryTaskList.class.php b/pandora_console/godmode/wizards/DiscoveryTaskList.class.php index 610353ebb7..00221aba1a 100644 --- a/pandora_console/godmode/wizards/DiscoveryTaskList.class.php +++ b/pandora_console/godmode/wizards/DiscoveryTaskList.class.php @@ -464,15 +464,30 @@ class DiscoveryTaskList extends Wizard } if ($task['id_recon_script'] == 0) { - // Discovery NetScan. - $data[6] = html_print_image( - 'images/network.png', - true, - ['title' => __('Discovery NetScan')] - ).' '; - $data[6] .= network_profiles_get_name( - $task['id_network_profile'] - ); + switch ($task['type']) { + case DISCOVERY_APP_MYSQL: + // Discovery Applications MySQL. + $data[6] = html_print_image( + 'images/network.png', + true, + ['title' => __('Discovery Applications MySQL')] + ).' '; + $data[6] .= __('Discovery.App.MySQL'); + break; + + case DISCOVERY_HOSTDEVICES: + default: + // Discovery NetScan. + $data[6] = html_print_image( + 'images/network.png', + true, + ['title' => __('Discovery NetScan')] + ).' '; + $data[6] .= network_profiles_get_name( + $task['id_network_profile'] + ); + break; + } } else { // APP recon task. $data[6] = html_print_image( @@ -612,12 +627,14 @@ class DiscoveryTaskList extends Wizard */ public function getTargetWiz($task) { - // TODO: Do not use description. Use recon_script ID instead. - switch ($task['description']) { - case 'Discovery.Application.VMware': + switch ($task['type']) { + case DISCOVERY_APP_MYSQL: + return 'wiz=app&mode=mysql&page=0'; + + case DISCOVERY_APP_VMWARE: return 'wiz=app&mode=vmware&page=0'; - case CLOUDWIZARD_AWS_DESCRIPTION: + case DISCOVERY_CLOUD_AWS: return 'wiz=cloud&mode=amazonws&page=1'; case 'console_task': diff --git a/pandora_console/include/constants.php b/pandora_console/include/constants.php index ceb48d1d0f..7266e9eff4 100644 --- a/pandora_console/include/constants.php +++ b/pandora_console/include/constants.php @@ -595,12 +595,10 @@ define('DISCOVERY_CLOUD_AWS_RDS', 7); define('DISCOVERY_SCRIPT_HOSTDEVICES_CUSTOM', 0); // Standard applications. define('DISCOVERY_SCRIPT_APP_VMWARE', 1); -define('DISCOVERY_SCRIPT_APP_MYSQL', 2); -define('DISCOVERY_SCRIPT_APP_ORACLE', 3); // Cloud environments. -define('DISCOVERY_SCRIPT_CLOUD_AWS', 100); -define('DISCOVERY_SCRIPT_CLOUD_AWS_EC2', 101); -define('DISCOVERY_SCRIPT_CLOUD_AWS_RDS', 102); +define('DISCOVERY_SCRIPT_CLOUD_AWS', 2); +define('DISCOVERY_SCRIPT_IPAM_RECON', 3); +define('DISCOVERY_SCRIPT_IPMI_RECON', 4); // Discovery task descriptions. define('CLOUDWIZARD_AWS_DESCRIPTION', 'Discovery.Cloud.AWS.EC2'); diff --git a/pandora_console/include/styles/wizard.css b/pandora_console/include/styles/wizard.css index 869ea85f2c..d7ec2e4ee5 100644 --- a/pandora_console/include/styles/wizard.css +++ b/pandora_console/include/styles/wizard.css @@ -16,8 +16,10 @@ ul.wizard li > label:not(.p-switch) { } ul.wizard li > textarea { - width: 250px; + width: 600px; + height: 15em; display: inline-block; + font-family: monospace; } .hidden { diff --git a/pandora_console/pandoradb.sql b/pandora_console/pandoradb.sql index d7c87538af..f3677663b4 100644 --- a/pandora_console/pandoradb.sql +++ b/pandora_console/pandoradb.sql @@ -786,6 +786,7 @@ CREATE TABLE IF NOT EXISTS `trecon_task` ( `auth_strings` text, `autoconfiguration_enabled` tinyint(1) unsigned default '0', `summary` text, + `type` int NOT NULL default 0, PRIMARY KEY (`id_rt`), KEY `recon_task_daemon` (`id_recon_server`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/pandora_console/pandoradb_data.sql b/pandora_console/pandoradb_data.sql index 4e30bdef7e..b8cc4be8b1 100644 --- a/pandora_console/pandoradb_data.sql +++ b/pandora_console/pandoradb_data.sql @@ -1135,9 +1135,10 @@ INSERT INTO `treport_custom_sql` (`id`, `name`, `sql`) VALUES (3, 'Monitoring&#x INSERT INTO `treport_custom_sql` (`id`, `name`, `sql`) VALUES (4, 'Group view', 'select t1.nombre, (select count(t3.id_agente) from tagente as t3 where t1.id_grupo = t3.id_grupo) as agents, (SELECT COUNT(t4.id_agente) FROM tagente as t4 WHERE t4.id_grupo = t1.id_grupo AND t4.disabled = 0 AND t4.ultimo_contacto < NOW() - (intervalo / (1/2))) as agent_unknown, (SELECT COUNT(tagente_estado.id_agente_estado) FROM tagente_estado, tagente, tagente_modulo WHERE tagente.id_grupo = t1.id_grupo AND tagente.disabled = 0 AND tagente.id_agente = tagente_estado.id_agente AND tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo AND tagente_modulo.disabled = 0 AND utimestamp > 0 AND tagente_modulo.id_tipo_modulo NOT IN(21,22,23,24,100) AND (UNIX_TIMESTAMP(NOW()) - tagente_estado.utimestamp) >= (tagente_estado.current_interval / (1/2))) as monitor_unknow, (SELECT COUNT(tagente_estado.id_agente_estado) FROM tagente_estado, tagente, tagente_modulo WHERE tagente.id_grupo = t1.id_grupo AND tagente.disabled = 0 AND tagente.id_agente = tagente_estado.id_agente AND tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo AND tagente_modulo.disabled = 0 AND tagente_modulo.id_tipo_modulo NOT IN (21,22,23,24) AND utimestamp = 0) as monitor_no_init, (SELECT COUNT(tagente_estado.id_agente_estado) FROM tagente_estado, tagente, tagente_modulo WHERE tagente.id_grupo = t1.id_grupo AND tagente.disabled = 0 AND tagente_estado.id_agente = tagente.id_agente AND tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo AND tagente_modulo.disabled = 0 AND estado = 0 AND ((UNIX_TIMESTAMP(NOW()) - tagente_estado.utimestamp) < (tagente_estado.current_interval / (1/2)) OR (tagente_modulo.id_tipo_modulo IN(21,22,23,24,100))) AND (utimestamp > 0 OR (tagente_modulo.id_tipo_modulo IN(21,22,23,24)))) as monitor_ok, (SELECT COUNT(tagente_estado.id_agente_estado) FROM tagente_estado, tagente, tagente_modulo WHERE tagente.id_grupo = t1.id_grupo AND tagente.disabled = 0 AND tagente_estado.id_agente = tagente.id_agente AND tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo AND tagente_modulo.disabled = 0 AND estado = 1 AND ((UNIX_TIMESTAMP(NOW()) - tagente_estado.utimestamp) < (tagente_estado.current_interval / (1/2)) OR (tagente_modulo.id_tipo_modulo IN(21,22,23,24,100))) AND utimestamp > 0) as monitor_critical, (SELECT COUNT(talert_template_modules.id) FROM talert_template_modules, tagente_modulo, tagente_estado, tagente WHERE tagente.id_grupo = t1.id_grupo AND tagente_modulo.id_agente = tagente.id_agente AND tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo AND tagente_modulo.disabled = 0 AND tagente.disabled = 0 AND talert_template_modules.id_agent_module = tagente_modulo.id_agente_modulo AND times_fired > 0) as monitor_alert_fired from tgrupo as t1 where 0 < (select count(t2.id_agente) from tagente as t2 where t1.id_grupo = t2.id_grupo)'); -- trecon scripts -INSERT INTO `trecon_script` (`type`,`name`,`description`,`script`,`macros`) VALUES (0, 'IPMI Recon','Specific Pandora FMS Intel DCM Discovery (c) Artica ST 2011 <info@artica.es>

Usage: ./ipmi-recon.pl <task_id> <group_id> <create_incident_flag> <custom_field1> <custom_field2> <custom_field3> <custom_field4>

* custom_field1 = Network i.e.: 192.168.100.0/24
* custom_field2 = Username
* custom_field3 = Password
* custom_field4 = Additional parameters i.e.: -D LAN_2_0','/usr/share/pandora_server/util/recon_scripts/ipmi-recon.pl','{\"1\":{\"macro\":\"_field1_\",\"desc\":\"Network\",\"help\":\"i.e.: 192.168.100.0/24\",\"value\":\"\",\"hide\":\"\"},\"2\":{\"macro\":\"_field2_\",\"desc\":\"Username\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"3\":{\"macro\":\"_field3_\",\"desc\":\"Password\",\"help\":\"\",\"value\":\"\",\"hide\":\"1\"},\"4\":{\"macro\":\"_field4_\",\"desc\":\"Additional parameters\",\"help\":\"Optional additional parameters such as -D LAN_2_0 to use IPMI ver 2.0 instead of 1.5.  These options will also be passed to the IPMI plugin when the current values are read.\",\"value\":\"\",\"hide\":\"\"}}'); INSERT INTO `trecon_script` (`type`,`name`,`description`,`script`,`macros`) VALUES (1, 'Discovery.Application.VMware', 'Discovery Application script to monitor VMware technologies (ESXi, VCenter, VSphere)', '/usr/share/pandora_server/util/recon_scripts/vmware-plugin.pl', '{"1":{"macro":"_field1_","desc":"Configuration file","help":"","value":"","hide":""}}'); -INSERT INTO `trecon_script` (`type`,`name`,`description`,`script`,`macros`) VALUES (100,'Discovery.Cloud', 'Discovery Cloud script to monitor Cloud technologies (AWS.EC2, AWS.S3, AWS.RDS, RDS,ȊWS.EKS)', '/usr/share/pandora_server/util/recon_scripts/pcm_client.pl', '{"1":{"macro":"_field1_","desc":"Configuration file","help":"","value":"","hide":""}}'); +INSERT INTO `trecon_script` (`type`,`name`,`description`,`script`,`macros`) VALUES (2, 'Discovery.Cloud', 'Discovery Cloud script to monitor Cloud technologies (AWS.EC2, AWS.S3, AWS.RDS, RDS,ȊWS.EKS)', '/usr/share/pandora_server/util/recon_scripts/pcm_client.pl', '{"1":{"macro":"_field1_","desc":"Configuration file","help":"","value":"","hide":""}}'); +-- IPAM is 3. +INSERT INTO `trecon_script` (`type`,`name`,`description`,`script`,`macros`) VALUES (4, 'IPMI Recon','Specific Pandora FMS Intel DCM Discovery (c) Artica ST 2011 <info@artica.es>

Usage: ./ipmi-recon.pl <task_id> <group_id> <create_incident_flag> <custom_field1> <custom_field2> <custom_field3> <custom_field4>

* custom_field1 = Network i.e.: 192.168.100.0/24
* custom_field2 = Username
* custom_field3 = Password
* custom_field4 = Additional parameters i.e.: -D LAN_2_0','/usr/share/pandora_server/util/recon_scripts/ipmi-recon.pl','{\"1\":{\"macro\":\"_field1_\",\"desc\":\"Network\",\"help\":\"i.e.: 192.168.100.0/24\",\"value\":\"\",\"hide\":\"\"},\"2\":{\"macro\":\"_field2_\",\"desc\":\"Username\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"3\":{\"macro\":\"_field3_\",\"desc\":\"Password\",\"help\":\"\",\"value\":\"\",\"hide\":\"1\"},\"4\":{\"macro\":\"_field4_\",\"desc\":\"Additional parameters\",\"help\":\"Optional additional parameters such as -D LAN_2_0 to use IPMI ver 2.0 instead of 1.5.  These options will also be passed to the IPMI plugin when the current values are read.\",\"value\":\"\",\"hide\":\"\"}}'); INSERT INTO `tplugin` (`id`, `name`, `description`, `max_timeout`, `execute`, `plugin_type`, `macros`, `parameters`) VALUES (1,'IPMI Plugin','Plugin to get IPMI monitors from a IPMI Device.',0,'/usr/share/pandora_server/util/plugin/ipmi-plugin.pl',0,'{\"1\":{\"macro\":\"_field1_\",\"desc\":\"Target IP\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"2\":{\"macro\":\"_field2_\",\"desc\":\"Username\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"3\":{\"macro\":\"_field3_\",\"desc\":\"Password\",\"help\":\"\",\"value\":\"\",\"hide\":\"true\"},\"4\":{\"macro\":\"_field4_\",\"desc\":\"Sensor\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"5\":{\"macro\":\"_field5_\",\"desc\":\"Additional Options\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"}}','-h _field1_ -u _field2_ -p _field3_ -s _field4_ -- _field5_'); diff --git a/pandora_server/lib/PandoraFMS/DiscoveryServer.pm b/pandora_server/lib/PandoraFMS/DiscoveryServer.pm index 918f0bcc4a..70abab5d2a 100644 --- a/pandora_server/lib/PandoraFMS/DiscoveryServer.pm +++ b/pandora_server/lib/PandoraFMS/DiscoveryServer.pm @@ -150,6 +150,9 @@ sub data_consumer ($$) { my ($self, $task_id) = @_; my ($pa_config, $dbh) = ($self->getConfig (), $self->getDBH ()); + # Get server id. + my $server_id = get_server_id($dbh, $pa_config->{'servername'}, $self->getServerType()); + # Get recon task data my $task = get_db_single_row ($dbh, 'SELECT * FROM trecon_task WHERE id_rt = ?', $task_id); return -1 unless defined ($task); @@ -201,7 +204,9 @@ sub data_consumer ($$) { auth_strings_array => \@auth_strings, autoconfiguration_enabled => $task->{'autoconfiguration_enabled'}, main_event_id => $main_event, - %{$pa_config} + server_id => $server_id, + %{$pa_config}, + task_data => $task ); $recon->scan(); @@ -413,6 +418,93 @@ sub PandoraFMS::Recon::Base::connect_agents($$$$$) { } } + +########################################################################## +# Create agents from db_scan. +# data = [ +# 'agent_data' => {}, +# 'module_data' => [] +# ] +########################################################################## +sub PandoraFMS::Recon::Base::create_agents($$) { + my ($self, $data) = @_; + + my $pa_config = $self->{'pa_config'}; + my $dbh = $self->{'dbh'}; + my $server_id = $self->{'server_id'}; + + return undef if (ref($data) ne "ARRAY"); + + foreach my $information (@{$data}) { + my $agent = $information->{'agent_data'}; + my $modules = $information->{'module_data'}; + my $force_processing = 0; + + # Search agent + my $current_agent = PandoraFMS::Core::locate_agent( + $pa_config, $dbh, $agent->{'agent_name'} + ); + + my $parent_id; + if (defined($agent->{'parent_agent'})) { + $parent_id = PandoraFMS::Core::locate_agent( + $pa_config, $dbh, $agent->{'parent_agent'} + ); + } + + my $agent_id; + + if (!$current_agent) { + # Create agent. + $agent_id = pandora_create_agent( + $pa_config, $pa_config->{'servername'}, $agent->{'agent_name'}, + $agent->{'address'}, $agent->{'id_group'}, $parent_id, + $agent->{'os'}, $agent->{'description'}, $agent->{'interval'}, + $dbh, $agent->{'timezone_offset'} + ); + + $current_agent = $parent_id = PandoraFMS::Core::locate_agent( + $pa_config, $dbh, $agent->{'agent_name'} + ); + + $force_processing = 1; + + } else { + $agent_id = $current_agent->{'id_agente'}; + } + + if (!defined($agent_id)) { + return undef; + } + + if ($agent->{'address'} ne '') { + pandora_add_agent_address( + $pa_config, $agent_id, $agent->{'agent_name'}, + $agent->{'address'}, $dbh + ); + } + + # Update agent information + pandora_update_agent( + $pa_config, time(), $agent_id, + $agent->{'os_version'}, $agent->{'agent_version'}, + $agent->{'interval'}, $dbh, undef, $parent_id + ); + + # Add modules. + if (ref($modules) eq "ARRAY") { + foreach my $module (@{$modules}) { + pandora_process_module( + $pa_config, {'data' => $module->{'value'}}, $current_agent, $module, + $module->{'type'}, '', time(), $server_id, $dbh + ); + } + } + } + +} + + ########################################################################## # Create an agent for the given device. Returns the ID of the new (or # existing) agent, undef on error. diff --git a/pandora_server/lib/PandoraFMS/Recon/Applications b/pandora_server/lib/PandoraFMS/Recon/Applications new file mode 120000 index 0000000000..f584395db5 --- /dev/null +++ b/pandora_server/lib/PandoraFMS/Recon/Applications @@ -0,0 +1 @@ +/tmp/pandora_enterprise/pandora_server/PandoraFMS-Enterprise/lib/PandoraFMS/Recon/Applications \ No newline at end of file diff --git a/pandora_server/lib/PandoraFMS/Recon/Base.pm b/pandora_server/lib/PandoraFMS/Recon/Base.pm index 5885e36611..9612599aa7 100644 --- a/pandora_server/lib/PandoraFMS/Recon/Base.pm +++ b/pandora_server/lib/PandoraFMS/Recon/Base.pm @@ -20,7 +20,16 @@ use constant { STEP_SCANNING => 1, STEP_AFT => 2, STEP_TRACEROUTE => 3, - STEP_GATEWAY => 4 + STEP_GATEWAY => 4, + STEP_STATISTICS => 1, + STEP_DATABASE_SCAN => 2, + STEP_CUSTOM_QUERIES => 3, + DISCOVERY_HOSTDEVICES => 0, + DISCOVERY_HOSTDEVICES_CUSTOM => 1, + DISCOVERY_CLOUD_AWS => 2, + DISCOVERY_APP_VMWARE => 3, + DISCOVERY_APP_MYSQL => 4, + DISCOVERY_APP_ORACLE => 5 }; # /dev/null @@ -1417,6 +1426,83 @@ sub scan_subnet($) { } } +########################################################################## +# Perform a DB scan. +########################################################################## +sub db_scan($) { + my ($self) = @_; + my ($progress, $step); + + my $type = ''; + + if ($self->{'task_data'}->{'type'} == DISCOVERY_APP_MYSQL) { + $type = 'MySQL'; + } elsif ($self->{'task_data'}->{'type'} == DISCOVERY_APP_ORACLE) { + $type = 'Oracle'; + } else { + # Unrecognized task type. + call('message', 'Unrecognized task type', 1); + $self->call('update_progress', -1); + return; + } + + # Connect to target. + my $dbObj = PandoraFMS::Recon::Util::enterprise_new( + 'PandoraFMS::Recon::Applications::'.$type, + $self->{'task_data'} + ); + + if (!defined($dbObj)) { + call('message', 'Cannot connect to target ' .'', 3); + $self->call('update_progress', -1); + return; + } + + my @modules; + + # Analyze. + $self->{'step'} = STEP_STATISTICS; + $self->{'c_network_name'} = $dbObj->get_host(); + $self->call('update_progress', 10); + + # Retrieve connection statistics. + # Retrieve uptime statistics + # Retrieve query stats + # Retrieve connections + # Retrieve innodb + # Retrieve cache + push @modules, $dbObj->get_statistics(); + $self->call('update_progress', 50); + + + # Custom queries. + push @modules, $dbObj->execute_custom_queries(); + $self->call('update_progress', 90); + + my $data = [ + { + 'agent_data' => { + 'agent_name' => $dbObj->get_agent_name(), + 'os' => $type, + 'os_version' => 'Discovery', + 'interval' => $self->{'task_data'}->{'interval_sweep'}, + 'id_group' => $self->{'task_data'}->{'id_group'}, + 'address' => $dbObj->get_host(), + + }, + 'module_data' => \@modules, + } + ]; + + $self->call('create_agents', $data); + + # Update progress. + # Done! + $self->{'step'} = ''; + $self->call('update_progress', -1); + +} + ########################################################################## # Perform a network scan. ########################################################################## @@ -1427,6 +1513,14 @@ sub scan($) { # 1% $self->call('update_progress', 1); + if (defined($self->{'task_data'})) { + if ($self->{'task_data'}->{'type'} == DISCOVERY_APP_MYSQL + || $self->{'task_data'}->{'type'} == DISCOVERY_APP_ORACLE) { + # Database scan. + return $self->db_scan(); + } + } + # Find devices. $self->call('message', "[1/5] Scanning the network...", 3); $self->{'step'} = STEP_SCANNING; diff --git a/pandora_server/lib/PandoraFMS/Recon/Cloud b/pandora_server/lib/PandoraFMS/Recon/Cloud new file mode 120000 index 0000000000..1980c9db6a --- /dev/null +++ b/pandora_server/lib/PandoraFMS/Recon/Cloud @@ -0,0 +1 @@ +/tmp/pandora_enterprise/pandora_server/PandoraFMS-Enterprise/lib/PandoraFMS/Recon/Cloud \ No newline at end of file diff --git a/pandora_server/lib/PandoraFMS/Recon/Util.pm b/pandora_server/lib/PandoraFMS/Recon/Util.pm index 85d251ff1b..64cc7b28e6 100644 --- a/pandora_server/lib/PandoraFMS/Recon/Util.pm +++ b/pandora_server/lib/PandoraFMS/Recon/Util.pm @@ -12,16 +12,47 @@ use lib '/usr/lib/perl5'; use Socket qw/inet_aton/; our @ISA = ("Exporter"); -our %EXPORT_TAGS = ( 'all' => [ qw( ) ] ); +our %EXPORT_TAGS = ( 'all' => [qw( )] ); our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); our @EXPORT = qw( - ip_to_long - mac_matches - mac_to_dec - parse_mac - subnet_matches + enterprise_new + ip_to_long + mac_matches + mac_to_dec + parse_mac + subnet_matches ); +######################################################################################## +# Return an Enterprise Recon object. +######################################################################################## +sub enterprise_new($$) { + my ($class, $arguments) = @_; + + my @args; + if (ref($arguments) eq "HASH") { + @args = %{$arguments}; + } + if (ref($arguments) eq "ARRAY") { + @args = @{$arguments}; + } + + # Try to load the module + if ($^O eq 'MSWin32') { + # If the Windows service dies the service is stopped, even inside an eval ($RUN is set to 0)! + eval 'local $SIG{__DIE__}; require '.$class.';'; + }else { + eval 'require '.$class.';'; + } + if ($@) { + # Not loaded. + return undef; + } + + return new $class(@args); +} + + ######################################################################################## # Return the numeric representation of the given IP address. ######################################################################################## @@ -35,13 +66,13 @@ sub ip_to_long($) { # Returns 1 if the two given MAC addresses are the same. ######################################################################################## sub mac_matches($$) { - my ($mac_1, $mac_2) = @_; + my ($mac_1, $mac_2) = @_; - if (parse_mac($mac_1) eq parse_mac($mac_2)) { - return 1; - } + if (parse_mac($mac_1) eq parse_mac($mac_2)) { + return 1; + } - return 0; + return 0; } ######################################################################################## @@ -53,7 +84,7 @@ sub mac_to_dec($) { my $dec_mac = ''; my @elements = split(/:/, $mac); foreach my $element (@elements) { - $dec_mac .= unpack('s', pack 's', hex($element)) . '.' + $dec_mac .= unpack('s', pack 's', hex($element)) . '.'; } chop($dec_mac); @@ -64,23 +95,23 @@ sub mac_to_dec($) { # Make sure all MAC addresses are in the same format (00 11 22 33 44 55 66). ######################################################################################## sub parse_mac($) { - my ($mac) = @_; + my ($mac) = @_; - # Remove leading and trailing whitespaces. - $mac =~ s/(^\s+)|(\s+$)//g; + # Remove leading and trailing whitespaces. + $mac =~ s/(^\s+)|(\s+$)//g; - # Replace whitespaces and dots with colons. - $mac =~ s/\s+|\./:/g; + # Replace whitespaces and dots with colons. + $mac =~ s/\s+|\./:/g; - # Convert hex digits to uppercase. - $mac =~ s/([a-f])/\U$1/g; + # Convert hex digits to uppercase. + $mac =~ s/([a-f])/\U$1/g; - # Add a leading 0 to single digits. - $mac =~ s/^([0-9A-F]):/0$1:/g; - $mac =~ s/:([0-9A-F]):/:0$1:/g; - $mac =~ s/:([0-9A-F])$/:0$1/g; + # Add a leading 0 to single digits. + $mac =~ s/^([0-9A-F]):/0$1:/g; + $mac =~ s/:([0-9A-F]):/:0$1:/g; + $mac =~ s/:([0-9A-F])$/:0$1/g; - return $mac; + return $mac; } ######################################################################################## @@ -95,6 +126,7 @@ sub subnet_matches($$;$) { $netaddr = $subnet; $netmask = ip_to_long($mask); } + # CIDR notation. else { ($netaddr, $netmask) = split('/', $subnet); From 60f37eac57c2e0063731adcac40f8af2236b2a45 Mon Sep 17 00:00:00 2001 From: fbsanchez <fborja.sanchez@artica.es> Date: Wed, 3 Apr 2019 21:08:52 +0200 Subject: [PATCH 05/31] removed unused folders Former-commit-id: 4c1870e836e7f05dd5a312e41c4f1f86bff26e22 --- pandora_server/lib/PandoraFMS/Recon/Applications | 1 - pandora_server/lib/PandoraFMS/Recon/Cloud | 1 - 2 files changed, 2 deletions(-) delete mode 120000 pandora_server/lib/PandoraFMS/Recon/Applications delete mode 120000 pandora_server/lib/PandoraFMS/Recon/Cloud diff --git a/pandora_server/lib/PandoraFMS/Recon/Applications b/pandora_server/lib/PandoraFMS/Recon/Applications deleted file mode 120000 index f584395db5..0000000000 --- a/pandora_server/lib/PandoraFMS/Recon/Applications +++ /dev/null @@ -1 +0,0 @@ -/tmp/pandora_enterprise/pandora_server/PandoraFMS-Enterprise/lib/PandoraFMS/Recon/Applications \ No newline at end of file diff --git a/pandora_server/lib/PandoraFMS/Recon/Cloud b/pandora_server/lib/PandoraFMS/Recon/Cloud deleted file mode 120000 index 1980c9db6a..0000000000 --- a/pandora_server/lib/PandoraFMS/Recon/Cloud +++ /dev/null @@ -1 +0,0 @@ -/tmp/pandora_enterprise/pandora_server/PandoraFMS-Enterprise/lib/PandoraFMS/Recon/Cloud \ No newline at end of file From 74303168ac9cfedebdaa209b5eeffaf37af555af Mon Sep 17 00:00:00 2001 From: fbsanchez <fborja.sanchez@artica.es> Date: Wed, 3 Apr 2019 21:55:11 +0200 Subject: [PATCH 06/31] WIP discovery F3 Former-commit-id: 493d05714a31c2f91f7b8ea5445397ebf1c526d7 --- pandora_server/lib/PandoraFMS/DiscoveryServer.pm | 13 ++++++++++--- pandora_server/lib/PandoraFMS/Recon/Base.pm | 2 +- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/pandora_server/lib/PandoraFMS/DiscoveryServer.pm b/pandora_server/lib/PandoraFMS/DiscoveryServer.pm index 70abab5d2a..797190a259 100644 --- a/pandora_server/lib/PandoraFMS/DiscoveryServer.pm +++ b/pandora_server/lib/PandoraFMS/DiscoveryServer.pm @@ -494,9 +494,16 @@ sub PandoraFMS::Recon::Base::create_agents($$) { # Add modules. if (ref($modules) eq "ARRAY") { foreach my $module (@{$modules}) { - pandora_process_module( - $pa_config, {'data' => $module->{'value'}}, $current_agent, $module, - $module->{'type'}, '', time(), $server_id, $dbh + my %data_translated = map { $_ => [ $module->{$_} ] } keys %{$module}; + + # Translate fields. + PandoraFMS::DataServer::process_module_data ( + $pa_config, \%data_translated, + $server_id, $current_agent, + $module->{'name'}, $module->{'type'}, + $agent->{'interval'}, + strftime ("%Y/%m/%d %H:%M:%S", localtime()), + $dbh, $force_processing ); } } diff --git a/pandora_server/lib/PandoraFMS/Recon/Base.pm b/pandora_server/lib/PandoraFMS/Recon/Base.pm index 9612599aa7..39c3bf0ba2 100644 --- a/pandora_server/lib/PandoraFMS/Recon/Base.pm +++ b/pandora_server/lib/PandoraFMS/Recon/Base.pm @@ -1488,7 +1488,7 @@ sub db_scan($) { 'interval' => $self->{'task_data'}->{'interval_sweep'}, 'id_group' => $self->{'task_data'}->{'id_group'}, 'address' => $dbObj->get_host(), - + 'description' => '', }, 'module_data' => \@modules, } From 654e0c28f6c64eb0a34bf7b8f7d56fdaae9ef5b8 Mon Sep 17 00:00:00 2001 From: fbsanchez <fborja.sanchez@artica.es> Date: Wed, 3 Apr 2019 22:44:06 +0200 Subject: [PATCH 07/31] WIP discovery F3 app db my multiserver Former-commit-id: a85c048a6d4e755b76a7e042e04cfebdfe69b6f4 --- pandora_server/lib/PandoraFMS/Recon/Base.pm | 101 +++++++++++--------- 1 file changed, 58 insertions(+), 43 deletions(-) diff --git a/pandora_server/lib/PandoraFMS/Recon/Base.pm b/pandora_server/lib/PandoraFMS/Recon/Base.pm index 39c3bf0ba2..d7fa83b6fb 100644 --- a/pandora_server/lib/PandoraFMS/Recon/Base.pm +++ b/pandora_server/lib/PandoraFMS/Recon/Base.pm @@ -1446,55 +1446,70 @@ sub db_scan($) { return; } - # Connect to target. - my $dbObj = PandoraFMS::Recon::Util::enterprise_new( - 'PandoraFMS::Recon::Applications::'.$type, - $self->{'task_data'} - ); + my @targets = split /,/, $self->{'task_data'}->{'subnet'}; - if (!defined($dbObj)) { - call('message', 'Cannot connect to target ' .'', 3); - $self->call('update_progress', -1); - return; - } + my $i = 0; + foreach my $target (@targets) { + call('message', 'Checking target ' . $target, 10); - my @modules; + # Force target acquirement. + $self->{'task_data'}->{'dbhost'} = $target; + $self->{'task_data'}->{'target_index'} = $i++; - # Analyze. - $self->{'step'} = STEP_STATISTICS; - $self->{'c_network_name'} = $dbObj->get_host(); - $self->call('update_progress', 10); + # Connect to target. + my $dbObj = PandoraFMS::Recon::Util::enterprise_new( + 'PandoraFMS::Recon::Applications::'.$type, + $self->{'task_data'} + ); - # Retrieve connection statistics. - # Retrieve uptime statistics - # Retrieve query stats - # Retrieve connections - # Retrieve innodb - # Retrieve cache - push @modules, $dbObj->get_statistics(); - $self->call('update_progress', 50); - - - # Custom queries. - push @modules, $dbObj->execute_custom_queries(); - $self->call('update_progress', 90); - - my $data = [ - { - 'agent_data' => { - 'agent_name' => $dbObj->get_agent_name(), - 'os' => $type, - 'os_version' => 'Discovery', - 'interval' => $self->{'task_data'}->{'interval_sweep'}, - 'id_group' => $self->{'task_data'}->{'id_group'}, - 'address' => $dbObj->get_host(), - 'description' => '', - }, - 'module_data' => \@modules, + if (!defined($dbObj)) { + call('message', 'Cannot connect to target ' . $target, 3); + next; } - ]; - $self->call('create_agents', $data); + my @modules; + + # Analyze. + $self->{'step'} = STEP_STATISTICS; + $self->{'c_network_name'} = $dbObj->get_host(); + $self->call('update_progress', 10); + + # Retrieve connection statistics. + # Retrieve uptime statistics + # Retrieve query stats + # Retrieve connections + # Retrieve innodb + # Retrieve cache + push @modules, $dbObj->get_statistics(); + $self->call('update_progress', 50); + + + # Custom queries. + push @modules, $dbObj->execute_custom_queries(); + $self->call('update_progress', 90); + + my $data = [ + { + 'agent_data' => { + 'agent_name' => $dbObj->get_agent_name(), + 'os' => $type, + 'os_version' => 'Discovery', + 'interval' => $self->{'task_data'}->{'interval_sweep'}, + 'id_group' => $self->{'task_data'}->{'id_group'}, + 'address' => $dbObj->get_host(), + 'description' => '', + }, + 'module_data' => \@modules, + } + ]; + + use Data::Dumper; + print Dumper($data); + $self->call('create_agents', $data); + + # Destroy item. + undef($dbObj); + } # Update progress. # Done! From 9e83f139e15e7f8b44bd92363cb5d6b405f66302 Mon Sep 17 00:00:00 2001 From: fbsanchez <fborja.sanchez@artica.es> Date: Wed, 3 Apr 2019 22:52:37 +0200 Subject: [PATCH 08/31] WIP discovery f3 Former-commit-id: cee7ee096e0a0c065bc4312a149ee223303224fc --- pandora_server/lib/PandoraFMS/Recon/Base.pm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pandora_server/lib/PandoraFMS/Recon/Base.pm b/pandora_server/lib/PandoraFMS/Recon/Base.pm index d7fa83b6fb..fb9967a54d 100644 --- a/pandora_server/lib/PandoraFMS/Recon/Base.pm +++ b/pandora_server/lib/PandoraFMS/Recon/Base.pm @@ -1464,8 +1464,11 @@ sub db_scan($) { if (!defined($dbObj)) { call('message', 'Cannot connect to target ' . $target, 3); + $self->{'summary'}->{'not_alive'} += 1; next; } + $self->{'summary'}->{'discovered'} += 1; + $self->{'summary'}->{'alive'} += 1; my @modules; @@ -1503,8 +1506,6 @@ sub db_scan($) { } ]; - use Data::Dumper; - print Dumper($data); $self->call('create_agents', $data); # Destroy item. From fcafe76943bc47112d58c532bbea8963470719f9 Mon Sep 17 00:00:00 2001 From: fbsanchez <fborja.sanchez@artica.es> Date: Thu, 4 Apr 2019 12:28:17 +0200 Subject: [PATCH 09/31] wip discovery f34 Former-commit-id: bb08450d3304ff140c4bae37e77b20a2329c600b --- .../lib/PandoraFMS/DiscoveryServer.pm | 5 +- pandora_server/lib/PandoraFMS/Recon/Base.pm | 93 +++++++++++-------- 2 files changed, 56 insertions(+), 42 deletions(-) diff --git a/pandora_server/lib/PandoraFMS/DiscoveryServer.pm b/pandora_server/lib/PandoraFMS/DiscoveryServer.pm index 797190a259..c97a393422 100644 --- a/pandora_server/lib/PandoraFMS/DiscoveryServer.pm +++ b/pandora_server/lib/PandoraFMS/DiscoveryServer.pm @@ -420,7 +420,7 @@ sub PandoraFMS::Recon::Base::connect_agents($$$$$) { ########################################################################## -# Create agents from db_scan. +# Create agents from db_scan. Uses DataServer methods. # data = [ # 'agent_data' => {}, # 'module_data' => [] @@ -494,9 +494,10 @@ sub PandoraFMS::Recon::Base::create_agents($$) { # Add modules. if (ref($modules) eq "ARRAY") { foreach my $module (@{$modules}) { + # Translate data structure to simulate XML parser return. my %data_translated = map { $_ => [ $module->{$_} ] } keys %{$module}; - # Translate fields. + # Process modules. PandoraFMS::DataServer::process_module_data ( $pa_config, \%data_translated, $server_id, $current_agent, diff --git a/pandora_server/lib/PandoraFMS/Recon/Base.pm b/pandora_server/lib/PandoraFMS/Recon/Base.pm index fb9967a54d..2b04dab950 100644 --- a/pandora_server/lib/PandoraFMS/Recon/Base.pm +++ b/pandora_server/lib/PandoraFMS/Recon/Base.pm @@ -1450,6 +1450,8 @@ sub db_scan($) { my $i = 0; foreach my $target (@targets) { + my @data; + my @modules; call('message', 'Checking target ' . $target, 10); # Force target acquirement. @@ -1462,51 +1464,62 @@ sub db_scan($) { $self->{'task_data'} ); - if (!defined($dbObj)) { + if (!$dbObj->is_connected()) { call('message', 'Cannot connect to target ' . $target, 3); $self->{'summary'}->{'not_alive'} += 1; - next; + push @modules, { + name => 'mysql_connection', + type => 'generic_proc', + data => 0, + description => 'MySQL availability' + }; + + } else { + $self->{'summary'}->{'discovered'} += 1; + $self->{'summary'}->{'alive'} += 1; + + push @modules, { + name => 'mysql_connection', + type => 'generic_proc', + data => 1, + description => 'MySQL availability' + }; + + # Analyze. + $self->{'step'} = STEP_STATISTICS; + $self->{'c_network_name'} = $dbObj->get_host(); + $self->call('update_progress', 10); + + # Retrieve connection statistics. + # Retrieve uptime statistics + # Retrieve query stats + # Retrieve connections + # Retrieve innodb + # Retrieve cache + push @modules, $dbObj->get_statistics(); + $self->call('update_progress', 50); + + + # Custom queries. + push @modules, $dbObj->execute_custom_queries(); + $self->call('update_progress', 90); } - $self->{'summary'}->{'discovered'} += 1; - $self->{'summary'}->{'alive'} += 1; - my @modules; + # Put engine agent at the beginning of the list. + unshift @data,{ + 'agent_data' => { + 'agent_name' => $dbObj->get_agent_name(), + 'os' => $type, + 'os_version' => 'Discovery', + 'interval' => $self->{'task_data'}->{'interval_sweep'}, + 'id_group' => $self->{'task_data'}->{'id_group'}, + 'address' => $dbObj->get_host(), + 'description' => '', + }, + 'module_data' => \@modules, + }; - # Analyze. - $self->{'step'} = STEP_STATISTICS; - $self->{'c_network_name'} = $dbObj->get_host(); - $self->call('update_progress', 10); - - # Retrieve connection statistics. - # Retrieve uptime statistics - # Retrieve query stats - # Retrieve connections - # Retrieve innodb - # Retrieve cache - push @modules, $dbObj->get_statistics(); - $self->call('update_progress', 50); - - - # Custom queries. - push @modules, $dbObj->execute_custom_queries(); - $self->call('update_progress', 90); - - my $data = [ - { - 'agent_data' => { - 'agent_name' => $dbObj->get_agent_name(), - 'os' => $type, - 'os_version' => 'Discovery', - 'interval' => $self->{'task_data'}->{'interval_sweep'}, - 'id_group' => $self->{'task_data'}->{'id_group'}, - 'address' => $dbObj->get_host(), - 'description' => '', - }, - 'module_data' => \@modules, - } - ]; - - $self->call('create_agents', $data); + $self->call('create_agents', \@data); # Destroy item. undef($dbObj); From ce9f9eab4e82554ee95079aea0e5e88ac64960de Mon Sep 17 00:00:00 2001 From: fbsanchez <fborja.sanchez@artica.es> Date: Thu, 4 Apr 2019 16:00:08 +0200 Subject: [PATCH 10/31] rc1 mysql recon Former-commit-id: 51e000229d6c2c94e59e8eeb8ef77d539ee6c775 --- .../lib/PandoraFMS/DiscoveryServer.pm | 4 ++-- pandora_server/lib/PandoraFMS/Recon/Base.pm | 20 ++++++++++++++++++- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/pandora_server/lib/PandoraFMS/DiscoveryServer.pm b/pandora_server/lib/PandoraFMS/DiscoveryServer.pm index c97a393422..eef7fa85f0 100644 --- a/pandora_server/lib/PandoraFMS/DiscoveryServer.pm +++ b/pandora_server/lib/PandoraFMS/DiscoveryServer.pm @@ -459,8 +459,8 @@ sub PandoraFMS::Recon::Base::create_agents($$) { $agent_id = pandora_create_agent( $pa_config, $pa_config->{'servername'}, $agent->{'agent_name'}, $agent->{'address'}, $agent->{'id_group'}, $parent_id, - $agent->{'os'}, $agent->{'description'}, $agent->{'interval'}, - $dbh, $agent->{'timezone_offset'} + get_os_id($dbh, $agent->{'os'}), $agent->{'description'}, + $agent->{'interval'}, $dbh, $agent->{'timezone_offset'} ); $current_agent = $parent_id = PandoraFMS::Core::locate_agent( diff --git a/pandora_server/lib/PandoraFMS/Recon/Base.pm b/pandora_server/lib/PandoraFMS/Recon/Base.pm index 2b04dab950..df00c10951 100644 --- a/pandora_server/lib/PandoraFMS/Recon/Base.pm +++ b/pandora_server/lib/PandoraFMS/Recon/Base.pm @@ -1475,6 +1475,8 @@ sub db_scan($) { }; } else { + my $dbObjCfg = $dbObj->get_config(); + $self->{'summary'}->{'discovered'} += 1; $self->{'summary'}->{'alive'} += 1; @@ -1499,10 +1501,26 @@ sub db_scan($) { push @modules, $dbObj->get_statistics(); $self->call('update_progress', 50); - # Custom queries. push @modules, $dbObj->execute_custom_queries(); $self->call('update_progress', 90); + + if (defined($dbObjCfg->{'scan_databases'}) + && $dbObjCfg->{'scan_databases'} == 1) { + my $__data = $dbObj->scan_databases(); + + if (ref($__data) eq "ARRAY") { + if (defined($dbObjCfg->{'agent_per_database'}) + && $dbObjCfg->{'agent_per_database'} == 1) { + # Agent per database detected. + push @data, @{$__data}; + } else { + # Merge modules into engine agent. + my @_modules = map { $_->{'module_data'} } @{$__data}; + push @modules, @_modules; + } + } + } } # Put engine agent at the beginning of the list. From 56f2acbbf16fb6fa9815e5b579a7b27ae850f34c Mon Sep 17 00:00:00 2001 From: fbsanchez <fborja.sanchez@artica.es> Date: Thu, 4 Apr 2019 16:05:16 +0200 Subject: [PATCH 11/31] discovery.app.mysql rc1 Former-commit-id: 51304e872d375b480cbbf88d058b1804106afb98 --- pandora_server/lib/PandoraFMS/DiscoveryServer.pm | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pandora_server/lib/PandoraFMS/DiscoveryServer.pm b/pandora_server/lib/PandoraFMS/DiscoveryServer.pm index eef7fa85f0..6179fbc4c3 100644 --- a/pandora_server/lib/PandoraFMS/DiscoveryServer.pm +++ b/pandora_server/lib/PandoraFMS/DiscoveryServer.pm @@ -453,13 +453,18 @@ sub PandoraFMS::Recon::Base::create_agents($$) { } my $agent_id; + my $os_id = get_os_id($dbh, $agent->{'os'}); + + if (!$os_id) { + $os_id = get_os_id($dbh, 'Other'); + } if (!$current_agent) { # Create agent. $agent_id = pandora_create_agent( $pa_config, $pa_config->{'servername'}, $agent->{'agent_name'}, $agent->{'address'}, $agent->{'id_group'}, $parent_id, - get_os_id($dbh, $agent->{'os'}), $agent->{'description'}, + $os_id, $agent->{'description'}, $agent->{'interval'}, $dbh, $agent->{'timezone_offset'} ); From 12743802705918964b3f46c66c1b88c0beeac9a7 Mon Sep 17 00:00:00 2001 From: fbsanchez <fborja.sanchez@artica.es> Date: Thu, 4 Apr 2019 16:07:50 +0200 Subject: [PATCH 12/31] minor fix Former-commit-id: a012c8155cd1d950044bc2c0531ee2abd9e89d07 --- pandora_server/lib/PandoraFMS/DiscoveryServer.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandora_server/lib/PandoraFMS/DiscoveryServer.pm b/pandora_server/lib/PandoraFMS/DiscoveryServer.pm index 6179fbc4c3..52c2a53a0a 100644 --- a/pandora_server/lib/PandoraFMS/DiscoveryServer.pm +++ b/pandora_server/lib/PandoraFMS/DiscoveryServer.pm @@ -455,7 +455,7 @@ sub PandoraFMS::Recon::Base::create_agents($$) { my $agent_id; my $os_id = get_os_id($dbh, $agent->{'os'}); - if (!$os_id) { + if ($os_id < 0) { $os_id = get_os_id($dbh, 'Other'); } From 143c501a6eab56ace3ccb5a4491979655113aea4 Mon Sep 17 00:00:00 2001 From: fbsanchez <fborja.sanchez@artica.es> Date: Thu, 4 Apr 2019 17:08:31 +0200 Subject: [PATCH 13/31] minor fixes Former-commit-id: 8d8c891a963b0e03838c2bf184b5da6bed01b2a9 --- pandora_server/lib/PandoraFMS/DiscoveryServer.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pandora_server/lib/PandoraFMS/DiscoveryServer.pm b/pandora_server/lib/PandoraFMS/DiscoveryServer.pm index 52c2a53a0a..f3b6f007e0 100644 --- a/pandora_server/lib/PandoraFMS/DiscoveryServer.pm +++ b/pandora_server/lib/PandoraFMS/DiscoveryServer.pm @@ -446,9 +446,9 @@ sub PandoraFMS::Recon::Base::create_agents($$) { ); my $parent_id; - if (defined($agent->{'parent_agent'})) { + if (defined($agent->{'parent_agent_name'})) { $parent_id = PandoraFMS::Core::locate_agent( - $pa_config, $dbh, $agent->{'parent_agent'} + $pa_config, $dbh, $agent->{'parent_agent_name'} ); } From e76a5af44122eafb5b00de4517cca02d0b716de8 Mon Sep 17 00:00:00 2001 From: fbsanchez <fborja.sanchez@artica.es> Date: Thu, 4 Apr 2019 18:20:26 +0200 Subject: [PATCH 14/31] minor fix parent link Former-commit-id: a2330dd0159ad58c454a06b7efe16699f7cee84a --- pandora_server/lib/PandoraFMS/DiscoveryServer.pm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pandora_server/lib/PandoraFMS/DiscoveryServer.pm b/pandora_server/lib/PandoraFMS/DiscoveryServer.pm index f3b6f007e0..44cd4dcdbb 100644 --- a/pandora_server/lib/PandoraFMS/DiscoveryServer.pm +++ b/pandora_server/lib/PandoraFMS/DiscoveryServer.pm @@ -450,6 +450,9 @@ sub PandoraFMS::Recon::Base::create_agents($$) { $parent_id = PandoraFMS::Core::locate_agent( $pa_config, $dbh, $agent->{'parent_agent_name'} ); + if ($parent_id) { + $parent_id = $parent_id->{'id_agente'}; + } } my $agent_id; From db9068e25a930febc2faf0c0bfba22402d6d3385 Mon Sep 17 00:00:00 2001 From: fbsanchez <fborja.sanchez@artica.es> Date: Fri, 5 Apr 2019 10:41:09 +0200 Subject: [PATCH 15/31] fixes in non agent per database Former-commit-id: 180cf7269886787b17dc359bf941b5ce5e1b1313 --- .../godmode/wizards/DiscoveryTaskList.class.php | 13 +++++++++++++ pandora_server/lib/PandoraFMS/Recon/Base.pm | 5 ++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/pandora_console/godmode/wizards/DiscoveryTaskList.class.php b/pandora_console/godmode/wizards/DiscoveryTaskList.class.php index 00221aba1a..2cbe9c4f45 100644 --- a/pandora_console/godmode/wizards/DiscoveryTaskList.class.php +++ b/pandora_console/godmode/wizards/DiscoveryTaskList.class.php @@ -475,6 +475,16 @@ class DiscoveryTaskList extends Wizard $data[6] .= __('Discovery.App.MySQL'); break; + case DISCOVERY_APP_ORACLE: + // Discovery Applications Oracle. + $data[6] = html_print_image( + 'images/network.png', + true, + ['title' => __('Discovery Applications Oracle')] + ).' '; + $data[6] .= __('Discovery.App.Oracle'); + break; + case DISCOVERY_HOSTDEVICES: default: // Discovery NetScan. @@ -631,6 +641,9 @@ class DiscoveryTaskList extends Wizard case DISCOVERY_APP_MYSQL: return 'wiz=app&mode=mysql&page=0'; + case DISCOVERY_APP_ORACLE: + return 'wiz=app&mode=oracle&page=0'; + case DISCOVERY_APP_VMWARE: return 'wiz=app&mode=vmware&page=0'; diff --git a/pandora_server/lib/PandoraFMS/Recon/Base.pm b/pandora_server/lib/PandoraFMS/Recon/Base.pm index df00c10951..6df41c4f92 100644 --- a/pandora_server/lib/PandoraFMS/Recon/Base.pm +++ b/pandora_server/lib/PandoraFMS/Recon/Base.pm @@ -1516,7 +1516,10 @@ sub db_scan($) { push @data, @{$__data}; } else { # Merge modules into engine agent. - my @_modules = map { $_->{'module_data'} } @{$__data}; + my @_modules = map { + map { $_ } @{$_->{'module_data'}} + } @{$__data}; + push @modules, @_modules; } } From 970a10ba504d31791bc565988bd4a086c9a2f6c5 Mon Sep 17 00:00:00 2001 From: fbsanchez <fborja.sanchez@artica.es> Date: Fri, 5 Apr 2019 10:41:37 +0200 Subject: [PATCH 16/31] fixes in non agent per database Former-commit-id: 7b34ea990bf52c96d4d6f65f11cf2949c199f2db --- .../godmode/wizards/DiscoveryTaskList.class.php | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/pandora_console/godmode/wizards/DiscoveryTaskList.class.php b/pandora_console/godmode/wizards/DiscoveryTaskList.class.php index 2cbe9c4f45..9d1242f989 100644 --- a/pandora_console/godmode/wizards/DiscoveryTaskList.class.php +++ b/pandora_console/godmode/wizards/DiscoveryTaskList.class.php @@ -96,8 +96,20 @@ class DiscoveryTaskList extends Wizard ] ); - // Header - ui_print_page_header(__('Task list'), '', false, '', true, '', false, '', GENERIC_SIZE_TEXT, '', $this->printHeader(true)); + // Header. + ui_print_page_header( + __('Task list'), + '', + false, + '', + true, + '', + false, + '', + GENERIC_SIZE_TEXT, + '', + $this->printHeader(true) + ); // Show redirected messages from discovery.php. if ($status === 0) { From 4808e4ae9735263afd1440d4ab9e2f29c9dc7ac2 Mon Sep 17 00:00:00 2001 From: Daniel Barbero <daniel.barbero@artica.es> Date: Fri, 5 Apr 2019 16:43:36 +0200 Subject: [PATCH 17/31] fixed errors map ipam Former-commit-id: 9a1e5460ab40d22135edc75f2adf186f8d56f3d4 --- pandora_console/include/class/NetworkMap.class.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pandora_console/include/class/NetworkMap.class.php b/pandora_console/include/class/NetworkMap.class.php index dba51499f4..c1061fe120 100644 --- a/pandora_console/include/class/NetworkMap.class.php +++ b/pandora_console/include/class/NetworkMap.class.php @@ -1616,6 +1616,16 @@ class NetworkMap if (is_array($node['style']) === false) { $node['style'] = json_decode($node['style'], true); + + // Add styles. + if (isset($source_data['style']) === true + && is_array($source_data['style']) === true + ) { + $node['style'] = array_merge( + $node['style'], + $source_data['style'] + ); + } } // Propagate styles. @@ -2722,6 +2732,7 @@ class NetworkMap } $this->nodesJS = $this->nodesToJS($nodes); + $output .= 'networkmap.nodes = ('.json_encode($this->nodesJS).");\n"; // Clean. From b9db5fdb6f7092d8fb717b56f8403bce3353da5e Mon Sep 17 00:00:00 2001 From: fbsanchez <fborja.sanchez@artica.es> Date: Fri, 5 Apr 2019 17:20:45 +0200 Subject: [PATCH 18/31] wip discovery f3 Former-commit-id: 6b9f5bc3995a16414e1c1a9201983f33eb6908ad --- pandora_server/lib/PandoraFMS/Recon/Base.pm | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/pandora_server/lib/PandoraFMS/Recon/Base.pm b/pandora_server/lib/PandoraFMS/Recon/Base.pm index 6df41c4f92..8e18f659e8 100644 --- a/pandora_server/lib/PandoraFMS/Recon/Base.pm +++ b/pandora_server/lib/PandoraFMS/Recon/Base.pm @@ -1468,10 +1468,10 @@ sub db_scan($) { call('message', 'Cannot connect to target ' . $target, 3); $self->{'summary'}->{'not_alive'} += 1; push @modules, { - name => 'mysql_connection', + name => $type . ' connection', type => 'generic_proc', data => 0, - description => 'MySQL availability' + description => $type . ' availability' }; } else { @@ -1481,10 +1481,10 @@ sub db_scan($) { $self->{'summary'}->{'alive'} += 1; push @modules, { - name => 'mysql_connection', + name => $type . ' connection', type => 'generic_proc', data => 1, - description => 'MySQL availability' + description => $type . ' availability' }; # Analyze. @@ -1527,11 +1527,12 @@ sub db_scan($) { } # Put engine agent at the beginning of the list. + my $version = $dbObj->get_version(); unshift @data,{ 'agent_data' => { 'agent_name' => $dbObj->get_agent_name(), 'os' => $type, - 'os_version' => 'Discovery', + 'os_version' => (defined($version) ? $version : 'Discovery'), 'interval' => $self->{'task_data'}->{'interval_sweep'}, 'id_group' => $self->{'task_data'}->{'id_group'}, 'address' => $dbObj->get_host(), From 54bd3bf08954d4b51fed59dbd3b110b503a14322 Mon Sep 17 00:00:00 2001 From: fbsanchez <fborja.sanchez@artica.es> Date: Mon, 8 Apr 2019 16:23:32 +0200 Subject: [PATCH 19/31] Discovery F3 Former-commit-id: 1990149c5f5795f825bc337fd7ae29d360348d45 --- .../lib/PandoraFMS/DiscoveryServer.pm | 2 +- pandora_server/lib/PandoraFMS/Recon/Base.pm | 33 +++++++++++++++++-- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/pandora_server/lib/PandoraFMS/DiscoveryServer.pm b/pandora_server/lib/PandoraFMS/DiscoveryServer.pm index 44cd4dcdbb..8e268f78cc 100644 --- a/pandora_server/lib/PandoraFMS/DiscoveryServer.pm +++ b/pandora_server/lib/PandoraFMS/DiscoveryServer.pm @@ -494,7 +494,7 @@ sub PandoraFMS::Recon::Base::create_agents($$) { # Update agent information pandora_update_agent( - $pa_config, time(), $agent_id, + $pa_config, strftime("%Y-%m-%d %H:%M:%S", localtime()), $agent_id, $agent->{'os_version'}, $agent->{'agent_version'}, $agent->{'interval'}, $dbh, undef, $parent_id ); diff --git a/pandora_server/lib/PandoraFMS/Recon/Base.pm b/pandora_server/lib/PandoraFMS/Recon/Base.pm index 8e18f659e8..97b239ce95 100644 --- a/pandora_server/lib/PandoraFMS/Recon/Base.pm +++ b/pandora_server/lib/PandoraFMS/Recon/Base.pm @@ -1448,16 +1448,28 @@ sub db_scan($) { my @targets = split /,/, $self->{'task_data'}->{'subnet'}; + my $global_step = 100 / (scalar @targets); + my $global_percent = 0; my $i = 0; foreach my $target (@targets) { my @data; my @modules; + + $self->{'step'} = STEP_DATABASE_SCAN; + $self->{'c_network_name'} = $target; + $self->{'c_network_percent'} = 0; + + # Send message call('message', 'Checking target ' . $target, 10); # Force target acquirement. $self->{'task_data'}->{'dbhost'} = $target; $self->{'task_data'}->{'target_index'} = $i++; + # Update progress + $self->{'c_network_percent'} = 10; + $self->call('update_progress', $global_percent + (10 / (scalar @targets))); + # Connect to target. my $dbObj = PandoraFMS::Recon::Util::enterprise_new( 'PandoraFMS::Recon::Applications::'.$type, @@ -1466,6 +1478,10 @@ sub db_scan($) { if (!$dbObj->is_connected()) { call('message', 'Cannot connect to target ' . $target, 3); + $global_percent += $global_step; + $self->{'c_network_percent'} = 90; + # Update progress + $self->call('update_progress', $global_percent + (90 / (scalar @targets))); $self->{'summary'}->{'not_alive'} += 1; push @modules, { name => $type . ' connection', @@ -1489,8 +1505,9 @@ sub db_scan($) { # Analyze. $self->{'step'} = STEP_STATISTICS; + $self->{'c_network_percent'} = 30; + $self->call('update_progress', $global_percent + (30 / (scalar @targets))); $self->{'c_network_name'} = $dbObj->get_host(); - $self->call('update_progress', 10); # Retrieve connection statistics. # Retrieve uptime statistics @@ -1498,15 +1515,21 @@ sub db_scan($) { # Retrieve connections # Retrieve innodb # Retrieve cache + $self->{'c_network_percent'} = 50; + $self->call('update_progress', $global_percent + (50 / (scalar @targets))); push @modules, $dbObj->get_statistics(); - $self->call('update_progress', 50); # Custom queries. + $self->{'step'} = STEP_CUSTOM_QUERIES; + $self->{'c_network_percent'} = 80; + $self->call('update_progress', $global_percent + (80 / (scalar @targets))); push @modules, $dbObj->execute_custom_queries(); - $self->call('update_progress', 90); if (defined($dbObjCfg->{'scan_databases'}) && $dbObjCfg->{'scan_databases'} == 1) { + # Skip database scan in Oracle tasks + next if $self->{'type'} == DISCOVERY_APP_ORACLE; + my $__data = $dbObj->scan_databases(); if (ref($__data) eq "ARRAY") { @@ -1545,6 +1568,10 @@ sub db_scan($) { # Destroy item. undef($dbObj); + + $global_percent += $global_step; + $self->{'c_network_percent'} = 100; + $self->call('update_progress', $global_percent); } # Update progress. From d5b1ac556522aad498ce216ae9478ee64f33aea7 Mon Sep 17 00:00:00 2001 From: Daniel Barbero Martin <daniel.barbero@artica.es> Date: Mon, 8 Apr 2019 18:28:27 +0200 Subject: [PATCH 20/31] fixed map IPAM Former-commit-id: a1334a1691a3e861f2510ac7d440f5730928ad9a --- .../include/class/NetworkMap.class.php | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/pandora_console/include/class/NetworkMap.class.php b/pandora_console/include/class/NetworkMap.class.php index c1061fe120..fd7274b94f 100644 --- a/pandora_console/include/class/NetworkMap.class.php +++ b/pandora_console/include/class/NetworkMap.class.php @@ -1242,6 +1242,11 @@ class NetworkMap return ''; } + if ($this->mapOptions['fixed_positions']) { + // Ignore. + return; + } + $dot_str = ''; // Color is being printed by D3, not graphviz. @@ -1259,6 +1264,15 @@ class NetworkMap $radius /= GRAPHVIZ_CONVERSION_FACTOR; + if (is_array($label)) { + $label = array_reduce( + function ($carry, $item) { + $carry .= $item; + return $carry; + } + ); + } + if (strlen($label) > 16) { $label = ui_print_truncate_text($label, 16, false, true, false); } @@ -2079,6 +2093,10 @@ class NetworkMap 'id_source' => $id_source, 'label' => $label, 'image' => null, + 'radius' => max( + $node['width'], + $node['height'] + ), ] ); @@ -2454,6 +2472,8 @@ class NetworkMap $this->map['height'] = $this->mapOptions['height']; } + $this->map['filter']['z_dash'] = $this->mapOptions['z_dash']; + if (is_array($graph) === true) { $nodes = $graph['nodes']; $relations = $graph['relations']; From e59ce5412c8b41db770459d872e76fd116d406c5 Mon Sep 17 00:00:00 2001 From: fbsanchez <fborja.sanchez@artica.es> Date: Tue, 9 Apr 2019 18:33:02 +0200 Subject: [PATCH 21/31] WIP Discovery RDS Former-commit-id: fba3f7dbd44ca131404aa2d3986d3925b9754382 --- .../godmode/wizards/HostDevices.class.php | 17 ++++- .../godmode/wizards/Wizard.main.php | 37 ++++------ .../include/functions_snmp_browser.php | 67 ++++++++++++------- pandora_server/lib/PandoraFMS/Recon/Base.pm | 6 +- 4 files changed, 75 insertions(+), 52 deletions(-) diff --git a/pandora_console/godmode/wizards/HostDevices.class.php b/pandora_console/godmode/wizards/HostDevices.class.php index e4e0e97fdc..b46828c271 100755 --- a/pandora_console/godmode/wizards/HostDevices.class.php +++ b/pandora_console/godmode/wizards/HostDevices.class.php @@ -149,7 +149,8 @@ class HostDevices extends Wizard ), 'label' => __('Discovery'), ], - ] + ], + true ); ui_print_page_header(__('Host & devices'), '', false, '', true, '', false, '', GENERIC_SIZE_TEXT, '', $this->printHeader(true)); @@ -533,7 +534,19 @@ class HostDevices extends Wizard if ($this->page < $this->maxPagesNetScan) { // Avoid to print header out of wizard. $this->prepareBreadcrum($breadcrum); - ui_print_page_header(__('NetScan'), '', false, '', true, '', false, '', GENERIC_SIZE_TEXT, '', $this->printHeader(true)); + ui_print_page_header( + __('NetScan'), + '', + false, + '', + true, + '', + false, + '', + GENERIC_SIZE_TEXT, + '', + $this->printHeader(true) + ); } if (isset($this->page) === true diff --git a/pandora_console/godmode/wizards/Wizard.main.php b/pandora_console/godmode/wizards/Wizard.main.php index d8a829e277..f043f143db 100644 --- a/pandora_console/godmode/wizards/Wizard.main.php +++ b/pandora_console/godmode/wizards/Wizard.main.php @@ -191,21 +191,20 @@ class Wizard * Builder for breadcrum * * @param array $urls Array of urls to be stored in breadcrum. - * @param boolean $add True if breadcrum should be added instead of - * overwrite it. + * @param boolean $add True if breadcrum should be added + * instead of overwrite it. * * @return void */ - public function prepareBreadcrum(array $urls, bool $add=false, bool $separator_beginning=false) - { + public function prepareBreadcrum( + array $urls, + bool $add=false + ) { $bc = []; $i = 0; - $count = 0; - $array_size = count($urls); + $array_size = (count($urls) - 1); foreach ($urls as $url) { - $count++; - if ($url['selected'] == 1) { $class = 'selected'; } else { @@ -213,20 +212,10 @@ class Wizard } $bc[$i] = ''; - - if ($separator_beginning === true) { - $bc[$i] .= '<span class="breadcrumb_link"> / </span>'; - } - - $bc[$i] .= '<span><a class="breadcrumb_link '.$class.'" href="'.$url['link'].'">'; - $bc[$i] .= $url['label']; - $bc[$i] .= '</a>'; - if ($count < $array_size) { - $bc[$i] .= '<span class="breadcrumb_link"> / </span>'; - } - + $bc[$i] .= '<span><a class="breadcrumb_link '.$class.'" href="'.$url['link'].'">'; + $bc[$i] .= $url['label']; + $bc[$i] .= '</a>'; $bc[$i] .= '</span>'; - $i++; } @@ -235,7 +224,6 @@ class Wizard } else { $this->setBreadcrum($bc); } - } @@ -275,7 +263,10 @@ class Wizard */ public function printBreadcrum() { - return implode('', $this->breadcrum); + return implode( + '<span class="breadcrumb_link"> / </span>', + $this->breadcrum + ); } diff --git a/pandora_console/include/functions_snmp_browser.php b/pandora_console/include/functions_snmp_browser.php index fd68b77e54..d22dd5dc1e 100644 --- a/pandora_console/include/functions_snmp_browser.php +++ b/pandora_console/include/functions_snmp_browser.php @@ -54,10 +54,13 @@ function snmp_browser_print_tree( $last=0, $last_array=[], $sufix=false, - $checked=[] + $checked=[], + $return=false ) { static $url = false; + $output = ''; + // Get the base URL for images. if ($url === false) { $url = ui_get_full_url('operation/tree', false, false, false); @@ -73,9 +76,9 @@ function snmp_browser_print_tree( $last_array[$depth] = $last; if ($depth > 0) { - echo "<ul id='ul_$id' style='margin: 0; padding: 0; display: none'>\n"; + $output .= "<ul id='ul_$id' style='margin: 0; padding: 0; display: none'>\n"; } else { - echo "<ul id='ul_$id' style='margin: 0; padding: 0;'>\n"; + $output .= "<ul id='ul_$id' style='margin: 0; padding: 0;'>\n"; } foreach ($tree['__LEAVES__'] as $level => $sub_level) { @@ -83,73 +86,89 @@ function snmp_browser_print_tree( $sub_id = time().rand(0, getrandmax()); // Display the branch. - echo "<li id='li_$sub_id' style='margin: 0; padding: 0;'>"; + $output .= "<li id='li_$sub_id' style='margin: 0; padding: 0;'>"; // Indent sub branches. for ($i = 1; $i <= $depth; $i++) { if ($last_array[$i] == 1) { - echo '<img src="'.$url.'/no_branch.png" style="vertical-align: middle;">'; + $output .= '<img src="'.$url.'/no_branch.png" style="vertical-align: middle;">'; } else { - echo '<img src="'.$url.'/branch.png" style="vertical-align: middle;">'; + $output .= '<img src="'.$url.'/branch.png" style="vertical-align: middle;">'; } } // Branch. if (! empty($sub_level['__LEAVES__'])) { - echo "<a id='anchor_$sub_id' onfocus='javascript: this.blur();' href='javascript: toggleTreeNode(\"$sub_id\", \"$id\");'>"; + $output .= "<a id='anchor_$sub_id' onfocus='javascript: this.blur();' href='javascript: toggleTreeNode(\"$sub_id\", \"$id\");'>"; if ($depth == 0 && $count == 0) { if ($count == $total) { - echo '<img src="'.$url.'/one_closed.png" style="vertical-align: middle;">'; + $output .= '<img src="'.$url.'/one_closed.png" style="vertical-align: middle;">'; } else { - echo '<img src="'.$url.'/first_closed.png" style="vertical-align: middle;">'; + $output .= '<img src="'.$url.'/first_closed.png" style="vertical-align: middle;">'; } } else if ($count == $total) { - echo '<img src="'.$url.'/last_closed.png" style="vertical-align: middle;">'; + $output .= '<img src="'.$url.'/last_closed.png" style="vertical-align: middle;">'; } else { - echo '<img src="'.$url.'/closed.png" style="vertical-align: middle;">'; + $output .= '<img src="'.$url.'/closed.png" style="vertical-align: middle;">'; } - echo '</a>'; + $output .= '</a>'; } + // Leave. else { if ($depth == 0 && $count == 0) { if ($count == $total) { - echo '<img src="'.$url.'/no_branch.png" style="vertical-align: middle;">'; + $output .= '<img src="'.$url.'/no_branch.png" style="vertical-align: middle;">'; } else { - echo '<img src="'.$url.'/first_leaf.png" style="vertical-align: middle;">'; + $output .= '<img src="'.$url.'/first_leaf.png" style="vertical-align: middle;">'; } } else if ($count == $total) { - echo '<img src="'.$url.'/last_leaf.png" style="vertical-align: middle;">'; + $output .= '<img src="'.$url.'/last_leaf.png" style="vertical-align: middle;">'; } else { - echo '<img src="'.$url.'/leaf.png" style="vertical-align: middle;">'; + $output .= '<img src="'.$url.'/leaf.png" style="vertical-align: middle;">'; } } // Branch or leave with branches! if (isset($sub_level['__OID__'])) { - echo "<a onfocus='javascript: this.blur();' href='javascript: snmpGet(\"".addslashes($sub_level['__OID__'])."\");'>"; - echo '<img src="'.$url.'/../../images/eye.png" style="vertical-align: middle;">'; - echo '</a>'; + $output .= "<a onfocus='javascript: this.blur();' href='javascript: snmpGet(\"".addslashes($sub_level['__OID__'])."\");'>"; + $output .= '<img src="'.$url.'/../../images/eye.png" style="vertical-align: middle;">'; + $output .= '</a>'; } $checkbox_name_sufix = ($sufix === true) ? '_'.$level : ''; $checkbox_name = 'create_'.$sub_id.$checkbox_name_sufix; $status = (!empty($checked) && isset($checked[$level])); - echo html_print_checkbox($checkbox_name, 0, $status, true, false, '').' <span>'.$level.'</span>'; + $output .= html_print_checkbox($checkbox_name, 0, $status, true, false, '').' <span>'.$level.'</span>'; if (isset($sub_level['__VALUE__'])) { - echo '<span class="value" style="display: none;"> = '.$sub_level['__VALUE__'].'</span>'; + $output .= '<span class="value" style="display: none;"> = '.$sub_level['__VALUE__'].'</span>'; } - echo '</li>'; + $output .= '</li>'; // Recursively print sub levels. - snmp_browser_print_tree($sub_level, $sub_id, ($depth + 1), ($count == $total ? 1 : 0), $last_array, $sufix, $checked); + $output .= snmp_browser_print_tree( + $sub_level, + $sub_id, + ($depth + 1), + ($count == $total ? 1 : 0), + $last_array, + $sufix, + $checked, + $return + ); $count++; } - echo '</ul>'; + $output .= '</ul>'; + + if ($return == false) { + echo $output; + } + + return $output; } diff --git a/pandora_server/lib/PandoraFMS/Recon/Base.pm b/pandora_server/lib/PandoraFMS/Recon/Base.pm index 97b239ce95..afc677c15a 100644 --- a/pandora_server/lib/PandoraFMS/Recon/Base.pm +++ b/pandora_server/lib/PandoraFMS/Recon/Base.pm @@ -1427,9 +1427,9 @@ sub scan_subnet($) { } ########################################################################## -# Perform a DB scan. +# Perform an Application scan. ########################################################################## -sub db_scan($) { +sub app_scan($) { my ($self) = @_; my ($progress, $step); @@ -1595,7 +1595,7 @@ sub scan($) { if ($self->{'task_data'}->{'type'} == DISCOVERY_APP_MYSQL || $self->{'task_data'}->{'type'} == DISCOVERY_APP_ORACLE) { # Database scan. - return $self->db_scan(); + return $self->app_scan(); } } From 834d5d6c50b485db2d3c93fe65460de4cfc2592d Mon Sep 17 00:00:00 2001 From: fbsanchez <fborja.sanchez@artica.es> Date: Wed, 10 Apr 2019 20:40:03 +0200 Subject: [PATCH 22/31] WIP:Discovery RDS Former-commit-id: d53eb29ec8e7c70c1c76918c1770f65ad81f8ba0 --- .../wizards/DiscoveryTaskList.class.php | 3 + .../lib/PandoraFMS/DiscoveryServer.pm | 1439 +++++++++-------- pandora_server/lib/PandoraFMS/Recon/Base.pm | 57 +- 3 files changed, 788 insertions(+), 711 deletions(-) diff --git a/pandora_console/godmode/wizards/DiscoveryTaskList.class.php b/pandora_console/godmode/wizards/DiscoveryTaskList.class.php index 9d1242f989..20b52c7e36 100644 --- a/pandora_console/godmode/wizards/DiscoveryTaskList.class.php +++ b/pandora_console/godmode/wizards/DiscoveryTaskList.class.php @@ -662,6 +662,9 @@ class DiscoveryTaskList extends Wizard case DISCOVERY_CLOUD_AWS: return 'wiz=cloud&mode=amazonws&page=1'; + case DISCOVERY_CLOUD_AWS_RDS: + return 'wiz=cloud&mode=amazonws&sub=rds&page=0'; + case 'console_task': return 'wiz=ctask'; diff --git a/pandora_server/lib/PandoraFMS/DiscoveryServer.pm b/pandora_server/lib/PandoraFMS/DiscoveryServer.pm index 8e268f78cc..681355011a 100644 --- a/pandora_server/lib/PandoraFMS/DiscoveryServer.pm +++ b/pandora_server/lib/PandoraFMS/DiscoveryServer.pm @@ -53,369 +53,388 @@ my $Sem :shared; my $TaskSem :shared; # IDs from tconfig_os. -use constant OS_OTHER => 10; -use constant OS_ROUTER => 17; -use constant OS_SWITCH => 18; +use constant { + OS_OTHER => 10, + OS_ROUTER => 17, + OS_SWITCH => 18, + DISCOVERY_HOSTDEVICES => 0, + DISCOVERY_HOSTDEVICES_CUSTOM => 1, + DISCOVERY_CLOUD_AWS => 2, + DISCOVERY_APP_VMWARE => 3, + DISCOVERY_APP_MYSQL => 4, + DISCOVERY_APP_ORACLE => 5, + DISCOVERY_CLOUD_AWS_EC2 => 6, + DISCOVERY_CLOUD_AWS_RDS => 7 +}; ######################################################################################## # Discovery Server class constructor. ######################################################################################## sub new ($$$$$$) { - my ($class, $config, $dbh) = @_; - - return undef unless $config->{'reconserver'} == 1 || $config->{'discoveryserver'} == 1; - - if (! -e $config->{'nmap'}) { - logger ($config, ' [E] ' . $config->{'nmap'} . " needed by " . $config->{'rb_product_name'} . " Discovery Server not found.", 1); - print_message ($config, ' [E] ' . $config->{'nmap'} . " needed by " . $config->{'rb_product_name'} . " Discovery Server not found.", 1); - return undef; - } + my ($class, $config, $dbh) = @_; + + return undef unless $config->{'reconserver'} == 1 || $config->{'discoveryserver'} == 1; + + if (! -e $config->{'nmap'}) { + logger ($config, ' [E] ' . $config->{'nmap'} . " needed by " . $config->{'rb_product_name'} . " Discovery Server not found.", 1); + print_message ($config, ' [E] ' . $config->{'nmap'} . " needed by " . $config->{'rb_product_name'} . " Discovery Server not found.", 1); + return undef; + } - # Initialize semaphores and queues - @TaskQueue = (); - %PendingTasks = (); - $Sem = Thread::Semaphore->new; - $TaskSem = Thread::Semaphore->new (0); - - # Restart automatic recon tasks. - db_do ($dbh, 'UPDATE trecon_task SET utimestamp = 0 WHERE id_recon_server = ? AND status <> -1 AND interval_sweep > 0', - get_server_id ($dbh, $config->{'servername'}, DISCOVERYSERVER)); + # Initialize semaphores and queues + @TaskQueue = (); + %PendingTasks = (); + $Sem = Thread::Semaphore->new; + $TaskSem = Thread::Semaphore->new (0); + + # Restart automatic recon tasks. + db_do ($dbh, 'UPDATE trecon_task SET utimestamp = 0 WHERE id_recon_server = ? AND status <> -1 AND interval_sweep > 0', + get_server_id ($dbh, $config->{'servername'}, DISCOVERYSERVER)); - # Reset (but do not restart) manual recon tasks. - db_do ($dbh, 'UPDATE trecon_task SET status = -1 WHERE id_recon_server = ? AND status <> -1 AND interval_sweep = 0', - get_server_id ($dbh, $config->{'servername'}, DISCOVERYSERVER)); + # Reset (but do not restart) manual recon tasks. + db_do ($dbh, 'UPDATE trecon_task SET status = -1 WHERE id_recon_server = ? AND status <> -1 AND interval_sweep = 0', + get_server_id ($dbh, $config->{'servername'}, DISCOVERYSERVER)); - # Call the constructor of the parent class - my $self = $class->SUPER::new($config, DISCOVERYSERVER, \&PandoraFMS::DiscoveryServer::data_producer, \&PandoraFMS::DiscoveryServer::data_consumer, $dbh); - - bless $self, $class; - return $self; + # Call the constructor of the parent class + my $self = $class->SUPER::new($config, DISCOVERYSERVER, \&PandoraFMS::DiscoveryServer::data_producer, \&PandoraFMS::DiscoveryServer::data_consumer, $dbh); + + bless $self, $class; + return $self; } ############################################################################### # Run. ############################################################################### sub run ($) { - my $self = shift; - my $pa_config = $self->getConfig (); - - print_message ($pa_config, " [*] Starting " . $pa_config->{'rb_product_name'} . " Discovery Server.", 1); - my $threads = $pa_config->{'recon_threads'}; + my $self = shift; + my $pa_config = $self->getConfig (); + + print_message ($pa_config, " [*] Starting " . $pa_config->{'rb_product_name'} . " Discovery Server.", 1); + my $threads = $pa_config->{'recon_threads'}; - # Use hightest value - if ($pa_config->{'discovery_threads'} > $pa_config->{'recon_threads'}) { - $threads = $pa_config->{'discovery_threads'}; - } - $self->setNumThreads($threads); - $self->SUPER::run (\@TaskQueue, \%PendingTasks, $Sem, $TaskSem); + # Use hightest value + if ($pa_config->{'discovery_threads'} > $pa_config->{'recon_threads'}) { + $threads = $pa_config->{'discovery_threads'}; + } + $self->setNumThreads($threads); + $self->SUPER::run (\@TaskQueue, \%PendingTasks, $Sem, $TaskSem); } ############################################################################### # Data producer. ############################################################################### sub data_producer ($) { - my $self = shift; - my ($pa_config, $dbh) = ($self->getConfig (), $self->getDBH ()); - - my @tasks; - - my $server_id = get_server_id ($dbh, $pa_config->{'servername'}, $self->getServerType ()); - return @tasks unless defined ($server_id); - - # Manual tasks have interval_sweep = 0 - # Manual tasks are "forced" like the other, setting the utimestamp to 1 - # By default, after create a tasks it takes the utimestamp to 0 - # Status -1 means "done". - - my @rows = get_db_rows ($dbh, 'SELECT * FROM trecon_task - WHERE id_recon_server = ? - AND disabled = 0 - AND ((utimestamp = 0 AND interval_sweep != 0 OR status = 1) - OR (status = -1 AND interval_sweep > 0 AND (utimestamp + interval_sweep) < UNIX_TIMESTAMP()))', $server_id); - foreach my $row (@rows) { - - # Update task status - update_recon_task ($dbh, $row->{'id_rt'}, 1); - - push (@tasks, $row->{'id_rt'}); - } - - return @tasks; + my $self = shift; + my ($pa_config, $dbh) = ($self->getConfig (), $self->getDBH ()); + + my @tasks; + + my $server_id = get_server_id ($dbh, $pa_config->{'servername'}, $self->getServerType ()); + return @tasks unless defined ($server_id); + + # Manual tasks have interval_sweep = 0 + # Manual tasks are "forced" like the other, setting the utimestamp to 1 + # By default, after create a tasks it takes the utimestamp to 0 + # Status -1 means "done". + + my @rows = get_db_rows ($dbh, 'SELECT * FROM trecon_task + WHERE id_recon_server = ? + AND disabled = 0 + AND ((utimestamp = 0 AND interval_sweep != 0 OR status = 1) + OR (status = -1 AND interval_sweep > 0 AND (utimestamp + interval_sweep) < UNIX_TIMESTAMP()))', $server_id); + foreach my $row (@rows) { + + # Update task status + update_recon_task ($dbh, $row->{'id_rt'}, 1); + + push (@tasks, $row->{'id_rt'}); + } + + return @tasks; } ############################################################################### # Data consumer. ############################################################################### sub data_consumer ($$) { - my ($self, $task_id) = @_; - my ($pa_config, $dbh) = ($self->getConfig (), $self->getDBH ()); + my ($self, $task_id) = @_; + my ($pa_config, $dbh) = ($self->getConfig (), $self->getDBH ()); - # Get server id. - my $server_id = get_server_id($dbh, $pa_config->{'servername'}, $self->getServerType()); + # Get server id. + my $server_id = get_server_id($dbh, $pa_config->{'servername'}, $self->getServerType()); - # Get recon task data - my $task = get_db_single_row ($dbh, 'SELECT * FROM trecon_task WHERE id_rt = ?', $task_id); - return -1 unless defined ($task); + # Get recon task data + my $task = get_db_single_row ($dbh, 'SELECT * FROM trecon_task WHERE id_rt = ?', $task_id); + return -1 unless defined ($task); - # Is it a recon script? - if (defined ($task->{'id_recon_script'}) && ($task->{'id_recon_script'} != 0)) { - exec_recon_script ($pa_config, $dbh, $task); - return; - } else { - logger($pa_config, 'Starting recon task for net ' . $task->{'subnet'} . '.', 10); - } + # Is it a recon script? + if (defined ($task->{'id_recon_script'}) && ($task->{'id_recon_script'} != 0)) { + exec_recon_script ($pa_config, $dbh, $task); + return; + } else { + logger($pa_config, 'Starting recon task for net ' . $task->{'subnet'} . '.', 10); + } - eval { - my @subnets = split(/,/, safe_output($task->{'subnet'})); - my @communities = split(/,/, safe_output($task->{'snmp_community'})); - my @auth_strings = (); - if(defined($task->{'auth_strings'})) { - @auth_strings = split(/,/, safe_output($task->{'auth_strings'})); - } + eval { + my @subnets = split(/,/, safe_output($task->{'subnet'})); + my @communities = split(/,/, safe_output($task->{'snmp_community'})); + my @auth_strings = (); + if(defined($task->{'auth_strings'})) { + @auth_strings = split(/,/, safe_output($task->{'auth_strings'})); + } - my $main_event = pandora_event($pa_config, "[Discovery] Execution summary",$task->{'id_group'}, 0, 0, 0, 0, 'system', 0, $dbh); + my $main_event = pandora_event($pa_config, "[Discovery] Execution summary",$task->{'id_group'}, 0, 0, 0, 0, 'system', 0, $dbh); - my $recon = new PandoraFMS::Recon::Base( - communities => \@communities, - dbh => $dbh, - group_id => $task->{'id_group'}, - id_os => $task->{'id_os'}, - id_network_profile => $task->{'id_network_profile'}, - os_detection => $task->{'os_detect'}, - parent_detection => $task->{'parent_detection'}, - parent_recursion => $task->{'parent_recursion'}, - pa_config => $pa_config, - recon_ports => $task->{'recon_ports'}, - resolve_names => $task->{'resolve_names'}, - snmp_auth_user => $task->{'snmp_auth_user'}, - snmp_auth_pass => $task->{'snmp_auth_pass'}, - snmp_auth_method => $task->{'snmp_auth_method'}, - snmp_checks => $task->{'snmp_checks'}, - snmp_enabled => $task->{'snmp_enabled'}, - snmp_privacy_method => $task->{'snmp_privacy_method'}, - snmp_privacy_pass => $task->{'snmp_privacy_pass'}, - snmp_security_level => $task->{'snmp_security_level'}, - snmp_timeout => $task->{'snmp_timeout'}, - snmp_version => $task->{'snmp_version'}, - subnets => \@subnets, - task_id => $task->{'id_rt'}, - vlan_cache_enabled => $task->{'vlan_enabled'}, - wmi_enabled => $task->{'wmi_enabled'}, - auth_strings_array => \@auth_strings, - autoconfiguration_enabled => $task->{'autoconfiguration_enabled'}, - main_event_id => $main_event, - server_id => $server_id, - %{$pa_config}, - task_data => $task - ); + my %cnf_extra; + if ($task->{'type'} == DISCOVERY_CLOUD_AWS_EC2 + || $task->{'type'} == DISCOVERY_CLOUD_AWS_RDS) { + $cnf_extra{'aws_access_key_id'} = pandora_get_config_value($dbh, 'aws_access_key_id'); + $cnf_extra{'aws_secret_access_key'} = pandora_get_config_value($dbh, 'aws_secret_access_key'); + $cnf_extra{'cloud_util_path'} = pandora_get_config_value($dbh, 'cloud_util_path'); + } - $recon->scan(); - }; - if ($@) { - update_recon_task ($dbh, $task_id, -1); - return; - } + my $recon = new PandoraFMS::Recon::Base( + communities => \@communities, + dbh => $dbh, + group_id => $task->{'id_group'}, + id_os => $task->{'id_os'}, + id_network_profile => $task->{'id_network_profile'}, + os_detection => $task->{'os_detect'}, + parent_detection => $task->{'parent_detection'}, + parent_recursion => $task->{'parent_recursion'}, + pa_config => $pa_config, + recon_ports => $task->{'recon_ports'}, + resolve_names => $task->{'resolve_names'}, + snmp_auth_user => $task->{'snmp_auth_user'}, + snmp_auth_pass => $task->{'snmp_auth_pass'}, + snmp_auth_method => $task->{'snmp_auth_method'}, + snmp_checks => $task->{'snmp_checks'}, + snmp_enabled => $task->{'snmp_enabled'}, + snmp_privacy_method => $task->{'snmp_privacy_method'}, + snmp_privacy_pass => $task->{'snmp_privacy_pass'}, + snmp_security_level => $task->{'snmp_security_level'}, + snmp_timeout => $task->{'snmp_timeout'}, + snmp_version => $task->{'snmp_version'}, + subnets => \@subnets, + task_id => $task->{'id_rt'}, + vlan_cache_enabled => $task->{'vlan_enabled'}, + wmi_enabled => $task->{'wmi_enabled'}, + auth_strings_array => \@auth_strings, + autoconfiguration_enabled => $task->{'autoconfiguration_enabled'}, + main_event_id => $main_event, + server_id => $server_id, + %{$pa_config}, + task_data => $task, + %cnf_extra + ); + + $recon->scan(); + }; + if ($@) { + update_recon_task ($dbh, $task_id, -1); + return; + } } ########################################################################## # Update recon task status. ########################################################################## sub update_recon_task ($$$) { - my ($dbh, $id_task, $status) = @_; - - db_do ($dbh, 'UPDATE trecon_task SET utimestamp = ?, status = ? WHERE id_rt = ?', time (), $status, $id_task); + my ($dbh, $id_task, $status) = @_; + + db_do ($dbh, 'UPDATE trecon_task SET utimestamp = ?, status = ? WHERE id_rt = ?', time (), $status, $id_task); } ########################################################################## # Executes recon scripts ########################################################################## sub exec_recon_script ($$$) { - my ($pa_config, $dbh, $task) = @_; - - # Get recon plugin data - my $script = get_db_single_row ($dbh, 'SELECT * FROM trecon_script WHERE id_recon_script = ?', $task->{'id_recon_script'}); - return -1 unless defined ($script); - - logger($pa_config, 'Executing recon script ' . safe_output($script->{'name'}), 10); - - my $command = safe_output($script->{'script'}); - - my $macros = safe_output($task->{'macros'}); + my ($pa_config, $dbh, $task) = @_; + + # Get recon plugin data + my $script = get_db_single_row ($dbh, 'SELECT * FROM trecon_script WHERE id_recon_script = ?', $task->{'id_recon_script'}); + return -1 unless defined ($script); + + logger($pa_config, 'Executing recon script ' . safe_output($script->{'name'}), 10); + + my $command = safe_output($script->{'script'}); + + my $macros = safe_output($task->{'macros'}); - # \r and \n should be escaped for decode_json(). - $macros =~ s/\n/\\n/g; - $macros =~ s/\r/\\r/g; - my $decoded_macros; - - if ($macros) { - eval { - $decoded_macros = decode_json(encode_utf8($macros)); - }; - } - - my $macros_parameters = ''; - - # Add module macros as parameter - if(ref($decoded_macros) eq "HASH") { - # Convert the hash to a sorted array - my @sorted_macros; - while (my ($i, $m) = each (%{$decoded_macros})) { - $sorted_macros[$i] = $m; - } + # \r and \n should be escaped for decode_json(). + $macros =~ s/\n/\\n/g; + $macros =~ s/\r/\\r/g; + my $decoded_macros; + + if ($macros) { + eval { + $decoded_macros = decode_json(encode_utf8($macros)); + }; + } + + my $macros_parameters = ''; + + # Add module macros as parameter + if(ref($decoded_macros) eq "HASH") { + # Convert the hash to a sorted array + my @sorted_macros; + while (my ($i, $m) = each (%{$decoded_macros})) { + $sorted_macros[$i] = $m; + } - # Remove the 0 position - shift @sorted_macros; + # Remove the 0 position + shift @sorted_macros; - foreach my $m (@sorted_macros) { - $macros_parameters = $macros_parameters . ' "' . $m->{"value"} . '"'; - } - } + foreach my $m (@sorted_macros) { + $macros_parameters = $macros_parameters . ' "' . $m->{"value"} . '"'; + } + } - my $ent_script = 0; - my $args = enterprise_hook('discovery_custom_recon_scripts',[$pa_config, $dbh, $task, $script]); - if (!$args) { - $args = "$task->{'id_rt'} $task->{'id_group'} $task->{'create_incident'} $macros_parameters"; - } else { - $ent_script = 1; - } - - if (-x $command) { - my $exec_output = `$command $args`; - logger($pa_config, "Execution output: \n". $exec_output, 10); - } else { - logger($pa_config, "Cannot execute recon task command $command.", 10); - } - - # Only update the timestamp in case something went wrong. The script should set the status. - db_do ($dbh, 'UPDATE trecon_task SET utimestamp = ? WHERE id_rt = ?', time (), $task->{'id_rt'}); + my $ent_script = 0; + my $args = enterprise_hook('discovery_custom_recon_scripts',[$pa_config, $dbh, $task, $script]); + if (!$args) { + $args = "$task->{'id_rt'} $task->{'id_group'} $task->{'create_incident'} $macros_parameters"; + } else { + $ent_script = 1; + } + + if (-x $command) { + my $exec_output = `$command $args`; + logger($pa_config, "Execution output: \n". $exec_output, 10); + } else { + logger($pa_config, "Cannot execute recon task command $command.", 10); + } + + # Only update the timestamp in case something went wrong. The script should set the status. + db_do ($dbh, 'UPDATE trecon_task SET utimestamp = ? WHERE id_rt = ?', time (), $task->{'id_rt'}); - if ($ent_script == 1) { - enterprise_hook('discovery_clean_custom_recon',[$pa_config, $dbh, $task, $script]); - } - - logger($pa_config, 'Done executing recon script ' . safe_output($script->{'name'}), 10); - return 0; + if ($ent_script == 1) { + enterprise_hook('discovery_clean_custom_recon',[$pa_config, $dbh, $task, $script]); + } + + logger($pa_config, 'Done executing recon script ' . safe_output($script->{'name'}), 10); + return 0; } ########################################################################## # Guess the OS using xprobe2 or nmap. ########################################################################## sub PandoraFMS::Recon::Base::guess_os($$) { - my ($self, $device) = @_; + my ($self, $device) = @_; - # OS detection disabled. Use the device type. - if ($self->{'os_detection'} == 0) { - my $device_type = $self->get_device_type($device); - return OS_OTHER unless defined($device_type); + # OS detection disabled. Use the device type. + if ($self->{'os_detection'} == 0) { + my $device_type = $self->get_device_type($device); + return OS_OTHER unless defined($device_type); - return OS_ROUTER if ($device_type eq 'router'); - return OS_SWITCH if ($device_type eq 'switch'); - return OS_OTHER; - } + return OS_ROUTER if ($device_type eq 'router'); + return OS_SWITCH if ($device_type eq 'switch'); + return OS_OTHER; + } - # Use xprobe2 if available - if (-e $self->{pa_config}->{xprobe2}) { - my $output = `"$self->{pa_config}->{xprobe2}" $device 2>$DEVNULL | grep 'Running OS' | head -1`; - return OS_OTHER if ($? != 0); - return pandora_get_os($self->{'dbh'}, $output); - } - - # Use nmap by default - if (-e $self->{pa_config}->{nmap}) { - my $output = `"$self->{pa_config}->{nmap}" -F -O $device 2>$DEVNULL | grep 'Aggressive OS guesses'`; - return OS_OTHER if ($? != 0); - return pandora_get_os($self->{'dbh'}, $output); - } + # Use xprobe2 if available + if (-e $self->{pa_config}->{xprobe2}) { + my $output = `"$self->{pa_config}->{xprobe2}" $device 2>$DEVNULL | grep 'Running OS' | head -1`; + return OS_OTHER if ($? != 0); + return pandora_get_os($self->{'dbh'}, $output); + } + + # Use nmap by default + if (-e $self->{pa_config}->{nmap}) { + my $output = `"$self->{pa_config}->{nmap}" -F -O $device 2>$DEVNULL | grep 'Aggressive OS guesses'`; + return OS_OTHER if ($? != 0); + return pandora_get_os($self->{'dbh'}, $output); + } - return OS_OTHER; + return OS_OTHER; } ############################################################################## # Returns the number of open ports from the given list. ############################################################################## sub PandoraFMS::Recon::Base::tcp_scan ($$) { - my ($self, $host) = @_; + my ($self, $host) = @_; - my $open_ports = `"$self->{pa_config}->{nmap}" -p$self->{recon_ports} $host | grep open | wc -l`; - return $open_ports; + my $open_ports = `"$self->{pa_config}->{nmap}" -p$self->{recon_ports} $host | grep open | wc -l`; + return $open_ports; } ########################################################################## # Create network profile modules for the given agent. ########################################################################## sub PandoraFMS::Recon::Base::create_network_profile_modules($$$) { - my ($self, $agent_id, $device) = @_; - - return unless ($self->{'id_network_profile'} > 0); - - # Get network components associated to the network profile. - my @np_components = get_db_rows($self->{'dbh'}, 'SELECT * FROM tnetwork_profile_component WHERE id_np = ?', $self->{'id_network_profile'}); - foreach my $np_component (@np_components) { + my ($self, $agent_id, $device) = @_; + + return unless ($self->{'id_network_profile'} > 0); + + # Get network components associated to the network profile. + my @np_components = get_db_rows($self->{'dbh'}, 'SELECT * FROM tnetwork_profile_component WHERE id_np = ?', $self->{'id_network_profile'}); + foreach my $np_component (@np_components) { - # Get network component data - my $component = get_db_single_row($self->{'dbh'}, 'SELECT * FROM tnetwork_component WHERE id_nc = ?', $np_component->{'id_nc'}); - if (!defined ($component)) { - $self->call('message', "Network component ID " . $np_component->{'id_nc'} . " not found.", 5); - next; - } + # Get network component data + my $component = get_db_single_row($self->{'dbh'}, 'SELECT * FROM tnetwork_component WHERE id_nc = ?', $np_component->{'id_nc'}); + if (!defined ($component)) { + $self->call('message', "Network component ID " . $np_component->{'id_nc'} . " not found.", 5); + next; + } - # Use snmp_community from network task instead the component snmp_community - $component->{'snmp_community'} = safe_output($self->get_community($device)); - $component->{'tcp_send'} = $self->{'snmp_version'}; - $component->{'custom_string_1'} = $self->{'snmp_privacy_method'}; - $component->{'custom_string_2'} = $self->{'snmp_privacy_pass'}; - $component->{'custom_string_3'} = $self->{'snmp_security_level'}; - $component->{'plugin_parameter'} = $self->{'snmp_auth_method'}; - $component->{'plugin_user'} = $self->{'snmp_auth_user'}; - $component->{'plugin_pass'} = $self->{'snmp_auth_pass'}; + # Use snmp_community from network task instead the component snmp_community + $component->{'snmp_community'} = safe_output($self->get_community($device)); + $component->{'tcp_send'} = $self->{'snmp_version'}; + $component->{'custom_string_1'} = $self->{'snmp_privacy_method'}; + $component->{'custom_string_2'} = $self->{'snmp_privacy_pass'}; + $component->{'custom_string_3'} = $self->{'snmp_security_level'}; + $component->{'plugin_parameter'} = $self->{'snmp_auth_method'}; + $component->{'plugin_user'} = $self->{'snmp_auth_user'}; + $component->{'plugin_pass'} = $self->{'snmp_auth_pass'}; - pandora_create_module_from_network_component($self->{'pa_config'}, $component, $agent_id, $self->{'dbh'}); - } + pandora_create_module_from_network_component($self->{'pa_config'}, $component, $agent_id, $self->{'dbh'}); + } } ########################################################################## # Connect the given devices in the Pandora FMS database. ########################################################################## sub PandoraFMS::Recon::Base::connect_agents($$$$$) { - my ($self, $dev_1, $if_1, $dev_2, $if_2) = @_; + my ($self, $dev_1, $if_1, $dev_2, $if_2) = @_; - # Get the agent for the first device. - my $agent_1 = get_agent_from_addr($self->{'dbh'}, $dev_1); - if (!defined($agent_1)) { - $agent_1 = get_agent_from_name($self->{'dbh'}, $dev_1); - } - return unless defined($agent_1); + # Get the agent for the first device. + my $agent_1 = get_agent_from_addr($self->{'dbh'}, $dev_1); + if (!defined($agent_1)) { + $agent_1 = get_agent_from_name($self->{'dbh'}, $dev_1); + } + return unless defined($agent_1); - # Get the agent for the second device. - my $agent_2 = get_agent_from_addr($self->{'dbh'}, $dev_2); - if (!defined($agent_2)) { - $agent_2 = get_agent_from_name($self->{'dbh'}, $dev_2); - } - return unless defined($agent_2); + # Get the agent for the second device. + my $agent_2 = get_agent_from_addr($self->{'dbh'}, $dev_2); + if (!defined($agent_2)) { + $agent_2 = get_agent_from_name($self->{'dbh'}, $dev_2); + } + return unless defined($agent_2); - # Use ping modules by default. - $if_1 = 'ping' if ($if_1 eq ''); - $if_2 = 'ping' if ($if_2 eq ''); + # Use ping modules by default. + $if_1 = 'ping' if ($if_1 eq ''); + $if_2 = 'ping' if ($if_2 eq ''); - # Check whether the modules exists. - my $module_name_1 = $if_1 eq 'ping' ? 'ping' : "${if_1}_ifOperStatus"; - my $module_name_2 = $if_2 eq 'ping' ? 'ping' : "${if_2}_ifOperStatus"; - my $module_id_1 = get_agent_module_id($self->{'dbh'}, $module_name_1, $agent_1->{'id_agente'}); - if ($module_id_1 <= 0) { - $self->call('message', "ERROR: Module " . safe_output($module_name_1) . " does not exist for agent $dev_1.", 5); - return; - } - my $module_id_2 = get_agent_module_id($self->{'dbh'}, $module_name_2, $agent_2->{'id_agente'}); - if ($module_id_2 <= 0) { - $self->call('message', "ERROR: Module " . safe_output($module_name_2) . " does not exist for agent $dev_2.", 5); - return; - } + # Check whether the modules exists. + my $module_name_1 = $if_1 eq 'ping' ? 'ping' : "${if_1}_ifOperStatus"; + my $module_name_2 = $if_2 eq 'ping' ? 'ping' : "${if_2}_ifOperStatus"; + my $module_id_1 = get_agent_module_id($self->{'dbh'}, $module_name_1, $agent_1->{'id_agente'}); + if ($module_id_1 <= 0) { + $self->call('message', "ERROR: Module " . safe_output($module_name_1) . " does not exist for agent $dev_1.", 5); + return; + } + my $module_id_2 = get_agent_module_id($self->{'dbh'}, $module_name_2, $agent_2->{'id_agente'}); + if ($module_id_2 <= 0) { + $self->call('message', "ERROR: Module " . safe_output($module_name_2) . " does not exist for agent $dev_2.", 5); + return; + } - # Connect the modules if they are not already connected. - my $connection_id = get_db_value($self->{'dbh'}, 'SELECT id FROM tmodule_relationship WHERE (module_a = ? AND module_b = ?) OR (module_b = ? AND module_a = ?)', $module_id_1, $module_id_2, $module_id_1, $module_id_2); - if (! defined($connection_id)) { - db_do($self->{'dbh'}, 'INSERT INTO tmodule_relationship (`module_a`, `module_b`, `id_rt`) VALUES(?, ?, ?)', $module_id_1, $module_id_2, $self->{'task_id'}); - } + # Connect the modules if they are not already connected. + my $connection_id = get_db_value($self->{'dbh'}, 'SELECT id FROM tmodule_relationship WHERE (module_a = ? AND module_b = ?) OR (module_b = ? AND module_a = ?)', $module_id_1, $module_id_2, $module_id_1, $module_id_2); + if (! defined($connection_id)) { + db_do($self->{'dbh'}, 'INSERT INTO tmodule_relationship (`module_a`, `module_b`, `id_rt`) VALUES(?, ?, ?)', $module_id_1, $module_id_2, $self->{'task_id'}); + } } @@ -427,96 +446,96 @@ sub PandoraFMS::Recon::Base::connect_agents($$$$$) { # ] ########################################################################## sub PandoraFMS::Recon::Base::create_agents($$) { - my ($self, $data) = @_; + my ($self, $data) = @_; - my $pa_config = $self->{'pa_config'}; - my $dbh = $self->{'dbh'}; - my $server_id = $self->{'server_id'}; + my $pa_config = $self->{'pa_config'}; + my $dbh = $self->{'dbh'}; + my $server_id = $self->{'server_id'}; - return undef if (ref($data) ne "ARRAY"); + return undef if (ref($data) ne "ARRAY"); - foreach my $information (@{$data}) { - my $agent = $information->{'agent_data'}; - my $modules = $information->{'module_data'}; - my $force_processing = 0; + foreach my $information (@{$data}) { + my $agent = $information->{'agent_data'}; + my $modules = $information->{'module_data'}; + my $force_processing = 0; - # Search agent - my $current_agent = PandoraFMS::Core::locate_agent( - $pa_config, $dbh, $agent->{'agent_name'} - ); + # Search agent + my $current_agent = PandoraFMS::Core::locate_agent( + $pa_config, $dbh, $agent->{'agent_name'} + ); - my $parent_id; - if (defined($agent->{'parent_agent_name'})) { - $parent_id = PandoraFMS::Core::locate_agent( - $pa_config, $dbh, $agent->{'parent_agent_name'} - ); - if ($parent_id) { - $parent_id = $parent_id->{'id_agente'}; - } - } + my $parent_id; + if (defined($agent->{'parent_agent_name'})) { + $parent_id = PandoraFMS::Core::locate_agent( + $pa_config, $dbh, $agent->{'parent_agent_name'} + ); + if ($parent_id) { + $parent_id = $parent_id->{'id_agente'}; + } + } - my $agent_id; - my $os_id = get_os_id($dbh, $agent->{'os'}); + my $agent_id; + my $os_id = get_os_id($dbh, $agent->{'os'}); - if ($os_id < 0) { - $os_id = get_os_id($dbh, 'Other'); - } + if ($os_id < 0) { + $os_id = get_os_id($dbh, 'Other'); + } - if (!$current_agent) { - # Create agent. - $agent_id = pandora_create_agent( - $pa_config, $pa_config->{'servername'}, $agent->{'agent_name'}, - $agent->{'address'}, $agent->{'id_group'}, $parent_id, - $os_id, $agent->{'description'}, - $agent->{'interval'}, $dbh, $agent->{'timezone_offset'} - ); + if (!$current_agent) { + # Create agent. + $agent_id = pandora_create_agent( + $pa_config, $pa_config->{'servername'}, $agent->{'agent_name'}, + $agent->{'address'}, $agent->{'id_group'}, $parent_id, + $os_id, $agent->{'description'}, + $agent->{'interval'}, $dbh, $agent->{'timezone_offset'} + ); - $current_agent = $parent_id = PandoraFMS::Core::locate_agent( - $pa_config, $dbh, $agent->{'agent_name'} - ); + $current_agent = $parent_id = PandoraFMS::Core::locate_agent( + $pa_config, $dbh, $agent->{'agent_name'} + ); - $force_processing = 1; + $force_processing = 1; - } else { - $agent_id = $current_agent->{'id_agente'}; - } + } else { + $agent_id = $current_agent->{'id_agente'}; + } - if (!defined($agent_id)) { - return undef; - } + if (!defined($agent_id)) { + return undef; + } - if ($agent->{'address'} ne '') { - pandora_add_agent_address( - $pa_config, $agent_id, $agent->{'agent_name'}, - $agent->{'address'}, $dbh - ); - } + if ($agent->{'address'} ne '') { + pandora_add_agent_address( + $pa_config, $agent_id, $agent->{'agent_name'}, + $agent->{'address'}, $dbh + ); + } - # Update agent information - pandora_update_agent( - $pa_config, strftime("%Y-%m-%d %H:%M:%S", localtime()), $agent_id, - $agent->{'os_version'}, $agent->{'agent_version'}, - $agent->{'interval'}, $dbh, undef, $parent_id - ); + # Update agent information + pandora_update_agent( + $pa_config, strftime("%Y-%m-%d %H:%M:%S", localtime()), $agent_id, + $agent->{'os_version'}, $agent->{'agent_version'}, + $agent->{'interval'}, $dbh, undef, $parent_id + ); - # Add modules. - if (ref($modules) eq "ARRAY") { - foreach my $module (@{$modules}) { - # Translate data structure to simulate XML parser return. - my %data_translated = map { $_ => [ $module->{$_} ] } keys %{$module}; + # Add modules. + if (ref($modules) eq "ARRAY") { + foreach my $module (@{$modules}) { + # Translate data structure to simulate XML parser return. + my %data_translated = map { $_ => [ $module->{$_} ] } keys %{$module}; - # Process modules. - PandoraFMS::DataServer::process_module_data ( - $pa_config, \%data_translated, - $server_id, $current_agent, - $module->{'name'}, $module->{'type'}, - $agent->{'interval'}, - strftime ("%Y/%m/%d %H:%M:%S", localtime()), - $dbh, $force_processing - ); - } - } - } + # Process modules. + PandoraFMS::DataServer::process_module_data ( + $pa_config, \%data_translated, + $server_id, $current_agent, + $module->{'name'}, $module->{'type'}, + $agent->{'interval'}, + strftime ("%Y/%m/%d %H:%M:%S", localtime()), + $dbh, $force_processing + ); + } + } + } } @@ -526,433 +545,433 @@ sub PandoraFMS::Recon::Base::create_agents($$) { # existing) agent, undef on error. ########################################################################## sub PandoraFMS::Recon::Base::create_agent($$) { - my ($self, $device) = @_; + my ($self, $device) = @_; - my @agents = get_db_rows($self->{'dbh'}, - 'SELECT * FROM taddress, taddress_agent, tagente - WHERE tagente.id_agente = taddress_agent.id_agent - AND taddress_agent.id_a = taddress.id_a - AND ip = ?', $device - ); + my @agents = get_db_rows($self->{'dbh'}, + 'SELECT * FROM taddress, taddress_agent, tagente + WHERE tagente.id_agente = taddress_agent.id_agent + AND taddress_agent.id_a = taddress.id_a + AND ip = ?', $device + ); - # Does the host already exist? - my $agent; - foreach my $candidate (@agents) { - $agent = {map {$_} %$candidate}; # copy contents, do not use shallow copy - # exclude $device itself, because it handle corner case when target includes NAT - my @registered = map {$_->{ip}} get_db_rows($self->{'dbh'}, - 'SELECT ip FROM taddress, taddress_agent, tagente - WHERE tagente.id_agente = taddress_agent.id_agent - AND taddress_agent.id_a = taddress.id_a - AND tagente.id_agente = ? - AND taddress.ip != ?', $agent->{id_agente}, $device - ); - foreach my $ip_addr (@registered) { - my @matched = grep { $_ =~ /^$ip_addr$/ } $self->get_addresses($device); - if (scalar(@matched) == 0) { - $agent = undef; - last; - } - } - last if(defined($agent)); # exit loop if match all ip_addr - } + # Does the host already exist? + my $agent; + foreach my $candidate (@agents) { + $agent = {map {$_} %$candidate}; # copy contents, do not use shallow copy + # exclude $device itself, because it handle corner case when target includes NAT + my @registered = map {$_->{ip}} get_db_rows($self->{'dbh'}, + 'SELECT ip FROM taddress, taddress_agent, tagente + WHERE tagente.id_agente = taddress_agent.id_agent + AND taddress_agent.id_a = taddress.id_a + AND tagente.id_agente = ? + AND taddress.ip != ?', $agent->{id_agente}, $device + ); + foreach my $ip_addr (@registered) { + my @matched = grep { $_ =~ /^$ip_addr$/ } $self->get_addresses($device); + if (scalar(@matched) == 0) { + $agent = undef; + last; + } + } + last if(defined($agent)); # exit loop if match all ip_addr + } - if (!defined($agent)) { - $agent = get_agent_from_name($self->{'dbh'}, $device); - } + if (!defined($agent)) { + $agent = get_agent_from_name($self->{'dbh'}, $device); + } - my ($agent_id, $agent_learning); - if (!defined($agent)) { + my ($agent_id, $agent_learning); + if (!defined($agent)) { - # Resolve hostnames. - my $host_name = $self->{'resolve_names'} == 1 ? gethostbyaddr (inet_aton($device), AF_INET) : $device; - $host_name = $device unless defined ($host_name); + # Resolve hostnames. + my $host_name = $self->{'resolve_names'} == 1 ? gethostbyaddr (inet_aton($device), AF_INET) : $device; + $host_name = $device unless defined ($host_name); - # Guess the OS. - my $id_os = $self->guess_os($device); + # Guess the OS. + my $id_os = $self->guess_os($device); - # Are we filtering hosts by OS? - return if ($self->{'id_os'} > 0 && $id_os != $self->{'id_os'}); + # Are we filtering hosts by OS? + return if ($self->{'id_os'} > 0 && $id_os != $self->{'id_os'}); - # Are we filtering hosts by TCP port? - return if ($self->{'recon_ports'} ne '' && $self->tcp_scan($device) == 0); - my $location = get_geoip_info($self->{'pa_config'}, $device); - $agent_id = pandora_create_agent( - $self->{'pa_config'}, $self->{'pa_config'}->{'servername'}, - $host_name, $device, $self->{'group_id'}, 0, $id_os, - '', 300, $self->{'dbh'}, undef, $location->{'longitude'}, - $location->{'latitude'} - ); - return undef unless defined ($agent_id) and ($agent_id > 0); + # Are we filtering hosts by TCP port? + return if ($self->{'recon_ports'} ne '' && $self->tcp_scan($device) == 0); + my $location = get_geoip_info($self->{'pa_config'}, $device); + $agent_id = pandora_create_agent( + $self->{'pa_config'}, $self->{'pa_config'}->{'servername'}, + $host_name, $device, $self->{'group_id'}, 0, $id_os, + '', 300, $self->{'dbh'}, undef, $location->{'longitude'}, + $location->{'latitude'} + ); + return undef unless defined ($agent_id) and ($agent_id > 0); - # Autoconfigure agent - if (defined($self->{'autoconfiguration_enabled'}) && $self->{'autoconfiguration_enabled'} == 1) { - my $agent_data = PandoraFMS::DB::get_db_single_row($self->{'dbh'}, 'SELECT * FROM tagente WHERE id_agente = ?', $agent_id); - # Update agent configuration once, after create agent. - enterprise_hook('autoconfigure_agent', [$self->{'pa_config'}, $host_name, $agent_id, $agent_data, $self->{'dbh'}, 1]); - } - - if (defined($self->{'main_event_id'})) { - my $addresses_str = join(',', safe_output($self->get_addresses($device))); - pandora_extended_event( - $self->{'pa_config'}, $self->{'dbh'}, $self->{'main_event_id'}, - "[Discovery] New " . safe_output($self->get_device_type($device)) . " found " . $host_name . " (" . $addresses_str . ") Agent $agent_id." - ); + # Autoconfigure agent + if (defined($self->{'autoconfiguration_enabled'}) && $self->{'autoconfiguration_enabled'} == 1) { + my $agent_data = PandoraFMS::DB::get_db_single_row($self->{'dbh'}, 'SELECT * FROM tagente WHERE id_agente = ?', $agent_id); + # Update agent configuration once, after create agent. + enterprise_hook('autoconfigure_agent', [$self->{'pa_config'}, $host_name, $agent_id, $agent_data, $self->{'dbh'}, 1]); + } + + if (defined($self->{'main_event_id'})) { + my $addresses_str = join(',', safe_output($self->get_addresses($device))); + pandora_extended_event( + $self->{'pa_config'}, $self->{'dbh'}, $self->{'main_event_id'}, + "[Discovery] New " . safe_output($self->get_device_type($device)) . " found " . $host_name . " (" . $addresses_str . ") Agent $agent_id." + ); - } - - $agent_learning = 1; + } + + $agent_learning = 1; - # Create network profile modules for the agent - $self->create_network_profile_modules($agent_id, $device); - } - else { - $agent_id = $agent->{'id_agente'}; - $agent_learning = $agent->{'modo'}; - } + # Create network profile modules for the agent + $self->create_network_profile_modules($agent_id, $device); + } + else { + $agent_id = $agent->{'id_agente'}; + $agent_learning = $agent->{'modo'}; + } - # Do not create any modules if the agent is not in learning mode. - return unless ($agent_learning == 1); + # Do not create any modules if the agent is not in learning mode. + return unless ($agent_learning == 1); - # Add found IP addresses to the agent. - foreach my $ip_addr ($self->get_addresses($device)) { - my $addr_id = get_addr_id($self->{'dbh'}, $ip_addr); - $addr_id = add_address($self->{'dbh'}, $ip_addr) unless ($addr_id > 0); - next unless ($addr_id > 0); + # Add found IP addresses to the agent. + foreach my $ip_addr ($self->get_addresses($device)) { + my $addr_id = get_addr_id($self->{'dbh'}, $ip_addr); + $addr_id = add_address($self->{'dbh'}, $ip_addr) unless ($addr_id > 0); + next unless ($addr_id > 0); - # Assign the new address to the agent - my $agent_addr_id = get_agent_addr_id($self->{'dbh'}, $addr_id, $agent_id); - if ($agent_addr_id <= 0) { - db_do($self->{'dbh'}, 'INSERT INTO taddress_agent (`id_a`, `id_agent`) - VALUES (?, ?)', $addr_id, $agent_id); - } - } + # Assign the new address to the agent + my $agent_addr_id = get_agent_addr_id($self->{'dbh'}, $addr_id, $agent_id); + if ($agent_addr_id <= 0) { + db_do($self->{'dbh'}, 'INSERT INTO taddress_agent (`id_a`, `id_agent`) + VALUES (?, ?)', $addr_id, $agent_id); + } + } - # Create a ping module. - my $module_id = get_agent_module_id($self->{'dbh'}, "ping", $agent_id); - if ($module_id <= 0) { - my %module = ('id_tipo_modulo' => 6, - 'id_modulo' => 2, - 'nombre' => "ping", - 'descripcion' => '', - 'id_agente' => $agent_id, - 'ip_target' => $device); - pandora_create_module_from_hash ($self->{'pa_config'}, \%module, $self->{'dbh'}); - } + # Create a ping module. + my $module_id = get_agent_module_id($self->{'dbh'}, "ping", $agent_id); + if ($module_id <= 0) { + my %module = ('id_tipo_modulo' => 6, + 'id_modulo' => 2, + 'nombre' => "ping", + 'descripcion' => '', + 'id_agente' => $agent_id, + 'ip_target' => $device); + pandora_create_module_from_hash ($self->{'pa_config'}, \%module, $self->{'dbh'}); + } - # Add interfaces to the agent if it responds to SNMP. - return $agent_id unless ($self->is_snmp_discovered($device)); - my $community = $self->get_community($device); + # Add interfaces to the agent if it responds to SNMP. + return $agent_id unless ($self->is_snmp_discovered($device)); + my $community = $self->get_community($device); - my @output = $self->snmp_get_value_array($device, $PandoraFMS::Recon::Base::IFINDEX); - foreach my $if_index (@output) { - next unless ($if_index =~ /^[0-9]+$/); + my @output = $self->snmp_get_value_array($device, $PandoraFMS::Recon::Base::IFINDEX); + foreach my $if_index (@output) { + next unless ($if_index =~ /^[0-9]+$/); - # Check the status of the interface. - if ($self->{'all_ifaces'} == 0) { - my $if_status = $self->snmp_get_value($device, "$PandoraFMS::Recon::Base::IFOPERSTATUS.$if_index"); - next unless $if_status == 1; - } + # Check the status of the interface. + if ($self->{'all_ifaces'} == 0) { + my $if_status = $self->snmp_get_value($device, "$PandoraFMS::Recon::Base::IFOPERSTATUS.$if_index"); + next unless $if_status == 1; + } - # Fill the module description with the IP and MAC addresses. - my $mac = $self->get_if_mac($device, $if_index); - my $ip = $self->get_if_ip($device, $if_index); - my $if_desc = ($mac ne '' ? "MAC $mac " : '') . ($ip ne '' ? "IP $ip" : ''); + # Fill the module description with the IP and MAC addresses. + my $mac = $self->get_if_mac($device, $if_index); + my $ip = $self->get_if_ip($device, $if_index); + my $if_desc = ($mac ne '' ? "MAC $mac " : '') . ($ip ne '' ? "IP $ip" : ''); - # Get the name of the network interface. - my $if_name = $self->snmp_get_value($device, "$PandoraFMS::Recon::Base::IFNAME.$if_index"); - $if_name = "if$if_index" unless defined ($if_name); - $if_name =~ s/"//g; + # Get the name of the network interface. + my $if_name = $self->snmp_get_value($device, "$PandoraFMS::Recon::Base::IFNAME.$if_index"); + $if_name = "if$if_index" unless defined ($if_name); + $if_name =~ s/"//g; - # Check whether the module already exists. - my $module_id = get_agent_module_id($self->{'dbh'}, "${if_name}_ifOperStatus", $agent_id); - next if ($module_id > 0 && !$agent_learning); - - # Encode problematic characters. - $if_name = safe_input($if_name); - $if_desc = safe_input($if_desc); + # Check whether the module already exists. + my $module_id = get_agent_module_id($self->{'dbh'}, "${if_name}_ifOperStatus", $agent_id); + next if ($module_id > 0 && !$agent_learning); + + # Encode problematic characters. + $if_name = safe_input($if_name); + $if_desc = safe_input($if_desc); - # Interface status module. - $module_id = get_agent_module_id($self->{'dbh'}, "${if_name}_ifOperStatus", $agent_id); - if ($module_id <= 0) { - my %module = ('id_tipo_modulo' => 18, - 'id_modulo' => 2, - 'nombre' => "${if_name}_ifOperStatus", - 'descripcion' => $if_desc, - 'id_agente' => $agent_id, - 'ip_target' => $device, - 'tcp_send' => $self->{'snmp_version'}, - 'custom_string_1' => $self->{'snmp_privacy_method'}, - 'custom_string_2' => $self->{'snmp_privacy_pass'}, - 'custom_string_3' => $self->{'snmp_security_level'}, - 'plugin_parameter' => $self->{'snmp_auth_method'}, - 'plugin_user' => $self->{'snmp_auth_user'}, - 'plugin_pass' => $self->{'snmp_auth_pass'}, - 'snmp_community' => $community, - 'snmp_oid' => "$PandoraFMS::Recon::Base::IFOPERSTATUS.$if_index" - ); - pandora_create_module_from_hash ($self->{'pa_config'}, \%module, $self->{'dbh'}); - } else { - my %module = ( - 'descripcion' => $if_desc, - 'ip_target' => $device, - 'snmp_community' => $community, - 'tcp_send' => $self->{'snmp_version'}, - 'custom_string_1' => $self->{'snmp_privacy_method'}, - 'custom_string_2' => $self->{'snmp_privacy_pass'}, - 'custom_string_3' => $self->{'snmp_security_level'}, - 'plugin_parameter' => $self->{'snmp_auth_method'}, - 'plugin_user' => $self->{'snmp_auth_user'}, - 'plugin_pass' => $self->{'snmp_auth_pass'}, - 'tcp_send' => $self->{'snmp_version'}, - ); - pandora_update_module_from_hash ($self->{'pa_config'}, \%module, 'id_agente_modulo', $module_id, $self->{'dbh'}); - } + # Interface status module. + $module_id = get_agent_module_id($self->{'dbh'}, "${if_name}_ifOperStatus", $agent_id); + if ($module_id <= 0) { + my %module = ('id_tipo_modulo' => 18, + 'id_modulo' => 2, + 'nombre' => "${if_name}_ifOperStatus", + 'descripcion' => $if_desc, + 'id_agente' => $agent_id, + 'ip_target' => $device, + 'tcp_send' => $self->{'snmp_version'}, + 'custom_string_1' => $self->{'snmp_privacy_method'}, + 'custom_string_2' => $self->{'snmp_privacy_pass'}, + 'custom_string_3' => $self->{'snmp_security_level'}, + 'plugin_parameter' => $self->{'snmp_auth_method'}, + 'plugin_user' => $self->{'snmp_auth_user'}, + 'plugin_pass' => $self->{'snmp_auth_pass'}, + 'snmp_community' => $community, + 'snmp_oid' => "$PandoraFMS::Recon::Base::IFOPERSTATUS.$if_index" + ); + pandora_create_module_from_hash ($self->{'pa_config'}, \%module, $self->{'dbh'}); + } else { + my %module = ( + 'descripcion' => $if_desc, + 'ip_target' => $device, + 'snmp_community' => $community, + 'tcp_send' => $self->{'snmp_version'}, + 'custom_string_1' => $self->{'snmp_privacy_method'}, + 'custom_string_2' => $self->{'snmp_privacy_pass'}, + 'custom_string_3' => $self->{'snmp_security_level'}, + 'plugin_parameter' => $self->{'snmp_auth_method'}, + 'plugin_user' => $self->{'snmp_auth_user'}, + 'plugin_pass' => $self->{'snmp_auth_pass'}, + 'tcp_send' => $self->{'snmp_version'}, + ); + pandora_update_module_from_hash ($self->{'pa_config'}, \%module, 'id_agente_modulo', $module_id, $self->{'dbh'}); + } - # Incoming traffic module. - my $if_hc_in_octets = $self->snmp_get_value($device, "$PandoraFMS::Recon::Base::IFHCINOCTECTS.$if_index"); - if (defined($if_hc_in_octets)) { - $module_id = get_agent_module_id($self->{'dbh'}, "${if_name}_ifHCInOctets", $agent_id); - if ($module_id <= 0) { - my %module = ('id_tipo_modulo' => 16, - 'id_modulo' => 2, - 'nombre' => "${if_name}_ifHCInOctets", - 'descripcion' => 'The total number of octets received on the interface, including framing characters. This object is a 64-bit version of ifInOctets.', - 'id_agente' => $agent_id, - 'ip_target' => $device, - 'tcp_send' => $self->{'snmp_version'}, - 'custom_string_1' => $self->{'snmp_privacy_method'}, - 'custom_string_2' => $self->{'snmp_privacy_pass'}, - 'custom_string_3' => $self->{'snmp_security_level'}, - 'plugin_parameter' => $self->{'snmp_auth_method'}, - 'plugin_user' => $self->{'snmp_auth_user'}, - 'plugin_pass' => $self->{'snmp_auth_pass'}, - 'snmp_community' => $community, - 'snmp_oid' => "$PandoraFMS::Recon::Base::IFHCINOCTECTS.$if_index"); - pandora_create_module_from_hash ($self->{'pa_config'}, \%module, $self->{'dbh'}); - } else { - my %module = ( - 'ip_target' => $device, - 'snmp_community' => $community, - 'tcp_send' => $self->{'snmp_version'}, - 'custom_string_1' => $self->{'snmp_privacy_method'}, - 'custom_string_2' => $self->{'snmp_privacy_pass'}, - 'custom_string_3' => $self->{'snmp_security_level'}, - 'plugin_parameter' => $self->{'snmp_auth_method'}, - 'plugin_user' => $self->{'snmp_auth_user'}, - 'plugin_pass' => $self->{'snmp_auth_pass'}, - ); - pandora_update_module_from_hash ($self->{'pa_config'}, \%module, 'id_agente_modulo', $module_id, $self->{'dbh'}); - } - } - # ifInOctets - elsif (defined($self->snmp_get_value($device, "$PandoraFMS::Recon::Base::IFINOCTECTS.$if_index"))) { - $module_id = get_agent_module_id($self->{'dbh'}, "${if_name}_ifInOctets", $agent_id); - if ($module_id <= 0) { - my %module = ('id_tipo_modulo' => 16, - 'id_modulo' => 2, - 'nombre' => "${if_name}_ifInOctets", - 'descripcion' => 'The total number of octets received on the interface, including framing characters.', - 'id_agente' => $agent_id, - 'ip_target' => $device, - 'tcp_send' => $self->{'snmp_version'}, - 'custom_string_1' => $self->{'snmp_privacy_method'}, - 'custom_string_2' => $self->{'snmp_privacy_pass'}, - 'custom_string_3' => $self->{'snmp_security_level'}, - 'plugin_parameter' => $self->{'snmp_auth_method'}, - 'plugin_user' => $self->{'snmp_auth_user'}, - 'plugin_pass' => $self->{'snmp_auth_pass'}, - 'snmp_community' => $community, - 'snmp_oid' => "$PandoraFMS::Recon::Base::IFINOCTECTS.$if_index"); - pandora_create_module_from_hash ($self->{'pa_config'}, \%module, $self->{'dbh'}); - } else { - my %module = ( - 'ip_target' => $device, - 'snmp_community' => $community, - 'tcp_send' => $self->{'snmp_version'}, - 'custom_string_1' => $self->{'snmp_privacy_method'}, - 'custom_string_2' => $self->{'snmp_privacy_pass'}, - 'custom_string_3' => $self->{'snmp_security_level'}, - 'plugin_parameter' => $self->{'snmp_auth_method'}, - 'plugin_user' => $self->{'snmp_auth_user'}, - 'plugin_pass' => $self->{'snmp_auth_pass'}, - ); - pandora_update_module_from_hash ($self->{'pa_config'}, \%module, 'id_agente_modulo', $module_id, $self->{'dbh'}); - } - } + # Incoming traffic module. + my $if_hc_in_octets = $self->snmp_get_value($device, "$PandoraFMS::Recon::Base::IFHCINOCTECTS.$if_index"); + if (defined($if_hc_in_octets)) { + $module_id = get_agent_module_id($self->{'dbh'}, "${if_name}_ifHCInOctets", $agent_id); + if ($module_id <= 0) { + my %module = ('id_tipo_modulo' => 16, + 'id_modulo' => 2, + 'nombre' => "${if_name}_ifHCInOctets", + 'descripcion' => 'The total number of octets received on the interface, including framing characters. This object is a 64-bit version of ifInOctets.', + 'id_agente' => $agent_id, + 'ip_target' => $device, + 'tcp_send' => $self->{'snmp_version'}, + 'custom_string_1' => $self->{'snmp_privacy_method'}, + 'custom_string_2' => $self->{'snmp_privacy_pass'}, + 'custom_string_3' => $self->{'snmp_security_level'}, + 'plugin_parameter' => $self->{'snmp_auth_method'}, + 'plugin_user' => $self->{'snmp_auth_user'}, + 'plugin_pass' => $self->{'snmp_auth_pass'}, + 'snmp_community' => $community, + 'snmp_oid' => "$PandoraFMS::Recon::Base::IFHCINOCTECTS.$if_index"); + pandora_create_module_from_hash ($self->{'pa_config'}, \%module, $self->{'dbh'}); + } else { + my %module = ( + 'ip_target' => $device, + 'snmp_community' => $community, + 'tcp_send' => $self->{'snmp_version'}, + 'custom_string_1' => $self->{'snmp_privacy_method'}, + 'custom_string_2' => $self->{'snmp_privacy_pass'}, + 'custom_string_3' => $self->{'snmp_security_level'}, + 'plugin_parameter' => $self->{'snmp_auth_method'}, + 'plugin_user' => $self->{'snmp_auth_user'}, + 'plugin_pass' => $self->{'snmp_auth_pass'}, + ); + pandora_update_module_from_hash ($self->{'pa_config'}, \%module, 'id_agente_modulo', $module_id, $self->{'dbh'}); + } + } + # ifInOctets + elsif (defined($self->snmp_get_value($device, "$PandoraFMS::Recon::Base::IFINOCTECTS.$if_index"))) { + $module_id = get_agent_module_id($self->{'dbh'}, "${if_name}_ifInOctets", $agent_id); + if ($module_id <= 0) { + my %module = ('id_tipo_modulo' => 16, + 'id_modulo' => 2, + 'nombre' => "${if_name}_ifInOctets", + 'descripcion' => 'The total number of octets received on the interface, including framing characters.', + 'id_agente' => $agent_id, + 'ip_target' => $device, + 'tcp_send' => $self->{'snmp_version'}, + 'custom_string_1' => $self->{'snmp_privacy_method'}, + 'custom_string_2' => $self->{'snmp_privacy_pass'}, + 'custom_string_3' => $self->{'snmp_security_level'}, + 'plugin_parameter' => $self->{'snmp_auth_method'}, + 'plugin_user' => $self->{'snmp_auth_user'}, + 'plugin_pass' => $self->{'snmp_auth_pass'}, + 'snmp_community' => $community, + 'snmp_oid' => "$PandoraFMS::Recon::Base::IFINOCTECTS.$if_index"); + pandora_create_module_from_hash ($self->{'pa_config'}, \%module, $self->{'dbh'}); + } else { + my %module = ( + 'ip_target' => $device, + 'snmp_community' => $community, + 'tcp_send' => $self->{'snmp_version'}, + 'custom_string_1' => $self->{'snmp_privacy_method'}, + 'custom_string_2' => $self->{'snmp_privacy_pass'}, + 'custom_string_3' => $self->{'snmp_security_level'}, + 'plugin_parameter' => $self->{'snmp_auth_method'}, + 'plugin_user' => $self->{'snmp_auth_user'}, + 'plugin_pass' => $self->{'snmp_auth_pass'}, + ); + pandora_update_module_from_hash ($self->{'pa_config'}, \%module, 'id_agente_modulo', $module_id, $self->{'dbh'}); + } + } - # Outgoing traffic module. - my $if_hc_out_octets = $self->snmp_get_value($device, "$PandoraFMS::Recon::Base::IFHCOUTOCTECTS.$if_index"); - if (defined($if_hc_out_octets)) { - $module_id = get_agent_module_id($self->{'dbh'}, "${if_name}_ifHCOutOctets", $agent_id); - if ($module_id <= 0) { - my %module = ('id_tipo_modulo' => 16, - 'id_modulo' => 2, - 'nombre' => "${if_name}_ifHCOutOctets", - 'descripcion' => 'The total number of octets received on the interface, including framing characters. This object is a 64-bit version of ifOutOctets.', - 'id_agente' => $agent_id, - 'ip_target' => $device, - 'tcp_send' => $self->{'snmp_version'}, - 'custom_string_1' => $self->{'snmp_privacy_method'}, - 'custom_string_2' => $self->{'snmp_privacy_pass'}, - 'custom_string_3' => $self->{'snmp_security_level'}, - 'plugin_parameter' => $self->{'snmp_auth_method'}, - 'plugin_user' => $self->{'snmp_auth_user'}, - 'plugin_pass' => $self->{'snmp_auth_pass'}, - 'snmp_community' => $community, - 'snmp_oid' => "$PandoraFMS::Recon::Base::IFHCOUTOCTECTS.$if_index"); - pandora_create_module_from_hash ($self->{'pa_config'}, \%module, $self->{'dbh'}); - } else { - my %module = ( - 'ip_target' => $device, - 'snmp_community' => $community, - 'tcp_send' => $self->{'snmp_version'}, - 'tcp_send' => $self->{'snmp_version'}, - 'custom_string_1' => $self->{'snmp_privacy_method'}, - 'custom_string_2' => $self->{'snmp_privacy_pass'}, - 'custom_string_3' => $self->{'snmp_security_level'}, - 'plugin_parameter' => $self->{'snmp_auth_method'}, - 'plugin_user' => $self->{'snmp_auth_user'}, - 'plugin_pass' => $self->{'snmp_auth_pass'}, - ); - pandora_update_module_from_hash ($self->{'pa_config'}, \%module, 'id_agente_modulo', $module_id, $self->{'dbh'}); - } - } - # ifOutOctets - elsif (defined($self->snmp_get_value($device, "$PandoraFMS::Recon::Base::IFOUTOCTECTS.$if_index"))) { - $module_id = get_agent_module_id($self->{'dbh'}, "${if_name}_ifOutOctets", $agent_id); - if ($module_id <= 0) { - my %module = ('id_tipo_modulo' => 16, - 'id_modulo' => 2, - 'nombre' => "${if_name}_ifOutOctets", - 'descripcion' => 'The total number of octets received on the interface, including framing characters.', - 'id_agente' => $agent_id, - 'ip_target' => $device, - 'tcp_send' => $self->{'snmp_version'}, - 'custom_string_1' => $self->{'snmp_privacy_method'}, - 'custom_string_2' => $self->{'snmp_privacy_pass'}, - 'custom_string_3' => $self->{'snmp_security_level'}, - 'plugin_parameter' => $self->{'snmp_auth_method'}, - 'plugin_user' => $self->{'snmp_auth_user'}, - 'plugin_pass' => $self->{'snmp_auth_pass'}, - 'snmp_community' => $community, - 'snmp_oid' => "$PandoraFMS::Recon::Base::IFOUTOCTECTS.$if_index"); - pandora_create_module_from_hash ($self->{'pa_config'}, \%module, $self->{'dbh'}); - } else { - my %module = ( - 'ip_target' => $device, - 'snmp_community' => $community, - 'tcp_send' => $self->{'snmp_version'}, - 'tcp_send' => $self->{'snmp_version'}, - 'custom_string_1' => $self->{'snmp_privacy_method'}, - 'custom_string_2' => $self->{'snmp_privacy_pass'}, - 'custom_string_3' => $self->{'snmp_security_level'}, - 'plugin_parameter' => $self->{'snmp_auth_method'}, - 'plugin_user' => $self->{'snmp_auth_user'}, - 'plugin_pass' => $self->{'snmp_auth_pass'}, - ); - pandora_update_module_from_hash ($self->{'pa_config'}, \%module, 'id_agente_modulo', $module_id, $self->{'dbh'}); - } - } - } + # Outgoing traffic module. + my $if_hc_out_octets = $self->snmp_get_value($device, "$PandoraFMS::Recon::Base::IFHCOUTOCTECTS.$if_index"); + if (defined($if_hc_out_octets)) { + $module_id = get_agent_module_id($self->{'dbh'}, "${if_name}_ifHCOutOctets", $agent_id); + if ($module_id <= 0) { + my %module = ('id_tipo_modulo' => 16, + 'id_modulo' => 2, + 'nombre' => "${if_name}_ifHCOutOctets", + 'descripcion' => 'The total number of octets received on the interface, including framing characters. This object is a 64-bit version of ifOutOctets.', + 'id_agente' => $agent_id, + 'ip_target' => $device, + 'tcp_send' => $self->{'snmp_version'}, + 'custom_string_1' => $self->{'snmp_privacy_method'}, + 'custom_string_2' => $self->{'snmp_privacy_pass'}, + 'custom_string_3' => $self->{'snmp_security_level'}, + 'plugin_parameter' => $self->{'snmp_auth_method'}, + 'plugin_user' => $self->{'snmp_auth_user'}, + 'plugin_pass' => $self->{'snmp_auth_pass'}, + 'snmp_community' => $community, + 'snmp_oid' => "$PandoraFMS::Recon::Base::IFHCOUTOCTECTS.$if_index"); + pandora_create_module_from_hash ($self->{'pa_config'}, \%module, $self->{'dbh'}); + } else { + my %module = ( + 'ip_target' => $device, + 'snmp_community' => $community, + 'tcp_send' => $self->{'snmp_version'}, + 'tcp_send' => $self->{'snmp_version'}, + 'custom_string_1' => $self->{'snmp_privacy_method'}, + 'custom_string_2' => $self->{'snmp_privacy_pass'}, + 'custom_string_3' => $self->{'snmp_security_level'}, + 'plugin_parameter' => $self->{'snmp_auth_method'}, + 'plugin_user' => $self->{'snmp_auth_user'}, + 'plugin_pass' => $self->{'snmp_auth_pass'}, + ); + pandora_update_module_from_hash ($self->{'pa_config'}, \%module, 'id_agente_modulo', $module_id, $self->{'dbh'}); + } + } + # ifOutOctets + elsif (defined($self->snmp_get_value($device, "$PandoraFMS::Recon::Base::IFOUTOCTECTS.$if_index"))) { + $module_id = get_agent_module_id($self->{'dbh'}, "${if_name}_ifOutOctets", $agent_id); + if ($module_id <= 0) { + my %module = ('id_tipo_modulo' => 16, + 'id_modulo' => 2, + 'nombre' => "${if_name}_ifOutOctets", + 'descripcion' => 'The total number of octets received on the interface, including framing characters.', + 'id_agente' => $agent_id, + 'ip_target' => $device, + 'tcp_send' => $self->{'snmp_version'}, + 'custom_string_1' => $self->{'snmp_privacy_method'}, + 'custom_string_2' => $self->{'snmp_privacy_pass'}, + 'custom_string_3' => $self->{'snmp_security_level'}, + 'plugin_parameter' => $self->{'snmp_auth_method'}, + 'plugin_user' => $self->{'snmp_auth_user'}, + 'plugin_pass' => $self->{'snmp_auth_pass'}, + 'snmp_community' => $community, + 'snmp_oid' => "$PandoraFMS::Recon::Base::IFOUTOCTECTS.$if_index"); + pandora_create_module_from_hash ($self->{'pa_config'}, \%module, $self->{'dbh'}); + } else { + my %module = ( + 'ip_target' => $device, + 'snmp_community' => $community, + 'tcp_send' => $self->{'snmp_version'}, + 'tcp_send' => $self->{'snmp_version'}, + 'custom_string_1' => $self->{'snmp_privacy_method'}, + 'custom_string_2' => $self->{'snmp_privacy_pass'}, + 'custom_string_3' => $self->{'snmp_security_level'}, + 'plugin_parameter' => $self->{'snmp_auth_method'}, + 'plugin_user' => $self->{'snmp_auth_user'}, + 'plugin_pass' => $self->{'snmp_auth_pass'}, + ); + pandora_update_module_from_hash ($self->{'pa_config'}, \%module, 'id_agente_modulo', $module_id, $self->{'dbh'}); + } + } + } - return $agent_id; + return $agent_id; } ########################################################################## # Delete already existing connections. ########################################################################## sub PandoraFMS::Recon::Base::delete_connections($) { - my ($self) = @_; + my ($self) = @_; - $self->call('message', "Deleting connections...", 10); - db_do($self->{'dbh'}, 'DELETE FROM tmodule_relationship WHERE id_rt=?', $self->{'task_id'}); + $self->call('message', "Deleting connections...", 10); + db_do($self->{'dbh'}, 'DELETE FROM tmodule_relationship WHERE id_rt=?', $self->{'task_id'}); } ####################################################################### # Print log messages. ####################################################################### sub PandoraFMS::Recon::Base::message($$$) { - my ($self, $message, $verbosity) = @_; - - logger($self->{'pa_config'}, "[Recon task " . $self->{'task_id'} . "] $message", $verbosity); + my ($self, $message, $verbosity) = @_; + + logger($self->{'pa_config'}, "[Recon task " . $self->{'task_id'} . "] $message", $verbosity); } ########################################################################## # Connect the given hosts to its parent. ########################################################################## sub PandoraFMS::Recon::Base::set_parent($$$) { - my ($self, $host, $parent) = @_; + my ($self, $host, $parent) = @_; - return unless ($self->{'parent_detection'} == 1); + return unless ($self->{'parent_detection'} == 1); - # Get the agent for the host. - my $agent = get_agent_from_addr($self->{'dbh'}, $host); - if (!defined($agent)) { - $agent = get_agent_from_name($self->{'dbh'}, $host); - } - return unless defined($agent); + # Get the agent for the host. + my $agent = get_agent_from_addr($self->{'dbh'}, $host); + if (!defined($agent)) { + $agent = get_agent_from_name($self->{'dbh'}, $host); + } + return unless defined($agent); - # Check if the parent agent exists. - my $agent_parent = get_agent_from_addr($self->{'dbh'}, $parent); - if (!defined($agent_parent)) { - $agent_parent = get_agent_from_name($self->{'dbh'}, $parent); - } - return unless (defined ($agent_parent)); + # Check if the parent agent exists. + my $agent_parent = get_agent_from_addr($self->{'dbh'}, $parent); + if (!defined($agent_parent)) { + $agent_parent = get_agent_from_name($self->{'dbh'}, $parent); + } + return unless (defined ($agent_parent)); - # Is the agent in learning mode? - return unless ($agent_parent->{'modo'} == 1); + # Is the agent in learning mode? + return unless ($agent_parent->{'modo'} == 1); - # Connect the host to its parent. - db_do($self->{'dbh'}, 'UPDATE tagente SET id_parent=? WHERE id_agente=?', $agent_parent->{'id_agente'}, $agent->{'id_agente'}); + # Connect the host to its parent. + db_do($self->{'dbh'}, 'UPDATE tagente SET id_parent=? WHERE id_agente=?', $agent_parent->{'id_agente'}, $agent->{'id_agente'}); } ########################################################################## # Create a WMI module for the given agent. ########################################################################## sub PandoraFMS::Recon::Base::wmi_module { - my ($self, $agent_id, $target, $wmi_query, $wmi_auth, $column, + my ($self, $agent_id, $target, $wmi_query, $wmi_auth, $column, $module_name, $module_description, $module_type, $unit) = @_; - # Check whether the module already exists. - my $module_id = get_agent_module_id($self->{'dbh'}, $module_name, $agent_id); - return if ($module_id > 0); + # Check whether the module already exists. + my $module_id = get_agent_module_id($self->{'dbh'}, $module_name, $agent_id); + return if ($module_id > 0); - my ($user, $pass) = ($wmi_auth ne '') ? split('%', $wmi_auth) : (undef, undef); - my %module = ( - 'descripcion' => safe_input($module_description), - 'id_agente' => $agent_id, - 'id_modulo' => 6, - 'id_tipo_modulo' => get_module_id($self->{'dbh'}, $module_type), - 'ip_target' => $target, - 'nombre' => safe_input($module_name), - 'plugin_pass' => defined($pass) ? $pass : '', - 'plugin_user' => defined($user) ? $user : '', - 'snmp_oid' => $wmi_query, - 'tcp_port' => $column, - 'unit' => defined($unit) ? $unit : '' - ); - - pandora_create_module_from_hash($self->{'pa_config'}, \%module, $self->{'dbh'}); + my ($user, $pass) = ($wmi_auth ne '') ? split('%', $wmi_auth) : (undef, undef); + my %module = ( + 'descripcion' => safe_input($module_description), + 'id_agente' => $agent_id, + 'id_modulo' => 6, + 'id_tipo_modulo' => get_module_id($self->{'dbh'}, $module_type), + 'ip_target' => $target, + 'nombre' => safe_input($module_name), + 'plugin_pass' => defined($pass) ? $pass : '', + 'plugin_user' => defined($user) ? $user : '', + 'snmp_oid' => $wmi_query, + 'tcp_port' => $column, + 'unit' => defined($unit) ? $unit : '' + ); + + pandora_create_module_from_hash($self->{'pa_config'}, \%module, $self->{'dbh'}); } ########################################################################## # Update recon task status. ########################################################################## sub PandoraFMS::Recon::Base::update_progress ($$) { - my ($self, $progress) = @_; + my ($self, $progress) = @_; - my $stats = {}; - if (defined($self->{'summary'}) && $self->{'summary'} ne '') { - $stats->{'summary'} = $self->{'summary'}; - } - $stats->{'step'} = $self->{'step'}; - $stats->{'c_network_name'} = $self->{'c_network_name'}; - $stats->{'c_network_percent'} = $self->{'c_network_percent'}; + my $stats = {}; + if (defined($self->{'summary'}) && $self->{'summary'} ne '') { + $stats->{'summary'} = $self->{'summary'}; + } + $stats->{'step'} = $self->{'step'}; + $stats->{'c_network_name'} = $self->{'c_network_name'}; + $stats->{'c_network_percent'} = $self->{'c_network_percent'}; - # Store progress, last contact and overall status. - db_do ($self->{'dbh'}, 'UPDATE trecon_task SET utimestamp = ?, status = ?, summary = ? WHERE id_rt = ?', - time (), $progress, encode_json($stats), $self->{'task_id'}); + # Store progress, last contact and overall status. + db_do ($self->{'dbh'}, 'UPDATE trecon_task SET utimestamp = ?, status = ?, summary = ? WHERE id_rt = ?', + time (), $progress, encode_json($stats), $self->{'task_id'}); } 1; diff --git a/pandora_server/lib/PandoraFMS/Recon/Base.pm b/pandora_server/lib/PandoraFMS/Recon/Base.pm index afc677c15a..58e0eb8543 100644 --- a/pandora_server/lib/PandoraFMS/Recon/Base.pm +++ b/pandora_server/lib/PandoraFMS/Recon/Base.pm @@ -29,7 +29,9 @@ use constant { DISCOVERY_CLOUD_AWS => 2, DISCOVERY_APP_VMWARE => 3, DISCOVERY_APP_MYSQL => 4, - DISCOVERY_APP_ORACLE => 5 + DISCOVERY_APP_ORACLE => 5, + DISCOVERY_CLOUD_AWS_EC2 => 6, + DISCOVERY_CLOUD_AWS_RDS => 7 }; # /dev/null @@ -1426,6 +1428,54 @@ sub scan_subnet($) { } } + +########################################################################## +# Perform a Cloud scan +########################################################################## +sub cloud_scan($) { + my $self = shift; + my ($progress, $step); + + my $type = ''; + + if ($self->{'task_data'}->{'type'} == DISCOVERY_CLOUD_AWS_EC2 + || $self->{'task_data'}->{'type'} == DISCOVERY_CLOUD_AWS_RDS) { + $type = 'Aws'; + } else { + # Unrecognized task type. + call('message', 'Unrecognized task type', 1); + $self->call('update_progress', -1); + return; + } + + # Initialize cloud object. + my $cloudObj = PandoraFMS::Recon::Util::enterprise_new( + 'PandoraFMS::Recon::Cloud::'.$type, + [ + task_data => $self->{'task_data'}, + aws_access_key_id => $self->{'aws_access_key_id'}, + aws_secret_access_key => $self->{'aws_secret_access_key'}, + cloud_util_path => $self->{'cloud_util_path'}, + parent => $self + ] + + ); + + if (!$cloudObj) { + # Failed to initialize, check Cloud credentials or anything. + call('message', 'Unable to initialize PandoraFMS::Recon::Cloud::'.$type, 3); + } else { + # Let Cloud object manage scan. + $cloudObj->scan(); + } + + # Update progress. + # Done! + $self->{'step'} = ''; + $self->call('update_progress', -1); +} + + ########################################################################## # Perform an Application scan. ########################################################################## @@ -1597,6 +1647,11 @@ sub scan($) { # Database scan. return $self->app_scan(); } + + if ($self->{'task_data'}->{'type'} == DISCOVERY_CLOUD_AWS_RDS) { + # Cloud scan. + return $self->cloud_scan(); + } } # Find devices. From 2af9cbb7119e21b85603326a4952e6e2743c2720 Mon Sep 17 00:00:00 2001 From: fbsanchez <fborja.sanchez@artica.es> Date: Wed, 10 Apr 2019 23:16:18 +0200 Subject: [PATCH 23/31] Discovery RDS Bypass perl thread ENV limitation Former-commit-id: 34ca5374e66c174887683077ba5efcae5412b9bb --- .../lib/PandoraFMS/DiscoveryServer.pm | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/pandora_server/lib/PandoraFMS/DiscoveryServer.pm b/pandora_server/lib/PandoraFMS/DiscoveryServer.pm index 681355011a..cb4ee3dbad 100644 --- a/pandora_server/lib/PandoraFMS/DiscoveryServer.pm +++ b/pandora_server/lib/PandoraFMS/DiscoveryServer.pm @@ -108,10 +108,15 @@ sub new ($$$$$$) { sub run ($) { my $self = shift; my $pa_config = $self->getConfig (); + my $dbh = $self->getDBH(); print_message ($pa_config, " [*] Starting " . $pa_config->{'rb_product_name'} . " Discovery Server.", 1); my $threads = $pa_config->{'recon_threads'}; + # Prepare some environmental variables. + $ENV{'AWS_ACCESS_KEY_ID'} = pandora_get_config_value($dbh, 'aws_access_key_id'); + $ENV{'AWS_SECRET_ACCESS_KEY'} = pandora_get_config_value($dbh, 'aws_secret_access_key'); + # Use hightest value if ($pa_config->{'discovery_threads'} > $pa_config->{'recon_threads'}) { $threads = $pa_config->{'discovery_threads'}; @@ -191,6 +196,40 @@ sub data_consumer ($$) { $cnf_extra{'aws_access_key_id'} = pandora_get_config_value($dbh, 'aws_access_key_id'); $cnf_extra{'aws_secret_access_key'} = pandora_get_config_value($dbh, 'aws_secret_access_key'); $cnf_extra{'cloud_util_path'} = pandora_get_config_value($dbh, 'cloud_util_path'); + + if (!defined($ENV{'AWS_ACCESS_KEY_ID'}) || !defined($ENV{'AWS_SECRET_ACCESS_KEY'}) + || $cnf_extra{'aws_secret_access_key'} ne $ENV{'AWS_ACCESS_KEY_ID'} + || $cnf_extra{'cloud_util_path'} ne $ENV{'AWS_SECRET_ACCESS_KEY'}) { + # Environmental data is out of date. Create a tmp file to manage + # credentials. Perl limitation. We cannot update ENV here. + $cnf_extra{'cred_file'} = $pa_config->{'temporal'} . '/tmp_discovery.' . md5($task->{'id_rt'} . $task->{'name'} . time()); + eval { + open(my $__file_cfg, '> '. $cnf_extra{'cred_file'}) or die($!); + print $__file_cfg $cnf_extra{'aws_secret_access_key'} . "\n"; + print $__file_cfg $cnf_extra{'cloud_util_path'}; + close($__file_cfg); + set_file_permissions( + $pa_config, + $cnf_extra{'cred_file'}, + 0600 + ); + }; + if ($@) { + logger( + $pa_config, + 'Cannot instantiate configuration file for task: ' . safe_output($task->{'name'}), + 5 + ); + # A server restart will override ENV definition (see run) + logger( + $pa_config, + 'Cannot execute Discovery task: ' . safe_output($task->{'name'}) . '. Please restart the server.', + 1 + ); + # Skip this task. + return; + } + } } my $recon = new PandoraFMS::Recon::Base( @@ -229,6 +268,12 @@ sub data_consumer ($$) { ); $recon->scan(); + + # Clean tmp file. + if (defined($cnf_extra{'cred_file'}) + && -f $cnf_extra{'cred_file'}) { + unlink($cnf_extra{'cred_file'}); + } }; if ($@) { update_recon_task ($dbh, $task_id, -1); From e998c8dd7016334b81bab7e907050aaa7ffa0915 Mon Sep 17 00:00:00 2001 From: fbsanchez <fborja.sanchez@artica.es> Date: Thu, 11 Apr 2019 15:05:03 +0200 Subject: [PATCH 24/31] Discovery RDS Former-commit-id: e03d600b06fec25fb5808b9425cc94832d9d1268 --- .../include/functions_snmp_browser.php | 16 +++++++++++++--- pandora_server/lib/PandoraFMS/DiscoveryServer.pm | 4 ++-- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/pandora_console/include/functions_snmp_browser.php b/pandora_console/include/functions_snmp_browser.php index d22dd5dc1e..496a7b747f 100644 --- a/pandora_console/include/functions_snmp_browser.php +++ b/pandora_console/include/functions_snmp_browser.php @@ -55,7 +55,9 @@ function snmp_browser_print_tree( $last_array=[], $sufix=false, $checked=[], - $return=false + $return=false, + $descriptive_ids=false, + $previous_id='' ) { static $url = false; @@ -138,7 +140,13 @@ function snmp_browser_print_tree( } $checkbox_name_sufix = ($sufix === true) ? '_'.$level : ''; - $checkbox_name = 'create_'.$sub_id.$checkbox_name_sufix; + if ($descriptive_ids === true) { + $checkbox_name = 'create_'.$sub_id.$previous_id.$checkbox_name_sufix; + } else { + $checkbox_name = 'create_'.$sub_id.$checkbox_name_sufix; + } + + $previous_id = $checkbox_name_sufix; $status = (!empty($checked) && isset($checked[$level])); $output .= html_print_checkbox($checkbox_name, 0, $status, true, false, '').' <span>'.$level.'</span>'; if (isset($sub_level['__VALUE__'])) { @@ -156,7 +164,9 @@ function snmp_browser_print_tree( $last_array, $sufix, $checked, - $return + $return, + $descriptive_ids, + $previous_id ); $count++; diff --git a/pandora_server/lib/PandoraFMS/DiscoveryServer.pm b/pandora_server/lib/PandoraFMS/DiscoveryServer.pm index cb4ee3dbad..76a8ac766c 100644 --- a/pandora_server/lib/PandoraFMS/DiscoveryServer.pm +++ b/pandora_server/lib/PandoraFMS/DiscoveryServer.pm @@ -205,13 +205,13 @@ sub data_consumer ($$) { $cnf_extra{'cred_file'} = $pa_config->{'temporal'} . '/tmp_discovery.' . md5($task->{'id_rt'} . $task->{'name'} . time()); eval { open(my $__file_cfg, '> '. $cnf_extra{'cred_file'}) or die($!); + print $__file_cfg $cnf_extra{'aws_access_key_id'} . "\n"; print $__file_cfg $cnf_extra{'aws_secret_access_key'} . "\n"; - print $__file_cfg $cnf_extra{'cloud_util_path'}; close($__file_cfg); set_file_permissions( $pa_config, $cnf_extra{'cred_file'}, - 0600 + "0600" ); }; if ($@) { From e80649073f84908e1fcfbd0a75338a240dee39ef Mon Sep 17 00:00:00 2001 From: fbsanchez <fborja.sanchez@artica.es> Date: Thu, 11 Apr 2019 15:36:55 +0200 Subject: [PATCH 25/31] Minor fixes Former-commit-id: 71698d61db59e7f94fb8c770715decb0fe6e5f0f --- pandora_server/lib/PandoraFMS/Config.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandora_server/lib/PandoraFMS/Config.pm b/pandora_server/lib/PandoraFMS/Config.pm index 57e3aa9483..2021241d4f 100644 --- a/pandora_server/lib/PandoraFMS/Config.pm +++ b/pandora_server/lib/PandoraFMS/Config.pm @@ -1200,7 +1200,7 @@ sub pandora_get_tconfig_token ($$$) { my ($dbh, $token, $default_value) = @_; my $token_value = get_db_value ($dbh, "SELECT value FROM tconfig WHERE token = ?", $token); - if (defined ($token_value)) { + if (defined ($token_value) && $token_value ne '') { return safe_output ($token_value); } From 8bdc980ab0ebf96f4c18ebd4306c75a2b65cb188 Mon Sep 17 00:00:00 2001 From: fbsanchez <fborja.sanchez@artica.es> Date: Fri, 12 Apr 2019 23:47:21 +0200 Subject: [PATCH 26/31] minor fix Former-commit-id: 4222b217953e88da43d0f50d3217a065dbb13332 --- pandora_server/lib/PandoraFMS/DiscoveryServer.pm | 12 ++++++------ pandora_server/lib/PandoraFMS/Recon/Base.pm | 1 + 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/pandora_server/lib/PandoraFMS/DiscoveryServer.pm b/pandora_server/lib/PandoraFMS/DiscoveryServer.pm index 76a8ac766c..c8b40d1848 100644 --- a/pandora_server/lib/PandoraFMS/DiscoveryServer.pm +++ b/pandora_server/lib/PandoraFMS/DiscoveryServer.pm @@ -202,15 +202,15 @@ sub data_consumer ($$) { || $cnf_extra{'cloud_util_path'} ne $ENV{'AWS_SECRET_ACCESS_KEY'}) { # Environmental data is out of date. Create a tmp file to manage # credentials. Perl limitation. We cannot update ENV here. - $cnf_extra{'cred_file'} = $pa_config->{'temporal'} . '/tmp_discovery.' . md5($task->{'id_rt'} . $task->{'name'} . time()); + $cnf_extra{'creds_file'} = $pa_config->{'temporal'} . '/tmp_discovery.' . md5($task->{'id_rt'} . $task->{'name'} . time()); eval { - open(my $__file_cfg, '> '. $cnf_extra{'cred_file'}) or die($!); + open(my $__file_cfg, '> '. $cnf_extra{'creds_file'}) or die($!); print $__file_cfg $cnf_extra{'aws_access_key_id'} . "\n"; print $__file_cfg $cnf_extra{'aws_secret_access_key'} . "\n"; close($__file_cfg); set_file_permissions( $pa_config, - $cnf_extra{'cred_file'}, + $cnf_extra{'creds_file'}, "0600" ); }; @@ -270,9 +270,9 @@ sub data_consumer ($$) { $recon->scan(); # Clean tmp file. - if (defined($cnf_extra{'cred_file'}) - && -f $cnf_extra{'cred_file'}) { - unlink($cnf_extra{'cred_file'}); + if (defined($cnf_extra{'creds_file'}) + && -f $cnf_extra{'creds_file'}) { + unlink($cnf_extra{'creds_file'}); } }; if ($@) { diff --git a/pandora_server/lib/PandoraFMS/Recon/Base.pm b/pandora_server/lib/PandoraFMS/Recon/Base.pm index 58e0eb8543..23532d843b 100644 --- a/pandora_server/lib/PandoraFMS/Recon/Base.pm +++ b/pandora_server/lib/PandoraFMS/Recon/Base.pm @@ -1456,6 +1456,7 @@ sub cloud_scan($) { aws_access_key_id => $self->{'aws_access_key_id'}, aws_secret_access_key => $self->{'aws_secret_access_key'}, cloud_util_path => $self->{'cloud_util_path'}, + creds_file => $self->{'creds_file'}, parent => $self ] From 6648e0268a3633496f4aa83e2129f7ec1981e2b2 Mon Sep 17 00:00:00 2001 From: fbsanchez <fborja.sanchez@artica.es> Date: Mon, 15 Apr 2019 12:54:22 +0200 Subject: [PATCH 27/31] removed reconview link from menu Former-commit-id: 41b80e4eaa41617982c91a218aee3902b76e4fde --- pandora_console/operation/menu.php | 6 ------ 1 file changed, 6 deletions(-) diff --git a/pandora_console/operation/menu.php b/pandora_console/operation/menu.php index e22769cd8a..f52d830d14 100644 --- a/pandora_console/operation/menu.php +++ b/pandora_console/operation/menu.php @@ -492,12 +492,6 @@ if (is_array($config['extensions'])) { $sub['godmode/agentes/planned_downtime.list']['id'] = 'Scheduled downtime'; } - if (check_acl($config['id_user'], 0, 'AW')) { - $sub['operation/servers/recon_view']['text'] = __('Recon view'); - $sub['operation/servers/recon_view']['id'] = 'Recon view'; - $sub['operation/servers/recon_view']['refr'] = 0; - } - foreach ($config['extensions'] as $extension) { // If no operation_menu is a godmode extension. if ($extension['operation_menu'] == '') { From 072fec3dd1bb133b59a3fb2136abfe51d4aafb5e Mon Sep 17 00:00:00 2001 From: fbsanchez <fborja.sanchez@artica.es> Date: Mon, 15 Apr 2019 13:03:11 +0200 Subject: [PATCH 28/31] removed map link from mysql/oracle/RDS discovery tasks Former-commit-id: c01ca25dbe4ca16265a6377d80f60f6d603b7664 --- pandora_console/godmode/wizards/DiscoveryTaskList.class.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pandora_console/godmode/wizards/DiscoveryTaskList.class.php b/pandora_console/godmode/wizards/DiscoveryTaskList.class.php index 20b52c7e36..fbd8bc4fb6 100644 --- a/pandora_console/godmode/wizards/DiscoveryTaskList.class.php +++ b/pandora_console/godmode/wizards/DiscoveryTaskList.class.php @@ -549,7 +549,11 @@ class DiscoveryTaskList extends Wizard $data[9] .= '</a>'; } - if ($task['disabled'] != 2 && $task['utimestamp'] > 0) { + if ($task['disabled'] != 2 && $task['utimestamp'] > 0 + && $task['type'] != DISCOVERY_APP_MYSQL + && $task['type'] != DISCOVERY_APP_ORACLE + && $task['type'] != DISCOVERY_CLOUD_AWS_RDS + ) { $data[9] .= '<a href="#" onclick="show_map('.$task['id_rt'].',\''.$task['name'].'\')">'; $data[9] .= html_print_image( 'images/dynamic_network_icon.png', From 8978b49a8b102c1eef23ecff5557519d2420dd03 Mon Sep 17 00:00:00 2001 From: fbsanchez <fborja.sanchez@artica.es> Date: Mon, 22 Apr 2019 09:33:51 +0200 Subject: [PATCH 29/31] minor fix while setting node_radius by default Former-commit-id: 37b603adc1eb025c84b4e6d298815894be8adcf6 --- pandora_console/include/class/NetworkMap.class.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pandora_console/include/class/NetworkMap.class.php b/pandora_console/include/class/NetworkMap.class.php index fd7274b94f..146e4d999f 100644 --- a/pandora_console/include/class/NetworkMap.class.php +++ b/pandora_console/include/class/NetworkMap.class.php @@ -2733,6 +2733,10 @@ class NetworkMap $output .= "var z_dash = null;\n"; } + if (empty($networkmap['filter']['node_radius']) === true) { + $networkmap['filter']['node_radius'] = $this->mapOptions['map_filter']['node_radius']; + } + $output .= 'var networkmap_refresh_time = 1000 * '.$networkmap['source_period'].";\n"; $output .= 'var networkmap_center = [ '.$networkmap['center_x'].', '.$networkmap['center_y']."];\n"; $output .= 'var networkmap_dimensions = [ '.$networkmap['width'].', '.$networkmap['height']."];\n"; From 19ec5a0733bcc5d4a818e1ee088828a03b500bf0 Mon Sep 17 00:00:00 2001 From: fbsanchez <fborja.sanchez@artica.es> Date: Mon, 22 Apr 2019 13:26:17 +0200 Subject: [PATCH 30/31] minor fix Former-commit-id: 34ebb713083bce476e15483e710f23295cf842cb --- pandora_console/godmode/wizards/DiscoveryTaskList.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandora_console/godmode/wizards/DiscoveryTaskList.class.php b/pandora_console/godmode/wizards/DiscoveryTaskList.class.php index 3f0317ab6a..3d67e91ae4 100644 --- a/pandora_console/godmode/wizards/DiscoveryTaskList.class.php +++ b/pandora_console/godmode/wizards/DiscoveryTaskList.class.php @@ -675,7 +675,7 @@ class DiscoveryTaskList extends Wizard return 'wiz=ctask'; default: - if ($task['id_recon_script'] === null) { + if (empty($task['id_recon_script']) === true) { return 'wiz=hd&mode=netscan'; } else { return 'wiz=hd&mode=customnetscan'; From f06e81dcc4bdbd79db24807cfee36da32e48bd6c Mon Sep 17 00:00:00 2001 From: fbsanchez <fborja.sanchez@artica.es> Date: Mon, 22 Apr 2019 13:49:58 +0200 Subject: [PATCH 31/31] Discovery: Minor update in description and extra information in log Former-commit-id: b24c095a8c75d190ba03ea089a9d680fcccd5b2b --- .../godmode/wizards/DiscoveryTaskList.class.php | 7 ++++++- pandora_server/lib/PandoraFMS/DiscoveryServer.pm | 5 +++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/pandora_console/godmode/wizards/DiscoveryTaskList.class.php b/pandora_console/godmode/wizards/DiscoveryTaskList.class.php index 3d67e91ae4..c9d8951e23 100644 --- a/pandora_console/godmode/wizards/DiscoveryTaskList.class.php +++ b/pandora_console/godmode/wizards/DiscoveryTaskList.class.php @@ -505,9 +505,14 @@ class DiscoveryTaskList extends Wizard true, ['title' => __('Discovery NetScan')] ).' '; - $data[6] .= network_profiles_get_name( + $str = network_profiles_get_name( $task['id_network_profile'] ); + if (!empty($str)) { + $data[6] .= $str; + } else { + $data[6] .= __('Discovery.NetScan'); + } break; } } else { diff --git a/pandora_server/lib/PandoraFMS/DiscoveryServer.pm b/pandora_server/lib/PandoraFMS/DiscoveryServer.pm index c8b40d1848..c92b56ed0d 100644 --- a/pandora_server/lib/PandoraFMS/DiscoveryServer.pm +++ b/pandora_server/lib/PandoraFMS/DiscoveryServer.pm @@ -276,6 +276,11 @@ sub data_consumer ($$) { } }; if ($@) { + logger( + $pa_config, + 'Cannot execute Discovery task: ' . safe_output($task->{'name'}) . $@, + 10 + ); update_recon_task ($dbh, $task_id, -1); return; }