Use Exceptions

Use exceptions for addHost()
Gets rid of silly mixed return and only returns the device_id.  Throwing an exception if we run into any issues.
Slightly modifies api add host output again to include device_id
This commit is contained in:
Tony Murray
2016-08-07 12:16:40 -05:00
parent f1268848b0
commit f3fc6f2906
6 changed files with 77 additions and 55 deletions

View File

@@ -49,7 +49,7 @@ if (isset ($options['p'])) {
if (! in_array ($port_assoc_mode, $valid_assoc_modes)) { if (! in_array ($port_assoc_mode, $valid_assoc_modes)) {
echo "Invalid port association mode '" . $port_assoc_mode . "'\n"; echo "Invalid port association mode '" . $port_assoc_mode . "'\n";
echo 'Valid modes: ' . join (', ', $valid_assoc_modes) . "\n"; echo 'Valid modes: ' . join (', ', $valid_assoc_modes) . "\n";
exit(2); exit(1);
} }
$cmd = array_shift($argv); $cmd = array_shift($argv);
@@ -115,7 +115,7 @@ if (!empty($argv[1])) {
$v3['authalgo'] = $arg; $v3['authalgo'] = $arg;
} else { } else {
echo 'Invalid argument: '.$arg."\n"; echo 'Invalid argument: '.$arg."\n";
exit(2); exit(1);
} }
} }
@@ -139,7 +139,7 @@ if (!empty($argv[1])) {
$v3['cryptoalgo'] = $arg; $v3['cryptoalgo'] = $arg;
} else { } else {
echo 'Invalid argument: '.$arg."\n"; echo 'Invalid argument: '.$arg."\n";
exit(2); exit(1);
} }
}//end while }//end while
@@ -165,16 +165,20 @@ if (!empty($argv[1])) {
} }
}//end if }//end if
$result = addHost($host, $snmpver, $port, $transport, 0, $poller_group, $force_add, $port_assoc_mode); try {
$device_id = addHost($host, $snmpver, $port, $transport, $poller_group, $force_add, $port_assoc_mode);
if (is_numeric($result)) { $device = device_by_id_cache($device_id);
$device = device_by_id_cache($result); echo "Added device {$device['hostname']} ($device_id)\n";
echo 'Added device '.$device['hostname'].' ('.$result.")\n";
exit(0); exit(0);
} } catch (HostUnreachableException $e) {
else { print_error($e->getMessage());
print $console_color->convert("%rWe couldn't add this device:\n " . $result . "%n\n"); foreach ($e->getReasons() as $reason) {
exit(1); echo " $reason\n";
}
exit(2);
} catch (Exception $e){
print_error($e->getMessage());
exit(3);
} }
} else { } else {
@@ -197,5 +201,5 @@ if (!empty($argv[1])) {
%rRemember to run discovery for the host afterwards.%n %rRemember to run discovery for the host afterwards.%n
' '
); );
exit(2); exit(1);
} }

View File

@@ -289,14 +289,13 @@ function add_device() {
$message = "You haven't specified an SNMP version to use"; $message = "You haven't specified an SNMP version to use";
} }
if (empty($message)) { if (empty($message)) {
$result = addHost($hostname, $snmpver, $port, $transport, 1, $poller_group, $force_add); try {
if (is_numeric($result)) { $device_id = addHost($hostname, $snmpver, $port, $transport, $poller_group, $force_add);
$code = 201; $code = 201;
$status = 'ok'; $status = 'ok';
$message = "Device $hostname has been added successfully"; $message = "Device $hostname ($device_id) has been added successfully";
} } catch (Exception $e) {
else { $message = $e->getMessage();
$message = $result;
} }
} }

View File

