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>";
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 $dummy => $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['dict_value']);
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 $dummy => $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 renderNewObjectForm ()
260 global $pageno, $tabno;
262 // Look for current submit.
263 if (isset ($_REQUEST['got_data']))
266 assertUIntArg ('object_type_id', __FUNCTION__
);
267 assertStringArg ('object_name', __FUNCTION__
, TRUE);
268 assertStringArg ('object_label', __FUNCTION__
, TRUE);
269 assertStringArg ('object_barcode', __FUNCTION__
, TRUE);
270 assertStringArg ('object_asset_no', __FUNCTION__
, TRUE);
271 $type_id = $_REQUEST['object_type_id'];
272 $name = $_REQUEST['object_name'];
273 $label = $_REQUEST['object_label'];
274 $asset_no = $_REQUEST['object_asset_no'];
275 $barcode = $_REQUEST['object_barcode'];
277 if (commitAddObject ($name, $label, $barcode, $type_id, $asset_no) === TRUE)
278 $log[] = array ('code' => 'success', 'message' => "Added new object '${name}'");
280 $log[] = array ('code' => 'error', 'message' => __FUNCTION__
. ': commitAddObject() failed');
284 // Render a form for the next.
285 startPortlet ('Object attributes');
287 echo "<input type=hidden name=page value=${pageno}>";
288 echo "<input type=hidden name=tab value=${tabno}>";
289 echo '<table border=0 align=center>';
290 echo "<tr><th class=tdright>Type:</th><td class=tdleft>";
291 $typelist = getObjectTypeList();
292 $typelist[0] = 'select type...';
293 printSelect ($typelist, 'object_type_id', getConfigVar ('DEFAULT_OBJECT_TYPE'));
295 echo "<tr><th class=tdright>Common name:</th><td class=tdleft><input type=text name=object_name></td></tr>\n";
296 echo "<tr><th class=tdright>Visible label:</th><td class=tdleft><input type=text name=object_label></td></tr>\n";
297 echo "<tr><th class=tdright>Asset tag:</th><td class=tdleft><input type=text name=object_asset_no></td></tr>\n";
298 echo "<tr><th class=tdright>Barcode:</th><td class=tdleft><input type=text name=object_barcode></td></tr>\n";
299 echo "<tr><td class=submit colspan=2><input type=submit name=got_data value='Create'></td></tr>\n";
300 echo '</form></table>';
304 function renderNewRackForm ($row_id)
306 global $pageno, $tabno;
308 // Look for current submit.
309 if (isset ($_REQUEST['got_data']))
312 assertStringArg ('rack_name', __FUNCTION__
);
313 assertUIntArg ('rack_height', __FUNCTION__
);
314 assertStringArg ('rack_comment', __FUNCTION__
, TRUE);
315 $name = $_REQUEST['rack_name'];
316 $height = $_REQUEST['rack_height'];
317 $comment = $_REQUEST['rack_comment'];
319 if (commitAddRack ($name, $height, $row_id, $comment) === TRUE)
320 $log[] = array ('code' => 'success', 'message' => "Added new rack '${name}'");
322 $log[] = array ('code' => 'error', 'message' => __FUNCTION__
. 'commitAddRack() failed');
326 // Render a form for the next.
327 startPortlet ('Rack attributes');
329 echo "<input type=hidden name=page value=${pageno}>";
330 echo "<input type=hidden name=tab value=${tabno}>";
331 echo "<input type=hidden name=row_id value=${row_id}>";
332 echo '<table border=0 align=center>';
333 $defh = getConfigVar ('DEFAULT_RACK_HEIGHT');
336 echo "<tr><th class=tdright>Name (required):</th><td class=tdleft><input type=text name=rack_name tabindex=1></td></tr>\n";
337 echo "<tr><th class=tdright>Height in units (required):</th><td class=tdleft><input type=text name=rack_height tabindex=2 value='${defh}'></td></tr>\n";
338 echo "<tr><th class=tdright>Comment:</th><td class=tdleft><input type=text name=rack_comment tabindex=3></td></tr>\n";
339 echo "<tr><td class=submit colspan=2><input type=submit name=got_data value='Create'></td></tr>\n";
340 echo '</form></table>';
344 function renderEditObjectForm ($object_id)
346 showMessageOrError();
348 if (isset ($_REQUEST['got_data']))
351 // object_id is already verified by page handler
352 assertUIntArg ('object_type_id', __FUNCTION__
);
353 assertStringArg ('object_name', __FUNCTION__
, TRUE);
354 assertStringArg ('object_label', __FUNCTION__
, TRUE);
355 assertStringArg ('object_barcode', __FUNCTION__
, TRUE);
356 assertStringArg ('object_asset_no', __FUNCTION__
, TRUE);
357 $type_id = $_REQUEST['object_type_id'];
358 if (isset ($_REQUEST['object_has_problems']) and $_REQUEST['object_has_problems'] == 'on')
359 $has_problems = 'yes';
361 $has_problems = 'no';
362 $name = $_REQUEST['object_name'];
363 $label = $_REQUEST['object_label'];
364 $barcode = $_REQUEST['object_barcode'];
365 $asset_no = $_REQUEST['object_asset_no'];
366 $comment = $_REQUEST['object_comment'];
368 if (commitUpdateObject ($object_id, $name, $label, $barcode, $type_id, $has_problems, $asset_no, $comment) === TRUE)
369 $log[] = array ('code' => 'success', 'message' => "Updated object '${name}'");
371 $log[] = array ('code' => 'error', 'message' => __FUNCTION__
. ': commitUpdateObject() failed');
372 // Invalidate thumb cache of all racks objects could occupy.
373 foreach (getResidentRacksData ($object_id, FALSE) as $rack_id)
374 resetThumbCache ($rack_id);
378 global $pageno, $tabno;
379 $object = getObjectInfo ($object_id);
382 showError ('getObjectInfo() failed', __FUNCTION__
);
386 // Render a form for the next submit;
387 echo '<table border=0 width=100%><tr>';
389 echo '<td class=pcleft>';
390 startPortlet ('Static attributes');
391 echo '<form method=post>';
392 echo "<input type=hidden name=page value=${pageno}>";
393 echo "<input type=hidden name=tab value=${tabno}>";
394 echo "<input type=hidden name=object_id value=${object_id}>";
395 echo "<input type=hidden name=got_data value=1>";
396 echo '<table border=0 align=center>';
397 echo "<tr><th class=tdright>Type:</th><td class=tdleft>";
398 printSelect (getObjectTypeList(), 'object_type_id', $object['objtype_id']);
400 // Common attributes.
401 echo "<tr><th class=tdright>Common name:</th><td class=tdleft><input type=text name=object_name value='${object['name']}'></td></tr>\n";
402 echo "<tr><th class=tdright>Visible label:</th><td class=tdleft><input type=text name=object_label value='${object['label']}'></td></tr>\n";
403 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";
404 echo "<tr><th class=tdright>Barcode:</th><td class=tdleft><input type=text name=object_barcode value='${object['barcode']}'></td></tr>\n";
405 echo "<tr><th class=tdright>Has problems:</th><td class=tdleft><input type=checkbox name=object_has_problems";
406 if ($object['has_problems'] == 'yes')
408 echo "></td></tr>\n";
409 echo "<tr><td colspan=2><b>Comment:</b><br><textarea name=object_comment rows=10 cols=80>${object['comment']}</textarea></td></tr>";
410 echo "<tr><th class=submit colspan=2>";
411 printImageHREF ('SAVE', 'Save changes', TRUE);
413 echo '</form></table><br>';
417 // Optional attributes.
418 echo '<td class=pcright>';
419 startPortlet ('Optional attributes');
420 $values = getAttrValues ($object_id);
422 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
423 echo "<tr><th> </th><th>Attribute</th><th>Value</th><th> </th></tr>\n";
424 echo "<form method=post action='${root}process.php'>\n";
425 echo "<input type=hidden name=page value=${pageno}>\n";
426 echo "<input type=hidden name=tab value=${tabno}>\n";
427 echo "<input type=hidden name=op value=upd>\n";
428 echo "<input type=hidden name=object_id value=${object_id}>\n";
429 echo '<input type=hidden name=num_attrs value=' . count($values) . ">\n";
432 foreach ($values as $record)
434 echo "<input type=hidden name=${i}_attr_id value=${record['id']}>";
436 if (!empty ($record['value']))
438 echo "<a href=${root}process.php?page=${pageno}&tab=${tabno}&op=del&object_id=${object_id}&attr_id=${record['id']}>";
439 printImageHREF ('clear', 'Clear value');
445 echo "<td class=tdright>${record['name']}:</td><td class=tdleft>";
446 switch ($record['type'])
451 echo "<input type=text name=${i}_value value='${record['value']}'>";
454 $chapter = readChapter ($record['chapter_name']);
455 $chapter[0] = '-- NOT SET --';
456 printSelect ($chapter, "${i}_value", $record['key']);
462 echo "<tr><td colspan=3>";
463 printImageHREF ('SAVE', 'Save changes', TRUE);
472 echo '<td colspan=2>';
473 startPortlet ('history');
474 renderHistory ($pageno, $object_id);
478 echo '</tr></table>';
481 // This is a clone of renderEditObjectForm().
482 function renderEditRackForm ($rack_id)
485 if (isset ($_REQUEST['got_data']))
488 assertUIntArg ('rack_row_id', __FUNCTION__
);
489 assertUIntArg ('rack_height', __FUNCTION__
);
490 assertStringArg ('rack_name', __FUNCTION__
);
491 assertStringArg ('rack_comment', __FUNCTION__
, TRUE);
492 $row_id = $_REQUEST['rack_row_id'];
493 $height = $_REQUEST['rack_height'];
494 $name = $_REQUEST['rack_name'];
495 $comment = $_REQUEST['rack_comment'];
497 if (commitUpdateRack ($rack_id, $name, $height, $row_id, $comment) === TRUE)
498 $log[] = array ('code' => 'success', 'message' => "Updated rack '${name}'");
500 $log[] = array ('code' => 'error', 'message' => __FUNCTION__
. ': commitUpdateRack() failed');
501 resetThumbCache ($rack_id);
505 global $pageno, $tabno;
506 $rack = getRackData ($rack_id);
509 showError ('getRackData() failed', __FUNCTION__
);
513 // Render a form for the next.
514 startPortlet ('Rack attributes');
516 echo "<input type=hidden name=page value=${pageno}>";
517 echo "<input type=hidden name=tab value=${tabno}>";
518 echo "<input type=hidden name=rack_id value=${rack_id}>";
519 echo '<table border=0 align=center>';
520 echo "<tr><th class=tdright>Rack row:</th><td class=tdleft>";
521 printSelect (readChapter ('RackRow'), 'rack_row_id', $rack['row_id']);
523 echo "<tr><th class=tdright>Name (required):</th><td class=tdleft><input type=text name=rack_name value='${rack['name']}'></td></tr>\n";
524 echo "<tr><th class=tdright>Height (required):</th><td class=tdleft><input type=text name=rack_height value='${rack['height']}'></td></tr>\n";
525 echo "<tr><th class=tdright>Comment:</th><td class=tdleft><input type=text name=rack_comment value='${rack['comment']}'></td></tr>\n";
526 echo "<tr><td class=submit colspan=2><input type=submit name=got_data value='Update'></td></tr>\n";
527 echo '</form></table><br>';
530 startPortlet ('History');
531 renderHistory ($pageno, $rack_id);
535 // This is a helper for creators and editors.
536 function printSelect ($rowList, $select_name, $selected_id = 1)
538 // First collect all data for OPTGROUPs, then ouput it and dump
539 // the rest of records as is.
542 foreach ($rowList as $dict_key => $dict_value)
544 if (strpos ($dict_value, '^') !== FALSE)
546 $tmp = explode ('^', $dict_value, 2);
547 $optgroup[$tmp[0]][$dict_key] = $tmp[1];
549 elseif (strpos ($dict_value, '&') !== FALSE)
551 $tmp = explode ('&', $dict_value, 2);
552 $optgroup[$tmp[0]][$dict_key] = $tmp[1];
555 $other[$dict_key] = $dict_value;
557 echo "<select name=${select_name}>";
558 if (!count ($optgroup))
560 foreach ($other as $dict_key => $dict_value)
562 echo "<option value=${dict_key}";
563 if ($dict_key == $selected_id)
565 echo ">${dict_value}</option>";
570 foreach ($optgroup as $groupname => $groupdata)
572 echo "<optgroup label='${groupname}'>";
573 foreach ($groupdata as $dict_key => $dict_value)
575 echo "<option value=${dict_key}";
576 if ($dict_key == $selected_id)
578 echo ">${dict_value}</option>";
580 echo "</optgroup>\n";
584 echo "<optgroup label='other'>\n";
585 foreach ($other as $dict_key => $dict_value)
587 echo "<option value=${dict_key}";
588 if ($dict_key == $selected_id)
590 echo ">${dict_value}</option>";
592 echo "</optgroup>\n";
598 // used by renderGridForm() and renderRackPage()
599 function renderRackInfoPortlet ($rackData)
601 startPortlet ('summary');
602 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
603 echo "<tr><th width='50%' class=tdright>Rack row:</th><td class=tdleft>${rackData['row_name']}</td></tr>\n";
604 echo "<tr><th width='50%' class=tdright>Name:</th><td class=tdleft>${rackData['name']}</td></tr>\n";
605 echo "<tr><th width='50%' class=tdright>Height:</th><td class=tdleft>${rackData['height']}</td></tr>\n";
606 echo "<tr><th width='50%' class=tdright>Utilization:</th><td class=tdleft>";
607 renderProgressBar (getRSUforRack ($rackData));
609 echo "<tr><th width='50%' class=tdright>Objects:</th><td class=tdleft>";
610 echo getObjectCount ($rackData);
612 printTagTRs ("${root}?page=rackspace&");
613 if (!empty ($rackData['comment']))
614 echo "<tr><th width='50%' class=tdright>Comment:</th><td class=tdleft>${rackData['comment']}</td></tr>\n";
619 // This is a universal editor of rack design/waste.
620 function renderGridForm ($rack_id = 0, $filter, $header, $submit, $state1, $state2)
624 showError ('Invalid rack_id', __FUNCTION__
);
627 if (($rackData = getRackData ($rack_id)) == NULL)
629 showError ('getRackData() failed', __FUNCTION__
);
633 global $root, $pageno, $tabno;
635 markupObjectProblems ($rackData);
637 // Process form submit.
638 if (isset ($_REQUEST['do_update']))
640 $log[] = processGridForm ($rackData, $state1, $state2);
642 $rackData = getRackData ($rack_id);
644 markupObjectProblems ($rackData);
647 // Render the result whatever it is.
649 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
650 echo "<tr><td colspan=2 align=center><h1>${rackData['name']}</h1></td></tr>\n";
652 // Left column with information portlet.
653 echo "<tr><td class=pcleft height='1%' width='50%'>";
654 renderRackInfoPortlet ($rackData);
656 echo "<td class=pcright>";
659 startPortlet ($header);
661 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
662 echo "<tr><th width='10%'> </th><th width='20%'>Front</th>";
663 echo "<th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
664 echo "<form method=post action='${root}?'>\n";
665 echo "<input type=hidden name=page value=${pageno}>\n";
666 echo "<input type=hidden name=tab value=${tabno}>\n";
667 echo "<input type=hidden name=rack_id value=${rack_id}>\n";
668 markupAtomGrid ($rackData, $state2);
669 renderAtomGrid ($rackData);
670 echo "</table></center>\n";
671 echo "<br><input type=submit name=do_update value='${submit}'></form><br><br>\n";
673 echo "</td></tr></table>\n";
676 function renderRackDesign ($rack_id)
678 renderGridForm ($rack_id, 'applyRackDesignMask', 'Rack design', 'Set rack design', 'A', 'F');
681 function renderRackProblems ($rack_id = 0)
683 renderGridForm ($rack_id, 'applyRackProblemMask', 'Rack problems', 'Mark unusable atoms', 'F', 'U');
686 function startPortlet ($title = '')
688 echo "<div class=portlet><h2>${title}</h2>";
691 function finishPortlet ()
696 function printRefsOfType ($refs, $type, $eq)
700 foreach ($refs as $ref)
702 if ($eq($ref['type'], $type))
704 if ($gotone) echo ', ';
705 echo "<a href='${root}?page=object&object_id=${ref['object_id']}'>";
706 if (!empty ($ref['name']))
707 echo $ref['name'] . '@';
708 echo "${ref['object_name']}</a>";
714 function renderRackObject ($object_id = 0)
719 showError ('Invalid object_id', __FUNCTION__
);
722 $info = getObjectInfo ($object_id);
725 showError ('getObjectInfo() failed', __FUNCTION__
);
728 // Main layout starts.
729 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
730 echo "<tr><td colspan=2 align=center><h1>${info['dname']}</h1></td></tr>\n";
731 // left column with uknown number of portlets
732 echo "<tr><td class=pcleft>";
733 startPortlet ('Object information');
734 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
735 if (!empty ($info['name']))
736 echo "<tr><th width='50%' class=tdright>Common name:</th><td class=tdleft>${info['name']}</td></tr>\n";
737 elseif (in_array ($info['objtype_id'], explode (',', getConfigVar ('NAMEFUL_OBJTYPES'))))
738 echo "<tr><td colspan=2 class=msg_error>Common name is missing.</td></tr>\n";
739 echo "<tr><th width='50%' class=tdright>Object type:</th>";
740 echo "<td class=tdleft><a href='${root}?page=objgroup&group_id=${info['objtype_id']}'>${info['objtype_name']}</a></td></tr>\n";
741 if (!empty ($info['asset_no']))
742 echo "<tr><th width='50%' class=tdright>Asset tag:</th><td class=tdleft>${info['asset_no']}</td></tr>\n";
743 elseif (in_array ($info['objtype_id'], explode (',', getConfigVar ('REQUIRE_ASSET_TAG_FOR'))))
744 echo "<tr><td colspan=2 class=msg_error>Asset tag is missing.</td></tr>\n";
745 if (!empty ($info['label']))
746 echo "<tr><th width='50%' class=tdright>Visible label:</th><td class=tdleft>${info['label']}</td></tr>\n";
747 if (!empty ($info['barcode']))
748 echo "<tr><th width='50%' class=tdright>Barcode:</th><td class=tdleft>${info['barcode']}</td></tr>\n";
749 if ($info['has_problems'] == 'yes')
750 echo "<tr><td colspan=2 class=msg_error>Has problems</td></tr>\n";
751 foreach (getAttrValues ($object_id, TRUE) as $record)
752 if (!empty ($record['value']))
753 echo "<tr><th width='50%' class=opt_attr_th>${record['name']}:</th><td class=tdleft>${record['a_value']}</td></tr>\n";
754 printTagTRs ("${root}?page=objgroup&group_id=${info['objtype_id']}&");
755 echo "</table><br>\n";
758 if (!empty ($info['comment']))
760 startPortlet ('Comment');
761 echo '<div class=commentblock>' . string_insert_hrefs ($info['comment']) . '</div>';
765 $ports = getObjectPortsAndLinks ($object_id);
768 startPortlet ('Ports and links');
769 usort($ports, 'sortByName');
773 if (isset ($_REQUEST['hl_port_id']))
775 assertUIntArg ('hl_port_id', __FUNCTION__
);
776 $hl_port_id = $_REQUEST['hl_port_id'];
778 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
779 echo "<tr><th>Local name</th><th>Visible label</th><th>Port type</th><th>L2 address</th>";
780 echo "<th>Rem. Object</th><th>Rem. port</th></tr>\n";
781 foreach ($ports as $port)
784 if ($hl_port_id == $port['id'])
785 echo ' class=port_highlight';
786 echo "><td>${port['name']}</td><td>${port['label']}</td><td>${port['type']}</td>";
787 echo "<td>${port['l2address']}</td>";
788 if ($port['remote_object_id'])
790 echo "<td><a href='${root}?page=object&object_id=${port['remote_object_id']}'>${port['remote_object_name']}</a></td>";
791 echo "<td>${port['remote_name']}</td>";
793 elseif (!empty ($port['reservation_comment']))
795 echo "<td><b>Reserved;</b></td>";
796 echo "<td>${port['reservation_comment']}</td>";
799 echo '<td> </td><td> </td>';
802 echo "</table><br>\n";
806 $addresses = getObjectAddresses ($object_id);
807 usort($addresses, 'sortAddresses');
808 if (count ($addresses))
810 startPortlet ('IPv4 addresses');
811 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
812 echo "<tr><th>Interface name</th><th>IP Address</th><th>Description</th><th>Misc</th></tr>\n";
813 foreach ($addresses as $addr)
815 if (strlen($addr['address_name'])>40)
816 $address_name = substr($addr['address_name'],0,38).'...';
818 $address_name = $addr['address_name'];
820 $virtnum = countRefsOfType($addr['references'], 'virtual', 'eq');
821 $sharednum = countRefsOfType($addr['references'], 'shared', 'eq');
822 $regnum = countRefsOfType($addr['references'], 'regular', 'eq');
823 $notvirtnum = countRefsOfType($addr['references'], 'virtual', 'neq');
825 if ($addr['address_reserved']=='yes')
827 elseif ($addr['type']!='virtual' && $regnum>0)
829 elseif ($addr['type']=='regular' && $sharednum>0)
834 echo "<tr class='$class'><td class=tdleft>${addr['name']}</td><td class=tdleft><a href='${root}?page=ipaddress&ip=${addr['ip']}'>${addr['ip']}</a></td><td class='description'>$address_name</td><td class=tdleft>\n";
836 if ($addr['address_reserved']=='yes')
837 echo "<b>Reserved;</b> ";
839 if ($addr['type'] == 'virtual')
845 printRefsOfType($addr['references'], 'virtual', 'neq');
848 elseif ($addr['type'] == 'shared')
854 printRefsOfType($addr['references'], 'shared', 'eq');
860 printRefsOfType($addr['references'], 'virtual', 'eq');
865 echo " Collisions: ";
866 printRefsOfType($addr['references'], 'regular', 'eq');
875 printRefsOfType($addr['references'], 'virtual', 'eq');
880 echo " Collisions: ";
881 printRefsOfType($addr['references'], 'virtual', 'neq');
887 echo "</table><br>\n";
891 $forwards = getNATv4ForObject ($object_id);
892 if (count($forwards['in']) or count($forwards['out']))
894 startPortlet('NATv4');
896 if (count($forwards['out']))
899 echo "<h3>locally performed NAT</h3>";
901 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
902 echo "<tr><th>Proto</th><th>Match endpoint</th><th>Translate to</th><th>Target object</th><th>Rule comment</th></tr>\n";
904 foreach ($forwards['out'] as $pf)
908 foreach ($addresses as $addr)
909 if ($addr['ip'] == $pf['localip'])
916 echo "<tr class='$class'>";
918 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>";
920 echo "<td class=tdleft><a href='${root}?page=ipaddress&tab=default&ip=${pf['remoteip']}'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
922 $address=getIPAddress($pf['remoteip']);
924 echo "<td class='description'>";
925 if (count ($address['bonds']))
926 foreach($address['bonds'] as $bond)
927 echo "<a href='${root}?page=object&tab=default&object_id=${bond['object_id']}'>${bond['object_name']}(${bond['name']})</a> ";
928 elseif (!empty ($pf['remote_addr_name']))
929 echo '(' . $pf['remote_addr_name'] . ')';
931 echo "</td><td class='description'>${pf['description']}</td>";
935 echo "</table><br><br>";
937 if (count($forwards['in']))
939 echo "<h3>arriving NAT connections</h3>";
941 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
942 echo "<tr><th>Matched endpoint</th><th>Source object</th><th>Translated to</th><th>Rule comment</th></tr>\n";
944 foreach ($forwards['in'] as $pf)
947 echo "<td>${pf['proto']}/<a href='${root}?page=ipaddress&tab=default&ip=${pf['localip']}'>${pf['localip']}</a>:${pf['localport']}</td>";
949 echo "<td class='description'><a href='${root}?page=object&tab=default&object_id=${pf['object_id']}'>${pf['object_name']}</a>";
951 echo "</td><td><a href='${root}?page=ipaddress&tab=default&ip=${pf['remoteip']}'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
952 echo "<td class='description'>${pf['description']}</td></tr>";
955 echo "</table><br><br>";
960 $pools = getRSPoolsForObject ($object_id);
963 startPortlet ('Real server pools');
964 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
965 echo "<tr><th>VS</th><th>RS pool</th><th>RS</th><th>VS config</th><th>RS config</th></tr>\n";
966 foreach ($pools as $vs_id => $info)
968 echo "<tr valign=top><td class=tdleft><a href='${root}?page=vservice&id=${vs_id}'>";
969 echo buildVServiceName ($info);
971 if (!empty ($info['name']))
972 echo " (${info['name']})";
973 echo "</td><td class=tdleft><a href='${root}?page=rspool&pool_id=${info['pool_id']}'>";
974 echo (empty ($info['pool_name']) ?
'ANONYMOUS' : $info['pool_name']);
975 echo '</a></td><td class=tdleft>' . $info['rscount'] . '</td>';
976 echo "<td class=tdleft><pre>${info['vsconfig']}</pre></td>";
977 echo "<td class=tdleft><pre>${info['rsconfig']}</pre></td>";
985 // After left column we have (surprise!) right column with rackspace portled only.
986 echo "<td class=pcright>";
988 startPortlet ('Rackspace allocation');
989 // FIXME: now we call getRackData() twice
990 $racks = getResidentRacksData ($object_id);
991 foreach ($racks as $rackData)
992 renderRack ($rackData['id'], $object_id);
999 function renderRackMultiSelect ($sname, $racks, $selected)
1001 echo "<select name=${sname} multiple size=" . getConfigVar ('MAXSELSIZE') . " onchange='getElementById(\"racks\").submit()'>\n";
1002 foreach ($racks as $rack)
1004 echo "<option value=${rack['id']}";
1005 if (!(array_search ($rack['id'], $selected) === FALSE))
1007 echo">${rack['row_name']}: ${rack['name']}</option>\n";
1012 function showMessageOrError ()
1014 if (isset($_REQUEST['message']))
1015 echo "<div class=msg_success>${_REQUEST['message']}</div>";
1016 if (isset($_REQUEST['error']))
1017 echo "<div class=msg_error>${_REQUEST['error']}</div>";
1020 // This function renders a form for port edition.
1021 function renderPortsForObject ($object_id = 0)
1023 global $root, $pageno, $tabno;
1024 if ($object_id <= 0)
1026 showError ('Invalid object_id', __FUNCTION__
);
1029 showMessageOrError();
1030 startPortlet ('Ports and interfaces');
1031 $ports = getObjectPortsAndLinks ($object_id);
1032 usort($ports, 'sortByName');
1033 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
1034 echo "<tr><th> </th><th>Local name</th><th>Visible label</th><th>Port type</th><th>L2 address</th>";
1035 echo "<th>Rem. object</th><th>Rem. port</th><th>(Un)link or (un)reserve</th><th> </th></tr>\n";
1036 foreach ($ports as $port)
1038 echo "<form action='${root}process.php'>";
1039 echo "<input type=hidden name=op value=editPort>";
1040 echo "<input type=hidden name=page value='${pageno}'>\n";
1041 echo "<input type=hidden name=tab value='${tabno}'>\n";
1042 echo "<input type=hidden name=port_id value='${port['id']}'>";
1043 echo "<input type=hidden name=object_id value='$object_id'>\n";
1044 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']}'>";
1045 printImageHREF ('delete', 'Unlink and Delete this port');
1047 echo "<td><input type=text name=name value='${port['name']}' size=8></td>";
1048 echo "<td><input type=text name=label value='${port['label']}' size=24></td>";
1049 echo "<td>${port['type']}</td>\n";
1050 echo "<td><input type=text name=l2address value='${port['l2address']}'></td>\n";
1051 if ($port['remote_object_id'])
1053 echo "<td><a href='${root}?page=object&object_id=${port['remote_object_id']}'>${port['remote_object_name']}</a></td>";
1054 echo "<td>${port['remote_name']}</td>";
1055 echo "<td><a href='${root}process.php?op=unlinkPort&page=${pageno}&tab=${tabno}&port_id=${port['id']}&object_id=$object_id&port_name=";
1056 echo urlencode ($port['name']);
1057 echo "&remote_port_name=${port['remote_name']}&remote_object_name=${port['remote_object_name']}'>";
1058 printImageHREF ('unlink', 'Unlink this port');
1061 elseif (!empty ($port['reservation_comment']))
1063 echo "<td><b>Reserved;</b></td>";
1064 echo "<td><input type=text name=reservation_comment value='${port['reservation_comment']}'></td>";
1065 echo "<td><a href='${root}process.php?op=useup&page=${pageno}&tab=${tabno}&port_id=${port['id']}&object_id=${object_id}'>";
1066 printImageHREF ('useup', 'Use up this port');
1071 echo "<td> </td><td> </td>";
1073 echo "<a href='javascript:;' onclick='window.open(\"${root}link_helper.php?port=${port['id']}&type=${port['type_id']}&object_id=$object_id&port_name=";
1074 echo urlencode ($port['name']);
1075 echo "\",\"findlink\",\"height=700, width=400, location=no, menubar=no, resizable=yes, scrollbars=no, status=no, titlebar=no, toolbar=no\");'>";
1076 printImageHREF ('link', 'Link this port');
1077 echo "</a> <input type=text name=reservation_comment>";
1081 printImageHREF ('save', 'Save changes', TRUE);
1082 echo "</td></form></tr>\n";
1084 echo "<form action='${root}process.php'><tr><td>";
1085 printImageHREF ('add', '', TRUE, 104);
1086 echo "</td><td><input type=text size=8 name=port_name tabindex=100></td>\n";
1087 echo "<td><input type=text size=24 name=port_label tabindex=101></td>";
1088 echo "<input type=hidden name=op value=addPort>\n";
1089 echo "<input type=hidden name=object_id value='${object_id}'>\n";
1090 echo "<input type=hidden name=page value='${pageno}'>\n";
1091 echo "<input type=hidden name=tab value='${tabno}'>\n";
1092 echo "<td><select name='port_type_id' tabindex=102>\n";
1093 $types = getPortTypes();
1094 $default_port_type = getConfigVar ('default_port_type');
1095 foreach ($types as $typeid => $typename)
1097 echo "<option value='${typeid}'";
1098 if ($typeid == $default_port_type)
1100 echo ">${typename}</option>\n";
1102 echo "</select></td>";
1103 echo "<td><input type=text name=port_l2address tabindex=103></td>\n";
1104 echo "<td colspan=4> </td></tr></form>";
1105 echo "</table><br>\n";
1108 startPortlet ('Add/update multiple ports');
1109 echo "<form action=${root}process.php method=post>";
1110 echo "<input type=hidden name=page value='${pageno}'>\n";
1111 echo "<input type=hidden name=tab value='${tabno}'>\n";
1112 echo "<input type=hidden name=object_id value='${object_id}'>\n";
1113 echo "<input type=hidden name=op value=addMultiPorts>";
1114 echo 'Format: <select name=format>';
1115 echo '<option value=c2900 disabled>Cisco 2900 series: sh int eth</option>';
1116 echo '<option value=c3600eth disabled>Cisco 3600 ethernet: sh arp | inc -</option>';
1117 echo '<option value=c3600asy>Cisco 3600 async: sh line | inc TTY</option>';
1118 echo '<option value=fiwg selected>Foundry ServerIron/FastIron WorkGroup/Edge: sh int br</option>';
1119 echo '<option value=fiedge disabled>Foundry FastIron Edge: sh int br</option>';
1120 echo '<option value=fisxii>Foundry FastIron SuperX/II4000: sh int br</option>';
1121 echo '<option value=ssv1>SSV:<interface name> <MAC address></option>';
1123 echo 'Default port type: ';
1124 echo "<select name=port_type>\n";
1125 foreach ($types as $typeid => $typename)
1127 echo "<option value='${typeid}'";
1128 if ($typeid == $default_port_type)
1130 echo ">${typename}</option>\n";
1133 echo "<input type=submit value='Parse output'><br>\n";
1134 echo "<textarea name=input cols=100 rows=50></textarea><br>\n";
1139 function renderNetworkForObject ($object_id=0)
1141 global $root, $pageno, $tabno;
1142 if ($object_id <= 0)
1144 showError ('Invalid object_id', __FUNCTION__
);
1147 showMessageOrError();
1148 startPortlet ('Network Addresses');
1149 $addresses = getObjectAddresses ($object_id);
1150 usort($addresses, 'sortAddresses');
1151 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
1152 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";
1153 foreach ($addresses as $addr)
1155 if (strlen($addr['address_name'])>40)
1156 $address_name = substr($addr['address_name'],0,38).'...';
1158 $address_name = $addr['address_name'];
1160 $virtnum = countRefsOfType($addr['references'], 'virtual', 'eq');
1161 $sharednum = countRefsOfType($addr['references'], 'shared', 'eq');
1162 $regnum = countRefsOfType($addr['references'], 'regular', 'eq');
1163 $notvirtnum = countRefsOfType($addr['references'], 'virtual', 'neq');
1165 if ($addr['address_reserved']=='yes')
1167 elseif ($addr['type']!='virtual' && $regnum>0)
1169 elseif ($addr['type']=='regular' && $sharednum>0)
1174 echo "<form action='process.php'>";
1175 echo "<input type=hidden name=page value='${pageno}'>\n";
1176 echo "<input type=hidden name=tab value='${tabno}'>\n";
1177 echo "<input type=hidden name=op value=editAddressFromObject>";
1178 echo "<input type=hidden name=object_id value='$object_id'>";
1179 echo "<input type=hidden name=ip value='${addr['ip']}'>";
1180 echo "<tr class='$class'><td><a href='process.php?op=delAddrFObj&page=${pageno}&tab=${tabno}&ip=${addr['ip']}&object_id=$object_id'>";
1181 printImageHREF ('delete', 'Delete this IPv4 address');
1183 echo "<td class=tdleft><input type='text' name='bond_name' value='${addr['name']}' size=10></td>";
1184 echo "<td class=tdleft><a href='${root}?page=ipaddress&ip=${addr['ip']}'>${addr['ip']}</a></td>";
1185 echo "<td class='description'>$address_name</td>\n";
1186 echo "<td><select name='bond_type'>";
1187 foreach (array('regular'=>'Regular', 'virtual'=>'Virtual', 'shared'=>'Shared') as $n => $v)
1189 echo "<option value='$n'";
1190 if ($addr['type'] == $n)
1192 echo ">$v</option>";
1195 if ($addr['address_reserved']=='yes')
1196 echo "<b>Reserved</b>; ";
1198 if ($addr['type'] == 'virtual')
1200 if ($notvirtnum > 0)
1203 printRefsOfType($addr['references'], 'virtual', 'neq');
1206 elseif ($addr['type'] == 'shared')
1211 printRefsOfType($addr['references'], 'shared', 'eq');
1217 printRefsOfType($addr['references'], 'virtual', 'eq');
1222 echo " Collisions: ";
1223 printRefsOfType($addr['references'], 'regular', 'eq');
1232 printRefsOfType($addr['references'], 'virtual', 'eq');
1235 if ($notvirtnum > 0)
1237 echo " Collisions: ";
1238 printRefsOfType($addr['references'], 'virtual', 'neq');
1243 printImageHREF ('save', 'Save changes', TRUE);
1244 echo "</td></form></tr>\n";
1248 echo "<form action='${root}process.php'><tr><td>";
1249 printImageHREF ('add', 'Allocate new address', TRUE, 99);
1250 echo "</td><td class=tdleft>";
1251 echo "<input type='text' size='10' name='name' tabindex=100></td>\n";
1252 echo "<input type=hidden name=page value='${pageno}'>\n";
1253 echo "<input type=hidden name=tab value='${tabno}'>\n";
1254 echo "<input type=hidden name=op value=addAddrFObj>\n";
1255 echo "<input type=hidden name=object_id value='$object_id'>\n";
1256 echo "<td class=tdleft><input type=text name='ip' tabindex=101>\n";
1257 echo "</td><td> </td><td><select name='type' tabindex=102>";
1258 echo "<option value='regular'>Regular</option>";
1259 echo "<option value='virtual'>Virtual</option>";
1260 echo "<option value='shared'>Shared</option>";
1262 echo "</td><td colspan=2> </td></tr></form>";
1263 echo "</table><br>\n";
1268 function printLog ($log)
1270 foreach ($log as $record)
1271 echo "<div class=msg_${record['code']}>${record['message']}</div>";
1275 The following conditions must be followed:
1276 1. We can mount onto free atoms only. This means: if any record for an atom
1277 already exists in RackSpace, it can't be used for mounting.
1278 2. We can't unmount from 'W' atoms. Operator should review appropriate comments
1279 and either delete them before unmounting or refuse to unmount the object.
1282 // We extensively use $_REQUEST in the function.
1283 function renderRackSpaceForObject ($object_id = 0)
1285 if ($object_id <= 0)
1287 showError ('Invalid object_id', __FUNCTION__
);
1290 $is_submit = isset ($_REQUEST['got_atoms']);
1291 $is_update = isset ($_REQUEST['rackmulti'][0]);
1292 $info = getObjectInfo ($object_id);
1295 showError ('getObjectInfo() failed', __FUNCTION__
);
1298 // Always process occupied racks plus racks chosen by user. First get racks with
1299 // already allocated rackspace...
1300 $workingRacksData = getResidentRacksData ($object_id);
1301 if ($workingRacksData === NULL)
1303 print_r ($workingRacksData);
1304 showError ('getResidentRacksData() failed', __FUNCTION__
);
1308 // ...and then add those chosen by user (if any).
1310 foreach ($_REQUEST['rackmulti'] as $cand_id)
1312 if (!isset ($workingRacksData[$cand_id]))
1314 $rackData = getRackData ($cand_id);
1315 if ($rackData == NULL)
1317 showError ('getRackData() failed', __FUNCTION__
);
1320 $workingRacksData[$cand_id] = $rackData;
1324 // Do it only once...
1325 foreach ($workingRacksData as &$rackData)
1326 applyObjectMountMask ($rackData, $object_id);
1327 // Now we workaround an old caveat: http://bugs.php.net/bug.php?id=37410
1330 // Here we process form submit by trying to save all submitted info to database.
1333 $oldMolecule = getMoleculeForObject ($object_id);
1334 $worldchanged = FALSE;
1336 foreach ($workingRacksData as $rack_id => $rackData)
1338 $logrecord = processGridForm ($rackData, 'F', 'T', $object_id);
1339 $log[] = $logrecord;
1340 if ($logrecord['code'] != 300)
1342 $worldchanged = TRUE;
1343 // Reload our working copy after form processing.
1344 $rackData = getRackData ($rack_id);
1345 if ($rackData == NULL)
1346 $log[] = array ('code' => 500, 'message' => 'Working copy update failed in ', __FUNCTION__
);
1347 applyObjectMountMask ($rackData, $object_id);
1348 $workingRacksData[$rack_id] = $rackData;
1354 $newMolecule = getMoleculeForObject ($object_id);
1355 $oc = count ($oldMolecule);
1356 $nc = count ($newMolecule);
1357 $omid = $oc ?
createMolecule ($oldMolecule) : 'NULL';
1358 $nmid = $nc ?
createMolecule ($newMolecule) : 'NULL';
1359 global $remote_username;
1360 $comment = empty ($_REQUEST['comment']) ?
'NULL' : "'${_REQUEST['comment']}'";
1362 "insert into MountOperation(object_id, old_molecule_id, new_molecule_id, user_name, comment) " .
1363 "values (${object_id}, ${omid}, ${nmid}, '${remote_username}', ${comment})";
1365 $result = $dbxlink->query ($query);
1366 if ($result == NULL)
1367 $log[] = array ('code' => 'error', 'message' => 'SQL query failed during history logging.');
1369 $log[] = array ('code' => 'success', 'message' => 'History logged.');
1374 // This is the time for rendering.
1375 global $root, $pageno, $tabno;
1376 echo "<form id='racks' action='${root}'>";
1377 echo "<input type=hidden name=page value='${pageno}'>\n";
1378 echo "<input type=hidden name=tab value='${tabno}'>\n";
1379 echo "<input type=hidden name=object_id value='${object_id}'>\n";
1380 // Main layout starts.
1381 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0><tr>";
1383 // Left portlet with rack list.
1384 echo "<td class=pcleft height='1%'>";
1385 startPortlet ('Racks');
1386 $allRacksData = getRacksForRow();
1387 if (count ($allRacksData) <= getConfigVar ('RACK_PRESELECT_THRESHOLD'))
1389 foreach (array_keys ($allRacksData) as $rack_id)
1391 $rackData = getRackData ($rack_id);
1392 if ($rackData == NULL)
1394 showError ('getRackData() failed', __FUNCTION__
);
1397 $workingRacksData[$rack_id] = $rackData;
1399 foreach ($workingRacksData as &$rackData)
1400 applyObjectMountMask ($rackData, $object_id);
1403 renderRackMultiSelect ('rackmulti[]', $allRacksData, array_keys ($workingRacksData));
1409 // Middle portlet with comment and submit.
1410 echo "<td class=pcleft>";
1411 startPortlet ('Comment');
1412 echo "<textarea name=comment rows=10 cols=40></textarea><br>\n";
1413 echo "<input type=submit value='Save' name=got_atoms>\n";
1419 // Right portlet with rendered racks. If this form submit is not final, we have to
1420 // reflect the former state of the grid in current form.
1421 echo "<td class=pcright rowspan=2 height='1%'>";
1422 startPortlet ('Working copy');
1423 echo '<table border=0 cellspacing=10 align=center><tr>';
1424 foreach ($workingRacksData as $rack_id => $rackData)
1426 // Order is important here: only original allocation is highlighted.
1427 highlightObject ($rackData, $object_id);
1428 markupAtomGrid ($rackData, 'T');
1429 // If we have a form processed, discard user input and show new database
1431 if (!$is_submit and $is_update)
1432 mergeGridFormToRack ($rackData);
1433 echo "<td valign=top>";
1434 echo "<center>\n<h2>${rackData['name']}</h2>\n";
1435 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
1436 echo "<tr><th width='10%'> </th><th width='20%'>Front</th>";
1437 echo "<th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
1438 renderAtomGrid ($rackData);
1439 echo "<tr><th width='10%'> </th><th width='20%'>Front</th>";
1440 echo "<th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
1441 echo "</table></center>\n";
1444 echo "</tr></table>";
1449 echo "</tr></table>\n";
1452 function renderMolecule ($mdata, $object_id)
1455 $rackpack = array();
1457 foreach ($mdata as $dummy => $rua)
1459 $rack_id = $rua['rack_id'];
1460 $unit_no = $rua['unit_no'];
1461 $atom = $rua['atom'];
1462 if (!isset ($rackpack[$rack_id]))
1464 $rackData = getRackData ($rack_id);
1465 for ($i = $rackData['height']; $i > 0; $i--)
1466 for ($locidx = 0; $locidx < 3; $locidx++
)
1467 $rackData[$i][$locidx]['state'] = 'F';
1468 $rackpack[$rack_id] = $rackData;
1470 $rackpack[$rack_id][$unit_no][$loclist[$atom]]['state'] = 'T';
1471 $rackpack[$rack_id][$unit_no][$loclist[$atom]]['object_id'] = $object_id;
1473 // now we have some racks to render
1474 foreach ($rackpack as $dummy => $rackData)
1476 markAllSpans ($rackData);
1477 echo "<table class=molecule cellspacing=0>\n";
1478 echo "<caption>${rackData['name']}</caption>\n";
1479 echo "<tr><th width='10%'> </th><th width='20%'>Front</th><th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
1480 for ($i = $rackData['height']; $i > 0; $i--)
1482 echo "<tr><th>$i</th>";
1483 for ($locidx = 0; $locidx < 3; $locidx++
)
1485 $state = $rackData[$i][$locidx]['state'];
1486 echo "<td class=state_${state}> </td>\n";
1494 function renderUnmountedObjectsPortlet ()
1496 startPortlet ('Unmounted objects');
1497 $objs = getUnmountedObjects();
1500 showError ('getUnmountedObjects() failed', __FUNCTION__
);
1503 global $root, $nextorder;
1505 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1506 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset number</th><th>Barcode</th></tr>';
1507 foreach ($objs as $obj)
1509 echo "<tr class=row_${order}><td><a href='${root}?page=object&object_id=${obj['id']}'>${obj['dname']}</a></td>";
1510 echo "<td>${obj['label']}</td>";
1511 echo "<td>${obj['asset_no']}</td>";
1512 echo "<td>${obj['barcode']}</td></tr>";
1513 $order = $nextorder[$order];
1515 echo "</table><br>\n";
1519 function renderProblematicObjectsPortlet ()
1521 startPortlet ('Problematic objects');
1522 $objs = getProblematicObjects();
1525 showError ('getProblematicObjects() failed', __FUNCTION__
);
1528 global $root, $nextorder;
1530 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1531 echo '<tr><th>Type</th><th>Common name</th></tr>';
1532 foreach ($objs as $obj)
1534 echo "<tr class=row_${order}><td>${obj['objtype_name']}</td>";
1535 echo "<td><a href='${root}?page=object&object_id=${obj['id']}'>${obj['dname']}</a></tr>";
1536 $order = $nextorder[$order];
1538 echo "</table><br>\n";
1542 function renderObjectSpace ()
1544 global $root, $taglist, $tagtree;
1545 echo "<table border=0 class=objectview>\n";
1546 echo "<tr><td class=pcleft width='50%'>";
1547 startPortlet ('View all by type');
1548 $groupInfo = getObjectGroupInfo();
1549 if ($groupInfo === NULL)
1551 showError ('getObjectGroupInfo() failed', __FUNCTION__
);
1554 if (count ($groupInfo) == 0)
1555 echo "No objects exist in DB";
1558 echo '<div align=left><ul>';
1559 foreach ($groupInfo as $gi)
1560 echo "<li><a href='${root}?page=objgroup&group_id=${gi['id']}'>${gi['name']}</a> (${gi['count']})</li>";
1565 echo '</td><td class=pcright>';
1567 startPortlet ('View all by tag');
1568 if (count ($taglist) == 0)
1569 echo "No tags exist in DB";
1571 renderTagCloud ('object');
1573 echo "</td></tr></table>\n";
1576 function renderObjectGroup ()
1578 global $root, $pageno, $tabno, $nextorder, $taglist, $tagtree;
1579 assertUIntArg ('group_id', __FUNCTION__
, TRUE);
1580 $group_id = $_REQUEST['group_id'];
1581 $tagfilter = getTagFilter();
1582 $tagfilter_str = getTagFilterStr ($tagfilter);
1583 echo "<table border=0 class=objectview>\n";
1584 echo "<tr><td class=pcleft width='25%'>";
1585 startPortlet ('change type');
1586 $groupInfo = getObjectGroupInfo();
1587 if ($groupInfo === NULL)
1589 showError ('getObjectGroupInfo() failed', __FUNCTION__
);
1592 if (count ($groupInfo) == 0)
1593 echo "No objects exist in DB";
1596 echo '<div align=left><ul>';
1597 foreach ($groupInfo as $gi)
1599 echo "<li><a href='${root}?page=${pageno}&group_id=${gi['id']}${tagfilter_str}'>";
1600 if ($gi['id'] == $group_id)
1602 echo "${gi['name']}</a>";
1603 if ($gi['id'] == $group_id)
1605 echo " (${gi['count']})";
1606 if ($gi['id'] == $group_id)
1614 echo '</td><td class=pcleft>';
1616 startPortlet ('Objects');
1617 $objects = getObjectList ($group_id, $tagfilter);
1618 if ($objects === NULL)
1620 showError ('getObjectList() failed', __FUNCTION__
);
1623 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1624 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>Barcode</th><th>Rack</th></tr>';
1626 foreach ($objects as $obj)
1628 echo "<tr class=row_${order}><td><a href='${root}?page=object&object_id=${obj['id']}'>${obj['dname']}</a></td>";
1629 echo "<td>${obj['label']}</td>";
1630 echo "<td>${obj['asset_no']}</td>";
1631 echo "<td>${obj['barcode']}</td>";
1632 if ($obj['rack_id'])
1633 echo "<td><a href='${root}?page=rack&rack_id=${obj['rack_id']}'>${obj['Rack_name']}</a></td>";
1635 echo '<td>Unmounted</td>';
1637 $order = $nextorder[$order];
1642 echo "</td><td class=pcright width='25%'>";
1644 renderTagFilterPortlet ($tagfilter, 'object', 'group_id', $group_id);
1645 echo "</td></tr></table>\n";
1648 function renderEmptyPortsSelect ($port_id, $type_id)
1650 $ports = getEmptyPortsOfType($type_id);
1651 usort($ports, 'sortEmptyPorts');
1652 foreach ($ports as $port)
1654 if ($port_id == $port['Port_id'])
1656 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";
1660 function renderObjectAddressesAndNames ()
1662 $addresses = getObjectAddressesAndNames();
1663 usort($addresses, 'sortObjectAddressesAndNames');
1664 foreach ($addresses as $address)
1666 echo "<option value='${address['ip']}' onclick='getElementById(\"ip\").value=\"${address['ip']}\";'>${address['object_name']} ${address['name']} ${address['ip']}</option>\n";
1670 // History viewer for history-enabled simple dictionaries.
1671 function renderHistory ($object_type, $object_id)
1673 switch ($object_type)
1676 $query = "select ctime, user_name, name, deleted, comment from RackRowHistory where id = ${object_id} order by ctime";
1677 $header = '<tr><th>change time</th><th>author</th><th>rack row name</th><th>is deleted?</th><th>rack row comment</th></tr>';
1682 "select ctime, user_name, rh.name, rh.deleted, d.dict_value as name, rh.height, rh.comment " .
1683 "from RackHistory as rh left join Dictionary as d on rh.row_id = d.dict_key " .
1684 "natural join Chapter " .
1685 "where chapter_name = 'RackRow' and rh.id = ${object_id} order by ctime";
1686 $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>';
1691 "select ctime, user_name, name, label, barcode, asset_no, deleted, has_problems, dict_value, comment " .
1692 "from RackObjectHistory inner join Dictionary on objtype_id = dict_key natural join Chapter " .
1693 "where chapter_name = 'RackObjectType' and id=${object_id} order by ctime";
1694 $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>';
1698 showError ("Uknown object type '${object_type}'", __FUNCTION__
);
1702 $result = $dbxlink->query ($query);
1703 if ($result == NULL)
1705 showError ('SQL query failed', __FUNCTION__
);
1708 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1712 while ($row = $result->fetch (PDO
::FETCH_NUM
))
1714 echo "<tr class=row_${order}><td>${row[0]}</td>";
1715 for ($i = 1; $i <= $extra; $i++
)
1716 echo "<td>" . $row[$i] . "</td>";
1718 $order = $nextorder[$order];
1720 echo "</table><br>\n";
1723 function renderRackspaceHistory ()
1725 global $root, $nextorder, $pageno, $tabno;
1727 $history = getRackspaceHistory();
1728 // Show the last operation by default.
1729 if (isset ($_REQUEST['op_id']))
1730 $op_id = $_REQUEST['op_id'];
1731 elseif (isset ($history[0]['mo_id']))
1732 $op_id = $history[0]['mo_id'];
1739 list ($omid, $nmid) = getOperationMolecules ($op_id);
1741 // Main layout starts.
1742 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
1744 // Left top portlet with old allocation.
1745 echo "<tr><td class=pcleft>";
1746 startPortlet ('Old allocation');
1749 $oldMolecule = getMolecule ($omid);
1750 renderMolecule ($oldMolecule, $object_id);
1756 echo '</td><td class=pcright>';
1758 // Right top portlet with new allocation
1759 startPortlet ('New allocation');
1762 $newMolecule = getMolecule ($nmid);
1763 renderMolecule ($newMolecule, $object_id);
1769 echo '</td></tr><tr><td colspan=2>';
1771 // Bottom portlet with list
1773 startPortlet ('Rackspace allocation history');
1774 echo "<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>\n";
1775 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";
1776 foreach ($history as $row)
1778 if ($row['mo_id'] == $op_id)
1781 $class = "row_${order}";
1782 echo "<tr class=${class}><td><a href='${root}?page=${pageno}&tab=${tabno}&op_id=${row['mo_id']}'>${row['ctime']}</a></td>";
1783 echo "<td>${row['user_name']}</td>";
1784 echo "<td>${row['ro_id']}</td><td>${row['objtype_name']}</td><td>${row['name']}</td><td>${row['comment']}</td>\n";
1786 $order = $nextorder[$order];
1791 echo '</td></tr></table>';
1795 function renderAddressspace ()
1797 global $root, $page;
1799 echo "<table border=0 class=objectview>\n";
1800 echo "<tr><td class=pcleft>";
1802 startPortlet ('Subnets');
1803 echo "<table class='widetable' border=0 cellpadding=10 cellspacing=0 align='center'>\n";
1804 $tagfilter = getTagFilter();
1805 $addrspaceList = getAddressspaceList ($tagfilter);
1806 echo "<tr><th>Subnet</th><th>Name</th><th>Utilization</th></tr>";
1807 foreach ($addrspaceList as $iprange)
1809 $range = getIPRange ($iprange['id']);
1810 $total = ($iprange['ip_bin'] |
$iprange['mask_bin_inv']) - ($iprange['ip_bin'] & $iprange['mask_bin']) +
1;
1811 $used = count ($range['addrlist']);
1812 echo "<tr><td class=tdleft><a href='${root}?page=iprange&id=${iprange['id']}'>${iprange['ip']}/${iprange['mask']}</a></td>";
1813 echo "<td class=tdleft>${iprange['name']}</td><td class=tdleft>";
1814 renderProgressBar ($used/$total);
1815 echo " ${used}/${total}</td></tr>";
1819 echo '</td><td class=pcright>';
1820 renderTagFilterPortlet ($tagfilter, 'ipv4net');
1821 echo "</td></tr></table>\n";
1824 function renderIPv4SLB ()
1826 global $root, $page, $nextorder;
1828 startPortlet ('SLB configuration');
1829 echo "<table border=0 width='100%'><tr>";
1830 foreach (array ('vservices', 'rspools', 'rservers', 'lbs') as $pno)
1831 echo "<td><h3><a href='${root}?page=${pno}'>" . $page[$pno]['title'] . "</a></h3></td>";
1832 echo '</tr></table>';
1835 $summary = getSLBSummary();
1836 startPortlet ('SLB tactical overview');
1837 // A single id-keyed array isn't used here to preserve existing
1838 // order of LBs returned by getSLBSummary()
1841 foreach ($summary as $vipdata)
1842 foreach (array_keys ($vipdata['lblist']) as $lb_object_id)
1843 if (!in_array ($lb_object_id, $lblist))
1845 $oi = getObjectInfo ($lb_object_id);
1846 $lbdname[$lb_object_id] = $oi['dname'];
1847 $lblist[] = $lb_object_id;
1849 if (!count ($summary))
1850 echo 'none configured';
1854 echo "<table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
1855 echo "<tr><th>VS ↓ LB →</th>";
1856 foreach ($lblist as $lb_object_id)
1857 echo "<th><a href='${root}?page=object&tab=default&object_id=${lb_object_id}'>" . $lbdname[$lb_object_id] . "</a></th>";
1859 foreach ($summary as $vsid => $vsdata)
1861 echo "<tr class=row_${order}><td class=tdleft><a href='$root?page=vservice&tab=default&id=${vsid}'>";
1862 echo buildVServiceName ($vsdata);
1864 if (!empty ($vsdata['name']))
1865 echo " (${vsdata['name']})";
1867 foreach ($lblist as $lb_object_id)
1869 echo '<td class=tdleft>';
1870 if (!isset ($vsdata['lblist'][$lb_object_id]))
1874 echo $vsdata['lblist'][$lb_object_id]['size'];
1875 echo " (<a href='${root}?page=rspool&pool_id=";
1876 echo $vsdata['lblist'][$lb_object_id]['id'] . "'>";
1877 echo $vsdata['lblist'][$lb_object_id]['name'] . '</a>)';
1882 $order = $nextorder[$order];
1889 function renderAddNewRange ()
1891 global $root, $pageno, $tabno;
1892 showMessageOrError();
1894 startPortlet ("Add New");
1895 echo "<table class='widetable' border=0 cellpadding=10 align='center'>\n";
1896 echo "<tr><th>Address range</th><th>Name</th><th>connected network</th><th>assign tags</th><th> </th></tr>\n";
1897 echo "<form name='add_new_range' action='process.php'>\n";
1898 echo "<input type=hidden name=op value=addRange>\n";
1899 echo "<input type=hidden name=page value='${pageno}'>\n";
1900 echo "<input type=hidden name=tab value='${tabno}'>\n";
1901 echo "<tr valign=top><td class='tdcenter'><input type=text name='range' size=18 class='live-validate' tabindex=1></td>\n";
1902 echo "<td class='tdcenter'><input type=text name='name' size='20' tabindex=2></td>\n";
1903 echo "<td class='tdcenter'><input type=checkbox name='is_bcast' tabindex=3 checked></td>\n";
1907 echo "<td class='tdcenter'><input type=submit value='Add a new range' tabindex=4></td>\n";
1908 echo "</td></tr>\n";
1909 echo "</form></table><br><br>\n";
1912 startPortlet ("Manage Existing");
1913 echo "<table class='widetable' border=0 cellpadding=10 align='center'>\n";
1914 $addrspaceList = getAddressspaceList();
1915 echo "<tr><th> </th><th>Address range</th><th>Name</th><th>Utilization</th></tr>";
1916 foreach ($addrspaceList as $iprange)
1918 $range = getIPRange($iprange['id']);
1919 $usedips = count ($range['addrlist']);
1920 $totalips = ($iprange['ip_bin'] |
$iprange['mask_bin_inv']) - ($iprange['ip_bin'] & $iprange['mask_bin']) +
1;
1924 echo "<a href='process.php?op=delRange&page=${pageno}&tab=${tabno}&id=${iprange['id']}'>";
1925 printImageHREF ('delete', 'Delete this IP range');
1929 printImageHREF ('nodelete', 'There are IP addresses allocated or reserved');
1930 echo "</td>\n<td class=tdleft><a href='${root}?page=iprange&id=${iprange['id']}'>";
1931 echo "${iprange['ip']}/${iprange['mask']}</a></td><td class=tdleft>${iprange['name']}";
1932 echo "</td><td class=tdleft>";
1933 renderProgressBar ($usedips / $totalips);
1934 echo " ${usedips}/${totalips}";
1941 function renderIPRange ($id)
1943 global $root, $pageno, $tabno;
1944 $netmaskbylen = array
1946 32 => '255.255.255.255',
1947 31 => '255.255.255.254',
1948 30 => '255.255.255.252',
1949 29 => '255.255.255.248',
1950 28 => '255.255.255.240',
1951 27 => '255.255.255.224',
1952 26 => '255.255.255.192',
1953 25 => '255.255.255.128',
1954 24 => '255.255.255.0',
1955 23 => '255.255.254.0',
1956 22 => '255.255.252.0',
1957 21 => '255.255.248.0',
1958 20 => '255.255.240.0',
1959 19 => '255.255.224.0',
1960 18 => '255.255.192.0',
1961 17 => '255.255.128.0',
1962 16 => '255.255.0.0',
1963 15 => '255.254.0.0',
1964 14 => '255.252.0.0',
1965 13 => '255.248.0.0',
1966 12 => '255.240.0.0',
1967 11 => '255.224.0.0',
1968 10 => '255.192.0.0',
1979 $wildcardbylen = array
1996 17 => '0.0.127.255',
1998 15 => '0.1.255.255',
1999 14 => '0.3.255.255',
2000 13 => '0.7.255.255',
2001 12 => '0.15.255.255',
2002 11 => '0.31.255.255',
2003 10 => '0.63.255.255',
2004 9 => '0.127.255.255',
2005 8 => '0.255.255.255',
2006 7 => '1.255.255.255',
2007 6 => '3.255.255.255',
2008 5 => '7.255.255.255',
2009 4 => '15.255.255.255',
2010 3 => '31.255.255.255',
2011 2 => '63.255.255.255',
2012 1 => '127.255.255.255'
2014 $maxperpage = getConfigVar ('IPV4_ADDRS_PER_PAGE');
2015 if (isset($_REQUEST['pg']))
2016 $page = $_REQUEST['pg'];
2020 $range = getIPRange($id);
2021 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
2022 echo "<tr><td colspan=2 align=center><h1>${range['ip']}/${range['mask']}</h1><h2>${range['name']}</h2></td></tr>\n";
2024 echo "<tr><td class=pcleft width='50%'>";
2025 startPortlet ('summary');
2026 $total = ($range['ip_bin'] |
$range['mask_bin_inv']) - ($range['ip_bin'] & $range['mask_bin']) +
1;
2027 $used = count ($range['addrlist']);
2028 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
2029 echo "<tr><th width='50%' class=tdright>Utilization:</th><td class=tdleft>";
2030 renderProgressBar ($used/$total);
2031 echo " ${used}/${total}</td></tr>\n";
2032 echo "<tr><th width='50%' class=tdright>Netmask:</th><td class=tdleft>";
2033 echo $netmaskbylen[$range['mask']];
2034 echo "</td></tr>\n";
2035 echo "<tr><th width='50%' class=tdright>Wildcard bits:</th><td class=tdleft>";
2036 echo $wildcardbylen[$range['mask']];
2037 echo "</td></tr>\n";
2038 printTagTRs ("${root}?page=ipv4space&");
2039 echo "</table><br>\n";
2043 echo "<td class=pcright>";
2044 startPortlet ('details');
2045 $startip = $range['ip_bin'] & $range['mask_bin'];
2046 $endip = $range['ip_bin'] |
$range['mask_bin_inv'];
2047 $realstartip = $startip;
2048 $realendip = $endip;
2050 if($endip - $startip > $maxperpage)
2052 $numpages = ($endip - $startip)/$maxperpage;
2053 $startip = $startip +
$page * $maxperpage;
2054 $endip = $startip +
$maxperpage-1;
2058 echo '<h3>' . long2ip ($startip) . ' ~ ' . long2ip ($endip) . '</h3>';
2059 for ($i=0; $i<$numpages; $i++
)
2064 echo "<a href='${root}?page=${pageno}&tab=${tabno}&id=$id&pg=$i'>$i</a> ";
2068 echo "<table class='widetable' border=0 cellspacing=0 cellpadding=5 align='center'>\n";
2069 echo "<tr><th>Address</th><th>Name</th><th>Allocation</th></tr>\n";
2072 for($ip = $startip; $ip<=$endip; $ip++
)
2074 if (isset ($range['addrlist'][$ip]))
2076 $numshared = countRefsOfType($range['addrlist'][$ip]['references'], 'shared', 'eq');
2077 $numreg = countRefsOfType($range['addrlist'][$ip]['references'], 'regular', 'eq');
2078 $numvirt = countRefsOfType($range['addrlist'][$ip]['references'], 'virtual', 'eq');
2079 $numlb = count ($range['addrlist'][$ip]['lbrefs']);
2080 $numrs = count ($range['addrlist'][$ip]['rsrefs']);
2082 $addr = $range['addrlist'][$ip];
2083 if ( ($numshared > 0 && $numreg > 0) ||
$numreg > 1 )
2084 echo "<tr class='trerror'>";
2085 elseif ( $addr['reserved'] == 'yes' and $numshared+
$numreg+
$numvirt+
$numlb+
$numrs > 0)
2086 echo "<tr class='trerror'>";
2087 elseif ( $addr['reserved'] == 'yes')
2088 echo "<tr class='trbusy'>";
2089 elseif ( $numshared > 0 ||
$numreg > 0 ||
$numlb > 0 ||
$numrs > 0)
2090 echo "<tr class='trbusy'>";
2094 echo "<td class=tdleft><a href='${root}?page=ipaddress&ip=${addr['ip']}'>${addr['ip']}</a></td>";
2095 echo "<td class=tdleft>${addr['name']}</td><td class=tdleft>";
2098 if ( $addr['reserved'] == 'yes')
2100 echo "<b>Reserved</b> ";
2103 foreach ($range['addrlist'][$ip]['references'] as $ref)
2105 echo "${delim}<a href='${root}?page=object&object_id=${ref['object_id']}'>";
2106 echo $ref['name'] . (empty ($ref['name']) ?
'' : '@');
2107 echo "${ref['object_name']}</a>";
2115 foreach ($range['addrlist'][$ip]['lbrefs'] as $ref)
2119 echo "${delim}<a href='${root}?page=object&object_id=${ref['object_id']}'>";
2120 echo "${ref['object_name']}</a>:<a href='${root}?page=vservice&id=${ref['vs_id']}'>";
2121 echo "${ref['vport']}/${ref['proto']}</a>→";
2129 foreach ($range['addrlist'][$ip]['rsrefs'] as $ref)
2133 echo "${delim}→${ref['rsport']}@<a href='${root}?page=rspool&pool_id=${ref['rspool_id']}'>";
2134 echo "${ref['rspool_name']}</a>";
2137 echo "</td></tr>\n";
2141 echo "<tr><td><a href='${root}?page=ipaddress&ip=".long2ip($ip)."'>".long2ip($ip)."</a></td><td> </td><td> </td></tr>\n";
2147 echo "</td></tr></table>\n";
2150 function renderIPRangeProperties ($id)
2152 global $pageno, $tabno;
2153 showMessageOrError();
2154 $range = getIPRange($id);
2155 echo "<center><h1>${range['ip']}/${range['mask']}</h1></center>\n";
2156 echo "<table border=0 cellpadding=10 cellpadding=1 align='center'>\n";
2157 echo "<form action='process.php'><input type=hidden name=op value=editRange>";
2158 echo "<input type=hidden name=page value='${pageno}'>\n";
2159 echo "<input type=hidden name=tab value='${tabno}'>\n";
2160 echo "<input type=hidden name=id value='${id}'>";
2161 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>";
2166 function renderIPAddress ()
2169 $ip = $_REQUEST['ip'];
2170 $address = getIPAddress($ip);
2171 echo "<center><h1>$ip</h1>";
2172 if ($address['exists'] == 1)
2173 echo "<h2>${address['name']}</h2>";
2176 // echo "<table width='100%' cesspadding=5 cellspacing=0 border=0 align='center'>";
2177 // echo "<tr valign='top'><td>";
2179 $numshared = countRefsOfType($address['bonds'], 'shared', 'eq');
2180 $numreg = countRefsOfType($address['bonds'], 'regular', 'eq');
2181 $numvirt = countRefsOfType($address['bonds'], 'virtual', 'eq');
2183 if ($address['reserved'] == 'yes' or ($numshared +
$numreg +
$numvirt) > 0)
2185 startPortlet ('Allocation');
2186 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
2187 echo "<tr><th>Object name</th><th>Interface name</th><th>Interface type</th></tr>\n";
2188 if ( ($numshared > 0 && $numreg > 0) ||
$numreg > 1 )
2190 elseif ( $address['reserved'] == 'yes' and $numshared+
$numreg+
$numvirt > 0)
2195 if ($address['reserved'] == 'yes')
2196 echo "<tr class='$class'><td colspan='3'><b>RESERVED</b></td></tr>";
2197 foreach ($address['bonds'] as $bond)
2199 echo "<tr class='$class'><td><a href='${root}?page=object&object_id=${bond['object_id']}'>${bond['object_name']}</td><td>${bond['name']}</td><td><b>";
2200 switch ($bond['type'])
2212 echo "</b></td></tr>\n";
2214 echo "</table><br><br>";
2218 if (count ($address['vslist']))
2220 startPortlet ('Virtual services (' . count ($address['vslist']) . ')');
2221 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
2222 echo "<tr><th>VS</th><th>name</th></tr>\n";
2223 foreach ($address['vslist'] as $vsinfo)
2225 echo "<tr><td class=tdleft><a href='${root}?page=vservice&id=${vsinfo['id']}'>";
2226 echo buildVServiceName ($vsinfo) . "</a></td><td class=tdleft>";
2227 echo $vsinfo['name'] . "</td></tr>\n";
2229 echo "</table><br><br>";
2233 if (count ($address['rslist']))
2235 startPortlet ('Real servers (' . count ($address['rslist']) . ')');
2236 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
2237 echo "<tr><th> </th><th>port</th><th>RS pool</th></tr>\n";
2238 foreach ($address['rslist'] as $rsinfo)
2241 if ($rsinfo['inservice'] == 'yes')
2242 printImageHREF ('inservice', 'in service');
2244 printImageHREF ('notinservice', 'NOT in service');
2245 echo "</td><td class=tdleft>${rsinfo['rsport']}</td><td class=tdleft><a href='${root}?page=rspool&pool_id=${rsinfo['pool_id']}'>";
2246 echo $rsinfo['poolname'] . "</a></td></tr>\n";
2248 echo "</table><br><br>";
2253 // echo "</td><td>";
2254 // echo "</td></tr></table>";
2257 function renderIPAddressProperties ()
2259 global $pageno, $tabno;
2260 $ip = $_REQUEST['ip'];
2261 showMessageOrError();
2262 $address = getIPAddress($ip);
2263 echo "<center><h1>$ip</h1></center>\n";
2264 echo "<table border=0 cellpadding=10 cellpadding=1 align='center'>\n";
2265 echo "<form action='process.php'><input type=hidden name=op value=editAddress>";
2266 echo "<input type=hidden name=page value='${pageno}'>\n";
2267 echo "<input type=hidden name=tab value='${tabno}'>\n";
2268 echo "<input type=hidden name=ip value='${ip}'>";
2269 echo "<tr><td class='tdright'>Name:</td><td class='tdleft'><input type=text name=name size=20 value='".($address['exists']==1?
$address['name']:'')."'></tr>";
2270 echo "<td class='tdright'>Reserved:</td><td class='tdleft'><input type=checkbox name=reserved size=20 ".($address['exists']==1?
(($address['reserved']=='yes')?
'checked':''):'')."></tr>";
2271 echo "<tr><td colspan=2 class='tdcenter'><input type=submit value='Update address'></td></form></tr>";
2276 function renderIPAddressAssignment ()
2278 global $pageno, $tabno, $root;
2279 $ip = $_REQUEST['ip'];
2280 $address = getIPAddress($ip);
2282 showMessageOrError();
2283 echo "<center><h1>$ip</h1></center>\n";
2286 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
2287 echo "<tr><th> </th><th>Object name</th><th>Interface name</th><th>Interface type</th><th> </th></tr>\n";
2289 $numshared = countRefsOfType($address['bonds'], 'shared', 'eq');
2290 $numreg = countRefsOfType($address['bonds'], 'regular', 'eq');
2291 $numvirt = countRefsOfType($address['bonds'], 'virtual', 'eq');
2294 if ( ($numshared > 0 && $numreg > 0) ||
$numreg > 1 )
2296 elseif ( $address['reserved'] == 'yes' and $numshared+
$numreg+
$numvirt > 0)
2303 if ($address['reserved'] == 'yes')
2304 echo "<tr class='$class'><td colspan='5'><b>RESERVED</b></td></tr>";
2305 foreach ($address['bonds'] as $bond)
2307 echo "<tr class='$class'><form action='process.php'>";
2308 echo "<input type=hidden name=op value='editBondForAddress'>";
2309 echo "<input type=hidden name=page value='${pageno}'>";
2310 echo "<input type=hidden name=tab value='${tabno}'>";
2311 echo "<input type=hidden name=ip value='$ip'>";
2312 echo "<input type=hidden name=object_id value='${bond['object_id']}'>";
2313 echo "<td><a href='process.php?op=delIpAssignment&page=${pageno}&tab=${tabno}&ip=$ip&object_id=${bond['object_id']}'>";
2314 printImageHREF ('delete', 'Unallocate address');
2316 echo "<td><a href='${root}?page=object&object_id=${bond['object_id']}'>${bond['object_name']}</td>";
2317 echo "<td><input type='text' name='bond_name' value='${bond['name']}' size=10></td>";
2318 echo "<td><select name='bond_type'>";
2319 switch ($bond['type'])
2322 echo "<option value='regular'>Regular</option>";
2323 echo "<option value='virtual' selected>Virtual</option>";
2324 echo "<option value='shared'>Shared</option>";
2327 echo "<option value='regular'>Regular</option>";
2328 echo "<option value='virtual'>Virtual</option>";
2329 echo "<option value='shared' selected>Shared</option>";
2332 echo "<option value='regular' selected>Regular</option>";
2333 echo "<option value='virtual'>Virtual</option>";
2334 echo "<option value='shared'>Shared</option>";
2337 echo "</select></td><td><input type='submit' value='OK'></td></form></tr>\n";
2339 echo "<form action='process.php'><input type='hidden' name='op' value='bindObjectToIp'>";
2340 echo "<input type=hidden name=page value='${pageno}'>\n";
2341 echo "<input type=hidden name=tab value='${tabno}'>\n";
2342 echo "<input type='hidden' name='ip' value='$ip'>";
2343 echo "<td colspan=2><select name='object_id'>";
2345 foreach (explode (',', getConfigVar ('IPV4_PERFORMERS')) as $type)
2346 foreach (getObjectList ($type) as $object)
2347 echo "<option value='${object['id']}'>${object['dname']}</option>";
2349 echo "</select></td><td><input type='text' name='bond_name' value='' size=10></td>";
2350 echo "<td><select name='bond_type'><option value='regular'>Regular</option><option value='virtual'>Virtual</option><option value='shared'>Shared</option></select></td>";
2351 echo "<td><input type='submit' value='Assign address'></td></form></tr>";
2352 echo "</table><br><br>";
2356 function renderNATv4ForObject ($object_id = 0)
2358 global $pageno, $tabno, $root;
2360 $info = getObjectInfo ($object_id);
2361 $forwards = getNATv4ForObject ($object_id);
2362 $addresses = getObjectAddresses ($object_id);
2363 showMessageOrError();
2364 echo "<center><h2>locally performed NAT</h2></center>";
2366 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
2367 echo "<tr><th></th><th>Match endpoint</th><th>Translate to</th><th>Target object</th><th>Comment</th><th> </th></tr>\n";
2369 foreach ($forwards['out'] as $pf)
2373 foreach ($addresses as $addr)
2374 if ($addr['ip'] == $pf['localip'])
2377 $name = $addr['name'];
2381 echo "<tr class='$class'>";
2382 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}'>";
2383 printImageHREF ('delete', 'Delete NAT rule');
2385 echo "<td>${pf['proto']}/${name}: <a href='${root}?page=ipaddress&tab=default&ip=${pf['localip']}'>${pf['localip']}</a>:${pf['localport']}";
2386 if (!empty ($pf['local_addr_name']))
2387 echo ' (' . $pf['local_addr_name'] . ')';
2389 echo "<td><a href='${root}?page=ipaddress&tab=default&ip=${pf['remoteip']}'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
2391 $address=getIPAddress($pf['remoteip']);
2393 echo "<td class='description'>";
2394 if (count ($address['bonds']))
2395 foreach($address['bonds'] as $bond)
2396 echo "<a href='${root}?page=object&tab=default&object_id=${bond['object_id']}'>${bond['object_name']}(${bond['name']})</a> ";
2397 elseif (!empty ($pf['remote_addr_name']))
2398 echo '(' . $pf['remote_addr_name'] . ')';
2399 echo "</td><form action='process.php'><input type='hidden' name='op' value='updPortForwarding'><input type=hidden name=page value='${pageno}'>";
2400 echo "<input type=hidden name=tab value='${tabno}'><input type='hidden' name='object_id' value='$object_id'>";
2401 echo "<input type='hidden' name='localip' value='${pf['localip']}'><input type='hidden' name='localport' value='${pf['localport']}'>";
2402 echo "<input type='hidden' name='remoteip' value='${pf['remoteip']}'><input type='hidden' name='remoteport' value='${pf['remoteport']}'>";
2403 echo "<input type='hidden' name='proto' value='${pf['proto']}'><td class='description'>";
2404 echo "<input type='text' name='description' value='${pf['description']}'></td><td>";
2405 printImageHREF ('save', 'Save changes', TRUE);
2406 echo "</td></form></tr>";
2408 echo "<form action='process.php'><input type='hidden' name='op' value='forwardPorts'>";
2409 echo "<input type='hidden' name='object_id' value='$object_id'>";
2410 echo "<input type=hidden name=page value='${pageno}'>\n";
2411 echo "<input type=hidden name=tab value='${tabno}'>\n";
2412 echo "<tr align='center'><td>";
2413 printImageHREF ('add', 'Add new NAT rule', TRUE);
2415 printSelect (array ('TCP' => 'TCP', 'UDP' => 'UDP'), 'proto');
2416 echo "<select name='localip' tabindex=1>";
2418 foreach ($addresses as $addr)
2419 echo "<option value='${addr['ip']}'>" . (empty ($addr['name']) ?
'' : "${addr['name']}: ") .
2420 "${addr['ip']}" . (empty ($addr['address_name']) ?
'' : " (${addr['address_name']})") . "</option>";
2422 echo "</select>:<input type='text' name='localport' size='4' tabindex=2></td>";
2423 echo "<td><input type='text' name='remoteip' id='remoteip' size='10' tabindex=3>";
2424 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\");'>";
2425 printImageHREF ('find', 'Find object');
2427 echo ":<input type='text' name='remoteport' size='4' tabindex=4></td><td></td>";
2428 echo "<td colspan=1><input type='text' name='description' size='20' tabindex=5></td><td> </td></tr>";
2431 echo "</table><br><br>";
2433 echo "<center><h2>arriving NAT connections</h2></center>";
2434 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
2435 echo "<tr><th></th><th>Source</th><th>Source objects</th><th>Target</th><th>Description</th></tr>\n";
2437 foreach ($forwards['in'] as $pf)
2439 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}'>";
2440 printImageHREF ('delete', 'Delete NAT rule');
2442 echo "<td>${pf['proto']}/<a href='${root}?page=ipaddress&tab=default&ip=${pf['localip']}'>${pf['localip']}</a>:${pf['localport']}</td>";
2443 echo "<td class='description'><a href='${root}?page=object&tab=default&object_id=${pf['object_id']}'>${pf['object_name']}</a>";
2444 echo "</td><td><a href='${root}?page=ipaddress&tab=default&ip=${pf['remoteip']}'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
2445 echo "<td class='description'>${pf['description']}</td></tr>";
2448 echo "</table><br><br>";
2452 function renderAddMultipleObjectsForm ()
2454 global $root, $pageno, $tabno, $nextorder;
2457 $global_type_id = 0;
2459 $asset_no = array();
2460 $keepvalues = FALSE;
2462 // Look for current submit.
2463 if (isset ($_REQUEST['got_fast_data']))
2466 $max = getConfigVar ('MASSCOUNT');
2467 for ($i = 0; $i < $max; $i++
)
2469 if (!isset ($_REQUEST["${i}_object_type_id"]))
2471 $log[] = array ('code' => 'error', 'message' => "Submitted form is invalid at line " . $i +
1);
2474 assertUIntArg ("${i}_object_type_id", __FUNCTION__
, TRUE);
2475 assertStringArg ("${i}_object_name", __FUNCTION__
, TRUE);
2476 assertStringArg ("${i}_object_label", __FUNCTION__
, TRUE);
2477 assertStringArg ("${i}_object_asset_no", __FUNCTION__
, TRUE);
2478 assertStringArg ("${i}_object_barcode", __FUNCTION__
, TRUE);
2479 $type_id[$i] = $_REQUEST["${i}_object_type_id"];
2480 // Save user input for possible rendering.
2481 $name[$i] = $_REQUEST["${i}_object_name"];
2482 $label[$i] = $_REQUEST["${i}_object_label"];
2483 $asset_no[$i] = $_REQUEST["${i}_object_asset_no"];
2484 $barcode[$i] = $_REQUEST["${i}_object_barcode"];
2486 // It's better to skip silently than printing a notice.
2487 if ($type_id[$i] == 0)
2489 if (commitAddObject ($name[$i], $label[$i], $barcode[$i], $type_id[$i], $asset_no[$i]) === TRUE)
2490 $log[] = array ('code' => 'success', 'message' => "Added new object '${name[$i]}'");
2492 $log[] = array ('code' => 'error', 'message' => __FUNCTION__
. ': commitAddObject() failed');
2495 elseif (isset ($_REQUEST['got_very_fast_data']))
2498 assertUIntArg ('global_type_id', __FUNCTION__
, TRUE);
2499 assertStringArg ('namelist', __FUNCTION__
, TRUE);
2500 $global_type_id = $_REQUEST['global_type_id'];
2501 if ($global_type_id == 0)
2503 if (!empty ($_REQUEST['namelist']))
2504 $log[] = array ('code' => 'error', 'message' => 'Object type is not selected, check the form below');
2506 $log[] = array ('code' => 'error', 'message' => 'Empty form has been ignored. Cheers.');
2510 // The name extractor below was stolen from ophandlers.php:addMultiPorts()
2511 $names1 = explode ('\n', $_REQUEST['namelist']);
2513 foreach ($names1 as $line)
2515 $parts = explode ('\r', $line);
2517 if (empty ($parts[0]))
2520 $names2[] = rtrim ($parts[0]);
2522 foreach ($names2 as $cname)
2523 if (commitAddObject ($cname, '', '', $global_type_id, '') === TRUE)
2524 $log[] = array ('code' => 'success', 'message' => "Added new object '${cname}'");
2526 $log[] = array ('code' => 'error', 'message' => "Could not add '${cname}'");
2531 // Render a form for the next.
2532 $typelist = getObjectTypeList();
2533 $typelist[0] = 'select type...';
2535 startPortlet ('Fast way');
2536 echo "<form name=fastform method=post action='${root}?page=${pageno}&tab=${tabno}'>";
2537 echo '<table border=0 align=center>';
2538 echo "<tr><th>Object type</th><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>Barcode</th></tr>\n";
2539 // If a user forgot to select object type on input, we keep his
2540 // previous input in the form.
2541 $max = getConfigVar ('MASSCOUNT');
2542 for ($i = 0; $i < $max; $i++
)
2545 // Don't employ DEFAULT_OBJECT_TYPE to avoid creating ghost records for pre-selected empty rows.
2546 printSelect ($typelist, "${i}_object_type_id", 0);
2548 echo "<td><input type=text size=30 name=${i}_object_name";
2549 if ($keepvalues and $type_id[$i] == 0)
2550 echo " value='${name[$i]}'";
2552 echo "<td><input type=text size=30 name=${i}_object_label";
2553 if ($keepvalues and $type_id[$i] == 0)
2554 echo " value='${label[$i]}'";
2556 echo "<td><input type=text size=20 name=${i}_object_asset_no";
2557 if ($keepvalues and $type_id[$i] == 0)
2558 echo " value='${asset_no[$i]}'";
2560 echo "<td><input type=text size=10 name=${i}_object_barcode";
2561 if ($keepvalues and $type_id[$i] == 0)
2562 echo " value='${barcode[$i]}'";
2566 echo "<tr><td class=submit colspan=5><input type=submit name=got_fast_data value='Create'></td></tr>\n";
2567 echo "</form></table>\n";
2570 startPortlet ('Very fast way');
2571 echo "<form name=veryfastform method=post action='${root}?page=${pageno}&tab=${tabno}'>";
2572 echo 'For each line shown below create an object of type ';
2573 printSelect ($typelist, "global_type_id", getConfigVar ('DEFAULT_OBJECT_TYPE'));
2574 echo " <input type=submit name=got_very_fast_data value='Go!'><br>\n";
2575 echo "<textarea name=namelist cols=40 rows=25>\n";
2576 if ($keepvalues and $global_type_id == 0)
2577 echo $_REQUEST['namelist'];
2578 echo "</textarea></form>\n";
2582 function printGreeting ()
2584 global $remote_username, $accounts, $root;
2585 $account = $accounts[$remote_username];
2586 echo "Hello, ${account['user_realname']}. This is RackTables " . CODE_VERSION
. ". Click <a href='${root}?logout'>here</a> to logout.";
2589 function renderSearchResults ()
2591 global $remote_username, $root;
2592 $terms = trim ($_REQUEST['q']);
2595 showError ('Search string cannot be empty.', __FUNCTION__
);
2598 if (!authorized ($remote_username, 'object', 'default'))
2600 showError ('You are not authorized for viewing information about objects.', __FUNCTION__
);
2604 // If we search for L2 address, we can either find one or find none.
2607 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
2608 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
2609 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
2610 // STP bridge ID: bridge priotity + port MAC address. Cut off first 4 chars and look for MAC address.
2611 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)
2613 // Search for L2 address.
2615 $terms = substr ($terms, -12);
2616 $result = searchByl2address ($terms);
2617 if ($result !== NULL)
2621 $summary['port'][] = $result;
2624 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))
2625 // Search for IP address.
2627 $result = getRangeByIp ($terms);
2628 if ($result !== NULL)
2631 $lasthit = 'ipv4address1';
2632 $summary['ipv4address1'][] = $terms;
2636 // Search for objects, addresses, networks, virtual services and RS pools by their description.
2638 $tmp = getObjectSearchResults ($terms);
2641 $nhits +
= count ($tmp);
2642 $lasthit = 'object';
2643 $summary['object'] = $tmp;
2645 $tmp = getIPv4AddressSearchResult ($terms);
2648 $nhits +
= count ($tmp);
2649 $lasthit = 'ipv4address2';
2650 $summary['ipv4address2'] = $tmp;
2652 $tmp = getIPv4PrefixSearchResult ($terms);
2655 $nhits +
= count ($tmp);
2656 $lasthit = 'ipv4network';
2657 $summary['ipv4network'] = $tmp;
2659 $tmp = getIPv4RSPoolSearchResult ($terms);
2662 $nhits +
= count ($tmp);
2663 $lasthit = 'ipv4rspool';
2664 $summary['ipv4rspool'] = $tmp;
2666 $tmp = getIPv4VServiceSearchResult ($terms);
2669 $nhits +
= count ($tmp);
2670 $lasthit = 'ipv4vs';
2671 $summary['ipv4vs'] = $tmp;
2675 echo "<center><h2>Nothing found for '${terms}'</h2></center>";
2676 elseif ($nhits == 1)
2678 $record = current ($summary[$lasthit]);
2682 echo "<script language='Javascript'>document.location='${root}?page=object";
2683 echo "&hl_port_id=" . $record['port_id'];
2684 echo "&object_id=" . $record['object_id'] . "';//</script>";
2686 case 'ipv4address1':
2687 echo "<script language='Javascript'>document.location='${root}?page=ipaddress";
2688 echo "&ip=${record}";
2689 echo "';//</script>";
2691 case 'ipv4address2':
2692 echo "<script language='Javascript'>document.location='${root}?page=ipaddress";
2693 echo "&ip=${record}";
2694 echo "';//</script>";
2697 echo "<script language='Javascript'>document.location='${root}?page=iprange";
2698 echo "&id=${record['id']}";
2699 echo "';//</script>";
2702 echo "<script language='Javascript'>document.location='${root}?page=object&object_id=${record['id']}';//</script>";
2705 echo "<script language='Javascript'>document.location='${root}?page=rspool&pool_id=${record['pool_id']}';//</script>";
2708 echo "<script language='Javascript'>document.location='${root}?page=vservice&id=${record['id']}';//</script>";
2717 echo "<center><h2>${nhits} result(s) found for '${terms}'</h2></center>";
2718 foreach ($summary as $where => $what)
2722 startPortlet ('Objects');
2723 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
2724 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>barcode</th></tr>';
2725 foreach ($what as $obj)
2727 echo "<tr class=row_${order}><td><a href=\"${root}?page=object&object_id=${obj['id']}\">${obj['dname']}</a></td>";
2728 echo "<td>${obj['label']}</td>";
2729 echo "<td>${obj['asset_no']}</td>";
2730 echo "<td>${obj['barcode']}</td></tr>";
2731 $order = $nextorder[$order];
2737 startPortlet ('IPv4 networks');
2738 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
2739 echo '<tr><th>Network</th><th>Descritpion</th></tr>';
2740 foreach ($what as $net)
2742 echo "<tr class=row_${order}><td class=tdleft><a href='${root}?page=iprange&id=${net['id']}'>${net['ip']}";
2743 echo '/' . $net['mask'] . '</a></td>';
2744 echo "<td class=tdleft>${net['name']}</td></tr>";
2745 $order = $nextorder[$order];
2750 case 'ipv4address2':
2751 startPortlet ('IPv4 addresses');
2752 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
2753 echo '<tr><th>Address</th><th>Descritpion</th></tr>';
2754 foreach ($what as $addr)
2756 echo "<tr class=row_${order}><td class=tdleft><a href='${root}?page=ipaddress&ip=${addr['ip']}'>";
2757 echo "${addr['ip']}</a></td>";
2758 echo "<td class=tdleft>${addr['name']}</td></tr>";
2759 $order = $nextorder[$order];
2765 startPortlet ('RS pools');
2766 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
2767 foreach ($what as $rspool)
2769 echo "<tr class=row_${order}><td class=tdleft><a href='${root}?page=rspool&pool_id=${rspool['pool_id']}'>";
2770 echo buildRSPoolName ($rspool);
2771 echo "</a></td></tr>";
2772 $order = $nextorder[$order];
2778 startPortlet ('Virtual services');
2779 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
2780 echo '<tr><th>VS</th><th>Descritpion</th></tr>';
2781 foreach ($what as $vs)
2783 echo "<tr class=row_${order}><td class=tdleft><a href='${root}?page=vservice&id=${vs['id']}'>";
2784 echo buildVServiceName ($vs);
2785 echo "</a></td><td>${vs['name']}</td></tr>";
2786 $order = $nextorder[$order];
2795 // This function prints a table of checkboxes to aid the user in toggling mount atoms
2796 // from one state to another. The first argument is rack data as
2797 // produced by getRackData(), the second is the value used for the 'unckecked' state
2798 // and the third is the value used for 'checked' state.
2800 // for mounting an object: printAtomGrid ($data, 'F', 'T')
2801 // for changing rack design: printAtomGrid ($data, 'A', 'F')
2802 // for adding rack problem: printAtomGrid ($data, 'F', 'U')
2803 // for adding object problem: printAtomGrid ($data, 'T', 'W')
2805 function renderAtomGrid ($data)
2807 $rack_id = $data['id'];
2808 for ($unit_no = $data['height']; $unit_no > 0; $unit_no--)
2810 echo "<tr><th>${unit_no}</th>";
2811 for ($locidx = 0; $locidx < 3; $locidx++
)
2813 $state = $data[$unit_no][$locidx]['state'];
2814 echo "<td class=state_${state}";
2815 if (isset ($data[$unit_no][$locidx]['hl']))
2816 echo $data[$unit_no][$locidx]['hl'];
2818 if (!($data[$unit_no][$locidx]['enabled'] === TRUE))
2819 echo '<input type=checkbox disabled>';
2821 echo "<input type=checkbox" . $data[$unit_no][$locidx]['checked'] . " name=atom_${rack_id}_${unit_no}_${locidx}>";
2828 function renderPermissions ()
2830 startPortlet ('User permissions');
2831 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
2832 echo "<tr><th>Username</th><th>Page</th><th>Tab</th><th>Access</th></tr>";
2833 global $perms, $nextorder;
2835 foreach ($perms as $username => $pages)
2836 foreach ($pages as $page => $tabs)
2837 foreach ($tabs as $tab => $access)
2839 echo "<tr class=row_${order}><td class=tdleft>$username</td><td>$page</td><td>$tab</td><td>$access</td></tr>\n";
2840 $order = $nextorder[$order];
2846 function renderAccounts ()
2848 global $nextorder, $accounts;
2849 startPortlet ('User accounts');
2850 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
2851 echo "<tr><th class=tdleft>Username</th><th class=tdleft>Real name</th></tr>";
2853 foreach ($accounts as $user)
2855 echo "<tr class=row_${order}><td class=tdleft><div title='\$userid_${user['user_id']}'>";
2856 echo "${user['user_name']}</div></td>";
2857 echo "<td class=tdleft>${user['user_realname']}</td></li>";
2858 $order = $nextorder[$order];
2864 function renderAccountsEditForm ()
2866 global $root, $pageno, $tabno, $accounts;
2867 startPortlet ('User accounts');
2868 showMessageOrError();
2869 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
2870 echo "<tr><th>op</th><th>Username</th><th>Real name</th><th>Password</th><th> </th></tr>\n";
2871 foreach ($accounts as $account)
2873 echo "<form action='${root}process.php'>";
2874 echo "<input type=hidden name=op value=updateAccount>";
2875 echo "<input type=hidden name=page value='${pageno}'>\n";
2876 echo "<input type=hidden name=tab value='${tabno}'>\n";
2877 echo "<input type=hidden name=id value='${account['user_id']}'><tr>";
2879 if ($account['user_enabled'] == 'yes' && $account['user_id'] != 1)
2881 echo "<a href='${root}process.php?op=disableAccount&page=${pageno}&tab=${tabno}&id=${account['user_id']}'>";
2882 printImageHREF ('blockuser', 'disable account');
2885 if ($account['user_enabled'] == 'no' && $account['user_id'] != 1)
2887 echo "<a href='${root}process.php?op=enableAccount&page=${pageno}&tab=${tabno}&id=${account['user_id']}'>";
2888 printImageHREF ('unblockuser', 'enable account');
2891 // Otherwise skip icon.
2893 echo "<td><input type=text name=username value='${account['user_name']}' size=16></td>";
2894 echo "<td><input type=text name=realname value='${account['user_realname']}' size=24></td>";
2895 echo "<td><input type=password name=password value='${account['user_password_hash']}' size=64></td><td>";
2896 printImageHREF ('save', 'Save changes', TRUE);
2897 echo "</td></form></tr>\n";
2899 echo "<form action='${root}process.php' method=post><tr>";
2900 echo "<input type=hidden name=op value=createAccount>\n";
2901 echo "<input type=hidden name=page value='${pageno}'>\n";
2902 echo "<input type=hidden name=tab value='${tabno}'>\n";
2903 echo "<td> </td><td><input type=text size=16 name=username tabindex=100></td>\n";
2904 echo "<td><input type=text size=24 name=realname tabindex=101></td>";
2905 echo "<td><input type=password size=64 name=password tabindex=102></td><td>";
2906 printImageHREF ('create', 'Add new account', TRUE, 103);
2907 echo "</td></tr></form>";
2908 echo "</table><br>\n";
2912 function printChildrenAsOptions ($root, $depth = 0)
2914 echo "<option value=${root['title']}>";
2917 for ($i = 0; $i < $depth; $i++
)
2919 echo $root['title'];
2921 foreach ($root['kids'] as $kid)
2922 printChildrenAsOptions ($kid, $depth +
1);
2925 // 1. Find all parentless pages.
2926 // 2. For each of them recursively find all children.
2927 // 3. Output the tree with recursion tree display.
2928 function printPagesTree ()
2932 foreach ($page as $ctitle => $cpage)
2933 if (!isset ($cpage['parent']))
2935 $croot['title'] = $ctitle;
2936 $croot['kids'] = getAllChildPages ($ctitle);
2937 printChildrenAsOptions ($croot);
2942 function renderPermissionsEditForm ()
2944 global $root, $pageno, $tabno, $perms, $accounts;
2945 startPortlet ('User permissions');
2946 showMessageOrError();
2947 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
2948 echo "<tr><th> </th><th>Username</th><th>Page</th><th>Tab</th><th>Access</th></tr>\n";
2949 foreach ($perms as $username => $pages)
2950 foreach ($pages as $access_page => $tabs)
2951 foreach ($tabs as $access_tab => $access)
2954 if ($username != '%')
2955 $userid = $accounts[$username]['user_id'];
2958 echo "<a href='${root}process.php?op=revoke&page=${pageno}&tab=${tabno}&access_userid=${userid}&access_page=${access_page}&access_tab=${access_tab}'>";
2959 printImageHREF ('revoke', 'Revoke permission');
2961 echo "<td>${username}</td>";
2962 echo "<td>${access_page}</td>";
2963 echo "<td>${access_tab}</td>";
2964 echo "<td>${access}</td>";
2967 echo "<form action='${root}process.php' method=post><tr>";
2968 echo "<input type=hidden name=op value=grant>\n";
2969 echo "<input type=hidden name=page value='${pageno}'>\n";
2970 echo "<input type=hidden name=tab value='${tabno}'>\n";
2971 // FIXME: border=0 doesn't work here for unknown reason
2973 printImageHREF ('grant', '', TRUE, 103);
2975 echo "<td><select name=access_userid>";
2976 echo "<option value=0>ANY</option>";
2977 foreach ($accounts as $account)
2978 echo "<option value=${account['user_id']}>${account['user_name']}</option>";
2979 echo "</select></td>\n";
2980 echo "<td><select name=access_page>";
2981 echo "<option value='%'>ANY</option>";
2983 echo "</select></td>";
2984 echo "<td><input type=text size=16 name=access_tab tabindex=102 value=default></td>";
2985 echo "<td><input type=radio name=access_value value=no checked>no <input type=radio name=access_value value=yes>yes</td>";
2986 echo "</tr></form>";
2987 echo "</table><br>\n";
2991 function renderPortMapViewer ()
2993 renderPortMap (FALSE);
2996 function renderPortMapEditor ()
2998 renderPortMap (TRUE);
3001 function renderPortMap ($editable = FALSE)
3003 global $nextorder, $root, $pageno, $tabno;
3004 showMessageOrError();
3005 startPortlet ("Port compatibility map");
3006 $ptlist = getPortTypes();
3007 $pclist = getPortCompat();
3008 $pctable = buildPortCompatMatrixFromList ($ptlist, $pclist);
3011 echo "<form method=post action='${root}process.php'>";
3012 echo "<input type=hidden name=page value='${pageno}'>";
3013 echo "<input type=hidden name=tab value='${tabno}'>";
3014 echo "<input type=hidden name=op value=save>";
3016 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
3017 echo "<tr><th class=vert_th> </th>";
3018 foreach ($ptlist as $name2)
3019 echo "<th>to ${name2}</th>";
3021 // Make a copy to have an independent array pointer.
3024 foreach ($ptlistY as $type1 => $name1)
3026 echo "<tr class=row_${order}><th class=vert_th style='border-bottom: 0px;'>from $name1</th>";
3027 foreach ($ptlist as $type2 => $name2)
3029 echo '<td><input type=checkbox' . ($editable ?
" name=atom_${type1}_${type2}" : ' disabled');
3030 echo ($pctable[$type1][$type2] ?
' checked' : '') . '></td>';
3033 $order = $nextorder[$order];
3035 echo '</table><br>';
3038 echo "<input type=submit value='Save changes'>";
3044 function renderConfigMainpage ()
3046 global $pageno, $root;
3047 $children = getDirectChildPages ($pageno);
3049 // FIXME: assume all config kids to have static titles at the moment,
3050 // but use some proper abstract function later.
3051 foreach ($children as $cpageno => $child)
3052 echo "<li><a href='${root}?page=${cpageno}'>" . $child['title'] . "</li>\n";
3057 function renderRackPage ($rack_id)
3061 showError ('Invalid rack_id', __FUNCTION__
);
3064 if (($rackData = getRackData ($rack_id)) == NULL)
3066 showError ('getRackData() failed', __FUNCTION__
);
3069 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0><tr>";
3071 // Left column with information.
3072 echo "<td class=pcleft>";
3073 renderRackInfoPortlet ($rackData);
3076 // Right column with rendered rack.
3078 startPortlet ('Rack diagram');
3079 renderRack ($rack_id);
3083 echo '</tr></table>';
3086 function renderDictionary ()
3089 $dict = getDict (TRUE);
3090 echo "<br><table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
3091 foreach ($dict as $chapter_no => $chapter)
3094 echo "<tr><th>Chapter</th><th>refs</th><th>Word</th></tr>\n";
3095 $wc = count ($chapter['word']);
3096 echo "<tr class=row_${order}><td class=tdleft" . ($wc ?
" rowspan = ${wc}" : '');
3097 echo "><div title='number=${chapter_no}'>${chapter['name']} (${wc} records)</div></td>";
3099 echo "<td colspan=2>none</td>";
3103 foreach ($chapter['word'] as $key => $value)
3106 echo "<tr class=row_${order}>";
3108 $chap_start = FALSE;
3109 echo '<td>' . ($chapter['refcnt'][$key] ?
$chapter['refcnt'][$key] : ' ') . '</td>';
3110 echo "<td><div title='key=${key}'>${value}</div></td></tr>\n";
3111 $order = $nextorder[$order];
3115 echo "</table>\n<br>";
3118 function renderDictionaryEditor ()
3120 global $root, $pageno, $tabno, $nextorder;
3122 showMessageOrError();
3123 echo "<br><table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
3124 foreach ($dict as $chapter_no => $chapter)
3127 echo "<tr><th>Chapter</th><th> </th><th>Word</th><th> </th></tr>\n";
3128 $wc = count ($chapter['word']);
3129 // One extra span for the new record per each chapter block.
3130 echo "<tr class=row_${order}><td class=tdleft" . ($wc ?
' rowspan = ' . ($wc +
1) : '');
3131 echo "><div title='number=${chapter_no}'>${chapter['name']} (${wc} records)</div></td>";
3132 echo "<form action='${root}process.php' method=post>";
3133 echo "<input type=hidden name=page value='${pageno}'>";
3134 echo "<input type=hidden name=tab value='${tabno}'>";
3135 echo "<input type=hidden name=op value=add>";
3136 echo "<input type=hidden name=chapter_no value='${chapter['no']}'>";
3137 echo "<td> </td>";
3138 echo "<td class=tdright><input type=text name=dict_value size=32></td>";
3139 echo "<td><input type=submit value='Add new'></td>";
3140 echo '</tr></form>';
3141 $order = $nextorder[$order];
3142 foreach ($chapter['word'] as $key => $value)
3144 echo "<form action='${root}process.php' method=post>";
3145 echo "<input type=hidden name=page value='${pageno}'>";
3146 echo "<input type=hidden name=tab value='${tabno}'>";
3147 echo "<input type=hidden name=op value='upd'>";
3148 echo "<input type=hidden name=chapter_no value='${chapter['no']}'>";
3149 echo "<input type=hidden name=dict_key value='${key}'>";
3150 echo "<tr class=row_${order}><td>";
3151 // Prevent deleting words currently used somewhere.
3152 if ($chapter['refcnt'][$key])
3153 printImageHREF ('nodelete', 'referenced ' . $chapter['refcnt'][$key] . ' time(s)');
3156 echo "<a href='${root}process.php?page=${pageno}&tab=${tabno}&op=del&chapter_no=${chapter['no']}&dict_key=${key}'>";
3157 printImageHREF ('delete', 'Delete word');
3161 echo "<td class=tdright><input type=text name=dict_value size=32 value='${value}'></td>";
3162 echo "<td><input type=submit value=OK></td>";
3163 echo "</tr></form>\n";
3164 $order = $nextorder[$order];
3165 } // foreach ($chapter['word']
3170 // We don't allow to rename/delete a sticky chapter and we don't allow
3171 // to delete a non-empty chapter.
3172 function renderChaptersEditor ()
3174 global $root, $pageno, $tabno;
3175 showMessageOrError();
3177 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
3178 echo '<tr><th> </th><th>Chapter name</th><th>Words</th><th> </th></tr>';
3179 foreach ($dict as $chapter)
3181 $wordcount = count ($chapter['word']);
3182 $sticky = $chapter['sticky'];
3183 echo "<form action='${root}process.php' method=post>";
3184 echo "<input type=hidden name=page value='${pageno}'>";
3185 echo "<input type=hidden name=tab value='${tabno}'>";
3186 echo "<input type=hidden name=op value=upd>";
3187 echo "<input type=hidden name=chapter_no value='${chapter['no']}'>";
3191 printImageHREF ('nodelete', 'system chapter');
3192 elseif ($wordcount > 0)
3193 printImageHREF ('nodelete', 'contains ' . $wordcount . ' word(s)');
3196 echo "<a href='${root}process.php?page=${pageno}&tab=${tabno}&op=del&chapter_no=${chapter['no']}'>";
3197 printImageHREF ('delete', 'Remove chapter');
3201 echo "<td><input type=text name=chapter_name value='${chapter['name']}'" . ($sticky ?
' disabled' : '') . "></td>";
3202 echo "<td class=tdleft>${wordcount}</td><td>";
3206 echo "<input type=submit value='OK'>";
3210 echo "<form action='${root}process.php' method=post>";
3211 echo "<input type=hidden name=page value='${pageno}'>";
3212 echo "<input type=hidden name=tab value='${tabno}'>";
3213 echo "<input type=hidden name=op value=add>";
3215 printImageHREF ('add', '', TRUE);
3216 echo "</td><td colspan=3><input type=text name=chapter_name></td>";
3222 function renderAttributes ()
3225 $attrMap = getAttrMap();
3226 startPortlet ('Optional attributes');
3227 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
3228 echo "<tr><th class=tdleft>Attribute name</th><th class=tdleft>Attribute type</th><th class=tdleft>Applies to</th></tr>";
3230 foreach ($attrMap as $attr)
3232 echo "<tr class=row_${order}>";
3233 echo "<td class=tdleft>${attr['name']}</td>";
3234 echo "<td class=tdleft>${attr['type']}</td>";
3235 echo '<td class=tdleft>';
3236 if (count ($attr['application']) == 0)
3239 foreach ($attr['application'] as $app)
3240 if ($attr['type'] == 'dict')
3241 echo "${app['objtype_name']} (values from '${app['chapter_name']}')<br>";
3243 echo "${app['objtype_name']}<br>";