Merge branch 'ent-3674-discovery-fase-3' into 'develop'

Ent 3674 discovery fase 3

See merge request artica/pandorafms!2315

Former-commit-id: d89d32a1432a3e449485eb113b3195dcc101ce80
This commit is contained in:
Alejandro Fraguas 2019-04-22 14:34:46 +02:00
commit f2d7584d70
15 changed files with 1433 additions and 778 deletions

View File

@ -39,4 +39,12 @@ ALTER TABLE `treport_content_template` ADD COLUMN `unknown_checks` TINYINT(1) DE
ALTER TABLE `treport_content_template` ADD COLUMN `agent_max_value` TINYINT(1) DEFAULT '1';
ALTER TABLE `treport_content_template` ADD COLUMN `agent_min_value` TINYINT(1) DEFAULT '1';
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";
COMMIT;

View File

@ -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) {
@ -464,15 +476,45 @@ class DiscoveryTaskList extends Wizard
}
if ($task['id_recon_script'] == 0) {
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_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.
$data[6] = html_print_image(
'images/network.png',
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 {
// APP recon task.
$data[6] = html_print_image(
@ -512,7 +554,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',
@ -614,19 +660,27 @@ 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_ORACLE:
return 'wiz=app&mode=oracle&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 DISCOVERY_CLOUD_AWS_RDS:
return 'wiz=cloud&mode=amazonws&sub=rds&page=0';
case 'console_task':
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';

View File

@ -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

View File

@ -191,21 +191,19 @@ 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)
{
public function prepareBreadcrum(
array $urls,
bool $add=false
) {
$bc = [];
$i = 0;
$count = 0;
$array_size = count($urls);
foreach ($urls as $url) {
$count++;
if ($url['selected'] == 1) {
$class = 'selected';
} else {
@ -217,7 +215,6 @@ class Wizard
$bc[$i] .= $url['label'];
$bc[$i] .= '</a>';
$bc[$i] .= '</span>';
$i++;
}
@ -226,7 +223,6 @@ class Wizard
} else {
$this->setBreadcrum($bc);
}
}
@ -266,7 +262,10 @@ class Wizard
*/
public function printBreadcrum()
{
return implode('<span class="breadcrumb_link">&nbsp/&nbsp</span>', $this->breadcrum);
return implode(
'<span class="breadcrumb_link">&nbsp/&nbsp</span>',
$this->breadcrum
);
}

View File

@ -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);
/**
@ -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.
*
@ -319,6 +333,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,9 +1015,10 @@ class NetworkMap
case NODE_GENERIC:
// Handmade ones.
// Add also parent relationship.
if (isset($node['id_parent'])) {
$parent_id = $node['id_parent'];
if ((int) $parent_id > 0) {
if ((int) $parent_id >= 0) {
$parent_node = $this->getNodeData(
(int) $parent_id,
'id_node'
@ -1009,7 +1026,7 @@ class NetworkMap
}
// Store relationship.
if ($parent_node) {
if ($parent_node !== null) {
$relations[] = [
'id_parent' => $parent_node,
'parent_type' => NODE_GENERIC,
@ -1017,6 +1034,7 @@ class NetworkMap
'child_type' => NODE_GENERIC,
];
}
}
break;
case NODE_PANDORA:
@ -1224,6 +1242,11 @@ class NetworkMap
return '';
}
if ($this->mapOptions['fixed_positions']) {
// Ignore.
return;
}
$dot_str = '';
// Color is being printed by D3, not graphviz.
@ -1233,8 +1256,22 @@ class NetworkMap
$url = 'none';
$parent = $data['parent'];
$font_size = $this->mapOptions['font_size'];
if (isset($data['radius'])) {
$radius = $data['radius'];
} else {
$radius = $this->mapOptions['map_filter']['node_radius'];
$radius /= GRAPHVIZ_RADIUS_CONVERSION_FACTOR;
}
$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);
@ -1593,6 +1630,21 @@ 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.
foreach ($node['style'] as $k => $v) {
$item[$k] = $v;
}
$item['type'] = $node['type'];
@ -1632,9 +1684,15 @@ 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']);
if (isset($source_data['color'])) {
$item['color'] = $source_data['color'];
} else {
$item['color'] = self::getColorByStatus(
$node['status']
);
}
break;
}
@ -1679,6 +1737,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 +1753,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;
@ -2036,6 +2093,10 @@ class NetworkMap
'id_source' => $id_source,
'label' => $label,
'image' => null,
'radius' => max(
$node['width'],
$node['height']
),
]
);
@ -2148,8 +2209,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 +2223,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 +2462,17 @@ class NetworkMap
* Calculate X,Y positions.
*/
if (!$this->mapOptions['fixed_positions']) {
$graph = $this->calculateCoords();
} else {
// Set by user.
$graph['nodes'] = $this->rawNodes;
$graph['relations'] = $this->relations;
$this->map['width'] = $this->mapOptions['width'];
$this->map['height'] = $this->mapOptions['height'];
}
$this->map['filter']['z_dash'] = $this->mapOptions['z_dash'];
if (is_array($graph) === true) {
$nodes = $graph['nodes'];
@ -2501,6 +2572,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);
@ -2658,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";
@ -2676,8 +2755,14 @@ class NetworkMap
$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'];
@ -2685,8 +2770,11 @@ class NetworkMap
$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 .= '
////////////////////////////////////////////////////////////////////
@ -3221,16 +3309,21 @@ class NetworkMap
&& $this->useTooltipster
) {
$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($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'].',
font_size: '.$this->mapOptions['font_size'].',
homedir: "'.ui_get_full_url(false).'",
custom_params: '.json_encode($this->tooltipParams).'
});
controller.init_map();
});
</script>';
@ -3315,9 +3408,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'].'">';
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 {

View File

@ -583,8 +583,22 @@ 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);
// Cloud environments.
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');

