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