From fbb6d3506113fed6231ba6f2859d7d99bbe63dc0 Mon Sep 17 00:00:00 2001 From: dupondje Date: Tue, 4 Sep 2018 23:41:51 +0200 Subject: [PATCH] Added support for Rancid git (#9036) DO NOT DELETE THIS TEXT #### Please note > Please read this information carefully. You can run `./scripts/pre-commit.php` to check your code before submitting. - [X] Have you followed our [code guidelines?](http://docs.librenms.org/Developing/Code-Guidelines/) #### Testers If you would like to test this pull request then please run: `./scripts/github-apply `, i.e `./scripts/github-apply 5926` This pull req adds support for Rancid GIT backend (instead of the current supported SVN). Not only git is preferred these days, also php-svn is non-existing on php 7+, so the only Rancid option is broken on PHP 7+, so might be nice to have this included :) --- doc/Extensions/Rancid.md | 5 +- doc/Support/Configuration.md | 1 + html/pages/device/showconfig.inc.php | 123 +++++++++++++++++++-------- includes/defaults.inc.php | 1 + 4 files changed, 93 insertions(+), 37 deletions(-) diff --git a/doc/Extensions/Rancid.md b/doc/Extensions/Rancid.md index c145e1a4c3..31ba22bda5 100644 --- a/doc/Extensions/Rancid.md +++ b/doc/Extensions/Rancid.md @@ -36,7 +36,7 @@ The options shown below also contains the default values. `sudo apt-get install rancid subversion` -Edit Rancid config file to use subversion instead of default cvs, and adds a group: +Edit Rancid config file to use subversion or git instead of default cvs, and adds a group: `sudo vi /etc/rancid/rancid.conf` `LIST_OF_GROUPS="librenms"` @@ -130,8 +130,9 @@ Add Rancid into LibreNMS config.php: ```php ### Rancid $config['rancid_configs'][] = '/var/lib/rancid/librenms/configs/'; +$config['rancid_repo_type'] = 'svn'; //'svn' or 'git' $config['rancid_ignorecomments'] = 0; ``` Now restart apache -`sudo /etc/init.d/apache2 restart` \ No newline at end of file +`sudo /etc/init.d/apache2 restart` diff --git a/doc/Support/Configuration.md b/doc/Support/Configuration.md index f9e352baaf..42b626b184 100644 --- a/doc/Support/Configuration.md +++ b/doc/Support/Configuration.md @@ -440,6 +440,7 @@ Enable / disable additional port statistics. ```php $config['rancid_configs'][] = '/var/lib/rancid/network/configs/'; +$config['rancid_repo_type'] = 'svn'; $config['rancid_ignorecomments'] = 0; ``` Rancid configuration, `rancid_configs` is an array containing all of the locations of your rancid files. diff --git a/html/pages/device/showconfig.inc.php b/html/pages/device/showconfig.inc.php index 1ac3f95bfa..17df0f0903 100644 --- a/html/pages/device/showconfig.inc.php +++ b/html/pages/device/showconfig.inc.php @@ -2,14 +2,16 @@ // FIXME svn stuff still using optc etc, won't work, needs updating! use LibreNMS\Authentication\Auth; +use LibreNMS\Config; +use Symfony\Component\Process\Process; if (Auth::user()->hasGlobalAdmin()) { - if (!is_array($config['rancid_configs'])) { - $config['rancid_configs'] = array($config['rancid_configs']); + if (!is_array(Config::get('rancid_configs'))) { + Config::set('rancid_configs', array(Config::get('rancid_configs'))); } - if (isset($config['rancid_configs'][0])) { - foreach ($config['rancid_configs'] as $configs) { + if (isset(Config::get('rancid_configs')[0])) { + foreach (Config::get('rancid_configs') as $configs) { if ($configs[(strlen($configs) - 1)] != '/') { $configs .= '/'; } @@ -19,9 +21,9 @@ if (Auth::user()->hasGlobalAdmin()) { } elseif (is_file($configs.strtok($device['hostname'], '.'))) { // Strip domain $file = $configs.strtok($device['hostname'], '.'); } else { - if (!empty($config['mydomain'])) { // Try with domain name if set - if (is_file($configs.$device['hostname'].'.'.$config['mydomain'])) { - $file = $configs.$device['hostname'].'.'.$config['mydomain']; + if (!empty(Config::get('mydomain'))) { // Try with domain name if set + if (is_file($configs.$device['hostname'].'.'.Config::get('mydomain'))) { + $file = $configs.$device['hostname'].'.'.Config::get('mydomain'); } } } // end if @@ -41,7 +43,7 @@ if (Auth::user()->hasGlobalAdmin()) { echo generate_link('Latest', array('page' => 'device', 'device' => $device['device_id'], 'tab' => 'showconfig')); } - if (function_exists('svn_log')) { + if (Config::get('rancid_repo_type') == 'svn' && function_exists('svn_log')) { $sep = ' | '; $svnlogs = svn_log($file, SVN_REVISION_HEAD, null, 8); $revlist = array(); @@ -54,7 +56,7 @@ if (Auth::user()->hasGlobalAdmin()) { echo ''; } - $linktext = 'r'.$svnlog['rev'].' '.date($config['dateformat']['byminute'], strtotime($svnlog['date'])).''; + $linktext = 'r'.$svnlog['rev'].' '.date(Config::get('dateformat')['byminute'], strtotime($svnlog['date'])).''; echo generate_link($linktext, array('page' => 'device', 'device' => $device['device_id'], 'tab' => 'showconfig', 'rev' => $svnlog['rev'])); if ($vars['rev'] == $svnlog['rev']) { @@ -64,29 +66,80 @@ if (Auth::user()->hasGlobalAdmin()) { $sep = ' | '; } }//end if + if (Config::get('rancid_repo_type') == 'git') { + $sep = ' | '; + + $process = new Process(array('git', 'log', '-n 8', '--pretty=format:%h;%ct', $file), $configs); + $process->run(); + $gitlogs_raw = explode(PHP_EOL, $process->getOutput()); + $gitlogs = array(); + + foreach ($gitlogs_raw as $gl) { + list($rev, $ts) = explode(";", $gl); + $gitlogs[] = array("rev" => $rev, "date" => $ts); + } + + $revlist = array(); + + foreach ($gitlogs as $gitlog) { + echo $sep; + $revlist[] = $gitlog['rev']; + + if ($vars['rev'] == $gitlog['rev']) { + echo ''; + } + + $linktext = 'r'.$gitlog['rev'].' '.date(Config::get('dateformat')['byminute'], $gitlog['date']).''; + echo generate_link($linktext, array('page' => 'device', 'device' => $device['device_id'], 'tab' => 'showconfig', 'rev' => $gitlog['rev'])); + + if ($vars['rev'] == $gitlog['rev']) { + echo ''; + } + + $sep = ' | '; + } + } print_optionbar_end(); - if (function_exists('svn_log') && in_array($vars['rev'], $revlist)) { - list($diff, $errors) = svn_diff($file, ($vars['rev'] - 1), $file, $vars['rev']); - if (!$diff) { - $text = 'No Difference'; - } else { - $text = ''; - while (!feof($diff)) { - $text .= fread($diff, 8192); - } + if (Config::get('rancid_repo_type') == 'svn') { + if (function_exists('svn_log') && in_array($vars['rev'], $revlist)) { + list($diff, $errors) = svn_diff($file, ($vars['rev'] - 1), $file, $vars['rev']); + if (!$diff) { + $text = 'No Difference'; + } else { + $text = ''; + while (!feof($diff)) { + $text .= fread($diff, 8192); + } - fclose($diff); - fclose($errors); + fclose($diff); + fclose($errors); + } + } else { + $fh = fopen($file, 'r') or die("Can't open file"); + $text = fread($fh, filesize($file)); + fclose($fh); + } + } elseif (Config::get('rancid_repo_type') == 'git') { + if (in_array($vars['rev'], $revlist)) { + $process = new Process(array('git', 'diff', $vars['rev'] . '^', $vars['rev'], $file), $configs); + $process->run(); + $diff = $process->getOutput(); + if (!$diff) { + $text = 'No Difference'; + } else { + $text = $diff; + $previous_config = $vars['rev'] . '^'; + } + } else { + $fh = fopen($file, 'r') or die("Can't open file"); + $text = fread($fh, filesize($file)); + fclose($fh); } - } else { - $fh = fopen($file, 'r') or die("Can't open file"); - $text = fread($fh, filesize($file)); - fclose($fh); } - if ($config['rancid_ignorecomments']) { + if (Config::get('rancid_ignorecomments')) { $lines = explode("\n", $text); for ($i = 0; $i < count($lines); $i++) { if ($lines[$i][0] == '#') { @@ -96,11 +149,11 @@ if (Auth::user()->hasGlobalAdmin()) { $text = join("\n", $lines); } - } elseif ($config['oxidized']['enabled'] === true && isset($config['oxidized']['url'])) { + } elseif (Config::get('oxidized')['enabled'] === true && isset(Config::get('oxidized')['url'])) { // Try with hostname as set in librenms first $oxidized_hostname = $device['hostname']; // fetch info about the node and then a list of versions for that node - $node_info = json_decode(file_get_contents($config['oxidized']['url'].'/node/show/'.$oxidized_hostname.'?format=json'), true); + $node_info = json_decode(file_get_contents(Config::get('oxidized')['url'].'/node/show/'.$oxidized_hostname.'?format=json'), true); // Try other hostname format if Oxidized request failed if (! $node_info) { @@ -108,18 +161,18 @@ if (Auth::user()->hasGlobalAdmin()) { if (strpos($oxidized_hostname, '.') !== false) { // Use short name $oxidized_hostname = strtok($device['hostname'], '.'); - } elseif ($config['mydomain']) { - $oxidized_hostname = $device['hostname'].'.'.$config['mydomain']; + } elseif (Config::get('mydomain')) { + $oxidized_hostname = $device['hostname'].'.'.Config::get('mydomain'); } // Try Oxidized again with new hostname, if it has changed if ($oxidized_hostname != $device['hostname']) { - $node_info = json_decode(file_get_contents($config['oxidized']['url'].'/node/show/'.$oxidized_hostname.'?format=json'), true); + $node_info = json_decode(file_get_contents(Config::get('oxidized')['url'].'/node/show/'.$oxidized_hostname.'?format=json'), true); } } - if ($config['oxidized']['features']['versioning'] === true) { // fetch a list of versions - $config_versions = json_decode(file_get_contents($config['oxidized']['url'].'/node/version?node_full='.(isset($node_info['full_name']) ? $node_info['full_name'] : $oxidized_hostname).'&format=json'), true); + if (Config::get('oxidized')['features']['versioning'] === true) { // fetch a list of versions + $config_versions = json_decode(file_get_contents(Config::get('oxidized')['url'].'/node/version?node_full='.(isset($node_info['full_name']) ? $node_info['full_name'] : $oxidized_hostname).'&format=json'), true); } $config_total = 1; @@ -157,7 +210,7 @@ if (Auth::user()->hasGlobalAdmin()) { } if (isset($previous_config)) { - $url = $config['oxidized']['url'].'/node/version/diffs?node='.$oxidized_hostname; + $url = Config::get('oxidized')['url'].'/node/version/diffs?node='.$oxidized_hostname; if (!empty($node_info['group'])) { $url .= '&group='.$node_info['group']; } @@ -166,10 +219,10 @@ if (Auth::user()->hasGlobalAdmin()) { $text = file_get_contents($url); // fetch diff } else { // fetch current_version - $text = file_get_contents($config['oxidized']['url'].'/node/version/view?node='.$oxidized_hostname.(!empty($node_info['group']) ? '&group='.$node_info['group'] : '').'&oid='.$current_config['oid'].'&date='.urlencode($current_config['date']).'&num='.$current_config['version'].'&format=text'); + $text = file_get_contents(Config::get('oxidized')['url'].'/node/version/view?node='.$oxidized_hostname.(!empty($node_info['group']) ? '&group='.$node_info['group'] : '').'&oid='.$current_config['oid'].'&date='.urlencode($current_config['date']).'&num='.$current_config['version'].'&format=text'); } } else { // just fetch the only version - $text = file_get_contents($config['oxidized']['url'].'/node/fetch/'.(!empty($node_info['group']) ? $node_info['group'].'/' : '').$oxidized_hostname); + $text = file_get_contents(Config::get('oxidized')['url'].'/node/fetch/'.(!empty($node_info['group']) ? $node_info['group'].'/' : '').$oxidized_hostname); } if (is_array($node_info) || $config_total > 1) { diff --git a/includes/defaults.inc.php b/includes/defaults.inc.php index 6d1c62cfa4..b792c014f1 100644 --- a/includes/defaults.inc.php +++ b/includes/defaults.inc.php @@ -516,6 +516,7 @@ $config['billing']['base'] = 1000; // Set the base to divider bytes to kB, MB, GB ,... (1000|1024) // External Integration // $config['rancid_configs'][] = '/var/lib/rancid/network/configs/'; +$config['rancid_repo_type'] = 'svn'; $config['rancid_ignorecomments'] = 0; // Ignore lines starting with # // $config['collectd_dir'] = '/var/lib/collectd/rrd';