View File

@ -54,10 +54,15 @@ function snmp_browser_print_tree(
$last=0,
$last_array=[],
$sufix=false,
$checked=[]
$checked=[],
$return=false,
$descriptive_ids=false,
$previous_id=''
) {
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 +78,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 +88,97 @@ 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 : '';
if ($descriptive_ids === true) {
$checkbox_name = 'create_'.$sub_id.$previous_id.$checkbox_name_sufix;
} else {
$checkbox_name = 'create_'.$sub_id.$checkbox_name_sufix;
$status = (!empty($checked) && isset($checked[$level]));
echo html_print_checkbox($checkbox_name, 0, $status, true, false, '').'&nbsp;<span>'.$level.'</span>';
if (isset($sub_level['__VALUE__'])) {
echo '<span class="value" style="display: none;">&nbsp;=&nbsp;'.$sub_level['__VALUE__'].'</span>';
}
echo '</li>';
$previous_id = $checkbox_name_sufix;
$status = (!empty($checked) && isset($checked[$level]));
$output .= html_print_checkbox($checkbox_name, 0, $status, true, false, '').'&nbsp;<span>'.$level.'</span>';
if (isset($sub_level['__VALUE__'])) {
$output .= '<span class="value" style="display: none;">&nbsp;=&nbsp;'.$sub_level['__VALUE__'].'</span>';
}
$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,
$descriptive_ids,
$previous_id
);
$count++;
}
echo '</ul>';
$output .= '</ul>';
if ($return == false) {
echo $output;
}
return $output;
}

View File

