Pre-check modules (SNMP, TCP, ICMP) Discovery
This commit is contained in:
parent
f58276ddbb
commit
99cb286274
|
@ -3067,6 +3067,8 @@ sub pandora_create_module_from_network_component ($$$$) {
|
|||
pandora_create_module_tags ($pa_config, $dbh, $module_id, $component_tags);
|
||||
|
||||
logger($pa_config, 'Creating module ' . safe_output ($component->{'nombre'}) . " (ID $module_id) for agent $addr from network component.", 10);
|
||||
|
||||
return $module_id;
|
||||
}
|
||||
|
||||
##########################################################################
|
||||
|
|
|
@ -441,11 +441,133 @@ sub PandoraFMS::Recon::Base::tcp_scan ($$) {
|
|||
return $open_ports;
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# Verifies if a module will be normal.
|
||||
################################################################################
|
||||
sub PandoraFMS::Recon::Base::test_module($$) {
|
||||
my ($self, $addr, $module) = @_;
|
||||
|
||||
# Default values.
|
||||
my $test = {
|
||||
%{$module},
|
||||
'ip_target' => $addr,
|
||||
};
|
||||
|
||||
if (is_enabled($module->{'__module_component'})) {
|
||||
# Component. Translate some fields.
|
||||
$test->{'id_tipo_modulo'} = $module->{'type'};
|
||||
} else {
|
||||
# Module.
|
||||
$test->{'id_tipo_modulo'} = $module->{'id_modulo'};
|
||||
}
|
||||
|
||||
my $value;
|
||||
|
||||
# 1. Try to retrieve value.
|
||||
if ($test->{'id_tipo_modulo'} >= 15 && $test->{'id_tipo_modulo'} <= 18) {
|
||||
# SNMP
|
||||
$value = $self->call(
|
||||
'snmp_get',
|
||||
$test->{'ip_target'},
|
||||
$test->{'snmp_oid'}
|
||||
);
|
||||
} elsif ($test->{'id_tipo_modulo'} == 6) {
|
||||
# ICMP - alive - already tested.
|
||||
$value = 1;
|
||||
|
||||
} elsif ($test->{'id_tipo_modulo'} == 7) {
|
||||
# ICMP - latency
|
||||
$value = pandora_ping_latency(
|
||||
$self->{'pa_config'},
|
||||
$test->{'ip_target'},
|
||||
$test->{'max_timeout'},
|
||||
$test->{'max_retries'},
|
||||
);
|
||||
|
||||
} elsif (($test->{'id_tipo_modulo'} >= 1 && $test->{'id_tipo_modulo'} <= 5)
|
||||
|| ($test->{'id_tipo_modulo'} >= 21 && $test->{'id_tipo_modulo'} <= 23)
|
||||
&& is_enabled($test->{'id_plugin'})
|
||||
) {
|
||||
# Generic, plugins. (21-23 ASYNC)
|
||||
# XXX TODO: Test plugins.
|
||||
return 1;
|
||||
|
||||
} elsif ($test->{'id_tipo_modulo'} >= 34 && $test->{'id_tipo_modulo'} <= 37) {
|
||||
# Remote command.
|
||||
# XXX TODO: Test remote commands.
|
||||
return 1;
|
||||
} elsif ($test->{'id_tipo_modulo'} >= 8 && $test->{'id_tipo_modulo'} <= 11) {
|
||||
# TCP
|
||||
|
||||
return 0 unless is_numeric($test->{'tcp_port'})
|
||||
&& $test->{'tcp_port'} > 0
|
||||
&& $test->{'tcp_port'} <= 65535;
|
||||
|
||||
my $result;
|
||||
|
||||
PandoraFMS::NetworkServer::pandora_query_tcp(
|
||||
$self->{'pa_config'},
|
||||
$test->{'tcp_port'},
|
||||
$test->{'ip_target'},
|
||||
\$result,
|
||||
\$value,
|
||||
$test->{'tcp_send'},
|
||||
$test->{'tcp_rcv'},
|
||||
$test->{'id_tipo_modulo'},
|
||||
$test->{'max_timeout'},
|
||||
$test->{'max_retries'},
|
||||
'<Discovery testing>',
|
||||
);
|
||||
|
||||
# Result 0 is OK, 1 failed
|
||||
return 0 unless defined($result) && $result == 0;
|
||||
return 0 unless defined($value);
|
||||
|
||||
}
|
||||
|
||||
# Invalid data (empty or not defined)
|
||||
return 0 if is_empty($value);
|
||||
|
||||
# 2. Check if value matches type definition and fits thresholds.
|
||||
if (is_in_array([1,2,4,5,6,7,8,9,11,15,16,18,21,22,25,30,31,32,34,35,37],$test->{'id_tipo_modulo'})) {
|
||||
# Numeric.
|
||||
return 0 unless is_numeric($value);
|
||||
|
||||
if (!is_enabled($test->{'critical_inverse'})) {
|
||||
return 0 if $value >= $test->{'min_critical'} && $value <= $test->{'max_critical'};
|
||||
} else {
|
||||
return 0 if $value < $test->{'min_critical'} && $value > $test->{'max_critical'};
|
||||
}
|
||||
|
||||
if (is_in_array([2,6,9,18,21,31,35], $test->{'id_tipo_modulo'})) {
|
||||
# Boolean.
|
||||
if (!is_enabled($test->{'critical_inverse'})) {
|
||||
return 0 if $value == 0;
|
||||
} else {
|
||||
return 0 if $value != 0;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
# String.
|
||||
if (!is_enabled($test->{'critical_inverse'})) {
|
||||
return 0 if !is_empty($test->{'str_critical'}) && $value =~ /$test->{'str_critical'}/;
|
||||
} else {
|
||||
return 0 if !is_empty($test->{'str_critical'}) && $value !~ /$test->{'str_critical'}/;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
# Success.
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# Create network profile modules for the given agent.
|
||||
################################################################################
|
||||
sub PandoraFMS::Recon::Base::create_network_profile_modules($$$) {
|
||||
my ($self, $agent_id, $device) = @_;
|
||||
sub PandoraFMS::Recon::Base::create_network_profile_modules($$) {
|
||||
my ($self, $device) = @_;
|
||||
|
||||
#
|
||||
# Plugin
|
||||
|
@ -454,50 +576,61 @@ sub PandoraFMS::Recon::Base::create_network_profile_modules($$$) {
|
|||
# ICMP
|
||||
#
|
||||
|
||||
use Data::Dumper;
|
||||
$Data::Dumper::Sortkeys = 1;
|
||||
|
||||
print Dumper($device);
|
||||
print Dumper($self->{'task_data'});
|
||||
|
||||
die();
|
||||
|
||||
return if empty($self->{'id_network_profile'});
|
||||
return if is_empty($self->{'id_network_profile'});
|
||||
|
||||
my @templates = split /,/, $self->{'id_network_profile'};
|
||||
|
||||
# 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 $data = $self->{'agents_found'}{$device};
|
||||
|
||||
# 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;
|
||||
foreach my $t_id (@templates) {
|
||||
# 1. Retrieve template info.
|
||||
my $template = get_db_single_row(
|
||||
$self->{'dbh'},
|
||||
'SELECT * FROM `tnetwork_profile` WHERE `id_np` = ?',
|
||||
$t_id
|
||||
);
|
||||
|
||||
# 2. Verify Private Enterprise Number matches (PEN)
|
||||
if (defined($template->{'pen'})) {
|
||||
my @penes = split(',', $template->{'pen'});
|
||||
|
||||
next unless (is_in_array(\@penes, $data->{'pen'}));
|
||||
}
|
||||
|
||||
## XXX Puede tener varios penes.
|
||||
#next if (defined($template->{'pen'})
|
||||
# && get_enterprise_oid($device) != $template->{'pen'} );
|
||||
|
||||
# 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'}
|
||||
# 2. retrieve module list from target template.
|
||||
my @np_components = get_db_rows(
|
||||
$self->{'dbh'},
|
||||
'SELECT * FROM tnetwork_profile_component WHERE id_np = ?',
|
||||
$t_id
|
||||
);
|
||||
|
||||
foreach my $np_component (@np_components) {
|
||||
# 2. Test each possible module.
|
||||
my $component = get_db_single_row(
|
||||
$self->{'dbh'},
|
||||
'SELECT * FROM tnetwork_component WHERE id_nc = ?',
|
||||
$np_component->{'id_nc'}
|
||||
);
|
||||
|
||||
$component->{'name'} = safe_output($component->{'name'});
|
||||
if ($component->{'type'} >= 15 && $component->{'type'} <= 18) {
|
||||
$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'};
|
||||
}
|
||||
|
||||
$component->{'__module_component'} = 1;
|
||||
|
||||
# 3. Try to register module into monitoring list.
|
||||
$self->call('add_module', $device, $component);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
################################################################################
|
||||
|
@ -580,9 +713,9 @@ sub PandoraFMS::Recon::Base::report_scanned_agents($) {
|
|||
$self->call('message', "Agent id: ".$data->{'agent'}{'agent_id'}, 5);
|
||||
|
||||
# Create selected modules.
|
||||
if(ref($data->{'modules'}) eq "ARRAY") {
|
||||
for (my $i=0; $i < scalar @{$data->{'modules'}}; $i++) {
|
||||
my $module = $data->{'modules'}[$i];
|
||||
if(ref($data->{'modules'}) eq "HASH") {
|
||||
foreach my $i (keys %{$data->{'modules'}}) {
|
||||
my $module = $data->{'modules'}{$i};
|
||||
|
||||
# Do not create any modules if the agent is not in learning mode.
|
||||
next unless ($agent_learning == 1);
|
||||
|
@ -596,22 +729,33 @@ sub PandoraFMS::Recon::Base::report_scanned_agents($) {
|
|||
|
||||
my $agentmodule_id = $module->{'agentmodule_id'};
|
||||
if (!defined($agentmodule_id) || $agentmodule_id == 0) {
|
||||
# Create module.
|
||||
$agentmodule_id = pandora_create_module_from_hash(
|
||||
$self->{'pa_config'},
|
||||
{
|
||||
'id_tipo_modulo' => get_module_id($self->{'dbh'}, $module->{'type'}),
|
||||
'id_modulo' => $module->{'id_modulo'},
|
||||
'nombre' => safe_input($module->{'name'}),
|
||||
'descripcion' => '',
|
||||
'id_agente' => $agent_id,
|
||||
'ip_target' => $data->{'agent'}{'direccion'}
|
||||
},
|
||||
$self->{'dbh'}
|
||||
);
|
||||
|
||||
if (is_enabled($module->{'__module_component'})) {
|
||||
# Module from network component.
|
||||
$agentmodule_id = pandora_create_module_from_network_component(
|
||||
$self->{'pa_config'},
|
||||
$module,
|
||||
$agent_id,
|
||||
$self->{'dbh'}
|
||||
);
|
||||
} else {
|
||||
# Create module - Direct.
|
||||
$agentmodule_id = pandora_create_module_from_hash(
|
||||
$self->{'pa_config'},
|
||||
{
|
||||
'id_tipo_modulo' => get_module_id($self->{'dbh'}, $module->{'type'}),
|
||||
'id_modulo' => $module->{'id_modulo'},
|
||||
'nombre' => safe_input($module->{'name'}),
|
||||
'descripcion' => '',
|
||||
'id_agente' => $agent_id,
|
||||
'ip_target' => $data->{'agent'}{'direccion'}
|
||||
},
|
||||
$self->{'dbh'}
|
||||
);
|
||||
}
|
||||
|
||||
# Store.
|
||||
$data->{'modules'}[$i]{'agentmodule_id'} = $agentmodule_id;
|
||||
$data->{'modules'}{$i}{'agentmodule_id'} = $agentmodule_id;
|
||||
|
||||
$self->call(
|
||||
'message',
|
||||
|
@ -725,13 +869,11 @@ sub PandoraFMS::Recon::Base::apply_monitoring($) {
|
|||
# From 80% to 90%.
|
||||
my ($progress, $step) = (80, 10.0 / scalar(@hosts));
|
||||
|
||||
use Data::Dumper;
|
||||
print Dumper($self->{'task_data'});
|
||||
|
||||
foreach my $label (keys %{$self->{'agents_found'}}) {
|
||||
$self->call('update_progress', $progress);
|
||||
$progress += $step;
|
||||
print ">> $label\n";
|
||||
$self->call('message', "Checking modules for $label", 5);
|
||||
$self->call('create_network_profile_modules', $label);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -384,9 +384,9 @@ sub are_connected($$$$$) {
|
|||
$dev_1 = $self->{'aliases'}->{$dev_1} if defined($self->{'aliases'}->{$dev_1});
|
||||
$dev_2 = $self->{'aliases'}->{$dev_2} if defined($self->{'aliases'}->{$dev_2});
|
||||
|
||||
# Use ping modules when interfaces are unknown.
|
||||
$if_1 = "ping" if $if_1 eq '';
|
||||
$if_2 = "ping" if $if_2 eq '';
|
||||
# Use Host Alive modules when interfaces are unknown.
|
||||
$if_1 = "Host Alive" if $if_1 eq '';
|
||||
$if_2 = "Host Alive" if $if_2 eq '';
|
||||
|
||||
if ( defined($self->{'connections'}->{"${dev_1}\t${if_1}\t${dev_2}\t${if_2}"})
|
||||
||defined($self->{'connections'}->{"${dev_2}\t${if_2}\t${dev_1}\t${if_1}"})) {
|
||||
|
@ -405,7 +405,7 @@ sub icmp_discovery($$) {
|
|||
|
||||
$self->prepare_agent($addr);
|
||||
|
||||
$self->add_module($addr, 'icmp',
|
||||
$self->add_module($addr,
|
||||
{
|
||||
'ip_target' => $addr,
|
||||
'name' => "Host Alive",
|
||||
|
@ -1328,12 +1328,22 @@ sub add_agent($$) {
|
|||
################################################################################
|
||||
# Add module to agent (tmp pool) (will be registered at the end of the scan).
|
||||
################################################################################
|
||||
sub add_module($$$$) {
|
||||
my ($self, $agent, $type, $data) = @_;
|
||||
sub add_module($$$) {
|
||||
my ($self, $agent, $data) = @_;
|
||||
|
||||
$self->prepare_agent($agent);
|
||||
|
||||
push @{$self->{'agents_found'}->{$agent}->{'modules'}}, $data;
|
||||
$self->{'agents_found'}->{$agent}->{'modules'} = {}
|
||||
unless ref($self->{'agents_found'}->{$agent}->{'modules'}) eq 'HASH';
|
||||
|
||||
# Test module. Is it well defined?
|
||||
return unless ref($data) eq 'HASH' && defined($data->{'name'})
|
||||
&& $data->{'name'} ne '';
|
||||
|
||||
# Test module. Is it success?
|
||||
return unless $self->call('test_module', $agent, $data);
|
||||
|
||||
$self->{'agents_found'}->{$agent}->{'modules'}{$data->{'name'}} = $data;
|
||||
|
||||
}
|
||||
|
||||
|
@ -1409,7 +1419,7 @@ sub scan_subnet($) {
|
|||
{
|
||||
'fping' => $self->{'fping'},
|
||||
# XXX CAMBIAR POR 0.5
|
||||
'networktimeout' => 0.01 # use fping defaults
|
||||
'networktimeout' => 0.5 # use fping defaults
|
||||
},
|
||||
@hosts[$block_index .. $to - 1]
|
||||
);
|
||||
|
@ -2136,7 +2146,7 @@ sub wmi_scan {
|
|||
# CPU.
|
||||
my @cpus = $self->wmi_get_value_array($target, $auth, 'SELECT DeviceId FROM Win32_Processor', 0);
|
||||
foreach my $cpu (@cpus) {
|
||||
$self->add_module($target, 'wmi',
|
||||
$self->add_module($target,
|
||||
{
|
||||
'target' => $target,
|
||||
'query' => "SELECT LoadPercentage FROM Win32_Processor WHERE DeviceId='$cpu'",
|
||||
|
@ -2153,7 +2163,7 @@ sub wmi_scan {
|
|||
# Memory.
|
||||
my $mem = $self->wmi_get_value($target, $auth, 'SELECT FreePhysicalMemory FROM Win32_OperatingSystem', 0);
|
||||
if (defined($mem)) {
|
||||
$self->add_module($target, 'wmi',
|
||||
$self->add_module($target,
|
||||
{
|
||||
'target' => $target,
|
||||
'query' => "SELECT FreePhysicalMemory, TotalVisibleMemorySize FROM Win32_OperatingSystem",
|
||||
|
@ -2170,7 +2180,7 @@ sub wmi_scan {
|
|||
# Disk.
|
||||
my @units = $self->wmi_get_value_array($target, $auth, 'SELECT DeviceID FROM Win32_LogicalDisk', 0);
|
||||
foreach my $unit (@units) {
|
||||
$self->add_module($target, 'wmi',
|
||||
$self->add_module($target,
|
||||
{
|
||||
'target' => $target,
|
||||
'query' => "SELECT FreeSpace FROM Win32_LogicalDisk WHERE DeviceID='$unit'",
|
||||
|
|
|
@ -113,6 +113,7 @@ our @EXPORT = qw(
|
|||
is_metaconsole
|
||||
is_offline
|
||||
is_empty
|
||||
is_in_array
|
||||
to_number
|
||||
clean_blank
|
||||
credential_store_get_key
|
||||
|
@ -659,6 +660,23 @@ sub is_empty {
|
|||
return 0;
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# Check if a value is in an array
|
||||
################################################################################
|
||||
sub is_in_array {
|
||||
my ($array, $value) = @_;
|
||||
|
||||
if (is_empty($value)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
my %params = map { $_ => 1 } @{$array};
|
||||
if (exists($params{$value})) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# SUB md5check (param_1, param_2)
|
||||
# Verify MD5 file .checksum
|
||||
|
|
Loading…
Reference in New Issue