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 ()
62 $tagfilter = getTagFilter();
63 $tagfilter_str = getTagFilterStr ($tagfilter);
64 echo "<table class=objview border=0 width='100%'><tr><td class=pcleft>";
65 renderTagFilterPortlet ($tagfilter, 'rack');
66 echo '</td><td class=pcright>';
67 echo '<table border=0 cellpadding=10 cellpadding=1>';
68 // generate thumb gallery
69 $rackrowList = getRackspace ($tagfilter);
70 global $root, $nextorder;
71 $rackwidth = getConfigVar ('rtwidth_0') +
getConfigVar ('rtwidth_1') +
getConfigVar ('rtwidth_2');
73 foreach ($rackrowList as $rackrow)
75 echo "<tr class=row_${order}><th class=tdleft>";
76 echo "<a href='${root}?page=row&row_id=${rackrow['row_id']}${tagfilter_str}'>";
77 echo "${rackrow['row_name']}</a></th>";
78 $rackList = getRacksForRow ($rackrow['row_id'], $tagfilter);
79 echo "<td><table border=0 cellspacing=5><tr>";
80 foreach ($rackList as $rack)
82 echo "<td align=center><a href='${root}?page=rack&rack_id=${rack['id']}'>";
83 echo "<img border=0 width=${rackwidth} height=";
84 echo 3 +
3 +
$rack['height'] * 2;
85 echo " title='${rack['height']} units'";
86 echo "src='render_image.php?img=minirack&rack_id=${rack['id']}'>";
87 echo "<br>${rack['name']}</a></td>";
89 echo "</tr></table></tr>\n";
90 $order = $nextorder[$order];
93 echo "</td></tr></table>\n";
96 function renderRow ($row_id)
100 showError ('Invalid row_id', __FUNCTION__
);
103 if (($rowInfo = getRackRowInfo ($row_id)) == NULL)
105 showError ('getRackRowInfo() failed', __FUNCTION__
);
108 $tagfilter = getTagFilter();
109 $rackList = getRacksForRow ($row_id, $tagfilter);
110 // Main layout starts.
111 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
113 // Left portlet with row information.
114 echo "<tr><td class=pcleft>";
115 startPortlet ($rowInfo['name']);
116 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
117 echo "<tr><th width='50%' class=tdright>Racks:</th><td class=tdleft>${rowInfo['count']}</td></tr>\n";
118 echo "<tr><th width='50%' class=tdright>Units:</th><td class=tdleft>${rowInfo['sum']}</td></tr>\n";
119 echo "<tr><th width='50%' class=tdright>Utilization:</th><td class=tdleft>";
120 renderProgressBar (getRSUforRackRow ($rackList));
122 echo "</table><br>\n";
125 echo "</td><td class=pcright rowspan=2>";
127 global $root, $nextorder;
128 $rackwidth = getConfigVar ('rtwidth_0') +
getConfigVar ('rtwidth_1') +
getConfigVar ('rtwidth_2');
130 startPortlet ('Racks');
131 echo "<table border=0 cellspacing=5 align='center'><tr>";
132 foreach ($rackList as $rack)
134 echo "<td align=center class=row_${order}><a href='${root}?page=rack&rack_id=${rack['id']}'>";
135 echo "<img border=0 width=" . $rackwidth * getConfigVar ('ROW_SCALE') . " height=";
136 echo (3 +
3 +
$rack['height'] * 2) * getConfigVar ('ROW_SCALE');
137 echo " title='${rack['height']} units'";
138 echo "src='render_image.php?img=minirack&rack_id=${rack['id']}'>";
139 echo "<br>${rack['name']}</a></td>";
140 $order = $nextorder[$order];
142 echo "</tr></table>\n";
146 echo "<tr><td class=pcleft>";
147 renderTagFilterPortlet ($tagfilter, 'rack', 'row_id', $row_id);
148 echo "</td></tr></table>";
151 function showError ($info = '', $funcname = 'N/A')
154 echo "<div class=msg_error>An error has occured in function [${funcname}]. ";
156 echo 'No additional information is available.';
158 echo "Additional information:<br><p>\n<pre>\n${info}\n</pre></p>";
159 echo "Go back or try starting from <a href='${root}'>index page</a>.<br></div>\n";
162 // This function renders rack as HTML table.
163 function renderRack ($rack_id = 0, $hl_obj_id = 0)
167 showError ('Invalid rack_id', __FUNCTION__
);
170 if (($rackData = getRackData ($rack_id)) == NULL)
172 showError ('getRackData() failed', __FUNCTION__
);
175 global $root, $pageno, $tabno;
176 markAllSpans ($rackData);
178 highlightObject ($rackData, $hl_obj_id);
179 markupObjectProblems ($rackData);
180 $prev_id = getPrevIDforRack ($rackData['row_id'], $rack_id);
181 $next_id = getNextIDforRack ($rackData['row_id'], $rack_id);
182 echo "<center><table border=0><tr valign=middle>";
183 echo "<td><h2><a href='${root}?page=row&row_id=${rackData['row_id']}'>${rackData['row_name']}</a> :</h2></td>";
184 // FIXME: use 'bypass'?
185 if ($prev_id != NULL)
187 echo "<td><a href='${root}?page=rack&rack_id=${prev_id}'>";
188 printImageHREF ('prev', 'previous rack');
191 echo "<td><h2><a href='${root}?page=rack&rack_id=${rackData['id']}'>${rackData['name']}</a></h2></td>";
192 if ($next_id != NULL)
194 echo "<td><a href='${root}?page=rack&rack_id=${next_id}'>";
195 printImageHREF ('next', 'next rack');
198 echo "</h2></td></tr></table>\n";
199 if ($rackData['left_is_front'] == 'yes')
200 $markup = array ('left' => 'Front', 'right' => 'Back');
202 $markup = array ('left' => 'Back', 'right' => 'Front');
203 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
204 echo "<tr><th width='10%'> </th><th width='20%'>${markup['left']}</th>";
205 echo "<th width='50%'>Interior</th><th width='20%'>${markup['right']}</th></tr>\n";
206 for ($i = $rackData['height']; $i > 0; $i--)
208 echo '<tr><th>' . ($rackData['bottom_is_unit1'] == 'yes' ?
$i : $rackData['height'] - $i +
1) . '</th>';
209 for ($locidx = 0; $locidx < 3; $locidx++
)
211 if (isset ($rackData[$i][$locidx]['skipped']))
213 $state = $rackData[$i][$locidx]['state'];
214 echo "<td class=state_${state}";
215 if (isset ($rackData[$i][$locidx]['hl']))
216 echo $rackData[$i][$locidx]['hl'];
217 if (isset ($rackData[$i][$locidx]['colspan']))
218 echo ' colspan=' . $rackData[$i][$locidx]['colspan'];
219 if (isset ($rackData[$i][$locidx]['rowspan']))
220 echo ' rowspan=' . $rackData[$i][$locidx]['rowspan'];
225 $objectData = getObjectInfo ($rackData[$i][$locidx]['object_id']);
226 if (!empty ($objectData['asset_no']))
227 $prefix = "<div title='${objectData['asset_no']}";
229 $prefix = "<div title='no asset tag";
230 // Don't tell about label, if it matches common name.
231 if ($objectData['name'] != $objectData['label'] and !empty ($objectData['label']))
232 $suffix = ", visible label is \"${objectData['label']}\"'>";
235 echo $prefix . $suffix;
236 echo "<a href='${root}?page=object&object_id=${objectData['id']}'>${objectData['dname']}</a></div>";
239 echo '<div title="This rackspace does not exist"> </div>';
242 echo '<div title="Free rackspace"> </div>';
245 echo '<div title="Problematic rackspace, you CAN\'T mount here"> </div>';
248 echo '<div title="No data"> </div>';
255 echo "</table></center>\n";
258 function renderNewRackForm ($row_id)
260 global $pageno, $tabno;
262 $taglist = isset ($_REQUEST['taglist']) ?
$_REQUEST['taglist'] : array();
264 // Look for current submit.
265 if (isset ($_REQUEST['got_data']))
267 assertStringArg ('rack_name', __FUNCTION__
);
268 assertUIntArg ('rack_height1', __FUNCTION__
);
269 assertStringArg ('rack_comment', __FUNCTION__
, TRUE);
270 $name = $_REQUEST['rack_name'];
272 if (commitAddRack ($name, $_REQUEST['rack_height1'], $row_id, $_REQUEST['rack_comment'], $taglist) === TRUE)
273 $log[] = array ('code' => 'success', 'message' => "Added new rack '${name}'");
275 $log[] = array ('code' => 'error', 'message' => __FUNCTION__
. ': commitAddRack() failed');
277 elseif (isset ($_REQUEST['got_mdata']))
279 assertUIntArg ('rack_height2', __FUNCTION__
);
280 assertStringArg ('rack_names', __FUNCTION__
, TRUE);
281 // copy-and-paste from renderAddMultipleObjectsForm()
282 $names1 = explode ('\n', $_REQUEST['rack_names']);
284 foreach ($names1 as $line)
286 $parts = explode ('\r', $line);
288 if (empty ($parts[0]))
291 $names2[] = rtrim ($parts[0]);
293 foreach ($names2 as $cname)
294 if (commitAddRack ($cname, $_REQUEST['rack_height2'], $row_id, '', $taglist) === TRUE)
295 $log[] = array ('code' => 'success', 'message' => "Added new rack '${cname}'");
297 $log[] = array ('code' => 'error', 'message' => __FUNCTION__
. ': commitAddRack() failed');
301 echo "<table border=0 width='100%'><tr><td valign=top>";
302 // Render a form for the next.
303 startPortlet ('Add one');
305 echo "<input type=hidden name=page value=${pageno}>";
306 echo "<input type=hidden name=tab value=${tabno}>";
307 echo "<input type=hidden name=row_id value=${row_id}>";
308 echo '<table border=0 align=center>';
309 $defh = getConfigVar ('DEFAULT_RACK_HEIGHT');
312 echo "<tr><th class=tdright>Rack name (*):</th><td class=tdleft><input type=text name=rack_name tabindex=1></td></tr>\n";
313 echo "<tr><th class=tdright>Height in units (*):</th><td class=tdleft><input type=text name=rack_height1 tabindex=2 value='${defh}'></td></tr>\n";
314 echo "<tr><th class=tdright>Comment:</th><td class=tdleft><input type=text name=rack_comment tabindex=3></td></tr>\n";
315 echo "<tr><td class=submit colspan=2><input type=submit name=got_data value='Add'></td></tr>\n";
320 echo '<td rowspan=2 valign=top>';
321 startPortlet ('Pre-assigned tags');
326 echo '<tr><td valign=top>';
327 startPortlet ('Add many');
328 echo '<table border=0 align=center>';
329 $defh = getConfigVar ('DEFAULT_RACK_HEIGHT');
332 echo "<tr><th class=tdright>Height in units (*):</th><td class=tdleft><input type=text name=rack_height2 value='${defh}'></td></tr>\n";
333 echo "<tr><th class=tdright>Rack names (*):</th><td class=tdleft><textarea name=rack_names cols=40 rows=25></textarea></td></tr>\n";
334 echo "<tr><td class=submit colspan=2><input type=submit name=got_mdata value='Add'></td></tr>\n";
335 echo '</form></table>';
341 function renderEditObjectForm ($object_id)
343 showMessageOrError();
345 global $pageno, $tabno, $root;
346 $object = getObjectInfo ($object_id);
349 showError ('getObjectInfo() failed', __FUNCTION__
);
352 echo '<table border=0 width=100%><tr>';
354 echo '<td class=pcleft>';
355 startPortlet ('Static attributes');
356 echo "<form method=post action='${root}process.php?page=${pageno}&tab=${tabno}&op=update'>";
357 echo "<input type=hidden name=object_id value=${object_id}>";
358 echo '<table border=0 align=center>';
359 echo "<tr><th class=tdright>Type:</th><td class=tdleft>";
360 printSelect (getObjectTypeList(), 'object_type_id', $object['objtype_id']);
363 echo "<tr><th class=tdright>Common name:</th><td class=tdleft><input type=text name=object_name value='${object['name']}'></td></tr>\n";
364 echo "<tr><th class=tdright>Visible label:</th><td class=tdleft><input type=text name=object_label value='${object['label']}'></td></tr>\n";
365 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";
366 echo "<tr><th class=tdright>Barcode:</th><td class=tdleft><input type=text name=object_barcode value='${object['barcode']}'></td></tr>\n";
367 echo "<tr><th class=tdright>Has problems:</th><td class=tdleft><input type=checkbox name=object_has_problems";
368 if ($object['has_problems'] == 'yes')
370 echo "></td></tr>\n";
371 echo "<tr><td colspan=2><b>Comment:</b><br><textarea name=object_comment rows=10 cols=80>${object['comment']}</textarea></td></tr>";
372 echo "<tr><th class=submit colspan=2>";
373 printImageHREF ('SAVE', 'Save changes', TRUE);
375 echo '</form></table><br>';
380 echo '<td class=pcright>';
381 startPortlet ('Optional attributes');
382 $values = getAttrValues ($object_id);
383 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
384 echo "<tr><th> </th><th>Attribute</th><th>Value</th><th> </th></tr>\n";
385 echo "<form method=post action='${root}process.php?page=${pageno}&tab=${tabno}&op=updateStickers'>\n";
386 echo "<input type=hidden name=object_id value=${object_id}>\n";
387 echo '<input type=hidden name=num_attrs value=' . count($values) . ">\n";
390 foreach ($values as $record)
392 echo "<input type=hidden name=${i}_attr_id value=${record['id']}>";
394 if (!empty ($record['value']))
396 echo "<a href='${root}process.php?page=${pageno}&tab=${tabno}&op=clearSticker&object_id=${object_id}&attr_id=${record['id']}'>";
397 printImageHREF ('clear', 'Clear value');
403 echo "<td class=tdright>${record['name']}:</td><td class=tdleft>";
404 switch ($record['type'])
409 echo "<input type=text name=${i}_value value='${record['value']}'>";
412 $chapter = readChapter ($record['chapter_name']);
413 $chapter[0] = '-- NOT SET --';
414 printSelect ($chapter, "${i}_value", $record['key']);
420 echo "<tr><td colspan=3>";
421 printImageHREF ('SAVE', 'Save changes', TRUE);
430 echo '<td colspan=2>';
431 startPortlet ('history');
432 renderHistory ($pageno, $object_id);
436 echo '</tr></table>';
439 // This is a clone of renderEditObjectForm().
440 function renderEditRackForm ($rack_id)
443 if (isset ($_REQUEST['got_data']))
446 assertUIntArg ('rack_row_id', __FUNCTION__
);
447 assertUIntArg ('rack_height', __FUNCTION__
);
448 assertStringArg ('rack_name', __FUNCTION__
);
449 assertStringArg ('rack_comment', __FUNCTION__
, TRUE);
450 $row_id = $_REQUEST['rack_row_id'];
451 $height = $_REQUEST['rack_height'];
452 $name = $_REQUEST['rack_name'];
453 $comment = $_REQUEST['rack_comment'];
455 if (commitUpdateRack ($rack_id, $name, $height, $row_id, $comment) === TRUE)
456 $log[] = array ('code' => 'success', 'message' => "Updated rack '${name}'");
458 $log[] = array ('code' => 'error', 'message' => __FUNCTION__
. ': commitUpdateRack() failed');
459 resetThumbCache ($rack_id);
463 global $pageno, $tabno;
464 $rack = getRackData ($rack_id);
467 showError ('getRackData() failed', __FUNCTION__
);
471 // Render a form for the next.
472 startPortlet ('Rack attributes');
474 echo "<input type=hidden name=page value=${pageno}>";
475 echo "<input type=hidden name=tab value=${tabno}>";
476 echo "<input type=hidden name=rack_id value=${rack_id}>";
477 echo '<table border=0 align=center>';
478 echo "<tr><th class=tdright>Rack row:</th><td class=tdleft>";
479 printSelect (readChapter ('RackRow'), 'rack_row_id', $rack['row_id']);
481 echo "<tr><th class=tdright>Name (required):</th><td class=tdleft><input type=text name=rack_name value='${rack['name']}'></td></tr>\n";
482 echo "<tr><th class=tdright>Height (required):</th><td class=tdleft><input type=text name=rack_height value='${rack['height']}'></td></tr>\n";
483 echo "<tr><th class=tdright>Comment:</th><td class=tdleft><input type=text name=rack_comment value='${rack['comment']}'></td></tr>\n";
484 echo "<tr><td class=submit colspan=2><input type=submit name=got_data value='Update'></td></tr>\n";
485 echo '</form></table><br>';
488 startPortlet ('History');
489 renderHistory ($pageno, $rack_id);
493 // This is a helper for creators and editors.
494 function printSelect ($rowList, $select_name, $selected_id = 1)
496 // First collect all data for OPTGROUPs, then ouput it and dump
497 // the rest of records as is.
500 foreach ($rowList as $dict_key => $dict_value)
502 if (strpos ($dict_value, '%GSKIP%') !== FALSE)
504 $tmp = explode ('%GSKIP%', $dict_value, 2);
505 $optgroup[$tmp[0]][$dict_key] = $tmp[1];
507 elseif (strpos ($dict_value, '%GPASS%') !== FALSE)
509 $tmp = explode ('%GPASS%', $dict_value, 2);
510 $optgroup[$tmp[0]][$dict_key] = $tmp[1];
513 $other[$dict_key] = $dict_value;
515 echo "<select name=${select_name}>";
516 if (!count ($optgroup))
518 foreach ($other as $dict_key => $dict_value)
520 echo "<option value=${dict_key}";
521 if ($dict_key == $selected_id)
523 echo ">${dict_value}</option>";
528 foreach ($optgroup as $groupname => $groupdata)
530 echo "<optgroup label='${groupname}'>";
531 foreach ($groupdata as $dict_key => $dict_value)
533 echo "<option value=${dict_key}";
534 if ($dict_key == $selected_id)
536 echo ">${dict_value}</option>";
538 echo "</optgroup>\n";
542 echo "<optgroup label='other'>\n";
543 foreach ($other as $dict_key => $dict_value)
545 echo "<option value=${dict_key}";
546 if ($dict_key == $selected_id)
548 echo ">${dict_value}</option>";
550 echo "</optgroup>\n";
556 // used by renderGridForm() and renderRackPage()
557 function renderRackInfoPortlet ($rackData)
560 startPortlet ('summary');
561 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
562 echo "<tr><th width='50%' class=tdright>Rack row:</th><td class=tdleft>${rackData['row_name']}</td></tr>\n";
563 echo "<tr><th width='50%' class=tdright>Name:</th><td class=tdleft>${rackData['name']}</td></tr>\n";
564 echo "<tr><th width='50%' class=tdright>Height:</th><td class=tdleft>${rackData['height']}</td></tr>\n";
565 echo "<tr><th width='50%' class=tdright>Utilization:</th><td class=tdleft>";
566 renderProgressBar (getRSUforRack ($rackData));
568 echo "<tr><th width='50%' class=tdright>Objects:</th><td class=tdleft>";
569 echo getObjectCount ($rackData);
571 printTagTRs ("${root}?page=rackspace&");
572 if (!empty ($rackData['comment']))
573 echo "<tr><th width='50%' class=tdright>Comment:</th><td class=tdleft>${rackData['comment']}</td></tr>\n";
578 // This is a universal editor of rack design/waste.
579 function renderGridForm ($rack_id = 0, $filter, $header, $submit, $state1, $state2)
583 showError ('Invalid rack_id', __FUNCTION__
);
586 if (($rackData = getRackData ($rack_id)) == NULL)
588 showError ('getRackData() failed', __FUNCTION__
);
592 global $root, $pageno, $tabno;
594 markupObjectProblems ($rackData);
596 // Process form submit.
597 if (isset ($_REQUEST['do_update']))
599 $log[] = processGridForm ($rackData, $state1, $state2);
601 $rackData = getRackData ($rack_id);
603 markupObjectProblems ($rackData);
606 // Render the result whatever it is.
608 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
609 echo "<tr><td colspan=2 align=center><h1>${rackData['name']}</h1></td></tr>\n";
611 // Left column with information portlet.
612 echo "<tr><td class=pcleft height='1%' width='50%'>";
613 renderRackInfoPortlet ($rackData);
615 echo "<td class=pcright>";
618 startPortlet ($header);
620 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
621 echo "<tr><th width='10%'> </th><th width='20%'>Front</th>";
622 echo "<th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
623 echo "<form method=post action='${root}?'>\n";
624 echo "<input type=hidden name=page value=${pageno}>\n";
625 echo "<input type=hidden name=tab value=${tabno}>\n";
626 echo "<input type=hidden name=rack_id value=${rack_id}>\n";
627 markupAtomGrid ($rackData, $state2);
628 renderAtomGrid ($rackData);
629 echo "</table></center>\n";
630 echo "<br><input type=submit name=do_update value='${submit}'></form><br><br>\n";
632 echo "</td></tr></table>\n";
635 function renderRackDesign ($rack_id)
637 renderGridForm ($rack_id, 'applyRackDesignMask', 'Rack design', 'Set rack design', 'A', 'F');
640 function renderRackProblems ($rack_id = 0)
642 renderGridForm ($rack_id, 'applyRackProblemMask', 'Rack problems', 'Mark unusable atoms', 'F', 'U');
645 function startPortlet ($title = '')
647 echo "<div class=portlet><h2>${title}</h2>";
650 function finishPortlet ()
655 function printRefsOfType ($refs, $type, $eq)
659 foreach ($refs as $ref)
661 if ($eq($ref['type'], $type))
663 if ($gotone) echo ', ';
664 echo "<a href='${root}?page=object&object_id=${ref['object_id']}'>";
665 if (!empty ($ref['name']))
666 echo $ref['name'] . '@';
667 echo "${ref['object_name']}</a>";
673 function renderRackObject ($object_id = 0)
675 global $root, $nextorder;
678 showError ('Invalid object_id', __FUNCTION__
);
681 $info = getObjectInfo ($object_id);
684 showError ('getObjectInfo() failed', __FUNCTION__
);
687 // Main layout starts.
688 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
689 echo "<tr><td colspan=2 align=center><h1>${info['dname']}</h1></td></tr>\n";
690 // left column with uknown number of portlets
691 echo "<tr><td class=pcleft>";
692 startPortlet ('Object information');
693 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
694 if (!empty ($info['name']))
695 echo "<tr><th width='50%' class=tdright>Common name:</th><td class=tdleft>${info['name']}</td></tr>\n";
696 elseif (in_array ($info['objtype_id'], explode (',', getConfigVar ('NAMEFUL_OBJTYPES'))))
697 echo "<tr><td colspan=2 class=msg_error>Common name is missing.</td></tr>\n";
698 echo "<tr><th width='50%' class=tdright>Object type:</th>";
699 echo "<td class=tdleft><a href='${root}?page=objgroup&group_id=${info['objtype_id']}'>${info['objtype_name']}</a></td></tr>\n";
700 if (!empty ($info['asset_no']))
701 echo "<tr><th width='50%' class=tdright>Asset tag:</th><td class=tdleft>${info['asset_no']}</td></tr>\n";
702 elseif (in_array ($info['objtype_id'], explode (',', getConfigVar ('REQUIRE_ASSET_TAG_FOR'))))
703 echo "<tr><td colspan=2 class=msg_error>Asset tag is missing.</td></tr>\n";
704 if (!empty ($info['label']))
705 echo "<tr><th width='50%' class=tdright>Visible label:</th><td class=tdleft>${info['label']}</td></tr>\n";
706 if (!empty ($info['barcode']))
707 echo "<tr><th width='50%' class=tdright>Barcode:</th><td class=tdleft>${info['barcode']}</td></tr>\n";
708 if ($info['has_problems'] == 'yes')
709 echo "<tr><td colspan=2 class=msg_error>Has problems</td></tr>\n";
710 foreach (getAttrValues ($object_id, TRUE) as $record)
711 if (!empty ($record['value']))
712 echo "<tr><th width='50%' class=opt_attr_th>${record['name']}:</th><td class=tdleft>${record['a_value']}</td></tr>\n";
713 printTagTRs ("${root}?page=objgroup&group_id=${info['objtype_id']}&");
714 echo "</table><br>\n";
717 if (!empty ($info['comment']))
719 startPortlet ('Comment');
720 echo '<div class=commentblock>' . string_insert_hrefs ($info['comment']) . '</div>';
724 $ports = getObjectPortsAndLinks ($object_id);
727 startPortlet ('Ports and links');
728 usort($ports, 'sortByName');
732 if (isset ($_REQUEST['hl_port_id']))
734 assertUIntArg ('hl_port_id', __FUNCTION__
);
735 $hl_port_id = $_REQUEST['hl_port_id'];
737 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
738 echo "<tr><th>Local name</th><th>Visible label</th><th>Port type</th><th>L2 address</th>";
739 echo "<th>Rem. Object</th><th>Rem. port</th></tr>\n";
740 foreach ($ports as $port)
743 if ($hl_port_id == $port['id'])
744 echo ' class=port_highlight';
745 echo "><td>${port['name']}</td><td>${port['label']}</td><td>${port['type']}</td>";
746 echo "<td>${port['l2address']}</td>";
747 if ($port['remote_object_id'])
749 echo "<td><a href='${root}?page=object&object_id=${port['remote_object_id']}'>${port['remote_object_name']}</a></td>";
750 echo "<td>${port['remote_name']}</td>";
752 elseif (!empty ($port['reservation_comment']))
754 echo "<td><b>Reserved;</b></td>";
755 echo "<td>${port['reservation_comment']}</td>";
758 echo '<td> </td><td> </td>';
761 echo "</table><br>\n";
765 $addresses = getObjectAddresses ($object_id);
766 usort($addresses, 'sortAddresses');
767 if (count ($addresses))
769 startPortlet ('IPv4 addresses');
770 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
771 echo "<tr><th>Interface name</th><th>IP Address</th><th>Description</th><th>Misc</th></tr>\n";
773 if (isset ($_REQUEST['hl_ipv4_addr']))
775 assertIPv4Arg ('hl_ipv4_addr', __FUNCTION__
);
776 $hl_ipv4_addr = $_REQUEST['hl_ipv4_addr'];
778 foreach ($addresses as $addr)
780 if (strlen($addr['address_name'])>40)
781 $address_name = substr($addr['address_name'],0,38).'...';
783 $address_name = $addr['address_name'];
785 $virtnum = countRefsOfType($addr['references'], 'virtual', 'eq');
786 $sharednum = countRefsOfType($addr['references'], 'shared', 'eq');
787 $regnum = countRefsOfType($addr['references'], 'regular', 'eq');
788 $notvirtnum = countRefsOfType($addr['references'], 'virtual', 'neq');
791 if ($addr['address_reserved']=='yes')
792 echo ' class=trerror';
793 elseif ($addr['type']!='virtual' && $regnum>0)
794 echo ' class=trerror';
795 elseif ($addr['type']=='regular' && $sharednum>0)
796 echo ' class=trerror';
798 if ($hl_ipv4_addr == $addr['ip'])
799 echo ' class=port_highlight';
800 echo "><td class=tdleft>${addr['name']}</td><td class=tdleft><a href='${root}?page=ipaddress&ip=${addr['ip']}'>${addr['ip']}</a></td><td class='description'>$address_name</td><td class=tdleft>\n";
802 if ($addr['address_reserved']=='yes')
803 echo "<b>Reserved;</b> ";
805 if ($addr['type'] == 'virtual')
811 printRefsOfType($addr['references'], 'virtual', 'neq');
814 elseif ($addr['type'] == 'shared')
820 printRefsOfType($addr['references'], 'shared', 'eq');
826 printRefsOfType($addr['references'], 'virtual', 'eq');
831 echo " Collisions: ";
832 printRefsOfType($addr['references'], 'regular', 'eq');
841 printRefsOfType($addr['references'], 'virtual', 'eq');
846 echo " Collisions: ";
847 printRefsOfType($addr['references'], 'virtual', 'neq');
853 echo "</table><br>\n";
857 $forwards = getNATv4ForObject ($object_id);
858 if (count($forwards['in']) or count($forwards['out']))
860 startPortlet('NATv4');
862 if (count($forwards['out']))
865 echo "<h3>locally performed NAT</h3>";
867 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
868 echo "<tr><th>Proto</th><th>Match endpoint</th><th>Translate to</th><th>Target object</th><th>Rule comment</th></tr>\n";
870 foreach ($forwards['out'] as $pf)
874 foreach ($addresses as $addr)
875 if ($addr['ip'] == $pf['localip'])
882 echo "<tr class='$class'>";
884 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>";
886 echo "<td class=tdleft><a href='${root}?page=ipaddress&tab=default&ip=${pf['remoteip']}'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
888 $address=getIPAddress($pf['remoteip']);
890 echo "<td class='description'>";
891 if (count ($address['bonds']))
892 foreach($address['bonds'] as $bond)
893 echo "<a href='${root}?page=object&tab=default&object_id=${bond['object_id']}'>${bond['object_name']}(${bond['name']})</a> ";
894 elseif (!empty ($pf['remote_addr_name']))
895 echo '(' . $pf['remote_addr_name'] . ')';
897 echo "</td><td class='description'>${pf['description']}</td>";
901 echo "</table><br><br>";
903 if (count($forwards['in']))
905 echo "<h3>arriving NAT connections</h3>";
907 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
908 echo "<tr><th>Matched endpoint</th><th>Source object</th><th>Translated to</th><th>Rule comment</th></tr>\n";
910 foreach ($forwards['in'] as $pf)
913 echo "<td>${pf['proto']}/<a href='${root}?page=ipaddress&tab=default&ip=${pf['localip']}'>${pf['localip']}</a>:${pf['localport']}</td>";
915 echo "<td class='description'><a href='${root}?page=object&tab=default&object_id=${pf['object_id']}'>${pf['object_name']}</a>";
917 echo "</td><td><a href='${root}?page=ipaddress&tab=default&ip=${pf['remoteip']}'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
918 echo "<td class='description'>${pf['description']}</td></tr>";
921 echo "</table><br><br>";
926 $pools = getRSPoolsForObject ($object_id);
930 startPortlet ('Real server pools');
931 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
932 echo "<tr><th>VS</th><th>RS pool</th><th>RS</th><th>VS config</th><th>RS config</th></tr>\n";
933 foreach ($pools as $vs_id => $info)
935 echo "<tr valign=top class=row_${order}><td class=tdleft><a href='${root}?page=ipv4vs&vs_id=${vs_id}'>";
936 echo buildVServiceName ($info);
938 if (!empty ($info['name']))
939 echo "<br>${info['name']}";
940 echo "</td><td class=tdleft><a href='${root}?page=ipv4rsp&pool_id=${info['pool_id']}'>";
941 echo (empty ($info['pool_name']) ?
'ANONYMOUS' : $info['pool_name']);
942 echo '</a></td><td class=tdleft>' . $info['rscount'] . '</td>';
943 echo "<td class=tdleft><pre>${info['vsconfig']}</pre></td>";
944 echo "<td class=tdleft><pre>${info['rsconfig']}</pre></td>";
946 $order = $nextorder[$order];
953 // After left column we have (surprise!) right column with rackspace portled only.
954 echo "<td class=pcright>";
956 startPortlet ('Rackspace allocation');
957 // FIXME: now we call getRackData() twice
958 $racks = getResidentRacksData ($object_id);
959 foreach ($racks as $rackData)
960 renderRack ($rackData['id'], $object_id);
967 function renderRackMultiSelect ($sname, $racks, $selected)
969 // Transform the given flat list into a list of groups, each representing a rack row.
971 foreach ($racks as $rack)
972 if (!isset ($rdata[$rack['row_name']]))
973 $rdata[$rack['row_name']] = array ($rack['id'] => $rack['name']);
975 $rdata[$rack['row_name']][$rack['id']] = $rack['name'];
976 echo "<select name=${sname} multiple size=" . getConfigVar ('MAXSELSIZE') . " onchange='getElementById(\"racks\").submit()'>\n";
977 foreach ($rdata as $optgroup => $racklist)
979 echo "<optgroup label='${optgroup}'>";
980 foreach ($racklist as $rack_id => $rack_name)
982 echo "<option value=${rack_id}";
983 if (!(array_search ($rack_id, $selected) === FALSE))
985 echo">${rack_name}</option>\n";
991 function showMessageOrError ()
993 if (isset ($_REQUEST['message']))
994 echo "<div class=msg_success>${_REQUEST['message']}</div>";
995 elseif (isset ($_REQUEST['error']))
996 echo "<div class=msg_error>${_REQUEST['error']}</div>";
997 elseif (isset ($_REQUEST['log']))
998 printLog (unserialize (base64_decode ($_REQUEST['log'])));
1001 // This function renders a form for port edition.
1002 function renderPortsForObject ($object_id = 0)
1004 global $root, $pageno, $tabno;
1005 if ($object_id <= 0)
1007 showError ('Invalid object_id', __FUNCTION__
);
1010 showMessageOrError();
1011 startPortlet ('Ports and interfaces');
1012 $ports = getObjectPortsAndLinks ($object_id);
1013 usort($ports, 'sortByName');
1014 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
1015 echo "<tr><th> </th><th>Local name</th><th>Visible label</th><th>Port type</th><th>L2 address</th>";
1016 echo "<th>Rem. object</th><th>Rem. port</th><th>(Un)link or (un)reserve</th><th> </th></tr>\n";
1017 foreach ($ports as $port)
1019 echo "<form action='${root}process.php'>";
1020 echo "<input type=hidden name=op value=editPort>";
1021 echo "<input type=hidden name=page value='${pageno}'>\n";
1022 echo "<input type=hidden name=tab value='${tabno}'>\n";
1023 echo "<input type=hidden name=port_id value='${port['id']}'>";
1024 echo "<input type=hidden name=object_id value='$object_id'>\n";
1025 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']}'>";
1026 printImageHREF ('delete', 'Unlink and Delete this port');
1028 echo "<td><input type=text name=name value='${port['name']}' size=8></td>";
1029 echo "<td><input type=text name=label value='${port['label']}' size=24></td>";
1030 echo "<td>${port['type']}</td>\n";
1031 echo "<td><input type=text name=l2address value='${port['l2address']}'></td>\n";
1032 if ($port['remote_object_id'])
1034 echo "<td><a href='${root}?page=object&object_id=${port['remote_object_id']}'>${port['remote_object_name']}</a></td>";
1035 echo "<td>${port['remote_name']}</td>";
1036 echo "<td><a href='${root}process.php?op=unlinkPort&page=${pageno}&tab=${tabno}&port_id=${port['id']}&object_id=$object_id&port_name=";
1037 echo urlencode ($port['name']);
1038 echo "&remote_port_name=${port['remote_name']}&remote_object_name=${port['remote_object_name']}'>";
1039 printImageHREF ('unlink', 'Unlink this port');
1042 elseif (!empty ($port['reservation_comment']))
1044 echo "<td><b>Reserved;</b></td>";
1045 echo "<td><input type=text name=reservation_comment value='${port['reservation_comment']}'></td>";
1046 echo "<td><a href='${root}process.php?op=useup&page=${pageno}&tab=${tabno}&port_id=${port['id']}&object_id=${object_id}'>";
1047 printImageHREF ('useup', 'Use up this port');
1052 echo "<td> </td><td> </td>";
1054 echo "<a href='javascript:;' onclick='window.open(\"${root}link_helper.php?port=${port['id']}&type=${port['type_id']}&object_id=$object_id&port_name=";
1055 echo urlencode ($port['name']);
1056 echo "\",\"findlink\",\"height=700, width=400, location=no, menubar=no, resizable=yes, scrollbars=no, status=no, titlebar=no, toolbar=no\");'>";
1057 printImageHREF ('link', 'Link this port');
1058 echo "</a> <input type=text name=reservation_comment>";
1062 printImageHREF ('save', 'Save changes', TRUE);
1063 echo "</td></form></tr>\n";
1065 echo "<form action='${root}process.php'><tr><td>";
1066 printImageHREF ('add', '', TRUE, 104);
1067 echo "</td><td><input type=text size=8 name=port_name tabindex=100></td>\n";
1068 echo "<td><input type=text size=24 name=port_label tabindex=101></td>";
1069 echo "<input type=hidden name=op value=addPort>\n";
1070 echo "<input type=hidden name=object_id value='${object_id}'>\n";
1071 echo "<input type=hidden name=page value='${pageno}'>\n";
1072 echo "<input type=hidden name=tab value='${tabno}'>\n";
1073 echo "<td><select name='port_type_id' tabindex=102>\n";
1074 $types = getPortTypes();
1075 $default_port_type = getConfigVar ('default_port_type');
1076 foreach ($types as $typeid => $typename)
1078 echo "<option value='${typeid}'";
1079 if ($typeid == $default_port_type)
1081 echo ">${typename}</option>\n";
1083 echo "</select></td>";
1084 echo "<td><input type=text name=port_l2address tabindex=103></td>\n";
1085 echo "<td colspan=4> </td></tr></form>";
1086 echo "</table><br>\n";
1089 startPortlet ('Add/update multiple ports');
1090 echo "<form action=${root}process.php method=post>";
1091 echo "<input type=hidden name=page value='${pageno}'>\n";
1092 echo "<input type=hidden name=tab value='${tabno}'>\n";
1093 echo "<input type=hidden name=object_id value='${object_id}'>\n";
1094 echo "<input type=hidden name=op value=addMultiPorts>";
1095 echo 'Format: <select name=format>';
1096 echo '<option value=c3600asy>Cisco 3600 async: sh line | inc TTY</option>';
1097 echo '<option value=fiwg selected>Foundry ServerIron/FastIron WorkGroup/Edge: sh int br</option>';
1098 echo '<option value=fisxii>Foundry FastIron SuperX/II4000: sh int br</option>';
1099 echo '<option value=ssv1>SSV:<interface name> <MAC address></option>';
1101 echo 'Default port type: ';
1102 echo "<select name=port_type>\n";
1103 foreach ($types as $typeid => $typename)
1105 echo "<option value='${typeid}'";
1106 if ($typeid == $default_port_type)
1108 echo ">${typename}</option>\n";
1111 echo "<input type=submit value='Parse output'><br>\n";
1112 echo "<textarea name=input cols=100 rows=50></textarea><br>\n";
1117 function renderNetworkForObject ($object_id=0)
1119 global $root, $pageno, $tabno;
1120 if ($object_id <= 0)
1122 showError ('Invalid object_id', __FUNCTION__
);
1125 showMessageOrError();
1126 startPortlet ('Network Addresses');
1127 $addresses = getObjectAddresses ($object_id);
1128 usort($addresses, 'sortAddresses');
1129 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
1130 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";
1131 foreach ($addresses as $addr)
1133 if (strlen($addr['address_name'])>40)
1134 $address_name = substr($addr['address_name'],0,38).'...';
1136 $address_name = $addr['address_name'];
1138 $virtnum = countRefsOfType($addr['references'], 'virtual', 'eq');
1139 $sharednum = countRefsOfType($addr['references'], 'shared', 'eq');
1140 $regnum = countRefsOfType($addr['references'], 'regular', 'eq');
1141 $notvirtnum = countRefsOfType($addr['references'], 'virtual', 'neq');
1143 if ($addr['address_reserved']=='yes')
1145 elseif ($addr['type']!='virtual' && $regnum>0)
1147 elseif ($addr['type']=='regular' && $sharednum>0)
1152 echo "<form action='process.php'>";
1153 echo "<input type=hidden name=page value='${pageno}'>\n";
1154 echo "<input type=hidden name=tab value='${tabno}'>\n";
1155 echo "<input type=hidden name=op value=updIPv4Allocation>";
1156 echo "<input type=hidden name=object_id value='$object_id'>";
1157 echo "<input type=hidden name=ip value='${addr['ip']}'>";
1158 echo "<tr class='$class'><td><a href='process.php?op=delIPv4Allocation&page=${pageno}&tab=${tabno}&ip=${addr['ip']}&object_id=$object_id'>";
1159 printImageHREF ('delete', 'Delete this IPv4 address');
1161 echo "<td class=tdleft><input type='text' name='bond_name' value='${addr['name']}' size=10></td>";
1162 echo "<td class=tdleft><a href='${root}?page=ipaddress&ip=${addr['ip']}'>${addr['ip']}</a></td>";
1163 echo "<td class='description'>$address_name</td>\n";
1164 echo "<td><select name='bond_type'>";
1165 foreach (array('regular'=>'Regular', 'virtual'=>'Virtual', 'shared'=>'Shared') as $n => $v)
1167 echo "<option value='$n'";
1168 if ($addr['type'] == $n)
1170 echo ">$v</option>";
1173 if ($addr['address_reserved']=='yes')
1174 echo "<b>Reserved</b>; ";
1176 if ($addr['type'] == 'virtual')
1178 if ($notvirtnum > 0)
1181 printRefsOfType($addr['references'], 'virtual', 'neq');
1184 elseif ($addr['type'] == 'shared')
1189 printRefsOfType($addr['references'], 'shared', 'eq');
1195 printRefsOfType($addr['references'], 'virtual', 'eq');
1200 echo " Collisions: ";
1201 printRefsOfType($addr['references'], 'regular', 'eq');
1210 printRefsOfType($addr['references'], 'virtual', 'eq');
1213 if ($notvirtnum > 0)
1215 echo " Collisions: ";
1216 printRefsOfType($addr['references'], 'virtual', 'neq');
1221 printImageHREF ('save', 'Save changes', TRUE);
1222 echo "</td></form></tr>\n";
1226 echo "<form action='${root}process.php'><tr><td>";
1227 printImageHREF ('add', 'Allocate new address', TRUE, 99);
1228 echo "</td><td class=tdleft>";
1229 echo "<input type='text' size='10' name='bond_name' tabindex=100></td>\n";
1230 echo "<input type=hidden name=page value='${pageno}'>\n";
1231 echo "<input type=hidden name=tab value='${tabno}'>\n";
1232 echo "<input type=hidden name=op value=addIPv4Allocation>\n";
1233 echo "<input type=hidden name=object_id value='$object_id'>\n";
1234 echo "<td class=tdleft><input type=text name='ip' tabindex=101>\n";
1235 echo "</td><td> </td><td><select name='bond_type' tabindex=102>";
1236 echo "<option value='regular'>Regular</option>";
1237 echo "<option value='virtual'>Virtual</option>";
1238 echo "<option value='shared'>Shared</option>";
1240 echo "</td><td colspan=2> </td></tr></form>";
1241 echo "</table><br>\n";
1246 function printLog ($log)
1248 foreach ($log as $record)
1249 echo "<div class=msg_${record['code']}>${record['message']}</div>";
1253 The following conditions must be followed:
1254 1. We can mount onto free atoms only. This means: if any record for an atom
1255 already exists in RackSpace, it can't be used for mounting.
1256 2. We can't unmount from 'W' atoms. Operator should review appropriate comments
1257 and either delete them before unmounting or refuse to unmount the object.
1260 // We extensively use $_REQUEST in the function.
1261 function renderRackSpaceForObject ($object_id = 0)
1263 if ($object_id <= 0)
1265 showError ('Invalid object_id', __FUNCTION__
);
1268 $is_submit = isset ($_REQUEST['got_atoms']);
1269 $is_update = isset ($_REQUEST['rackmulti'][0]);
1270 $info = getObjectInfo ($object_id);
1273 showError ('getObjectInfo() failed', __FUNCTION__
);
1276 // Always process occupied racks plus racks chosen by user. First get racks with
1277 // already allocated rackspace...
1278 $workingRacksData = getResidentRacksData ($object_id);
1279 if ($workingRacksData === NULL)
1281 print_r ($workingRacksData);
1282 showError ('getResidentRacksData() failed', __FUNCTION__
);
1286 // ...and then add those chosen by user (if any).
1288 foreach ($_REQUEST['rackmulti'] as $cand_id)
1290 if (!isset ($workingRacksData[$cand_id]))
1292 $rackData = getRackData ($cand_id);
1293 if ($rackData == NULL)
1295 showError ('getRackData() failed', __FUNCTION__
);
1298 $workingRacksData[$cand_id] = $rackData;
1302 // Do it only once...
1303 foreach ($workingRacksData as &$rackData)
1304 applyObjectMountMask ($rackData, $object_id);
1305 // Now we workaround an old caveat: http://bugs.php.net/bug.php?id=37410
1308 // Here we process form submit by trying to save all submitted info to database.
1311 $oldMolecule = getMoleculeForObject ($object_id);
1312 $worldchanged = FALSE;
1314 foreach ($workingRacksData as $rack_id => $rackData)
1316 $logrecord = processGridForm ($rackData, 'F', 'T', $object_id);
1317 $log[] = $logrecord;
1318 if ($logrecord['code'] != 300)
1320 $worldchanged = TRUE;
1321 // Reload our working copy after form processing.
1322 $rackData = getRackData ($rack_id);
1323 if ($rackData == NULL)
1324 $log[] = array ('code' => 500, 'message' => 'Working copy update failed in ', __FUNCTION__
);
1325 applyObjectMountMask ($rackData, $object_id);
1326 $workingRacksData[$rack_id] = $rackData;
1332 $newMolecule = getMoleculeForObject ($object_id);
1333 $oc = count ($oldMolecule);
1334 $nc = count ($newMolecule);
1335 $omid = $oc ?
createMolecule ($oldMolecule) : 'NULL';
1336 $nmid = $nc ?
createMolecule ($newMolecule) : 'NULL';
1337 global $remote_username;
1338 $comment = empty ($_REQUEST['comment']) ?
'NULL' : "'${_REQUEST['comment']}'";
1340 "insert into MountOperation(object_id, old_molecule_id, new_molecule_id, user_name, comment) " .
1341 "values (${object_id}, ${omid}, ${nmid}, '${remote_username}', ${comment})";
1343 $result = $dbxlink->query ($query);
1344 if ($result == NULL)
1345 $log[] = array ('code' => 'error', 'message' => 'SQL query failed during history logging.');
1347 $log[] = array ('code' => 'success', 'message' => 'History logged.');
1352 // This is the time for rendering.
1353 global $root, $pageno, $tabno;
1354 echo "<form id='racks' action='${root}'>";
1355 echo "<input type=hidden name=page value='${pageno}'>\n";
1356 echo "<input type=hidden name=tab value='${tabno}'>\n";
1357 echo "<input type=hidden name=object_id value='${object_id}'>\n";
1358 // Main layout starts.
1359 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0><tr>";
1361 // Left portlet with rack list.
1362 echo "<td class=pcleft height='1%'>";
1363 startPortlet ('Racks');
1364 $allRacksData = getRacksForRow();
1365 if (count ($allRacksData) <= getConfigVar ('RACK_PRESELECT_THRESHOLD'))
1367 foreach (array_keys ($allRacksData) as $rack_id)
1369 $rackData = getRackData ($rack_id);
1370 if ($rackData == NULL)
1372 showError ('getRackData() failed', __FUNCTION__
);
1375 $workingRacksData[$rack_id] = $rackData;
1377 foreach ($workingRacksData as &$rackData)
1378 applyObjectMountMask ($rackData, $object_id);
1381 renderRackMultiSelect ('rackmulti[]', $allRacksData, array_keys ($workingRacksData));
1387 // Middle portlet with comment and submit.
1388 echo "<td class=pcleft>";
1389 startPortlet ('Comment');
1390 echo "<textarea name=comment rows=10 cols=40></textarea><br>\n";
1391 echo "<input type=submit value='Save' name=got_atoms>\n";
1397 // Right portlet with rendered racks. If this form submit is not final, we have to
1398 // reflect the former state of the grid in current form.
1399 echo "<td class=pcright rowspan=2 height='1%'>";
1400 startPortlet ('Working copy');
1401 echo '<table border=0 cellspacing=10 align=center><tr>';
1402 foreach ($workingRacksData as $rack_id => $rackData)
1404 // Order is important here: only original allocation is highlighted.
1405 highlightObject ($rackData, $object_id);
1406 markupAtomGrid ($rackData, 'T');
1407 // If we have a form processed, discard user input and show new database
1409 if (!$is_submit and $is_update)
1410 mergeGridFormToRack ($rackData);
1411 echo "<td valign=top>";
1412 echo "<center>\n<h2>${rackData['name']}</h2>\n";
1413 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
1414 echo "<tr><th width='10%'> </th><th width='20%'>Front</th>";
1415 echo "<th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
1416 renderAtomGrid ($rackData);
1417 echo "<tr><th width='10%'> </th><th width='20%'>Front</th>";
1418 echo "<th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
1419 echo "</table></center>\n";
1422 echo "</tr></table>";
1427 echo "</tr></table>\n";
1430 function renderMolecule ($mdata, $object_id)
1433 $rackpack = array();
1435 foreach ($mdata as $rua)
1437 $rack_id = $rua['rack_id'];
1438 $unit_no = $rua['unit_no'];
1439 $atom = $rua['atom'];
1440 if (!isset ($rackpack[$rack_id]))
1442 $rackData = getRackData ($rack_id);
1443 for ($i = $rackData['height']; $i > 0; $i--)
1444 for ($locidx = 0; $locidx < 3; $locidx++
)
1445 $rackData[$i][$locidx]['state'] = 'F';
1446 $rackpack[$rack_id] = $rackData;
1448 $rackpack[$rack_id][$unit_no][$loclist[$atom]]['state'] = 'T';
1449 $rackpack[$rack_id][$unit_no][$loclist[$atom]]['object_id'] = $object_id;
1451 // now we have some racks to render
1452 foreach ($rackpack as $rackData)
1454 markAllSpans ($rackData);
1455 echo "<table class=molecule cellspacing=0>\n";
1456 echo "<caption>${rackData['name']}</caption>\n";
1457 echo "<tr><th width='10%'> </th><th width='20%'>Front</th><th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
1458 for ($i = $rackData['height']; $i > 0; $i--)
1460 echo "<tr><th>$i</th>";
1461 for ($locidx = 0; $locidx < 3; $locidx++
)
1463 $state = $rackData[$i][$locidx]['state'];
1464 echo "<td class=state_${state}> </td>\n";
1472 function renderUnmountedObjectsPortlet ()
1474 startPortlet ('Unmounted objects');
1475 $objs = getUnmountedObjects();
1478 showError ('getUnmountedObjects() failed', __FUNCTION__
);
1481 global $root, $nextorder;
1483 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1484 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset number</th><th>Barcode</th></tr>';
1485 foreach ($objs as $obj)
1487 echo "<tr class=row_${order}><td><a href='${root}?page=object&object_id=${obj['id']}'>${obj['dname']}</a></td>";
1488 echo "<td>${obj['label']}</td>";
1489 echo "<td>${obj['asset_no']}</td>";
1490 echo "<td>${obj['barcode']}</td></tr>";
1491 $order = $nextorder[$order];
1493 echo "</table><br>\n";
1497 function renderProblematicObjectsPortlet ()
1499 startPortlet ('Problematic objects');
1500 $objs = getProblematicObjects();
1503 showError ('getProblematicObjects() failed', __FUNCTION__
);
1506 global $root, $nextorder;
1508 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1509 echo '<tr><th>Type</th><th>Common name</th></tr>';
1510 foreach ($objs as $obj)
1512 echo "<tr class=row_${order}><td>${obj['objtype_name']}</td>";
1513 echo "<td><a href='${root}?page=object&object_id=${obj['id']}'>${obj['dname']}</a></tr>";
1514 $order = $nextorder[$order];
1516 echo "</table><br>\n";
1520 function renderObjectSpace ()
1522 global $root, $taglist, $tagtree;
1523 echo "<table border=0 class=objectview>\n";
1524 echo "<tr><td class=pcleft width='50%'>";
1525 startPortlet ('View all by type');
1526 $groupInfo = getObjectGroupInfo();
1527 if ($groupInfo === NULL)
1529 showError ('getObjectGroupInfo() failed', __FUNCTION__
);
1532 if (count ($groupInfo) == 0)
1533 echo "No objects exist in DB";
1536 echo '<div align=left><ul>';
1537 foreach ($groupInfo as $gi)
1538 echo "<li><a href='${root}?page=objgroup&group_id=${gi['id']}'>${gi['name']}</a> (${gi['count']})</li>";
1543 echo '</td><td class=pcright>';
1545 startPortlet ('View all by tag');
1546 if (count ($taglist) == 0)
1547 echo "No tags exist in DB";
1549 renderTagCloud ('object');
1551 echo "</td></tr></table>\n";
1554 function renderObjectGroup ()
1556 global $root, $pageno, $tabno, $nextorder, $taglist, $tagtree;
1557 assertUIntArg ('group_id', __FUNCTION__
, TRUE);
1558 $group_id = $_REQUEST['group_id'];
1559 $tagfilter = getTagFilter();
1560 $tagfilter_str = getTagFilterStr ($tagfilter);
1561 echo "<table border=0 class=objectview>\n";
1562 echo "<tr><td class=pcleft width='25%'>";
1563 startPortlet ('change type');
1564 $groupInfo = getObjectGroupInfo();
1565 if ($groupInfo === NULL)
1567 showError ('getObjectGroupInfo() failed', __FUNCTION__
);
1570 if (count ($groupInfo) == 0)
1571 echo "No objects exist in DB";
1574 echo '<div align=left><ul>';
1575 foreach ($groupInfo as $gi)
1577 echo "<li><a href='${root}?page=${pageno}&group_id=${gi['id']}${tagfilter_str}'>";
1578 if ($gi['id'] == $group_id)
1580 echo "${gi['name']}</a>";
1581 if ($gi['id'] == $group_id)
1583 echo " (${gi['count']})";
1584 if ($gi['id'] == $group_id)
1592 echo '</td><td class=pcleft>';
1594 startPortlet ('Objects');
1595 $objects = getObjectList ($group_id, $tagfilter, getTFMode());
1596 if ($objects === NULL)
1598 showError ('getObjectList() failed', __FUNCTION__
);
1601 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1602 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>Barcode</th><th>Rack</th></tr>';
1604 foreach ($objects as $obj)
1606 echo "<tr class=row_${order}><td><a href='${root}?page=object&object_id=${obj['id']}'>${obj['dname']}</a></td>";
1607 echo "<td>${obj['label']}</td>";
1608 echo "<td>${obj['asset_no']}</td>";
1609 echo "<td>${obj['barcode']}</td>";
1610 if ($obj['rack_id'])
1611 echo "<td><a href='${root}?page=rack&rack_id=${obj['rack_id']}'>${obj['Rack_name']}</a></td>";
1613 echo '<td>Unmounted</td>';
1615 $order = $nextorder[$order];
1620 echo "</td><td class=pcright width='25%'>";
1622 renderTagFilterPortlet ($tagfilter, 'object', 'group_id', $group_id);
1623 echo "</td></tr></table>\n";
1626 function renderEmptyPortsSelect ($port_id, $type_id)
1628 $ports = getEmptyPortsOfType($type_id);
1629 usort($ports, 'sortEmptyPorts');
1630 foreach ($ports as $port)
1632 if ($port_id == $port['Port_id'])
1634 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";
1638 function renderObjectAddressesAndNames ()
1640 $addresses = getObjectAddressesAndNames();
1641 usort($addresses, 'sortObjectAddressesAndNames');
1642 foreach ($addresses as $address)
1644 echo "<option value='${address['ip']}' onclick='getElementById(\"ip\").value=\"${address['ip']}\";'>${address['object_name']} ${address['name']} ${address['ip']}</option>\n";
1648 // History viewer for history-enabled simple dictionaries.
1649 function renderHistory ($object_type, $object_id)
1651 switch ($object_type)
1654 $query = "select ctime, user_name, name, deleted, comment from RackRowHistory where id = ${object_id} order by ctime";
1655 $header = '<tr><th>change time</th><th>author</th><th>rack row name</th><th>is deleted?</th><th>rack row comment</th></tr>';
1660 "select ctime, user_name, rh.name, rh.deleted, d.dict_value as name, rh.height, rh.comment " .
1661 "from RackHistory as rh left join Dictionary as d on rh.row_id = d.dict_key " .
1662 "natural join Chapter " .
1663 "where chapter_name = 'RackRow' and rh.id = ${object_id} order by ctime";
1664 $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>';
1669 "select ctime, user_name, name, label, barcode, asset_no, deleted, has_problems, dict_value, comment " .
1670 "from RackObjectHistory inner join Dictionary on objtype_id = dict_key natural join Chapter " .
1671 "where chapter_name = 'RackObjectType' and id=${object_id} order by ctime";
1672 $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>';
1676 showError ("Uknown object type '${object_type}'", __FUNCTION__
);
1680 $result = $dbxlink->query ($query);
1681 if ($result == NULL)
1683 showError ('SQL query failed', __FUNCTION__
);
1686 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1690 while ($row = $result->fetch (PDO
::FETCH_NUM
))
1692 echo "<tr class=row_${order}><td>${row[0]}</td>";
1693 for ($i = 1; $i <= $extra; $i++
)
1694 echo "<td>" . $row[$i] . "</td>";
1696 $order = $nextorder[$order];
1698 echo "</table><br>\n";
1701 function renderRackspaceHistory ()
1703 global $root, $nextorder, $pageno, $tabno;
1705 $history = getRackspaceHistory();
1706 // Show the last operation by default.
1707 if (isset ($_REQUEST['op_id']))
1708 $op_id = $_REQUEST['op_id'];
1709 elseif (isset ($history[0]['mo_id']))
1710 $op_id = $history[0]['mo_id'];
1717 list ($omid, $nmid) = getOperationMolecules ($op_id);
1719 // Main layout starts.
1720 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
1722 // Left top portlet with old allocation.
1723 echo "<tr><td class=pcleft>";
1724 startPortlet ('Old allocation');
1727 $oldMolecule = getMolecule ($omid);
1728 renderMolecule ($oldMolecule, $object_id);
1734 echo '</td><td class=pcright>';
1736 // Right top portlet with new allocation
1737 startPortlet ('New allocation');
1740 $newMolecule = getMolecule ($nmid);
1741 renderMolecule ($newMolecule, $object_id);
1747 echo '</td></tr><tr><td colspan=2>';
1749 // Bottom portlet with list
1751 startPortlet ('Rackspace allocation history');
1752 echo "<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>\n";
1753 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";
1754 foreach ($history as $row)
1756 if ($row['mo_id'] == $op_id)
1759 $class = "row_${order}";
1760 echo "<tr class=${class}><td><a href='${root}?page=${pageno}&tab=${tabno}&op_id=${row['mo_id']}'>${row['ctime']}</a></td>";
1761 echo "<td>${row['user_name']}</td>";
1762 echo "<td>${row['ro_id']}</td><td>${row['objtype_name']}</td><td>${row['name']}</td><td>${row['comment']}</td>\n";
1764 $order = $nextorder[$order];
1769 echo '</td></tr></table>';
1773 function renderAddressspace ()
1775 global $root, $page;
1777 echo "<table border=0 class=objectview>\n";
1778 echo "<tr><td class=pcleft>";
1780 startPortlet ('Subnets');
1781 echo "<table class='widetable' border=0 cellpadding=10 cellspacing=0 align='center'>\n";
1782 $tagfilter = getTagFilter();
1783 $addrspaceList = getAddressspaceList ($tagfilter, getTFMode());
1784 echo "<tr><th>Subnet</th><th>Name</th><th>Utilization</th></tr>";
1785 foreach ($addrspaceList as $iprange)
1787 $range = getIPRange ($iprange['id']);
1788 $total = ($iprange['ip_bin'] |
$iprange['mask_bin_inv']) - ($iprange['ip_bin'] & $iprange['mask_bin']) +
1;
1789 $used = count ($range['addrlist']);
1790 echo "<tr><td class=tdleft><a href='${root}?page=iprange&id=${iprange['id']}'>${iprange['ip']}/${iprange['mask']}</a></td>";
1791 echo "<td class=tdleft>${iprange['name']}</td><td class=tdleft>";
1792 renderProgressBar ($used/$total);
1793 echo " ${used}/${total}</td></tr>";
1797 echo '</td><td class=pcright>';
1798 renderTagFilterPortlet ($tagfilter, 'ipv4net');
1799 echo "</td></tr></table>\n";
1802 function renderIPv4SLB ()
1804 global $root, $page, $nextorder;
1806 startPortlet ('SLB configuration');
1807 echo "<table border=0 width='100%'><tr>";
1808 foreach (array ('ipv4vslist', 'ipv4rsplist', 'rservers', 'lbs') as $pno)
1809 echo "<td><h3><a href='${root}?page=${pno}'>" . $page[$pno]['title'] . "</a></h3></td>";
1810 echo '</tr></table>';
1813 $summary = getSLBSummary();
1814 startPortlet ('SLB tactical overview');
1815 // A single id-keyed array isn't used here to preserve existing
1816 // order of LBs returned by getSLBSummary()
1819 foreach ($summary as $vipdata)
1820 foreach (array_keys ($vipdata['lblist']) as $lb_object_id)
1821 if (!in_array ($lb_object_id, $lblist))
1823 $oi = getObjectInfo ($lb_object_id);
1824 $lbdname[$lb_object_id] = $oi['dname'];
1825 $lblist[] = $lb_object_id;
1827 if (!count ($summary))
1828 echo 'none configured';
1832 echo "<table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
1833 echo "<tr><th>VS ↓ LB →</th>";
1834 foreach ($lblist as $lb_object_id)
1835 echo "<th><a href='${root}?page=object&tab=default&object_id=${lb_object_id}'>" . $lbdname[$lb_object_id] . "</a></th>";
1837 foreach ($summary as $vsid => $vsdata)
1839 echo "<tr class=row_${order}><td class=tdleft><a href='$root?page=ipv4vs&tab=default&vs_id=${vsid}'>";
1840 echo buildVServiceName ($vsdata);
1842 if (!empty ($vsdata['name']))
1843 echo "<br>${vsdata['name']}";
1845 foreach ($lblist as $lb_object_id)
1847 echo '<td class=tdleft>';
1848 if (!isset ($vsdata['lblist'][$lb_object_id]))
1852 echo $vsdata['lblist'][$lb_object_id]['size'];
1853 echo " (<a href='${root}?page=ipv4rsp&pool_id=";
1854 echo $vsdata['lblist'][$lb_object_id]['id'] . "'>";
1855 echo $vsdata['lblist'][$lb_object_id]['name'] . '</a>)';
1860 $order = $nextorder[$order];
1867 function renderAddNewRange ()
1869 global $root, $pageno, $tabno;
1870 showMessageOrError();
1872 startPortlet ("Add New");
1873 echo "<table class='widetable' border=0 cellpadding=10 align='center'>\n";
1874 echo "<tr><th>Address range</th><th>Name</th><th>connected network</th><th>assign tags</th><th> </th></tr>\n";
1875 echo "<form name='add_new_range' action='process.php'>\n";
1876 echo "<input type=hidden name=op value=addIPv4Prefix>\n";
1877 echo "<input type=hidden name=page value='${pageno}'>\n";
1878 echo "<input type=hidden name=tab value='${tabno}'>\n";
1879 echo "<tr valign=top><td class='tdcenter'><input type=text name='range' size=18 class='live-validate' tabindex=1></td>\n";
1880 echo "<td class='tdcenter'><input type=text name='name' size='20' tabindex=2></td>\n";
1881 echo "<td class='tdcenter'><input type=checkbox name='is_bcast' tabindex=3 checked></td>\n";
1885 echo "<td class='tdcenter'><input type=submit value='Add a new range' tabindex=4></td>\n";
1886 echo "</td></tr>\n";
1887 echo "</form></table><br><br>\n";
1890 startPortlet ("Manage Existing");
1891 echo "<table class='widetable' border=0 cellpadding=10 align='center'>\n";
1892 $addrspaceList = getAddressspaceList();
1893 echo "<tr><th> </th><th>Address range</th><th>Name</th><th>Utilization</th></tr>";
1894 foreach ($addrspaceList as $iprange)
1896 $range = getIPRange($iprange['id']);
1897 $usedips = count ($range['addrlist']);
1898 $totalips = ($iprange['ip_bin'] |
$iprange['mask_bin_inv']) - ($iprange['ip_bin'] & $iprange['mask_bin']) +
1;
1902 echo "<a href='process.php?op=delIPv4Prefix&page=${pageno}&tab=${tabno}&id=${iprange['id']}'>";
1903 printImageHREF ('delete', 'Delete this IP range');
1907 printImageHREF ('nodelete', 'There are IP addresses allocated or reserved');
1908 echo "</td>\n<td class=tdleft><a href='${root}?page=iprange&id=${iprange['id']}'>";
1909 echo "${iprange['ip']}/${iprange['mask']}</a></td><td class=tdleft>${iprange['name']}";
1910 echo "</td><td class=tdleft>";
1911 renderProgressBar ($usedips / $totalips);
1912 echo " ${usedips}/${totalips}";
1919 function renderIPRange ($id)
1921 global $root, $pageno, $tabno;
1922 $netmaskbylen = array
1924 32 => '255.255.255.255',
1925 31 => '255.255.255.254',
1926 30 => '255.255.255.252',
1927 29 => '255.255.255.248',
1928 28 => '255.255.255.240',
1929 27 => '255.255.255.224',
1930 26 => '255.255.255.192',
1931 25 => '255.255.255.128',
1932 24 => '255.255.255.0',
1933 23 => '255.255.254.0',
1934 22 => '255.255.252.0',
1935 21 => '255.255.248.0',
1936 20 => '255.255.240.0',
1937 19 => '255.255.224.0',
1938 18 => '255.255.192.0',
1939 17 => '255.255.128.0',
1940 16 => '255.255.0.0',
1941 15 => '255.254.0.0',
1942 14 => '255.252.0.0',
1943 13 => '255.248.0.0',
1944 12 => '255.240.0.0',
1945 11 => '255.224.0.0',
1946 10 => '255.192.0.0',
1957 $wildcardbylen = array
1974 17 => '0.0.127.255',
1976 15 => '0.1.255.255',
1977 14 => '0.3.255.255',
1978 13 => '0.7.255.255',
1979 12 => '0.15.255.255',
1980 11 => '0.31.255.255',
1981 10 => '0.63.255.255',
1982 9 => '0.127.255.255',
1983 8 => '0.255.255.255',
1984 7 => '1.255.255.255',
1985 6 => '3.255.255.255',
1986 5 => '7.255.255.255',
1987 4 => '15.255.255.255',
1988 3 => '31.255.255.255',
1989 2 => '63.255.255.255',
1990 1 => '127.255.255.255'
1992 $maxperpage = getConfigVar ('IPV4_ADDRS_PER_PAGE');
1993 if (isset($_REQUEST['pg']))
1994 $page = $_REQUEST['pg'];
1998 $range = getIPRange($id);
1999 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
2000 echo "<tr><td colspan=2 align=center><h1>${range['ip']}/${range['mask']}</h1><h2>${range['name']}</h2></td></tr>\n";
2002 echo "<tr><td class=pcleft width='50%'>";
2003 startPortlet ('summary');
2004 $total = ($range['ip_bin'] |
$range['mask_bin_inv']) - ($range['ip_bin'] & $range['mask_bin']) +
1;
2005 $used = count ($range['addrlist']);
2006 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
2007 echo "<tr><th width='50%' class=tdright>Utilization:</th><td class=tdleft>";
2008 renderProgressBar ($used/$total);
2009 echo " ${used}/${total}</td></tr>\n";
2010 echo "<tr><th width='50%' class=tdright>Netmask:</th><td class=tdleft>";
2011 echo $netmaskbylen[$range['mask']];
2012 echo "</td></tr>\n";
2013 echo "<tr><th width='50%' class=tdright>Wildcard bits:</th><td class=tdleft>";
2014 echo $wildcardbylen[$range['mask']];
2015 echo "</td></tr>\n";
2016 printTagTRs ("${root}?page=ipv4space&");
2017 echo "</table><br>\n";
2021 echo "<td class=pcright>";
2022 startPortlet ('details');
2023 $startip = $range['ip_bin'] & $range['mask_bin'];
2024 $endip = $range['ip_bin'] |
$range['mask_bin_inv'];
2025 $realstartip = $startip;
2026 $realendip = $endip;
2028 if($endip - $startip > $maxperpage)
2030 $numpages = ($endip - $startip)/$maxperpage;
2031 $startip = $startip +
$page * $maxperpage;
2032 $endip = $startip +
$maxperpage-1;
2036 echo '<h3>' . long2ip ($startip) . ' ~ ' . long2ip ($endip) . '</h3>';
2037 for ($i=0; $i<$numpages; $i++
)
2042 echo "<a href='${root}?page=${pageno}&tab=${tabno}&id=$id&pg=$i'>$i</a> ";
2046 echo "<table class='widetable' border=0 cellspacing=0 cellpadding=5 align='center'>\n";
2047 echo "<tr><th>Address</th><th>Name</th><th>Allocation</th></tr>\n";
2050 for ($ip = $startip; $ip<=$endip; $ip++
)
2051 if (!isset ($range['addrlist'][$ip]))
2052 echo "<tr><td class=tdleft><a href='${root}?page=ipaddress&ip=".long2ip($ip)."'>".long2ip($ip)."</a></td><td> </td><td> </td></tr>\n";
2055 $numshared = countRefsOfType($range['addrlist'][$ip]['references'], 'shared', 'eq');
2056 $numreg = countRefsOfType($range['addrlist'][$ip]['references'], 'regular', 'eq');
2057 $numvirt = countRefsOfType($range['addrlist'][$ip]['references'], 'virtual', 'eq');
2058 $numlb = count ($range['addrlist'][$ip]['lbrefs']);
2059 $numrs = count ($range['addrlist'][$ip]['rsrefs']);
2061 $addr = $range['addrlist'][$ip];
2062 if ( ($numshared > 0 && $numreg > 0) ||
$numreg > 1 )
2063 echo "<tr class='trerror'>";
2064 elseif ( $addr['reserved'] == 'yes' and $numshared+
$numreg+
$numvirt+
$numlb+
$numrs > 0)
2065 echo "<tr class='trerror'>";
2066 elseif ( $addr['reserved'] == 'yes')
2067 echo "<tr class='trbusy'>";
2068 elseif ( $numshared > 0 ||
$numreg > 0 ||
$numlb > 0 ||
$numrs > 0)
2069 echo "<tr class='trbusy'>";
2073 echo "<td class=tdleft><a href='${root}?page=ipaddress&ip=${addr['ip']}'>${addr['ip']}</a></td>";
2074 echo "<td class=tdleft>${addr['name']}</td><td class=tdleft>";
2077 if ( $addr['reserved'] == 'yes')
2079 echo "<b>Reserved</b> ";
2082 foreach ($range['addrlist'][$ip]['references'] as $ref)
2084 echo "${delim}<a href='${root}?page=object&object_id=${ref['object_id']}";
2085 echo "&hl_ipv4_addr=${addr['ip']}'>";
2086 echo $ref['name'] . (empty ($ref['name']) ?
'' : '@');
2087 echo "${ref['object_name']}</a>";
2095 foreach ($range['addrlist'][$ip]['lbrefs'] as $ref)
2099 echo "${delim}<a href='${root}?page=object&object_id=${ref['object_id']}'>";
2100 echo "${ref['object_name']}</a>:<a href='${root}?page=ipv4vs&vs_id=${ref['vs_id']}'>";
2101 echo "${ref['vport']}/${ref['proto']}</a>→";
2109 foreach ($range['addrlist'][$ip]['rsrefs'] as $ref)
2113 echo "${delim}→${ref['rsport']}@<a href='${root}?page=ipv4rsp&pool_id=${ref['rspool_id']}'>";
2114 echo "${ref['rspool_name']}</a>";
2117 echo "</td></tr>\n";
2123 echo "</td></tr></table>\n";
2126 function renderIPRangeProperties ($id)
2128 global $pageno, $tabno;
2129 showMessageOrError();
2130 $range = getIPRange($id);
2131 echo "<center><h1>${range['ip']}/${range['mask']}</h1></center>\n";
2132 echo "<table border=0 cellpadding=10 cellpadding=1 align='center'>\n";
2133 echo "<form action='process.php'><input type=hidden name=op value=editRange>";
2134 echo "<input type=hidden name=page value='${pageno}'>\n";
2135 echo "<input type=hidden name=tab value='${tabno}'>\n";
2136 echo "<input type=hidden name=id value='${id}'>";
2137 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>";
2142 function renderIPAddress ($ip)
2145 $address = getIPAddress ($ip);
2146 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
2147 echo "<tr><td colspan=2 align=center><h1>${ip}</h1></td></tr>\n";
2148 if ($address['exists'] == 1)
2149 echo "<tr><td colspan=2 align=center><h2>${address['name']}</h2></td></tr>\n";
2151 echo "<tr><td class=pcleft>";
2152 startPortlet ('summary');
2153 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
2154 echo "<tr><th width='50%' class=tdright>Allocations:</th><td class=tdleft>" . count ($address['bonds']) . "</td></tr>\n";
2155 echo "<tr><th width='50%' class=tdright>Originated NAT connections:</th><td class=tdleft>" . count ($address['outpf']) . "</td></tr>\n";
2156 echo "<tr><th width='50%' class=tdright>Arriving NAT connections:</th><td class=tdleft>" . count ($address['inpf']) . "</td></tr>\n";
2157 echo "<tr><th width='50%' class=tdright>SLB virtual services:</th><td class=tdleft>" . count ($address['vslist']) . "</td></tr>\n";
2158 echo "<tr><th width='50%' class=tdright>SLB real servers:</th><td class=tdleft>" . count ($address['rslist']) . "</td></tr>\n";
2160 echo "</table><br>\n";
2164 echo "<td class=pcright>";
2165 $numshared = countRefsOfType($address['bonds'], 'shared', 'eq');
2166 $numreg = countRefsOfType($address['bonds'], 'regular', 'eq');
2167 $numvirt = countRefsOfType($address['bonds'], 'virtual', 'eq');
2169 if ($address['reserved'] == 'yes' or ($numshared +
$numreg +
$numvirt) > 0)
2171 startPortlet ('Allocations');
2172 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
2173 echo "<tr><th>Object name</th><th>Interface name</th><th>Interface type</th></tr>\n";
2174 if ( ($numshared > 0 && $numreg > 0) ||
$numreg > 1 )
2176 elseif ( $address['reserved'] == 'yes' and $numshared+
$numreg+
$numvirt > 0)
2181 if ($address['reserved'] == 'yes')
2182 echo "<tr class='$class'><td colspan='3'><b>RESERVED</b></td></tr>";
2183 foreach ($address['bonds'] as $bond)
2185 echo "<tr class='$class'><td><a href='${root}?page=object&object_id=${bond['object_id']}";
2186 echo "&hl_ipv4_addr=${ip}'>${bond['object_name']}</td><td>${bond['name']}</td><td><b>";
2187 switch ($bond['type'])
2199 echo "</b></td></tr>\n";
2201 echo "</table><br><br>";
2205 if (count ($address['vslist']))
2207 startPortlet ('Virtual services (' . count ($address['vslist']) . ')');
2208 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
2209 echo "<tr><th>VS</th><th>name</th></tr>\n";
2210 foreach ($address['vslist'] as $vsinfo)
2212 echo "<tr><td class=tdleft><a href='${root}?page=ipv4vs&vs_id=${vsinfo['id']}'>";
2213 echo buildVServiceName ($vsinfo) . "</a></td><td class=tdleft>";
2214 echo $vsinfo['name'] . "</td></tr>\n";
2216 echo "</table><br><br>";
2220 if (count ($address['rslist']))
2222 startPortlet ('Real servers (' . count ($address['rslist']) . ')');
2223 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
2224 echo "<tr><th> </th><th>port</th><th>RS pool</th></tr>\n";
2225 foreach ($address['rslist'] as $rsinfo)
2228 if ($rsinfo['inservice'] == 'yes')
2229 printImageHREF ('inservice', 'in service');
2231 printImageHREF ('notinservice', 'NOT in service');
2232 echo "</td><td class=tdleft>${rsinfo['rsport']}</td><td class=tdleft><a href='${root}?page=ipv4rsp&pool_id=${rsinfo['pool_id']}'>";
2233 echo $rsinfo['poolname'] . "</a></td></tr>\n";
2235 echo "</table><br><br>";
2239 if (count ($address['outpf']))
2241 startPortlet ('departing NAT rules');
2242 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
2243 echo "<tr><th>proto</th><th>from</th><th>to</th><th>comment</th></tr>\n";
2244 foreach ($address['outpf'] as $rule)
2245 echo "<tr><td>${rule['proto']}</td><td>${rule['localip']}:${rule['localport']}</td><td>${rule['remoteip']}:${rule['localport']}</td><td>${rule['description']}</td></tr>";
2250 if (count ($address['inpf']))
2252 startPortlet ('arriving NAT rules');
2253 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
2254 echo "<tr><th>proto</th><th>from</th><th>to</th><th>comment</th></tr>\n";
2255 foreach ($address['inpf'] as $rule)
2256 echo "<tr><td>${rule['proto']}</td><td>${rule['localip']}:${rule['localport']}</td><td>${rule['remoteip']}:${rule['localport']}</td><td>${rule['description']}</td></tr>";
2265 function renderIPAddressProperties ($ip)
2267 global $pageno, $tabno, $root;
2268 showMessageOrError();
2269 $address = getIPAddress($ip);
2270 echo "<center><h1>$ip</h1></center>\n";
2271 startPortlet ('update');
2272 echo "<table border=0 cellpadding=10 cellpadding=1 align='center'>\n";
2273 echo "<form action='process.php'><input type=hidden name=op value=editAddress>";
2274 echo "<input type=hidden name=page value='${pageno}'>\n";
2275 echo "<input type=hidden name=tab value='${tabno}'>\n";
2276 echo "<input type=hidden name=ip value='${ip}'>";
2277 echo "<tr><td class='tdright'>Name:</td><td class='tdleft'><input type=text name=name size=20 value='".($address['exists']==1?
$address['name']:'')."'></tr>";
2278 echo "<td class='tdright'>Reserved:</td><td class='tdleft'><input type=checkbox name=reserved size=20 ".($address['exists']==1?
(($address['reserved']=='yes')?
'checked':''):'')."></tr>";
2279 echo "<tr><td colspan=2 class='tdcenter'><input type=submit value='Update address'></td></form></tr>";
2282 if (empty ($address['name']) and $address['reserved'] == 'no')
2284 startPortlet ('release');
2285 echo "<form action='${root}process.php?page=${pageno}&tab=${tabno}&op=editAddress' method=post>";
2286 echo "<input type=hidden name=ip value='${ip}'>";
2287 echo "<input type=hidden name=name value=''>";
2288 echo "<input type=hidden name=reserved value=''>";
2289 echo "<input type=submit value='release'></form>";
2293 function renderIPAddressAssignment ($ip)
2295 global $pageno, $tabno, $root;
2296 $address = getIPAddress($ip);
2298 showMessageOrError();
2299 echo "<center><h1>$ip</h1></center>\n";
2302 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
2303 echo "<tr><th> </th><th>object name</th><th>object interface</th><th>allocation type</th><th> </th></tr>\n";
2305 $numshared = countRefsOfType($address['bonds'], 'shared', 'eq');
2306 $numreg = countRefsOfType($address['bonds'], 'regular', 'eq');
2307 $numvirt = countRefsOfType($address['bonds'], 'virtual', 'eq');
2310 if ( ($numshared > 0 && $numreg > 0) ||
$numreg > 1 )
2312 elseif ( $address['reserved'] == 'yes' and $numshared+
$numreg+
$numvirt > 0)
2319 if ($address['reserved'] == 'yes')
2320 echo "<tr class='$class'><td colspan='5'><b>RESERVED</b></td></tr>";
2321 foreach ($address['bonds'] as $bond)
2323 echo "<tr class='$class'><form action='process.php'>";
2324 echo "<input type=hidden name=op value='updIPv4Allocation'>";
2325 echo "<input type=hidden name=page value='${pageno}'>";
2326 echo "<input type=hidden name=tab value='${tabno}'>";
2327 echo "<input type=hidden name=ip value='$ip'>";
2328 echo "<input type=hidden name=object_id value='${bond['object_id']}'>";
2329 echo "<td><a href='process.php?op=delIPv4Allocation&page=${pageno}&tab=${tabno}&ip=$ip&object_id=${bond['object_id']}'>";
2330 printImageHREF ('delete', 'Unallocate address');
2332 echo "<td><a href='${root}?page=object&object_id=${bond['object_id']}&hl_ipv4_addr=${ip}'>${bond['object_name']}</td>";
2333 echo "<td><input type='text' name='bond_name' value='${bond['name']}' size=10></td>";
2334 echo "<td><select name='bond_type'>";
2335 switch ($bond['type'])
2338 echo "<option value='regular'>Regular</option>";
2339 echo "<option value='virtual' selected>Virtual</option>";
2340 echo "<option value='shared'>Shared</option>";
2343 echo "<option value='regular'>Regular</option>";
2344 echo "<option value='virtual'>Virtual</option>";
2345 echo "<option value='shared' selected>Shared</option>";
2348 echo "<option value='regular' selected>Regular</option>";
2349 echo "<option value='virtual'>Virtual</option>";
2350 echo "<option value='shared'>Shared</option>";
2353 echo "</select></td><td>";
2354 printImageHREF ('save', 'Save changes', TRUE);
2355 echo "</td></form></tr>\n";
2357 echo "<form action='process.php'><input type='hidden' name='op' value='addIPv4Allocation'>";
2358 echo "<input type=hidden name=page value='${pageno}'>\n";
2359 echo "<input type=hidden name=tab value='${tabno}'>\n";
2360 echo "<input type='hidden' name='ip' value='$ip'>";
2362 printImageHREF ('add', 'new allocation', TRUE);
2363 echo "</td><td><select name='object_id'>";
2365 foreach (explode (',', getConfigVar ('IPV4_PERFORMERS')) as $type)
2366 foreach (getNarrowObjectList ($type) as $object)
2367 echo "<option value='${object['id']}'>${object['dname']}</option>";
2369 echo "</select></td><td><input type='text' name='bond_name' value='' size=10></td>";
2370 echo "<td><select name='bond_type'><option value='regular'>Regular</option><option value='virtual'>Virtual</option><option value='shared'>Shared</option></select></td>";
2371 echo "<td> </td></form></tr>";
2372 echo "</table><br><br>";
2376 function renderNATv4ForObject ($object_id = 0)
2378 global $pageno, $tabno, $root;
2380 $info = getObjectInfo ($object_id);
2381 $forwards = getNATv4ForObject ($object_id);
2382 $addresses = getObjectAddresses ($object_id);
2383 showMessageOrError();
2384 echo "<center><h2>locally performed NAT</h2></center>";
2386 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
2387 echo "<tr><th></th><th>Match endpoint</th><th>Translate to</th><th>Target object</th><th>Comment</th><th> </th></tr>\n";
2389 foreach ($forwards['out'] as $pf)
2393 foreach ($addresses as $addr)
2394 if ($addr['ip'] == $pf['localip'])
2397 $name = $addr['name'];
2401 echo "<tr class='$class'>";
2402 echo "<td><a href='process.php?op=delPortForwarding&localip=${pf['localip']}&localport=${pf['localport']}&remoteip=${pf['remoteip']}&remoteport=${pf['remoteport']}&proto=${pf['proto']}&object_id=$object_id&page=${pageno}&tab=${tabno}'>";
2403 printImageHREF ('delete', 'Delete NAT rule');
2405 echo "<td>${pf['proto']}/${name}: <a href='${root}?page=ipaddress&tab=default&ip=${pf['localip']}'>${pf['localip']}</a>:${pf['localport']}";
2406 if (!empty ($pf['local_addr_name']))
2407 echo ' (' . $pf['local_addr_name'] . ')';
2409 echo "<td><a href='${root}?page=ipaddress&tab=default&ip=${pf['remoteip']}'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
2411 $address=getIPAddress($pf['remoteip']);
2413 echo "<td class='description'>";
2414 if (count ($address['bonds']))
2415 foreach($address['bonds'] as $bond)
2416 echo "<a href='${root}?page=object&tab=default&object_id=${bond['object_id']}'>${bond['object_name']}(${bond['name']})</a> ";
2417 elseif (!empty ($pf['remote_addr_name']))
2418 echo '(' . $pf['remote_addr_name'] . ')';
2419 echo "</td><form action='process.php'><input type='hidden' name='op' value='updPortForwarding'><input type=hidden name=page value='${pageno}'>";
2420 echo "<input type=hidden name=tab value='${tabno}'><input type='hidden' name='object_id' value='$object_id'>";
2421 echo "<input type='hidden' name='localip' value='${pf['localip']}'><input type='hidden' name='localport' value='${pf['localport']}'>";
2422 echo "<input type='hidden' name='remoteip' value='${pf['remoteip']}'><input type='hidden' name='remoteport' value='${pf['remoteport']}'>";
2423 echo "<input type='hidden' name='proto' value='${pf['proto']}'><td class='description'>";
2424 echo "<input type='text' name='description' value='${pf['description']}'></td><td>";
2425 printImageHREF ('save', 'Save changes', TRUE);
2426 echo "</td></form></tr>";
2428 echo "<form action='process.php'><input type='hidden' name='op' value='forwardPorts'>";
2429 echo "<input type='hidden' name='object_id' value='$object_id'>";
2430 echo "<input type=hidden name=page value='${pageno}'>\n";
2431 echo "<input type=hidden name=tab value='${tabno}'>\n";
2432 echo "<tr align='center'><td>";
2433 printImageHREF ('add', 'Add new NAT rule', TRUE);
2435 printSelect (array ('TCP' => 'TCP', 'UDP' => 'UDP'), 'proto');
2436 echo "<select name='localip' tabindex=1>";
2438 foreach ($addresses as $addr)
2439 echo "<option value='${addr['ip']}'>" . (empty ($addr['name']) ?
'' : "${addr['name']}: ") .
2440 "${addr['ip']}" . (empty ($addr['address_name']) ?
'' : " (${addr['address_name']})") . "</option>";
2442 echo "</select>:<input type='text' name='localport' size='4' tabindex=2></td>";
2443 echo "<td><input type='text' name='remoteip' id='remoteip' size='10' tabindex=3>";
2444 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\");'>";
2445 printImageHREF ('find', 'Find object');
2447 echo ":<input type='text' name='remoteport' size='4' tabindex=4></td><td></td>";
2448 echo "<td colspan=1><input type='text' name='description' size='20' tabindex=5></td><td> </td></tr>";
2451 echo "</table><br><br>";
2453 echo "<center><h2>arriving NAT connections</h2></center>";
2454 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
2455 echo "<tr><th></th><th>Source</th><th>Source objects</th><th>Target</th><th>Description</th></tr>\n";
2457 foreach ($forwards['in'] as $pf)
2459 echo "<tr><td><a href='process.php?op=delPortForwarding&localip=${pf['localip']}&localport=${pf['localport']}&remoteip=${pf['remoteip']}&remoteport=${pf['remoteport']}&proto=${pf['proto']}&object_id=${pf['object_id']}&page=${pageno}&tab=${tabno}'>";
2460 printImageHREF ('delete', 'Delete NAT rule');
2462 echo "<td>${pf['proto']}/<a href='${root}?page=ipaddress&tab=default&ip=${pf['localip']}'>${pf['localip']}</a>:${pf['localport']}</td>";
2463 echo "<td class='description'><a href='${root}?page=object&tab=default&object_id=${pf['object_id']}'>${pf['object_name']}</a>";
2464 echo "</td><td><a href='${root}?page=ipaddress&tab=default&ip=${pf['remoteip']}'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
2465 echo "<td class='description'>${pf['description']}</td></tr>";
2468 echo "</table><br><br>";
2471 function renderAddMultipleObjectsForm ()
2473 global $root, $pageno, $tabno, $nextorder;
2476 $global_type_id = 0;
2478 $asset_no = array();
2479 $keepvalues1 = $keepvalues2 = FALSE;
2481 // Look for current submit.
2482 if (isset ($_REQUEST['got_fast_data']))
2484 $taglist = isset ($_REQUEST['taglist']) ?
$_REQUEST['taglist'] : array();
2485 $keepvalues1 = TRUE;
2486 $max = getConfigVar ('MASSCOUNT');
2487 for ($i = 0; $i < $max; $i++
)
2489 if (!isset ($_REQUEST["${i}_object_type_id"]))
2491 $log[] = array ('code' => 'error', 'message' => "Submitted form is invalid at line " . $i +
1);
2494 assertUIntArg ("${i}_object_type_id", __FUNCTION__
, TRUE);
2495 assertStringArg ("${i}_object_name", __FUNCTION__
, TRUE);
2496 assertStringArg ("${i}_object_label", __FUNCTION__
, TRUE);
2497 assertStringArg ("${i}_object_asset_no", __FUNCTION__
, TRUE);
2498 assertStringArg ("${i}_object_barcode", __FUNCTION__
, TRUE);
2499 $type_id[$i] = $_REQUEST["${i}_object_type_id"];
2500 // Save user input for possible rendering.
2501 $name[$i] = $_REQUEST["${i}_object_name"];
2502 $label[$i] = $_REQUEST["${i}_object_label"];
2503 $asset_no[$i] = $_REQUEST["${i}_object_asset_no"];
2504 $barcode[$i] = $_REQUEST["${i}_object_barcode"];
2506 // It's better to skip silently, than to print a notice.
2507 if ($type_id[$i] == 0)
2509 if (commitAddObject ($name[$i], $label[$i], $barcode[$i], $type_id[$i], $asset_no[$i], $taglist) === TRUE)
2510 $log[] = array ('code' => 'success', 'message' => "Added new object '${name[$i]}'");
2512 $log[] = array ('code' => 'error', 'message' => __FUNCTION__
. ': commitAddObject() failed');
2515 elseif (isset ($_REQUEST['got_very_fast_data']))
2517 $taglist = isset ($_REQUEST['taglist']) ?
$_REQUEST['taglist'] : array();
2518 $keepvalues2 = TRUE;
2519 assertUIntArg ('global_type_id', __FUNCTION__
, TRUE);
2520 assertStringArg ('namelist', __FUNCTION__
, TRUE);
2521 $global_type_id = $_REQUEST['global_type_id'];
2522 if ($global_type_id == 0)
2524 if (!empty ($_REQUEST['namelist']))
2525 $log[] = array ('code' => 'error', 'message' => 'Object type is not selected, check the form below');
2527 $log[] = array ('code' => 'error', 'message' => 'Empty form has been ignored. Cheers.');
2531 // The name extractor below was stolen from ophandlers.php:addMultiPorts()
2532 $names1 = explode ('\n', $_REQUEST['namelist']);
2534 foreach ($names1 as $line)
2536 $parts = explode ('\r', $line);
2538 if (empty ($parts[0]))
2541 $names2[] = rtrim ($parts[0]);
2543 foreach ($names2 as $cname)
2544 if (commitAddObject ($cname, '', '', $global_type_id, '', $taglist) === TRUE)
2545 $log[] = array ('code' => 'success', 'message' => "Added new object '${cname}'");
2547 $log[] = array ('code' => 'error', 'message' => "Could not add '${cname}'");
2552 // Render a form for the next.
2553 $typelist = getObjectTypeList();
2554 $typelist[0] = 'select type...';
2556 startPortlet ('Distinct types, same tags');
2557 $max = getConfigVar ('MASSCOUNT');
2558 echo "<form name=fastform method=post action='${root}?page=${pageno}&tab=${tabno}'>";
2559 echo '<table border=0 align=center>';
2560 echo "<tr><th>Object type</th><th>Common name</th><th>Visible label</th>";
2561 echo "<th>Asset tag</th><th>Barcode</th><th>Tags</th></tr>\n";
2562 // If a user forgot to select object type on input, we keep his
2563 // previous input in the form.
2564 for ($i = 0; $i < $max; $i++
)
2567 // Don't employ DEFAULT_OBJECT_TYPE to avoid creating ghost records for pre-selected empty rows.
2568 printSelect ($typelist, "${i}_object_type_id", 0);
2570 echo "<td><input type=text size=30 name=${i}_object_name";
2571 if ($keepvalues1 and isset ($name[$i]) and (!isset ($type_id[$i]) or $type_id[$i] == 0))
2572 echo " value='${name[$i]}'";
2574 echo "<td><input type=text size=30 name=${i}_object_label";
2575 if ($keepvalues1 and isset ($label[$i]) and (!isset ($type_id[$i]) or $type_id[$i] == 0))
2576 echo " value='${label[$i]}'";
2578 echo "<td><input type=text size=20 name=${i}_object_asset_no";
2579 if ($keepvalues1 and isset ($asset_no[$i]) and (!isset ($type_id[$i]) or $type_id[$i] == 0))
2580 echo " value='${asset_no[$i]}'";
2582 echo "<td><input type=text size=10 name=${i}_object_barcode";
2583 if ($keepvalues1 and isset ($barcode[$i]) and (!isset ($type_id[$i]) or $type_id[$i] == 0))
2584 echo " value='${barcode[$i]}'";
2588 echo "<td valign=top rowspan=${max}>";
2594 echo "<tr><td class=submit colspan=5><input type=submit name=got_fast_data value='Go!'></td></tr>\n";
2595 echo "</form></table>\n";
2598 startPortlet ('Same type, same tags');
2599 echo "<form name=veryfastform method=post action='${root}?page=${pageno}&tab=${tabno}'>";
2600 echo "<table border=0 align=center><tr><th>names</th><th>type</th></tr>";
2601 echo "<tr><td rowspan=3><textarea name=namelist cols=40 rows=25>\n";
2602 if ($keepvalues2 and $global_type_id == 0)
2603 echo $_REQUEST['namelist'];
2604 echo "</textarea></td><td valign=top>";
2605 printSelect ($typelist, "global_type_id", getConfigVar ('DEFAULT_OBJECT_TYPE'));
2607 echo "<tr><th>Tags</th></tr>";
2608 echo "<tr><td valign=top>";
2611 echo "<tr><td colspan=2><input type=submit name=got_very_fast_data value='Go!'></td></tr></table>\n";
2616 function printGreeting ()
2618 global $remote_username, $accounts, $root;
2619 $account = $accounts[$remote_username];
2620 echo "Hello, ${account['user_realname']}. This is RackTables " . CODE_VERSION
. ". Click <a href='${root}?logout'>here</a> to logout.";
2623 function renderSearchResults ()
2625 global $remote_username, $root;
2626 $terms = trim ($_REQUEST['q']);
2629 showError ('Search string cannot be empty.', __FUNCTION__
);
2632 if (!permitted ('objects', 'default'))
2634 showError ('You are not authorized for viewing information about objects.', __FUNCTION__
);
2638 // If we search for L2 address, we can either find one or find none.
2641 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
2642 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
2643 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
2644 // STP bridge ID: bridge priotity + port MAC address. Cut off first 4 chars and look for MAC address.
2645 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)
2647 // Search for L2 address.
2649 $terms = str_replace ('.', '', $terms);
2650 $terms = str_replace (':', '', $terms);
2651 $terms = substr ($terms, -12);
2652 $result = searchByl2address ($terms);
2653 if ($result !== NULL)
2657 $summary['port'][] = $result;
2660 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))
2661 // Search for IP address.
2663 $result = getRangeByIp ($terms);
2664 if ($result !== NULL)
2667 $lasthit = 'ipv4address1';
2668 $summary['ipv4address1'][] = $terms;
2672 // Search for objects, addresses, networks, virtual services and RS pools by their description.
2674 $tmp = getObjectSearchResults ($terms);
2677 $nhits +
= count ($tmp);
2678 $lasthit = 'object';
2679 $summary['object'] = $tmp;
2681 $tmp = getIPv4AddressSearchResult ($terms);
2684 $nhits +
= count ($tmp);
2685 $lasthit = 'ipv4address2';
2686 $summary['ipv4address2'] = $tmp;
2688 $tmp = getIPv4PrefixSearchResult ($terms);
2691 $nhits +
= count ($tmp);
2692 $lasthit = 'ipv4network';
2693 $summary['ipv4network'] = $tmp;
2695 $tmp = getIPv4RSPoolSearchResult ($terms);
2698 $nhits +
= count ($tmp);
2699 $lasthit = 'ipv4rspool';
2700 $summary['ipv4rspool'] = $tmp;
2702 $tmp = getIPv4VServiceSearchResult ($terms);
2705 $nhits +
= count ($tmp);
2706 $lasthit = 'ipv4vs';
2707 $summary['ipv4vs'] = $tmp;
2709 $tmp = getAccountSearchResult ($terms);
2712 $nhits +
= count ($tmp);
2714 $summary['user'] = $tmp;
2718 echo "<center><h2>Nothing found for '${terms}'</h2></center>";
2719 elseif ($nhits == 1)
2721 $record = current ($summary[$lasthit]);
2725 echo "<script language='Javascript'>document.location='${root}?page=object";
2726 echo "&hl_port_id=" . $record['port_id'];
2727 echo "&object_id=" . $record['object_id'] . "';//</script>";
2729 case 'ipv4address1':
2730 echo "<script language='Javascript'>document.location='${root}?page=ipaddress";
2731 echo "&ip=${record}";
2732 echo "';//</script>";
2734 case 'ipv4address2':
2735 echo "<script language='Javascript'>document.location='${root}?page=ipaddress";
2736 echo "&ip=${record['ip']}";
2737 echo "';//</script>";
2740 echo "<script language='Javascript'>document.location='${root}?page=iprange";
2741 echo "&id=${record['id']}";
2742 echo "';//</script>";
2745 echo "<script language='Javascript'>document.location='${root}?page=object&object_id=${record['id']}';//</script>";
2748 echo "<script language='Javascript'>document.location='${root}?page=ipv4rsp&pool_id=${record['pool_id']}';//</script>";
2751 echo "<script language='Javascript'>document.location='${root}?page=ipv4vs&vs_id=${record['id']}';//</script>";
2754 echo "<script language='Javascript'>document.location='${root}?page=user&user_id=${record['user_id']}';//</script>";
2763 echo "<center><h2>${nhits} result(s) found for '${terms}'</h2></center>";
2764 foreach ($summary as $where => $what)
2768 startPortlet ("<a href='${root}?page=objects'>Objects</a>");
2769 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
2770 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>barcode</th></tr>';
2771 foreach ($what as $obj)
2773 echo "<tr class=row_${order}><td><a href=\"${root}?page=object&object_id=${obj['id']}\">${obj['dname']}</a></td>";
2774 echo "<td>${obj['label']}</td>";
2775 echo "<td>${obj['asset_no']}</td>";
2776 echo "<td>${obj['barcode']}</td></tr>";
2777 $order = $nextorder[$order];
2783 startPortlet ("<a href='${root}?page=ipv4space'>IPv4 networks</a>");
2784 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
2785 echo '<tr><th>Network</th><th>Descritpion</th></tr>';
2786 foreach ($what as $net)
2788 echo "<tr class=row_${order}><td class=tdleft><a href='${root}?page=iprange&id=${net['id']}'>${net['ip']}";
2789 echo '/' . $net['mask'] . '</a></td>';
2790 echo "<td class=tdleft>${net['name']}</td></tr>";
2791 $order = $nextorder[$order];
2796 case 'ipv4address2':
2797 startPortlet ('IPv4 addresses');
2798 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
2799 echo '<tr><th>Address</th><th>Descritpion</th></tr>';
2800 foreach ($what as $addr)
2802 echo "<tr class=row_${order}><td class=tdleft><a href='${root}?page=ipaddress&ip=${addr['ip']}'>";
2803 echo "${addr['ip']}</a></td>";
2804 echo "<td class=tdleft>${addr['name']}</td></tr>";
2805 $order = $nextorder[$order];
2811 startPortlet ("<a href='${root}?page=ipv4rsplist'>RS pools</a>");
2812 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
2813 foreach ($what as $rspool)
2815 echo "<tr class=row_${order}><td class=tdleft><a href='${root}?page=ipv4rsp&pool_id=${rspool['pool_id']}'>";
2816 echo buildRSPoolName ($rspool);
2817 echo "</a></td></tr>";
2818 $order = $nextorder[$order];
2824 startPortlet ("<a href='${root}?page=ipv4vslist'>Virtual services</a>");
2825 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
2826 echo '<tr><th>VS</th><th>Descritpion</th></tr>';
2827 foreach ($what as $vs)
2829 echo "<tr class=row_${order}><td class=tdleft><a href='${root}?page=ipv4vs&vs_id=${vs['id']}'>";
2830 echo buildVServiceName ($vs);
2831 echo "</a></td><td class=tdleft>${vs['name']}</td></tr>";
2832 $order = $nextorder[$order];
2838 startPortlet ("<a href='${root}?page=userlist'>Users</a>");
2839 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
2840 echo '<tr><th>username</th><th>realname</th></tr>';
2841 foreach ($what as $item)
2843 echo "<tr class=row_${order}><td class=tdleft><a href='${root}?page=user&user_id=${item['user_id']}'>";
2844 echo $item['user_name'];
2845 echo "</a></td><td class=tdleft>${item['user_realname']}</td></tr>";
2846 $order = $nextorder[$order];
2855 // This function prints a table of checkboxes to aid the user in toggling mount atoms
2856 // from one state to another. The first argument is rack data as
2857 // produced by getRackData(), the second is the value used for the 'unckecked' state
2858 // and the third is the value used for 'checked' state.
2860 // for mounting an object: printAtomGrid ($data, 'F', 'T')
2861 // for changing rack design: printAtomGrid ($data, 'A', 'F')
2862 // for adding rack problem: printAtomGrid ($data, 'F', 'U')
2863 // for adding object problem: printAtomGrid ($data, 'T', 'W')
2865 function renderAtomGrid ($data)
2867 $rack_id = $data['id'];
2868 for ($unit_no = $data['height']; $unit_no > 0; $unit_no--)
2870 echo "<tr><th>${unit_no}</th>";
2871 for ($locidx = 0; $locidx < 3; $locidx++
)
2873 $state = $data[$unit_no][$locidx]['state'];
2874 echo "<td class=state_${state}";
2875 if (isset ($data[$unit_no][$locidx]['hl']))
2876 echo $data[$unit_no][$locidx]['hl'];
2878 if (!($data[$unit_no][$locidx]['enabled'] === TRUE))
2879 echo '<input type=checkbox disabled>';
2881 echo "<input type=checkbox" . $data[$unit_no][$locidx]['checked'] . " name=atom_${rack_id}_${unit_no}_${locidx}>";
2888 function renderUserList ()
2890 global $nextorder, $accounts, $root;
2891 echo "<table border=0 class=objectview>\n";
2892 echo "<tr><td class=pcleft>";
2893 startPortlet ('User accounts');
2894 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
2895 echo "<tr><th class=tdleft>Username</th><th class=tdleft>Real name</th></tr>";
2897 $tagfilter = getTagFilter();
2898 foreach (getUserAccounts ($tagfilter, getTFMode()) as $user)
2900 echo "<tr class=row_${order}><td class=tdleft><a href='${root}?page=user&user_id=${user['user_id']}'>";
2901 echo "${user['user_name']}</a></td>";
2902 echo "<td class=tdleft>${user['user_realname']}</td></li>";
2903 $order = $nextorder[$order];
2907 echo '</td><td class=pcright>';
2908 renderTagFilterPortlet ($tagfilter, 'user');
2909 echo "</td></tr></table>\n";
2912 function renderUserListEditor ()
2914 global $root, $pageno, $tabno, $accounts;
2915 startPortlet ('User accounts');
2916 showMessageOrError();
2917 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
2918 echo "<tr><th>status (click to change)</th><th>Username</th><th>Real name</th><th>Password</th><th> </th></tr>\n";
2919 foreach ($accounts as $account)
2921 echo "<form action='${root}process.php'>";
2922 echo "<input type=hidden name=op value=updateUser>";
2923 echo "<input type=hidden name=page value='${pageno}'>\n";
2924 echo "<input type=hidden name=tab value='${tabno}'>\n";
2925 echo "<input type=hidden name=user_id value='${account['user_id']}'><tr>";
2927 if ($account['user_enabled'] == 'yes' && $account['user_id'] != 1)
2929 echo "<a href='${root}process.php?op=disableUser&page=${pageno}&tab=${tabno}&user_id=${account['user_id']}'>";
2930 printImageHREF ('blockuser', 'disable account');
2933 if ($account['user_enabled'] == 'no' && $account['user_id'] != 1)
2935 echo "<a href='${root}process.php?op=enableUser&page=${pageno}&tab=${tabno}&user_id=${account['user_id']}'>";
2936 printImageHREF ('unblockuser', 'enable account');
2939 // Otherwise skip icon.
2941 echo "<td><input type=text name=username value='${account['user_name']}' size=16></td>";
2942 echo "<td><input type=text name=realname value='${account['user_realname']}' size=24></td>";
2943 echo "<td><input type=password name=password value='${account['user_password_hash']}' size=64></td><td>";
2944 printImageHREF ('save', 'Save changes', TRUE);
2945 echo "</td></form></tr>\n";
2947 echo "<form action='${root}process.php' method=post><tr>";
2948 echo "<input type=hidden name=op value=createUser>\n";
2949 echo "<input type=hidden name=page value='${pageno}'>\n";
2950 echo "<input type=hidden name=tab value='${tabno}'>\n";
2951 echo "<td> </td><td><input type=text size=16 name=username tabindex=100></td>\n";
2952 echo "<td><input type=text size=24 name=realname tabindex=101></td>";
2953 echo "<td><input type=password size=64 name=password tabindex=102></td><td>";
2954 printImageHREF ('create', 'Add new account', TRUE, 103);
2955 echo "</td></tr></form>";
2956 echo "</table><br>\n";
2960 function printChildrenAsOptions ($root, $depth = 0)
2962 echo "<option value=${root['title']}>";
2965 for ($i = 0; $i < $depth; $i++
)
2967 echo $root['title'];
2969 foreach ($root['kids'] as $kid)
2970 printChildrenAsOptions ($kid, $depth +
1);
2973 // 1. Find all parentless pages.
2974 // 2. For each of them recursively find all children.
2975 // 3. Output the tree with recursion tree display.
2976 function printPagesTree ()
2980 foreach ($page as $ctitle => $cpage)
2981 if (!isset ($cpage['parent']))
2983 $croot['title'] = $ctitle;
2984 $croot['kids'] = getAllChildPages ($ctitle);
2985 printChildrenAsOptions ($croot);
2990 function renderPortMapViewer ()
2992 renderPortMap (FALSE);
2995 function renderPortMapEditor ()
2997 renderPortMap (TRUE);
3000 function renderPortMap ($editable = FALSE)
3002 global $nextorder, $root, $pageno, $tabno;
3003 showMessageOrError();
3004 startPortlet ("Port compatibility map");
3005 $ptlist = getPortTypes();
3006 $pclist = getPortCompat();
3007 $pctable = buildPortCompatMatrixFromList ($ptlist, $pclist);
3010 echo "<form method=post action='${root}process.php'>";
3011 echo "<input type=hidden name=page value='${pageno}'>";
3012 echo "<input type=hidden name=tab value='${tabno}'>";
3013 echo "<input type=hidden name=op value=save>";
3015 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
3016 echo "<tr><th class=vert_th> </th>";
3017 foreach ($ptlist as $name2)
3018 echo "<th>to ${name2}</th>";
3020 // Make a copy to have an independent array pointer.
3023 foreach ($ptlistY as $type1 => $name1)
3025 echo "<tr class=row_${order}><th class=vert_th style='border-bottom: 0px;'>from $name1</th>";
3026 foreach ($ptlist as $type2 => $name2)
3028 echo '<td><input type=checkbox' . ($editable ?
" name=atom_${type1}_${type2}" : ' disabled');
3029 echo ($pctable[$type1][$type2] ?
' checked' : '') . '></td>';
3032 $order = $nextorder[$order];
3034 echo '</table><br>';
3037 echo "<input type=submit value='Save changes'>";
3043 function renderConfigMainpage ()
3045 global $pageno, $root;
3046 $children = getDirectChildPages ($pageno);
3048 // FIXME: assume all config kids to have static titles at the moment,
3049 // but use some proper abstract function later.
3050 foreach ($children as $cpageno => $child)
3051 echo "<li><a href='${root}?page=${cpageno}'>" . $child['title'] . "</li>\n";
3056 function renderRackPage ($rack_id)
3060 showError ('Invalid rack_id', __FUNCTION__
);
3063 if (($rackData = getRackData ($rack_id)) == NULL)
3065 showError ('getRackData() failed', __FUNCTION__
);
3068 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0><tr>";
3070 // Left column with information.
3071 echo "<td class=pcleft>";
3072 renderRackInfoPortlet ($rackData);
3075 // Right column with rendered rack.
3077 startPortlet ('Rack diagram');
3078 renderRack ($rack_id);
3082 echo '</tr></table>';
3085 function renderDictionary ()
3088 $dict = getDict (TRUE);
3089 echo "<br><table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
3090 foreach ($dict as $chapter_no => $chapter)
3093 echo "<tr><th>Chapter</th><th>refs</th><th>Word</th></tr>\n";
3094 $wc = count ($chapter['word']);
3095 echo "<tr class=row_${order}><td class=tdleft" . ($wc ?
" rowspan = ${wc}" : '');
3096 echo "><div title='number=${chapter_no}'>${chapter['name']} (${wc} records)</div></td>";
3098 echo "<td colspan=2>none</td>";
3102 foreach ($chapter['word'] as $key => $value)
3105 echo "<tr class=row_${order}>";
3107 $chap_start = FALSE;
3108 echo '<td>' . ($chapter['refcnt'][$key] ?
$chapter['refcnt'][$key] : ' ') . '</td>';
3109 echo "<td><div title='key=${key}'>${value}</div></td></tr>\n";
3110 $order = $nextorder[$order];
3114 echo "</table>\n<br>";
3117 function renderDictionaryEditor ()
3119 global $root, $pageno, $tabno, $nextorder;
3121 showMessageOrError();
3122 echo "<br><table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
3123 foreach ($dict as $chapter_no => $chapter)
3126 echo "<tr><th>Chapter</th><th> </th><th>Word</th><th> </th></tr>\n";
3127 $wc = count ($chapter['word']);
3128 // One extra span for the new record per each chapter block.
3129 echo "<tr class=row_${order}><td class=tdleft" . ($wc ?
' rowspan = ' . ($wc +
1) : '');
3130 echo "><div title='number=${chapter_no}'>${chapter['name']} (${wc} records)</div></td>";
3131 echo "<form action='${root}process.php' method=post>";
3132 echo "<input type=hidden name=page value='${pageno}'>";
3133 echo "<input type=hidden name=tab value='${tabno}'>";
3134 echo "<input type=hidden name=op value=add>";
3135 echo "<input type=hidden name=chapter_no value='${chapter['no']}'>";
3136 echo "<td> </td>";
3137 echo "<td class=tdright><input type=text name=dict_value size=32></td>";
3138 echo "<td><input type=submit value='Add new'></td>";
3139 echo '</tr></form>';
3140 $order = $nextorder[$order];
3141 foreach ($chapter['word'] as $key => $value)
3143 echo "<form action='${root}process.php' method=post>";
3144 echo "<input type=hidden name=page value='${pageno}'>";
3145 echo "<input type=hidden name=tab value='${tabno}'>";
3146 echo "<input type=hidden name=op value='upd'>";
3147 echo "<input type=hidden name=chapter_no value='${chapter['no']}'>";
3148 echo "<input type=hidden name=dict_key value='${key}'>";
3149 echo "<tr class=row_${order}><td>";
3150 // Prevent deleting words currently used somewhere.
3151 if ($chapter['refcnt'][$key])
3152 printImageHREF ('nodelete', 'referenced ' . $chapter['refcnt'][$key] . ' time(s)');
3155 echo "<a href='${root}process.php?page=${pageno}&tab=${tabno}&op=del&chapter_no=${chapter['no']}&dict_key=${key}'>";
3156 printImageHREF ('delete', 'Delete word');
3160 echo "<td class=tdright><input type=text name=dict_value size=32 value='${value}'></td>";
3161 echo "<td><input type=submit value=OK></td>";
3162 echo "</tr></form>\n";
3163 $order = $nextorder[$order];
3164 } // foreach ($chapter['word']
3169 // We don't allow to rename/delete a sticky chapter and we don't allow
3170 // to delete a non-empty chapter.
3171 function renderChaptersEditor ()
3173 global $root, $pageno, $tabno;
3174 showMessageOrError();
3176 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
3177 echo '<tr><th> </th><th>Chapter name</th><th>Words</th><th> </th></tr>';
3178 foreach ($dict as $chapter)
3180 $wordcount = count ($chapter['word']);
3181 $sticky = $chapter['sticky'];
3182 echo "<form action='${root}process.php' method=post>";
3183 echo "<input type=hidden name=page value='${pageno}'>";
3184 echo "<input type=hidden name=tab value='${tabno}'>";
3185 echo "<input type=hidden name=op value=upd>";
3186 echo "<input type=hidden name=chapter_no value='${chapter['no']}'>";
3190 printImageHREF ('nodelete', 'system chapter');
3191 elseif ($wordcount > 0)
3192 printImageHREF ('nodelete', 'contains ' . $wordcount . ' word(s)');
3195 echo "<a href='${root}process.php?page=${pageno}&tab=${tabno}&op=del&chapter_no=${chapter['no']}'>";
3196 printImageHREF ('delete', 'Remove chapter');
3200 echo "<td><input type=text name=chapter_name value='${chapter['name']}'" . ($sticky ?
' disabled' : '') . "></td>";
3201 echo "<td class=tdleft>${wordcount}</td><td>";
3205 echo "<input type=submit value='OK'>";
3209 echo "<form action='${root}process.php' method=post>";
3210 echo "<input type=hidden name=page value='${pageno}'>";
3211 echo "<input type=hidden name=tab value='${tabno}'>";
3212 echo "<input type=hidden name=op value=add>";
3214 printImageHREF ('add', '', TRUE);
3215 echo "</td><td colspan=3><input type=text name=chapter_name></td>";
3221 function renderAttributes ()
3224 $attrMap = getAttrMap();