@ -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 {

View File

@ -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'] == '') {

View File

@ -790,6 +790,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;
@ -967,6 +968,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;

View File

@ -1135,10 +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&#x20;view', 'select&#x20;t1.nombre,&#x20;&#40;select&#x20;count&#40;t3.id_agente&#41;&#x20;from&#x20;tagente&#x20;as&#x20;t3&#x20;where&#x20;t1.id_grupo&#x20;=&#x20;t3.id_grupo&#41;&#x20;as&#x20;agents,&#x20;&#40;SELECT&#x20;COUNT&#40;t4.id_agente&#41;&#x20;FROM&#x20;tagente&#x20;as&#x20;t4&#x20;WHERE&#x20;t4.id_grupo&#x20;=&#x20;t1.id_grupo&#x20;AND&#x20;t4.disabled&#x20;=&#x20;0&#x20;AND&#x20;t4.ultimo_contacto&#x20;&lt;&#x20;NOW&#40;&#41;&#x20;-&#x20;&#40;intervalo&#x20;/&#x20;&#40;1/2&#41;&#41;&#41;&#x20;as&#x20;agent_unknown,&#x20;&#40;SELECT&#x20;COUNT&#40;tagente_estado.id_agente_estado&#41;&#x20;FROM&#x20;tagente_estado,&#x20;tagente,&#x20;tagente_modulo&#x20;WHERE&#x20;tagente.id_grupo&#x20;=&#x20;t1.id_grupo&#x20;AND&#x20;tagente.disabled&#x20;=&#x20;0&#x20;AND&#x20;tagente.id_agente&#x20;=&#x20;tagente_estado.id_agente&#x20;AND&#x20;tagente_estado.id_agente_modulo&#x20;=&#x20;tagente_modulo.id_agente_modulo&#x20;AND&#x20;tagente_modulo.disabled&#x20;=&#x20;0&#x20;AND&#x20;utimestamp&#x20;&gt;&#x20;0&#x20;AND&#x20;tagente_modulo.id_tipo_modulo&#x20;NOT&#x20;IN&#40;21,22,23,24,100&#41;&#x20;AND&#x20;&#40;UNIX_TIMESTAMP&#40;NOW&#40;&#41;&#41;&#x20;-&#x20;tagente_estado.utimestamp&#41;&#x20;&gt;=&#x20;&#40;tagente_estado.current_interval&#x20;/&#x20;&#40;1/2&#41;&#41;&#41;&#x20;as&#x20;monitor_unknow,&#x20;&#40;SELECT&#x20;COUNT&#40;tagente_estado.id_agente_estado&#41;&#x20;FROM&#x20;tagente_estado,&#x20;tagente,&#x20;tagente_modulo&#x20;WHERE&#x20;tagente.id_grupo&#x20;=&#x20;t1.id_grupo&#x20;AND&#x20;tagente.disabled&#x20;=&#x20;0&#x20;AND&#x20;tagente.id_agente&#x20;=&#x20;tagente_estado.id_agente&#x20;AND&#x20;tagente_estado.id_agente_modulo&#x20;=&#x20;tagente_modulo.id_agente_modulo&#x20;AND&#x20;tagente_modulo.disabled&#x20;=&#x20;0&#x20;AND&#x20;tagente_modulo.id_tipo_modulo&#x20;NOT&#x20;IN&#x20;&#40;21,22,23,24&#41;&#x20;AND&#x20;utimestamp&#x20;=&#x20;0&#41;&#x20;as&#x20;monitor_no_init,&#x20;&#40;SELECT&#x20;COUNT&#40;tagente_estado.id_agente_estado&#41;&#x20;FROM&#x20;tagente_estado,&#x20;tagente,&#x20;tagente_modulo&#x20;WHERE&#x20;tagente.id_grupo&#x20;=&#x20;t1.id_grupo&#x20;AND&#x20;tagente.disabled&#x20;=&#x20;0&#x20;AND&#x20;tagente_estado.id_agente&#x20;=&#x20;tagente.id_agente&#x20;AND&#x20;tagente_estado.id_agente_modulo&#x20;=&#x20;tagente_modulo.id_agente_modulo&#x20;AND&#x20;tagente_modulo.disabled&#x20;=&#x20;0&#x20;AND&#x20;estado&#x20;=&#x20;0&#x20;AND&#x20;&#40;&#40;UNIX_TIMESTAMP&#40;NOW&#40;&#41;&#41;&#x20;-&#x20;tagente_estado.utimestamp&#41;&#x20;&lt;&#x20;&#40;tagente_estado.current_interval&#x20;/&#x20;&#40;1/2&#41;&#41;&#x20;OR&#x20;&#40;tagente_modulo.id_tipo_modulo&#x20;IN&#40;21,22,23,24,100&#41;&#41;&#41;&#x20;AND&#x20;&#40;utimestamp&#x20;&gt;&#x20;0&#x20;OR&#x20;&#40;tagente_modulo.id_tipo_modulo&#x20;IN&#40;21,22,23,24&#41;&#41;&#41;&#41;&#x20;as&#x20;monitor_ok,&#x20;&#40;SELECT&#x20;COUNT&#40;tagente_estado.id_agente_estado&#41;&#x20;FROM&#x20;tagente_estado,&#x20;tagente,&#x20;tagente_modulo&#x20;WHERE&#x20;tagente.id_grupo&#x20;=&#x20;t1.id_grupo&#x20;AND&#x20;tagente.disabled&#x20;=&#x20;0&#x20;AND&#x20;tagente_estado.id_agente&#x20;=&#x20;tagente.id_agente&#x20;AND&#x20;tagente_estado.id_agente_modulo&#x20;=&#x20;tagente_modulo.id_agente_modulo&#x20;AND&#x20;tagente_modulo.disabled&#x20;=&#x20;0&#x20;AND&#x20;estado&#x20;=&#x20;1&#x20;AND&#x20;&#40;&#40;UNIX_TIMESTAMP&#40;NOW&#40;&#41;&#41;&#x20;-&#x20;tagente_estado.utimestamp&#41;&#x20;&lt;&#x20;&#40;tagente_estado.current_interval&#x20;/&#x20;&#40;1/2&#41;&#41;&#x20;OR&#x20;&#40;tagente_modulo.id_tipo_modulo&#x20;IN&#40;21,22,23,24,100&#41;&#41;&#41;&#x20;AND&#x20;utimestamp&#x20;&gt;&#x20;0&#41;&#x20;as&#x20;monitor_critical,&#x20;&#40;SELECT&#x20;COUNT&#40;talert_template_modules.id&#41;&#x20;FROM&#x20;talert_template_modules,&#x20;tagente_modulo,&#x20;tagente_estado,&#x20;tagente&#x20;WHERE&#x20;tagente.id_grupo&#x20;=&#x20;t1.id_grupo&#x20;AND&#x20;tagente_modulo.id_agente&#x20;=&#x20;tagente.id_agente&#x20;AND&#x20;tagente_estado.id_agente_modulo&#x20;=&#x20;tagente_modulo.id_agente_modulo&#x20;AND&#x20;tagente_modulo.disabled&#x20;=&#x20;0&#x20;AND&#x20;tagente.disabled&#x20;=&#x20;0&#x20;AND&#x20;talert_template_modules.id_agent_module&#x20;=&#x20;tagente_modulo.id_agente_modulo&#x20;AND&#x20;times_fired&#x20;&gt;&#x20;0&#41;&#x20;as&#x20;monitor_alert_fired&#x20;from&#x20;tgrupo&#x20;as&#x20;t1&#x20;where&#x20;0&#x20;&lt;&#x20;&#40;select&#x20;count&#40;t2.id_agente&#41;&#x20;from&#x20;tagente&#x20;as&#x20;t2&#x20;where&#x20;t1.id_grupo&#x20;=&#x20;t2.id_grupo&#41;');
-- trecon scripts
INSERT INTO `trecon_script` VALUES (2,'IPMI&#x20;Recon','Specific&#x20;Pandora&#x20;FMS&#x20;Intel&#x20;DCM&#x20;Discovery&#x20;&#40;c&#41;&#x20;Artica&#x20;ST&#x20;2011&#x20;&lt;info@artica.es&gt;&#x0d;&#x0a;&#x0d;&#x0a;Usage:&#x20;./ipmi-recon.pl&#x20;&lt;task_id&gt;&#x20;&lt;group_id&gt;&#x20;&lt;create_incident_flag&gt;&#x20;&lt;custom_field1&gt;&#x20;&lt;custom_field2&gt;&#x20;&lt;custom_field3&gt;&#x20;&lt;custom_field4&gt;&#x0d;&#x0a;&#x0d;&#x0a;*&#x20;custom_field1&#x20;=&#x20;Network&#x20;i.e.:&#x20;192.168.100.0/24&#x0d;&#x0a;*&#x20;custom_field2&#x20;=&#x20;Username&#x0d;&#x0a;*&#x20;custom_field3&#x20;=&#x20;Password&#x0d;&#x0a;*&#x20;custom_field4&#x20;=&#x20;Additional&#x20;parameters&#x20;i.e.:&#x20;-D&#x20;LAN_2_0','/usr/share/pandora_server/util/recon_scripts/ipmi-recon.pl','{\"1\":{\"macro\":\"_field1_\",\"desc\":\"Network\",\"help\":\"i.e.:&#x20;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&#x20;parameters\",\"help\":\"Optional&#x20;additional&#x20;parameters&#x20;such&#x20;as&#x20;-D&#x20;LAN_2_0&#x20;to&#x20;use&#x20;IPMI&#x20;ver&#x20;2.0&#x20;instead&#x20;of&#x20;1.5.&#x20;&#x20;These&#x20;options&#x20;will&#x20;also&#x20;be&#x20;passed&#x20;to&#x20;the&#x20;IPMI&#x20;plugin&#x20;when&#x20;the&#x20;current&#x20;values&#x20;are&#x20;read.\",\"value\":\"\",\"hide\":\"\"}}');
INSERT INTO `trecon_script` VALUES (5,'WMI&#x20;Recon&#x20;Script','This&#x20;script&#x20;is&#x20;used&#x20;to&#x20;automatically&#x20;gather&#x20;host&#x20;information&#x20;via&#x20;WMI.&#x0d;&#x0a;Available&#x20;parameters:&#x0d;&#x0a;&#x0d;&#x0a;*&#x20;Network&#x20;=&#x20;network&#x20;to&#x20;scan&#x20;&#40;e.g.&#x20;192.168.100.0/24&#41;.&#x0d;&#x0a;*&#x20;WMI&#x20;auth&#x20;=&#x20;comma&#x20;separated&#x20;list&#x20;of&#x20;WMI&#x20;authentication&#x20;tokens&#x20;in&#x20;the&#x20;format&#x20;username%password&#x20;&#40;e.g.&#x20;Administrador%pass&#41;.&#x0d;&#x0a;&#x0d;&#x0a;See&#x20;the&#x20;documentation&#x20;for&#x20;more&#x20;information.','/usr/share/pandora_server/util/recon_scripts/wmi-recon.pl','{\"1\":{\"macro\":\"_field1_\",\"desc\":\"Network\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"},\"2\":{\"macro\":\"_field2_\",\"desc\":\"WMI&#x20;auth\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"}}');
INSERT INTO `trecon_script` (`name`,`description`,`script`,`macros`) VALUES ('Discovery.Application.VMware', 'Discovery&#x20;Application&#x20;script&#x20;to&#x20;monitor&#x20;VMware&#x20;technologies&#x20;&#40;ESXi,&#x20;VCenter,&#x20;VSphere&#41;', '/usr/share/pandora_server/util/recon_scripts/vmware-plugin.pl', '{"1":{"macro":"_field1_","desc":"Configuration&#x20;file","help":"","value":"","hide":""}}');
INSERT INTO `trecon_script` (`name`,`description`,`script`,`macros`) VALUES ('Discovery.Cloud', 'Discovery&#x20;Cloud&#x20;script&#x20;to&#x20;monitor&#x20;Cloud&#x20;technologies&#x20;&#40;AWS.EC2,&#x20;AWS.S3,&#x20;AWS.RDS,&#x20RDS,&#x20AWS.EKS&#41;', '/usr/share/pandora_server/util/recon_scripts/pcm_client.pl', '{"1":{"macro":"_field1_","desc":"Configuration&#x20;file","help":"","value":"","hide":""}}');
INSERT INTO `trecon_script` (`type`,`name`,`description`,`script`,`macros`) VALUES (1, 'Discovery.Application.VMware', 'Discovery&#x20;Application&#x20;script&#x20;to&#x20;monitor&#x20;VMware&#x20;technologies&#x20;&#40;ESXi,&#x20;VCenter,&#x20;VSphere&#41;', '/usr/share/pandora_server/util/recon_scripts/vmware-plugin.pl', '{"1":{"macro":"_field1_","desc":"Configuration&#x20;file","help":"","value":"","hide":""}}');
INSERT INTO `trecon_script` (`type`,`name`,`description`,`script`,`macros`) VALUES (2, 'Discovery.Cloud', 'Discovery&#x20;Cloud&#x20;script&#x20;to&#x20;monitor&#x20;Cloud&#x20;technologies&#x20;&#40;AWS.EC2,&#x20;AWS.S3,&#x20;AWS.RDS,&#x20RDS,&#x20AWS.EKS&#41;', '/usr/share/pandora_server/util/recon_scripts/pcm_client.pl', '{"1":{"macro":"_field1_","desc":"Configuration&#x20;file","help":"","value":"","hide":""}}');
-- IPAM is 3.
INSERT INTO `trecon_script` (`type`,`name`,`description`,`script`,`macros`) VALUES (4, 'IPMI&#x20;Recon','Specific&#x20;Pandora&#x20;FMS&#x20;Intel&#x20;DCM&#x20;Discovery&#x20;&#40;c&#41;&#x20;Artica&#x20;ST&#x20;2011&#x20;&lt;info@artica.es&gt;&#x0d;&#x0a;&#x0d;&#x0a;Usage:&#x20;./ipmi-recon.pl&#x20;&lt;task_id&gt;&#x20;&lt;group_id&gt;&#x20;&lt;create_incident_flag&gt;&#x20;&lt;custom_field1&gt;&#x20;&lt;custom_field2&gt;&#x20;&lt;custom_field3&gt;&#x20;&lt;custom_field4&gt;&#x0d;&#x0a;&#x0d;&#x0a;*&#x20;custom_field1&#x20;=&#x20;Network&#x20;i.e.:&#x20;192.168.100.0/24&#x0d;&#x0a;*&#x20;custom_field2&#x20;=&#x20;Username&#x0d;&#x0a;*&#x20;custom_field3&#x20;=&#x20;Password&#x0d;&#x0a;*&#x20;custom_field4&#x20;=&#x20;Additional&#x20;parameters&#x20;i.e.:&#x20;-D&#x20;LAN_2_0','/usr/share/pandora_server/util/recon_scripts/ipmi-recon.pl','{\"1\":{\"macro\":\"_field1_\",\"desc\":\"Network\",\"help\":\"i.e.:&#x20;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&#x20;parameters\",\"help\":\"Optional&#x20;additional&#x20;parameters&#x20;such&#x20;as&#x20;-D&#x20;LAN_2_0&#x20;to&#x20;use&#x20;IPMI&#x20;ver&#x20;2.0&#x20;instead&#x20;of&#x20;1.5.&#x20;&#x20;These&#x20;options&#x20;will&#x20;also&#x20;be&#x20;passed&#x20;to&#x20;the&#x20;IPMI&#x20;plugin&#x20;when&#x20;the&#x20;current&#x20;values&#x20;are&#x20;read.\",\"value\":\"\",\"hide\":\"\"}}');
INSERT INTO `tplugin` (`id`, `name`, `description`, `max_timeout`, `execute`, `plugin_type`, `macros`, `parameters`) VALUES (1,'IPMI&#x20;Plugin','Plugin&#x20;to&#x20;get&#x20;IPMI&#x20;monitors&#x20;from&#x20;a&#x20;IPMI&#x20;Device.',0,'/usr/share/pandora_server/util/plugin/ipmi-plugin.pl',0,'{\"1\":{\"macro\":\"_field1_\",\"desc\":\"Target&#x20;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&#x20;Options\",\"help\":\"\",\"value\":\"\",\"hide\":\"\"}}','-h&#x20;_field1_&#x20;-u&#x20;_field2_&#x20;-p&#x20;_field3_&#x20;-s&#x20;_field4_&#x20;--&#x20;_field5_');

View File

@ -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);
}

