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)) {
echo "Invalid port association mode '" . $port_assoc_mode . "'\n";
echo 'Valid modes: ' . join (', ', $valid_assoc_modes) . "\n";
exit(2);
exit(1);
}
$cmd = array_shift($argv);
@@ -115,7 +115,7 @@ if (!empty($argv[1])) {
$v3['authalgo'] = $arg;
} else {
echo 'Invalid argument: '.$arg."\n";
exit(2);
exit(1);
}
}
@@ -139,7 +139,7 @@ if (!empty($argv[1])) {
$v3['cryptoalgo'] = $arg;
} else {
echo 'Invalid argument: '.$arg."\n";
exit(2);
exit(1);
}
}//end while
@@ -165,16 +165,20 @@ if (!empty($argv[1])) {
}
}//end if
$result = addHost($host, $snmpver, $port, $transport, 0, $poller_group, $force_add, $port_assoc_mode);
if (is_numeric($result)) {
$device = device_by_id_cache($result);
echo 'Added device '.$device['hostname'].' ('.$result.")\n";
try {
$device_id = addHost($host, $snmpver, $port, $transport, $poller_group, $force_add, $port_assoc_mode);
$device = device_by_id_cache($device_id);
echo "Added device {$device['hostname']} ($device_id)\n";
exit(0);
}
else {
print $console_color->convert("%rWe couldn't add this device:\n " . $result . "%n\n");
exit(1);
} catch (HostUnreachableException $e) {
print_error($e->getMessage());
foreach ($e->getReasons() as $reason) {
echo " $reason\n";
}
exit(2);
} catch (Exception $e){
print_error($e->getMessage());
exit(3);
}
} else {
@@ -197,5 +201,5 @@ if (!empty($argv[1])) {
%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";
}
if (empty($message)) {
$result = addHost($hostname, $snmpver, $port, $transport, 1, $poller_group, $force_add);
if (is_numeric($result)) {
try {
$device_id = addHost($hostname, $snmpver, $port, $transport, $poller_group, $force_add);
$code = 201;
$status = 'ok';
$message = "Device $hostname has been added successfully";
}
else {
$message = $result;
$message = "Device $hostname ($device_id) has been added successfully";
} catch (Exception $e) {
$message = $e->getMessage();
}
}

View File

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

View File

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

View File

@@ -17,7 +17,8 @@
include_once("Net/IPv4.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/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 $port the port to connect to for snmp
* @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 $force_add add even if the device isn't pingable
* @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;
// Test Database Exists
if (host_exists($host) === true) {
return "Already have host $host";
throw new HostExistsException("Already have host $host");
}
// Valid 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
@@ -279,14 +287,14 @@ function addHost($host, $snmp_version = '', $port = '161', $transport = 'udp', $
$ip = $host;
}
if (ip_exists($ip)) {
return "Already have host with this IP $host";
throw new HostIpExistsException("Already have host with this IP $host");
}
// Test reachability
$address_family = snmpTransportToAddressFamily($transport);
$ping_result = isPingable($host, $address_family);
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
@@ -296,13 +304,13 @@ function addHost($host, $snmp_version = '', $port = '161', $transport = 'udp', $
$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
foreach ($snmpvers as $snmpver) {
if ($snmpver === "v3") {
// Try each set of parameters from config
foreach ($config['snmp']['v3'] as $v3) {
$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)) {
$snmphost = snmp_get($device, "sysName.0", "-Oqv", "SNMPv2-MIB");
$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;
}
} 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") {
// try each community from config
foreach ($config['snmp']['community'] as $community) {
$device = deviceArray($host, $community, $snmpver, $port, $transport, null, $port_assoc_mode);
print_message("Trying community $community ...", $quiet);
if ($force_add == 1 || isSNMPable($device)) {
$snmphost = snmp_get($device, "sysName.0", "-Oqv", "SNMPv2-MIB");
$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;
}
} else {
print_error("No reply on community $community using $snmpver", $quiet);
$host_unreachable_exception->addReason("SNMP $snmpver: No reply with community $community");
}
}
} 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') {

View File

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