@@ -66,11 +66,16 @@ if ($_POST['hostname']) {
} }
$port_assoc_mode = $_POST['port_assoc_mode']; $port_assoc_mode = $_POST['port_assoc_mode'];
$result = addHost($hostname, $snmpver, $port, $transport, 0, $poller_group, $force_add, $port_assoc_mode); try {
if (is_numeric($result)) { $device_id = addHost($hostname, $snmpver, $port, $transport, $poller_group, $force_add, $port_assoc_mode);
print_message("Device added ($result)"); print_message("Device added ($device_id)");
} else { } catch (HostUnreachableException $e) {
print_error('Error: ' . $result); print_error($e->getMessage());
foreach ($e->getReasons() as $reason) {
print_error($reason);
}
} catch (Exception $e){
print_error($e->getMessage());
} }
} }
else { else {

View File

@@ -53,9 +53,8 @@ function discover_new_device($hostname, $device = '', $method = '', $interface =
} }
if (match_network($config['nets'], $ip)) { if (match_network($config['nets'], $ip)) {
$result = addHost($dst_host, '', '161', 'udp', '0', $config['distributed_poller_group']); try {
if (is_numeric($result)) { $remote_device_id = addHost($dst_host, '', '161', 'udp', $config['distributed_poller_group']);
$remote_device_id = $result;
$remote_device = device_by_id_cache($remote_device_id, 1); $remote_device = device_by_id_cache($remote_device_id, 1);
echo '+[' . $remote_device['hostname'] . '(' . $remote_device['device_id'] . ')]'; echo '+[' . $remote_device['hostname'] . '(' . $remote_device['device_id'] . ')]';
discover_device($remote_device); discover_device($remote_device);
@@ -73,10 +72,10 @@ function discover_new_device($hostname, $device = '', $method = '', $interface =
} }
return $remote_device_id; return $remote_device_id;
} else { } catch (HostExistsException $e) {
if(substr($result, 0, 12) !== 'Already have') { // already have this device
log_event("$method discovery of " . $dst_host . " ($ip) failed - " . $result); } catch (Exception $e) {
} log_event("$method discovery of " . $dst_host . " ($ip) failed - " . $e->getMessage());
} }
} else { } else {
d_echo("$ip not in a matched network - skipping\n"); d_echo("$ip not in a matched network - skipping\n");

View File

@@ -17,7 +17,8 @@
include_once("Net/IPv4.php"); include_once("Net/IPv4.php");
include_once("Net/IPv6.php"); include_once("Net/IPv6.php");
// Observium Includes // Includes
include_once($config['install_dir'] . "/includes/exceptions.inc.php");
include_once($config['install_dir'] . "/includes/dbFacile.php"); include_once($config['install_dir'] . "/includes/dbFacile.php");
include_once($config['install_dir'] . "/includes/common.php"); include_once($config['install_dir'] . "/includes/common.php");
@@ -253,23 +254,30 @@ function delete_device($id) {
* @param string $snmp_version If this is empty, try v2c,v3,v1. Otherwise, use this specific version. * @param string $snmp_version If this is empty, try v2c,v3,v1. Otherwise, use this specific version.
* @param string $port the port to connect to for snmp * @param string $port the port to connect to for snmp
* @param string $transport udp or tcp * @param string $transport udp or tcp
* @param int $quiet don't output anything
* @param string $poller_group the poller group this device will belong to * @param string $poller_group the poller group this device will belong to
* @param string $force_add add even if the device isn't pingable * @param string $force_add add even if the device isn't pingable
* @param string $port_assoc_mode snmp field to use to determine unique ports * @param string $port_assoc_mode snmp field to use to determine unique ports
* @return int|string returns the id of the added device, otherwise an error message *
* @return int returns the device_id of the added device
*
* @throws HostExistsException This hostname already exists
* @throws HostIpExistsException We already have a host with this IP
* @throws HostUnreachableException We could not reach this device is some way
* @throws HostUnreachablePingException We could not ping the device
* @throws InvalidPortAssocModeException The given port association mode was invalid
* @throws SnmpVersionUnsupportedException The given snmp version was invalid
*/ */
function addHost($host, $snmp_version = '', $port = '161', $transport = 'udp', $quiet = 0, $poller_group = '0', $force_add = '0', $port_assoc_mode = 'ifIndex') { function addHost($host, $snmp_version = '', $port = '161', $transport = 'udp', $poller_group = '0', $force_add = '0', $port_assoc_mode = 'ifIndex') {
global $config; global $config;
// Test Database Exists // Test Database Exists
if (host_exists($host) === true) { if (host_exists($host) === true) {
return "Already have host $host"; throw new HostExistsException("Already have host $host");
} }
// Valid port assoc mode // Valid port assoc mode
if (!is_valid_port_assoc_mode($port_assoc_mode)) { if (!is_valid_port_assoc_mode($port_assoc_mode)) {
return "Invalid port association_mode '$port_assoc_mode'. Valid modes are: " . join(', ', get_port_assoc_modes()); throw new InvalidPortAssocModeException("Invalid port association_mode '$port_assoc_mode'. Valid modes are: " . join(', ', get_port_assoc_modes()));
} }
// check if we have the host by IP // check if we have the host by IP
@@ -279,14 +287,14 @@ function addHost($host, $snmp_version = '', $port = '161', $transport = 'udp', $
$ip = $host; $ip = $host;
} }
if (ip_exists($ip)) { if (ip_exists($ip)) {
return "Already have host with this IP $host"; throw new HostIpExistsException("Already have host with this IP $host");
} }
// Test reachability // Test reachability
$address_family = snmpTransportToAddressFamily($transport); $address_family = snmpTransportToAddressFamily($transport);
$ping_result = isPingable($host, $address_family); $ping_result = isPingable($host, $address_family);
if ($force_add == 1 || !$ping_result['result']) { if ($force_add == 1 || !$ping_result['result']) {
return "Could not ping $host"; throw new HostUnreachablePingException("Could not ping $host");
} }
// if $snmpver isn't set, try each version of snmp // if $snmpver isn't set, try each version of snmp
@@ -296,13 +304,13 @@ function addHost($host, $snmp_version = '', $port = '161', $transport = 'udp', $
$snmpvers = array($snmp_version); $snmpvers = array($snmp_version);
} }
$host_unreachable_exception = new HostUnreachableException("Could not connect, please check the snmp details and snmp reachability");
// try different snmp variables to add the device // try different snmp variables to add the device
foreach ($snmpvers as $snmpver) { foreach ($snmpvers as $snmpver) {
if ($snmpver === "v3") { if ($snmpver === "v3") {
// Try each set of parameters from config // Try each set of parameters from config
foreach ($config['snmp']['v3'] as $v3) { foreach ($config['snmp']['v3'] as $v3) {
$device = deviceArray($host, null, $snmpver, $port, $transport, $v3, $port_assoc_mode); $device = deviceArray($host, null, $snmpver, $port, $transport, $v3, $port_assoc_mode);
print_message("Trying v3 parameters " . $v3['authname'] . "/" . $v3['authlevel'] . " ... ", $quiet);
if ($force_add == 1 || isSNMPable($device)) { if ($force_add == 1 || isSNMPable($device)) {
$snmphost = snmp_get($device, "sysName.0", "-Oqv", "SNMPv2-MIB"); $snmphost = snmp_get($device, "sysName.0", "-Oqv", "SNMPv2-MIB");
$result = createHost($host, null, $snmpver, $port, $transport, $v3, $poller_group, $port_assoc_mode, $snmphost); $result = createHost($host, null, $snmpver, $port, $transport, $v3, $poller_group, $port_assoc_mode, $snmphost);
@@ -310,14 +318,14 @@ function addHost($host, $snmp_version = '', $port = '161', $transport = 'udp', $
return $result; return $result;
} }
} else { } else {
print_error("No reply on credentials " . $v3['authname'] . "/" . $v3['authlevel'] . " using $snmpver", $quiet); $host_unreachable_exception->addReason("SNMP $snmpver: No reply with credentials " . $v3['authname'] . "/" . $v3['authlevel']);
} }
} }
} elseif ($snmpver === "v2c" || $snmpver === "v1") { } elseif ($snmpver === "v2c" || $snmpver === "v1") {
// try each community from config // try each community from config
foreach ($config['snmp']['community'] as $community) { foreach ($config['snmp']['community'] as $community) {
$device = deviceArray($host, $community, $snmpver, $port, $transport, null, $port_assoc_mode); $device = deviceArray($host, $community, $snmpver, $port, $transport, null, $port_assoc_mode);
print_message("Trying community $community ...", $quiet);
if ($force_add == 1 || isSNMPable($device)) { if ($force_add == 1 || isSNMPable($device)) {
$snmphost = snmp_get($device, "sysName.0", "-Oqv", "SNMPv2-MIB"); $snmphost = snmp_get($device, "sysName.0", "-Oqv", "SNMPv2-MIB");
$result = createHost($host, $community, $snmpver, $port, $transport, array(), $poller_group, $port_assoc_mode, $snmphost); $result = createHost($host, $community, $snmpver, $port, $transport, array(), $poller_group, $port_assoc_mode, $snmphost);
@@ -325,15 +333,15 @@ function addHost($host, $snmp_version = '', $port = '161', $transport = 'udp', $
return $result; return $result;
} }
} else { } else {
print_error("No reply on community $community using $snmpver", $quiet); $host_unreachable_exception->addReason("SNMP $snmpver: No reply with community $community");
} }
} }
} else { } else {
return "Unsupported SNMP Version \"$snmpver\", must be v1, v2c, or v3"; throw new SnmpVersionUnsupportedException("Unsupported SNMP Version \"$snmpver\", must be v1, v2c, or v3");
} }
} }
return "Could not connect, please check the snmp details and snmp reachability"; throw $host_unreachable_exception;
} }
function deviceArray($host, $community, $snmpver, $port = 161, $transport = 'udp', $v3, $port_assoc_mode = 'ifIndex') { function deviceArray($host, $community, $snmpver, $port = 161, $transport = 'udp', $v3, $port_assoc_mode = 'ifIndex') {

View File

@@ -42,7 +42,7 @@ require 'includes/functions.php';
require 'includes/discovery/functions.inc.php'; require 'includes/discovery/functions.inc.php';
function perform_snmp_scan($net) { function perform_snmp_scan($net) {
global $stats, $config, $quiet; global $stats, $config, $debug;
echo 'Range: '.$net->network.'/'.$net->bitmask.PHP_EOL; echo 'Range: '.$net->network.'/'.$net->bitmask.PHP_EOL;
$config['snmp']['timeout'] = 1; $config['snmp']['timeout'] = 1;
$config['snmp']['retries'] = 0; $config['snmp']['retries'] = 0;
@@ -63,22 +63,30 @@ function perform_snmp_scan($net) {
continue; continue;
} }
foreach (array('udp','tcp') as $transport) { foreach (array('udp','tcp') as $transport) {
$result = addHost(gethostbyaddr($host), '', $config['snmp']['port'], $transport, $quiet, $config['distributed_poller_group'], 0); try {
if (is_numeric($result)) { addHost(gethostbyaddr($host), '', $config['snmp']['port'], $transport, $config['distributed_poller_group']);
$stats['added']++; $stats['added']++;
echo '+'; echo '+';
break; break;
} elseif (substr($result, 0, 12) === 'Already have') { } catch (HostExistsException $e) {
$stats['known']++; $stats['known']++;
echo '*'; echo '*';
break; break;
} elseif (substr($result, 0 , 14) === 'Could not ping') { } catch (HostUnreachablePingException $e) {
echo '.'; echo '.';
break; break;
} elseif ($transport == 'tcp') { } catch (HostUnreachableException $e) {
// tried both udp and tcp without success if ($debug) {
$stats['failed']++; print_error($e->getMessage() . " over $transport");
echo '-'; foreach ($e->getReasons() as $reason) {
echo " $reason\n";
}
}
if ($transport == 'tcp') {
// tried both udp and tcp without success
$stats['failed']++;
echo '-';
}
} }
} }
} }
@@ -104,7 +112,6 @@ if (isset($opts['h']) || (empty($opts) && (!isset($config['nets']) || empty($con
} }
if (isset($opts['d'])) { if (isset($opts['d'])) {
$debug = true; $debug = true;
$quiet = 0;
} }
if (isset($opts['l'])) { if (isset($opts['l'])) {
echo ' * = Known Device; . = Unpingable Device; + = Added Device; - = Failed To Add Device;'.PHP_EOL; echo ' * = Known Device; . = Unpingable Device; + = Added Device; - = Failed To Add Device;'.PHP_EOL;