View File

@ -53,9 +53,19 @@ 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.
@ -98,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'};
@ -150,6 +165,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);
@ -172,6 +190,48 @@ sub data_consumer ($$) {
my $main_event = pandora_event($pa_config, "[Discovery] Execution summary",$task->{'id_group'}, 0, 0, 0, 0, 'system', 0, $dbh);
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');
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{'creds_file'} = $pa_config->{'temporal'} . '/tmp_discovery.' . md5($task->{'id_rt'} . $task->{'name'} . time());
eval {
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{'creds_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(
communities => \@communities,
dbh => $dbh,
@ -201,12 +261,26 @@ 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,
%cnf_extra
);
$recon->scan();
# Clean tmp file.
if (defined($cnf_extra{'creds_file'})
&& -f $cnf_extra{'creds_file'}) {
unlink($cnf_extra{'creds_file'});
}
};
if ($@) {
logger(
$pa_config,
'Cannot execute Discovery task: ' . safe_output($task->{'name'}) . $@,
10
);
update_recon_task ($dbh, $task_id, -1);
return;
}
@ -413,6 +487,109 @@ sub PandoraFMS::Recon::Base::connect_agents($$$$$) {
}
}
##########################################################################
# Create agents from db_scan. Uses DataServer methods.
# 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_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'});
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'}
);
$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, 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};
# 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
);
}
}
}
}
##########################################################################
# Create an agent for the given device. Returns the ID of the new (or
# existing) agent, undef on error.

