4 * This file contains frontend functions for RackTables.
8 // Interface function's special.
9 $nextorder['odd'] = 'even';
10 $nextorder['even'] = 'odd';
13 function renderIndex ()
17 <table border
=0 cellpadding
=0 cellspacing
=0 width
='100%'>
20 <div style
='text-align: center; margin: 10px; '>
21 <table width
='100%' cellspacing
=0 cellpadding
=30 class=mainmenu border
=0>
24 <h1
><a href
='<?php echo $root; ?>?page=rackspace'>Rackspace
<br
>
25 <?php
printImageHREF ('rackspace'); ?
></a
></h1
>
28 <h1
><a href
='<?php echo $root; ?>?page=objects'>Objects
<br
>
29 <?php
printImageHREF ('objects'); ?
></a
></h1
>
32 <h1
><a href
='<?php echo $root; ?>?page=ipv4space'>IPv4 space
<br
>
33 <?php
printImageHREF ('ipv4space'); ?
></a
></h1
>
37 <table width
='100%' cellspacing
=0 cellpadding
=30 class=mainmenu border
=0>
40 <h1
><a href
='<?php echo $root; ?>?page=config'>Configuration
<br
>
41 <?php
printImageHREF ('config'); ?
></a
></h1
>
44 <h1
><a href
='<?php echo $root; ?>?page=reports'>Reports
<br
>
45 <?php
printImageHREF ('reports'); ?
></a
></h1
>
48 <h1
><a href
='<?php echo $root; ?>?page=ipv4slb'>IPv4 SLB
<br
>
49 <?php
printImageHREF ('ipv4slb'); ?
></a
></h1
>
60 function renderRackspace ()
63 <table border
=0 cellpadding
=10 cellpadding
=1>
65 // generate thumb gallery
66 $rackrowList = getRackRowInfo();
67 global $root, $nextorder;
68 $rackwidth = getConfigVar ('rtwidth_0') +
getConfigVar ('rtwidth_1') +
getConfigVar ('rtwidth_2');
70 foreach ($rackrowList as $rackrow)
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)
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'";
81 echo "src='render_image.php?img=minirack&rack_id=${rack['id']}'>";
82 echo "<br>${rack['name']}</a></td>";
84 echo "</tr></table></tr>\n";
85 $order = $nextorder[$order];
90 function renderRow ($row_id)
94 showError ('Invalid row_id', __FUNCTION__
);
97 if (($rowInfo = getRackRowInfo ($row_id)) == NULL)
99 showError ('getRackRowInfo() failed', __FUNCTION__
);
102 $rackList = getRacksForRow ($row_id);
103 // Main layout starts.
104 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
106 // Left portlet with row information.
107 echo "<tr><td class=pcleft>";
108 startPortlet ($rowInfo['dict_value']);
109 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
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";
112 echo "<tr><th width='50%' class=tdright>Utilization:</th><td class=tdleft>";
113 renderProgressBar (getRSUforRackRow ($rackList));
115 echo "</table><br>\n";
118 echo "</td><td class=pcright>";
120 global $root, $nextorder;
121 $rackwidth = getConfigVar ('rtwidth_0') +
getConfigVar ('rtwidth_1') +
getConfigVar ('rtwidth_2');
123 startPortlet ('Racks');
124 echo "<table border=0 cellspacing=5 align='center'><tr>";
125 foreach ($rackList as $dummy => $rack)
127 echo "<td align=center class=row_${order}><a href='${root}?page=rack&rack_id=${rack['id']}'>";
128 echo "<img border=0 width=" . $rackwidth * getConfigVar ('ROW_SCALE') . " height=";
129 echo (3 +
3 +
$rack['height'] * 2) * getConfigVar ('ROW_SCALE');
130 echo " title='${rack['height']} units'";
131 echo "src='render_image.php?img=minirack&rack_id=${rack['id']}'>";
132 echo "<br>${rack['name']}</a></td>";
133 $order = $nextorder[$order];
135 echo "</tr></table>\n";
138 echo "</td></tr></table>";
141 function showError ($info = '', $funcname = 'N/A')
144 echo "<div class=msg_error>An error has occured in function [${funcname}]. ";
146 echo 'No additional information is available.';
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";
152 // This function renders rack as HTML table.
153 function renderRack ($rack_id = 0, $hl_obj_id = 0)
157 showError ('Invalid rack_id', __FUNCTION__
);
160 if (($rackData = getRackData ($rack_id)) == NULL)
162 showError ('getRackData() failed', __FUNCTION__
);
165 global $root, $pageno, $tabno;
166 markAllSpans ($rackData);
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}'>< < <</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}'>> > ></a>";
180 if ($rackData['left_is_front'] == 'yes')
181 $markup = array ('left' => 'Front', 'right' => 'Back');
183 $markup = array ('left' => 'Back', 'right' => 'Front');
184 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
185 echo "<tr><th width='10%'> </th><th width='20%'>${markup['left']}</th>";
186 echo "<th width='50%'>Interior</th><th width='20%'>${markup['right']}</th></tr>\n";
187 for ($i = $rackData['height']; $i > 0; $i--)
189 echo '<tr><th>' . ($rackData['bottom_is_unit1'] == 'yes' ?
$i : $rackData['height'] - $i +
1) . '</th>';
190 for ($locidx = 0; $locidx < 3; $locidx++
)
192 if (isset ($rackData[$i][$locidx]['skipped']))
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'];
206 $objectData = getObjectInfo ($rackData[$i][$locidx]['object_id']);
207 if (!empty ($objectData['asset_no']))
208 $prefix = "<div title='${objectData['asset_no']}";
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']}\"'>";
216 echo $prefix . $suffix;
217 echo "<a href='${root}?page=object&object_id=${objectData['id']}'>${objectData['dname']}</a></div>";
220 echo '<div title="This rackspace does not exist"> </div>';
223 echo '<div title="Free rackspace"> </div>';
226 echo '<div title="Problematic rackspace, you CAN\'T mount here"> </div>';
229 echo '<div title="No data"> </div>';
236 echo "</table></center>\n";
239 function renderNewObjectForm ()
241 global $pageno, $tabno;
243 // Look for current submit.
244 if (isset ($_REQUEST['got_data']))
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'];
258 if (commitAddObject ($name, $label, $barcode, $type_id, $asset_no) === TRUE)
259 $log[] = array ('code' => 'success', 'message' => "Added new object '${name}'");
261 $log[] = array ('code' => 'error', 'message' => __FUNCTION__
. ': commitAddObject() failed');
265 // Render a form for the next.
266 startPortlet ('Object attributes');
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>";
272 printSelect (getObjectTypeList(), 'object_type_id');
274 echo "<tr><th class=tdright>Common name:</th><td class=tdleft><input type=text name=object_name></td></tr>\n";
275 echo "<tr><th class=tdright>Visible label:</th><td class=tdleft><input type=text name=object_label></td></tr>\n";
276 echo "<tr><th class=tdright>Asset tag:</th><td class=tdleft><input type=text name=object_asset_no></td></tr>\n";
277 echo "<tr><th class=tdright>Barcode:</th><td class=tdleft><input type=text name=object_barcode></td></tr>\n";
278 echo "<tr><td class=submit colspan=2><input type=submit name=got_data value='Create'></td></tr>\n";
279 echo '</form></table>';
283 function renderNewRackForm ($row_id)
285 global $pageno, $tabno;
287 // Look for current submit.
288 if (isset ($_REQUEST['got_data']))
291 assertStringArg ('rack_name');
292 assertUIntArg ('rack_height');
293 assertStringArg ('rack_comment', TRUE);
294 $name = $_REQUEST['rack_name'];
295 $height = $_REQUEST['rack_height'];
296 $comment = $_REQUEST['rack_comment'];
298 if (commitAddRack ($name, $height, $row_id, $comment) === TRUE)
299 $log[] = array ('code' => 'success', 'message' => "Added new rack '${name}'");
301 $log[] = array ('code' => 'error', 'message' => __FUNCTION__
. 'commitAddRack() failed');
305 // Render a form for the next.
306 startPortlet ('Rack attributes');
308 echo "<input type=hidden name=page value=${pageno}>";
309 echo "<input type=hidden name=tab value=${tabno}>";
310 echo "<input type=hidden name=row_id value=${row_id}>";
311 echo '<table border=0 align=center>';
312 $defh = getConfigVar ('DEFAULT_RACK_HEIGHT');
315 echo "<tr><th class=tdright>Name (required):</th><td class=tdleft><input type=text name=rack_name tabindex=1></td></tr>\n";
316 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";
317 echo "<tr><th class=tdright>Comment:</th><td class=tdleft><input type=text name=rack_comment tabindex=3></td></tr>\n";
318 echo "<tr><td class=submit colspan=2><input type=submit name=got_data value='Create'></td></tr>\n";
319 echo '</form></table>';
323 function renderEditObjectForm ($object_id)
325 showMessageOrError();
327 if (isset ($_REQUEST['got_data']))
330 // object_id is already verified by page handler
331 assertUIntArg ('object_type_id');
332 assertStringArg ('object_name', TRUE);
333 assertStringArg ('object_label', TRUE);
334 assertStringArg ('object_barcode', TRUE);
335 assertStringArg ('object_asset_no', TRUE);
336 $type_id = $_REQUEST['object_type_id'];
337 if (isset ($_REQUEST['object_has_problems']) and $_REQUEST['object_has_problems'] == 'on')
338 $has_problems = 'yes';
340 $has_problems = 'no';
341 $name = $_REQUEST['object_name'];
342 $label = $_REQUEST['object_label'];
343 $barcode = $_REQUEST['object_barcode'];
344 $asset_no = $_REQUEST['object_asset_no'];
345 $comment = $_REQUEST['object_comment'];
347 if (commitUpdateObject ($object_id, $name, $label, $barcode, $type_id, $has_problems, $asset_no, $comment) === TRUE)
348 $log[] = array ('code' => 'success', 'message' => "Updated object '${name}'");
350 $log[] = array ('code' => 'error', 'message' => __FUNCTION__
. ': commitUpdateObject() failed');
351 // Invalidate thumb cache of all racks objects could occupy.
352 foreach (getResidentRacksData ($object_id, FALSE) as $rack_id)
353 resetThumbCache ($rack_id);
357 global $pageno, $tabno;
358 $object = getObjectInfo ($object_id);
361 showError ('getObjectInfo() failed', __FUNCTION__
);
365 // Render a form for the next submit;
366 echo '<table border=0 width=100%><tr>';
368 echo '<td class=pcleft>';
369 startPortlet ('Static attributes');
370 echo '<form method=post>';
371 echo "<input type=hidden name=page value=${pageno}>";
372 echo "<input type=hidden name=tab value=${tabno}>";
373 echo "<input type=hidden name=object_id value=${object_id}>";
374 echo '<table border=0 align=center>';
375 echo "<tr><th class=tdright>Type:</th><td class=tdleft>";
376 printSelect (getObjectTypeList(), 'object_type_id', $object['objtype_id']);
378 // Common attributes.
379 echo "<tr><th class=tdright>Common name:</th><td class=tdleft><input type=text name=object_name value='${object['name']}'></td></tr>\n";
380 echo "<tr><th class=tdright>Visible label:</th><td class=tdleft><input type=text name=object_label value='${object['label']}'></td></tr>\n";
381 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";
382 echo "<tr><th class=tdright>Barcode:</th><td class=tdleft><input type=text name=object_barcode value='${object['barcode']}'></td></tr>\n";
383 echo "<tr><th class=tdright>Has problems:</th><td class=tdleft><input type=checkbox name=object_has_problems";
384 if ($object['has_problems'] == 'yes')
386 echo "></td></tr>\n";
387 echo "<tr><td colspan=2><b>Comment:</b><br><textarea name=object_comment rows=10 cols=80>${object['comment']}</textarea></td></tr>";
388 echo "<tr><th class=submit colspan=2><input type=submit name=got_data value='Update'></td></tr>\n";
389 echo '</form></table><br>';
393 // Optional attributes.
394 echo '<td class=pcright>';
395 startPortlet ('Optional attributes');
396 $values = getAttrValues ($object_id);
398 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
399 echo "<tr><th> </th><th>Attribute</th><th>Value</th><th> </th></tr>\n";
400 echo "<form method=post action='${root}process.php'>\n";
401 echo "<input type=hidden name=page value=${pageno}>\n";
402 echo "<input type=hidden name=tab value=${tabno}>\n";
403 echo "<input type=hidden name=op value=upd>\n";
404 echo "<input type=hidden name=object_id value=${object_id}>\n";
405 echo '<input type=hidden name=num_attrs value=' . count($values) . ">\n";
408 foreach ($values as $record)
410 echo "<input type=hidden name=${i}_attr_id value=${record['id']}>";
412 if (!empty ($record['value']))
414 echo "<a href=${root}process.php?page=${pageno}&tab=${tabno}&op=del&object_id=${object_id}&attr_id=${record['id']}>";
415 printImageHREF ('delete', 'Delete value');
419 printImageHREF ('nodelete', 'Already empty');
421 echo "<td class=tdright>${record['name']}:</td><td class=tdleft>";
422 switch ($record['type'])
427 echo "<input type=text name=${i}_value value='${record['value']}'>";
430 $chapter = readChapter ($record['chapter_name']);
431 $chapter[0] = '-- NOT SET --';
432 printSelect ($chapter, "${i}_value", $record['key']);
438 echo "<tr><td colspan=3><input type=submit value='Update'></td></tr>\n";
446 echo '<td colspan=2>';
447 startPortlet ('history');
448 renderHistory ($pageno, $object_id);
452 echo '</tr></table>';
455 // This is a clone of renderEditObjectForm().
456 function renderEditRackForm ($rack_id)
459 if (isset ($_REQUEST['got_data']))
462 assertUIntArg ('rack_row_id');
463 assertUIntArg ('rack_height');
464 assertStringArg ('rack_name');
465 assertStringArg ('rack_comment', TRUE);
466 $row_id = $_REQUEST['rack_row_id'];
467 $height = $_REQUEST['rack_height'];
468 $name = $_REQUEST['rack_name'];
469 $comment = $_REQUEST['rack_comment'];
471 if (commitUpdateRack ($rack_id, $name, $height, $row_id, $comment) === TRUE)
472 $log[] = array ('code' => 'success', 'message' => "Updated rack '${name}'");
474 $log[] = array ('code' => 'error', 'message' => __FUNCTION__
. ': commitUpdateRack() failed');
475 resetThumbCache ($rack_id);
479 global $pageno, $tabno;
480 $rack = getRackData ($rack_id);
483 showError ('getRackData() failed', __FUNCTION__
);
487 // Render a form for the next.
488 startPortlet ('Rack attributes');
490 echo "<input type=hidden name=page value=${pageno}>";
491 echo "<input type=hidden name=tab value=${tabno}>";
492 echo "<input type=hidden name=rack_id value=${rack_id}>";
493 echo '<table border=0 align=center>';
494 echo "<tr><th class=tdright>Rack row:</th><td class=tdleft>";
495 printSelect (readChapter ('RackRow'), 'rack_row_id', $rack['row_id']);
497 echo "<tr><th class=tdright>Name (required):</th><td class=tdleft><input type=text name=rack_name value='${rack['name']}'></td></tr>\n";
498 echo "<tr><th class=tdright>Height (required):</th><td class=tdleft><input type=text name=rack_height value='${rack['height']}'></td></tr>\n";
499 echo "<tr><th class=tdright>Comment:</th><td class=tdleft><input type=text name=rack_comment value='${rack['comment']}'></td></tr>\n";
500 echo "<tr><td class=submit colspan=2><input type=submit name=got_data value='Update'></td></tr>\n";
501 echo '</form></table><br>';
504 startPortlet ('History');
505 renderHistory ($pageno, $rack_id);
509 // This is a helper for creators and editors.
510 function printSelect ($rowList, $select_name, $selected_id = 1)
512 echo "<select name=${select_name}>";
513 foreach ($rowList as $dict_key => $dict_value)
515 echo "<option value=${dict_key}";
516 if ($dict_key == $selected_id)
518 echo ">${dict_value}</option>";
523 // This is a universal editor of rack design/waste.
524 function renderGridForm ($rack_id = 0, $filter, $header, $submit, $state1, $state2)
528 showError ('Invalid rack_id', __FUNCTION__
);
531 if (($rackData = getRackData ($rack_id)) == NULL)
533 showError ('getRackData() failed', __FUNCTION__
);
537 global $root, $pageno, $tabno;
539 markupObjectProblems ($rackData);
541 // Process form submit.
542 if (isset ($_REQUEST['do_update']))
544 $log[] = processGridForm ($rackData, $state1, $state2);
548 // Render the result whatever it is.
550 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
551 echo "<tr><td colspan=2 align=center><h1>${rackData['name']}</h1></td></tr>\n";
553 // Left column with information portlet.
554 echo "<tr><td class=pcleft height='1%' width='50%'>";
555 startPortlet ('Rack information');
556 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
557 echo "<tr><th width='50%' class=tdright>Rack name:</th><td class=tdleft>${rackData['name']}</td></tr>\n";
558 echo "<tr><th width='50%' class=tdright>Height:</th><td class=tdleft>${rackData['height']}</td></tr>\n";
559 echo "<tr><th width='50%' class=tdright>Rack row:</th><td class=tdleft>${rackData['row_name']}</td></tr>\n";
560 echo "<tr><th width='50%' class=tdright>Comment:</th><td class=tdleft>${rackData['comment']}</td></tr>\n";
565 echo "<td class=pcright>";
568 startPortlet ($header);
570 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
571 echo "<tr><th width='10%'> </th><th width='20%'>Front</th>";
572 echo "<th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
573 echo "<form method=post action='${root}?'>\n";
574 echo "<input type=hidden name=page value=${pageno}>\n";
575 echo "<input type=hidden name=tab value=${tabno}>\n";
576 echo "<input type=hidden name=rack_id value=${rack_id}>\n";
577 markupAtomGrid ($rackData, $state2);
578 renderAtomGrid ($rackData);
579 echo "</table></center>\n";
580 echo "<br><input type=submit name=do_update value='${submit}'></form><br><br>\n";
582 echo "</td></tr></table>\n";
585 function renderRackDesign ($rack_id)
587 renderGridForm ($rack_id, 'applyRackDesignMask', 'Rack design', 'Set rack design', 'A', 'F');
590 function renderRackProblems ($rack_id = 0)
592 renderGridForm ($rack_id, 'applyRackProblemMask', 'Rack problems', 'Mark unusable atoms', 'F', 'U');
595 function startPortlet ($title = '')
597 echo "<div class=portlet><h2>${title}</h2>";
600 function finishPortlet ()
605 function printRefsOfType ($refs, $type, $eq)
609 foreach ($refs as $ref)
611 if ($eq($ref['type'], $type))
613 if ($gotone) echo ', ';
614 echo "<a href='${root}?page=object&object_id=${ref['object_id']}'>";
615 if (!empty ($ref['name']))
616 echo $ref['name'] . '@';
617 echo "${ref['object_name']}</a>";
623 function renderRackObject ($object_id = 0)
628 showError ('Invalid object_id', __FUNCTION__
);
631 $info = getObjectInfo ($object_id);
634 showError ('getObjectInfo() failed', __FUNCTION__
);
637 // Main layout starts.
638 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
639 echo "<tr><td colspan=2 align=center><h1>${info['dname']}</h1></td></tr>\n";
640 // left column with uknown number of portlets
641 echo "<tr><td class=pcleft>";
642 startPortlet ('Object information');
643 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
644 if (!empty ($info['name']))
645 echo "<tr><th width='50%' class=tdright>Common name:</th><td class=tdleft>${info['name']}</td></tr>\n";
646 elseif (in_array ($info['objtype_id'], explode (',', getConfigVar ('NAMEFUL_OBJTYPES'))))
647 echo "<tr><td colspan=2 class=msg_error>Common name is missing.</td></tr>\n";
648 echo "<tr><th width='50%' class=tdright>Object type:</th><td class=tdleft>${info['objtype_name']}</td></tr>\n";
649 if (!empty ($info['asset_no']))
650 echo "<tr><th width='50%' class=tdright>Asset tag:</th><td class=tdleft>${info['asset_no']}</td></tr>\n";
651 elseif (in_array ($info['objtype_id'], explode (',', getConfigVar ('REQUIRE_ASSET_TAG_FOR'))))
652 echo "<tr><td colspan=2 class=msg_error>Asset tag is missing.</td></tr>\n";
653 if (!empty ($info['label']))
654 echo "<tr><th width='50%' class=tdright>Visible label:</th><td class=tdleft>${info['label']}</td></tr>\n";
655 if (!empty ($info['barcode']))
656 echo "<tr><th width='50%' class=tdright>Barcode:</th><td class=tdleft>${info['barcode']}</td></tr>\n";
657 if ($info['has_problems'] == 'yes')
658 echo "<tr><td colspan=2 class=msg_error>Has problems</td></tr>\n";
659 foreach (getAttrValues ($object_id) as $record)
660 if (!empty ($record['value']))
661 echo "<tr><th width='50%' class=opt_attr_th>${record['name']}:</th><td class=tdleft>${record['a_value']}</td></tr>\n";
662 echo "</table><br>\n";
665 if (!empty ($info['comment']))
667 startPortlet ('Comment');
668 echo '<div class=commentblock>' . string_insert_hrefs ($info['comment']) . '</div>';
672 $ports = getObjectPortsAndLinks ($object_id);
675 startPortlet ('Ports and links');
676 usort($ports, 'sortByName');
680 if (isset ($_REQUEST['hl_port_id']))
682 assertUIntArg ('hl_port_id');
683 $hl_port_id = $_REQUEST['hl_port_id'];
685 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
686 echo "<tr><th>Local name</th><th>Visible label</th><th>Port type</th><th>L2 address</th>";
687 echo "<th>Rem. Object</th><th>Rem. port</th></tr>\n";
688 foreach ($ports as $port)
691 if ($hl_port_id == $port['id'])
692 echo ' class=port_highlight';
693 echo "><td>${port['name']}</td><td>${port['label']}</td><td>${port['type']}</td>";
694 echo "<td>${port['l2address']}</td>";
695 if ($port['remote_object_id'])
697 echo "<td><a href='${root}?page=object&object_id=${port['remote_object_id']}'>${port['remote_object_name']}</a></td>";
698 echo "<td>${port['remote_name']}</td>";
700 elseif (!empty ($port['reservation_comment']))
702 echo "<td><b>Reserved;</b></td>";
703 echo "<td>${port['reservation_comment']}</td>";
706 echo '<td> </td><td> </td>';
709 echo "</table><br>\n";
713 $addresses = getObjectAddresses ($object_id);
714 usort($addresses, 'sortAddresses');
715 if (count ($addresses))
717 startPortlet ('IPv4 addresses');
718 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
719 echo "<tr><th>Interface name</th><th>IP Address</th><th>Description</th><th>Misc</th></tr>\n";
720 foreach ($addresses as $addr)
722 if (strlen($addr['address_name'])>40)
723 $address_name = substr($addr['address_name'],0,38).'...';
725 $address_name = $addr['address_name'];
727 $virtnum = countRefsOfType($addr['references'], 'virtual', 'eq');
728 $sharednum = countRefsOfType($addr['references'], 'shared', 'eq');
729 $regnum = countRefsOfType($addr['references'], 'regular', 'eq');
730 $notvirtnum = countRefsOfType($addr['references'], 'virtual', 'neq');
732 if ($addr['address_reserved']=='yes')
734 elseif ($addr['type']!='virtual' && $regnum>0)
736 elseif ($addr['type']=='regular' && $sharednum>0)
741 echo "<tr class='$class'><td>${addr['name']}</td><td><a href='${root}?page=ipaddress&ip=${addr['ip']}'>${addr['ip']}</a></td><td class='description'>$address_name</td><td>\n";
743 if ($addr['address_reserved']=='yes')
744 echo "<b>Reserved;</b> ";
746 if ($addr['type'] == 'virtual')
752 printRefsOfType($addr['references'], 'virtual', 'neq');
755 elseif ($addr['type'] == 'shared')
761 printRefsOfType($addr['references'], 'shared', 'eq');
767 printRefsOfType($addr['references'], 'virtual', 'eq');
772 echo " Collisions: ";
773 printRefsOfType($addr['references'], 'regular', 'eq');
782 printRefsOfType($addr['references'], 'virtual', 'eq');
787 echo " Collisions: ";
788 printRefsOfType($addr['references'], 'virtual', 'neq');
794 echo "</table><br>\n";
798 $forwards = getObjectForwards ($object_id);
799 if (count($forwards['in']) or count($forwards['out']))
801 startPortlet('NATv4');
803 if (count($forwards['out']))
806 echo "<h3>locally performed NAT</h3>";
808 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
809 echo "<tr><th>Proto</th><th>Match endpoint</th><th>Translate to</th><th>Target object</th><th>Rule comment</th></tr>\n";
811 foreach ($forwards['out'] as $pf)
815 foreach ($addresses as $addr)
816 if ($addr['ip'] == $pf['localip'])
823 echo "<tr class='$class'>";
825 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>";
827 echo "<td class=tdleft><a href='${root}?page=ipaddress&tab=default&ip=${pf['remoteip']}'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
829 $address=getIPAddress($pf['remoteip']);
831 echo "<td class='description'>";
832 if (count ($address['bonds']))
833 foreach($address['bonds'] as $bond)
834 echo "<a href='${root}?page=object&tab=default&object_id=${bond['object_id']}'>${bond['object_name']}(${bond['name']})</a> ";
835 elseif (!empty ($pf['remote_addr_name']))
836 echo '(' . $pf['remote_addr_name'] . ')';
838 echo "</td><td class='description'>${pf['description']}</td>";
842 echo "</table><br><br>";
844 if (count($forwards['in']))
846 echo "<h3>arriving NAT connections</h3>";
848 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
849 echo "<tr><th>Matched endpoint</th><th>Source object</th><th>Translated to</th><th>Rule comment</th></tr>\n";
851 foreach ($forwards['in'] as $pf)
854 echo "<td>${pf['proto']}/<a href='${root}?page=ipaddress&tab=default&ip=${pf['localip']}'>${pf['localip']}</a>:${pf['localport']}</td>";
856 echo "<td class='description'><a href='${root}?page=object&tab=default&object_id=${pf['object_id']}'>${pf['object_name']}</a>";
858 echo "</td><td><a href='${root}?page=ipaddress&tab=default&ip=${pf['remoteip']}'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
859 echo "<td class='description'>${pf['description']}</td></tr>";
862 echo "</table><br><br>";
867 $pools = getRSPoolsForObject ($object_id);
870 startPortlet ('Real server pools');
871 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
872 echo "<tr><th>VS</th><th>RS pool</th><th>RS</th><th>VS config</th><th>RS config</th></tr>\n";
873 foreach ($pools as $vs_id => $info)
875 echo "<tr valign=top><td class=tdleft><a href='${root}?page=vservice&id=${vs_id}'>";
876 echo buildVServiceName ($info);
878 if (!empty ($info['name']))
879 echo " (${info['name']})";
880 echo "</td><td class=tdleft><a href='${root}?page=rspool&id=${info['pool_id']}'>";
881 echo (empty ($info['pool_name']) ?
'ANONYMOUS' : $info['pool_name']);
882 echo '</a></td><td class=tdleft>' . $info['rscount'] . '</td>';
883 echo "<td class=tdleft><pre>${info['vsconfig']}</pre></td>";
884 echo "<td class=tdleft><pre>${info['rsconfig']}</pre></td>";
892 // After left column we have (surprise!) right column with rackspace portled only.
893 echo "<td class=pcright>";
895 startPortlet ('Rackspace allocation');
896 // FIXME: now we call getRackData() twice
897 $racks = getResidentRacksData ($object_id);
898 foreach ($racks as $rackData)
899 renderRack ($rackData['id'], $object_id);
906 function renderRackMultiSelect ($sname, $racks, $selected)
908 echo "<select name=${sname} multiple size=" . getConfigVar ('MAXSELSIZE') . " onchange='getElementById(\"racks\").submit()'>\n";
909 foreach ($racks as $rack)
911 echo "<option value=${rack['id']}";
912 if (!(array_search ($rack['id'], $selected) === FALSE))
914 echo">${rack['row_name']}: ${rack['name']}</option>\n";
919 function showMessageOrError ()
921 if (isset($_REQUEST['message']))
922 echo "<div class=msg_success>${_REQUEST['message']}</div>";
923 if (isset($_REQUEST['error']))
924 echo "<div class=msg_error>${_REQUEST['error']}</div>";
927 // This function renders a form for port edition.
928 function renderPortsForObject ($object_id = 0)
930 global $root, $pageno, $tabno;
933 showError ('Invalid object_id', __FUNCTION__
);
936 showMessageOrError();
937 startPortlet ('Ports and interfaces');
938 $ports = getObjectPortsAndLinks ($object_id);
939 usort($ports, 'sortByName');
940 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
941 echo "<tr><th> </th><th>Local name</th><th>Visible label</th><th>Port type</th><th>L2 address</th>";
942 echo "<th>Rem. object</th><th>Rem. port</th><th>(Un)link or (un)reserve</th><th> </th></tr>\n";
943 foreach ($ports as $port)
945 echo "<form action='${root}process.php'>";
946 echo "<input type=hidden name=op value=editPort>";
947 echo "<input type=hidden name=page value='${pageno}'>\n";
948 echo "<input type=hidden name=tab value='${tabno}'>\n";
949 echo "<input type=hidden name=port_id value='${port['id']}'>";
950 echo "<input type=hidden name=object_id value='$object_id'>\n";
951 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']}'>";
952 printImageHREF ('delete', 'Unlink and Delete this port');
954 echo "<td><input type=text name=name value='${port['name']}' size=8></td>";
955 echo "<td><input type=text name=label value='${port['label']}' size=24></td>";
956 echo "<td>${port['type']}</td>\n";
957 echo "<td><input type=text name=l2address value='${port['l2address']}'></td>\n";
958 if ($port['remote_object_id'])
960 echo "<td><a href='${root}?page=object&object_id=${port['remote_object_id']}'>${port['remote_object_name']}</a></td>";
961 echo "<td>${port['remote_name']}</td>";
962 echo "<td><a href='${root}process.php?op=unlinkPort&page=${pageno}&tab=${tabno}&port_id=${port['id']}&object_id=$object_id&port_name=";
963 echo urlencode ($port['name']);
964 echo "&remote_port_name=${port['remote_name']}&remote_object_name=${port['remote_object_name']}'>";
965 printImageHREF ('unlink', 'Unlink this port');
968 elseif (!empty ($port['reservation_comment']))
970 echo "<td><b>Reserved;</b></td>";
971 echo "<td><input type=text name=reservation_comment value='${port['reservation_comment']}'></td>";
972 echo "<td><a href='${root}process.php?op=useup&page=${pageno}&tab=${tabno}&port_id=${port['id']}&object_id=${object_id}'>";
973 printImageHREF ('useup', 'Use up this port');
978 echo "<td> </td><td> </td>";
980 echo "<a href='javascript:;' onclick='window.open(\"${root}link_helper.php?port=${port['id']}&type=${port['type_id']}&object_id=$object_id&port_name=";
981 echo urlencode ($port['name']);
982 echo "\",\"findlink\",\"height=700, width=400, location=no, menubar=no, resizable=yes, scrollbars=no, status=no, titlebar=no, toolbar=no\");'>";
983 printImageHREF ('link', 'Link this port');
984 echo "</a> <input type=text name=reservation_comment>";
987 echo "<td><input type='submit' value='OK'></td>";
988 echo "</form></tr>\n";
990 echo "<form action='${root}process.php'><tr>";
991 echo "<td colspan=2><input type=text size=10 name=port_name tabindex=100></td>\n";
992 echo "<td><input type=text size=24 name=port_label tabindex=101></td>";
993 echo "<input type=hidden name=op value=addPort>\n";
994 echo "<input type=hidden name=object_id value='${object_id}'>\n";
995 echo "<input type=hidden name=page value='${pageno}'>\n";
996 echo "<input type=hidden name=tab value='${tabno}'>\n";
997 echo "<td><select name='port_type_id' tabindex=102>\n";
998 $types = getPortTypes();
999 $default_port_type = getConfigVar ('default_port_type');
1000 foreach ($types as $typeid => $typename)
1002 echo "<option value='${typeid}'";
1003 if ($typeid == $default_port_type)
1005 echo ">${typename}</option>\n";
1007 echo "</select></td>";
1008 echo "<td><input type=text name=port_l2address tabindex=103></td>\n";
1009 echo "<td colspan=4><input type='submit' value='Add a new port' tabindex=104></td></tr></form>";
1010 echo "</table><br>\n";
1013 startPortlet ('Add/update multiple ports');
1014 echo "<form action=${root}process.php method=post>";
1015 echo "<input type=hidden name=page value='${pageno}'>\n";
1016 echo "<input type=hidden name=tab value='${tabno}'>\n";
1017 echo "<input type=hidden name=object_id value='${object_id}'>\n";
1018 echo "<input type=hidden name=op value=addMultiPorts>";
1019 echo 'Format: <select name=format>';
1020 echo '<option value=c2900 disabled>Cisco 2900 series: sh int eth</option>';
1021 echo '<option value=c3600eth disabled>Cisco 3600 ethernet: sh arp | inc -</option>';
1022 echo '<option value=c3600asy>Cisco 3600 async: sh line | inc TTY</option>';
1023 echo '<option value=fiwg selected>Foundry ServerIron/FastIron WorkGroup/Edge: sh int br</option>';
1024 echo '<option value=fiedge disabled>Foundry FastIron Edge: sh int br</option>';
1025 echo '<option value=fisxii>Foundry FastIron SuperX/II4000: sh int br</option>';
1026 echo '<option value=ssv1>SSV:<interface name> <MAC address></option>';
1028 echo 'Default port type: ';
1029 echo "<select name=port_type>\n";
1030 foreach ($types as $typeid => $typename)
1032 echo "<option value='${typeid}'";
1033 if ($typeid == $default_port_type)
1035 echo ">${typename}</option>\n";
1038 echo "<input type=submit value='Parse output'><br>\n";
1039 echo "<textarea name=input cols=100 rows=50></textarea><br>\n";
1044 function renderNetworkForObject ($object_id=0)
1046 global $root, $pageno, $tabno;
1047 if ($object_id <= 0)
1049 showError ('Invalid object_id', __FUNCTION__
);
1052 showMessageOrError();
1053 startPortlet ('Network Addresses');
1054 $addresses = getObjectAddresses ($object_id);
1055 usort($addresses, 'sortAddresses');
1056 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
1057 echo "<tr><th> </th><th>Interface name</th><th>IP Address</th><th>Description</th><th>Type</th><th>Misc</th><th> </th></tr>\n";
1058 foreach ($addresses as $addr)
1060 if (strlen($addr['address_name'])>40)
1061 $address_name = substr($addr['address_name'],0,38).'...';
1063 $address_name = $addr['address_name'];
1065 $virtnum = countRefsOfType($addr['references'], 'virtual', 'eq');
1066 $sharednum = countRefsOfType($addr['references'], 'shared', 'eq');
1067 $regnum = countRefsOfType($addr['references'], 'regular', 'eq');
1068 $notvirtnum = countRefsOfType($addr['references'], 'virtual', 'neq');
1070 if ($addr['address_reserved']=='yes')
1072 elseif ($addr['type']!='virtual' && $regnum>0)
1074 elseif ($addr['type']=='regular' && $sharednum>0)
1079 echo "<form action='process.php'>";
1080 echo "<input type=hidden name=page value='${pageno}'>\n";
1081 echo "<input type=hidden name=tab value='${tabno}'>\n";
1082 echo "<input type=hidden name=op value=editAddressFromObject>";
1083 echo "<input type=hidden name=object_id value='$object_id'>";
1084 echo "<input type=hidden name=ip value='${addr['ip']}'>";
1085 echo "<tr class='$class'><td><a href='process.php?op=delAddrFObj&page=${pageno}&tab=${tabno}&ip=${addr['ip']}&object_id=$object_id'>";
1086 printImageHREF ('delete', 'Delete this IPv4 address');
1088 echo "<td><input type='text' name='bond_name' value='${addr['name']}' size=10></td>";
1089 echo "<td><a href='${root}?page=ipaddress&ip=${addr['ip']}'>${addr['ip']}</a></td>";
1090 echo "<td class='description'>$address_name</td>\n";
1091 echo "<td><select name='bond_type'>";
1092 foreach (array('regular'=>'Regular', 'virtual'=>'Virtual', 'shared'=>'Shared') as $n => $v)
1094 echo "<option value='$n'";
1095 if ($addr['type'] == $n)
1097 echo ">$v</option>";
1100 if ($addr['address_reserved']=='yes')
1101 echo "<b>Reserved</b>; ";
1103 if ($addr['type'] == 'virtual')
1105 if ($notvirtnum > 0)
1108 printRefsOfType($addr['references'], 'virtual', 'neq');
1111 elseif ($addr['type'] == 'shared')
1116 printRefsOfType($addr['references'], 'shared', 'eq');
1122 printRefsOfType($addr['references'], 'virtual', 'eq');
1127 echo " Collisions: ";
1128 printRefsOfType($addr['references'], 'regular', 'eq');
1137 printRefsOfType($addr['references'], 'virtual', 'eq');
1140 if ($notvirtnum > 0)
1142 echo " Collisions: ";
1143 printRefsOfType($addr['references'], 'virtual', 'neq');
1147 echo "</td><td><input type=submit value='OK'></td></form></tr>\n";
1151 echo "<form action='${root}process.php'><tr><td colspan=2><input type='text' size='10' name='name' tabindex=100></td>\n";
1152 echo "<input type=hidden name=page value='${pageno}'>\n";
1153 echo "<input type=hidden name=tab value='${tabno}'>\n";
1154 echo "<input type=hidden name=op value=addAddrFObj>\n";
1155 echo "<input type=hidden name=object_id value='$object_id'>\n";
1157 echo "<td><input type=text name='ip' tabindex=101>\n";
1158 echo "</td><td><select name='type' tabindex=102>";
1159 echo "<option value='regular'>Regular</option>";
1160 echo "<option value='virtual'>Virtual</option>";
1161 echo "<option value='shared'>Shared</option>";
1163 echo "</td><td colspan=3><input type='submit' value='Add a new interface' tabindex=103></td></tr></form>";
1164 echo "</table><br>\n";
1169 function printLog ($log)
1171 foreach ($log as $record)
1172 echo "<div class=msg_${record['code']}>${record['message']}</div>";
1176 The following conditions must be followed:
1177 1. We can mount onto free atoms only. This means: if any record for an atom
1178 already exists in RackSpace, it can't be used for mounting.
1179 2. We can't unmount from 'W' atoms. Operator should review appropriate comments
1180 and either delete them before unmounting or refuse to unmount the object.
1183 // We extensively use $_REQUEST in the function.
1184 function renderRackSpaceForObject ($object_id = 0)
1186 if ($object_id <= 0)
1188 showError ('Invalid object_id', __FUNCTION__
);
1191 $is_submit = isset ($_REQUEST['got_atoms']);
1192 $is_update = isset ($_REQUEST['rackmulti'][0]);
1193 $info = getObjectInfo ($object_id);
1196 showError ('getObjectInfo() failed', __FUNCTION__
);
1199 // Always process occupied racks plus racks chosen by user. First get racks with
1200 // already allocated rackspace...
1201 $workingRacksData = getResidentRacksData ($object_id);
1202 if ($workingRacksData === NULL)
1204 print_r ($workingRacksData);
1205 showError ('getResidentRacksData() failed', __FUNCTION__
);
1209 // ...and then add those chosen by user (if any).
1211 foreach ($_REQUEST['rackmulti'] as $cand_id)
1213 if (!isset ($workingRacksData[$cand_id]))
1215 $rackData = getRackData ($cand_id);
1216 if ($rackData == NULL)
1218 showError ('getRackData() failed', __FUNCTION__
);
1221 $workingRacksData[$cand_id] = $rackData;
1225 // Do it only once...
1226 foreach ($workingRacksData as &$rackData)
1227 applyObjectMountMask ($rackData, $object_id);
1228 // Now we workaround an old caveat: http://bugs.php.net/bug.php?id=37410
1231 // Here we process form submit by trying to save all submitted info to database.
1234 $oldMolecule = getMoleculeForObject ($object_id);
1235 $worldchanged = FALSE;
1237 foreach ($workingRacksData as $rack_id => $rackData)
1239 $logrecord = processGridForm ($rackData, 'F', 'T', $object_id);
1240 $log[] = $logrecord;
1241 if ($logrecord['code'] != 300)
1243 $worldchanged = TRUE;
1244 // Reload our working copy after form processing.
1245 $rackData = getRackData ($rack_id);
1246 if ($rackData == NULL)
1247 $log[] = array ('code' => 500, 'message' => 'Working copy update failed in ', __FUNCTION__
);
1248 applyObjectMountMask ($rackData, $object_id);
1249 $workingRacksData[$rack_id] = $rackData;
1255 $newMolecule = getMoleculeForObject ($object_id);
1256 $oc = count ($oldMolecule);
1257 $nc = count ($newMolecule);
1258 $omid = $oc ?
createMolecule ($oldMolecule) : 'NULL';
1259 $nmid = $nc ?
createMolecule ($newMolecule) : 'NULL';
1260 global $remote_username;
1261 $comment = empty ($_REQUEST['comment']) ?
'NULL' : "'${_REQUEST['comment']}'";
1263 "insert into MountOperation(object_id, old_molecule_id, new_molecule_id, user_name, comment) " .
1264 "values (${object_id}, ${omid}, ${nmid}, '${remote_username}', ${comment})";
1266 $result = $dbxlink->query ($query);
1267 if ($result == NULL)
1268 $log[] = array ('code' => 'error', 'message' => 'SQL query failed during history logging.');
1270 $log[] = array ('code' => 'success', 'message' => 'History logged.');
1275 // This is the time for rendering.
1276 global $root, $pageno, $tabno;
1277 echo "<form id='racks' action='${root}'>";
1278 echo "<input type=hidden name=page value='${pageno}'>\n";
1279 echo "<input type=hidden name=tab value='${tabno}'>\n";
1280 echo "<input type=hidden name=object_id value='${object_id}'>\n";
1281 // Main layout starts.
1282 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0><tr>";
1284 // Left portlet with rack list.
1285 echo "<td class=pcleft height='1%'>";
1286 startPortlet ('Racks');
1287 $allRacksData = getRacksForRow();
1288 if (count ($allRacksData) <= getConfigVar ('RACK_PRESELECT_THRESHOLD'))
1290 foreach (array_keys ($allRacksData) as $rack_id)
1292 $rackData = getRackData ($rack_id);
1293 if ($rackData == NULL)
1295 showError ('getRackData() failed', __FUNCTION__
);
1298 $workingRacksData[$rack_id] = $rackData;
1300 foreach ($workingRacksData as &$rackData)
1301 applyObjectMountMask ($rackData, $object_id);
1304 renderRackMultiSelect ('rackmulti[]', $allRacksData, array_keys ($workingRacksData));
1310 // Middle portlet with comment and submit.
1311 echo "<td class=pcleft>";
1312 startPortlet ('Comment');
1313 echo "<textarea name=comment rows=10 cols=40></textarea><br>\n";
1314 echo "<input type=submit value='Save' name=got_atoms>\n";
1320 // Right portlet with rendered racks. If this form submit is not final, we have to
1321 // reflect the former state of the grid in current form.
1322 echo "<td class=pcright rowspan=2 height='1%'>";
1323 startPortlet ('Working copy');
1324 echo '<table border=0 cellspacing=10 align=center><tr>';
1325 foreach ($workingRacksData as $rack_id => $rackData)
1327 // Order is important here: only original allocation is highlighted.
1328 highlightObject ($rackData, $object_id);
1329 markupAtomGrid ($rackData, 'T');
1330 // If we have a form processed, discard user input and show new database
1332 if (!$is_submit and $is_update)
1333 mergeGridFormToRack ($rackData);
1334 echo "<td valign=top>";
1335 echo "<center>\n<h2>${rackData['name']}</h2>\n";
1336 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
1337 echo "<tr><th width='10%'> </th><th width='20%'>Front</th>";
1338 echo "<th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
1339 renderAtomGrid ($rackData);
1340 echo "<tr><th width='10%'> </th><th width='20%'>Front</th>";
1341 echo "<th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
1342 echo "</table></center>\n";
1345 echo "</tr></table>";
1350 echo "</tr></table>\n";
1353 function renderMolecule ($mdata, $object_id)
1356 $rackpack = array();
1358 foreach ($mdata as $dummy => $rua)
1360 $rack_id = $rua['rack_id'];
1361 $unit_no = $rua['unit_no'];
1362 $atom = $rua['atom'];
1363 if (!isset ($rackpack[$rack_id]))
1365 $rackData = getRackData ($rack_id);
1366 for ($i = $rackData['height']; $i > 0; $i--)
1367 for ($locidx = 0; $locidx < 3; $locidx++
)
1368 $rackData[$i][$locidx]['state'] = 'F';
1369 $rackpack[$rack_id] = $rackData;
1371 $rackpack[$rack_id][$unit_no][$loclist[$atom]]['state'] = 'T';
1372 $rackpack[$rack_id][$unit_no][$loclist[$atom]]['object_id'] = $object_id;
1374 // now we have some racks to render
1375 foreach ($rackpack as $dummy => $rackData)
1377 markAllSpans ($rackData);
1378 echo "<table class=molecule cellspacing=0>\n";
1379 echo "<caption>${rackData['name']}</caption>\n";
1380 echo "<tr><th width='10%'> </th><th width='20%'>Front</th><th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
1381 for ($i = $rackData['height']; $i > 0; $i--)
1383 echo "<tr><th>$i</th>";
1384 for ($locidx = 0; $locidx < 3; $locidx++
)
1386 $state = $rackData[$i][$locidx]['state'];
1387 echo "<td class=state_${state}> </td>\n";
1395 function renderUnmountedObjectsPortlet ()
1397 startPortlet ('Unmounted objects');
1398 $objs = getUnmountedObjects();
1401 showError ('getUnmountedObjects() failed', __FUNCTION__
);
1404 global $root, $nextorder;
1406 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1407 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset number</th><th>Barcode</th></tr>';
1408 foreach ($objs as $obj)
1410 echo "<tr class=row_${order}><td><a href='${root}?page=object&object_id=${obj['id']}'>${obj['dname']}</a></td>";
1411 echo "<td>${obj['label']}</td>";
1412 echo "<td>${obj['asset_no']}</td>";
1413 echo "<td>${obj['barcode']}</td></tr>";
1414 $order = $nextorder[$order];
1416 echo "</table><br>\n";
1420 function renderProblematicObjectsPortlet ()
1422 startPortlet ('Problematic objects');
1423 $objs = getProblematicObjects();
1426 showError ('getProblematicObjects() failed', __FUNCTION__
);
1429 global $root, $nextorder;
1431 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1432 echo '<tr><th>Type</th><th>Common name</th></tr>';
1433 foreach ($objs as $obj)
1435 echo "<tr class=row_${order}><td>${obj['objtype_name']}</td>";
1436 echo "<td><a href='${root}?page=object&object_id=${obj['id']}'>${obj['dname']}</a></tr>";
1437 $order = $nextorder[$order];
1439 echo "</table><br>\n";
1443 function renderObjectGroupSummary ()
1446 $summary = getObjectGroupInfo();
1447 if ($summary === NULL)
1449 showError ('getObjectGroupInfo() failed', __FUNCTION__
);
1452 echo "<table border=0 class=objectview>\n";
1453 echo "<tr><td class=pcleft width='25%'>";
1455 startPortlet ('Summary');
1456 foreach ($summary as $gi)
1458 echo "<a href='${root}?page=objgroup&group_id=${gi['id']}'><b>${gi['name']}</b></a> <i>(${gi['count']})</i><br>";
1462 echo '</td><td class=pcright>';
1463 renderUnmountedObjectsPortlet();
1464 echo '</td><td class=pcright>';
1465 renderProblematicObjectsPortlet();
1466 echo "</td></tr></table>\n";
1469 function renderObjectGroup ($group_id = 0)
1472 $summary = getObjectGroupInfo();
1473 if ($summary == NULL)
1475 showError ('getObjectGroupInfo() failed', __FUNCTION__
);
1478 $objects = getObjectList ($group_id);
1479 if ($objects === NULL)
1481 showError ('getObjectList() failed', __FUNCTION__
);
1484 echo "<table border=0 class=objectview>\n";
1485 echo "<tr><td class=pcleft width='25%'>";
1487 startPortlet ('All objects');
1488 foreach ($summary as $gi)
1490 echo "<a href='${root}?page=objgroup&group_id=${gi['id']}'><b>${gi['name']}</b></a> <i>(${gi['count']})</i><br>";
1494 echo '</td><td class=pcright>';
1496 startPortlet ('Object group');
1497 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1498 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>Barcode</th><th>Rack</th></tr>';
1501 foreach ($objects as $obj)
1503 echo "<tr class=row_${order}><td><a href='${root}?page=object&object_id=${obj['id']}'>${obj['dname']}</a></td>";
1504 echo "<td>${obj['label']}</td>";
1505 echo "<td>${obj['asset_no']}</td>";
1506 echo "<td>${obj['barcode']}</td>";
1507 if ($obj['rack_id'])
1508 echo "<td><a href='${root}?page=rack&rack_id=${obj['rack_id']}'>${obj['Rack_name']}</a></td>";
1510 echo '<td>Unmounted</td>';
1512 $order = $nextorder[$order];
1517 echo "</td></tr></table>";
1520 function renderEmptyPortsSelect ($port_id, $type_id)
1522 $ports = getEmptyPortsOfType($type_id);
1523 usort($ports, 'sortEmptyPorts');
1524 foreach ($ports as $port)
1526 if ($port_id == $port['Port_id'])
1528 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";
1532 function renderObjectAddressesAndNames ()
1534 $addresses = getObjectAddressesAndNames();
1535 usort($addresses, 'sortObjectAddressesAndNames');
1536 foreach ($addresses as $address)
1538 echo "<option value='${address['ip']}' onclick='getElementById(\"ip\").value=\"${address['ip']}\";'>${address['object_name']} ${address['name']} ${address['ip']}</option>\n";
1542 // History viewer for history-enabled simple dictionaries.
1543 function renderHistory ($object_type, $object_id)
1545 switch ($object_type)
1548 $query = "select ctime, user_name, name, deleted, comment from RackRowHistory where id = ${object_id} order by ctime";
1549 $header = '<tr><th>change time</th><th>author</th><th>rack row name</th><th>is deleted?</th><th>rack row comment</th></tr>';
1554 "select ctime, user_name, rh.name, rh.deleted, d.dict_value as name, rh.height, rh.comment " .
1555 "from RackHistory as rh left join Dictionary as d on rh.row_id = d.dict_key " .
1556 "natural join Chapter " .
1557 "where chapter_name = 'RackRow' and rh.id = ${object_id} order by ctime";
1558 $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>';
1563 "select ctime, user_name, name, label, barcode, asset_no, deleted, has_problems, dict_value, comment " .
1564 "from RackObjectHistory inner join Dictionary on objtype_id = dict_key natural join Chapter " .
1565 "where chapter_name = 'RackObjectType' and id=${object_id} order by ctime";
1566 $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>';
1570 showError ("Uknown object type '${object_type}'", __FUNCTION__
);
1574 $result = $dbxlink->query ($query);
1575 if ($result == NULL)
1577 showError ('SQL query failed', __FUNCTION__
);
1580 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1584 while ($row = $result->fetch (PDO
::FETCH_NUM
))
1586 echo "<tr class=row_${order}><td>${row[0]}</td>";
1587 for ($i = 1; $i <= $extra; $i++
)
1588 echo "<td>" . $row[$i] . "</td>";
1590 $order = $nextorder[$order];
1592 echo "</table><br>\n";
1595 function renderRackspaceHistory ()
1597 global $root, $nextorder, $pageno, $tabno;
1599 $history = getRackspaceHistory();
1600 // Show the last operation by default.
1601 if (isset ($_REQUEST['op_id']))
1602 $op_id = $_REQUEST['op_id'];
1603 elseif (isset ($history[0]['mo_id']))
1604 $op_id = $history[0]['mo_id'];
1611 list ($omid, $nmid) = getOperationMolecules ($op_id);
1613 // Main layout starts.
1614 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
1616 // Left top portlet with old allocation.
1617 echo "<tr><td class=pcleft>";
1618 startPortlet ('Old allocation');
1621 $oldMolecule = getMolecule ($omid);
1622 renderMolecule ($oldMolecule, $object_id);
1628 echo '</td><td class=pcright>';
1630 // Right top portlet with new allocation
1631 startPortlet ('New allocation');
1634 $newMolecule = getMolecule ($nmid);
1635 renderMolecule ($newMolecule, $object_id);
1641 echo '</td></tr><tr><td colspan=2>';
1643 // Bottom portlet with list
1645 startPortlet ('Rackspace allocation history');
1646 echo "<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>\n";
1647 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";
1648 foreach ($history as $row)
1650 if ($row['mo_id'] == $op_id)
1653 $class = "row_${order}";
1654 echo "<tr class=${class}><td><a href='${root}?page=${pageno}&tab=${tabno}&op_id=${row['mo_id']}'>${row['ctime']}</a></td>";
1655 echo "<td>${row['user_name']}</td>";
1656 echo "<td>${row['ro_id']}</td><td>${row['objtype_name']}</td><td>${row['name']}</td><td>${row['comment']}</td>\n";
1658 $order = $nextorder[$order];
1663 echo '</td></tr></table>';
1667 function renderAddressspace ()
1669 global $root, $page;
1671 startPortlet ('Subnets');
1672 echo "<table class='widetable' border=0 cellpadding=10 cellspacing=0 align='center'>\n";
1673 $addrspaceList = getAddressspaceList();
1674 echo "<tr><th>Subnet</th><th>Name</th><th>Utilization</th></tr>";
1675 foreach ($addrspaceList as $iprange)
1677 $range = getIPRange ($iprange['id']);
1678 $total = ($iprange['ip_bin'] |
$iprange['mask_bin_inv']) - ($iprange['ip_bin'] & $iprange['mask_bin']) +
1;
1679 $used = count ($range['addrlist']);
1680 echo "<tr><td class=tdleft><a href='${root}?page=iprange&id=${iprange['id']}'>${iprange['ip']}/${iprange['mask']}</a></td>";
1681 echo "<td class=tdleft>${iprange['name']}</td><td class=tdleft>";
1682 renderProgressBar ($used/$total);
1683 echo " ${used}/${total}</td></tr>";
1689 function renderIPv4SLB ()
1691 global $root, $page, $nextorder;
1693 startPortlet ('SLB configuration');
1694 echo "<table border=0 width='100%'><tr>";
1695 foreach (array ('vservices', 'rspools', 'rservers', 'lbs') as $pno)
1696 echo "<td><h3><a href='${root}?page=${pno}'>" . $page[$pno]['title'] . "</a></h3></td>";
1697 echo '</tr></table>';
1700 $summary = getSLBSummary();
1701 startPortlet ('SLB tactical overview');
1702 // A single id-keyed array isn't used here to preserve existing
1703 // order of LBs returned by getSLBSummary()
1706 foreach ($summary as $vipdata)
1707 foreach (array_keys ($vipdata['lblist']) as $lb_object_id)
1708 if (!in_array ($lb_object_id, $lblist))
1710 $oi = getObjectInfo ($lb_object_id);
1711 $lbdname[$lb_object_id] = $oi['dname'];
1712 $lblist[] = $lb_object_id;
1714 if (!count ($summary))
1715 echo 'none configured';
1719 echo "<table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
1720 echo "<tr><th>VS ↓ LB →</th>";
1721 foreach ($lblist as $lb_object_id)
1722 echo "<th><a href='${root}?page=object&tab=default&object_id=${lb_object_id}'>" . $lbdname[$lb_object_id] . "</a></th>";
1724 foreach ($summary as $vsid => $vsdata)
1726 echo "<tr class=row_${order}><td class=tdleft><a href='$root?page=vservice&tab=default&id=${vsid}'>";
1727 echo buildVServiceName ($vsdata);
1729 if (!empty ($vsdata['name']))
1730 echo " (${vsdata['name']})";
1732 foreach ($lblist as $lb_object_id)
1734 echo '<td class=tdleft>';
1735 if (!isset ($vsdata['lblist'][$lb_object_id]))
1739 echo $vsdata['lblist'][$lb_object_id]['size'];
1740 echo " (<a href='${root}?page=rspool&id=";
1741 echo $vsdata['lblist'][$lb_object_id]['id'] . "'>";
1742 echo $vsdata['lblist'][$lb_object_id]['name'] . '</a>)';
1747 $order = $nextorder[$order];
1754 function renderAddNewRange ()
1756 global $root, $pageno, $tabno;
1757 showMessageOrError();
1759 echo "<center><h2>Add New</h2></center>\n";
1760 echo "<table class='widetable' border=0 cellpadding=10 align='center'>\n";
1761 echo "<tr><th>Address range</th><th>Name</th><th>C>*</th><th> </th></tr>\n";
1762 echo "<form name='add_new_range' action='process.php'>\n";
1763 echo "<input type=hidden name=op value=addRange>\n";
1764 echo "<input type=hidden name=page value='${pageno}'>\n";
1765 echo "<input type=hidden name=tab value='${tabno}'>\n";
1766 echo "<tr><td class='tdcenter'><input type=text name='range' size=18 class='live-validate' tabindex=1></td>\n";
1767 echo "<td class='tdcenter'><input type=text name='name' size='20' tabindex=2></td>\n";
1768 echo "<td class='tdcenter'><input type=checkbox name='is_bcast' tabindex=3 checked></td>\n";
1769 echo "<td class='tdcenter'><input type=submit value='Add a new range' tabindex=4></td></tr>\n";
1770 echo "</form></table><br><br>\n";
1772 echo "<center><h2>Manage Existing</h2></center>\n";
1773 echo "<table class='widetable' border=0 cellpadding=10 align='center'>\n";
1774 $addrspaceList = getAddressspaceList();
1775 echo "<tr><th> </th><th>Address range</th><th>Name</th><th>Utilization</th></tr>";
1776 foreach ($addrspaceList as $iprange)
1778 $range = getIPRange($iprange['id']);
1779 $usedips = count ($range['addrlist']);
1780 $totalips = ($iprange['ip_bin'] |
$iprange['mask_bin_inv']) - ($iprange['ip_bin'] & $iprange['mask_bin']) +
1;
1784 echo "<a href='process.php?op=delRange&page=${pageno}&tab=${tabno}&id=${iprange['id']}'>";
1785 printImageHREF ('delete', 'Delete this IP range');
1789 printImageHREF ('nodelete', 'There are IP addresses allocated or reserved');
1790 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>";
1791 renderProgressBar ($usedips / $totalips);
1792 echo " ${usedips}/${totalips}";
1798 function renderIPRange ($id)
1800 global $root, $pageno, $tabno;
1801 $maxperpage = getConfigVar ('IPV4_ADDRS_PER_PAGE');
1802 if (isset($_REQUEST['pg']))
1803 $page = $_REQUEST['pg'];
1807 $range = getIPRange($id);
1808 echo "<center><h1>${range['ip']}/${range['mask']}</h1><h2>${range['name']}</h2></center>\n";
1810 $startip = $range['ip_bin'] & $range['mask_bin'];
1811 $endip = $range['ip_bin'] |
$range['mask_bin_inv'];
1812 $realstartip = $startip;
1813 $realendip = $endip;
1815 if($endip - $startip > $maxperpage)
1817 $numpages = ($endip - $startip)/$maxperpage;
1818 $startip = $startip +
$page * $maxperpage;
1819 $endip = $startip +
$maxperpage-1;
1823 echo '<h3>' . long2ip ($startip) . ' ~ ' . long2ip ($endip) . '</h3>';
1824 for ($i=0; $i<$numpages; $i++
)
1829 echo "<a href='${root}?page=${pageno}&tab=${tabno}&id=$id&pg=$i'>$i</a> ";
1833 echo "<table class='widetable' border=0 cellspacing=0 cellpadding=5 align='center'>\n";
1834 echo "<tr><th>Address</th><th>Name</th><th>Allocation</th></tr>\n";
1837 for($ip = $startip; $ip<=$endip; $ip++
)
1839 if (isset ($range['addrlist'][$ip]))
1841 $numshared = countRefsOfType($range['addrlist'][$ip]['references'], 'shared', 'eq');
1842 $numreg = countRefsOfType($range['addrlist'][$ip]['references'], 'regular', 'eq');
1843 $numvirt = countRefsOfType($range['addrlist'][$ip]['references'], 'virtual', 'eq');
1845 $addr = $range['addrlist'][$ip];
1846 if ( ($numshared > 0 && $numreg > 0) ||
$numreg > 1 )
1847 echo "<tr class='trerror'>";
1848 elseif ( $addr['reserved'] == 'yes' and $numshared+
$numreg+
$numvirt > 0)
1849 echo "<tr class='trerror'>";
1850 elseif ( $addr['reserved'] == 'yes')
1851 echo "<tr class='trbusy'>";
1852 elseif ( $numshared > 0 ||
$numreg > 0)
1853 echo "<tr class='trbusy'>";
1857 echo "<td><a href='${root}?page=ipaddress&ip=${addr['ip']}'>${addr['ip']}</a></td><td>${addr['name']}</td><td>";
1859 if ( $addr['reserved'] == 'yes')
1861 echo "<b>Reserved</b> ";
1864 foreach ($range['addrlist'][$ip]['references'] as $ref)
1866 echo "${delim}<a href='${root}?page=object&object_id=${ref['object_id']}'>";
1867 echo $ref['name'] . (empty ($ref['name']) ?
'' : '@');
1868 echo "${ref['object_name']}</a>";
1871 echo "</td></tr>\n";
1875 echo "<tr><td><a href='${root}?page=ipaddress&ip=".long2ip($ip)."'>".long2ip($ip)."</a></td><td> </td><td> </td></tr>\n";
1883 function renderIPRangeProperties ($id)
1885 global $pageno, $tabno;
1886 showMessageOrError();
1887 $range = getIPRange($id);
1888 echo "<center><h1>${range['ip']}/${range['mask']}</h1></center>\n";
1889 echo "<table border=0 cellpadding=10 cellpadding=1 align='center'>\n";
1890 echo "<form action='process.php'><input type=hidden name=op value=editRange>";
1891 echo "<input type=hidden name=page value='${pageno}'>\n";
1892 echo "<input type=hidden name=tab value='${tabno}'>\n";
1893 echo "<input type=hidden name=id value='${id}'>";
1894 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>";
1899 function renderIPAddress ()
1902 $ip = $_REQUEST['ip'];
1903 $address = getIPAddress($ip);
1904 echo "<center><h1>$ip</h1>";
1905 if ($address['exists'] == 1)
1906 echo "<h2>${address['name']}</h2>";
1909 // echo "<table width='100%' cesspadding=5 cellspacing=0 border=0 align='center'>";
1910 // echo "<tr valign='top'><td>";
1912 $numshared = countRefsOfType($address['bonds'], 'shared', 'eq');
1913 $numreg = countRefsOfType($address['bonds'], 'regular', 'eq');
1914 $numvirt = countRefsOfType($address['bonds'], 'virtual', 'eq');
1916 if ($address['reserved'] == 'yes' or ($numshared +
$numreg +
$numvirt) > 0)
1918 startPortlet ('Allocation');
1919 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
1920 echo "<tr><th>Object name</th><th>Interface name</th><th>Interface type</th></tr>\n";
1921 if ( ($numshared > 0 && $numreg > 0) ||
$numreg > 1 )
1923 elseif ( $address['reserved'] == 'yes' and $numshared+
$numreg+
$numvirt > 0)
1928 if ($address['reserved'] == 'yes')
1929 echo "<tr class='$class'><td colspan='3'><b>RESERVED</b></td></tr>";
1930 foreach ($address['bonds'] as $bond)
1932 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>";
1933 switch ($bond['type'])
1945 echo "</b></td></tr>\n";
1947 echo "</table><br><br>";
1951 if (count ($address['vslist']))
1953 startPortlet ('Virtual services (' . count ($address['vslist']) . ')');
1954 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
1955 echo "<tr><th>VS</th><th>name</th></tr>\n";
1956 foreach ($address['vslist'] as $vsinfo)
1958 echo "<tr><td class=tdleft><a href='${root}?page=vservice&id=${vsinfo['id']}'>";
1959 echo buildVServiceName ($vsinfo) . "</a></td><td class=tdleft>";
1960 echo $vsinfo['name'] . "</td></tr>\n";
1962 echo "</table><br><br>";
1966 if (count ($address['rslist']))
1968 startPortlet ('Real servers (' . count ($address['rslist']) . ')');
1969 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
1970 echo "<tr><th>in service</th><th>port</th><th>RS pool</th></tr>\n";
1971 foreach ($address['rslist'] as $rsinfo)
1974 if ($rsinfo['inservice'] == 'yes')
1975 printImageHREF ('inservice', 'in service');
1977 printImageHREF ('notinservice', 'NOT in service');
1978 echo "${rsinfo['rsport']}</td><td class=tdleft><a href='${root}?page=rspool&id=${rsinfo['pool_id']}'>";
1979 echo $rsinfo['poolname'] . "</a></td></tr>\n";
1981 echo "</table><br><br>";
1986 // echo "</td><td>";
1987 // echo "</td></tr></table>";
1990 function renderIPAddressProperties ()
1992 global $pageno, $tabno;
1993 $ip = $_REQUEST['ip'];
1994 showMessageOrError();
1995 $address = getIPAddress($ip);
1996 echo "<center><h1>$ip</h1></center>\n";
1997 echo "<table border=0 cellpadding=10 cellpadding=1 align='center'>\n";
1998 echo "<form action='process.php'><input type=hidden name=op value=editAddress>";
1999 echo "<input type=hidden name=page value='${pageno}'>\n";
2000 echo "<input type=hidden name=tab value='${tabno}'>\n";
2001 echo "<input type=hidden name=ip value='${ip}'>";
2002 echo "<tr><td class='tdright'>Name:</td><td class='tdleft'><input type=text name=name size=20 value='".($address['exists']==1?
$address['name']:'')."'></tr>";
2003 echo "<td class='tdright'>Reserved:</td><td class='tdleft'><input type=checkbox name=reserved size=20 ".($address['exists']==1?
(($address['reserved']=='yes')?
'checked':''):'')."></tr>";
2004 echo "<tr><td colspan=2 class='tdcenter'><input type=submit value='Update address'></td></form></tr>";
2009 function renderIPAddressAssignment ()
2011 global $pageno, $tabno, $root;
2012 $ip = $_REQUEST['ip'];
2013 $address = getIPAddress($ip);
2015 showMessageOrError();
2016 echo "<center><h1>$ip</h1></center>\n";
2019 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
2020 echo "<tr><th> </th><th>Object name</th><th>Interface name</th><th>Interface type</th><th> </th></tr>\n";
2022 $numshared = countRefsOfType($address['bonds'], 'shared', 'eq');
2023 $numreg = countRefsOfType($address['bonds'], 'regular', 'eq');
2024 $numvirt = countRefsOfType($address['bonds'], 'virtual', 'eq');
2027 if ( ($numshared > 0 && $numreg > 0) ||
$numreg > 1 )
2029 elseif ( $address['reserved'] == 'yes' and $numshared+
$numreg+
$numvirt > 0)
2036 if ($address['reserved'] == 'yes')
2037 echo "<tr class='$class'><td colspan='5'><b>RESERVED</b></td></tr>";
2038 foreach ($address['bonds'] as $bond)
2040 echo "<tr class='$class'><form action='process.php'>";
2041 echo "<input type=hidden name=op value='editBondForAddress'>";
2042 echo "<input type=hidden name=page value='${pageno}'>";
2043 echo "<input type=hidden name=tab value='${tabno}'>";
2044 echo "<input type=hidden name=ip value='$ip'>";
2045 echo "<input type=hidden name=object_id value='${bond['object_id']}'>";
2046 echo "<td><a href='process.php?op=delIpAssignment&page=${pageno}&tab=${tabno}&ip=$ip&object_id=${bond['object_id']}'>";
2047 printImageHREF ('delete', 'Unallocate address');
2049 echo "<td><a href='${root}?page=object&object_id=${bond['object_id']}'>${bond['object_name']}</td>";
2050 echo "<td><input type='text' name='bond_name' value='${bond['name']}' size=10></td>";
2051 echo "<td><select name='bond_type'>";
2052 switch ($bond['type'])
2055 echo "<option value='regular'>Regular</option>";
2056 echo "<option value='virtual' selected>Virtual</option>";
2057 echo "<option value='shared'>Shared</option>";
2060 echo "<option value='regular'>Regular</option>";
2061 echo "<option value='virtual'>Virtual</option>";
2062 echo "<option value='shared' selected>Shared</option>";
2065 echo "<option value='regular' selected>Regular</option>";
2066 echo "<option value='virtual'>Virtual</option>";
2067 echo "<option value='shared'>Shared</option>";
2070 echo "</select></td><td><input type='submit' value='OK'></td></form></tr>\n";
2072 echo "<form action='process.php'><input type='hidden' name='op' value='bindObjectToIp'>";
2073 echo "<input type=hidden name=page value='${pageno}'>\n";
2074 echo "<input type=hidden name=tab value='${tabno}'>\n";
2075 echo "<input type='hidden' name='ip' value='$ip'>";
2076 echo "<td colspan=2><select name='object_id'>";
2078 foreach (explode (',', getConfigVar ('IPV4_PERFORMERS')) as $type)
2079 foreach (getObjectList ($type) as $object)
2080 echo "<option value='${object['id']}'>${object['dname']}</option>";
2082 echo "</select></td><td><input type='text' name='bond_name' value='' size=10></td>";
2083 echo "<td><select name='bond_type'><option value='regular'>Regular</option><option value='virtual'>Virtual</option><option value='shared'>Shared</option></select></td>";
2084 echo "<td><input type='submit' value='Assign address'></td></form></tr>";
2085 echo "</table><br><br>";
2089 function renderIPAddressPortForwarding ($object_id=0)
2091 global $pageno, $tabno, $root;
2093 $info = getObjectInfo ($object_id);
2094 $forwards = getObjectForwards ($object_id);
2095 $addresses = getObjectAddresses ($object_id);
2096 showMessageOrError();
2097 echo "<center><h2>locally performed NAT</h2></center>";
2099 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
2100 echo "<tr><th></th><th>Match endpoint</th><th>Translate to</th><th>Target object</th><th>Comment</th></tr>\n";
2102 foreach ($forwards['out'] as $pf)
2106 foreach ($addresses as $addr)
2107 if ($addr['ip'] == $pf['localip'])
2110 $name = $addr['name'];
2114 echo "<tr class='$class'>";
2115 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}'>";
2116 printImageHREF ('delete', 'Delete NAT rule');
2118 echo "<td>${pf['proto']}/${name}: <a href='${root}?page=ipaddress&tab=default&ip=${pf['localip']}'>${pf['localip']}</a>:${pf['localport']}";
2119 if (!empty ($pf['local_addr_name']))
2120 echo ' (' . $pf['local_addr_name'] . ')';
2122 echo "<td><a href='${root}?page=ipaddress&tab=default&ip=${pf['remoteip']}'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
2124 $address=getIPAddress($pf['remoteip']);
2126 echo "<td class='description'>";
2127 if (count ($address['bonds']))
2128 foreach($address['bonds'] as $bond)
2129 echo "<a href='${root}?page=object&tab=default&object_id=${bond['object_id']}'>${bond['object_name']}(${bond['name']})</a> ";
2130 elseif (!empty ($pf['remote_addr_name']))
2131 echo '(' . $pf['remote_addr_name'] . ')';
2132 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>";
2135 echo "<form action='process.php'><input type='hidden' name='op' value='forwardPorts'>";
2136 echo "<input type='hidden' name='object_id' value='$object_id'>";
2137 echo "<input type=hidden name=page value='${pageno}'>\n";
2138 echo "<input type=hidden name=tab value='${tabno}'>\n";
2139 echo "<tr align='center'><td colspan=2>";
2140 printSelect (readChapter ('Protocols'), 'proto');
2141 echo "<select name='localip' tabindex=1>";
2143 foreach ($addresses as $addr)
2144 echo "<option value='${addr['ip']}'>" . (empty ($addr['name']) ?
'' : "${addr['name']}: ") .
2145 "${addr['ip']}" . (empty ($addr['address_name']) ?
'' : " (${addr['address_name']})") . "</option>";
2147 echo "</select>:<input type='text' name='localport' size='4' tabindex=2></td>";
2148 echo "<td><input type='text' name='remoteip' id='remoteip' size='10' tabindex=3>";
2149 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\");'>";
2150 printImageHREF ('find', 'Find object');
2152 echo ":<input type='text' name='remoteport' size='4' tabindex=4></td><td></td>";
2153 echo "<td colspan=1><input type='text' name='description' size='20' tabindex=5> <input type='submit' value='Create Forwarding' tabindex=6></td></tr>";
2156 echo "</table><br><br>";
2159 echo "<center><h2>arriving NAT connections</h2></center>";
2160 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
2161 echo "<tr><th></th><th>Source</th><th>Source objects</th><th>Target</th><th>Description</th></tr>\n";
2163 foreach ($forwards['in'] as $pf)
2167 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}'>";
2168 printImageHREF ('delete', 'Delete NAT rule');
2170 echo "<td>${pf['proto']}/<a href='${root}?page=ipaddress&tab=default&ip=${pf['localip']}'>${pf['localip']}</a>:${pf['localport']}</td>";
2171 echo "<td class='description'><a href='${root}?page=object&tab=default&object_id=${pf['object_id']}'>${pf['object_name']}</a>";
2172 echo "</td><td><a href='${root}?page=ipaddress&tab=default&ip=${pf['remoteip']}'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
2173 echo "<td class='description'>${pf['description']}</td></tr>";
2176 // echo "<form action='process.php'><input type='hidden' name='op' value='forwardPorts'>";
2177 // echo "<input type='hidden' name='object_id' value='$object_id'>";
2178 // echo "<input type=hidden name=page value='${pageno}'>\n";
2179 // echo "<input type=hidden name=tab value='${tabno}'>\n";
2180 // 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'>";
2181 // foreach ($addresses as $addr)
2182 // echo "<option value='${addr['ip']}'>${addr['ip']}</option>";
2184 // 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>";
2186 echo "</table><br><br>";
2192 function renderAddMultipleObjectsForm ()
2194 global $pageno, $tabno, $nextorder;
2197 $global_type_id = 0;
2199 $asset_no = array();
2200 $keepvalues = FALSE;
2202 // Look for current submit.
2203 if (isset ($_REQUEST['got_fast_data']))
2206 $max = getConfigVar ('MASSCOUNT');
2207 for ($i = 0; $i < $max; $i++
)
2209 if (!isset ($_REQUEST["${i}_object_type_id"]))
2211 $log[] = array ('code' => 'error', 'message' => "Submitted form is invalid at line " . $i +
1);
2214 assertUIntArg ("${i}_object_type_id", TRUE);
2215 assertStringArg ("${i}_object_name", TRUE);
2216 assertStringArg ("${i}_object_label", TRUE);
2217 assertStringArg ("${i}_object_asset_no", TRUE);
2218 assertStringArg ("${i}_object_barcode", TRUE);
2219 $type_id[$i] = $_REQUEST["${i}_object_type_id"];
2220 // Save user input for possible rendering.
2221 $name[$i] = $_REQUEST["${i}_object_name"];
2222 $label[$i] = $_REQUEST["${i}_object_label"];
2223 $asset_no[$i] = $_REQUEST["${i}_object_asset_no"];
2224 $barcode[$i] = $_REQUEST["${i}_object_barcode"];
2226 // It's better to skip silently than printing a notice.
2227 if ($type_id[$i] == 0)
2229 if (commitAddObject ($name[$i], $label[$i], $barcode[$i], $type_id[$i], $asset_no[$i]) === TRUE)
2230 $log[] = array ('code' => 'success', 'message' => "Added new object '${name[$i]}'");
2232 $log[] = array ('code' => 'error', 'message' => __FUNCTION__
. ': commitAddObject() failed');
2235 elseif (isset ($_REQUEST['got_very_fast_data']))
2238 assertUIntArg ('global_type_id', TRUE);
2239 assertStringArg ('namelist', TRUE);
2240 $global_type_id = $_REQUEST['global_type_id'];
2241 if ($global_type_id == 0)
2243 if (!empty ($_REQUEST['namelist']))
2244 $log[] = array ('code' => 'error', 'message' => 'Object type is not selected, check the form below');
2246 $log[] = array ('code' => 'error', 'message' => 'Empty form has been ignored. Cheers.');
2250 // The name extractor below was stolen from ophandlers.php:addMultiPorts()
2251 $names1 = explode ('\n', $_REQUEST['namelist']);
2253 foreach ($names1 as $line)
2255 $parts = explode ('\r', $line);
2257 if (empty ($parts[0]))
2260 $names2[] = rtrim ($parts[0]);
2262 foreach ($names2 as $cname)
2263 if (commitAddObject ($cname, '', '', $global_type_id, '') === TRUE)
2264 $log[] = array ('code' => 'success', 'message' => "Added new object '${cname}'");
2266 $log[] = array ('code' => 'error', 'message' => "Could not add '${cname}'");
2271 // Render a form for the next.
2272 $typelist = getObjectTypeList();
2273 $typelist[0] = 'select type...';
2275 startPortlet ('Fast way');
2277 echo "<input type=hidden name=page value=${pageno}>";
2278 echo "<input type=hidden name=tab value=${tabno}>";
2279 echo '<table border=0 align=center>';
2280 echo "<tr><th>Object type</th><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>Barcode</th></tr>\n";
2281 // If a user forgot to select object type on input, we keep his
2282 // previous input in the form.
2283 $max = getConfigVar ('MASSCOUNT');
2284 for ($i = 0; $i < $max; $i++
)
2287 printSelect ($typelist, "${i}_object_type_id", 0);
2289 echo "<td><input type=text size=30 name=${i}_object_name";
2290 if ($keepvalues and $type_id[$i] == 0)
2291 echo " value='${name[$i]}'";
2293 echo "<td><input type=text size=30 name=${i}_object_label";
2294 if ($keepvalues and $type_id[$i] == 0)
2295 echo " value='${label[$i]}'";
2297 echo "<td><input type=text size=20 name=${i}_object_asset_no";
2298 if ($keepvalues and $type_id[$i] == 0)
2299 echo " value='${asset_no[$i]}'";
2301 echo "<td><input type=text size=10 name=${i}_object_barcode";
2302 if ($keepvalues and $type_id[$i] == 0)
2303 echo " value='${barcode[$i]}'";
2307 echo "<tr><td class=submit colspan=5><input type=submit name=got_fast_data value='Create'></td></tr>\n";
2308 echo "</form></table>\n";
2311 startPortlet ('Very fast way');
2313 echo "<input type=hidden name=page value=${pageno}>";
2314 echo "<input type=hidden name=tab value=${tabno}>";
2315 echo 'For each line shown below create an object of type ';
2316 printSelect ($typelist, "global_type_id", 0);
2317 echo " <input type=submit name=got_very_fast_data value='Go!'><br>\n";
2318 echo "<textarea name=namelist cols=40 rows=25>\n";
2319 if ($keepvalues and $global_type_id == 0)
2320 echo $_REQUEST['namelist'];
2321 echo "</textarea></form>\n";
2325 function printGreeting ()
2327 global $remote_username, $accounts, $root;
2328 $account = $accounts[$remote_username];
2329 echo "Hello, ${account['user_realname']}. This is RackTables " . CODE_VERSION
. ". Click <a href='${root}?logout'>here</a> to logout.";
2332 function renderSearchResults ()
2334 global $remote_username, $root;
2335 $terms = trim ($_REQUEST['q']);
2338 showError ('Search string cannot be empty.', __FUNCTION__
);
2341 if (!authorized ($remote_username, 'object', 'default'))
2343 showError ('You are not authorized for viewing information about objects.', __FUNCTION__
);
2346 // If we search for L2 address, we can either find one or find none.
2349 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
2350 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
2351 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)
2353 // Search for L2 address.
2355 $result = searchByl2address ($terms);
2356 if ($result !== NULL)
2358 echo "<script language='Javascript'>document.location='${root}?page=object";
2359 echo "&hl_port_id=${result['port_id']}";
2360 echo "&object_id=${result['object_id']}';//</script>";
2363 echo "L2 address '${terms}' not found!";
2365 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))
2366 // STP bridge ID: bridge priotity + port MAC address. Cut off first 4 chars and look for MAC address.
2368 $terms = substr ($terms, 4);
2369 $result = searchByl2address ($terms);
2370 if ($result !== NULL)
2372 echo "<script language='Javascript'>document.location='${root}?page=object";
2373 echo "&hl_port_id=${result['port_id']}";
2374 echo "&object_id=${result['object_id']}';//</script>";
2377 echo "L2 address '${terms}' not found!";
2379 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))
2380 // Search for IP address.
2382 $result = getRangeByIp ($terms);
2383 if ($result !== NULL)
2385 echo "<script language='Javascript'>document.location='${root}?page=ipaddress";
2386 echo "&ip=${terms}";
2387 echo "';//</script>";
2390 echo "IP address '${terms}' not found!";
2394 // Search for objects.
2396 $objects = getSearchResults ($terms);
2397 if (count ($objects) == 1)
2399 $obj = current ($objects);
2400 echo "<script language='Javascript'>document.location='${root}?page=object&object_id=${obj['id']}';//</script>";
2402 elseif (count ($objects) > 1)
2404 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
2405 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>barcode</th></tr>';
2408 foreach ($objects as $obj)
2410 echo "<tr class=row_${order}><td><a href=\"${root}?page=object&object_id=${obj['id']}\">${obj['dname']}</a></td>";
2411 echo "<td>${obj['label']}</td>";
2412 echo "<td>${obj['asset_no']}</td>";
2413 echo "<td>${obj['barcode']}</td></tr>";
2414 $order = $nextorder[$order];
2419 echo "Object '${terms}' not found!";
2423 // This function prints a table of checkboxes to aid the user in toggling mount atoms
2424 // from one state to another. The first argument is rack data as
2425 // produced by getRackData(), the second is the value used for the 'unckecked' state
2426 // and the third is the value used for 'checked' state.
2428 // for mounting an object: printAtomGrid ($data, 'F', 'T')
2429 // for changing rack design: printAtomGrid ($data, 'A', 'F')
2430 // for adding rack problem: printAtomGrid ($data, 'F', 'U')
2431 // for adding object problem: printAtomGrid ($data, 'T', 'W')
2433 function renderAtomGrid ($data)
2435 $rack_id = $data['id'];
2436 for ($unit_no = $data['height']; $unit_no > 0; $unit_no--)
2438 echo "<tr><th>${unit_no}</th>";
2439 for ($locidx = 0; $locidx < 3; $locidx++
)
2441 $state = $data[$unit_no][$locidx]['state'];
2442 echo "<td class=state_${state}";
2443 if (isset ($data[$unit_no][$locidx]['hl']))
2444 echo $data[$unit_no][$locidx]['hl'];
2446 if (!($data[$unit_no][$locidx]['enabled'] === TRUE))
2447 echo '<input type=checkbox disabled>';
2449 echo "<input type=checkbox" . $data[$unit_no][$locidx]['checked'] . " name=atom_${rack_id}_${unit_no}_${locidx}>";
2456 function renderPermissions ()
2458 startPortlet ('User permissions');
2459 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
2460 echo "<tr><th>Username</th><th>Page</th><th>Tab</th><th>Access</th></tr>";
2461 global $perms, $nextorder;
2463 foreach ($perms as $username => $pages)
2464 foreach ($pages as $page => $tabs)
2465 foreach ($tabs as $tab => $access)
2467 echo "<tr class=row_${order}><td class=tdleft>$username</td><td>$page</td><td>$tab</td><td>$access</td></tr>\n";
2468 $order = $nextorder[$order];
2474 function renderAccounts ()
2476 global $nextorder, $accounts;
2477 startPortlet ('User accounts');
2478 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
2479 echo "<tr><th class=tdleft>Username</th><th class=tdleft>Real name</th></tr>";
2481 foreach ($accounts as $user)
2483 echo "<tr class=row_${order}><td class=tdleft>${user['user_name']}</td><td class=tdleft>${user['user_realname']}</td></li>";
2484 $order = $nextorder[$order];
2490 function renderAccountsEditForm ()
2492 global $root, $pageno, $tabno, $accounts;
2493 startPortlet ('User accounts');
2494 showMessageOrError();
2495 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
2496 echo "<tr><th>op</th><th>Username</th><th>Real name</th><th>Password</th><th> </th></tr>\n";
2497 foreach ($accounts as $account)
2499 echo "<form action='${root}process.php'>";
2500 echo "<input type=hidden name=op value=updateAccount>";
2501 echo "<input type=hidden name=page value='${pageno}'>\n";
2502 echo "<input type=hidden name=tab value='${tabno}'>\n";
2503 echo "<input type=hidden name=id value='${account['user_id']}'><tr>";
2505 if ($account['user_enabled'] == 'yes' && $account['user_id'] != 1)
2507 echo "<a href='${root}process.php?op=disableAccount&page=${pageno}&tab=${tabno}&id=${account['user_id']}'>";
2508 printImageHREF ('blockuser', 'disable account');
2511 if ($account['user_enabled'] == 'no' && $account['user_id'] != 1)
2513 echo "<a href='${root}process.php?op=enableAccount&page=${pageno}&tab=${tabno}&id=${account['user_id']}'>";
2514 printImageHREF ('unblockuser', 'enable account');
2517 // Otherwise skip icon.
2519 echo "<td><input type=text name=username value='${account['user_name']}' size=16></td>";
2520 echo "<td><input type=text name=realname value='${account['user_realname']}' size=24></td>";
2521 echo "<td><input type=password name=password value='${account['user_password_hash']}' size=64></td>";
2522 echo "<td><input type='submit' value='OK'></td>";
2523 echo "</form></tr>\n";
2525 echo "<form action='${root}process.php' method=post><tr>";
2526 echo "<input type=hidden name=op value=createAccount>\n";
2527 echo "<input type=hidden name=page value='${pageno}'>\n";
2528 echo "<input type=hidden name=tab value='${tabno}'>\n";
2529 echo "<td colspan=2><input type=text size=16 name=username tabindex=100></td>\n";
2530 echo "<td><input type=text size=24 name=realname tabindex=101></td>";
2531 echo "<td><input type=password size=64 name=password tabindex=102></td>";
2532 echo "<td colspan=4><input type=submit value='Create account' tabindex=103></td></tr></form>";
2533 echo "</table><br>\n";
2537 function printChildrenAsOptions ($root, $depth = 0)
2539 echo "<option value=${root['title']}>";
2542 for ($i = 0; $i < $depth; $i++
)
2544 echo $root['title'];
2546 foreach ($root['kids'] as $kid)
2547 printChildrenAsOptions ($kid, $depth +
1);
2550 // 1. Find all parentless pages.
2551 // 2. For each of them recursively find all children.
2552 // 3. Output the tree with recursion tree display.
2553 function printPagesTree ()
2557 foreach ($page as $ctitle => $cpage)
2558 if (!isset ($cpage['parent']))
2560 $croot['title'] = $ctitle;
2561 $croot['kids'] = getAllChildPages ($ctitle);
2562 printChildrenAsOptions ($croot);
2567 function renderPermissionsEditForm ()
2569 global $root, $pageno, $tabno, $perms, $accounts;
2570 startPortlet ('User permissions');
2571 showMessageOrError();
2572 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
2573 echo "<tr><th> </th><th>Username</th><th>Page</th><th>Tab</th><th>Access</th></tr>\n";
2574 foreach ($perms as $username => $pages)
2575 foreach ($pages as $access_page => $tabs)
2576 foreach ($tabs as $access_tab => $access)
2579 if ($username != '%')
2580 $userid = $accounts[$username]['user_id'];
2583 echo "<a href='${root}process.php?op=revoke&page=${pageno}&tab=${tabno}&access_userid=${userid}&access_page=${access_page}&access_tab=${access_tab}'>";
2584 printImageHREF ('revoke', 'Revoke permission');
2586 echo "<td>${username}</td>";
2587 echo "<td>${access_page}</td>";
2588 echo "<td>${access_tab}</td>";
2589 echo "<td>${access}</td>";
2592 echo "<form action='${root}process.php' method=post><tr>";
2593 echo "<input type=hidden name=op value=grant>\n";
2594 echo "<input type=hidden name=page value='${pageno}'>\n";
2595 echo "<input type=hidden name=tab value='${tabno}'>\n";
2596 // FIXME: border=0 doesn't work here for unknown reason
2598 printImageHREF ('grant', '', TRUE, 103);
2600 echo "<td><select name=access_userid>";
2601 echo "<option value=0>ANY</option>";
2602 foreach ($accounts as $account)
2603 echo "<option value=${account['user_id']}>${account['user_name']}</option>";
2604 echo "</select></td>\n";
2605 echo "<td><select name=access_page>";
2606 echo "<option value='%'>ANY</option>";
2608 echo "</select></td>";
2609 echo "<td><input type=text size=16 name=access_tab tabindex=102 value=default></td>";
2610 echo "<td><input type=radio name=access_value value=no checked>no <input type=radio name=access_value value=yes>yes</td>";
2611 echo "</tr></form>";
2612 echo "</table><br>\n";
2616 function renderPortMap ($editable = FALSE)
2618 global $nextorder, $root, $pageno, $tabno;
2619 showMessageOrError();
2620 startPortlet ("Port compatibility map");
2621 $ptlist = getPortTypes();
2622 $pclist = getPortCompat();
2623 $pctable = buildPortCompatMatrixFromList ($ptlist, $pclist);
2626 echo "<form method=post action='${root}process.php'>";
2627 echo "<input type=hidden name=page value='${pageno}'>";
2628 echo "<input type=hidden name=tab value='${tabno}'>";
2629 echo "<input type=hidden name=op value=save>";
2631 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
2632 echo "<tr><th class=vert_th> </th>";
2633 foreach ($ptlist as $name2)
2634 echo "<th>to ${name2}</th>";
2636 // Make a copy to have an independent array pointer.
2639 foreach ($ptlistY as $type1 => $name1)
2641 echo "<tr class=row_${order}><th class=vert_th style='border-bottom: 0px;'>from $name1</th>";
2642 foreach ($ptlist as $type2 => $name2)
2644 echo '<td><input type=checkbox' . ($editable ?
" name=atom_${type1}_${type2}" : ' disabled');
2645 echo ($pctable[$type1][$type2] ?
' checked' : '') . '></td>';
2648 $order = $nextorder[$order];
2650 echo '</table><br>';
2653 echo "<input type=submit value='Save changes'>";
2659 function renderConfigMainpage ()
2661 global $pageno, $root;
2662 $children = getDirectChildPages ($pageno);
2664 // FIXME: assume all config kids to have static titles at the moment,
2665 // but use some proper abstract function later.
2666 foreach ($children as $cpageno => $child)
2667 echo "<li><a href='${root}?page=${cpageno}'>" . $child['title'] . "</li>\n";
2672 function renderRackPage ($rack_id)
2676 showError ('Invalid rack_id', __FUNCTION__
);
2679 if (($rackData = getRackData ($rack_id)) == NULL)
2681 showError ('getRackData() failed', __FUNCTION__
);
2684 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0><tr>";
2686 // Left column with information.
2687 echo "<td class=pcleft>";
2688 startPortlet ('Rack information');
2689 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
2690 echo "<tr><th width='50%' class=tdright>Rack row:</th><td class=tdleft>${rackData['row_name']}</td></tr>\n";
2691 echo "<tr><th width='50%' class=tdright>Name:</th><td class=tdleft>${rackData['name']}</td></tr>\n";
2692 echo "<tr><th width='50%' class=tdright>Height:</th><td class=tdleft>${rackData['height']}</td></tr>\n";
2693 echo "<tr><th width='50%' class=tdright>Utilization:</th><td class=tdleft>";
2694 renderProgressBar (getRSUforRack ($rackData));
2695 echo "</td></tr>\n";
2696 echo "<tr><th width='50%' class=tdright>Objects:</th><td class=tdleft>";
2697 echo getObjectCount ($rackData);
2698 echo "</td></tr>\n";
2699 if (!empty ($rackData['comment']))
2700 echo "<tr><th width='50%' class=tdright>Comment:</th><td class=tdleft>${rackData['comment']}</td></tr>\n";
2705 // Right column with rendered rack.
2707 startPortlet ('Rack diagram');
2708 renderRack ($rack_id);
2712 echo '</tr></table>';
2715 function renderDictionary ()
2719 echo "<br><table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
2720 foreach ($dict as $chapter_no => $chapter)
2723 echo "<tr><th>Chapter</th><th>refs</th><th>Word</th></tr>\n";
2724 $wc = count ($chapter['word']);
2725 echo "<tr class=row_${order}><td class=tdleft" . ($wc ?
" rowspan = ${wc}" : '');
2726 echo "><div title='number=${chapter_no}'>${chapter['name']} (${wc} records)</div></td>";
2728 echo "<td colspan=2>none</td>";
2732 foreach ($chapter['word'] as $key => $value)
2735 echo "<tr class=row_${order}>";
2737 $chap_start = FALSE;
2738 echo '<td>' . ($chapter['refcnt'][$key] ?
$chapter['refcnt'][$key] : ' ') . '</td>';
2739 echo "<td><div title='key=${key}'>${value}</div></td></tr>\n";
2740 $order = $nextorder[$order];
2747 function renderDictionaryEditor ()
2749 global $root, $pageno, $tabno, $nextorder;
2751 showMessageOrError();
2752 echo "<br><table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
2753 foreach ($dict as $chapter_no => $chapter)
2756 echo "<tr><th>Chapter</th><th> </th><th>Word</th><th> </th></tr>\n";
2757 $wc = count ($chapter['word']);
2758 // One extra span for the new record per each chapter block.
2759 echo "<tr class=row_${order}><td class=tdleft" . ($wc ?
' rowspan = ' . ($wc +
1) : '');
2760 echo "><div title='number=${chapter_no}'>${chapter['name']} (${wc} records)</div></td>";
2761 echo "<form action='${root}process.php' method=post>";
2762 echo "<input type=hidden name=page value='${pageno}'>";
2763 echo "<input type=hidden name=tab value='${tabno}'>";
2764 echo "<input type=hidden name=op value=add>";
2765 echo "<input type=hidden name=chapter_no value='${chapter['no']}'>";
2766 echo "<td> </td>";
2767 echo "<td class=tdright><input type=text name=dict_value size=32></td>";
2768 echo "<td><input type=submit value='Add new'></td>";
2769 echo '</tr></form>';
2770 $order = $nextorder[$order];
2771 foreach ($chapter['word'] as $key => $value)
2773 echo "<form action='${root}process.php' method=post>";
2774 echo "<input type=hidden name=page value='${pageno}'>";
2775 echo "<input type=hidden name=tab value='${tabno}'>";
2776 echo "<input type=hidden name=op value='upd'>";
2777 echo "<input type=hidden name=chapter_no value='${chapter['no']}'>";
2778 echo "<input type=hidden name=dict_key value='${key}'>";
2779 echo "<tr class=row_${order}><td>";
2780 // Prevent deleting words currently used somewhere.
2781 if ($chapter['refcnt'][$key])
2782 printImageHREF ('nodelete', 'referenced ' . $chapter['refcnt'][$key] . ' time(s)');
2785 echo "<a href='${root}process.php?page=${pageno}&tab=${tabno}&op=del&chapter_no=${chapter['no']}&dict_key=${key}'>";
2786 printImageHREF ('delete', 'Delete word');
2790 echo "<td class=tdright><input type=text name=dict_value size=32 value='${value}'></td>";
2791 echo "<td><input type=submit value=OK></td>";
2792 echo "</tr></form>\n";
2793 $order = $nextorder[$order];
2794 } // foreach ($chapter['word']
2799 // We don't allow to rename/delete a sticky chapter and we don't allow
2800 // to delete a non-empty chapter.
2801 function renderChaptersEditor ()
2803 global $root, $pageno, $tabno;
2804 showMessageOrError();
2806 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
2807 echo '<tr><th> </th><th>Chapter name</th><th>Words</th><th> </th></tr>';
2808 foreach ($dict as $chapter)
2810 $wordcount = count ($chapter['word']);
2811 $sticky = $chapter['sticky'];
2812 echo "<form action='${root}process.php' method=post>";
2813 echo "<input type=hidden name=page value='${pageno}'>";
2814 echo "<input type=hidden name=tab value='${tabno}'>";
2815 echo "<input type=hidden name=op value=upd>";
2816 echo "<input type=hidden name=chapter_no value='${chapter['no']}'>";
2820 printImageHREF ('nodelete', 'system chapter');
2821 elseif ($wordcount > 0)
2822 printImageHREF ('nodelete', 'contains ' . $wordcount . ' word(s)');
2825 echo "<a href='${root}process.php?page=${pageno}&tab=${tabno}&op=del&chapter_no=${chapter['no']}'>";
2826 printImageHREF ('delete', 'Remove chapter');
2830 echo "<td><input type=text name=chapter_name value='${chapter['name']}'" . ($sticky ?
' disabled' : '') . "></td>";
2831 echo "<td class=tdleft>${wordcount}</td><td>";
2835 echo "<input type=submit value='OK'>";
2839 echo "<form action='${root}process.php' method=post>";
2840 echo "<input type=hidden name=page value='${pageno}'>";
2841 echo "<input type=hidden name=tab value='${tabno}'>";
2842 echo "<input type=hidden name=op value=add>";
2844 printImageHREF ('add', '', TRUE);
2845 echo "</td><td colspan=3><input type=text name=chapter_name></td>";
2851 function renderAttributes ()
2854 $attrMap = getAttrMap();
2855 startPortlet ('Optional attributes');
2856 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
2857 echo "<tr><th class=tdleft>Attribute name</th><th class=tdleft>Attribute type</th><th class=tdleft>Applies to</th></tr>";
2859 foreach ($attrMap as $attr)
2861 echo "<tr class=row_${order}>";
2862 echo "<td class=tdleft>${attr['name']}</td>";
2863 echo "<td class=tdleft>${attr['type']}</td>";
2864 echo '<td class=tdleft>';
2865 if (count ($attr['application']) == 0)
2868 foreach ($attr['application'] as $app)
2869 if ($attr['type'] == 'dict')
2870 echo "${app['objtype_name']} (values from '${app['chapter_name']}')<br>";
2872 echo "${app['objtype_name']}<br>";
2875 $order = $nextorder[$order];
2877 echo "</table><br>\n";
2881 function renderEditAttributesForm ()
2883 global $root, $pageno, $tabno;
2884 $attrMap = getAttrMap();
2885 showMessageOrError();
2886 startPortlet ('Optional attributes');
2887 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
2888 echo '<tr><th> </th><th>Name</th><th>Type</th><th> </th></tr>';
2889 foreach ($attrMap as $attr)
2891 echo "<form action='${root}process.php' method=post>";
2892 echo "<input type=hidden name=page value='${pageno}'>";
2893 echo "<input type=hidden name=tab value='${tabno}'>";
2894 echo "<input type=hidden name=op value=upd>";
2895 echo "<input type=hidden name=attr_id value='${attr['id']}'>";
2897 echo "<td><a href='${root}process.php?page=${pageno}&tab=${tabno}&op=del&attr_id=${attr['id']}'>";
2898 printImageHREF ('delete', 'Remove attribute');
2900 echo "<td><input type=text name=attr_name value='${attr['name']}'></td>";
2901 echo "<td>${attr['type']}</td>";
2902 echo "<td><input type=submit value='OK'></td>";
2906 echo "<form action='${root}process.php' method=post>";
2907 echo "<input type=hidden name=page value='${pageno}'>";
2908 echo "<input type=hidden name=tab value='${tabno}'>";
2909 echo "<input type=hidden name=op value=add>";
2911 printImageHREF ('add', '', TRUE);
2912 echo "</td><td><input type=text name=attr_name></td>";
2913 echo '<td><select name=attr_type>';
2914 echo '<option value=uint>uint</option>';
2915 echo '<option value=float>float</option>';
2916 echo '<option value=string>string</option>';
2917 echo '<option value=dict>dict</option>';
2918 echo '</select></td>';
2925 function renderEditAttrMapForm ()
2927 global $root, $pageno, $tabno;
2928 $attrMap = getAttrMap();
2929 showMessageOrError();
2930 startPortlet ('Attribute map');
2931 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
2932 echo '<tr><th> </th><th>Attribute name</th><th>Object type</th><th>Dictionary chapter</th></tr>';
2933 foreach ($attrMap as $attr)
2935 if (count ($attr['application']) == 0)
2937 foreach ($attr['application'] as $app)
2941 echo "<a href='${root}process.php?page=${pageno}&tab=${tabno}&op=del&";
2942 echo "attr_id=${attr['id']}&objtype_id=${app['objtype_id']}'>";
2943 printImageHREF ('delete', 'Remove mapping');
2946 echo "<td>${attr['name']}</td>";
2947 echo "<td>${app['objtype_name']}</td>";
2949 if ($attr['type'] == 'dict')
2950 echo "${app['chapter_name']}";
2953 echo "</td></tr>\n";
2956 echo "<form action='${root}process.php' method=post>";
2957 echo "<input type=hidden name=page value='${pageno}'>";
2958 echo "<input type=hidden name=tab value='${tabno}'>";
2959 echo "<input type=hidden name=op value=add>";
2961 printImageHREF ('add', '', TRUE);
2962 echo "</td><td><select name=attr_id>";
2963 $shortType['uint'] = 'U';
2964 $shortType['float'] = 'F';
2965 $shortType['string'] = 'S';
2966 $shortType['dict'] = 'D';
2967 foreach ($attrMap as $attr)
2968 echo "<option value=${attr['id']}>[" . $shortType[$attr['type']] . "] ${attr['name']}</option>";
2969 echo "</select></td>";
2971 printSelect (getObjectTypeList(), 'objtype_id');
2974 echo '<td><select name=chapter_no>';
2975 foreach ($dict as $chapter)
2976 if (!$chapter['sticky'])
2977 echo "<option value='${chapter['no']}'>${chapter['name']}</option>";
2978 echo '</select></td>';
2985 function printImageHREF ($tag, $title = '', $do_input = FALSE, $tabindex = 0)
2988 $image['error']['path'] = 'pix/error.png';
2989 $image['error']['width'] = 76;
2990 $image['error']['height'] = 17;
2991 $image['logo']['path'] = 'pix/defaultlogo.png';
2992 $image['logo']['width'] = 210;
2993 $image['logo']['height'] = 40;
2994 $image['rackspace']['path'] = 'pix/racks.png';
2995 $image['rackspace']['width'] = 218;
2996 $image['rackspace']['height'] = 200;
2997 $image['objects']['path'] = 'pix/server.png';
2998 $image['objects']['width'] = 218;
2999 $image['objects']['height'] = 200;
3000 $image['ipv4space']['path'] = 'pix/addressspace.png';
3001 $image['ipv4space']['width'] = 218;
3002 $image['ipv4space']['height'] = 200;
3003 $image['ipv4slb']['path'] = 'pix/slb.png';
3004 $image['ipv4slb']['width'] = 218;
3005 $image['ipv4slb']['height'] = 200;
3006 $image['config']['path'] = 'pix/configuration.png';
3007 $image['config']['width'] = 218;
3008 $image['config']['height'] = 200;
3009 $image['reports']['path'] = 'pix/report.png';
3010 $image['reports']['width'] = 218;
3011 $image['reports']['height'] = 200;
3012 $image['help']['path'] = 'pix/help.png';
3013 $image['help']['width'] = 218;
3014 $image['help']['height'] = 200;
3015 $image['reserve']['path'] = 'pix/stop.png';
3016 $image['reserve']['width'] = 16;
3017 $image['reserve']['height'] = 16;
3018 $image['useup']['path'] = 'pix/go.png';
3019 $image['useup']['width'] = 16;
3020 $image['useup']['height'] = 16;
3021 $image['blockuser'] = $image['reserve'];
3022 $image['unblockuser'] = $image['useup'];
3023 $image['link']['path'] = 'pix/link.png';
3024 $image['link']['width'] = 24;
3025 $image['link']['height'] = 24;
3026 $image['unlink']['path'] = 'pix/unlink.png';
3027 $image['unlink']['width'] = 24;
3028 $image['unlink']['height'] = 24;
3029 $image['add']['path'] = 'pix/greenplus.png';
3030 $image['add']['width'] = 16;
3031 $image['add']['height'] = 16;
3032 $image['delete']['path'] = 'pix/delete_s.gif';
3033 $image['delete']['width'] = 16;
3034 $image['delete']['height'] = 16;
3035 $image['nodelete']['path'] = 'pix/delete_g.png';
3036 $image['nodelete']['width'] = 16;
3037 $image['nodelete']['height'] = 16;
3038 $image['grant'] = $image['add'];
3039 $image['revoke'] = $image['delete'];
3040 $image['helphint']['path'] = 'pix/helphint.png';
3041 $image['helphint']['width'] = 24;
3042 $image['helphint']['height'] = 24;
3043 $image['inservice']['path'] = 'pix/go.png';
3044 $image['inservice']['width'] = 16;
3045 $image['inservice']['height'] = 16;
3046 $image['notinservice']['path'] = 'pix/stop.png';
3047 $image['notinservice']['width'] = 16;
3048 $image['notinservice']['height'] = 16;
3049 $image['find']['path'] = 'pix/find.png';
3050 $image['find']['width'] = 16;
3051 $image['find']['height'] = 16;
3052 if (!isset ($image[$tag]))
3054 $img = $image[$tag];
3055 if ($do_input == TRUE)
3057 "<input type=image name=submit " .
3058 "src='${root}${img['path']}' " .
3060 ($tabindex ?
'' : "tabindex=${tabindex}") .
3065 "src='${root}${img['path']}' " .
3066 "width=${img['width']} " .
3067 "height=${img['height']} " .
3069 (empty ($title) ?
'' : "title='${title}'") .
3073 // This function returns URL for favourite icon.
3074 function getFaviconURL ()
3077 return $root . 'pix/racktables.ico';
3080 function renderReportSummary ()
3082 echo "<table width='100%'>\n";
3083 echo "<tr><td class=pcleft>\n";
3084 startPortlet ("Dictionary/objects stats");
3086 foreach (getDictStats() as $header => $data)
3087 echo "<tr><th class=tdright>${header}:</th><td class=tdleft>${data}</td></tr>\n";
3090 startPortlet ('IPv4 stats');
3092 foreach (getIPv4Stats() as $header => $data)
3093 echo "<tr><th class=tdright>${header}:</th><td class=tdleft>${data}</td></tr>\n";
3096 startPortlet ('Rackspace stats');
3098 foreach (getRackspaceStats() as $header => $data)
3099 echo "<tr><th class=tdright>${header}:</th><td class=tdleft>${data}</td></tr>\n";
3103 echo "</td><td class=pcright>\n";
3105 startPortlet ("Here be dragons");
3109 echo 'ASCII art © Daniel C. Au';
3111 echo "</td></tr>\n";
3118 <div
class=dragon
><pre
><font color
="#00ff33">
3120 |
<font color
="#ff0000">@</font
>___oo
3121 /\
/\
/ (__
<font color
=yellow
>,,,,</font
>|
3126 <
; >
; |
(<font color
=white
>,,</font
>) )__
)
3129 \
______(_______
<font color
=white
>;;;</font
> __
<font color
=white
>;;;</font
>
3135 function renderUIConfig ()
3137 global $configCache, $nextorder;
3138 showMessageOrError();
3139 startPortlet ('Current configuration');
3140 echo '<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center width="50%">';
3141 echo '<tr><th class=tdleft>Option</th><th class=tdleft>Value</th></tr>';
3143 foreach ($configCache as $v)
3145 if ($v['is_hidden'] != 'no')
3147 echo "<tr class=row_${order}>";
3148 echo "<td class=tdright>${v['description']}</td>\n";
3149 echo "<td class=tdleft>${v['varvalue']}</td></tr>";
3150 $order = $nextorder[$order];
3156 function renderUIConfigEditForm ()
3158 global $root, $pageno, $tabno, $configCache;
3159 showMessageOrError();
3160 startPortlet ('Current configuration');
3161 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable width='50%'>\n";
3162 echo "<tr><th class=tdleft>Option</th>";
3163 echo "<th class=tdleft>Value</th></tr>";
3164 echo "<form action='${root}process.php'>";
3165 echo "<input type=hidden name=op value='upd'>";
3166 echo "<input type=hidden name=page value='${pageno}'>\n";
3167 echo "<input type=hidden name=tab value='${tabno}'>\n";
3170 foreach ($configCache as $v)
3172 if ($v['is_hidden'] != 'no')
3174 echo "<input type=hidden name=${i}_varname value='${v['varname']}'>";
3175 echo "<tr><td class=tdright>${v['description']}</td>";
3176 echo "<td class=tdleft><input type=text name=${i}_varvalue value='${v['varvalue']}' size=24></td>";
3180 echo "<input type=hidden name=num_vars value=${i}>\n";
3181 echo "<tr><td colspan=2><input type=submit value='Save changes'></td></tr>";
3186 // This function queries the gateway about current VLAN configuration and
3187 // renders a form suitable for submit. Ah, and it does submit processing as well.
3188 function renderVLANMembership ($object_id = 0)
3190 global $root, $pageno, $tabno, $remote_username;
3191 if ($object_id <= 0)
3193 showError ('Invalid object_id', __FUNCTION__
);
3197 // Handle probable pending submit.
3198 if (isset ($_REQUEST['portcount']))
3200 $data = getSwitchVLANs ($object_id);
3203 showError ('getSwitchVLANs() failed during submit processing', __FUNCTION__
);
3206 list ($vlanlist, $portlist) = $data;
3207 // Here we just build up 1 set command for the gateway with all of the ports
3208 // included. The gateway is expected to filter unnecessary changes silently
3209 // and to provide a list of responses with either error or success message
3210 // for each of the rest.
3211 assertUIntArg ('portcount');
3212 $nports = $_REQUEST['portcount'];
3216 for ($i = 0; $i < $nports; $i++
)
3219 !isset ($_REQUEST['portname_' . $i]) ||
3220 !isset ($_REQUEST['vlanid_' . $i]) ||
3221 $_REQUEST['portname_' . $i] != $portlist[$i]['portname']
3223 $log[] = array ('code' => 'error', 'message' => "Ignoring malformed record #${i} in form submit");
3226 $_REQUEST['vlanid_' . $i] == $portlist[$i]['vlanid'] ||
3227 $portlist[$i]['vlaind'] == 'TRUNK'
3232 $setcmd .= $prefix . $_REQUEST['portname_' . $i] . '=' . $_REQUEST['vlanid_' . $i];
3236 // Feed the gateway and interpret its (non)response.
3238 printLog (setSwitchVLANs ($object_id, $setcmd));
3241 // Reload and render.
3242 $data = getSwitchVLANs ($object_id);