1<?php 2 3// FIXME svn stuff still using optc etc, won't work, needs updating! 4use LibreNMS\Config; 5use Symfony\Component\Process\Process; 6 7if (Auth::user()->hasGlobalAdmin()) { 8 if (! empty($rancid_file)) { 9 echo '<div style="clear: both;">'; 10 11 print_optionbar_start('', ''); 12 13 echo "<span style='font-weight: bold;'>Config</span> » "; 14 15 if (! $vars['rev']) { 16 echo '<span class="pagemenu-selected">'; 17 echo generate_link('Latest', ['page' => 'device', 'device' => $device['device_id'], 'tab' => 'showconfig']); 18 echo '</span>'; 19 } else { 20 echo generate_link('Latest', ['page' => 'device', 'device' => $device['device_id'], 'tab' => 'showconfig']); 21 } 22 23 if (Config::get('rancid_repo_type') == 'svn' && function_exists('svn_log')) { 24 $sep = ' | '; 25 $svnlogs = svn_log($rancid_file, SVN_REVISION_HEAD, null, 8); 26 $revlist = []; 27 28 foreach ($svnlogs as $svnlog) { 29 echo $sep; 30 $revlist[] = $svnlog['rev']; 31 32 if ($vars['rev'] == $svnlog['rev']) { 33 echo '<span class="pagemenu-selected">'; 34 } 35 36 $linktext = 'r' . $svnlog['rev'] . ' <small>' . date(Config::get('dateformat.byminute'), strtotime($svnlog['date'])) . '</small>'; 37 echo generate_link($linktext, ['page' => 'device', 'device' => $device['device_id'], 'tab' => 'showconfig', 'rev' => $svnlog['rev']]); 38 39 if ($vars['rev'] == $svnlog['rev']) { 40 echo '</span>'; 41 } 42 43 $sep = ' | '; 44 } 45 }//end if 46 if (Config::get('rancid_repo_type') == 'git') { 47 $sep = ' | '; 48 49 $process = new Process(['git', 'log', '-n 8', '--pretty=format:%h;%ct', $rancid_file], $rancid_path); 50 $process->run(); 51 $gitlogs_raw = explode(PHP_EOL, $process->getOutput()); 52 $gitlogs = []; 53 54 foreach ($gitlogs_raw as $gl) { 55 [$rev, $ts] = explode(';', $gl); 56 $gitlogs[] = ['rev' => $rev, 'date' => $ts]; 57 } 58 59 $revlist = []; 60 61 foreach ($gitlogs as $gitlog) { 62 echo $sep; 63 $revlist[] = $gitlog['rev']; 64 65 if ($vars['rev'] == $gitlog['rev']) { 66 echo '<span class="pagemenu-selected">'; 67 } 68 69 $linktext = 'r' . $gitlog['rev'] . ' <small>' . date(Config::get('dateformat.byminute'), $gitlog['date']) . '</small>'; 70 echo generate_link($linktext, ['page' => 'device', 'device' => $device['device_id'], 'tab' => 'showconfig', 'rev' => $gitlog['rev']]); 71 72 if ($vars['rev'] == $gitlog['rev']) { 73 echo '</span>'; 74 } 75 76 $sep = ' | '; 77 } 78 } 79 80 print_optionbar_end(); 81 82 if (Config::get('rancid_repo_type') == 'svn') { 83 if (function_exists('svn_log') && in_array($vars['rev'], $revlist)) { 84 [$diff, $errors] = svn_diff($rancid_file, ($vars['rev'] - 1), $rancid_file, $vars['rev']); 85 if (! $diff) { 86 $text = 'No Difference'; 87 } else { 88 $text = ''; 89 while (! feof($diff)) { 90 $text .= fread($diff, 8192); 91 } 92 93 fclose($diff); 94 fclose($errors); 95 } 96 } else { 97 $fh = fopen($rancid_file, 'r') or exit("Can't open file"); 98 $text = fread($fh, filesize($rancid_file)); 99 fclose($fh); 100 } 101 } elseif (Config::get('rancid_repo_type') == 'git') { 102 if (in_array($vars['rev'], $revlist)) { 103 $process = new Process(['git', 'diff', $vars['rev'] . '^', $vars['rev'], $rancid_file], $rancid_path); 104 $process->run(); 105 $diff = $process->getOutput(); 106 if (! $diff) { 107 $text = 'No Difference'; 108 } else { 109 $text = $diff; 110 $previous_config = $vars['rev'] . '^'; 111 } 112 } else { 113 $fh = fopen($rancid_file, 'r') or exit("Can't open file"); 114 $text = fread($fh, filesize($rancid_file)); 115 fclose($fh); 116 } 117 } 118 119 if (Config::get('rancid_ignorecomments')) { 120 $lines = explode("\n", $text); 121 for ($i = 0; $i < count($lines); $i++) { 122 if ($lines[$i][0] == '#') { 123 unset($lines[$i]); 124 } 125 } 126 127 $text = join("\n", $lines); 128 } 129 } elseif (Config::get('oxidized.enabled') === true && Config::has('oxidized.url')) { 130 // Try with hostname as set in librenms first 131 $oxidized_hostname = $device['hostname']; 132 // fetch info about the node and then a list of versions for that node 133 $node_info = json_decode(file_get_contents(Config::get('oxidized.url') . '/node/show/' . $oxidized_hostname . '?format=json'), true); 134 135 if (! empty($node_info['last']['start'])) { 136 $node_info['last']['start'] = date(Config::get('dateformat.long'), strtotime($node_info['last']['start'])); 137 } 138 if (! empty($node_info['last']['end'])) { 139 $node_info['last']['end'] = date(Config::get('dateformat.long'), strtotime($node_info['last']['end'])); 140 } 141 // Try other hostname format if Oxidized request failed 142 if (! $node_info) { 143 // Adjust hostname based on whether domain was already in it or not 144 if (strpos($oxidized_hostname, '.') !== false) { 145 // Use short name 146 $oxidized_hostname = strtok($device['hostname'], '.'); 147 } elseif (Config::get('mydomain')) { 148 $oxidized_hostname = $device['hostname'] . '.' . Config::get('mydomain'); 149 } 150 151 // Try Oxidized again with new hostname, if it has changed 152 if ($oxidized_hostname != $device['hostname']) { 153 $node_info = json_decode(file_get_contents(Config::get('oxidized.url') . '/node/show/' . $oxidized_hostname . '?format=json'), true); 154 } 155 } 156 157 if (Config::get('oxidized.features.versioning') === true) { // fetch a list of versions 158 $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); 159 } 160 161 $config_total = 1; 162 if (is_array($config_versions)) { 163 $config_total = count($config_versions); 164 } 165 166 if ($config_total > 1) { 167 // populate current_version 168 if (isset($_POST['config'])) { 169 [$oid,$date,$version] = explode('|', $_POST['config']); 170 $current_config = ['oid'=>$oid, 'date'=>$date, 'version'=>$version]; 171 } else { // no version selected 172 $current_config = ['oid' => $config_versions[0]['oid'], 'date' => $config_versions[0]['date'], 'version' => $config_total]; 173 } 174 175 // populate previous_version 176 if (isset($_POST['diff'])) { // diff requested 177 [$oid,$date,$version] = explode('|', $_POST['prevconfig']); 178 if (isset($oid) && $oid != $current_config['oid']) { 179 $previous_config = ['oid'=>$oid, 'date'=>$date, 'version'=>$version]; 180 } elseif ($current_config['version'] != 1) { // assume previous, unless current is first config 181 foreach ($config_versions as $key => $version) { 182 if ($version['oid'] == $current_config['oid']) { 183 $prev_key = $key + 1; 184 $previous_config['oid'] = $config_versions[$prev_key]['oid']; 185 $previous_config['date'] = $config_versions[$prev_key]['date']; 186 $previous_config['version'] = $config_total - $prev_key; 187 break; 188 } 189 } 190 } else { 191 print_error('No previous version, please select a different version.'); 192 } 193 } 194 195 if (isset($previous_config)) { 196 $url = Config::get('oxidized.url') . '/node/version/diffs?node=' . $oxidized_hostname; 197 if (! empty($node_info['group'])) { 198 $url .= '&group=' . $node_info['group']; 199 } 200 $url .= '&oid=' . $current_config['oid'] . '&date=' . urlencode($current_config['date']) . '&num=' . $current_config['version'] . '&oid2=' . $previous_config['oid'] . '&format=text'; 201 202 $text = file_get_contents($url); // fetch diff 203 } else { 204 // fetch current_version 205 $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'); 206 } 207 } else { // just fetch the only version 208 $text = file_get_contents(Config::get('oxidized.url') . '/node/fetch/' . (! empty($node_info['group']) ? $node_info['group'] . '/' : '') . $oxidized_hostname); 209 } 210 211 if (is_array($node_info) || $config_total > 1) { 212 echo '<br /> 213 <div class="row"> 214 '; 215 216 if (is_array($node_info)) { 217 echo ' 218 <div class="col-sm-4"> 219 <div class="panel panel-primary"> 220 <div class="panel-heading">Sync status: <strong>' . $node_info['last']['status'] . '</strong></div> 221 <ul class="list-group"> 222 <li class="list-group-item"><strong>Node:</strong> ' . $node_info['name'] . '</li> 223 <li class="list-group-item"><strong>IP:</strong> ' . $node_info['ip'] . '</li> 224 <li class="list-group-item"><strong>Model:</strong> ' . $node_info['model'] . '</li> 225 <li class="list-group-item" style="overflow:hidden"><strong>Last Sync:</strong> ' . $node_info['last']['end'] . ' <button class="btn btn-primary btn-xs" style="float: right;" name="queue-refresh" onclick=\'refresh_oxidized_node("' . $device['hostname'] . '")\'>Refresh</button></li> 226 </ul> 227 </div> 228 </div> 229 '; 230 } 231 232 if ($config_total > 1) { 233 echo ' 234 <div class="col-sm-8"> 235 <form class="form-horizontal" action="" method="post"> 236 ' . csrf_field() . ' 237 <div class="form-group"> 238 <label for="config" class="col-sm-2 control-label">Config version</label> 239 <div class="col-sm-6"> 240 <select id="config" name="config" class="form-control"> 241 '; 242 243 $i = $config_total; 244 foreach ($config_versions as $version) { 245 echo '<option value="' . $version['oid'] . '|' . $version['date'] . '|' . $config_total . '" '; 246 if ($current_config['oid'] == $version['oid']) { 247 $author = $version['author']['name']; 248 $msg = $version['message']; 249 if (isset($previous_config)) { 250 echo 'selected>+'; 251 } else { 252 echo 'selected>*'; 253 } 254 } elseif ($previous_config['oid'] == $version['oid']) { 255 echo '> -'; 256 } else { 257 echo '> '; 258 } 259 echo $i . ' :: ' . $version['date'] . '</option>'; 260 $i--; 261 } 262 263 echo ' 264 </select> 265 </div> 266 </div> 267 <div class="form-group"> 268 <div class="col-sm-offset-2 col-sm-6"> 269 <input type="hidden" name="prevconfig" value="'; 270 echo implode('|', $current_config); 271 echo '"> 272 <button type="submit" class="btn btn-primary btn-sm" name="show">Show version</button> 273 <button type="submit" class="btn btn-primary btn-sm" name="diff">Show diff</button> 274 </div> 275 </div> 276 </form> 277 </div> 278 '; 279 } 280 281 echo '</div>'; 282 } else { 283 echo '<br />'; 284 print_error("We couldn't retrieve the device information from Oxidized"); 285 $text = ''; 286 } 287 }//end if 288 289 if (! empty($author)) { 290 echo ' 291 <div class="panel panel-primary"> 292 <div class="panel-heading">Author: <strong>' . $author . '</strong></div>'; 293 if (! empty($msg)) { 294 echo ' 295 <ul class="list-group"> 296 <li class="list-group-item"><strong>Message:</strong> ' . $msg . '</li> 297 </ul>'; 298 } 299 echo ' 300 </div>'; 301 } 302 if (! empty($text)) { 303 $language = isset($previous_config) ? 'diff' : Config::getOsSetting($device['os'], 'config_highlighting', 'ios'); 304 $geshi = new GeSHi(htmlspecialchars_decode($text), $language); 305 $geshi->enable_line_numbers(GESHI_FANCY_LINE_NUMBERS); 306 $geshi->set_overall_style('color: black;'); 307 // $geshi->set_line_style('color: #999999'); 308 echo '<div class="config">'; 309 echo '<input id="linenumbers" class="btn btn-primary" type="submit" value="Hide line numbers"/>'; 310 echo $geshi->parse_code(); 311 echo '</div>'; 312 } 313}//end if 314 315$pagetitle[] = 'Config'; 316