r1835 + fix IPv4 address search for the only result found
[racktables] / inc / interface.php
CommitLineData
b325120a 1<?php
e673ee24
DO
2/*
3*
4* This file contains frontend functions for RackTables.
5*
6*/
7
9c0b0016
DO
8// Interface function's special.
9$nextorder['odd'] = 'even';
10$nextorder['even'] = 'odd';
11
e673ee24
DO
12// Main menu.
13function renderIndex ()
14{
15 global $root;
16?>
17<table border=0 cellpadding=0 cellspacing=0 width='100%'>
18 <tr>
19 <td>
20 <div style='text-align: center; margin: 10px; '>
21 <table width='100%' cellspacing=0 cellpadding=30 class=mainmenu border=0>
22 <tr>
23 <td>
b325120a
DO
24 <h1><a href='<?php echo $root; ?>?page=rackspace'>Rackspace<br>
25 <?php printImageHREF ('rackspace'); ?></a></h1>
e673ee24
DO
26 </td>
27 <td>
b325120a
DO
28 <h1><a href='<?php echo $root; ?>?page=objects'>Objects<br>
29 <?php printImageHREF ('objects'); ?></a></h1>
e673ee24
DO
30 </td>
31 <td>
b325120a
DO
32 <h1><a href='<?php echo $root; ?>?page=ipv4space'>IPv4 space<br>
33 <?php printImageHREF ('ipv4space'); ?></a></h1>
e673ee24
DO
34 </td>
35 </tr>
36 </table>
37 <table width='100%' cellspacing=0 cellpadding=30 class=mainmenu border=0>
38 <tr>
39 <td>
b325120a
DO
40 <h1><a href='<?php echo $root; ?>?page=config'>Configuration<br>
41 <?php printImageHREF ('config'); ?></a></h1>
e673ee24
DO
42 </td>
43 <td>
da95280e 44 <h1><a href='<?php echo $root; ?>?page=reports'>Reports<br>
b325120a 45 <?php printImageHREF ('reports'); ?></a></h1>
e673ee24 46 </td>
ae545907 47 <td>
f973f491
DO
48 <h1><a href='<?php echo $root; ?>?page=ipv4slb'>IPv4 SLB<br>
49 <?php printImageHREF ('ipv4slb'); ?></a></h1>
ae545907 50 </td>
e673ee24
DO
51 </tr>
52 </table>
53 </div>
54 </td>
55 </tr>
56</table>
b325120a 57<?php
e673ee24
DO
58}
59
60function renderRackspace ()
61{
62?>
63 <table border=0 cellpadding=10 cellpadding=1>
b325120a 64<?php
e673ee24
DO
65 // generate thumb gallery
66 $rackrowList = getRackRowInfo();
9c0b0016
DO
67 global $root, $nextorder;
68 $rackwidth = getConfigVar ('rtwidth_0') + getConfigVar ('rtwidth_1') + getConfigVar ('rtwidth_2');
e673ee24
DO
69 $order = 'odd';
70 foreach ($rackrowList as $rackrow)
71 {
72 echo "<tr class=row_${order}><th><a href='${root}?page=row&row_id=${rackrow['dict_key']}'>${rackrow['dict_value']}</a></th>";
73 $rackList = getRacksForRow ($rackrow['dict_key']);
74 echo "<td><table border=0 cellspacing=5><tr>";
75 foreach ($rackList as $dummy => $rack)
76 {
77 echo "<td align=center><a href='${root}?page=rack&rack_id=${rack['id']}'>";
78 echo "<img border=0 width=${rackwidth} height=";
79 echo 3 + 3 + $rack['height'] * 2;
80 echo " title='${rack['height']} units'";
d2ec5490 81 echo "src='render_image.php?img=minirack&rack_id=${rack['id']}'>";
e673ee24
DO
82 echo "<br>${rack['name']}</a></td>";
83 }
84 echo "</tr></table></tr>\n";
85 $order = $nextorder[$order];
86 }
87 echo "</table>\n";
88}
89
90function renderRow ($row_id)
91{
92 if ($row_id == 0)
93 {
39a6338a 94 showError ('Invalid row_id', __FUNCTION__);
e673ee24
DO
95 return;
96 }
97 if (($rowInfo = getRackRowInfo ($row_id)) == NULL)
98 {
39a6338a 99 showError ('getRackRowInfo() failed', __FUNCTION__);
e673ee24
DO
100 return;
101 }
114e50af 102 $rackList = getRacksForRow ($row_id);
e673ee24
DO
103 // Main layout starts.
104 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
105
106 // Left portlet with row information.
107 echo "<tr><td class=pcleft>";
51a2330f 108 startPortlet ($rowInfo['dict_value']);
e673ee24 109 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
e673ee24
DO
110 echo "<tr><th width='50%' class=tdright>Racks:</th><td class=tdleft>${rowInfo['count']}</td></tr>\n";
111 echo "<tr><th width='50%' class=tdright>Units:</th><td class=tdleft>${rowInfo['sum']}</td></tr>\n";
114e50af
DO
112 echo "<tr><th width='50%' class=tdright>Utilization:</th><td class=tdleft>";
113 renderProgressBar (getRSUforRackRow ($rackList));
114 echo "</td></tr>\n";
e673ee24
DO
115 echo "</table><br>\n";
116 finishPortlet();
117
118 echo "</td><td class=pcright>";
119
9c0b0016
DO
120 global $root, $nextorder;
121 $rackwidth = getConfigVar ('rtwidth_0') + getConfigVar ('rtwidth_1') + getConfigVar ('rtwidth_2');
e673ee24
DO
122 $order = 'odd';
123 startPortlet ('Racks');
124 echo "<table border=0 cellspacing=5 align='center'><tr>";
125 foreach ($rackList as $dummy => $rack)
126 {
127 echo "<td align=center class=row_${order}><a href='${root}?page=rack&rack_id=${rack['id']}'>";
9c0b0016
DO
128 echo "<img border=0 width=" . $rackwidth * getConfigVar ('ROW_SCALE') . " height=";
129 echo (3 + 3 + $rack['height'] * 2) * getConfigVar ('ROW_SCALE');
e673ee24 130 echo " title='${rack['height']} units'";
d2ec5490 131 echo "src='render_image.php?img=minirack&rack_id=${rack['id']}'>";
e673ee24
DO
132 echo "<br>${rack['name']}</a></td>";
133 $order = $nextorder[$order];
134 }
135 echo "</tr></table>\n";
136 finishPortlet();
137
138 echo "</td></tr></table>";
139}
140
39a6338a 141function showError ($info = '', $funcname = 'N/A')
e673ee24
DO
142{
143 global $root;
b1cae282 144 echo "<div class=msg_error>An error has occured in function [${funcname}]. ";
e673ee24
DO
145 if (empty ($info))
146 echo 'No additional information is available.';
147 else
148 echo "Additional information:<br><p>\n<pre>\n${info}\n</pre></p>";
149 echo "Go back or try starting from <a href='${root}'>index page</a>.<br></div>\n";
150}
151
152// This function renders rack as HTML table.
153function renderRack ($rack_id = 0, $hl_obj_id = 0)
154{
155 if ($rack_id == 0)
156 {
39a6338a 157 showError ('Invalid rack_id', __FUNCTION__);
e673ee24
DO
158 return;
159 }
160 if (($rackData = getRackData ($rack_id)) == NULL)
161 {
39a6338a 162 showError ('getRackData() failed', __FUNCTION__);
e673ee24
DO
163 return;
164 }
165 global $root, $pageno, $tabno;
166 markAllSpans ($rackData);
167 if ($hl_obj_id > 0)
168 highlightObject ($rackData, $hl_obj_id);
169 markupObjectProblems ($rackData);
170 $prev_id = getPrevIDforRack ($rackData['row_id'], $rack_id);
171 $next_id = getNextIDforRack ($rackData['row_id'], $rack_id);
172 echo "<center>\n<h2><a href='${root}?page=row&row_id=${rackData['row_id']}'>${rackData['row_name']}</a> :";
173 // FIXME: use 'bypass'?
174 if ($prev_id != NULL)
175 echo " <a href='${root}?page=rack&rack_id=${prev_id}'>&lt; &lt; &lt;</a>";
176 echo " <a href='${root}?page=rack&rack_id=${rackData['id']}'>${rackData['name']}</a>";
177 if ($next_id != NULL)
178 echo " <a href='${root}?page=rack&rack_id=${next_id}'>&gt; &gt; &gt;</a>";
179 echo "</h2>\n";
1c81a02c
DO
180 if ($rackData['left_is_front'] == 'yes')
181 $markup = array ('left' => 'Front', 'right' => 'Back');
182 else
183 $markup = array ('left' => 'Back', 'right' => 'Front');
e673ee24 184 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
9ddfe309
DO
185 echo "<tr><th width='10%'>&nbsp;</th><th width='20%'>${markup['left']}</th>";
186 echo "<th width='50%'>Interior</th><th width='20%'>${markup['right']}</th></tr>\n";
e673ee24
DO
187 for ($i = $rackData['height']; $i > 0; $i--)
188 {
9ddfe309 189 echo '<tr><th>' . ($rackData['bottom_is_unit1'] == 'yes' ? $i : $rackData['height'] - $i + 1) . '</th>';
e673ee24
DO
190 for ($locidx = 0; $locidx < 3; $locidx++)
191 {
192 if (isset ($rackData[$i][$locidx]['skipped']))
193 continue;
194 $state = $rackData[$i][$locidx]['state'];
195 echo "<td class=state_${state}";
196 if (isset ($rackData[$i][$locidx]['hl']))
197 echo $rackData[$i][$locidx]['hl'];
198 if (isset ($rackData[$i][$locidx]['colspan']))
199 echo ' colspan=' . $rackData[$i][$locidx]['colspan'];
200 if (isset ($rackData[$i][$locidx]['rowspan']))
201 echo ' rowspan=' . $rackData[$i][$locidx]['rowspan'];
202 echo ">";
203 switch ($state)
204 {
205 case 'T':
206 $objectData = getObjectInfo ($rackData[$i][$locidx]['object_id']);
207 if (!empty ($objectData['asset_no']))
208 $prefix = "<div title='${objectData['asset_no']}";
209 else
210 $prefix = "<div title='no asset tag";
211 // Don't tell about label, if it matches common name.
212 if ($objectData['name'] != $objectData['label'] and !empty ($objectData['label']))
213 $suffix = ", visible label is \"${objectData['label']}\"'>";
214 else
215 $suffix = "'>";
216 echo $prefix . $suffix;
217 echo "<a href='${root}?page=object&object_id=${objectData['id']}'>${objectData['dname']}</a></div>";
218 break;
219 case 'A':
220 echo '<div title="This rackspace does not exist">&nbsp;</div>';
221 break;
222 case 'F':
223 echo '<div title="Free rackspace">&nbsp;</div>';
224 break;
225 case 'U':
226 echo '<div title="Problematic rackspace, you CAN\'T mount here">&nbsp;</div>';
227 break;
228 default:
229 echo '<div title="No data">&nbsp;</div>';
230 break;
231 }
232 echo '</td>';
233 }
234 echo "</tr>\n";
235 }
236 echo "</table></center>\n";
237}
238
239function renderNewObjectForm ()
240{
241 global $pageno, $tabno;
242
243 // Look for current submit.
244 if (isset ($_REQUEST['got_data']))
245 {
246 $log = array();
247 assertUIntArg ('object_type_id');
248 assertStringArg ('object_name', TRUE);
249 assertStringArg ('object_label', TRUE);
250 assertStringArg ('object_barcode', TRUE);
251 assertStringArg ('object_asset_no', TRUE);
252 $type_id = $_REQUEST['object_type_id'];
253 $name = $_REQUEST['object_name'];
254 $label = $_REQUEST['object_label'];
255 $asset_no = $_REQUEST['object_asset_no'];
256 $barcode = $_REQUEST['object_barcode'];
257
258 if (commitAddObject ($name, $label, $barcode, $type_id, $asset_no) === TRUE)
259 $log[] = array ('code' => 'success', 'message' => "Added new object '${name}'");
260 else
4d2e93f2 261 $log[] = array ('code' => 'error', 'message' => __FUNCTION__ . ': commitAddObject() failed');
e673ee24
DO
262 printLog ($log);
263 }
264
265 // Render a form for the next.
266 startPortlet ('Object attributes');
267 echo '<form>';
268 echo "<input type=hidden name=page value=${pageno}>";
269 echo "<input type=hidden name=tab value=${tabno}>";
270 echo '<table border=0 align=center>';
271 echo "<tr><th class=tdright>Type:</th><td class=tdleft>";
a477e405
DO
272 $typelist = getObjectTypeList();
273 $typelist[0] = 'select type...';
274 printSelect ($typelist, 'object_type_id', getConfigVar ('DEFAULT_OBJECT_TYPE'));
e673ee24
DO
275 echo "</td></tr>\n";
276 echo "<tr><th class=tdright>Common name:</th><td class=tdleft><input type=text name=object_name></td></tr>\n";
277 echo "<tr><th class=tdright>Visible label:</th><td class=tdleft><input type=text name=object_label></td></tr>\n";
278 echo "<tr><th class=tdright>Asset tag:</th><td class=tdleft><input type=text name=object_asset_no></td></tr>\n";
279 echo "<tr><th class=tdright>Barcode:</th><td class=tdleft><input type=text name=object_barcode></td></tr>\n";
280 echo "<tr><td class=submit colspan=2><input type=submit name=got_data value='Create'></td></tr>\n";
281 echo '</form></table>';
282 finishPortlet();
283}
284
285function renderNewRackForm ($row_id)
286{
287 global $pageno, $tabno;
288
289 // Look for current submit.
290 if (isset ($_REQUEST['got_data']))
291 {
292 $log = array();
293 assertStringArg ('rack_name');
294 assertUIntArg ('rack_height');
295 assertStringArg ('rack_comment', TRUE);
296 $name = $_REQUEST['rack_name'];
297 $height = $_REQUEST['rack_height'];
298 $comment = $_REQUEST['rack_comment'];
299
300 if (commitAddRack ($name, $height, $row_id, $comment) === TRUE)
301 $log[] = array ('code' => 'success', 'message' => "Added new rack '${name}'");
302 else
4d2e93f2 303 $log[] = array ('code' => 'error', 'message' => __FUNCTION__ . 'commitAddRack() failed');
e673ee24
DO
304 printLog ($log);
305 }
306
307 // Render a form for the next.
308 startPortlet ('Rack attributes');
309 echo '<form>';
310 echo "<input type=hidden name=page value=${pageno}>";
311 echo "<input type=hidden name=tab value=${tabno}>";
312 echo "<input type=hidden name=row_id value=${row_id}>";
313 echo '<table border=0 align=center>';
b901bf1f
DO
314 $defh = getConfigVar ('DEFAULT_RACK_HEIGHT');
315 if ($defh == 0)
316 $defh = '';
a7bc8321 317 echo "<tr><th class=tdright>Name (required):</th><td class=tdleft><input type=text name=rack_name tabindex=1></td></tr>\n";
b901bf1f 318 echo "<tr><th class=tdright>Height in units (required):</th><td class=tdleft><input type=text name=rack_height tabindex=2 value='${defh}'></td></tr>\n";
4134b5c0 319 echo "<tr><th class=tdright>Comment:</th><td class=tdleft><input type=text name=rack_comment tabindex=3></td></tr>\n";
e673ee24
DO
320 echo "<tr><td class=submit colspan=2><input type=submit name=got_data value='Create'></td></tr>\n";
321 echo '</form></table>';
322 finishPortlet();
323}
324
325function renderEditObjectForm ($object_id)
326{
327 showMessageOrError();
328 // Handle submit.
329 if (isset ($_REQUEST['got_data']))
330 {
331 $log = array();
332 // object_id is already verified by page handler
333 assertUIntArg ('object_type_id');
334 assertStringArg ('object_name', TRUE);
335 assertStringArg ('object_label', TRUE);
336 assertStringArg ('object_barcode', TRUE);
337 assertStringArg ('object_asset_no', TRUE);
338 $type_id = $_REQUEST['object_type_id'];
339 if (isset ($_REQUEST['object_has_problems']) and $_REQUEST['object_has_problems'] == 'on')
340 $has_problems = 'yes';
341 else
342 $has_problems = 'no';
343 $name = $_REQUEST['object_name'];
344 $label = $_REQUEST['object_label'];
345 $barcode = $_REQUEST['object_barcode'];
346 $asset_no = $_REQUEST['object_asset_no'];
347 $comment = $_REQUEST['object_comment'];
348
349 if (commitUpdateObject ($object_id, $name, $label, $barcode, $type_id, $has_problems, $asset_no, $comment) === TRUE)
350 $log[] = array ('code' => 'success', 'message' => "Updated object '${name}'");
351 else
4d2e93f2 352 $log[] = array ('code' => 'error', 'message' => __FUNCTION__ . ': commitUpdateObject() failed');
c7fe33be
DO
353 // Invalidate thumb cache of all racks objects could occupy.
354 foreach (getResidentRacksData ($object_id, FALSE) as $rack_id)
355 resetThumbCache ($rack_id);
e673ee24
DO
356 printLog ($log);
357 }
358
359 global $pageno, $tabno;
360 $object = getObjectInfo ($object_id);
361 if ($object == NULL)
362 {
39a6338a 363 showError ('getObjectInfo() failed', __FUNCTION__);
e673ee24
DO
364 return;
365 }
366
367 // Render a form for the next submit;
368 echo '<table border=0 width=100%><tr>';
369
370 echo '<td class=pcleft>';
371 startPortlet ('Static attributes');
250a40c5 372 echo '<form method=post>';
e673ee24
DO
373 echo "<input type=hidden name=page value=${pageno}>";
374 echo "<input type=hidden name=tab value=${tabno}>";
375 echo "<input type=hidden name=object_id value=${object_id}>";
376 echo '<table border=0 align=center>';
377 echo "<tr><th class=tdright>Type:</th><td class=tdleft>";
378 printSelect (getObjectTypeList(), 'object_type_id', $object['objtype_id']);
379 echo "</td></tr>\n";
380 // Common attributes.
381 echo "<tr><th class=tdright>Common name:</th><td class=tdleft><input type=text name=object_name value='${object['name']}'></td></tr>\n";
382 echo "<tr><th class=tdright>Visible label:</th><td class=tdleft><input type=text name=object_label value='${object['label']}'></td></tr>\n";
383 echo "<tr><th class=tdright>Asset tag:</th><td class=tdleft><input type=text name=object_asset_no value='${object['asset_no']}'></td></tr>\n";
384 echo "<tr><th class=tdright>Barcode:</th><td class=tdleft><input type=text name=object_barcode value='${object['barcode']}'></td></tr>\n";
385 echo "<tr><th class=tdright>Has problems:</th><td class=tdleft><input type=checkbox name=object_has_problems";
386 if ($object['has_problems'] == 'yes')
387 echo ' checked';
388 echo "></td></tr>\n";
389 echo "<tr><td colspan=2><b>Comment:</b><br><textarea name=object_comment rows=10 cols=80>${object['comment']}</textarea></td></tr>";
390 echo "<tr><th class=submit colspan=2><input type=submit name=got_data value='Update'></td></tr>\n";
391 echo '</form></table><br>';
392 finishPortlet();
393 echo '</td>';
394
395 // Optional attributes.
396 echo '<td class=pcright>';
397 startPortlet ('Optional attributes');
398 $values = getAttrValues ($object_id);
399 global $root;
400 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
401 echo "<tr><th>&nbsp;</th><th>Attribute</th><th>Value</th><th>&nbsp;</th></tr>\n";
0dfb8a2a
DO
402 echo "<form method=post action='${root}process.php'>\n";
403 echo "<input type=hidden name=page value=${pageno}>\n";
404 echo "<input type=hidden name=tab value=${tabno}>\n";
405 echo "<input type=hidden name=op value=upd>\n";
406 echo "<input type=hidden name=object_id value=${object_id}>\n";
407 echo '<input type=hidden name=num_attrs value=' . count($values) . ">\n";
408
409 $i = 0;
e673ee24
DO
410 foreach ($values as $record)
411 {
0dfb8a2a 412 echo "<input type=hidden name=${i}_attr_id value=${record['id']}>";
0c4605ab 413 echo '<tr><td>';
ca1fec24 414 if (!empty ($record['value']))
0c4605ab
DO
415 {
416 echo "<a href=${root}process.php?page=${pageno}&tab=${tabno}&op=del&object_id=${object_id}&attr_id=${record['id']}>";
417 printImageHREF ('delete', 'Delete value');
418 echo '</a>';
419 }
420 else
421 printImageHREF ('nodelete', 'Already empty');
422 echo '</td>';
e673ee24
DO
423 echo "<td class=tdright>${record['name']}:</td><td class=tdleft>";
424 switch ($record['type'])
425 {
426 case 'uint':
427 case 'float':
428 case 'string':
0dfb8a2a 429 echo "<input type=text name=${i}_value value='${record['value']}'>";
e673ee24
DO
430 break;
431 case 'dict':
432 $chapter = readChapter ($record['chapter_name']);
4c330a14 433 $chapter[0] = '-- NOT SET --';
0dfb8a2a 434 printSelect ($chapter, "${i}_value", $record['key']);
e673ee24
DO
435 break;
436 }
0dfb8a2a
DO
437 echo "</td></tr>\n";
438 $i++;
e673ee24 439 }
0dfb8a2a
DO
440 echo "<tr><td colspan=3><input type=submit value='Update'></td></tr>\n";
441 echo "</form>";
e673ee24
DO
442 echo "</table>\n";
443 finishPortlet();
444 echo '</td>';
445
446 echo '</tr><tr>';
447
448 echo '<td colspan=2>';
449 startPortlet ('history');
450 renderHistory ($pageno, $object_id);
451 finishPortlet();
452 echo '</td>';
453
454 echo '</tr></table>';
455}
456
457// This is a clone of renderEditObjectForm().
458function renderEditRackForm ($rack_id)
459{
460 // Handle submit.
461 if (isset ($_REQUEST['got_data']))
462 {
463 $log = array();
464 assertUIntArg ('rack_row_id');
465 assertUIntArg ('rack_height');
466 assertStringArg ('rack_name');
467 assertStringArg ('rack_comment', TRUE);
468 $row_id = $_REQUEST['rack_row_id'];
469 $height = $_REQUEST['rack_height'];
470 $name = $_REQUEST['rack_name'];
471 $comment = $_REQUEST['rack_comment'];
472
473 if (commitUpdateRack ($rack_id, $name, $height, $row_id, $comment) === TRUE)
474 $log[] = array ('code' => 'success', 'message' => "Updated rack '${name}'");
475 else
4d2e93f2 476 $log[] = array ('code' => 'error', 'message' => __FUNCTION__ . ': commitUpdateRack() failed');
c7fe33be 477 resetThumbCache ($rack_id);
e673ee24
DO
478 printLog ($log);
479 }
480
481 global $pageno, $tabno;
482 $rack = getRackData ($rack_id);
483 if ($rack == NULL)
484 {
39a6338a 485 showError ('getRackData() failed', __FUNCTION__);
e673ee24
DO
486 return;
487 }
488
489 // Render a form for the next.
490 startPortlet ('Rack attributes');
491 echo '<form>';
492 echo "<input type=hidden name=page value=${pageno}>";
493 echo "<input type=hidden name=tab value=${tabno}>";
494 echo "<input type=hidden name=rack_id value=${rack_id}>";
495 echo '<table border=0 align=center>';
496 echo "<tr><th class=tdright>Rack row:</th><td class=tdleft>";
4c330a14 497 printSelect (readChapter ('RackRow'), 'rack_row_id', $rack['row_id']);
e673ee24
DO
498 echo "</td></tr>\n";
499 echo "<tr><th class=tdright>Name (required):</th><td class=tdleft><input type=text name=rack_name value='${rack['name']}'></td></tr>\n";
500 echo "<tr><th class=tdright>Height (required):</th><td class=tdleft><input type=text name=rack_height value='${rack['height']}'></td></tr>\n";
501 echo "<tr><th class=tdright>Comment:</th><td class=tdleft><input type=text name=rack_comment value='${rack['comment']}'></td></tr>\n";
502 echo "<tr><td class=submit colspan=2><input type=submit name=got_data value='Update'></td></tr>\n";
503 echo '</form></table><br>';
504 finishPortlet();
505
506 startPortlet ('History');
507 renderHistory ($pageno, $rack_id);
508 finishPortlet();
509}
510
511// This is a helper for creators and editors.
512function printSelect ($rowList, $select_name, $selected_id = 1)
513{
9e7f32a7
DO
514 // First collect all data for OPTGROUPs, then ouput it and dump
515 // the rest of records as is.
516 $optgroup = array();
517 $other = array();
4c330a14 518 foreach ($rowList as $dict_key => $dict_value)
e673ee24 519 {
24cbe8af 520 if (strpos ($dict_value, '^') !== FALSE)
9e7f32a7 521 {
24cbe8af 522 $tmp = explode ('^', $dict_value, 2);
9e7f32a7
DO
523 $optgroup[$tmp[0]][$dict_key] = $tmp[1];
524 }
525 else
526 $other[$dict_key] = $dict_value;
527 }
528 echo "<select name=${select_name}>";
529 if (!count ($optgroup))
530 {
531 foreach ($other as $dict_key => $dict_value)
532 {
533 echo "<option value=${dict_key}";
534 if ($dict_key == $selected_id)
535 echo ' selected';
536 echo ">${dict_value}</option>";
537 }
538 }
539 else
540 {
541 foreach ($optgroup as $groupname => $groupdata)
542 {
543 echo "<optgroup label='${groupname}'>";
544 foreach ($groupdata as $dict_key => $dict_value)
545 {
546 echo "<option value=${dict_key}";
547 if ($dict_key == $selected_id)
548 echo ' selected';
549 echo ">${dict_value}</option>";
550 }
551 echo "</optgroup>\n";
552 }
553 if (count ($other))
554 {
555 echo "<optgroup label='other'>\n";
556 foreach ($other as $dict_key => $dict_value)
557 {
558 echo "<option value=${dict_key}";
559 if ($dict_key == $selected_id)
560 echo ' selected';
561 echo ">${dict_value}</option>";
562 }
563 echo "</optgroup>\n";
564 }
e673ee24
DO
565 }
566 echo "</select>";
567}
568
569// This is a universal editor of rack design/waste.
bb09cca0 570function renderGridForm ($rack_id = 0, $filter, $header, $submit, $state1, $state2)
e673ee24
DO
571{
572 if ($rack_id == 0)
573 {
591ff2c4 574 showError ('Invalid rack_id', __FUNCTION__);
e673ee24
DO
575 return;
576 }
577 if (($rackData = getRackData ($rack_id)) == NULL)
578 {
591ff2c4 579 showError ('getRackData() failed', __FUNCTION__);
e673ee24
DO
580 return;
581 }
582
583 global $root, $pageno, $tabno;
584 $filter($rackData);
585 markupObjectProblems ($rackData);
586
587 // Process form submit.
588 if (isset ($_REQUEST['do_update']))
589 {
590 $log[] = processGridForm ($rackData, $state1, $state2);
591 printLog($log);
592 }
593
594 // Render the result whatever it is.
595 // Main layout.
596 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
597 echo "<tr><td colspan=2 align=center><h1>${rackData['name']}</h1></td></tr>\n";
598
599 // Left column with information portlet.
600 echo "<tr><td class=pcleft height='1%' width='50%'>";
601 startPortlet ('Rack information');
602 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
603 echo "<tr><th width='50%' class=tdright>Rack name:</th><td class=tdleft>${rackData['name']}</td></tr>\n";
604 echo "<tr><th width='50%' class=tdright>Height:</th><td class=tdleft>${rackData['height']}</td></tr>\n";
605 echo "<tr><th width='50%' class=tdright>Rack row:</th><td class=tdleft>${rackData['row_name']}</td></tr>\n";
606 echo "<tr><th width='50%' class=tdright>Comment:</th><td class=tdleft>${rackData['comment']}</td></tr>\n";
607 echo "</table>\n";
608 finishPortlet();
609
610 echo "</td>\n";
bb09cca0 611 echo "<td class=pcright>";
e673ee24
DO
612
613 // Grid form.
614 startPortlet ($header);
615 echo "<center>\n";
616 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
617 echo "<tr><th width='10%'>&nbsp;</th><th width='20%'>Front</th>";
618 echo "<th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
9d479d56 619 echo "<form method=post action='${root}?'>\n";
e673ee24
DO
620 echo "<input type=hidden name=page value=${pageno}>\n";
621 echo "<input type=hidden name=tab value=${tabno}>\n";
622 echo "<input type=hidden name=rack_id value=${rack_id}>\n";
623 markupAtomGrid ($rackData, $state2);
624 renderAtomGrid ($rackData);
625 echo "</table></center>\n";
626 echo "<br><input type=submit name=do_update value='${submit}'></form><br><br>\n";
627 finishPortlet();
bb09cca0 628 echo "</td></tr></table>\n";
e673ee24
DO
629}
630
631function renderRackDesign ($rack_id)
632{
bb09cca0 633 renderGridForm ($rack_id, 'applyRackDesignMask', 'Rack design', 'Set rack design', 'A', 'F');
e673ee24
DO
634}
635
636function renderRackProblems ($rack_id = 0)
637{
bb09cca0 638 renderGridForm ($rack_id, 'applyRackProblemMask', 'Rack problems', 'Mark unusable atoms', 'F', 'U');
e673ee24
DO
639}
640
641function startPortlet ($title = '')
642{
643 echo "<div class=portlet><h2>${title}</h2>";
644}
645
646function finishPortlet ()
647{
648 echo "</div>\n";
649}
650
651function printRefsOfType ($refs, $type, $eq)
652{
653 global $root;
654 $gotone=0;
655 foreach ($refs as $ref)
656 {
657 if ($eq($ref['type'], $type))
658 {
659 if ($gotone) echo ', ';
4b2bf583
DO
660 echo "<a href='${root}?page=object&object_id=${ref['object_id']}'>";
661 if (!empty ($ref['name']))
662 echo $ref['name'] . '@';
663 echo "${ref['object_name']}</a>";
e673ee24
DO
664 $gotone=1;
665 }
666 }
667}
668
669function renderRackObject ($object_id = 0)
670{
41bd8c87 671 global $root;
e673ee24
DO
672 if ($object_id <= 0)
673 {
591ff2c4 674 showError ('Invalid object_id', __FUNCTION__);
e673ee24
DO
675 return;
676 }
677 $info = getObjectInfo ($object_id);
678 if ($info == NULL)
679 {
591ff2c4 680 showError ('getObjectInfo() failed', __FUNCTION__);
e673ee24
DO
681 return;
682 }
683 // Main layout starts.
684 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
685 echo "<tr><td colspan=2 align=center><h1>${info['dname']}</h1></td></tr>\n";
686 // left column with uknown number of portlets
687 echo "<tr><td class=pcleft>";
688 startPortlet ('Object information');
689 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
690 if (!empty ($info['name']))
691 echo "<tr><th width='50%' class=tdright>Common name:</th><td class=tdleft>${info['name']}</td></tr>\n";
9c0b0016 692 elseif (in_array ($info['objtype_id'], explode (',', getConfigVar ('NAMEFUL_OBJTYPES'))))
a0ec6295 693 echo "<tr><td colspan=2 class=msg_error>Common name is missing.</td></tr>\n";
e673ee24
DO
694 echo "<tr><th width='50%' class=tdright>Object type:</th><td class=tdleft>${info['objtype_name']}</td></tr>\n";
695 if (!empty ($info['asset_no']))
696 echo "<tr><th width='50%' class=tdright>Asset tag:</th><td class=tdleft>${info['asset_no']}</td></tr>\n";
a6305acc 697 elseif (in_array ($info['objtype_id'], explode (',', getConfigVar ('REQUIRE_ASSET_TAG_FOR'))))
a0ec6295 698 echo "<tr><td colspan=2 class=msg_error>Asset tag is missing.</td></tr>\n";
e673ee24
DO
699 if (!empty ($info['label']))
700 echo "<tr><th width='50%' class=tdright>Visible label:</th><td class=tdleft>${info['label']}</td></tr>\n";
701 if (!empty ($info['barcode']))
702 echo "<tr><th width='50%' class=tdright>Barcode:</th><td class=tdleft>${info['barcode']}</td></tr>\n";
703 if ($info['has_problems'] == 'yes')
704 echo "<tr><td colspan=2 class=msg_error>Has problems</td></tr>\n";
24cbe8af
DO
705 $attrs = getAttrValues ($object_id, TRUE);
706 foreach (getAttrValues ($object_id, TRUE) as $record)
e673ee24 707 if (!empty ($record['value']))
50a954f6 708 echo "<tr><th width='50%' class=opt_attr_th>${record['name']}:</th><td class=tdleft>${record['a_value']}</td></tr>\n";
41bd8c87 709 printTagTRs();
e673ee24
DO
710 echo "</table><br>\n";
711 finishPortlet();
712
713 if (!empty ($info['comment']))
714 {
715 startPortlet ('Comment');
6cc5d6cd 716 echo '<div class=commentblock>' . string_insert_hrefs ($info['comment']) . '</div>';
e673ee24
DO
717 finishPortlet ();
718 }
719
720 $ports = getObjectPortsAndLinks ($object_id);
721 if (count ($ports))
722 {
723 startPortlet ('Ports and links');
724 usort($ports, 'sortByName');
725 if ($ports)
726 {
727 $hl_port_id = 0;
728 if (isset ($_REQUEST['hl_port_id']))
729 {
730 assertUIntArg ('hl_port_id');
731 $hl_port_id = $_REQUEST['hl_port_id'];
732 }
733 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
734 echo "<tr><th>Local name</th><th>Visible label</th><th>Port type</th><th>L2 address</th>";
735 echo "<th>Rem. Object</th><th>Rem. port</th></tr>\n";
736 foreach ($ports as $port)
737 {
738 echo '<tr';
739 if ($hl_port_id == $port['id'])
740 echo ' class=port_highlight';
741 echo "><td>${port['name']}</td><td>${port['label']}</td><td>${port['type']}</td>";
742 echo "<td>${port['l2address']}</td>";
743 if ($port['remote_object_id'])
744 {
745 echo "<td><a href='${root}?page=object&object_id=${port['remote_object_id']}'>${port['remote_object_name']}</a></td>";
746 echo "<td>${port['remote_name']}</td>";
747 }
748 elseif (!empty ($port['reservation_comment']))
749 {
750 echo "<td><b>Reserved;</b></td>";
751 echo "<td>${port['reservation_comment']}</td>";
752 }
753 else
754 echo '<td>&nbsp;</td><td>&nbsp;</td>';
755 echo "</tr>\n";
756 }
757 echo "</table><br>\n";
758 }
759 finishPortlet();
760 }
761 $addresses = getObjectAddresses ($object_id);
762 usort($addresses, 'sortAddresses');
763 if (count ($addresses))
764 {
f28fbe8b 765 startPortlet ('IPv4 addresses');
e673ee24
DO
766 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
767 echo "<tr><th>Interface name</th><th>IP Address</th><th>Description</th><th>Misc</th></tr>\n";
768 foreach ($addresses as $addr)
769 {
770 if (strlen($addr['address_name'])>40)
771 $address_name = substr($addr['address_name'],0,38).'...';
772 else
773 $address_name = $addr['address_name'];
774
775 $virtnum = countRefsOfType($addr['references'], 'virtual', 'eq');
776 $sharednum = countRefsOfType($addr['references'], 'shared', 'eq');
777 $regnum = countRefsOfType($addr['references'], 'regular', 'eq');
778 $notvirtnum = countRefsOfType($addr['references'], 'virtual', 'neq');
779
780 if ($addr['address_reserved']=='yes')
24e85a1a 781 $class='trerror';
e673ee24 782 elseif ($addr['type']!='virtual' && $regnum>0)
24e85a1a 783 $class='trerror';
e673ee24 784 elseif ($addr['type']=='regular' && $sharednum>0)
24e85a1a 785 $class='trerror';
e673ee24
DO
786 else
787 $class='';
788
cf50bfff 789 echo "<tr class='$class'><td class=tdleft>${addr['name']}</td><td class=tdleft><a href='${root}?page=ipaddress&ip=${addr['ip']}'>${addr['ip']}</a></td><td class='description'>$address_name</td><td class=tdleft>\n";
e673ee24
DO
790
791 if ($addr['address_reserved']=='yes')
792 echo "<b>Reserved;</b> ";
793
794 if ($addr['type'] == 'virtual')
795 {
796 echo "<b>V</b>";
797 if ($notvirtnum > 0)
798 {
799 echo " Owners: ";
800 printRefsOfType($addr['references'], 'virtual', 'neq');
801 }
802 }
803 elseif ($addr['type'] == 'shared')
804 {
805 echo "<b>S</b>";
806 if ($sharednum > 0)
807 {
808 echo " Peers: ";
809 printRefsOfType($addr['references'], 'shared', 'eq');
810 echo ";";
811 }
812 if ($virtnum > 0)
813 {
814 echo " Virtuals: ";
815 printRefsOfType($addr['references'], 'virtual', 'eq');
816 echo ";";
817 }
818 if ($regnum > 0)
819 {
820 echo " Collisions: ";
821 printRefsOfType($addr['references'], 'regular', 'eq');
822 }
823
824 }
825 else
826 {
827 if ($virtnum > 0)
828 {
829 echo " Virtuals: ";
830 printRefsOfType($addr['references'], 'virtual', 'eq');
831 echo ";";
832 }
833 if ($notvirtnum > 0)
834 {
835 echo " Collisions: ";
836 printRefsOfType($addr['references'], 'virtual', 'neq');
837 }
838 }
839
840 echo "</td></tr>\n";
841 }
842 echo "</table><br>\n";
843 finishPortlet();
844 }
845
846 $forwards = getObjectForwards ($object_id);
847 if (count($forwards['in']) or count($forwards['out']))
848 {
f28fbe8b 849 startPortlet('NATv4');
e673ee24
DO
850
851 if (count($forwards['out']))
852 {
853
f28fbe8b 854 echo "<h3>locally performed NAT</h3>";
e673ee24
DO
855
856 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
f28fbe8b 857 echo "<tr><th>Proto</th><th>Match endpoint</th><th>Translate to</th><th>Target object</th><th>Rule comment</th></tr>\n";
e673ee24
DO
858
859 foreach ($forwards['out'] as $pf)
860 {
24e85a1a 861 $class='trerrorg';
e673ee24
DO
862 $name='';
863 foreach ($addresses as $addr)
864 if ($addr['ip'] == $pf['localip'])
865 {
866 $class='';
867 $name=$addr['name'];
868 break;
869 }
870
871 echo "<tr class='$class'>";
872
f28fbe8b 873 echo "<td>${pf['proto']}</td><td class=tdleft>${name}: <a href='${root}?page=ipaddress&tab=default&ip=${pf['localip']}'>${pf['localip']}</a>:${pf['localport']}</td>";
e673ee24 874
f28fbe8b 875 echo "<td class=tdleft><a href='${root}?page=ipaddress&tab=default&ip=${pf['remoteip']}'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
e673ee24
DO
876
877 $address=getIPAddress($pf['remoteip']);
878
879 echo "<td class='description'>";
f28fbe8b
DO
880 if (count ($address['bonds']))
881 foreach($address['bonds'] as $bond)
882 echo "<a href='${root}?page=object&tab=default&object_id=${bond['object_id']}'>${bond['object_name']}(${bond['name']})</a> ";
883 elseif (!empty ($pf['remote_addr_name']))
884 echo '(' . $pf['remote_addr_name'] . ')';
e673ee24
DO
885
886 echo "</td><td class='description'>${pf['description']}</td>";
887
888 echo "</tr>";
889 }
890 echo "</table><br><br>";
891 }
892 if (count($forwards['in']))
893 {
f28fbe8b 894 echo "<h3>arriving NAT connections</h3>";
e673ee24
DO
895
896 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
f28fbe8b 897 echo "<tr><th>Matched endpoint</th><th>Source object</th><th>Translated to</th><th>Rule comment</th></tr>\n";
e673ee24
DO
898
899 foreach ($forwards['in'] as $pf)
900 {
901 echo "<tr>";
902 echo "<td>${pf['proto']}/<a href='${root}?page=ipaddress&tab=default&ip=${pf['localip']}'>${pf['localip']}</a>:${pf['localport']}</td>";
903
904 echo "<td class='description'><a href='${root}?page=object&tab=default&object_id=${pf['object_id']}'>${pf['object_name']}</a>";
905
906 echo "</td><td><a href='${root}?page=ipaddress&tab=default&ip=${pf['remoteip']}'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
907 echo "<td class='description'>${pf['description']}</td></tr>";
908 }
909
910 echo "</table><br><br>";
911 }
912 finishPortlet();
913 }
914
78e7b769
DO
915 $pools = getRSPoolsForObject ($object_id);
916 if (count ($pools))
917 {
918 startPortlet ('Real server pools');
919 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
732e4578 920 echo "<tr><th>VS</th><th>RS pool</th><th>RS</th><th>VS config</th><th>RS config</th></tr>\n";
748805bf 921 foreach ($pools as $vs_id => $info)
78e7b769 922 {
732e4578 923 echo "<tr valign=top><td class=tdleft><a href='${root}?page=vservice&id=${vs_id}'>";
748805bf
DO
924 echo buildVServiceName ($info);
925 echo '</a>';
926 if (!empty ($info['name']))
927 echo " (${info['name']})";
c0ae6968 928 echo "</td><td class=tdleft><a href='${root}?page=rspool&pool_id=${info['pool_id']}'>";
748805bf 929 echo (empty ($info['pool_name']) ? 'ANONYMOUS' : $info['pool_name']);
732e4578
DO
930 echo '</a></td><td class=tdleft>' . $info['rscount'] . '</td>';
931 echo "<td class=tdleft><pre>${info['vsconfig']}</pre></td>";
932 echo "<td class=tdleft><pre>${info['rsconfig']}</pre></td>";
78e7b769
DO
933 echo "</tr>\n";
934 }
935 echo "</table>\n";
936 finishPortlet();
937 }
e673ee24
DO
938 echo "</td>\n";
939
940 // After left column we have (surprise!) right column with rackspace portled only.
941 echo "<td class=pcright>";
942 // rackspace portlet
943 startPortlet ('Rackspace allocation');
944 // FIXME: now we call getRackData() twice
945 $racks = getResidentRacksData ($object_id);
946 foreach ($racks as $rackData)
947 renderRack ($rackData['id'], $object_id);
948 echo '<br>';
949 finishPortlet();
950 echo "</td></tr>";
951 echo "</table>\n";
952}
953
954function renderRackMultiSelect ($sname, $racks, $selected)
955{
9c0b0016 956 echo "<select name=${sname} multiple size=" . getConfigVar ('MAXSELSIZE') . " onchange='getElementById(\"racks\").submit()'>\n";
e673ee24
DO
957 foreach ($racks as $rack)
958 {
959 echo "<option value=${rack['id']}";
960 if (!(array_search ($rack['id'], $selected) === FALSE))
961 echo ' selected';
6a3a37b2 962 echo">${rack['row_name']}: ${rack['name']}</option>\n";
e673ee24
DO
963 }
964 echo "</select>\n";
965}
966
967function showMessageOrError ()
968{
969 if (isset($_REQUEST['message']))
970 echo "<div class=msg_success>${_REQUEST['message']}</div>";
971 if (isset($_REQUEST['error']))
972 echo "<div class=msg_error>${_REQUEST['error']}</div>";
973}
974
975// This function renders a form for port edition.
976function renderPortsForObject ($object_id = 0)
977{
978 global $root, $pageno, $tabno;
979 if ($object_id <= 0)
980 {
591ff2c4 981 showError ('Invalid object_id', __FUNCTION__);
e673ee24
DO
982 return;
983 }
984 showMessageOrError();
985 startPortlet ('Ports and interfaces');
986 $ports = getObjectPortsAndLinks ($object_id);
987 usort($ports, 'sortByName');
988 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
989 echo "<tr><th>&nbsp;</th><th>Local name</th><th>Visible label</th><th>Port type</th><th>L2 address</th>";
990 echo "<th>Rem. object</th><th>Rem. port</th><th>(Un)link or (un)reserve</th><th>&nbsp;</th></tr>\n";
991 foreach ($ports as $port)
992 {
993 echo "<form action='${root}process.php'>";
994 echo "<input type=hidden name=op value=editPort>";
995 echo "<input type=hidden name=page value='${pageno}'>\n";
996 echo "<input type=hidden name=tab value='${tabno}'>\n";
997 echo "<input type=hidden name=port_id value='${port['id']}'>";
998 echo "<input type=hidden name=object_id value='$object_id'>\n";
999 echo "<tr><td><a href='${root}process.php?op=delPort&page=${pageno}&tab=${tabno}&port_id=${port['id']}&object_id=$object_id&port_name=${port['name']}'>";
1000 printImageHREF ('delete', 'Unlink and Delete this port');
1001 echo "</a></td>\n";
1002 echo "<td><input type=text name=name value='${port['name']}' size=8></td>";
1003 echo "<td><input type=text name=label value='${port['label']}' size=24></td>";
1004 echo "<td>${port['type']}</td>\n";
1005 echo "<td><input type=text name=l2address value='${port['l2address']}'></td>\n";
1006 if ($port['remote_object_id'])
1007 {
1008 echo "<td><a href='${root}?page=object&object_id=${port['remote_object_id']}'>${port['remote_object_name']}</a></td>";
1009 echo "<td>${port['remote_name']}</td>";
1010 echo "<td><a href='${root}process.php?op=unlinkPort&page=${pageno}&tab=${tabno}&port_id=${port['id']}&object_id=$object_id&port_name=";
1011 echo urlencode ($port['name']);
1012 echo "&remote_port_name=${port['remote_name']}&remote_object_name=${port['remote_object_name']}'>";
1013 printImageHREF ('unlink', 'Unlink this port');
1014 echo "</a></td>";
1015 }
1016 elseif (!empty ($port['reservation_comment']))
1017 {
1018 echo "<td><b>Reserved;</b></td>";
1019 echo "<td><input type=text name=reservation_comment value='${port['reservation_comment']}'></td>";
1020 echo "<td><a href='${root}process.php?op=useup&page=${pageno}&tab=${tabno}&port_id=${port['id']}&object_id=${object_id}'>";
1021 printImageHREF ('useup', 'Use up this port');
1022 echo "</a></td>";
1023 }
1024 else
1025 {
1026 echo "<td>&nbsp;</td><td>&nbsp;</td>";
1027 echo "<td>";
1028 echo "<a href='javascript:;' onclick='window.open(\"${root}link_helper.php?port=${port['id']}&type=${port['type_id']}&object_id=$object_id&port_name=";
1029 echo urlencode ($port['name']);
1030 echo "\",\"findlink\",\"height=700, width=400, location=no, menubar=no, resizable=yes, scrollbars=no, status=no, titlebar=no, toolbar=no\");'>";
1031 printImageHREF ('link', 'Link this port');
1032 echo "</a> <input type=text name=reservation_comment>";
1033 echo "</td>\n";
1034 }
1035 echo "<td><input type='submit' value='OK'></td>";
1036 echo "</form></tr>\n";
1037 }
1038 echo "<form action='${root}process.php'><tr>";
1039 echo "<td colspan=2><input type=text size=10 name=port_name tabindex=100></td>\n";
1040 echo "<td><input type=text size=24 name=port_label tabindex=101></td>";
1041 echo "<input type=hidden name=op value=addPort>\n";
1042 echo "<input type=hidden name=object_id value='${object_id}'>\n";
1043 echo "<input type=hidden name=page value='${pageno}'>\n";
1044 echo "<input type=hidden name=tab value='${tabno}'>\n";
1045 echo "<td><select name='port_type_id' tabindex=102>\n";
1046 $types = getPortTypes();
9c0b0016 1047 $default_port_type = getConfigVar ('default_port_type');
e673ee24
DO
1048 foreach ($types as $typeid => $typename)
1049 {
1050 echo "<option value='${typeid}'";
1051 if ($typeid == $default_port_type)
1052 echo " selected";
1053 echo ">${typename}</option>\n";
1054 }
1055 echo "</select></td>";
1056 echo "<td><input type=text name=port_l2address tabindex=103></td>\n";
1057 echo "<td colspan=4><input type='submit' value='Add a new port' tabindex=104></td></tr></form>";
1058 echo "</table><br>\n";
1059 finishPortlet();
1060
1061 startPortlet ('Add/update multiple ports');
1062 echo "<form action=${root}process.php method=post>";
1063 echo "<input type=hidden name=page value='${pageno}'>\n";
1064 echo "<input type=hidden name=tab value='${tabno}'>\n";
1065 echo "<input type=hidden name=object_id value='${object_id}'>\n";
1066 echo "<input type=hidden name=op value=addMultiPorts>";
1067 echo 'Format: <select name=format>';
1068 echo '<option value=c2900 disabled>Cisco 2900 series: sh int eth</option>';
1069 echo '<option value=c3600eth disabled>Cisco 3600 ethernet: sh arp | inc -</option>';
1070 echo '<option value=c3600asy>Cisco 3600 async: sh line | inc TTY</option>';
1071 echo '<option value=fiwg selected>Foundry ServerIron/FastIron WorkGroup/Edge: sh int br</option>';
1072 echo '<option value=fiedge disabled>Foundry FastIron Edge: sh int br</option>';
1073 echo '<option value=fisxii>Foundry FastIron SuperX/II4000: sh int br</option>';
351d4dbf 1074 echo '<option value=ssv1>SSV:&lt;interface name&gt; &lt;MAC address&gt;</option>';
e673ee24
DO
1075 echo "</select>";
1076 echo 'Default port type: ';
1077 echo "<select name=port_type>\n";
1078 foreach ($types as $typeid => $typename)
1079 {
1080 echo "<option value='${typeid}'";
1081 if ($typeid == $default_port_type)
1082 echo " selected";
1083 echo ">${typename}</option>\n";
1084 }
1085 echo "</select>";
1086 echo "<input type=submit value='Parse output'><br>\n";
1087 echo "<textarea name=input cols=100 rows=50></textarea><br>\n";
1088 echo '</form>';
1089 finishPortlet();
1090}
1091
1092function renderNetworkForObject ($object_id=0)
1093{
1094 global $root, $pageno, $tabno;
1095 if ($object_id <= 0)
1096 {
591ff2c4 1097 showError ('Invalid object_id', __FUNCTION__);
e673ee24
DO
1098 return;
1099 }
1100 showMessageOrError();
1101 startPortlet ('Network Addresses');
1102 $addresses = getObjectAddresses ($object_id);
1103 usort($addresses, 'sortAddresses');
1104 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
1105 echo "<tr><th>&nbsp;</th><th>Interface name</th><th>IP Address</th><th>Description</th><th>Type</th><th>Misc</th><th>&nbsp</th></tr>\n";
1106 foreach ($addresses as $addr)
1107 {
1108 if (strlen($addr['address_name'])>40)
1109 $address_name = substr($addr['address_name'],0,38).'...';
1110 else
1111 $address_name = $addr['address_name'];
1112
1113 $virtnum = countRefsOfType($addr['references'], 'virtual', 'eq');
1114 $sharednum = countRefsOfType($addr['references'], 'shared', 'eq');
1115 $regnum = countRefsOfType($addr['references'], 'regular', 'eq');
1116 $notvirtnum = countRefsOfType($addr['references'], 'virtual', 'neq');
1117
1118 if ($addr['address_reserved']=='yes')
24e85a1a 1119 $class='trerror';
e673ee24 1120 elseif ($addr['type']!='virtual' && $regnum>0)
24e85a1a 1121 $class='trerror';
e673ee24 1122 elseif ($addr['type']=='regular' && $sharednum>0)
24e85a1a 1123 $class='trerror';
e673ee24
DO
1124 else
1125 $class='';
1126
1127 echo "<form action='process.php'>";
1128 echo "<input type=hidden name=page value='${pageno}'>\n";
1129 echo "<input type=hidden name=tab value='${tabno}'>\n";
1130 echo "<input type=hidden name=op value=editAddressFromObject>";
1131 echo "<input type=hidden name=object_id value='$object_id'>";
1132 echo "<input type=hidden name=ip value='${addr['ip']}'>";
1133 echo "<tr class='$class'><td><a href='process.php?op=delAddrFObj&page=${pageno}&tab=${tabno}&ip=${addr['ip']}&object_id=$object_id'>";
1134 printImageHREF ('delete', 'Delete this IPv4 address');
1135 echo "</a></td>";
1136 echo "<td><input type='text' name='bond_name' value='${addr['name']}' size=10></td>";
1137 echo "<td><a href='${root}?page=ipaddress&ip=${addr['ip']}'>${addr['ip']}</a></td>";
1138 echo "<td class='description'>$address_name</td>\n";
1139 echo "<td><select name='bond_type'>";
1140 foreach (array('regular'=>'Regular', 'virtual'=>'Virtual', 'shared'=>'Shared') as $n => $v)
1141 {
1142 echo "<option value='$n'";
1143 if ($addr['type'] == $n)
1144 echo " selected";
1145 echo ">$v</option>";
1146 }
1147 echo "</td><td>";
1148 if ($addr['address_reserved']=='yes')
1149 echo "<b>Reserved</b>; ";
1150
1151 if ($addr['type'] == 'virtual')
1152 {
1153 if ($notvirtnum > 0)
1154 {
1155 echo " Owners: ";
1156 printRefsOfType($addr['references'], 'virtual', 'neq');
1157 }
1158 }
1159 elseif ($addr['type'] == 'shared')
1160 {
1161 if ($sharednum > 0)
1162 {
1163 echo " Peers: ";
1164 printRefsOfType($addr['references'], 'shared', 'eq');
1165 echo ";";
1166 }
1167 if ($virtnum > 0)
1168 {
1169 echo " Virtuals: ";
1170 printRefsOfType($addr['references'], 'virtual', 'eq');
1171 echo ";";
1172 }
1173 if ($regnum > 0)
1174 {
1175 echo " Collisions: ";
1176 printRefsOfType($addr['references'], 'regular', 'eq');
1177 }
1178
1179 }
1180 else
1181 {
1182 if ($virtnum > 0)
1183 {
1184 echo " Virtuals: ";
1185 printRefsOfType($addr['references'], 'virtual', 'eq');
1186 echo ";";
1187 }
1188 if ($notvirtnum > 0)
1189 {
1190 echo " Collisions: ";
1191 printRefsOfType($addr['references'], 'virtual', 'neq');
1192 }
1193 }
1194
1195 echo "</td><td><input type=submit value='OK'></td></form></tr>\n";
1196 }
1197
1198
1199 echo "<form action='${root}process.php'><tr><td colspan=2><input type='text' size='10' name='name' tabindex=100></td>\n";
1200 echo "<input type=hidden name=page value='${pageno}'>\n";
1201 echo "<input type=hidden name=tab value='${tabno}'>\n";
1202 echo "<input type=hidden name=op value=addAddrFObj>\n";
1203 echo "<input type=hidden name=object_id value='$object_id'>\n";
1204
1205 echo "<td><input type=text name='ip' tabindex=101>\n";
1206 echo "</td><td><select name='type' tabindex=102>";
1207 echo "<option value='regular'>Regular</option>";
1208 echo "<option value='virtual'>Virtual</option>";
1209 echo "<option value='shared'>Shared</option>";
1210 echo "</select>";
1211 echo "</td><td colspan=3><input type='submit' value='Add a new interface' tabindex=103></td></tr></form>";
1212 echo "</table><br>\n";
1213 finishPortlet();
1214
1215}
1216
1217function printLog ($log)
1218{
1219 foreach ($log as $record)
1220 echo "<div class=msg_${record['code']}>${record['message']}</div>";
1221}
1222
1223/*
1224The following conditions must be followed:
12251. We can mount onto free atoms only. This means: if any record for an atom
1226already exists in RackSpace, it can't be used for mounting.
12272. We can't unmount from 'W' atoms. Operator should review appropriate comments
1228and either delete them before unmounting or refuse to unmount the object.
1229*/
1230
1231// We extensively use $_REQUEST in the function.
1232function renderRackSpaceForObject ($object_id = 0)
1233{
1234 if ($object_id <= 0)
1235 {
591ff2c4 1236 showError ('Invalid object_id', __FUNCTION__);
e673ee24
DO
1237 return;
1238 }
1239 $is_submit = isset ($_REQUEST['got_atoms']);
1240 $is_update = isset ($_REQUEST['rackmulti'][0]);
1241 $info = getObjectInfo ($object_id);
1242 if ($info == NULL)
1243 {
591ff2c4 1244 showError ('getObjectInfo() failed', __FUNCTION__);
e673ee24
DO
1245 return;
1246 }
1247 // Always process occupied racks plus racks chosen by user. First get racks with
1248 // already allocated rackspace...
1249 $workingRacksData = getResidentRacksData ($object_id);
1250 if ($workingRacksData === NULL)
1251 {
1252 print_r ($workingRacksData);
591ff2c4 1253 showError ('getResidentRacksData() failed', __FUNCTION__);
e673ee24
DO
1254 return;
1255 }
1256
1257 // ...and then add those chosen by user (if any).
1258 if ($is_update)
1259 foreach ($_REQUEST['rackmulti'] as $cand_id)
1260 {
1261 if (!isset ($workingRacksData[$cand_id]))
1262 {
1263 $rackData = getRackData ($cand_id);
1264 if ($rackData == NULL)
1265 {
591ff2c4 1266 showError ('getRackData() failed', __FUNCTION__);
e673ee24
DO
1267 return NULL;
1268 }
1269 $workingRacksData[$cand_id] = $rackData;
1270 }
1271 }
1272
1273 // Do it only once...
1274 foreach ($workingRacksData as &$rackData)
1275 applyObjectMountMask ($rackData, $object_id);
1276 // Now we workaround an old caveat: http://bugs.php.net/bug.php?id=37410
1277 unset ($rackData);
1278
1279 // Here we process form submit by trying to save all submitted info to database.
1280 if ($is_submit)
1281 {
1282 $oldMolecule = getMoleculeForObject ($object_id);
1283 $worldchanged = FALSE;
1284 $log = array();
1285 foreach ($workingRacksData as $rack_id => $rackData)
1286 {
1287 $logrecord = processGridForm ($rackData, 'F', 'T', $object_id);
1288 $log[] = $logrecord;
1289 if ($logrecord['code'] != 300)
1290 {
1291 $worldchanged = TRUE;
1292 // Reload our working copy after form processing.
1293 $rackData = getRackData ($rack_id);
1294 if ($rackData == NULL)
4d2e93f2 1295 $log[] = array ('code' => 500, 'message' => 'Working copy update failed in ', __FUNCTION__);
e673ee24
DO
1296 applyObjectMountMask ($rackData, $object_id);
1297 $workingRacksData[$rack_id] = $rackData;
1298 }
1299 }
1300 if ($worldchanged)
1301 {
1302 // Log a record.
1303 $newMolecule = getMoleculeForObject ($object_id);
1304 $oc = count ($oldMolecule);
1305 $nc = count ($newMolecule);
1306 $omid = $oc ? createMolecule ($oldMolecule) : 'NULL';
1307 $nmid = $nc ? createMolecule ($newMolecule) : 'NULL';
1308 global $remote_username;
1309 $comment = empty ($_REQUEST['comment']) ? 'NULL' : "'${_REQUEST['comment']}'";
1310 $query =
1311 "insert into MountOperation(object_id, old_molecule_id, new_molecule_id, user_name, comment) " .
1312 "values (${object_id}, ${omid}, ${nmid}, '${remote_username}', ${comment})";
1313 global $dbxlink;
1314 $result = $dbxlink->query ($query);
1315 if ($result == NULL)
1316 $log[] = array ('code' => 'error', 'message' => 'SQL query failed during history logging.');
1317 else
1318 $log[] = array ('code' => 'success', 'message' => 'History logged.');
1319 }
1320 printLog ($log);
1321 }
1322
1323 // This is the time for rendering.
1324 global $root, $pageno, $tabno;
1325 echo "<form id='racks' action='${root}'>";
1326 echo "<input type=hidden name=page value='${pageno}'>\n";
1327 echo "<input type=hidden name=tab value='${tabno}'>\n";
1328 echo "<input type=hidden name=object_id value='${object_id}'>\n";
1329 // Main layout starts.
1330 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0><tr>";
1331
1332 // Left portlet with rack list.
1333 echo "<td class=pcleft height='1%'>";
1334 startPortlet ('Racks');
1335 $allRacksData = getRacksForRow();
4b8d413e
DO
1336 if (count ($allRacksData) <= getConfigVar ('RACK_PRESELECT_THRESHOLD'))
1337 {
1338 foreach (array_keys ($allRacksData) as $rack_id)
1339 {
1340 $rackData = getRackData ($rack_id);
1341 if ($rackData == NULL)
1342 {
1343 showError ('getRackData() failed', __FUNCTION__);
1344 return NULL;
1345 }
1346 $workingRacksData[$rack_id] = $rackData;
1347 }
1348 foreach ($workingRacksData as &$rackData)
1349 applyObjectMountMask ($rackData, $object_id);
1350 unset ($rackData);
1351 }
1352 renderRackMultiSelect ('rackmulti[]', $allRacksData, array_keys ($workingRacksData));
e673ee24
DO
1353 echo "<br>";
1354 echo "<br>";
1355 finishPortlet();
1356 echo "</td>";
1357
1358 // Middle portlet with comment and submit.
1359 echo "<td class=pcleft>";
1360 startPortlet ('Comment');
1361 echo "<textarea name=comment rows=10 cols=40></textarea><br>\n";
1362 echo "<input type=submit value='Save' name=got_atoms>\n";
1363 echo "<br>";
1364 echo "<br>";
1365 finishPortlet();
1366 echo "</td>";
1367
1368 // Right portlet with rendered racks. If this form submit is not final, we have to
1369 // reflect the former state of the grid in current form.
1370 echo "<td class=pcright rowspan=2 height='1%'>";
1371 startPortlet ('Working copy');
1372 echo '<table border=0 cellspacing=10 align=center><tr>';
1373 foreach ($workingRacksData as $rack_id => $rackData)
1374 {
1375 // Order is important here: only original allocation is highlighted.
1376 highlightObject ($rackData, $object_id);
1377 markupAtomGrid ($rackData, 'T');
1378 // If we have a form processed, discard user input and show new database
1379 // contents.
1380 if (!$is_submit and $is_update)
1381 mergeGridFormToRack ($rackData);
1382 echo "<td valign=top>";
1383 echo "<center>\n<h2>${rackData['name']}</h2>\n";
1384 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
1385 echo "<tr><th width='10%'>&nbsp;</th><th width='20%'>Front</th>";
1386 echo "<th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
1387 renderAtomGrid ($rackData);
9b7468b7
DO
1388 echo "<tr><th width='10%'>&nbsp;</th><th width='20%'>Front</th>";
1389 echo "<th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
e673ee24
DO
1390 echo "</table></center>\n";
1391 echo '</td>';
1392 }
1393 echo "</tr></table>";
1394 finishPortlet();
1395 echo "</td>\n";
1396
1397 echo "</form>\n";
1398 echo "</tr></table>\n";
1399}
1400
1401function renderMolecule ($mdata, $object_id)
1402{
1403 // sort data out
1404 $rackpack = array();
1405 global $loclist;
1406 foreach ($mdata as $dummy => $rua)
1407 {
1408 $rack_id = $rua['rack_id'];
1409 $unit_no = $rua['unit_no'];
1410 $atom = $rua['atom'];
1411 if (!isset ($rackpack[$rack_id]))
1412 {
1413 $rackData = getRackData ($rack_id);
1414 for ($i = $rackData['height']; $i > 0; $i--)
1415 for ($locidx = 0; $locidx < 3; $locidx++)
1416 $rackData[$i][$locidx]['state'] = 'F';
1417 $rackpack[$rack_id] = $rackData;
1418 }
1419 $rackpack[$rack_id][$unit_no][$loclist[$atom]]['state'] = 'T';
1420 $rackpack[$rack_id][$unit_no][$loclist[$atom]]['object_id'] = $object_id;
1421 }
1422 // now we have some racks to render
1423 foreach ($rackpack as $dummy => $rackData)
1424 {
1425 markAllSpans ($rackData);
1426 echo "<table class=molecule cellspacing=0>\n";
1427 echo "<caption>${rackData['name']}</caption>\n";
1428 echo "<tr><th width='10%'>&nbsp;</th><th width='20%'>Front</th><th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
1429 for ($i = $rackData['height']; $i > 0; $i--)
1430 {
1431 echo "<tr><th>$i</th>";
1432 for ($locidx = 0; $locidx < 3; $locidx++)
1433 {
1434 $state = $rackData[$i][$locidx]['state'];
1435 echo "<td class=state_${state}>&nbsp;</td>\n";
1436 }
1437 echo "</tr>\n";
1438 }
1439 echo "</table>\n";
1440 }
1441}
1442
1443function renderUnmountedObjectsPortlet ()
1444{
1445 startPortlet ('Unmounted objects');
1446 $objs = getUnmountedObjects();
1447 if ($objs === NULL)
1448 {
591ff2c4 1449 showError ('getUnmountedObjects() failed', __FUNCTION__);
e673ee24
DO
1450 return;
1451 }
1452 global $root, $nextorder;
1453 $order = 'odd';
1454 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
18d94c29 1455 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset number</th><th>Barcode</th></tr>';
e673ee24
DO
1456 foreach ($objs as $obj)
1457 {
1458 echo "<tr class=row_${order}><td><a href='${root}?page=object&object_id=${obj['id']}'>${obj['dname']}</a></td>";
1459 echo "<td>${obj['label']}</td>";
18d94c29
DO
1460 echo "<td>${obj['asset_no']}</td>";
1461 echo "<td>${obj['barcode']}</td></tr>";
e673ee24
DO
1462 $order = $nextorder[$order];
1463 }
1464 echo "</table><br>\n";
1465 finishPortlet();
1466}
1467
1468function renderProblematicObjectsPortlet ()
1469{
1470 startPortlet ('Problematic objects');
1471 $objs = getProblematicObjects();
1472 if ($objs === NULL)
1473 {
591ff2c4 1474 showError ('getProblematicObjects() failed', __FUNCTION__);
e673ee24
DO
1475 return;
1476 }
1477 global $root, $nextorder;
1478 $order = 'odd';
1479 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1480 echo '<tr><th>Type</th><th>Common name</th></tr>';
1481 foreach ($objs as $obj)
1482 {
1483 echo "<tr class=row_${order}><td>${obj['objtype_name']}</td>";
1484 echo "<td><a href='${root}?page=object&object_id=${obj['id']}'>${obj['dname']}</a></tr>";
1485 $order = $nextorder[$order];
1486 }
1487 echo "</table><br>\n";
1488 finishPortlet();
1489}
1490
1491function renderObjectGroupSummary ()
1492{
1493 global $root;
20c901a7
DO
1494 $tagfilter = isset ($_REQUEST['tagfilter']) ? $_REQUEST['tagfilter'] : array();
1495 $tagfilter = complementByKids ($tagfilter);
e673ee24
DO
1496 $summary = getObjectGroupInfo();
1497 if ($summary === NULL)
1498 {
591ff2c4 1499 showError ('getObjectGroupInfo() failed', __FUNCTION__);
e673ee24
DO
1500 return;
1501 }
1502 echo "<table border=0 class=objectview>\n";
1503 echo "<tr><td class=pcleft width='25%'>";
1504
1505 startPortlet ('Summary');
1506 foreach ($summary as $gi)
e673ee24 1507 echo "<a href='${root}?page=objgroup&group_id=${gi['id']}'><b>${gi['name']}</b></a> <i>(${gi['count']})</i><br>";
e673ee24
DO
1508 finishPortlet();
1509
1510 echo '</td><td class=pcright>';
1511 renderUnmountedObjectsPortlet();
1512 echo '</td><td class=pcright>';
1513 renderProblematicObjectsPortlet();
20c901a7
DO
1514 echo '</td><td class=pcright>';
1515 renderTagFilterPortlet ($tagfilter, 'object');
e673ee24
DO
1516 echo "</td></tr></table>\n";
1517}
1518
466dcbe6 1519function renderObjectGroup ()
e673ee24
DO
1520{
1521 global $root;
466dcbe6
DO
1522 assertUIntArg ('group_id');
1523 $group_id = $_REQUEST['group_id'];
e673ee24
DO
1524 $summary = getObjectGroupInfo();
1525 if ($summary == NULL)
1526 {
591ff2c4 1527 showError ('getObjectGroupInfo() failed', __FUNCTION__);
e673ee24
DO
1528 return;
1529 }
1530 $objects = getObjectList ($group_id);
1531 if ($objects === NULL)
1532 {
591ff2c4 1533 showError ('getObjectList() failed', __FUNCTION__);
e673ee24
DO
1534 return;
1535 }
1536 echo "<table border=0 class=objectview>\n";
1537 echo "<tr><td class=pcleft width='25%'>";
1538
1539 startPortlet ('All objects');
1540 foreach ($summary as $gi)
1541 {
1542 echo "<a href='${root}?page=objgroup&group_id=${gi['id']}'><b>${gi['name']}</b></a> <i>(${gi['count']})</i><br>";
1543 }
1544 finishPortlet();
1545
1546 echo '</td><td class=pcright>';
1547
1548 startPortlet ('Object group');
1549 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
18d94c29 1550 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>Barcode</th><th>Rack</th></tr>';
e673ee24
DO
1551 $order = 'odd';
1552 global $nextorder;
1553 foreach ($objects as $obj)
1554 {
1555 echo "<tr class=row_${order}><td><a href='${root}?page=object&object_id=${obj['id']}'>${obj['dname']}</a></td>";
1556 echo "<td>${obj['label']}</td>";
1557 echo "<td>${obj['asset_no']}</td>";
18d94c29 1558 echo "<td>${obj['barcode']}</td>";
e673ee24
DO
1559 if ($obj['rack_id'])
1560 echo "<td><a href='${root}?page=rack&rack_id=${obj['rack_id']}'>${obj['Rack_name']}</a></td>";
1561 else
1562 echo '<td>Unmounted</td>';
1563 echo '</tr>';
1564 $order = $nextorder[$order];
1565 }
1566 echo '</table>';
1567 finishPortlet();
1568
1569 echo "</td></tr></table>";
1570}
1571
1572function renderEmptyPortsSelect ($port_id, $type_id)
1573{
1574 $ports = getEmptyPortsOfType($type_id);
1575 usort($ports, 'sortEmptyPorts');
1576 foreach ($ports as $port)
1577 {
1578 if ($port_id == $port['Port_id'])
1579 continue;
1580 echo "<option value='${port['Port_id']}' onclick='getElementById(\"remote_port_name\").value=\"${port['Port_name']}\"; getElementById(\"remote_object_name\").value=\"${port['Object_name']}\";'>${port['Object_name']} ${port['Port_name']}</option>\n";
1581 }
1582}
1583
1584function renderObjectAddressesAndNames ()
1585{
1586 $addresses = getObjectAddressesAndNames();
1587 usort($addresses, 'sortObjectAddressesAndNames');
1588 foreach ($addresses as $address)
1589 {
1590 echo "<option value='${address['ip']}' onclick='getElementById(\"ip\").value=\"${address['ip']}\";'>${address['object_name']} ${address['name']} ${address['ip']}</option>\n";
1591 }
1592}
1593
1594// History viewer for history-enabled simple dictionaries.
1595function renderHistory ($object_type, $object_id)
1596{
1597 switch ($object_type)
1598 {
1599 case 'row':
1600 $query = "select ctime, user_name, name, deleted, comment from RackRowHistory where id = ${object_id} order by ctime";
1601 $header = '<tr><th>change time</th><th>author</th><th>rack row name</th><th>is deleted?</th><th>rack row comment</th></tr>';
1602 $extra = 4;
1603 break;
1604 case 'rack':
1605 $query =
1606 "select ctime, user_name, rh.name, rh.deleted, d.dict_value as name, rh.height, rh.comment " .
1607 "from RackHistory as rh left join Dictionary as d on rh.row_id = d.dict_key " .
1608 "natural join Chapter " .
1609 "where chapter_name = 'RackRow' and rh.id = ${object_id} order by ctime";
1610 $header = '<tr><th>change time</th><th>author</th><th>rack name</th><th>is deleted?</th><th>rack row name</th><th>rack height</th><th>rack comment</th></tr>';
1611 $extra = 6;
1612 break;
1613 case 'object':
1614 $query =
1615 "select ctime, user_name, name, label, barcode, asset_no, deleted, has_problems, dict_value, comment " .
1616 "from RackObjectHistory inner join Dictionary on objtype_id = dict_key natural join Chapter " .
1617 "where chapter_name = 'RackObjectType' and id=${object_id} order by ctime";
1618 $header = '<tr><th>change time</th><th>author</th><th>common name</th><th>visible label</th><th>barcode</th><th>asset no</th><th>is deleted?</th><th>has problems?</th><th>object type</th><th>comment</th></tr>';
1619 $extra = 9;
1620 break;
1621 default:
591ff2c4 1622 showError ("Uknown object type '${object_type}'", __FUNCTION__);
e673ee24
DO
1623 return;
1624 }
1625 global $dbxlink;
1626 $result = $dbxlink->query ($query);
1627 if ($result == NULL)
1628 {
591ff2c4 1629 showError ('SQL query failed', __FUNCTION__);
e673ee24
DO
1630 return;
1631 }
1632 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1633 $order = 'odd';
1634 global $nextorder;
1635 echo $header;
1636 while ($row = $result->fetch (PDO::FETCH_NUM))
1637 {
1638 echo "<tr class=row_${order}><td>${row[0]}</td>";
1639 for ($i = 1; $i <= $extra; $i++)
1640 echo "<td>" . $row[$i] . "</td>";
1641 echo "</tr>\n";
1642 $order = $nextorder[$order];
1643 }
1644 echo "</table><br>\n";
1645}
1646
1647function renderRackspaceHistory ()
1648{
1649 global $root, $nextorder, $pageno, $tabno;
1650 $order = 'odd';
1651 $history = getRackspaceHistory();
1652 // Show the last operation by default.
1653 if (isset ($_REQUEST['op_id']))
1654 $op_id = $_REQUEST['op_id'];
1655 elseif (isset ($history[0]['mo_id']))
1656 $op_id = $history[0]['mo_id'];
1657 else $op_id = NULL;
1658
1659 $omid = NULL;
1660 $nmid = NULL;
1661 $object_id = 1;
1662 if ($op_id)
1663 list ($omid, $nmid) = getOperationMolecules ($op_id);
1664
1665 // Main layout starts.
1666 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
1667
1668 // Left top portlet with old allocation.
1669 echo "<tr><td class=pcleft>";
1670 startPortlet ('Old allocation');
1671 if ($omid)
1672 {
1673 $oldMolecule = getMolecule ($omid);
1674 renderMolecule ($oldMolecule, $object_id);
1675 }
1676 else
1677 echo "nothing";
1678 finishPortlet();
1679
1680 echo '</td><td class=pcright>';
1681
1682 // Right top portlet with new allocation
1683 startPortlet ('New allocation');
1684 if ($nmid)
1685 {
1686 $newMolecule = getMolecule ($nmid);
1687 renderMolecule ($newMolecule, $object_id);
1688 }
1689 else
1690 echo "nothing";
1691 finishPortlet();
1692
1693 echo '</td></tr><tr><td colspan=2>';
1694
1695 // Bottom portlet with list
1696
1697 startPortlet ('Rackspace allocation history');
1698 echo "<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>\n";
1699 echo "<tr><th>timestamp</th><th>author</th><th>rack object ID</th><th>rack object type</th><th>rack object name</th><th>comment</th></tr>\n";
1700 foreach ($history as $row)
1701 {
1702 if ($row['mo_id'] == $op_id)
1703 $class = 'hl';
1704 else
1705 $class = "row_${order}";
1706 echo "<tr class=${class}><td><a href='${root}?page=${pageno}&tab=${tabno}&op_id=${row['mo_id']}'>${row['ctime']}</a></td>";
1707 echo "<td>${row['user_name']}</td>";
1708 echo "<td>${row['ro_id']}</td><td>${row['objtype_name']}</td><td>${row['name']}</td><td>${row['comment']}</td>\n";
1709 echo "</tr>\n";
1710 $order = $nextorder[$order];
1711 }
1712 echo "</table>\n";
1713 finishPortlet();
1714
1715 echo '</td></tr></table>';
1716
1717}
1718
1719function renderAddressspace ()
1720{
b3c50e6c 1721 global $root, $page;
a7fe7729 1722
74ccacff
DO
1723 echo "<table border=0 class=objectview>\n";
1724 echo "<tr><td class=pcleft>";
1725
a7fe7729 1726 startPortlet ('Subnets');
e673ee24 1727 echo "<table class='widetable' border=0 cellpadding=10 cellspacing=0 align='center'>\n";
74ccacff
DO
1728 $tagfilter = isset ($_REQUEST['tagfilter']) ? $_REQUEST['tagfilter'] : array();
1729 $tagfilter = complementByKids ($tagfilter);
1730 $addrspaceList = getAddressspaceList ($tagfilter);
119f2ad2 1731 echo "<tr><th>Subnet</th><th>Name</th><th>Utilization</th></tr>";
e673ee24
DO
1732 foreach ($addrspaceList as $iprange)
1733 {
119f2ad2
DO
1734 $range = getIPRange ($iprange['id']);
1735 $total = ($iprange['ip_bin'] | $iprange['mask_bin_inv']) - ($iprange['ip_bin'] & $iprange['mask_bin']) + 1;
1736 $used = count ($range['addrlist']);
1737 echo "<tr><td class=tdleft><a href='${root}?page=iprange&id=${iprange['id']}'>${iprange['ip']}/${iprange['mask']}</a></td>";
1738 echo "<td class=tdleft>${iprange['name']}</td><td class=tdleft>";
1739 renderProgressBar ($used/$total);
1740 echo " ${used}/${total}</td></tr>";
e673ee24
DO
1741 }
1742 echo "</table>\n";
a7fe7729 1743 finishPortlet();
74ccacff 1744 echo '</td><td class=pcright>';
5b7bd02e 1745 renderTagFilterPortlet ($tagfilter, 'ipv4net');
74ccacff 1746 echo "</td></tr></table>\n";
f973f491 1747}
a7fe7729 1748
f973f491
DO
1749function renderIPv4SLB ()
1750{
80e85ea1 1751 global $root, $page, $nextorder;
a7fe7729 1752
6fec9f39 1753 startPortlet ('SLB configuration');
b3c50e6c
DO
1754 echo "<table border=0 width='100%'><tr>";
1755 foreach (array ('vservices', 'rspools', 'rservers', 'lbs') as $pno)
e57dca7f 1756 echo "<td><h3><a href='${root}?page=${pno}'>" . $page[$pno]['title'] . "</a></h3></td>";
b3c50e6c
DO
1757 echo '</tr></table>';
1758 finishPortlet();
1759
c3bdc503 1760 $summary = getSLBSummary();
6fec9f39 1761 startPortlet ('SLB tactical overview');
4cadac8f
DO
1762 // A single id-keyed array isn't used here to preserve existing
1763 // order of LBs returned by getSLBSummary()
c3bdc503
DO
1764 $lblist = array();
1765 $lbdname = array();
4cadac8f 1766 foreach ($summary as $vipdata)
da04825a 1767 foreach (array_keys ($vipdata['lblist']) as $lb_object_id)
c3bdc503
DO
1768 if (!in_array ($lb_object_id, $lblist))
1769 {
1770 $oi = getObjectInfo ($lb_object_id);
1771 $lbdname[$lb_object_id] = $oi['dname'];
1772 $lblist[] = $lb_object_id;
1773 }
1774 if (!count ($summary))
1775 echo 'none configured';
1776 else
1777 {
80e85ea1 1778 $order = 'odd';
c3bdc503 1779 echo "<table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
a7bc13c8 1780 echo "<tr><th>VS&nbsp;&darr; LB&nbsp;&rarr;</th>";
c3bdc503 1781 foreach ($lblist as $lb_object_id)
71b8bda1 1782 echo "<th><a href='${root}?page=object&tab=default&object_id=${lb_object_id}'>" . $lbdname[$lb_object_id] . "</a></th>";
c3bdc503 1783 echo "</tr>\n";
4cadac8f
DO
1784 foreach ($summary as $vsid => $vsdata)
1785 {
80e85ea1 1786 echo "<tr class=row_${order}><td class=tdleft><a href='$root?page=vservice&tab=default&id=${vsid}'>";
8d790216 1787 echo buildVServiceName ($vsdata);
6fec9f39
DO
1788 echo '</a>';
1789 if (!empty ($vsdata['name']))
1790 echo " (${vsdata['name']})";
1791 echo "</td>";
4cadac8f 1792 foreach ($lblist as $lb_object_id)
da04825a 1793 {
60fbcece 1794 echo '<td class=tdleft>';
2b4eee17 1795 if (!isset ($vsdata['lblist'][$lb_object_id]))
da04825a
DO
1796 echo '&nbsp;';
1797 else
6fec9f39
DO
1798 {
1799 echo $vsdata['lblist'][$lb_object_id]['size'];
c0ae6968 1800 echo " (<a href='${root}?page=rspool&pool_id=";
6fec9f39
DO
1801 echo $vsdata['lblist'][$lb_object_id]['id'] . "'>";
1802 echo $vsdata['lblist'][$lb_object_id]['name'] . '</a>)';
1803 }
da04825a
DO
1804 echo '</td>';
1805 }
1806 echo "</tr>\n";
80e85ea1 1807 $order = $nextorder[$order];
4cadac8f 1808 }
c3bdc503
DO
1809 echo "</table>\n";
1810 }
a7fe7729 1811 finishPortlet ();
e673ee24
DO
1812}
1813
1814function renderAddNewRange ()
1815{
1816 global $root, $pageno, $tabno;
1817 showMessageOrError();
2a201216 1818
5c0bb421 1819 startPortlet ("Add New");
2a201216 1820 echo "<table class='widetable' border=0 cellpadding=10 align='center'>\n";
5c0bb421 1821 echo "<tr><th>Address range</th><th>Name</th><th>connected network</th><th>assign tags</th><th>&nbsp;</th></tr>\n";
2a201216
DY
1822 echo "<form name='add_new_range' action='process.php'>\n";
1823 echo "<input type=hidden name=op value=addRange>\n";
1824 echo "<input type=hidden name=page value='${pageno}'>\n";
1825 echo "<input type=hidden name=tab value='${tabno}'>\n";
5c0bb421 1826 echo "<tr valign=top><td class='tdcenter'><input type=text name='range' size=18 class='live-validate' tabindex=1></td>\n";
7059c1d2
DO
1827 echo "<td class='tdcenter'><input type=text name='name' size='20' tabindex=2></td>\n";
1828 echo "<td class='tdcenter'><input type=checkbox name='is_bcast' tabindex=3 checked></td>\n";
5c0bb421
DO
1829 echo "<td>\n";
1830 renderTagSelect();
1831 echo "</td>\n";
1832 echo "<td class='tdcenter'><input type=submit value='Add a new range' tabindex=4></td>\n";
1833 echo "</td></tr>\n";
2a201216 1834 echo "</form></table><br><br>\n";
5c0bb421 1835 finishPortlet();
2a201216 1836
5c0bb421 1837 startPortlet ("Manage Existing");
2a201216 1838 echo "<table class='widetable' border=0 cellpadding=10 align='center'>\n";
e673ee24 1839 $addrspaceList = getAddressspaceList();
283824c8 1840 echo "<tr><th>&nbsp;</th><th>Address range</th><th>Name</th><th>Utilization</th></tr>";
e673ee24
DO
1841 foreach ($addrspaceList as $iprange)
1842 {
1843 $range = getIPRange($iprange['id']);
dc462202 1844 $usedips = count ($range['addrlist']);
283824c8 1845 $totalips = ($iprange['ip_bin'] | $iprange['mask_bin_inv']) - ($iprange['ip_bin'] & $iprange['mask_bin']) + 1;
0c4605ab 1846 echo "<tr><td>";
e673ee24
DO
1847 if ($usedips == 0)
1848 {
0c4605ab 1849 echo "<a href='process.php?op=delRange&page=${pageno}&tab=${tabno}&id=${iprange['id']}'>";
e673ee24 1850 printImageHREF ('delete', 'Delete this IP range');
0c4605ab 1851 echo "</a>";
e673ee24
DO
1852 }
1853 else
0c4605ab 1854 printImageHREF ('nodelete', 'There are IP addresses allocated or reserved');
20c901a7
DO
1855 echo "</td>\n<td class=tdleft><a href='${root}?page=iprange&id=${iprange['id']}'>";
1856 echo "${iprange['ip']}/${iprange['mask']}</a></td><td class=tdleft>${iprange['name']}";
1857 echo "</td><td class=tdleft>";
283824c8
DO
1858 renderProgressBar ($usedips / $totalips);
1859 echo " ${usedips}/${totalips}";
e673ee24
DO
1860 echo "</td></tr>";
1861 }
cee27f1d 1862 echo "</table>";
5c0bb421 1863 finishPortlet();
e673ee24
DO
1864}
1865
2fe5476a 1866function renderIPRange ($id)
e673ee24 1867{
41bd8c87 1868 global $root, $pageno, $tabno;
b901bf1f 1869 $maxperpage = getConfigVar ('IPV4_ADDRS_PER_PAGE');
e673ee24
DO
1870 if (isset($_REQUEST['pg']))
1871 $page = $_REQUEST['pg'];
1872 else
1873 $page=0;
1874
e673ee24 1875 $range = getIPRange($id);
2034d968
DO
1876 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
1877 echo "<tr><td colspan=2 align=center><h1>${range['ip']}/${range['mask']}</h1><h2>${range['name']}</h2></td></tr>\n";
1878
1879 echo "<tr><td class=pcleft width='50%'>";
1880 startPortlet ('summary');
1881 $total = ($range['ip_bin'] | $range['mask_bin_inv']) - ($range['ip_bin'] & $range['mask_bin']) + 1;
1882 $used = count ($range['addrlist']);
1883 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
1884 echo "<tr><th width='50%' class=tdright>Utilization:</th><td class=tdleft>";
1885 renderProgressBar ($used/$total);
1886 echo "&nbsp;${used}/${total}</td></tr>\n";
41bd8c87 1887 printTagTRs();
2034d968
DO
1888 echo "</table><br>\n";
1889 finishPortlet();
1890 echo "</td>\n";
e673ee24 1891
2034d968
DO
1892 echo "<td class=pcright>";
1893 startPortlet ('details');
e673ee24
DO
1894 $startip = $range['ip_bin'] & $range['mask_bin'];
1895 $endip = $range['ip_bin'] | $range['mask_bin_inv'];
1896 $realstartip = $startip;
1897 $realendip = $endip;
1898 $numpages = 0;
1899 if($endip - $startip > $maxperpage)
1900 {
e673ee24
DO
1901 $numpages = ($endip - $startip)/$maxperpage;
1902 $startip = $startip + $page * $maxperpage;
1903 $endip = $startip + $maxperpage-1;
1904 }
1905 echo "<center>";
b901bf1f
DO
1906 if ($numpages)
1907 echo '<h3>' . long2ip ($startip) . ' ~ ' . long2ip ($endip) . '</h3>';
e673ee24
DO
1908 for ($i=0; $i<$numpages; $i++)
1909 {
1910 if ($i == $page)
1911 echo "<b>$i</b> ";
1912 else
a60e0851 1913 echo "<a href='${root}?page=${pageno}&tab=${tabno}&id=$id&pg=$i'>$i</a> ";
e673ee24
DO
1914 }
1915 echo "</center>";
1916
1917 echo "<table class='widetable' border=0 cellspacing=0 cellpadding=5 align='center'>\n";
1918 echo "<tr><th>Address</th><th>Name</th><th>Allocation</th></tr>\n";
1919
1920
1921 for($ip = $startip; $ip<=$endip; $ip++)
1922 {
dcee8072 1923 if (isset ($range['addrlist'][$ip]))
e673ee24
DO
1924 {
1925 $numshared = countRefsOfType($range['addrlist'][$ip]['references'], 'shared', 'eq');
1926 $numreg = countRefsOfType($range['addrlist'][$ip]['references'], 'regular', 'eq');
1927 $numvirt = countRefsOfType($range['addrlist'][$ip]['references'], 'virtual', 'eq');
602663f4
DO
1928 $numlb = count ($range['addrlist'][$ip]['lbrefs']);
1929 $numrs = count ($range['addrlist'][$ip]['rsrefs']);
e673ee24
DO
1930
1931 $addr = $range['addrlist'][$ip];
1932 if ( ($numshared > 0 && $numreg > 0) || $numreg > 1 )
24e85a1a 1933 echo "<tr class='trerror'>";
e485e609 1934 elseif ( $addr['reserved'] == 'yes' and $numshared+$numreg+$numvirt+$numlb+$numrs > 0)
24e85a1a 1935 echo "<tr class='trerror'>";
e673ee24
DO
1936 elseif ( $addr['reserved'] == 'yes')
1937 echo "<tr class='trbusy'>";
602663f4 1938 elseif ( $numshared > 0 || $numreg > 0 || $numlb > 0 || $numrs > 0)
e673ee24
DO
1939 echo "<tr class='trbusy'>";
1940 else
1941 echo "<tr>";
1942
1943 echo "<td><a href='${root}?page=ipaddress&ip=${addr['ip']}'>${addr['ip']}</a></td><td>${addr['name']}</td><td>";
6131056c 1944 $delim = '';
602663f4 1945 $prologue = '';
e673ee24 1946 if ( $addr['reserved'] == 'yes')
6131056c 1947 {
55434dd5 1948 echo "<b>Reserved</b> ";
6131056c
DO
1949 $delim = '; ';
1950 }
e673ee24
DO
1951 foreach ($range['addrlist'][$ip]['references'] as $ref)
1952 {
e26b085f 1953 echo "${delim}<a href='${root}?page=object&object_id=${ref['object_id']}'>";
db88e2de 1954 echo $ref['name'] . (empty ($ref['name']) ? '' : '@');
e26b085f
DO
1955 echo "${ref['object_name']}</a>";
1956 $delim = '; ';
e673ee24 1957 }
602663f4
DO
1958 if ($delim != '')
1959 {
1960 $delim = '';
1961 $prologue = '<br>';
1962 }
1963 foreach ($range['addrlist'][$ip]['lbrefs'] as $ref)
1964 {
1965 echo $prologue;
1966 $prologue = '';
1967 echo "${delim}<a href='${root}?page=object&object_id=${ref['object_id']}'>";
1968 echo "${ref['object_name']}</a>:<a href='${root}?page=vservice&id=${ref['vs_id']}'>";
1969 echo "${ref['vport']}/${ref['proto']}</a>&rarr;";
1970 $delim = '; ';
1971 }
1972 if ($delim != '')
1973 {
1974 $delim = '';
1975 $prologue = '<br>';
1976 }
1977 foreach ($range['addrlist'][$ip]['rsrefs'] as $ref)
1978 {
1979 echo $prologue;
1980 $prologue = '';
c0ae6968 1981 echo "${delim}&rarr;${ref['rsport']}@<a href='${root}?page=rspool&pool_id=${ref['rspool_id']}'>";
602663f4
DO
1982 echo "${ref['rspool_name']}</a>";
1983 $delim = '; ';
1984 }
e673ee24
DO
1985 echo "</td></tr>\n";
1986 }
1987 else
1988 {
1989 echo "<tr><td><a href='${root}?page=ipaddress&ip=".long2ip($ip)."'>".long2ip($ip)."</a></td><td>&nbsp;</td><td>&nbsp;</td></tr>\n";
1990 }
1991 }
1992
1993 echo "</table>";
2034d968
DO
1994 finishPortlet();
1995 echo "</td></tr></table>\n";
e673ee24
DO
1996}
1997
2fe5476a 1998function renderIPRangeProperties ($id)
e673ee24
DO
1999{
2000 global $pageno, $tabno;
e673ee24
DO
2001 showMessageOrError();
2002 $range = getIPRange($id);
2003 echo "<center><h1>${range['ip']}/${range['mask']}</h1></center>\n";
2004 echo "<table border=0 cellpadding=10 cellpadding=1 align='center'>\n";
2005 echo "<form action='process.php'><input type=hidden name=op value=editRange>";
2006 echo "<input type=hidden name=page value='${pageno}'>\n";
2007 echo "<input type=hidden name=tab value='${tabno}'>\n";
2008 echo "<input type=hidden name=id value='${id}'>";
2009 echo "<tr><td class='tdright'>Name:</td><td class='tdleft'><input type=text name=name size=20 value='${range['name']}'></tr><tr><td colspan=2 class='tdcenter'><input type=submit value='Update range'></td></form></tr>";
2010 echo "</table>\n";
2011
2012}
2013
2014function renderIPAddress ()
2015{
2016 global $root;
2017 $ip = $_REQUEST['ip'];
2018 $address = getIPAddress($ip);
2019 echo "<center><h1>$ip</h1>";
2020 if ($address['exists'] == 1)
2021 echo "<h2>${address['name']}</h2>";
2022 echo "</center>\n";
2023
2024// echo "<table width='100%' cesspadding=5 cellspacing=0 border=0 align='center'>";
2025// echo "<tr valign='top'><td>";
2026
e673ee24
DO
2027 $numshared = countRefsOfType($address['bonds'], 'shared', 'eq');
2028 $numreg = countRefsOfType($address['bonds'], 'regular', 'eq');
2029 $numvirt = countRefsOfType($address['bonds'], 'virtual', 'eq');
2030
59bebe2b
DO
2031 if ($address['reserved'] == 'yes' or ($numshared + $numreg + $numvirt) > 0)
2032 {
2033 startPortlet ('Allocation');
2034 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
2035 echo "<tr><th>Object name</th><th>Interface name</th><th>Interface type</th></tr>\n";
2036 if ( ($numshared > 0 && $numreg > 0) || $numreg > 1 )
2037 $class='trerror';
2038 elseif ( $address['reserved'] == 'yes' and $numshared+$numreg+$numvirt > 0)
2039 $class='trerror';
2040 else
2041 $class='';
e673ee24 2042
59bebe2b
DO
2043 if ($address['reserved'] == 'yes')
2044 echo "<tr class='$class'><td colspan='3'><b>RESERVED</b></td></tr>";
2045 foreach ($address['bonds'] as $bond)
2046 {
2047 echo "<tr class='$class'><td><a href='${root}?page=object&object_id=${bond['object_id']}'>${bond['object_name']}</td><td>${bond['name']}</td><td><b>";
2048 switch ($bond['type'])
2049 {
2050 case 'virtual':
2051 echo "Virtual";
2052 break;
2053 case 'shared':
2054 echo "Shared";
2055 break;
2056 case 'regular':
2057 echo "Regular";
2058 break;
2059 }
2060 echo "</b></td></tr>\n";
2061 }
2062 echo "</table><br><br>";
2063 finishPortlet();
2064 }
e673ee24 2065
59bebe2b 2066 if (count ($address['vslist']))
e673ee24 2067 {
59bebe2b
DO
2068 startPortlet ('Virtual services (' . count ($address['vslist']) . ')');
2069 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
2070 echo "<tr><th>VS</th><th>name</th></tr>\n";
2071 foreach ($address['vslist'] as $vsinfo)
e673ee24 2072 {
59bebe2b
DO
2073 echo "<tr><td class=tdleft><a href='${root}?page=vservice&id=${vsinfo['id']}'>";
2074 echo buildVServiceName ($vsinfo) . "</a></td><td class=tdleft>";
5fe1ed76 2075 echo $vsinfo['name'] . "</td></tr>\n";
e673ee24 2076 }
59bebe2b
DO
2077 echo "</table><br><br>";
2078 finishPortlet();
e673ee24 2079 }
5fe1ed76
DO
2080
2081 if (count ($address['rslist']))
2082 {
2083 startPortlet ('Real servers (' . count ($address['rslist']) . ')');
2084 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
53f4b619 2085 echo "<tr><th>&nbsp;</th><th>port</th><th>RS pool</th></tr>\n";
5fe1ed76
DO
2086 foreach ($address['rslist'] as $rsinfo)
2087 {
2088 echo "<tr><td>";
2089 if ($rsinfo['inservice'] == 'yes')
2090 printImageHREF ('inservice', 'in service');
2091 else
2092 printImageHREF ('notinservice', 'NOT in service');
c0ae6968 2093 echo "</td><td class=tdleft>${rsinfo['rsport']}</td><td class=tdleft><a href='${root}?page=rspool&pool_id=${rsinfo['pool_id']}'>";
5fe1ed76
DO
2094 echo $rsinfo['poolname'] . "</a></td></tr>\n";
2095 }
2096 echo "</table><br><br>";
2097 finishPortlet();
2098 }
2099
2100
e673ee24
DO
2101// echo "</td><td>";
2102// echo "</td></tr></table>";
2103}
2104
2105function renderIPAddressProperties ()
2106{
2107 global $pageno, $tabno;
2108 $ip = $_REQUEST['ip'];
2109 showMessageOrError();
2110 $address = getIPAddress($ip);
2111 echo "<center><h1>$ip</h1></center>\n";
2112 echo "<table border=0 cellpadding=10 cellpadding=1 align='center'>\n";
2113 echo "<form action='process.php'><input type=hidden name=op value=editAddress>";
2114 echo "<input type=hidden name=page value='${pageno}'>\n";
2115 echo "<input type=hidden name=tab value='${tabno}'>\n";
2116 echo "<input type=hidden name=ip value='${ip}'>";
2117 echo "<tr><td class='tdright'>Name:</td><td class='tdleft'><input type=text name=name size=20 value='".($address['exists']==1?$address['name']:'')."'></tr>";
2118 echo "<td class='tdright'>Reserved:</td><td class='tdleft'><input type=checkbox name=reserved size=20 ".($address['exists']==1?(($address['reserved']=='yes')?'checked':''):'')."></tr>";
2119 echo "<tr><td colspan=2 class='tdcenter'><input type=submit value='Update address'></td></form></tr>";
2120 echo "</table>\n";
2121
2122}
2123
2124function renderIPAddressAssignment ()
2125{
2126 global $pageno, $tabno, $root;
2127 $ip = $_REQUEST['ip'];
2128 $address = getIPAddress($ip);
2129
2130 showMessageOrError();
2131 echo "<center><h1>$ip</h1></center>\n";
2132
2133
2134 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
2135 echo "<tr><th>&nbsp;</th><th>Object name</th><th>Interface name</th><th>Interface type</th><th>&nbsp;</th></tr>\n";
2136
2137 $numshared = countRefsOfType($address['bonds'], 'shared', 'eq');
2138 $numreg = countRefsOfType($address['bonds'], 'regular', 'eq');
2139 $numvirt = countRefsOfType($address['bonds'], 'virtual', 'eq');
2140
2141
2142 if ( ($numshared > 0 && $numreg > 0) || $numreg > 1 )
24e85a1a 2143 $class='trerror';
e673ee24 2144 elseif ( $address['reserved'] == 'yes' and $numshared+$numreg+$numvirt > 0)
24e85a1a 2145 $class='trerror';
e673ee24
DO
2146 else
2147 $class='';
2148
2149
2150
2151 if ($address['reserved'] == 'yes')
2152 echo "<tr class='$class'><td colspan='5'><b>RESERVED</b></td></tr>";
2153 foreach ($address['bonds'] as $bond)
2154 {
2155 echo "<tr class='$class'><form action='process.php'>";
2156 echo "<input type=hidden name=op value='editBondForAddress'>";
2157 echo "<input type=hidden name=page value='${pageno}'>";
2158 echo "<input type=hidden name=tab value='${tabno}'>";
2159 echo "<input type=hidden name=ip value='$ip'>";
2160 echo "<input type=hidden name=object_id value='${bond['object_id']}'>";
2161 echo "<td><a href='process.php?op=delIpAssignment&page=${pageno}&tab=${tabno}&ip=$ip&object_id=${bond['object_id']}'>";
2162 printImageHREF ('delete', 'Unallocate address');
2163 echo "</a></td>";
2164 echo "<td><a href='${root}?page=object&object_id=${bond['object_id']}'>${bond['object_name']}</td>";
2165 echo "<td><input type='text' name='bond_name' value='${bond['name']}' size=10></td>";
2166 echo "<td><select name='bond_type'>";
2167 switch ($bond['type'])
2168 {
2169 case 'virtual':
2170 echo "<option value='regular'>Regular</option>";
2171 echo "<option value='virtual' selected>Virtual</option>";
2172 echo "<option value='shared'>Shared</option>";
2173 break;
2174 case 'shared':
2175 echo "<option value='regular'>Regular</option>";
2176 echo "<option value='virtual'>Virtual</option>";
2177 echo "<option value='shared' selected>Shared</option>";
2178 break;
2179 case 'regular':
2180 echo "<option value='regular' selected>Regular</option>";
2181 echo "<option value='virtual'>Virtual</option>";
2182 echo "<option value='shared'>Shared</option>";
2183 break;
2184 }
2185 echo "</select></td><td><input type='submit' value='OK'></td></form></tr>\n";
2186 }
2187 echo "<form action='process.php'><input type='hidden' name='op' value='bindObjectToIp'>";
2188 echo "<input type=hidden name=page value='${pageno}'>\n";
2189 echo "<input type=hidden name=tab value='${tabno}'>\n";
2190 echo "<input type='hidden' name='ip' value='$ip'>";
2191 echo "<td colspan=2><select name='object_id'>";
2192
6dbdc7c7
DO
2193 foreach (explode (',', getConfigVar ('IPV4_PERFORMERS')) as $type)
2194 foreach (getObjectList ($type) as $object)
e673ee24 2195 echo "<option value='${object['id']}'>${object['dname']}</option>";
e673ee24
DO
2196
2197 echo "</select></td><td><input type='text' name='bond_name' value='' size=10></td>";
2198 echo "<td><select name='bond_type'><option value='regular'>Regular</option><option value='virtual'>Virtual</option><option value='shared'>Shared</option></select></td>";
2199 echo "<td><input type='submit' value='Assign address'></td></form></tr>";
2200 echo "</table><br><br>";
2201
2202}
2203
2204function renderIPAddressPortForwarding ($object_id=0)
2205{
2206 global $pageno, $tabno, $root;
2207
2208 $info = getObjectInfo ($object_id);
2209 $forwards = getObjectForwards ($object_id);
2210 $addresses = getObjectAddresses ($object_id);
2211 showMessageOrError();
f28fbe8b 2212 echo "<center><h2>locally performed NAT</h2></center>";
e673ee24
DO
2213
2214 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
f28fbe8b 2215 echo "<tr><th></th><th>Match endpoint</th><th>Translate to</th><th>Target object</th><th>Comment</th></tr>\n";
e673ee24
DO
2216
2217 foreach ($forwards['out'] as $pf)
2218 {
24e85a1a 2219 $class='trerror';
e673ee24
DO
2220 $name='';
2221 foreach ($addresses as $addr)
2222 if ($addr['ip'] == $pf['localip'])
2223 {
2224 $class='';
2225 $name = $addr['name'];
2226 break;
2227 }
2228
2229 echo "<tr class='$class'>";
4de22e7e
DO
2230 echo "<td><a href='process.php?op=delPortForwarding&localip=${pf['localip']}&localport=${pf['localport']}&remoteip=${pf['remoteip']}&remoteport=${pf['remoteport']}&proto=${pf['proto_bin']}&object_id=$object_id&page=${pageno}&tab=${tabno}'>";
2231 printImageHREF ('delete', 'Delete NAT rule');
2232 echo "</a></td>";
f28fbe8b
DO
2233 echo "<td>${pf['proto']}/${name}: <a href='${root}?page=ipaddress&tab=default&ip=${pf['localip']}'>${pf['localip']}</a>:${pf['localport']}";
2234 if (!empty ($pf['local_addr_name']))
2235 echo ' (' . $pf['local_addr_name'] . ')';
2236 echo "</td>";
e673ee24
DO
2237 echo "<td><a href='${root}?page=ipaddress&tab=default&ip=${pf['remoteip']}'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
2238
2239 $address=getIPAddress($pf['remoteip']);
2240
2241 echo "<td class='description'>";
f28fbe8b
DO
2242 if (count ($address['bonds']))
2243 foreach($address['bonds'] as $bond)
2244 echo "<a href='${root}?page=object&tab=default&object_id=${bond['object_id']}'>${bond['object_name']}(${bond['name']})</a> ";
2245 elseif (!empty ($pf['remote_addr_name']))
2246 echo '(' . $pf['remote_addr_name'] . ')';
e673ee24
DO
2247 echo "</td><form action='process.php'><input type='hidden' name='op' value='updPortForwarding'><input type=hidden name=page value='${pageno}'><input type=hidden name=tab value='${tabno}'><input type='hidden' name='object_id' value='$object_id'><input type='hidden' name='localip' value='${pf['localip']}'><input type='hidden' name='localport' value='${pf['localport']}'><input type='hidden' name='remoteip' value='${pf['remoteip']}'><input type='hidden' name='remoteport' value='${pf['remoteport']}'><input type='hidden' name='proto' value='${pf['proto_bin']}'><td class='description'><input type='text' name='description' value='${pf['description']}'> <input type='submit' value='OK'></td></form>";
2248 echo "</tr>";
2249 }
2250 echo "<form action='process.php'><input type='hidden' name='op' value='forwardPorts'>";
2251 echo "<input type='hidden' name='object_id' value='$object_id'>";
2252 echo "<input type=hidden name=page value='${pageno}'>\n";
2253 echo "<input type=hidden name=tab value='${tabno}'>\n";
436605a7
DO
2254 echo "<tr align='center'><td colspan=2>";
2255 printSelect (readChapter ('Protocols'), 'proto');
52c3543f 2256 echo "<select name='localip' tabindex=1>";
e673ee24
DO
2257
2258 foreach ($addresses as $addr)
09992c16
DO
2259 echo "<option value='${addr['ip']}'>" . (empty ($addr['name']) ? '' : "${addr['name']}: ") .
2260 "${addr['ip']}" . (empty ($addr['address_name']) ? '' : " (${addr['address_name']})") . "</option>";
e673ee24 2261
52c3543f
DO
2262 echo "</select>:<input type='text' name='localport' size='4' tabindex=2></td>";
2263 echo "<td><input type='text' name='remoteip' id='remoteip' size='10' tabindex=3>";
4de22e7e
DO
2264 echo "<a href='javascript:;' onclick='window.open(\"${root}/find_object_ip_helper.php\", \"findobjectip\", \"height=700, width=400, location=no, menubar=no, resizable=yes, scrollbars=no, status=no, titlebar=no, toolbar=no\");'>";
2265 printImageHREF ('find', 'Find object');
2266 echo "</a>";
52c3543f
DO
2267 echo ":<input type='text' name='remoteport' size='4' tabindex=4></td><td></td>";
2268 echo "<td colspan=1><input type='text' name='description' size='20' tabindex=5> <input type='submit' value='Create Forwarding' tabindex=6></td></tr>";
e673ee24
DO
2269 echo "</form>";
2270
2271 echo "</table><br><br>";
2272
2273
f28fbe8b 2274 echo "<center><h2>arriving NAT connections</h2></center>";
e673ee24
DO
2275 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
2276 echo "<tr><th></th><th>Source</th><th>Source objects</th><th>Target</th><th>Description</th></tr>\n";
2277
2278 foreach ($forwards['in'] as $pf)
2279 {
2280 echo "<tr>";
2281
4de22e7e
DO
2282 echo "<td><a href='process.php?op=delPortForwarding&localip=${pf['localip']}&localport=${pf['localport']}&remoteip=${pf['remoteip']}&remoteport=${pf['remoteport']}&proto=${pf['proto_bin']}&object_id=${pf['object_id']}&page=${pageno}&tab=${tabno}'>";
2283 printImageHREF ('delete', 'Delete NAT rule');
2284 echo "</a></td>";
e673ee24
DO
2285 echo "<td>${pf['proto']}/<a href='${root}?page=ipaddress&tab=default&ip=${pf['localip']}'>${pf['localip']}</a>:${pf['localport']}</td>";
2286 echo "<td class='description'><a href='${root}?page=object&tab=default&object_id=${pf['object_id']}'>${pf['object_name']}</a>";
2287 echo "</td><td><a href='${root}?page=ipaddress&tab=default&ip=${pf['remoteip']}'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
2288 echo "<td class='description'>${pf['description']}</td></tr>";
2289 }
2290
2291// echo "<form action='process.php'><input type='hidden' name='op' value='forwardPorts'>";
2292// echo "<input type='hidden' name='object_id' value='$object_id'>";
2293// echo "<input type=hidden name=page value='${pageno}'>\n";
2294// echo "<input type=hidden name=tab value='${tabno}'>\n";
2295// echo "<tr align='center'><td colspan=2><select name='proto'><option value='1'>TCP</option><option value='2'>UDP</option><input type='text' name='localip' size='10'>:<input type='text' name='localport' size='4'></td><td><select name='localip'>";
2296// foreach ($addresses as $addr)
2297// echo "<option value='${addr['ip']}'>${addr['ip']}</option>";
2298//
2299// echo "</select>:<input type='text' name='remoteport' size='4'></td><td><input type='text' name='description' size='20'></td><td><input type='submit' value='Create Forwarding'></td></tr>";
2300// echo "</form>";
2301 echo "</table><br><br>";
2302
2303
2304}
2305
2306
2307function renderAddMultipleObjectsForm ()
2308{
20c901a7 2309 global $root, $pageno, $tabno, $nextorder;
e673ee24
DO
2310
2311 $type_id = array();
7f791d1d 2312 $global_type_id = 0;
e673ee24
DO
2313 $name = array();
2314 $asset_no = array();
2315 $keepvalues = FALSE;
7f791d1d 2316 $log = array();
e673ee24 2317 // Look for current submit.
7f791d1d 2318 if (isset ($_REQUEST['got_fast_data']))
e673ee24
DO
2319 {
2320 $keepvalues = TRUE;
9c0b0016
DO
2321 $max = getConfigVar ('MASSCOUNT');
2322 for ($i = 0; $i < $max; $i++)
e673ee24
DO
2323 {
2324 if (!isset ($_REQUEST["${i}_object_type_id"]))
2325 {
2326 $log[] = array ('code' => 'error', 'message' => "Submitted form is invalid at line " . $i + 1);
2327 break;
2328 }
2329 assertUIntArg ("${i}_object_type_id", TRUE);
2330 assertStringArg ("${i}_object_name", TRUE);
2331 assertStringArg ("${i}_object_label", TRUE);
2332 assertStringArg ("${i}_object_asset_no", TRUE);
2333 assertStringArg ("${i}_object_barcode", TRUE);
2334 $type_id[$i] = $_REQUEST["${i}_object_type_id"];
2335 // Save user input for possible rendering.
2336 $name[$i] = $_REQUEST["${i}_object_name"];
2337 $label[$i] = $_REQUEST["${i}_object_label"];
2338 $asset_no[$i] = $_REQUEST["${i}_object_asset_no"];
2339 $barcode[$i] = $_REQUEST["${i}_object_barcode"];
2340
2341 // It's better to skip silently than printing a notice.
2342 if ($type_id[$i] == 0)
2343 continue;
2344 if (commitAddObject ($name[$i], $label[$i], $barcode[$i], $type_id[$i], $asset_no[$i]) === TRUE)
2345 $log[] = array ('code' => 'success', 'message' => "Added new object '${name[$i]}'");
2346 else
4d2e93f2 2347 $log[] = array ('code' => 'error', 'message' => __FUNCTION__ . ': commitAddObject() failed');
e673ee24 2348 }
e673ee24 2349 }
7f791d1d
DO
2350 elseif (isset ($_REQUEST['got_very_fast_data']))
2351 {
2352 $keepvalues = TRUE;
2353 assertUIntArg ('global_type_id', TRUE);
2354 assertStringArg ('namelist', TRUE);
2355 $global_type_id = $_REQUEST['global_type_id'];
2356 if ($global_type_id == 0)
2357 {
2358 if (!empty ($_REQUEST['namelist']))
2359 $log[] = array ('code' => 'error', 'message' => 'Object type is not selected, check the form below');
2360 else
2361 $log[] = array ('code' => 'error', 'message' => 'Empty form has been ignored. Cheers.');
2362 }
2363 else
2364 {
2365 // The name extractor below was stolen from ophandlers.php:addMultiPorts()
2366 $names1 = explode ('\n', $_REQUEST['namelist']);
2367 $names2 = array();
2368 foreach ($names1 as $line)
2369 {
2370 $parts = explode ('\r', $line);
2371 reset ($parts);
2372 if (empty ($parts[0]))
2373 continue;
2374 else
2375 $names2[] = rtrim ($parts[0]);
2376 }
2377 foreach ($names2 as $cname)
2378 if (commitAddObject ($cname, '', '', $global_type_id, '') === TRUE)
2379 $log[] = array ('code' => 'success', 'message' => "Added new object '${cname}'");
2380 else
2381 $log[] = array ('code' => 'error', 'message' => "Could not add '${cname}'");
2382 }
2383 }
2384 printLog ($log);
e673ee24
DO
2385
2386 // Render a form for the next.
2387 $typelist = getObjectTypeList();
4c330a14 2388 $typelist[0] = 'select type...';
7f791d1d
DO
2389
2390 startPortlet ('Fast way');
20c901a7 2391 echo "<form name=fastform method=post action='${root}?page=${pageno}&tab=${tabno}'>";
e673ee24
DO
2392 echo '<table border=0 align=center>';
2393 echo "<tr><th>Object type</th><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>Barcode</th></tr>\n";
7f791d1d 2394 // If a user forgot to select object type on input, we keep his
e673ee24 2395 // previous input in the form.
9c0b0016
DO
2396 $max = getConfigVar ('MASSCOUNT');
2397 for ($i = 0; $i < $max; $i++)
e673ee24 2398 {
7f791d1d 2399 echo '<tr><td>';
e7ade6bf
DO
2400 // Don't employ DEFAULT_OBJECT_TYPE to avoid creating ghost records for pre-selected empty rows.
2401 printSelect ($typelist, "${i}_object_type_id", 0);
e673ee24
DO
2402 echo '</td>';
2403 echo "<td><input type=text size=30 name=${i}_object_name";
2404 if ($keepvalues and $type_id[$i] == 0)
2405 echo " value='${name[$i]}'";
2406 echo "></td>";
2407 echo "<td><input type=text size=30 name=${i}_object_label";
2408 if ($keepvalues and $type_id[$i] == 0)
2409 echo " value='${label[$i]}'";
2410 echo "></td>";
2411 echo "<td><input type=text size=20 name=${i}_object_asset_no";
2412 if ($keepvalues and $type_id[$i] == 0)
2413 echo " value='${asset_no[$i]}'";
2414 echo "></td>";
2415 echo "<td><input type=text size=10 name=${i}_object_barcode";
2416 if ($keepvalues and $type_id[$i] == 0)
2417 echo " value='${barcode[$i]}'";
2418 echo "></td>";
2419 echo "</tr>\n";
e673ee24 2420 }
7f791d1d 2421 echo "<tr><td class=submit colspan=5><input type=submit name=got_fast_data value='Create'></td></tr>\n";
e673ee24
DO
2422 echo "</form></table>\n";
2423 finishPortlet();
7f791d1d
DO
2424
2425 startPortlet ('Very fast way');
20c901a7 2426 echo "<form name=veryfastform method=post action='${root}?page=${pageno}&tab=${tabno}'>";
7f791d1d 2427 echo 'For each line shown below create an object of type ';
a477e405 2428 printSelect ($typelist, "global_type_id", getConfigVar ('DEFAULT_OBJECT_TYPE'));
7f791d1d
DO
2429 echo " <input type=submit name=got_very_fast_data value='Go!'><br>\n";
2430 echo "<textarea name=namelist cols=40 rows=25>\n";
2431 if ($keepvalues and $global_type_id == 0)
2432 echo $_REQUEST['namelist'];
2433 echo "</textarea></form>\n";
2434 finishPortlet();
e673ee24
DO
2435}
2436
2437function printGreeting ()
2438{
59cd003e 2439 global $remote_username, $accounts, $root;
e673ee24 2440 $account = $accounts[$remote_username];
4eb5efb7 2441 echo "Hello, ${account['user_realname']}. This is RackTables " . CODE_VERSION . ". Click <a href='${root}?logout'>here</a> to logout.";
e673ee24
DO
2442}
2443
2444function renderSearchResults ()
2445{
2446 global $remote_username, $root;
2447 $terms = trim ($_REQUEST['q']);
2448 if (empty ($terms))
2449 {
591ff2c4 2450 showError ('Search string cannot be empty.', __FUNCTION__);
e673ee24
DO
2451 return;
2452 }
2453 if (!authorized ($remote_username, 'object', 'default'))
2454 {
591ff2c4 2455 showError ('You are not authorized for viewing information about objects.', __FUNCTION__);
e673ee24
DO
2456 return;
2457 }
ea5fc465 2458 $nhits = 0;
e673ee24
DO
2459 // If we search for L2 address, we can either find one or find none.
2460 if
2461 (
2462 preg_match ('/^[0-9a-f][0-9a-f]?:[0-9a-f][0-9a-f]?:[0-9a-f][0-9a-f]?:[0-9a-f][0-9a-f]?:[0-9a-f][0-9a-f]?:[0-9a-f][0-9a-f]?$/i', $terms) or
2463 preg_match ('/^[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]$/i', $terms) or
ea5fc465
DO
2464 preg_match ('/^[0-9a-f][0-9a-f][0-9a-f][0-9a-f].[0-9a-f][0-9a-f][0-9a-f][0-9a-f].[0-9a-f][0-9a-f][0-9a-f][0-9a-f]$/i', $terms) or
2465 // STP bridge ID: bridge priotity + port MAC address. Cut off first 4 chars and look for MAC address.
2466 preg_match ('/^[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]$/i', $terms)
e673ee24
DO
2467 )
2468 // Search for L2 address.
2469 {
ea5fc465 2470 $terms = substr ($terms, -12);
e673ee24
DO
2471 $result = searchByl2address ($terms);
2472 if ($result !== NULL)
2473 {
ea5fc465
DO
2474 $nhits++;
2475 $lasthit = 'port';
2476 $summary['port'][] = $result;
e673ee24 2477 }
e673ee24
DO
2478 }
2479 elseif (preg_match ('/^[0-9][0-9]?[0-9]?\.[0-9]?[0-9]?[0-9]?\.[0-9][0-9]?[0-9]?\.[0-9]?[0-9]?[0-9]?$/i', $terms))
2480 // Search for IP address.
2481 {
2482 $result = getRangeByIp ($terms);
2483 if ($result !== NULL)
2484 {
ea5fc465 2485 $nhits++;
bc3ab23e 2486 $lasthit = 'ipv4address1';
ea5fc465 2487 $summary['ipv4address1'][] = $terms;
e673ee24 2488 }
e673ee24
DO
2489 }
2490 else
ea5fc465 2491 // Search for objects, addresses, networks, virtual services and RS pools by their description.
e673ee24 2492 {
ea5fc465
DO
2493 $tmp = getObjectSearchResults ($terms);
2494 if (count ($tmp))
e673ee24 2495 {
ea5fc465
DO
2496 $nhits += count ($tmp);
2497 $lasthit = 'object';
2498 $summary['object'] = $tmp;
e673ee24 2499 }
ea5fc465
DO
2500 $tmp = getIPv4AddressSearchResult ($terms);
2501 if (count ($tmp))
e673ee24 2502 {
ea5fc465
DO
2503 $nhits += count ($tmp);
2504 $lasthit = 'ipv4address2';
2505 $summary['ipv4address2'] = $tmp;
2506 }
2507 $tmp = getIPv4PrefixSearchResult ($terms);
2508 if (count ($tmp))
2509 {
2510 $nhits += count ($tmp);
2511 $lasthit = 'ipv4network';
2512 $summary['ipv4network'] = $tmp;
2513 }
2514 }
2515 if ($nhits == 0)
2516 echo "<center><h2>Nothing found for '${terms}'</h2></center>";
2517 elseif ($nhits == 1)
2518 {
2519 $record = current ($summary[$lasthit]);
2520 switch ($lasthit)
2521 {
2522 case 'port':
2523 echo "<script language='Javascript'>document.location='${root}?page=object";
2524 echo "&hl_port_id=" . $record['port_id'];
2525 echo "&object_id=" . $record['object_id'] . "';//</script>";
2526 break;
2527 case 'ipv4address1':
2528 echo "<script language='Javascript'>document.location='${root}?page=ipaddress";
2529 echo "&ip=${record}";
2530 echo "';//</script>";
2531 break;
2532 case 'ipv4address2':
2533 echo "<script language='Javascript'>document.location='${root}?page=ipaddress";
2534 echo "&ip=${record}";
2535 echo "';//</script>";
2536 break;
2537 case 'ipv4network':
2538 echo "<script language='Javascript'>document.location='${root}?page=iprange";
2539 echo "&id=${record['id']}";
2540 echo "';//</script>";
2541 break;
2542 case 'object':
2543 echo "<script language='Javascript'>document.location='${root}?page=object&object_id=${record['id']}';//</script>";
2544 break;
2545 }
2546 return;
2547 }
2548 else
2549 {
2550 global $nextorder;
2551 $order = 'odd';
2552 echo "<center><h2>${nhits} result(s) found for '${terms}'</h2></center>";
2553 foreach ($summary as $where => $what)
2554 switch ($where)
e673ee24 2555 {
ea5fc465
DO
2556 case 'object':
2557 startPortlet ('Objects');
2558 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
2559 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>barcode</th></tr>';
2560 foreach ($what as $obj)
2561 {
2562 echo "<tr class=row_${order}><td><a href=\"${root}?page=object&object_id=${obj['id']}\">${obj['dname']}</a></td>";
2563 echo "<td>${obj['label']}</td>";
2564 echo "<td>${obj['asset_no']}</td>";
2565 echo "<td>${obj['barcode']}</td></tr>";
2566 $order = $nextorder[$order];
2567 }
2568 echo '</table>';
2569 finishPortlet();
2570 break;
2571 case 'ipv4network':
2572 startPortlet ('IPv4 networks');
2573 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
2574 echo '<tr><th>Network</th><th>Descritpion</th></tr>';
2575 foreach ($what as $net)
2576 {
2577 echo "<tr class=row_${order}><td class=tdleft><a href='${root}?page=iprange&id=${net['id']}'>${net['ip']}";
2578 echo '/' . $net['mask'] . '</a></td>';
2579 echo "<td class=tdleft>${net['name']}</td></tr>";
2580 $order = $nextorder[$order];
2581 }
2582 echo '</table>';
2583 finishPortlet();
2584 break;
2585 case 'ipv4address2':
2586 startPortlet ('IPv4 addresses');
2587 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
2588 echo '<tr><th>Address</th><th>Descritpion</th></tr>';
2589 foreach ($what as $addr)
2590 {
2591 echo "<tr class=row_${order}><td class=tdleft><a href='${root}?page=ipaddress&id=${addr['ip']}'>";
2592 echo "${addr['ip']}</a></td>";
2593 echo "<td class=tdleft>${addr['name']}</td></tr>";
2594 $order = $nextorder[$order];
2595 }
2596 echo '</table>';
2597 finishPortlet();
2598 break;
e673ee24 2599 }
e673ee24
DO
2600 }
2601}
2602
2603// This function prints a table of checkboxes to aid the user in toggling mount atoms
2604// from one state to another. The first argument is rack data as
2605// produced by getRackData(), the second is the value used for the 'unckecked' state
2606// and the third is the value used for 'checked' state.
2607// Usage contexts:
2608// for mounting an object: printAtomGrid ($data, 'F', 'T')
2609// for changing rack design: printAtomGrid ($data, 'A', 'F')
2610// for adding rack problem: printAtomGrid ($data, 'F', 'U')
2611// for adding object problem: printAtomGrid ($data, 'T', 'W')
2612
2613function renderAtomGrid ($data)
2614{
2615 $rack_id = $data['id'];
2616 for ($unit_no = $data['height']; $unit_no > 0; $unit_no--)
2617 {
2618 echo "<tr><th>${unit_no}</th>";
2619 for ($locidx = 0; $locidx < 3; $locidx++)
2620 {
2621 $state = $data[$unit_no][$locidx]['state'];
2622 echo "<td class=state_${state}";
2623 if (isset ($data[$unit_no][$locidx]['hl']))
2624 echo $data[$unit_no][$locidx]['hl'];
2625 echo ">";
2626 if (!($data[$unit_no][$locidx]['enabled'] === TRUE))
2627 echo '<input type=checkbox disabled>';
2628 else
2629 echo "<input type=checkbox" . $data[$unit_no][$locidx]['checked'] . " name=atom_${rack_id}_${unit_no}_${locidx}>";
2630 echo '</td>';
2631 }
2632 echo "</tr>\n";
2633 }
2634}
2635
2636function renderPermissions ()
2637{
2638 startPortlet ('User permissions');
2639 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
2640 echo "<tr><th>Username</th><th>Page</th><th>Tab</th><th>Access</th></tr>";
2641 global $perms, $nextorder;
2642 $order = 'odd';
2643 foreach ($perms as $username => $pages)
2644 foreach ($pages as $page => $tabs)
2645 foreach ($tabs as $tab => $access)
2646 {
2647 echo "<tr class=row_${order}><td class=tdleft>$username</td><td>$page</td><td>$tab</td><td>$access</td></tr>\n";
2648 $order = $nextorder[$order];
2649 }
2650 echo "</table>\n";
2651 finishPortlet();
2652}
2653
2654function renderAccounts ()
2655{
2656 global $nextorder, $accounts;
2657 startPortlet ('User accounts');
2658 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
2659 echo "<tr><th class=tdleft>Username</th><th class=tdleft>Real name</th></tr>";
2660 $order = 'odd';
2661 foreach ($accounts as $user)
2662 {
20c901a7
DO
2663 echo "<tr class=row_${order}><td class=tdleft><div title='\$userid_${user['user_id']}'>";
2664 echo "${user['user_name']}</div></td>";
2665 echo "<td class=tdleft>${user['user_realname']}</td></li>";
e673ee24
DO
2666 $order = $nextorder[$order];
2667 }
2668 echo '</table>';
2669 finishPortlet();
2670}
2671
2672function renderAccountsEditForm ()
2673{
2674 global $root, $pageno, $tabno, $accounts;
2675 startPortlet ('User accounts');
2676 showMessageOrError();
2677 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
2678 echo "<tr><th>op</th><th>Username</th><th>Real name</th><th>Password</th><th>&nbsp;</th></tr>\n";
2679 foreach ($accounts as $account)
2680 {
2681 echo "<form action='${root}process.php'>";
2682 echo "<input type=hidden name=op value=updateAccount>";
2683 echo "<input type=hidden name=page value='${pageno}'>\n";
2684 echo "<input type=hidden name=tab value='${tabno}'>\n";
2685 echo "<input type=hidden name=id value='${account['user_id']}'><tr>";
2686 echo "<td>";
2687 if ($account['user_enabled'] == 'yes' && $account['user_id'] != 1)
2688 {
2689 echo "<a href='${root}process.php?op=disableAccount&page=${pageno}&tab=${tabno}&id=${account['user_id']}'>";
2690 printImageHREF ('blockuser', 'disable account');
2691 echo "</a>\n";
2692 }
2693 if ($account['user_enabled'] == 'no' && $account['user_id'] != 1)
2694 {
2695 echo "<a href='${root}process.php?op=enableAccount&page=${pageno}&tab=${tabno}&id=${account['user_id']}'>";
2696 printImageHREF ('unblockuser', 'enable account');
2697 echo "</a>\n";
2698 }
2699 // Otherwise skip icon.
2700 echo "</td>";
2701 echo "<td><input type=text name=username value='${account['user_name']}' size=16></td>";
2702 echo "<td><input type=text name=realname value='${account['user_realname']}' size=24></td>";
2703 echo "<td><input type=password name=password value='${account['user_password_hash']}' size=64></td>";
2704 echo "<td><input type='submit' value='OK'></td>";
2705 echo "</form></tr>\n";
2706 }
2707 echo "<form action='${root}process.php' method=post><tr>";
2708 echo "<input type=hidden name=op value=createAccount>\n";
2709 echo "<input type=hidden name=page value='${pageno}'>\n";
2710 echo "<input type=hidden name=tab value='${tabno}'>\n";
2711 echo "<td colspan=2><input type=text size=16 name=username tabindex=100></td>\n";
2712 echo "<td><input type=text size=24 name=realname tabindex=101></td>";
2713 echo "<td><input type=password size=64 name=password tabindex=102></td>";
2714 echo "<td colspan=4><input type=submit value='Create account' tabindex=103></td></tr></form>";
2715 echo "</table><br>\n";
2716 finishPortlet();
2717}
2718
2719function printChildrenAsOptions ($root, $depth = 0)
2720{
2721 echo "<option value=${root['title']}>";
2722 if ($depth == 0)
2723 echo '* ';
2724 for ($i = 0; $i < $depth; $i++)
2725 echo '-- ';
2726 echo $root['title'];
2727 echo "</option>\n";
2728 foreach ($root['kids'] as $kid)
2729 printChildrenAsOptions ($kid, $depth + 1);
2730}
2731
2732// 1. Find all parentless pages.
2733// 2. For each of them recursively find all children.
2734// 3. Output the tree with recursion tree display.
2735function printPagesTree ()
2736{
2737 global $page;
2738 echo '<pre>';
2739 foreach ($page as $ctitle => $cpage)
2740 if (!isset ($cpage['parent']))
2741 {
2742 $croot['title'] = $ctitle;
2743 $croot['kids'] = getAllChildPages ($ctitle);
2744 printChildrenAsOptions ($croot);
2745 }
2746 echo '</pre>';
2747}
2748
2749function renderPermissionsEditForm ()
2750{
2751 global $root, $pageno, $tabno, $perms, $accounts;
2752 startPortlet ('User permissions');
2753 showMessageOrError();
2754 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
2755 echo "<tr><th>&nbsp;</th><th>Username</th><th>Page</th><th>Tab</th><th>Access</th></tr>\n";
2756 foreach ($perms as $username => $pages)
2757 foreach ($pages as $access_page => $tabs)
2758 foreach ($tabs as $access_tab => $access)
2759 {
2760 echo "<td>";
2761 if ($username != '%')
2762 $userid = $accounts[$username]['user_id'];
2763 else
2764 $userid = 0;
2765 echo "<a href='${root}process.php?op=revoke&page=${pageno}&tab=${tabno}&access_userid=${userid}&access_page=${access_page}&access_tab=${access_tab}'>";
2766 printImageHREF ('revoke', 'Revoke permission');
2767 echo "</a></td>";
2768 echo "<td>${username}</td>";
2769 echo "<td>${access_page}</td>";
2770 echo "<td>${access_tab}</td>";
2771 echo "<td>${access}</td>";
2772 echo "</tr>\n";
2773 }
2774 echo "<form action='${root}process.php' method=post><tr>";
2775 echo "<input type=hidden name=op value=grant>\n";
2776 echo "<input type=hidden name=page value='${pageno}'>\n";
2777 echo "<input type=hidden name=tab value='${tabno}'>\n";
2778 // FIXME: border=0 doesn't work here for unknown reason
2779 echo "<td>";
a5ae8c2a 2780 printImageHREF ('grant', '', TRUE, 103);
e673ee24
DO
2781 echo "</td>";
2782 echo "<td><select name=access_userid>";
2783 echo "<option value=0>ANY</option>";
2784 foreach ($accounts as $account)
2785 echo "<option value=${account['user_id']}>${account['user_name']}</option>";
2786 echo "</select></td>\n";
2787 echo "<td><select name=access_page>";
2788 echo "<option value='%'>ANY</option>";
2789 printPagesTree();
2790 echo "</select></td>";
2791 echo "<td><input type=text size=16 name=access_tab tabindex=102 value=default></td>";
2792 echo "<td><input type=radio name=access_value value=no checked>no <input type=radio name=access_value value=yes>yes</td>";
2793 echo "</tr></form>";
2794 echo "</table><br>\n";
2795 finishPortlet();
2796}
2797
17c32f4c
DO
2798function renderPortMapViewer ()
2799{
2800 renderPortMap (FALSE);
2801}
2802
2803function renderPortMapEditor ()
2804{
2805 renderPortMap (TRUE);
2806}
2807
e673ee24
DO
2808function renderPortMap ($editable = FALSE)
2809{
2810 global $nextorder, $root, $pageno, $tabno;
2811 showMessageOrError();
2812 startPortlet ("Port compatibility map");
2813 $ptlist = getPortTypes();
2814 $pclist = getPortCompat();
2815 $pctable = buildPortCompatMatrixFromList ($ptlist, $pclist);
2816 if ($editable)
2817 {
2818 echo "<form method=post action='${root}process.php'>";
2819 echo "<input type=hidden name=page value='${pageno}'>";
2820 echo "<input type=hidden name=tab value='${tabno}'>";
2821 echo "<input type=hidden name=op value=save>";
2822 }
2823 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
2824 echo "<tr><th class=vert_th>&nbsp;</th>";
2825 foreach ($ptlist as $name2)
2826 echo "<th>to ${name2}</th>";
2827 echo "</tr>";
2828 // Make a copy to have an independent array pointer.
2829 $ptlistY = $ptlist;
2830 $order = 'odd';
2831 foreach ($ptlistY as $type1 => $name1)
2832 {
2833 echo "<tr class=row_${order}><th class=vert_th style='border-bottom: 0px;'>from $name1</th>";
2834 foreach ($ptlist as $type2 => $name2)
2835 {
2836 echo '<td><input type=checkbox' . ($editable ? " name=atom_${type1}_${type2}" : ' disabled');
2837 echo ($pctable[$type1][$type2] ? ' checked' : '') . '></td>';
2838 }
2839 echo "</tr>\n";
2840 $order = $nextorder[$order];
2841 }
2842 echo '</table><br>';
2843 if ($editable)
2844 {
2845 echo "<input type=submit value='Save changes'>";
2846 echo "</form>";
2847 }
2848 finishPortlet();
2849}
2850
2851function renderConfigMainpage ()
2852{
2853 global $pageno, $root;
2854 $children = getDirectChildPages ($pageno);
2855 echo '<ul>';
27ef67da
DO
2856 // FIXME: assume all config kids to have static titles at the moment,
2857 // but use some proper abstract function later.
e673ee24 2858 foreach ($children as $cpageno => $child)
27ef67da 2859 echo "<li><a href='${root}?page=${cpageno}'>" . $child['title'] . "</li>\n";
e673ee24
DO
2860 echo '';
2861 echo '</ul>';
2862}
2863
2864function renderRackPage ($rack_id)
2865{
2866 if ($rack_id == 0)
2867 {
591ff2c4 2868 showError ('Invalid rack_id', __FUNCTION__);
e673ee24
DO
2869 return;
2870 }
2871 if (($rackData = getRackData ($rack_id)) == NULL)
2872 {
591ff2c4 2873 showError ('getRackData() failed', __FUNCTION__);
e673ee24
DO
2874 return;
2875 }
2876 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0><tr>";
2877
2878 // Left column with information.
2879 echo "<td class=pcleft>";
2880 startPortlet ('Rack information');
2881 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
2882 echo "<tr><th width='50%' class=tdright>Rack row:</th><td class=tdleft>${rackData['row_name']}</td></tr>\n";
2883 echo "<tr><th width='50%' class=tdright>Name:</th><td class=tdleft>${rackData['name']}</td></tr>\n";
2884 echo "<tr><th width='50%' class=tdright>Height:</th><td class=tdleft>${rackData['height']}</td></tr>\n";
8a1b387d 2885 echo "<tr><th width='50%' class=tdright>Utilization:</th><td class=tdleft>";
11df133a 2886 renderProgressBar (getRSUforRack ($rackData));
8a1b387d 2887 echo "</td></tr>\n";
f1a0477d
DO
2888 echo "<tr><th width='50%' class=tdright>Objects:</th><td class=tdleft>";
2889 echo getObjectCount ($rackData);
2890 echo "</td></tr>\n";
41bd8c87 2891 printTagTRs();
e673ee24
DO
2892 if (!empty ($rackData['comment']))
2893 echo "<tr><th width='50%' class=tdright>Comment:</th><td class=tdleft>${rackData['comment']}</td></tr>\n";
2894 echo '</table>';
2895 finishPortlet();
2896 echo '</td>';
2897
2898 // Right column with rendered rack.
2899 echo '<td>';
2900 startPortlet ('Rack diagram');
2901 renderRack ($rack_id);
2902 finishPortlet();
2903 echo '</td>';
2904
2905 echo '</tr></table>';
2906}
2907
2908function renderDictionary ()
2909{
2910 global $nextorder;
2dd59b15 2911 $dict = getDict (TRUE);
aa28ebdf 2912 echo "<br><table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
aa28ebdf
DO
2913 foreach ($dict as $chapter_no => $chapter)
2914 {
a22ec5b4 2915 $order = 'odd';
83d2fcca 2916 echo "<tr><th>Chapter</th><th>refs</th><th>Word</th></tr>\n";
aa28ebdf
DO
2917 $wc = count ($chapter['word']);
2918 echo "<tr class=row_${order}><td class=tdleft" . ($wc ? " rowspan = ${wc}" : '');
2919 echo "><div title='number=${chapter_no}'>${chapter['name']} (${wc} records)</div></td>";
2920 if (!$wc)
2921 echo "<td colspan=2>none</td>";
2922 else
e673ee24 2923 {
aa28ebdf
DO
2924 $chap_start = TRUE;
2925 foreach ($chapter['word'] as $key => $value)
2926 {
2927 if (!$chap_start)
2928 echo "<tr class=row_${order}>";
2929 else
2930 $chap_start = FALSE;
6bb8e41d
DO
2931 echo '<td>' . ($chapter['refcnt'][$key] ? $chapter['refcnt'][$key] : '&nbsp;') . '</td>';
2932 echo "<td><div title='key=${key}'>${value}</div></td></tr>\n";
aa28ebdf
DO
2933 $order = $nextorder[$order];
2934 }
e673ee24 2935 }
e673ee24 2936 }
2dd59b15 2937 echo "</table>\n<br>";
e673ee24
DO
2938}
2939
2940function renderDictionaryEditor ()
2941{
f632bd28 2942 global $root, $pageno, $tabno, $nextorder;
e673ee24 2943 $dict = getDict();
95d80773 2944 showMessageOrError();
f632bd28
DO
2945 echo "<br><table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
2946 foreach ($dict as $chapter_no => $chapter)
e673ee24 2947 {
f632bd28 2948 $order = 'odd';
b2f9fa84 2949 echo "<tr><th>Chapter</th><th>&nbsp;</th><th>Word</th><th>&nbsp;</th></tr>\n";
f632bd28
DO
2950 $wc = count ($chapter['word']);
2951 // One extra span for the new record per each chapter block.
2952 echo "<tr class=row_${order}><td class=tdleft" . ($wc ? ' rowspan = ' . ($wc + 1) : '');
2953 echo "><div title='number=${chapter_no}'>${chapter['name']} (${wc} records)</div></td>";
2954 echo "<form action='${root}process.php' method=post>";
2955 echo "<input type=hidden name=page value='${pageno}'>";
2956 echo "<input type=hidden name=tab value='${tabno}'>";
2957 echo "<input type=hidden name=op value=add>";
2958 echo "<input type=hidden name=chapter_no value='${chapter['no']}'>";
2959 echo "<td>&nbsp;</td>";
2960 echo "<td class=tdright><input type=text name=dict_value size=32></td>";
95d80773 2961 echo "<td><input type=submit value='Add new'></td>";
f632bd28 2962 echo '</tr></form>';
b2f9fa84 2963 $order = $nextorder[$order];
e673ee24
DO
2964 foreach ($chapter['word'] as $key => $value)
2965 {
2966 echo "<form action='${root}process.php' method=post>";
2967 echo "<input type=hidden name=page value='${pageno}'>";
2968 echo "<input type=hidden name=tab value='${tabno}'>";
2969 echo "<input type=hidden name=op value='upd'>";
2970 echo "<input type=hidden name=chapter_no value='${chapter['no']}'>";
2971 echo "<input type=hidden name=dict_key value='${key}'>";
95d80773 2972 echo "<tr class=row_${order}><td>";
f632bd28
DO
2973 // Prevent deleting words currently used somewhere.
2974 if ($chapter['refcnt'][$key])
b2f9fa84 2975 printImageHREF ('nodelete', 'referenced ' . $chapter['refcnt'][$key] . ' time(s)');
f632bd28
DO
2976 else
2977 {
2978 echo "<a href='${root}process.php?page=${pageno}&tab=${tabno}&op=del&chapter_no=${chapter['no']}&dict_key=${key}'>";
2979 printImageHREF ('delete', 'Delete word');
2980 echo "</a>";
2981 }
2982 echo '</td>';
e673ee24
DO
2983 echo "<td class=tdright><input type=text name=dict_value size=32 value='${value}'></td>";
2984 echo "<td><input type=submit value=OK></td>";
f632bd28
DO
2985 echo "</tr></form>\n";
2986 $order = $nextorder[$order];
2987 } // foreach ($chapter['word']
2988 } // foreach ($dict
2989 echo "</table>\n";
e673ee24
DO
2990}
2991
2992// We don't allow to rename/delete a sticky chapter and we don't allow
2993// to delete a non-empty chapter.
2994function renderChaptersEditor ()
2995{
2996 global $root, $pageno, $tabno;
2997 showMessageOrError();
2998 $dict = getDict();
2999 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
3000 echo '<tr><th>&nbsp;</th><th>Chapter name</th><th>Words</th><th>&nbsp;</th></tr>';
3001 foreach ($dict as $chapter)
3002 {
3003 $wordcount = count ($chapter['word']);
3004 $sticky = $chapter['sticky'];
3005 echo "<form action='${root}process.php' method=post>";
3006 echo "<input type=hidden name=page value='${pageno}'>";
3007 echo "<input type=hidden name=tab value='${tabno}'>";
3008 echo "<input type=hidden name=op value=upd>";
3009 echo "<input type=hidden name=chapter_no value='${chapter['no']}'>";
3010 echo '<tr>';
3011 echo '<td>';
0c4605ab
DO
3012 if ($sticky)
3013 printImageHREF ('nodelete', 'system chapter');
3014 elseif ($wordcount > 0)
3015 printImageHREF ('nodelete', 'contains ' . $wordcount . ' word(s)');
e673ee24
DO
3016 else
3017 {
3018 echo "<a href='${root}process.php?page=${pageno}&tab=${tabno}&op=del&chapter_no=${chapter['no']}'>";
3019 printImageHREF ('delete', 'Remove chapter');
3020 echo "</a>";
3021 }
3022 echo '</td>';
3023 echo "<td><input type=text name=chapter_name value='${chapter['name']}'" . ($sticky ? ' disabled' : '') . "></td>";
3024 echo "<td class=tdleft>${wordcount}</td><td>";
3025 if ($sticky)
3026 echo '&nbsp;';
3027 else
3028 echo "<input type=submit value='OK'>";
3029 echo '</td></tr>';
3030 echo '</form>';
3031 }
3032 echo "<form action='${root}process.php' method=post>";
3033 echo "<input type=hidden name=page value='${pageno}'>";
3034 echo "<input type=hidden name=tab value='${tabno}'>";
3035 echo "<input type=hidden name=op value=add>";
3036 echo '<tr><td>';
a5ae8c2a 3037 printImageHREF ('add', '', TRUE);
e673ee24
DO
3038 echo "</td><td colspan=3><input type=text name=chapter_name></td>";
3039 echo '</tr>';
3040 echo '</form>';
3041 echo "</table>\n";
3042}
3043
3044function renderAttributes ()
3045{
3046 global $nextorder;
3047 $attrMap = getAttrMap();
3048 startPortlet ('Optional attributes');
3049 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
3050 echo "<tr><th class=tdleft>Attribute name</th><th class=tdleft>Attribute type</th><th class=tdleft>Applies to</th></tr>";
3051 $order = 'odd';
3052 foreach ($attrMap as $attr)
3053 {
3054 echo "<tr class=row_${order}>";
3055 echo "<td class=tdleft>${attr['name']}</td>";
3056 echo "<td class=tdleft>${attr['type']}</td>";
3057 echo '<td class=tdleft>';
3058 if (count ($attr['application']) == 0)
3059 echo '&nbsp;';
3060 else
3061 foreach ($attr['application'] as $app)
3062 if ($attr['type'] == 'dict')
3063 echo "${app['objtype_name']} (values from '${app['chapter_name']}')<br>";
3064 else
3065 echo "${app['objtype_name']}<br>";
3066 echo '</td>';
3067 echo "</tr>\n";
3068 $order = $nextorder[$order];
3069 }
3070 echo "</table><br>\n";
3071 finishPortlet();
3072}
3073
3074function renderEditAttributesForm ()
3075{
3076 global $root, $pageno, $tabno;
3077 $attrMap = getAttrMap();
3078 showMessageOrError();
3079 startPortlet ('Optional attributes');
3080 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
3081 echo '<tr><th>&nbsp;</th><th>Name</th><th>Type</th><th>&nbsp;</th></tr>';
3082 foreach ($attrMap as $attr)
3083 {
3084 echo "<form action='${root}process.php' method=post>";
3085 echo "<input type=hidden name=page value='${pageno}'>";
3086 echo "<input type=hidden name=tab value='${tabno}'>";
3087 echo "<input type=hidden name=op value=upd>";
3088 echo "<input type=hidden name=attr_id value='${attr['id']}'>";
3089 echo '<tr>';
3090 echo "<td><a href='${root}process.php?page=${pageno}&tab=${tabno}&op=del&attr_id=${attr['id']}'>";
3091 printImageHREF ('delete', 'Remove attribute');
3092 echo '</a></td>';
3093 echo "<td><input type=text name=attr_name value='${attr['name']}'></td>";
3094 echo "<td>${attr['type']}</td>";
3095 echo "<td><input type=submit value='OK'></td>";
3096 echo '</tr>';
3097 echo '</form>';
3098 }
3099 echo "<form action='${root}process.php' method=post>";
3100 echo "<input type=hidden name=page value='${pageno}'>";
3101 echo "<input type=hidden name=tab value='${tabno}'>";
3102 echo "<input type=hidden name=op value=add>";
3103 echo '<tr><td>';
a5ae8c2a 3104 printImageHREF ('add', '', TRUE);
e673ee24
DO
3105 echo "</td><td><input type=text name=attr_name></td>";
3106 echo '<td><select name=attr_type>';
3107 echo '<option value=uint>uint</option>';
3108 echo '<option value=float>float</option>';
3109 echo '<option value=string>string</option>';
3110 echo '<option value=dict>dict</option>';
3111 echo '</select></td>';
3112 echo '</tr>';
3113 echo '</form>';
3114 echo "</table>\n";
3115 finishPortlet();
3116}
3117
3118function renderEditAttrMapForm ()
3119{
3120 global $root, $pageno, $tabno;
3121 $attrMap = getAttrMap();
3122 showMessageOrError();
3123 startPortlet ('Attribute map');
3124 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
3125 echo '<tr><th>&nbsp;</th><th>Attribute name</th><th>Object type</th><th>Dictionary chapter</th></tr>';
3126 foreach ($attrMap as $attr)
3127 {
3128 if (count ($attr['application']) == 0)
3129 continue;
3130 foreach ($attr['application'] as $app)
3131 {
3132 echo '<tr>';
3133 echo '<td>';
3134 echo "<a href='${root}process.php?page=${pageno}&tab=${tabno}&op=del&";
3135 echo "attr_id=${attr['id']}&objtype_id=${app['objtype_id']}'>";
3136 printImageHREF ('delete', 'Remove mapping');
3137 echo "</a>";
3138 echo '</td>';
3139 echo "<td>${attr['name']}</td>";
3140 echo "<td>${app['objtype_name']}</td>";
3141 echo "<td>";
3142 if ($attr['type'] == 'dict')
3143 echo "${app['chapter_name']}";
3144 else
3145 echo '&nbsp;';
3146 echo "</td></tr>\n";
3147 }
3148 }
3149 echo "<form action='${root}process.php' method=post>";
3150 echo "<input type=hidden name=page value='${pageno}'>";
3151 echo "<input type=hidden name=tab value='${tabno}'>";
3152 echo "<input type=hidden name=op value=add>";
3153 echo '<tr><td>';
a5ae8c2a 3154 printImageHREF ('add', '', TRUE);
e673ee24
DO
3155 echo "</td><td><select name=attr_id>";
3156 $shortType['uint'] = 'U';
3157 $shortType['float'] = 'F';
3158 $shortType['string'] = 'S';
3159 $shortType['dict'] = 'D';
3160 foreach ($attrMap as $attr)
3161 echo "<option value=${attr['id']}>[" . $shortType[$attr['type']] . "] ${attr['name']}</option>";
3162 echo "</select></td>";
3163 echo '<td>';
3164 printSelect (getObjectTypeList(), 'objtype_id');
3165 echo '</td>';
3166 $dict = getDict();
3167 echo '<td><select name=chapter_no>';
3168 foreach ($dict as $chapter)
3169 if (!$chapter['sticky'])
3170 echo "<option value='${chapter['no']}'>${chapter['name']}</option>";
3171 echo '</select></td>';
3172 echo '</tr>';
3173 echo '</form>';
3174 echo "</table>\n";
3175 finishPortlet();
3176}
3177
a5ae8c2a 3178function printImageHREF ($tag, $title = '', $do_input = FALSE, $tabindex = 0)
e673ee24 3179{
a5ae8c2a
DO
3180 global $root;
3181 $image['error']['path'] = 'pix/error.png';
3182 $image['error']['width'] = 76;
3183 $image['error']['height'] = 17;
a5ae8c2a
DO
3184 $image['logo']['path'] = 'pix/defaultlogo.png';
3185 $image['logo']['width'] = 210;
3186 $image['logo']['height'] = 40;
3187 $image['rackspace']['path'] = 'pix/racks.png';
3188 $image['rackspace']['width'] = 218;
3189 $image['rackspace']['height'] = 200;
3190 $image['objects']['path'] = 'pix/server.png';
3191 $image['objects']['width'] = 218;
3192 $image['objects']['height'] = 200;
3193 $image['ipv4space']['path'] = 'pix/addressspace.png';
3194 $image['ipv4space']['width'] = 218;
3195 $image['ipv4space']['height'] = 200;
f973f491
DO
3196 $image['ipv4slb']['path'] = 'pix/slb.png';
3197 $image['ipv4slb']['width'] = 218;
3198 $image['ipv4slb']['height'] = 200;
a5ae8c2a
DO
3199 $image['config']['path'] = 'pix/configuration.png';
3200 $image['config']['width'] = 218;
3201 $image['config']['height'] = 200;
3202 $image['reports']['path'] = 'pix/report.png';
3203 $image['reports']['width'] = 218;
3204 $image['reports']['height'] = 200;
a5ae8c2a
DO
3205 $image['reserve']['path'] = 'pix/stop.png';
3206 $image['reserve']['width'] = 16;
3207 $image['reserve']['height'] = 16;
3208 $image['useup']['path'] = 'pix/go.png';
3209 $image['useup']['width'] = 16;
3210 $image['useup']['height'] = 16;
3211 $image['blockuser'] = $image['reserve'];
3212 $image['unblockuser'] = $image['useup'];
3213 $image['link']['path'] = 'pix/link.png';
3214 $image['link']['width'] = 24;
3215 $image['link']['height'] = 24;
3216 $image['unlink']['path'] = 'pix/unlink.png';
3217 $image['unlink']['width'] = 24;
3218 $image['unlink']['height'] = 24;
3219 $image['add']['path'] = 'pix/greenplus.png';
3220 $image['add']['width'] = 16;
3221 $image['add']['height'] = 16;
3222 $image['delete']['path'] = 'pix/delete_s.gif';
3223 $image['delete']['width'] = 16;
3224 $image['delete']['height'] = 16;
0c4605ab
DO
3225 $image['nodelete']['path'] = 'pix/delete_g.png';
3226 $image['nodelete']['width'] = 16;
3227 $image['nodelete']['height'] = 16;
a5ae8c2a
DO
3228 $image['grant'] = $image['add'];
3229 $image['revoke'] = $image['delete'];
1f7d18fa
DO
3230 $image['inservice']['path'] = 'pix/go.png';
3231 $image['inservice']['width'] = 16;
3232 $image['inservice']['height'] = 16;
3233 $image['notinservice']['path'] = 'pix/stop.png';
3234 $image['notinservice']['width'] = 16;
3235 $image['notinservice']['height'] = 16;
4de22e7e
DO
3236 $image['find']['path'] = 'pix/find.png';
3237 $image['find']['width'] = 16;
3238 $image['find']['height'] = 16;
b39e7545
DO
3239 $image['spacer']['path'] = 'pix/pixel.png';
3240 $image['spacer']['width'] = 16;
3241 $image['spacer']['height'] = 16;
e673ee24
DO
3242 if (!isset ($image[$tag]))
3243 $tag = 'error';
3244 $img = $image[$tag];
a5ae8c2a
DO
3245 if ($do_input == TRUE)
3246 echo
3247 "<input type=image name=submit " .
3248 "src='${root}${img['path']}' " .
3249 "border=0 " .
3250 ($tabindex ? '' : "tabindex=${tabindex}") .
3251 ">";
3252 else
3253 echo
3254 "<img " .
3255 "src='${root}${img['path']}' " .
3256 "width=${img['width']} " .
3257 "height=${img['height']} " .
3258 "border=0 " .
3259 (empty ($title) ? '' : "title='${title}'") .
3260 ">";
e673ee24
DO
3261}
3262
3263// This function returns URL for favourite icon.
3264function getFaviconURL ()
3265{
46100c70
DO
3266 global $root;
3267 return $root . 'pix/racktables.ico';
e673ee24
DO
3268}
3269
3270function renderReportSummary ()
3271{
da95280e
DO
3272 echo "<table width='100%'>\n";
3273 echo "<tr><td class=pcleft>\n";
08b4cb24 3274 startPortlet ("Dictionary/objects stats");
da95280e
DO
3275 echo "<table>\n";
3276 foreach (getDictStats() as $header => $data)
7e233246 3277 echo "<tr><th class=tdright>${header}:</th><td class=tdleft>${data}</td></tr>\n";
8948cd63
DO
3278 echo "</table>\n";
3279 finishPortlet();
3280 startPortlet ('IPv4 stats');
3281 echo "<table>\n";
3282 foreach (getIPv4Stats() as $header => $data)
3283 echo "<tr><th class=tdright>${header}:</th><td class=tdleft>${data}</td></tr>\n";
3284 echo "</table>\n";
3285 finishPortlet();
3286 startPortlet ('Rackspace stats');
3287 echo "<table>\n";
3288 foreach (getRackspaceStats() as $header => $data)
3289 echo "<tr><th class=tdright>${header}:</th><td class=tdleft>${data}</td></tr>\n";
da95280e
DO
3290 echo "</table>\n";
3291 finishPortlet();
3292
3293 echo "</td><td class=pcright>\n";
3294
c461c579
DO
3295 startPortlet ("Here be dragons");
3296 dragon();
3297 dragon();
3298 dragon();
3299 echo 'ASCII art &copy; Daniel C. Au';
3300 finishPortlet();
da95280e
DO
3301 echo "</td></tr>\n";
3302 echo "</table>\n";
c461c579
DO
3303}
3304
3305function dragon ()
3306{
3307?>
3308<div class=dragon><pre><font color="#00ff33">
3309 \||/
3310 | <font color="#ff0000">@</font>___oo
3311 /\ /\ / (__<font color=yellow>,,,,</font>|
3312 ) /^\) ^\/ _)
3313 ) /^\/ _)
3314 ) _ / / _)
3315 /\ )/\/ || | )_)
3316 &lt; &gt; |(<font color=white>,,</font>) )__)
3317 || / \)___)\
3318 | \____( )___) )___
3319 \______(_______<font color=white>;;;</font> __<font color=white>;;;</font>
3320
3321</font></pre></div>
3322<?php
e673ee24
DO
3323}
3324
3325function renderUIConfig ()
3326{
4fe32e78
DY
3327 global $configCache, $nextorder;
3328 showMessageOrError();
0a1b1268 3329 startPortlet ('Current configuration');
c461c579
DO
3330 echo '<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center width="50%">';
3331 echo '<tr><th class=tdleft>Option</th><th class=tdleft>Value</th></tr>';
4fe32e78 3332 $order = 'odd';
0a1b1268 3333 foreach ($configCache as $v)
4fe32e78 3334 {
c461c579
DO
3335 if ($v['is_hidden'] != 'no')
3336 continue;
3337 echo "<tr class=row_${order}>";
3338 echo "<td class=tdright>${v['description']}</td>\n";
3339 echo "<td class=tdleft>${v['varvalue']}</td></tr>";
3340 $order = $nextorder[$order];
4fe32e78 3341 }
0a1b1268
DO
3342 echo "</table>\n";
3343 finishPortlet();
7865c525
DO
3344}
3345
4fe32e78
DY
3346function renderUIConfigEditForm ()
3347{
c461c579 3348 global $root, $pageno, $tabno, $configCache;
4fe32e78
DY
3349 showMessageOrError();
3350 startPortlet ('Current configuration');
c461c579
DO
3351 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable width='50%'>\n";
3352 echo "<tr><th class=tdleft>Option</th>";
3353 echo "<th class=tdleft>Value</th></tr>";
4fe32e78
DY
3354 echo "<form action='${root}process.php'>";
3355 echo "<input type=hidden name=op value='upd'>";
c461c579
DO
3356 echo "<input type=hidden name=page value='${pageno}'>\n";
3357 echo "<input type=hidden name=tab value='${tabno}'>\n";
4fe32e78
DY
3358
3359 $i = 0;
3360 foreach ($configCache as $v)
3361 {
c461c579
DO
3362 if ($v['is_hidden'] != 'no')
3363 continue;
3364 echo "<input type=hidden name=${i}_varname value='${v['varname']}'>";
3365 echo "<tr><td class=tdright>${v['description']}</td>";
3366 echo "<td class=tdleft><input type=text name=${i}_varvalue value='${v['varvalue']}' size=24></td>";
3367 echo "</tr>\n";
3368 $i++;
4fe32e78
DY
3369 }
3370 echo "<input type=hidden name=num_vars value=${i}>\n";
c461c579 3371 echo "<tr><td colspan=2><input type=submit value='Save changes'></td></tr>";
4fe32e78
DY
3372 echo "</form>";
3373 finishPortlet();
3374}
3375
7865c525
DO
3376// This function queries the gateway about current VLAN configuration and
3377// renders a form suitable for submit. Ah, and it does submit processing as well.
111b4a67
DO
3378function renderVLANMembership ($object_id = 0)
3379{
fc8d0004 3380 global $root, $pageno, $tabno, $remote_username;
111b4a67
DO
3381 if ($object_id <= 0)
3382 {
591ff2c4 3383 showError ('Invalid object_id', __FUNCTION__);
111b4a67
DO
3384 return;
3385 }
7865c525
DO
3386
3387 // Handle probable pending submit.
3388 if (isset ($_REQUEST['portcount']))
111b4a67 3389 {
7865c525
DO
3390 $data = getSwitchVLANs ($object_id);
3391 if ($data === NULL)
2da7c9b0 3392 {
591ff2c4 3393 showError ('getSwitchVLANs() failed during submit processing', __FUNCTION__);
fc8d0004
DO
3394 return;
3395 }
7865c525
DO
3396 list ($vlanlist, $portlist) = $data;
3397 // Here we just build up 1 set command for the gateway with all of the ports
3398 // included. The gateway is expected to filter unnecessary changes silently
3399 // and to provide a list of responses with either error or success message
3400 // for each of the rest.
3401 assertUIntArg ('portcount');
3402 $nports = $_REQUEST['portcount'];
3403 $prefix = 'set ';
3404 $log = array();
3405 $setcmd = '';
3406 for ($i = 0; $i < $nports; $i++)
3407 if
3408 (
3409 !isset ($_REQUEST['portname_' . $i]) ||
3410 !isset ($_REQUEST['vlanid_' . $i]) ||
3411 $_REQUEST['portname_' . $i] != $portlist[$i]['portname']
3412 )
cd40a2a0 3413 $log[] = array ('code' => 'error', 'message' => "Ignoring malformed record #${i} in form submit");
7865c525
DO
3414 elseif
3415 (
3416 $_REQUEST['vlanid_' . $i] == $portlist[$i]['vlanid'] ||
3417 $portlist[$i]['vlaind'] == 'TRUNK'
3418 )
3419 continue;
3420 else
3421 {
3422 $setcmd .= $prefix . $_REQUEST['portname_' . $i] . '=' . $_REQUEST['vlanid_' . $i];
3423 $prefix = ';';
3424 }
3425 printLog ($log);
3426 // Feed the gateway and interpret its (non)response.
3427 if ($setcmd != '')
3428 printLog (setSwitchVLANs ($object_id, $setcmd));
3429 }
3430
3431 // Reload and render.
3432 $data = getSwitchVLANs ($object_id);
3433 if ($data === NULL)
3434 return;
18cb9495 3435 list ($vlanlist, $portlist, $maclist) = $data;
d28ea105 3436
a684aa6f 3437 echo '<table border=0 width="100%"><tr><td colspan=3>';
d28ea105 3438
2b9e0abd 3439 startPortlet ('Current status');
18cb9495 3440 echo "<table class=widetable cellspacing=3 cellpadding=5 align=center width='100%'><tr>";
7865c525
DO
3441 echo "<form method=post>";
3442 echo "<input type=hidden name=page value='${pageno}'>";
3443 echo "<input type=hidden name=tab value='${tabno}'>";
3444 echo "<input type=hidden name=object_id value=${object_id}>";
0d591525
DO
3445 $portcount = count ($portlist);
3446 echo "<input type=hidden name=portcount value=" . $portcount . ">\n";
7865c525 3447 $portno = 0;
9c0b0016 3448 $ports_per_row = getConfigVar ('PORTS_PER_ROW');
7865c525
DO
3449 foreach ($portlist as $port)
3450 {
3451 // Don't let wide forms break our fancy pages.
9c0b0016 3452 if ($portno % $ports_per_row == 0)
fc8d0004 3453 {
7865c525
DO
3454 if ($portno > 0)
3455 echo "</tr>\n";
0d591525 3456 echo "<tr><th>" . ($portno + 1) . "-" . ($portno + $ports_per_row > $portcount ? $portcount : $portno + $ports_per_row) . "</th>";
fc8d0004 3457 }
18cb9495
DO
3458 echo '<td class=port_';
3459 if ($port['status'] == 'notconnect')
3460 echo 'notconnect';
2b9e0abd
DO
3461 elseif ($port['status'] == 'disabled')
3462 echo 'disabled';
18cb9495
DO
3463 elseif ($port['status'] != 'connected')
3464 echo 'unknown';
3465 elseif (!isset ($maclist[$port['portname']]))
3466 echo 'connected_none';
3467 else
3468 {
3469 $maccount = 0;
3470 foreach ($maclist[$port['portname']] as $vlanid => $addrs)
3471 $maccount += count ($addrs);
3472 if ($maccount == 1)
3473 echo 'connected_single';
3474 else
3475 echo 'connected_multi';
3476 }
3477 echo '>' . $port['portname'] . '<br>';
7865c525
DO
3478 echo "<input type=hidden name=portname_${portno} value=" . $port['portname'] . '>';
3479 if ($port['vlanid'] == 'trunk')
fc8d0004 3480 {
7865c525
DO
3481 echo "<input type=hidden name=vlanid_${portno} value='trunk'>";
3482 echo "<select disabled multiple='multiple' size=1><option>TRUNK</option></select>";
fc8d0004 3483 }
7865c525 3484 else
fc8d0004 3485 {
7865c525 3486 echo "<select name=vlanid_${portno}>";
8c7a0e37
DO
3487 // A port may belong to a VLAN, which is absent from the VLAN table, this is normal.
3488 // We must be able to render its SELECT properly at least.
3489 $in_table = FALSE;
d28ea105 3490 foreach ($vlanlist as $v => $d)
fc8d0004 3491 {
7865c525
DO
3492 echo "<option value=${v}";
3493 if ($v == $port['vlanid'])
8c7a0e37 3494 {
7865c525 3495 echo ' selected';
8c7a0e37
DO
3496 $in_table = TRUE;
3497 }
3498 echo ">${v}</option>\n";
fc8d0004 3499 }
8c7a0e37
DO
3500 if (!$in_table)
3501 echo "<option value=${port['vlanid']} selected>${port['vlanid']}</option>\n";
7865c525 3502 echo "</select>";
fc8d0004 3503 }
7865c525
DO
3504 $portno++;
3505 echo "</td>";
111b4a67 3506 }
9c0b0016 3507 echo "</tr><tr><td colspan=" . ($ports_per_row + 1) . "><input type=submit value='Save changes'></form></td></tr></table>";
7865c525 3508 finishPortlet();
d28ea105 3509
a684aa6f
DO
3510 echo '</td></tr><tr><td class=pcleft>';
3511 startPortlet ('VLAN table');
3512 echo '<table class=cooltable cellspacing=0 cellpadding=5 align=center width="100%">';
3513 echo "<tr><th>ID</th><th>Description</th></tr>";
3514 $order = 'even';
3515 global $nextorder;
3516 foreach ($vlanlist as $id => $descr)
3517 {
3518 echo "<tr class=row_${order}><td class=tdright>${id}</td><td class=tdleft>${descr}</td></tr>";
3519 $order = $nextorder[$order];
3520 }
3521 echo '</table>';
3522 finishPortlet();
3523
3524 echo '</td><td class=pcright>';
3525
3526 startPortlet ('Color legend');
3527 echo '<table>';
3528 echo "<tr><th>port state</th><th>color code</th></tr>";
3529 echo "<tr><td>not connected</td><td class=port_notconnect>SAMPLE</td></tr>";
3530 echo "<tr><td>disabled</td><td class=port_disabled>SAMPLE</td></tr>";
3531 echo "<tr><td>unknown</td><td class=port_unknown>SAMPLE</td></tr>";
3532 echo "<tr><td>connected with none MAC addresses active</td><td class=port_connected_none>SAMPLE</td></tr>";
3533 echo "<tr><td>connected with 1 MAC addresses active</td><td class=port_connected_single>SAMPLE</td></tr>";
3534 echo "<tr><td>connected with 1+ MAC addresses active</td><td class=port_connected_multi>SAMPLE</td></tr>";
3535 echo '</table>';
3536 finishPortlet();
3537
3538 echo '</td><td class=pcright>';
3539
18cb9495
DO
3540 if (count ($maclist))
3541 {
3542 startPortlet ('MAC address table');
3543 echo '<table border=0 class=cooltable align=center cellspacing=0 cellpadding=5>';
3544 echo "<tr><th>Port</th><th>VLAN ID</th><th>MAC address</th></tr>\n";
3545 $order = 'even';
3546 foreach ($maclist as $portname => $portdata)
3547 foreach ($portdata as $vlanid => $addrgroup)
3548 foreach ($addrgroup as $addr)
3549 {
818a43a2
DO
3550 echo "<tr class=row_${order}><td class=tdleft>$portname</td><td class=tdleft>$vlanid</td>";
3551 echo "<td class=tdleft>$addr</td></tr>\n";
18cb9495
DO
3552 $order = $nextorder[$order];
3553 }
3554 echo '</table>';
3555 finishPortlet();
3556 }
3557
18cb9495
DO
3558 // End of main table.
3559 echo '</td></tr></table>';
111b4a67
DO
3560}
3561
9c67f713
DO
3562// This snippet either renders a form inviting the user to start SNMP query
3563// on the current device or displays the result of the scan.
3564function renderSNMPPortFinder ($object_id = 0)
3565{
3566 global $root, $pageno, $tabno, $remote_username;
3567 if ($object_id <= 0)
3568 {
591ff2c4 3569 showError ('Invalid object_id', __FUNCTION__);
9c67f713
DO
3570 return;
3571 }
dd9afc41 3572// FIXME: check if SNMP PHP extension is available!
9c67f713
DO
3573 if (isset ($_REQUEST['do_scan']))
3574 {
dd9afc41 3575 $log = array();
1c4d54d4
DO
3576// IDs: http://cisco.com/en/US/products/sw/cscowork/ps2064/products_device_support_table09186a0080803bb4.html
3577// 2960: http://www.cisco.com/en/US/products/ps6406/prod_models_comparison.html
65813f73 3578// 2970: http://cisco.com/en/US/products/hw/switches/ps5206/products_qanda_item09186a00801b1750.shtml
563196e8 3579// 3500XL: http://cisco.com/en/US/products/hw/switches/ps637/products_eol_models.html
1c4d54d4 3580// 3560: http://cisco.com/en/US/products/hw/switches/ps5528/products_data_sheet09186a00801f3d7f.html
563196e8 3581// 3750: http://cisco.com/en/US/products/hw/switches/ps5023/products_data_sheet09186a008016136f.html
137b7a50 3582 $ciscomodel[283] = 'WS-C6509-E (9-slot system)';
818e40c7
DO
3583// FIXME: hwtype hardcoded value will become invalid after the Dictionary table transformation
3584// in 0.14.7 version. Either the values will have to be adjusted as well or we have to switch
3585// to value lookup (not reliable).
64d5f2b4 3586 $hwtype[283] = 148;
dd9afc41
DO
3587# $ciscomodel[694] = 'WS-C2960-24TC-L (24 Ethernet 10/100 ports and 2 dual-purpose uplinks)';
3588# $ciscomodel[695] = 'WS-C2960-48TC-L (48 Ethernet 10/100 ports and 2 dual-purpose uplinks)';
3589 $ciscomodel[696] = 'WS-C2960G-24TC-L (20 Ethernet 10/100/1000 ports and 4 dual-purpose uplinks)';
64d5f2b4 3590 $hwtype[696] = 167;
dd9afc41 3591 $ciscomodel[697] = 'WS-C2960G-48TC-L (44 Ethernet 10/100/1000 ports and 4 dual-purpose uplinks)';
64d5f2b4 3592 $hwtype[697] = 166;
dd9afc41
DO
3593# $ciscomodel[716] = 'WS-C2960-24TT-L (24 Ethernet 10/100 ports and 2 10/100/1000 uplinks)';
3594# $ciscomodel[717] = 'WS-C2960-48TT-L (48 Ethernet 10/100 ports and 2 10/100/1000 uplinks)';
65813f73 3595 $ciscomodel[527] = 'WS-C2970G-24T (24 Ethernet 10/100/1000 ports)';
64d5f2b4 3596 $hwtype[527] = 210;
65813f73
DO
3597 $ciscomodel[561] = 'WS-C2970G-24TS (24 Ethernet 10/100/1000 ports and 4 10/100/1000 SFP uplinks)';
3598 $hwtype[561] = 115;
137b7a50 3599# $ciscomodel[633] = 'WS-C3560-24TS (24 Ethernet 10/100 ports and 2 10/100/1000 SFP uplinks)';
64d5f2b4 3600# $hwtype[633] = 169;
137b7a50 3601 $ciscomodel[634] = 'WS-C3560-48TS (48 Ethernet 10/100 ports and 4 10/100/1000 SFP uplinks)';
64d5f2b4 3602 $hwtype[634] = 170;
137b7a50 3603# $ciscomodel[563] = 'WS-C3560-24PS (24 Ethernet 10/100 POE ports and 2 10/100/1000 SFP uplinks)';
64d5f2b4 3604# $hwtype[563] = 171;
137b7a50 3605 $ciscomodel[564] = 'WS-C3560-48PS (48 Ethernet 10/100 POE ports and 4 10/100/1000 SFP uplinks)';
64d5f2b4 3606 $hwtype[564] = 172;
1c4d54d4 3607 $ciscomodel[614] = 'WS-C3560G-24PS (24 Ethernet 10/100/1000 POE ports and 4 10/100/1000 SFP uplinks)';
64d5f2b4 3608 $hwtype[614] = 175;
1c4d54d4 3609 $ciscomodel[615] = 'WS-C3560G-24TS (24 Ethernet 10/100/1000 ports and 4 10/100/1000 SFP uplinks)';
64d5f2b4 3610 $hwtype[615] = 173;
1c4d54d4 3611 $ciscomodel[616] = 'WS-C3560G-48PS (48 Ethernet 10/100/1000 POE ports and 4 10/100/1000 SFP uplinks)';
64d5f2b4 3612 $hwtype[616] = 176;
1c4d54d4 3613 $ciscomodel[617] = 'WS-C3560G-48TS (48 Ethernet 10/100/1000 ports and 4 10/100/1000 SFP uplinks)';
64d5f2b4 3614 $hwtype[617] = 174;
7a9f3034 3615 $ciscomodel[58] = 'WS-C4503 (3-slot system)';
64d5f2b4 3616 $hwtype[58] = 145;
7a9f3034 3617 $ciscomodel[503] = '4503 (3-slot system)';
64d5f2b4 3618 $hwtype[503] = 145;
7a9f3034 3619 $ciscomodel[59] = 'WS-C4506 (6-slot system)';
64d5f2b4 3620 $hwtype[59] = 156;
7a9f3034