View File

@ -20,7 +20,18 @@ 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,
DISCOVERY_CLOUD_AWS_EC2 => 6,
DISCOVERY_CLOUD_AWS_RDS => 7
};
# /dev/null
@ -194,6 +205,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 +253,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 +283,7 @@ sub new {
$self->{'snmp_security_level'} = '';
}
return bless($self, $class);
return $self;
}
########################################################################################
@ -1415,6 +1428,210 @@ 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'},
creds_file => $self->{'creds_file'},
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.
##########################################################################
sub app_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;
}
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,
$self->{'task_data'}
);
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',
type => 'generic_proc',
data => 0,
description => $type . ' availability'
};
} else {
my $dbObjCfg = $dbObj->get_config();
$self->{'summary'}->{'discovered'} += 1;
$self->{'summary'}->{'alive'} += 1;
push @modules, {
name => $type . ' connection',
type => 'generic_proc',
data => 1,
description => $type . ' availability'
};
# 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();
# Retrieve connection statistics.
# Retrieve uptime statistics
# Retrieve query stats
# 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();
# 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();
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") {
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 {
map { $_ } @{$_->{'module_data'}}
} @{$__data};
push @modules, @_modules;
}
}
}
}
# 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' => (defined($version) ? $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);
# Destroy item.
undef($dbObj);
$global_percent += $global_step;
$self->{'c_network_percent'} = 100;
$self->call('update_progress', $global_percent);
}
# Update progress.
# Done!
$self->{'step'} = '';
$self->call('update_progress', -1);
}
##########################################################################
# Perform a network scan.
##########################################################################
@ -1425,6 +1642,19 @@ 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->app_scan();
}
if ($self->{'task_data'}->{'type'} == DISCOVERY_CLOUD_AWS_RDS) {
# Cloud scan.
return $self->cloud_scan();
}
}
# Find devices.
$self->call('message', "[1/5] Scanning the network...", 3);
$self->{'step'} = STEP_SCANNING;
@ -1540,7 +1770,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;
}
}

View File

@ -12,9 +12,10 @@ 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(
enterprise_new
ip_to_long
mac_matches
mac_to_dec
@ -22,6 +23,36 @@ our @EXPORT = qw(
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.
########################################################################################
@ -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);
@ -95,6 +126,7 @@ sub subnet_matches($$;$) {
$netaddr = $subnet;
$netmask = ip_to_long($mask);
}
# CIDR notation.
else {
($netaddr, $netmask) = split('/', $subnet);