1 | <?php |
||
2 | |||
3 | // FIXME svn stuff still using optc etc, won't work, needs updating! |
||
4 | use LibreNMS\Config; |
||
0 ignored issues
–
show
|
|||
5 | use Symfony\Component\Process\Process; |
||
6 | |||
7 | if (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 |
Let?s assume that you have a directory layout like this:
and let?s assume the following content of
Bar.php
:If both files
OtherDir/Foo.php
andSomeDir/Foo.php
are loaded in the same runtime, you will see a PHP error such as the following:PHP Fatal error: Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php
However, as
OtherDir/Foo.php
does not necessarily have to be loaded and the error is only triggered if it is loaded beforeOtherDir/Bar.php
, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias: