diff --git a/pandora_server/ChangeLog b/pandora_server/ChangeLog index ffb591bd14..6208febefd 100644 --- a/pandora_server/ChangeLog +++ b/pandora_server/ChangeLog @@ -1,3 +1,8 @@ +2011-10-10 Dario Rodriguez <dario.rodriguez@artica.es> + + * util/plugin/ipmi-plugin.pl: Added first version of ipmi plugin. + * util/recon_scripts/ipmi-recon.pl: Added first version of ipmi recon task + 2011-10-10 Javier Lanz <javier.lanz@artica.es> * util/pandora_manage.pl: Fixed a wee bug with 'group' parameter diff --git a/pandora_server/util/plugin/ipmi-plugin.pl b/pandora_server/util/plugin/ipmi-plugin.pl new file mode 100644 index 0000000000..368b3349b0 --- /dev/null +++ b/pandora_server/util/plugin/ipmi-plugin.pl @@ -0,0 +1,46 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +sub get_param($) { + my $param = shift; + my $value = undef; + + $param = "-".$param; + + for(my $i=0; $i<$#ARGV; $i++) { + + if ($ARGV[$i] eq $param) { + $value = $ARGV[$i+1]; + last; + } + + } + + return $value; +} + +my $host = get_param("h"); +my $user = get_param("u"); +my $pass = get_param("p"); +my $sensor = get_param("s"); + +my $res = `ipmi-sensors -h $host -u $user -p $pass -s $sensor`; + +my @aux = split(/:/, $res); + +my $value = $aux[2]; + +$value =~ s/\n//; + +if ($value =~ / (\S+) .+/) { + $value = $1; +} + +#Clean value +$value =~ s/^\s+//; +$value =~ s/\s+$//; + +#Output the value +print $value; diff --git a/pandora_server/util/recon_scripts/ipmi-recon.pl b/pandora_server/util/recon_scripts/ipmi-recon.pl new file mode 100644 index 0000000000..170768b934 --- /dev/null +++ b/pandora_server/util/recon_scripts/ipmi-recon.pl @@ -0,0 +1,232 @@ +#!/usr/bin/perl +# (c) Dario Rodriguez 2011 <dario.rodriguez@artica.es> +# Intel DCM Discovery + +use POSIX qw(setsid strftime strftime ceil); + +use strict; +use warnings; + +use IO::Socket::INET; +use NetAddr::IP; + +# Default lib dir for RPM and DEB packages + +use lib '/usr/lib/perl5'; + +use PandoraFMS::Tools; +use PandoraFMS::DB; +use PandoraFMS::Core; +use PandoraFMS::Config; +########################################################################## +# Global variables so set behaviour here: + +my $target_timeout = 5; # Fixed to 5 secs by default + +########################################################################## +# Code begins here, do not touch +########################################################################## +my $pandora_conf = "/etc/pandora/pandora_server.conf"; +my $task_id = $ARGV[0]; # Passed automatically by the server +my $target_group = $ARGV[1]; # Defined by user +my $create_incident = $ARGV[2]; # Defined by user + +# Used Custom Fields in this script +my $target_network = $ARGV[3]; # Filed1 defined by user +my $username = $ARGV[4]; # Field2 defined by user +my $password = $ARGV[5]; # Field3 defined by user + + +########################################################################## +# 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); +} + +########################################################################## +# Show help +########################################################################## +sub show_help { + print "\nSpecific Pandora FMS Intel DCM Discovery\n"; + print "(c) Artica ST 2011 <info\@artica.es>\n\n"; + print "Usage:\n\n"; + print " $0 <task_id> <group_id> <create_incident_flag> <custom_field1> <custom_field2> <custom_field3>\n\n"; + print " * custom_field1 = network. i.e.: 192.168.100.0/24\n"; + print " * custom_field2 = username \n"; + print " * custom_fiedl3 = password \n"; + exit; +} + +########################################################################## +# Get SNMP response. +########################################################################## +sub get_snmp_response ($$$) { + my ($target_timeout, $target_community, $addr) = @_; + + # The OID used is the SysUptime OID + my $buffer = `/usr/bin/snmpget -v 1 -r0 -t$target_timeout -OUevqt -c '$target_community' $addr .1.3.6.1.2.1.1.3.0 2>/dev/null`; + + # Remove forbidden caracters + $buffer =~ s/\l|\r|\"|\n|\<|\>|\&|\[|\]//g; + + return $buffer; +} + +sub ipmi_ping ($) { + my $addr = shift; + + my $cmd = "ipmiping $addr -c 3"; + + my $res = `$cmd`; + + if ($res =~ /100\.0% packet loss/) { + return 0; + } + + return 1; +} + +sub create_ipmi_modules($$$$$$) { + my ($conf, $dbh, $addr, $user, $pass, $id_agent) = @_; + + my $cmd = "ipmi-sensors -h $addr -u $user -p $pass"; + + my $res = `$cmd`; + + my @lines = split(/\n/, $res); + + my $ipmi_plugin_id = get_db_value($dbh, "SELECT id FROM tplugin WHERE name = '".safe_input("IPMI Plugin")."'"); + + + foreach my $line (@lines) { + my @aux = split(/:/, $line); + + my $name = $aux[1]; + + #Trim name + $name =~ s/^\s+//; + $name =~ s/\s+$//; + + my $module_type = "generic_data_string"; + + if ($aux[2] =~ /.+ (\w) \(/) { + $module_type = "generic_data"; + } + + my $id_module_type = get_module_id($dbh, $module_type); + + my $params = "-s $aux[0]"; + + my %parameters; + + $parameters{"nombre"} = safe_input($name); + $parameters{"id_tipo_modulo"} = $id_module_type; + $parameters{"id_agente"} = $id_agent; + $parameters{"id_plugin"} = $ipmi_plugin_id; + $parameters{"ip_target"} = $addr; + $parameters{"plugin_user"} = $user; + $parameters{"plugin_pass"} = $pass; + $parameters{"id_modulo"} = 4; + $parameters{"plugin_parameter"} = $params; + + pandora_create_module_from_hash ($conf, \%parameters, $dbh); + + } +} + +########################################################################## +########################################################################## +# M A I N C O D E +########################################################################## +########################################################################## + + +if ($#ARGV == -1){ + show_help(); +} + +# Pandora server configuration +my %conf; +$conf{"quiet"} = 0; +$conf{"verbosity"} = 1; # Verbose 1 by default +$conf{"daemon"}=0; # Daemon 0 by default +$conf{'PID'}=""; # PID file not exist by default +$conf{'pandora_path'} = $pandora_conf; + +# Read config file +pandora_load_config (\%conf); + +# Connect to the DB +my $dbh = db_connect ('mysql', $conf{'dbname'}, $conf{'dbhost'}, '3306', $conf{'dbuser'}, $conf{'dbpass'}); + + +# Start the network sweep +# Get a NetAddr::IP object for the target network +my $net_addr = new NetAddr::IP ($target_network); +if (! defined ($net_addr)) { + logger (\%conf, "Invalid network " . $target_network . " for Intel DCM Discovery task", 1); + update_recon_task ($dbh, $task_id, -1); + return -1; +} + +# Scan the network for host +my ($total_hosts, $hosts_found, $addr_found) = ($net_addr->num, 0, ''); + +my $last = 0; +for (my $i = 1; $net_addr <= $net_addr->broadcast; $i++, $net_addr++) { + if($last == 1) { + last; + } + + my $net_addr_temp = $net_addr + 1; + if($net_addr eq $net_addr_temp) { + $last = 1; + } + + if ($net_addr =~ /\b\d{1,3}\.\d{1,3}\.\d{1,3}\.(\d{1,3})\b/) { + if($1 eq '0' || $1 eq '255') { + next; + } + } + + my $addr = (split(/\//, $net_addr))[0]; + $hosts_found ++; + + # Update the recon task + update_recon_task ($dbh, $task_id, ceil ($i / ($total_hosts / 100))); + + my $alive = 0; + if (ipmi_ping ($addr) == 1) { + $alive = 1; + } + + next unless ($alive > 0); + + # Resolve the address + my $host_name = gethostbyaddr(inet_aton($addr), AF_INET); + $host_name = $addr unless defined ($host_name); + + logger(\%conf, "Intel DCM Device found host $host_name.", 10); + + # Check if the agent exists + my $agent_id = get_agent_id($dbh, $host_name); + + # If the agent doesnt exist we create it + if($agent_id == -1) { + # Create a new agent + $agent_id = pandora_create_agent (\%conf, $conf{'servername'}, $host_name, $addr, $target_group, 0, 11, '', 300, $dbh); + + create_ipmi_modules(\%conf, $dbh, $addr, $username, $password, $agent_id); + } + + # Generate an event + pandora_event (\%conf, "[RECON] New Intel DCM host [$host_name] detected on network [" . $target_network . ']', $target_group, $agent_id, 2, 0, 0, 'recon_host_detected', 0, $dbh); +} + +# Mark recon task as done +update_recon_task ($dbh, $task_id, -1); + +# End of code