From de56dccc8ab93d0b0b47fbe9a3e7a89d623fb562 Mon Sep 17 00:00:00 2001 From: Tony Murray Date: Sat, 10 Feb 2018 14:38:25 -0600 Subject: [PATCH] refactor: Move config loading into the Config class. (#8100) Self contain dbFacile too. Update rrdtool default setting to be similar to others. Move silly cisco-entities.php into entity-physical.inc.php --- LibreNMS/Config.php | 155 ++++++++++++++++++ includes/cisco-entities.php | 23 --- includes/dbFacile.php | 51 ++++++ includes/defaults.inc.php | 3 +- .../entity-physical/entity-physical.inc.php | 22 +++ includes/functions.php | 54 +----- includes/init.php | 29 ++-- includes/load_db_graph_types.inc.php | 28 ---- includes/mergecnf.inc.php | 71 -------- includes/rrdtool.inc.php | 10 +- 10 files changed, 247 insertions(+), 199 deletions(-) delete mode 100644 includes/cisco-entities.php delete mode 100644 includes/load_db_graph_types.inc.php delete mode 100644 includes/mergecnf.inc.php diff --git a/LibreNMS/Config.php b/LibreNMS/Config.php index cf4e0a5836..48ca5769e6 100644 --- a/LibreNMS/Config.php +++ b/LibreNMS/Config.php @@ -27,6 +27,64 @@ namespace LibreNMS; class Config { + /** + * Load the user config from config.php + * + * @param string $install_dir + * @return array + */ + public static function &load($install_dir = null) + { + global $config; + + if (empty($install_dir)) { + $install_dir = __DIR__ . '/../'; + } + $install_dir = realpath($install_dir); + $config['install_dir'] = $install_dir; + + // load defaults + require $install_dir . '/includes/defaults.inc.php'; + require $install_dir . '/includes/definitions.inc.php'; + + // variable definitions (remove me) + require $install_dir . '/includes/vmware_guestid.inc.php'; + + // Load user config + include $install_dir . '/config.php'; + + return $config; + } + + /** + * Load Config from the database + * + * @throws Exceptions\DatabaseConnectException + */ + public static function &loadFromDatabase() + { + global $config; + + if (empty($config)) { + self::load(); + } + + // Make sure the database is connected + dbConnect(); + + // pull in the database config settings + self::mergeDb(); + + // load graph types from the database + self::loadGraphsFromDb(); + + // Process $config to tidy up + self::processConfig(); + + return $config; + } + + /** * Get a config value, if non existent null (or default if set) will be returned * @@ -224,4 +282,101 @@ class Config return is_array($curr) && isset($curr[$last]); } + + /** + * merge the database config with the global config + * Global config overrides db + */ + private static function mergeDb() + { + global $config; + + $db_config = array(); + foreach (dbFetchRows('SELECT `config_name`,`config_value` FROM `config`') as $obj) { + self::assignArrayByPath($db_config, $obj['config_name'], $obj['config_value']); + } + $config = array_replace_recursive($db_config, $config); + } + + /** + * Assign a value into the passed array by a path + * 'snmp.version' = 'v1' becomes $arr['snmp']['version'] = 'v1' + * + * @param array $arr the array to insert the value into, will be modified in place + * @param string $path the path to insert the value at + * @param mixed $value the value to insert, will be type cast + * @param string $separator path separator + */ + private static function assignArrayByPath(&$arr, $path, $value, $separator = '.') + { + // type cast value. Is this needed here? + if (filter_var($value, FILTER_VALIDATE_INT)) { + $value = (int) $value; + } elseif (filter_var($value, FILTER_VALIDATE_FLOAT)) { + $value = (float) $value; + } elseif (filter_var($value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE) !== null) { + $value = filter_var($value, FILTER_VALIDATE_BOOLEAN); + } + + $keys = explode($separator, $path); + + // walk the array creating keys if they don't exist + foreach ($keys as $key) { + $arr = &$arr[$key]; + } + // assign the variable + $arr = $value; + } + + private static function loadGraphsFromDb() + { + global $config; + + // load graph types from the database + foreach (dbFetchRows('SELECT * FROM graph_types') as $graph) { + foreach ($graph as $k => $v) { + if (strpos($k, 'graph_') == 0) { + // remove leading 'graph_' from column name + $key = str_replace('graph_', '', $k); + } else { + $key = $k; + } + $g[$key] = $v; + } + + $config['graph_types'][$g['type']][$g['subtype']] = $g; + } + } + + /** + * Proces the config after it has been loaded. + * Make sure certain variables have been set properly and + * + * + */ + private static function processConfig() + { + if (!self::get('email_from')) { + self::set('email_from', '"' . self::get('project_name') . '" <' . self::get('email_user') . '@' . php_uname('n') . '>'); + } + + if (self::get('secure_cookies')) { + ini_set('session.cookie_secure', 1); + } + + if ($rrd_real_95th = self::get('rrdgraph_real_95th')) { + self::set('rrdgraph_real_percentile', $rrd_real_95th); + } + + if ($fping_millisc = self::get('fping_options.millisec')) { + self::set('fping_options.interval', $fping_millisc); + } + + // make sure we have full path to binaries in case PATH isn't set + foreach (array('fping', 'fping6', 'snmpgetnext', 'rrdtool') as $bin) { + if (!is_executable(self::get($bin))) { + self::set($bin, locate_binary($bin), true, $bin, "Path to $bin", 'external', 'paths'); + } + } + } } diff --git a/includes/cisco-entities.php b/includes/cisco-entities.php deleted file mode 100644 index 17cb7b978c..0000000000 --- a/includes/cisco-entities.php +++ /dev/null @@ -1,23 +0,0 @@ - 'C7200-IO-FE-MII', - 'cevChassis7140Dualfe' => 'C7140-2FE', - 'cevChassis7204' => 'C7204', - 'cevChassis7204Vxr' => 'C7204VXR', - 'cevChassis7206' => 'C7206', - 'cevChassis7206Vxr' => 'C7206VXR', - 'cevCpu7200Npe200' => 'NPE-200', - 'cevCpu7200Npe225' => 'NPE-225', - 'cevCpu7200Npe300' => 'NPE-300', - 'cevCpu7200Npe400' => 'NPE-400', - 'cevCpu7200Npeg1' => 'NPE-G1', - 'cevCpu7200Npeg2' => 'NPE-G2', - 'cevPa1feTxIsl' => 'PA-FE-TX-ISL', - 'cevPa2feTxI82543' => 'PA-2FE-TX', - 'cevPa8e' => 'PA-8E', - 'cevPaA8tX21' => 'PA-8T-X21', - 'cevMGBIC1000BaseLX' => '1000BaseLX GBIC', - 'cevPort10GigBaseLR' => '10GigBaseLR', -); diff --git a/includes/dbFacile.php b/includes/dbFacile.php index 72ed95b190..8c7bc745fb 100644 --- a/includes/dbFacile.php +++ b/includes/dbFacile.php @@ -624,3 +624,54 @@ function dbGenPlaceholders($count) { return '(' . implode(',', array_fill(0, $count, '?')) . ')'; } + +/** + * Update statistics for db operations + * + * @param string $stat fetchcell, fetchrow, fetchrows, fetchcolumn, update, insert, delete + * @param float $start_time The time the operation started with 'microtime(true)' + * @return float The calculated run time + */ +function recordDbStatistic($stat, $start_time) +{ + global $db_stats; + + if (!isset($db_stats)) { + $db_stats = array( + 'ops' => array( + 'insert' => 0, + 'update' => 0, + 'delete' => 0, + 'fetchcell' => 0, + 'fetchcolumn' => 0, + 'fetchrow' => 0, + 'fetchrows' => 0, + ), + 'time' => array( + 'insert' => 0.0, + 'update' => 0.0, + 'delete' => 0.0, + 'fetchcell' => 0.0, + 'fetchcolumn' => 0.0, + 'fetchrow' => 0.0, + 'fetchrows' => 0.0, + ), + ); + } + + $runtime = microtime(true) - $start_time; + $db_stats['ops'][$stat]++; + $db_stats['time'][$stat] += $runtime; + + //double accounting corrections + if ($stat == 'fetchcolumn') { + $db_stats['ops']['fetchrows']--; + $db_stats['time']['fetchrows'] -= $runtime; + } + if ($stat == 'fetchcell') { + $db_stats['ops']['fetchrow']--; + $db_stats['time']['fetchrow'] -= $runtime; + } + + return $runtime; +} diff --git a/includes/defaults.inc.php b/includes/defaults.inc.php index 44fb5f1c11..479d269267 100644 --- a/includes/defaults.inc.php +++ b/includes/defaults.inc.php @@ -20,7 +20,6 @@ // // Please don't edit this file -- make changes to the configuration array in config.php // -error_reporting(E_ERROR|E_PARSE|E_CORE_ERROR|E_COMPILE_ERROR); // Default directories $config['project_name'] = 'LibreNMS'; @@ -123,7 +122,7 @@ $config['int_customers'] = 1; // Enable Customer Port Parsing $config['customers_descr'] = 'cust'; $config['transit_descr'][] = 'transit'; -// Add custom transit descriptions (can be an string) +// Add custom transit descriptions (can be an string) $config['peering_descr'][] = 'peering'; // Add custom peering descriptions (can be an string) $config['core_descr'][] = 'core'; diff --git a/includes/discovery/entity-physical/entity-physical.inc.php b/includes/discovery/entity-physical/entity-physical.inc.php index 5004603197..a8f2a6e564 100644 --- a/includes/discovery/entity-physical/entity-physical.inc.php +++ b/includes/discovery/entity-physical/entity-physical.inc.php @@ -89,6 +89,28 @@ foreach ($entity_array as $entPhysicalIndex => $entry) { unset($ifIndex_array); } + // List of real names for cisco entities + $entPhysicalVendorTypes = array( + 'cevC7xxxIo1feTxIsl' => 'C7200-IO-FE-MII', + 'cevChassis7140Dualfe' => 'C7140-2FE', + 'cevChassis7204' => 'C7204', + 'cevChassis7204Vxr' => 'C7204VXR', + 'cevChassis7206' => 'C7206', + 'cevChassis7206Vxr' => 'C7206VXR', + 'cevCpu7200Npe200' => 'NPE-200', + 'cevCpu7200Npe225' => 'NPE-225', + 'cevCpu7200Npe300' => 'NPE-300', + 'cevCpu7200Npe400' => 'NPE-400', + 'cevCpu7200Npeg1' => 'NPE-G1', + 'cevCpu7200Npeg2' => 'NPE-G2', + 'cevPa1feTxIsl' => 'PA-FE-TX-ISL', + 'cevPa2feTxI82543' => 'PA-2FE-TX', + 'cevPa8e' => 'PA-8E', + 'cevPaA8tX21' => 'PA-8T-X21', + 'cevMGBIC1000BaseLX' => '1000BaseLX GBIC', + 'cevPort10GigBaseLR' => '10GigBaseLR', + ); + if ($entPhysicalVendorTypes[$entPhysicalVendorType] && !$entPhysicalModelName) { $entPhysicalModelName = $entPhysicalVendorTypes[$entPhysicalVendorType]; } diff --git a/includes/functions.php b/includes/functions.php index c68bc2bc12..cd5272d702 100644 --- a/includes/functions.php +++ b/includes/functions.php @@ -1987,9 +1987,9 @@ function get_toner_levels($device, $raw_value, $capacity) */ function initStats() { - global $snmp_stats, $db_stats, $rrd_stats; + global $snmp_stats, $rrd_stats; - if (!isset($snmp_stats, $db_stats, $rrd_stats)) { + if (!isset($snmp_stats, $rrd_stats)) { $snmp_stats = array( 'ops' => array( 'snmpget' => 0, @@ -2003,27 +2003,6 @@ function initStats() ) ); - $db_stats = array( - 'ops' => array( - 'insert' => 0, - 'update' => 0, - 'delete' => 0, - 'fetchcell' => 0, - 'fetchcolumn' => 0, - 'fetchrow' => 0, - 'fetchrows' => 0, - ), - 'time' => array( - 'insert' => 0.0, - 'update' => 0.0, - 'delete' => 0.0, - 'fetchcell' => 0.0, - 'fetchcolumn' => 0.0, - 'fetchrow' => 0.0, - 'fetchrows' => 0.0, - ), - ); - $rrd_stats = array( 'ops' => array( 'update' => 0, @@ -2138,35 +2117,6 @@ function recordRrdStatistic($stat, $start_time) return $runtime; } -/** - * Update statistics for db operations - * - * @param string $stat fetchcell, fetchrow, fetchrows, fetchcolumn, update, insert, delete - * @param float $start_time The time the operation started with 'microtime(true)' - * @return float The calculated run time - */ -function recordDbStatistic($stat, $start_time) -{ - global $db_stats; - initStats(); - - $runtime = microtime(true) - $start_time; - $db_stats['ops'][$stat]++; - $db_stats['time'][$stat] += $runtime; - - //double accounting corrections - if ($stat == 'fetchcolumn') { - $db_stats['ops']['fetchrows']--; - $db_stats['time']['fetchrows'] -= $runtime; - } - if ($stat == 'fetchcell') { - $db_stats['ops']['fetchrow']--; - $db_stats['time']['fetchrow'] -= $runtime; - } - - return $runtime; -} - /** * @param string $stat snmpget, snmpwalk * @param float $start_time The time the operation started with 'microtime(true)' diff --git a/includes/init.php b/includes/init.php index aa82fd3335..260d8f8b21 100644 --- a/includes/init.php +++ b/includes/init.php @@ -28,9 +28,12 @@ */ use LibreNMS\Authentication\Auth; +use LibreNMS\Config; global $config; +error_reporting(E_ERROR|E_PARSE|E_CORE_ERROR|E_COMPILE_ERROR); + $install_dir = realpath(__DIR__ . '/..'); $config['install_dir'] = $install_dir; chdir($install_dir); @@ -65,7 +68,6 @@ if (module_selected('mocksnmp', $init_modules)) { require_once $install_dir . '/includes/snmp.inc.php'; } require_once $install_dir . '/includes/services.inc.php'; -require_once $install_dir . '/includes/mergecnf.inc.php'; require_once $install_dir . '/includes/functions.php'; require_once $install_dir . '/includes/rewrites.php'; @@ -88,19 +90,11 @@ if (module_selected('alerts', $init_modules)) { require_once $install_dir . '/includes/alerts.inc.php'; } -// variable definitions -require $install_dir . '/includes/cisco-entities.php'; -require $install_dir . '/includes/vmware_guestid.inc.php'; -require $install_dir . '/includes/defaults.inc.php'; -require $install_dir . '/includes/definitions.inc.php'; - // Display config.php errors instead of http 500 $display_bak = ini_get('display_errors'); ini_set('display_errors', 1); -include $install_dir . '/config.php'; -if (isset($config['php_memory_limit']) && is_numeric($config['php_memory_limit']) && $config['php_memory_limit'] > 128) { - ini_set('memory_limit', $config['php_memory_limit'].'M'); -} +Config::load($install_dir); +// set display_errors back ini_set('display_errors', $display_bak); if (!module_selected('nodb', $init_modules)) { @@ -120,6 +114,8 @@ if (!module_selected('nodb', $init_modules)) { // Connect to database try { dbConnect(); + + Config::loadFromDatabase(); } catch (\LibreNMS\Exceptions\DatabaseConnectException $e) { if (isCli()) { echo 'MySQL Error: ' . $e->getMessage() . PHP_EOL; @@ -128,15 +124,10 @@ if (!module_selected('nodb', $init_modules)) { } exit(2); } +} - // pull in the database config settings - mergedb(); - - // load graph types from the database - require $install_dir . '/includes/load_db_graph_types.inc.php'; - - // Process $config to tidy up - require $install_dir . '/includes/process_config.inc.php'; +if (isset($config['php_memory_limit']) && is_numeric($config['php_memory_limit']) && $config['php_memory_limit'] > 128) { + ini_set('memory_limit', $config['php_memory_limit'].'M'); } try { diff --git a/includes/load_db_graph_types.inc.php b/includes/load_db_graph_types.inc.php deleted file mode 100644 index e970ada325..0000000000 --- a/includes/load_db_graph_types.inc.php +++ /dev/null @@ -1,28 +0,0 @@ - - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. Please see LICENSE.txt at the top level of - * the source code distribution for details. - */ - -// load graph types from the database -foreach (dbFetchRows('select * from graph_types') as $graph) { - foreach ($graph as $k => $v) { - if (strpos($k, 'graph_') == 0) { - // remove leading 'graph_' from column name - $key = str_replace('graph_', '', $k); - } else { - $key = $k; - } - $g[$key] = $v; - } - - $config['graph_types'][$g['type']][$g['subtype']] = $g; -} diff --git a/includes/mergecnf.inc.php b/includes/mergecnf.inc.php deleted file mode 100644 index 3497223a15..0000000000 --- a/includes/mergecnf.inc.php +++ /dev/null @@ -1,71 +0,0 @@ - - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * */ - -/** - * Merge config function - * @author f0o - * @copyright 2015 f0o, LibreNMS - * @license GPL - * @package LibreNMS - * @subpackage Config - */ - - -/** - * merge the database config with the global config - * Global config overrides db - */ -function mergedb() -{ - global $config; - - $db_config = array(); - foreach (dbFetchRows('SELECT `config_name`,`config_value` FROM `config`') as $obj) { - assign_array_by_path($db_config, $obj['config_name'], $obj['config_value']); - } - $config = array_replace_recursive($db_config, $config); -} - -/** - * Assign a value into the passed array by a path - * 'snmp.version' = 'v1' becomes $arr['snmp']['version'] = 'v1' - * - * @param array $arr the array to insert the value into, will be modified in place - * @param string $path the path to insert the value at - * @param mixed $value the value to insert, will be type cast - * @param string $separator path separator - */ -function assign_array_by_path(&$arr, $path, $value, $separator = '.') -{ - // type cast value. Is this needed here? - if (filter_var($value, FILTER_VALIDATE_INT)) { - $value = (int) $value; - } elseif (filter_var($value, FILTER_VALIDATE_FLOAT)) { - $value = (float) $value; - } elseif (filter_var($value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE) !== null) { - $value = filter_var($value, FILTER_VALIDATE_BOOLEAN); - } - - $keys = explode($separator, $path); - - // walk the array creating keys if they don't exist - foreach ($keys as $key) { - $arr = &$arr[$key]; - } - // assign the variable - $arr = $value; -} diff --git a/includes/rrdtool.inc.php b/includes/rrdtool.inc.php index aaca84532e..dd801c2183 100644 --- a/includes/rrdtool.inc.php +++ b/includes/rrdtool.inc.php @@ -24,6 +24,7 @@ * @author Tony Murray */ +use LibreNMS\Config; use LibreNMS\Exceptions\FileExistsException; use LibreNMS\Proc; @@ -192,7 +193,7 @@ function rrdtool_build_command($command, $filename, $options) if ($command == 'create') { // <1.4.3 doesn't support -O, so make sure the file doesn't exist - if (version_compare($config['rrdtool_version'], '1.4.3', '<')) { + if (version_compare(Config::get('rrdtool_version', '1.4'), '1.4.3', '<')) { if (is_file($filename)) { throw new FileExistsException(); } @@ -202,9 +203,10 @@ function rrdtool_build_command($command, $filename, $options) } // no remote for create < 1.5.5 and tune < 1.5 + $rrdtool_version = Config::get('rrdtool_version', '1.4'); if ($config['rrdcached'] && - !($command == 'create' && version_compare($config['rrdtool_version'], '1.5.5', '<')) && - !($command == 'tune' && $config['rrdcached'] && version_compare($config['rrdtool_version'], '1.5', '<')) + !($command == 'create' && version_compare($rrdtool_version, '1.5.5', '<')) && + !($command == 'tune' && $config['rrdcached'] && version_compare($rrdtool_version, '1.5', '<')) ) { // only relative paths if using rrdcached $filename = str_replace(array($config['rrd_dir'].'/', $config['rrd_dir']), '', $filename); @@ -226,7 +228,7 @@ function rrdtool_build_command($command, $filename, $options) function rrdtool_check_rrd_exists($filename) { global $config; - if ($config['rrdcached'] && version_compare($config['rrdtool_version'], '1.5', '>=')) { + if ($config['rrdcached'] && version_compare(Config::get('rrdtool_version', '1.4'), '1.5', '>=')) { $chk = rrdtool('last', $filename, ''); $filename = str_replace(array($config['rrd_dir'].'/', $config['rrd_dir']), '', $filename); return !str_contains(implode($chk), "$filename': No such file or directory");