4 * This file contains frontend functions for RackTables.
8 // Interface function's special.
9 $nextorder['odd'] = 'even';
10 $nextorder['even'] = 'odd';
13 function renderIndex ()
17 <table border
=0 cellpadding
=0 cellspacing
=0 width
='100%'>
20 <div style
='text-align: center; margin: 10px; '>
21 <table width
='100%' cellspacing
=0 cellpadding
=30 class=mainmenu border
=0>
24 <h1
><a href
='<?php echo $root; ?>?page=rackspace'>Rackspace
<br
>
25 <?php
printImageHREF ('rackspace'); ?
></a
></h1
>
28 <h1
><a href
='<?php echo $root; ?>?page=objects'>Objects
<br
>
29 <?php
printImageHREF ('objects'); ?
></a
></h1
>
32 <h1
><a href
='<?php echo $root; ?>?page=ipv4space'>IPv4 space
<br
>
33 <?php
printImageHREF ('ipv4space'); ?
></a
></h1
>
37 <table width
='100%' cellspacing
=0 cellpadding
=30 class=mainmenu border
=0>
40 <h1
><a href
='<?php echo $root; ?>?page=config'>Configuration
<br
>
41 <?php
printImageHREF ('config'); ?
></a
></h1
>
44 <h1
><a href
='<?php echo $root; ?>?page=reports'>Reports
<br
>
45 <?php
printImageHREF ('reports'); ?
></a
></h1
>
48 <h1
><a href
='<?php echo $root; ?>?page=ipv4slb'>IPv4 SLB
<br
>
49 <?php
printImageHREF ('ipv4slb'); ?
></a
></h1
>
60 function renderRackspace ()
63 <table border
=0 cellpadding
=10 cellpadding
=1>
65 // generate thumb gallery
66 $rackrowList = getRackRowInfo();
67 global $root, $nextorder;
68 $rackwidth = getConfigVar ('rtwidth_0') +
getConfigVar ('rtwidth_1') +
getConfigVar ('rtwidth_2');
70 foreach ($rackrowList as $rackrow)
72 echo "<tr class=row_${order}><th><a href='${root}?page=row&row_id=${rackrow['dict_key']}'>${rackrow['dict_value']}</a></th>";
73 $rackList = getRacksForRow ($rackrow['dict_key']);
74 echo "<td><table border=0 cellspacing=5><tr>";
75 foreach ($rackList as $dummy => $rack)
77 echo "<td align=center><a href='${root}?page=rack&rack_id=${rack['id']}'>";
78 echo "<img border=0 width=${rackwidth} height=";
79 echo 3 +
3 +
$rack['height'] * 2;
80 echo " title='${rack['height']} units'";
81 echo "src='render_image.php?img=minirack&rack_id=${rack['id']}'>";
82 echo "<br>${rack['name']}</a></td>";
84 echo "</tr></table></tr>\n";
85 $order = $nextorder[$order];
90 function renderRow ($row_id)
94 showError ('Invalid row_id', __FUNCTION__
);
97 if (($rowInfo = getRackRowInfo ($row_id)) == NULL)
99 showError ('getRackRowInfo() failed', __FUNCTION__
);
102 $rackList = getRacksForRow ($row_id);
103 // Main layout starts.
104 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
106 // Left portlet with row information.
107 echo "<tr><td class=pcleft>";
108 startPortlet ($rowInfo['dict_value']);
109 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
110 echo "<tr><th width='50%' class=tdright>Racks:</th><td class=tdleft>${rowInfo['count']}</td></tr>\n";
111 echo "<tr><th width='50%' class=tdright>Units:</th><td class=tdleft>${rowInfo['sum']}</td></tr>\n";
112 echo "<tr><th width='50%' class=tdright>Utilization:</th><td class=tdleft>";
113 renderProgressBar (getRSUforRackRow ($rackList));
115 echo "</table><br>\n";
118 echo "</td><td class=pcright>";
120 global $root, $nextorder;
121 $rackwidth = getConfigVar ('rtwidth_0') +
getConfigVar ('rtwidth_1') +
getConfigVar ('rtwidth_2');
123 startPortlet ('Racks');
124 echo "<table border=0 cellspacing=5 align='center'><tr>";
125 foreach ($rackList as $dummy => $rack)
127 echo "<td align=center class=row_${order}><a href='${root}?page=rack&rack_id=${rack['id']}'>";
128 echo "<img border=0 width=" . $rackwidth * getConfigVar ('ROW_SCALE') . " height=";
129 echo (3 +
3 +
$rack['height'] * 2) * getConfigVar ('ROW_SCALE');
130 echo " title='${rack['height']} units'";
131 echo "src='render_image.php?img=minirack&rack_id=${rack['id']}'>";
132 echo "<br>${rack['name']}</a></td>";
133 $order = $nextorder[$order];
135 echo "</tr></table>\n";
138 echo "</td></tr></table>";
141 function showError ($info = '', $funcname = 'N/A')
144 echo "<div class=msg_error>An error has occured in function [${funcname}]. ";
146 echo 'No additional information is available.';
148 echo "Additional information:<br><p>\n<pre>\n${info}\n</pre></p>";
149 echo "Go back or try starting from <a href='${root}'>index page</a>.<br></div>\n";
152 // This function renders rack as HTML table.
153 function renderRack ($rack_id = 0, $hl_obj_id = 0)
157 showError ('Invalid rack_id', __FUNCTION__
);
160 if (($rackData = getRackData ($rack_id)) == NULL)
162 showError ('getRackData() failed', __FUNCTION__
);
165 global $root, $pageno, $tabno;
166 markAllSpans ($rackData);
168 highlightObject ($rackData, $hl_obj_id);
169 markupObjectProblems ($rackData);
170 $prev_id = getPrevIDforRack ($rackData['row_id'], $rack_id);
171 $next_id = getNextIDforRack ($rackData['row_id'], $rack_id);
172 echo "<center><table border=0><tr valign=middle>";
173 echo "<td><h2><a href='${root}?page=row&row_id=${rackData['row_id']}'>${rackData['row_name']}</a> :</h2></td>";
174 // FIXME: use 'bypass'?
175 if ($prev_id != NULL)
177 echo "<td><a href='${root}?page=rack&rack_id=${prev_id}'>";
178 printImageHREF ('prev', 'previous rack');
181 echo "<td><h2><a href='${root}?page=rack&rack_id=${rackData['id']}'>${rackData['name']}</a></h2></td>";
182 if ($next_id != NULL)
184 echo "<td><a href='${root}?page=rack&rack_id=${next_id}'>";
185 printImageHREF ('next', 'next rack');
188 echo "</h2></td></tr></table>\n";
189 if ($rackData['left_is_front'] == 'yes')
190 $markup = array ('left' => 'Front', 'right' => 'Back');
192 $markup = array ('left' => 'Back', 'right' => 'Front');
193 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
194 echo "<tr><th width='10%'> </th><th width='20%'>${markup['left']}</th>";
195 echo "<th width='50%'>Interior</th><th width='20%'>${markup['right']}</th></tr>\n";
196 for ($i = $rackData['height']; $i > 0; $i--)
198 echo '<tr><th>' . ($rackData['bottom_is_unit1'] == 'yes' ?
$i : $rackData['height'] - $i +
1) . '</th>';
199 for ($locidx = 0; $locidx < 3; $locidx++
)
201 if (isset ($rackData[$i][$locidx]['skipped']))
203 $state = $rackData[$i][$locidx]['state'];
204 echo "<td class=state_${state}";
205 if (isset ($rackData[$i][$locidx]['hl']))
206 echo $rackData[$i][$locidx]['hl'];
207 if (isset ($rackData[$i][$locidx]['colspan']))
208 echo ' colspan=' . $rackData[$i][$locidx]['colspan'];
209 if (isset ($rackData[$i][$locidx]['rowspan']))
210 echo ' rowspan=' . $rackData[$i][$locidx]['rowspan'];
215 $objectData = getObjectInfo ($rackData[$i][$locidx]['object_id']);
216 if (!empty ($objectData['asset_no']))
217 $prefix = "<div title='${objectData['asset_no']}";
219 $prefix = "<div title='no asset tag";
220 // Don't tell about label, if it matches common name.
221 if ($objectData['name'] != $objectData['label'] and !empty ($objectData['label']))
222 $suffix = ", visible label is \"${objectData['label']}\"'>";
225 echo $prefix . $suffix;
226 echo "<a href='${root}?page=object&object_id=${objectData['id']}'>${objectData['dname']}</a></div>";
229 echo '<div title="This rackspace does not exist"> </div>';
232 echo '<div title="Free rackspace"> </div>';
235 echo '<div title="Problematic rackspace, you CAN\'T mount here"> </div>';
238 echo '<div title="No data"> </div>';
245 echo "</table></center>\n";
248 function renderNewObjectForm ()
250 global $pageno, $tabno;
252 // Look for current submit.
253 if (isset ($_REQUEST['got_data']))
256 assertUIntArg ('object_type_id', __FUNCTION__
);
257 assertStringArg ('object_name', __FUNCTION__
, TRUE);
258 assertStringArg ('object_label', __FUNCTION__
, TRUE);
259 assertStringArg ('object_barcode', __FUNCTION__
, TRUE);
260 assertStringArg ('object_asset_no', __FUNCTION__
, TRUE);
261 $type_id = $_REQUEST['object_type_id'];
262 $name = $_REQUEST['object_name'];
263 $label = $_REQUEST['object_label'];
264 $asset_no = $_REQUEST['object_asset_no'];
265 $barcode = $_REQUEST['object_barcode'];
267 if (commitAddObject ($name, $label, $barcode, $type_id, $asset_no) === TRUE)
268 $log[] = array ('code' => 'success', 'message' => "Added new object '${name}'");
270 $log[] = array ('code' => 'error', 'message' => __FUNCTION__
. ': commitAddObject() failed');
274 // Render a form for the next.
275 startPortlet ('Object attributes');
277 echo "<input type=hidden name=page value=${pageno}>";
278 echo "<input type=hidden name=tab value=${tabno}>";
279 echo '<table border=0 align=center>';
280 echo "<tr><th class=tdright>Type:</th><td class=tdleft>";
281 $typelist = getObjectTypeList();
282 $typelist[0] = 'select type...';
283 printSelect ($typelist, 'object_type_id', getConfigVar ('DEFAULT_OBJECT_TYPE'));
285 echo "<tr><th class=tdright>Common name:</th><td class=tdleft><input type=text name=object_name></td></tr>\n";
286 echo "<tr><th class=tdright>Visible label:</th><td class=tdleft><input type=text name=object_label></td></tr>\n";
287 echo "<tr><th class=tdright>Asset tag:</th><td class=tdleft><input type=text name=object_asset_no></td></tr>\n";
288 echo "<tr><th class=tdright>Barcode:</th><td class=tdleft><input type=text name=object_barcode></td></tr>\n";
289 echo "<tr><td class=submit colspan=2><input type=submit name=got_data value='Create'></td></tr>\n";
290 echo '</form></table>';
294 function renderNewRackForm ($row_id)
296 global $pageno, $tabno;
298 // Look for current submit.
299 if (isset ($_REQUEST['got_data']))
302 assertStringArg ('rack_name', __FUNCTION__
);
303 assertUIntArg ('rack_height', __FUNCTION__
);
304 assertStringArg ('rack_comment', __FUNCTION__
, TRUE);
305 $name = $_REQUEST['rack_name'];
306 $height = $_REQUEST['rack_height'];
307 $comment = $_REQUEST['rack_comment'];
309 if (commitAddRack ($name, $height, $row_id, $comment) === TRUE)
310 $log[] = array ('code' => 'success', 'message' => "Added new rack '${name}'");
312 $log[] = array ('code' => 'error', 'message' => __FUNCTION__
. 'commitAddRack() failed');
316 // Render a form for the next.
317 startPortlet ('Rack attributes');
319 echo "<input type=hidden name=page value=${pageno}>";
320 echo "<input type=hidden name=tab value=${tabno}>";
321 echo "<input type=hidden name=row_id value=${row_id}>";
322 echo '<table border=0 align=center>';
323 $defh = getConfigVar ('DEFAULT_RACK_HEIGHT');
326 echo "<tr><th class=tdright>Name (required):</th><td class=tdleft><input type=text name=rack_name tabindex=1></td></tr>\n";
327 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";
328 echo "<tr><th class=tdright>Comment:</th><td class=tdleft><input type=text name=rack_comment tabindex=3></td></tr>\n";
329 echo "<tr><td class=submit colspan=2><input type=submit name=got_data value='Create'></td></tr>\n";
330 echo '</form></table>';
334 function renderEditObjectForm ($object_id)
336 showMessageOrError();
338 if (isset ($_REQUEST['got_data']))
341 // object_id is already verified by page handler
342 assertUIntArg ('object_type_id', __FUNCTION__
);
343 assertStringArg ('object_name', __FUNCTION__
, TRUE);
344 assertStringArg ('object_label', __FUNCTION__
, TRUE);
345 assertStringArg ('object_barcode', __FUNCTION__
, TRUE);
346 assertStringArg ('object_asset_no', __FUNCTION__
, TRUE);
347 $type_id = $_REQUEST['object_type_id'];
348 if (isset ($_REQUEST['object_has_problems']) and $_REQUEST['object_has_problems'] == 'on')
349 $has_problems = 'yes';
351 $has_problems = 'no';
352 $name = $_REQUEST['object_name'];
353 $label = $_REQUEST['object_label'];
354 $barcode = $_REQUEST['object_barcode'];
355 $asset_no = $_REQUEST['object_asset_no'];
356 $comment = $_REQUEST['object_comment'];
358 if (commitUpdateObject ($object_id, $name, $label, $barcode, $type_id, $has_problems, $asset_no, $comment) === TRUE)
359 $log[] = array ('code' => 'success', 'message' => "Updated object '${name}'");
361 $log[] = array ('code' => 'error', 'message' => __FUNCTION__
. ': commitUpdateObject() failed');
362 // Invalidate thumb cache of all racks objects could occupy.
363 foreach (getResidentRacksData ($object_id, FALSE) as $rack_id)
364 resetThumbCache ($rack_id);
368 global $pageno, $tabno;
369 $object = getObjectInfo ($object_id);
372 showError ('getObjectInfo() failed', __FUNCTION__
);
376 // Render a form for the next submit;
377 echo '<table border=0 width=100%><tr>';
379 echo '<td class=pcleft>';
380 startPortlet ('Static attributes');
381 echo '<form method=post>';
382 echo "<input type=hidden name=page value=${pageno}>";
383 echo "<input type=hidden name=tab value=${tabno}>";
384 echo "<input type=hidden name=object_id value=${object_id}>";
385 echo '<table border=0 align=center>';
386 echo "<tr><th class=tdright>Type:</th><td class=tdleft>";
387 printSelect (getObjectTypeList(), 'object_type_id', $object['objtype_id']);
389 // Common attributes.
390 echo "<tr><th class=tdright>Common name:</th><td class=tdleft><input type=text name=object_name value='${object['name']}'></td></tr>\n";
391 echo "<tr><th class=tdright>Visible label:</th><td class=tdleft><input type=text name=object_label value='${object['label']}'></td></tr>\n";
392 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";
393 echo "<tr><th class=tdright>Barcode:</th><td class=tdleft><input type=text name=object_barcode value='${object['barcode']}'></td></tr>\n";
394 echo "<tr><th class=tdright>Has problems:</th><td class=tdleft><input type=checkbox name=object_has_problems";
395 if ($object['has_problems'] == 'yes')
397 echo "></td></tr>\n";
398 echo "<tr><td colspan=2><b>Comment:</b><br><textarea name=object_comment rows=10 cols=80>${object['comment']}</textarea></td></tr>";
399 echo "<tr><th class=submit colspan=2><input type=submit name=got_data value='Update'></td></tr>\n";
400 echo '</form></table><br>';
404 // Optional attributes.
405 echo '<td class=pcright>';
406 startPortlet ('Optional attributes');
407 $values = getAttrValues ($object_id);
409 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
410 echo "<tr><th> </th><th>Attribute</th><th>Value</th><th> </th></tr>\n";
411 echo "<form method=post action='${root}process.php'>\n";
412 echo "<input type=hidden name=page value=${pageno}>\n";
413 echo "<input type=hidden name=tab value=${tabno}>\n";
414 echo "<input type=hidden name=op value=upd>\n";
415 echo "<input type=hidden name=object_id value=${object_id}>\n";
416 echo '<input type=hidden name=num_attrs value=' . count($values) . ">\n";
419 foreach ($values as $record)
421 echo "<input type=hidden name=${i}_attr_id value=${record['id']}>";
423 if (!empty ($record['value']))
425 echo "<a href=${root}process.php?page=${pageno}&tab=${tabno}&op=del&object_id=${object_id}&attr_id=${record['id']}>";
426 printImageHREF ('clear', 'Clear value');
432 echo "<td class=tdright>${record['name']}:</td><td class=tdleft>";
433 switch ($record['type'])
438 echo "<input type=text name=${i}_value value='${record['value']}'>";
441 $chapter = readChapter ($record['chapter_name']);
442 $chapter[0] = '-- NOT SET --';
443 printSelect ($chapter, "${i}_value", $record['key']);
449 echo "<tr><td colspan=3><input type=submit value='Update'></td></tr>\n";
457 echo '<td colspan=2>';
458 startPortlet ('history');
459 renderHistory ($pageno, $object_id);
463 echo '</tr></table>';
466 // This is a clone of renderEditObjectForm().
467 function renderEditRackForm ($rack_id)
470 if (isset ($_REQUEST['got_data']))
473 assertUIntArg ('rack_row_id', __FUNCTION__
);
474 assertUIntArg ('rack_height', __FUNCTION__
);
475 assertStringArg ('rack_name', __FUNCTION__
);
476 assertStringArg ('rack_comment', __FUNCTION__
, TRUE);
477 $row_id = $_REQUEST['rack_row_id'];
478 $height = $_REQUEST['rack_height'];
479 $name = $_REQUEST['rack_name'];
480 $comment = $_REQUEST['rack_comment'];
482 if (commitUpdateRack ($rack_id, $name, $height, $row_id, $comment) === TRUE)
483 $log[] = array ('code' => 'success', 'message' => "Updated rack '${name}'");
485 $log[] = array ('code' => 'error', 'message' => __FUNCTION__
. ': commitUpdateRack() failed');
486 resetThumbCache ($rack_id);
490 global $pageno, $tabno;
491 $rack = getRackData ($rack_id);
494 showError ('getRackData() failed', __FUNCTION__
);
498 // Render a form for the next.
499 startPortlet ('Rack attributes');
501 echo "<input type=hidden name=page value=${pageno}>";
502 echo "<input type=hidden name=tab value=${tabno}>";
503 echo "<input type=hidden name=rack_id value=${rack_id}>";
504 echo '<table border=0 align=center>';
505 echo "<tr><th class=tdright>Rack row:</th><td class=tdleft>";
506 printSelect (readChapter ('RackRow'), 'rack_row_id', $rack['row_id']);
508 echo "<tr><th class=tdright>Name (required):</th><td class=tdleft><input type=text name=rack_name value='${rack['name']}'></td></tr>\n";
509 echo "<tr><th class=tdright>Height (required):</th><td class=tdleft><input type=text name=rack_height value='${rack['height']}'></td></tr>\n";
510 echo "<tr><th class=tdright>Comment:</th><td class=tdleft><input type=text name=rack_comment value='${rack['comment']}'></td></tr>\n";
511 echo "<tr><td class=submit colspan=2><input type=submit name=got_data value='Update'></td></tr>\n";
512 echo '</form></table><br>';
515 startPortlet ('History');
516 renderHistory ($pageno, $rack_id);
520 // This is a helper for creators and editors.
521 function printSelect ($rowList, $select_name, $selected_id = 1)
523 // First collect all data for OPTGROUPs, then ouput it and dump
524 // the rest of records as is.
527 foreach ($rowList as $dict_key => $dict_value)
529 if (strpos ($dict_value, '^') !== FALSE)
531 $tmp = explode ('^', $dict_value, 2);
532 $optgroup[$tmp[0]][$dict_key] = $tmp[1];
534 elseif (strpos ($dict_value, '&') !== FALSE)
536 $tmp = explode ('&', $dict_value, 2);
537 $optgroup[$tmp[0]][$dict_key] = $tmp[1];
540 $other[$dict_key] = $dict_value;
542 echo "<select name=${select_name}>";
543 if (!count ($optgroup))
545 foreach ($other as $dict_key => $dict_value)
547 echo "<option value=${dict_key}";
548 if ($dict_key == $selected_id)
550 echo ">${dict_value}</option>";
555 foreach ($optgroup as $groupname => $groupdata)
557 echo "<optgroup label='${groupname}'>";
558 foreach ($groupdata as $dict_key => $dict_value)
560 echo "<option value=${dict_key}";
561 if ($dict_key == $selected_id)
563 echo ">${dict_value}</option>";
565 echo "</optgroup>\n";
569 echo "<optgroup label='other'>\n";
570 foreach ($other as $dict_key => $dict_value)
572 echo "<option value=${dict_key}";
573 if ($dict_key == $selected_id)
575 echo ">${dict_value}</option>";
577 echo "</optgroup>\n";
583 // This is a universal editor of rack design/waste.
584 function renderGridForm ($rack_id = 0, $filter, $header, $submit, $state1, $state2)
588 showError ('Invalid rack_id', __FUNCTION__
);
591 if (($rackData = getRackData ($rack_id)) == NULL)
593 showError ('getRackData() failed', __FUNCTION__
);
597 global $root, $pageno, $tabno;
599 markupObjectProblems ($rackData);
601 // Process form submit.
602 if (isset ($_REQUEST['do_update']))
604 $log[] = processGridForm ($rackData, $state1, $state2);
608 // Render the result whatever it is.
610 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
611 echo "<tr><td colspan=2 align=center><h1>${rackData['name']}</h1></td></tr>\n";
613 // Left column with information portlet.
614 echo "<tr><td class=pcleft height='1%' width='50%'>";
615 startPortlet ('Rack information');
616 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
617 echo "<tr><th width='50%' class=tdright>Rack name:</th><td class=tdleft>${rackData['name']}</td></tr>\n";
618 echo "<tr><th width='50%' class=tdright>Height:</th><td class=tdleft>${rackData['height']}</td></tr>\n";
619 echo "<tr><th width='50%' class=tdright>Rack row:</th><td class=tdleft>${rackData['row_name']}</td></tr>\n";
620 echo "<tr><th width='50%' class=tdright>Comment:</th><td class=tdleft>${rackData['comment']}</td></tr>\n";
625 echo "<td class=pcright>";
628 startPortlet ($header);
630 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
631 echo "<tr><th width='10%'> </th><th width='20%'>Front</th>";
632 echo "<th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
633 echo "<form method=post action='${root}?'>\n";
634 echo "<input type=hidden name=page value=${pageno}>\n";
635 echo "<input type=hidden name=tab value=${tabno}>\n";
636 echo "<input type=hidden name=rack_id value=${rack_id}>\n";
637 markupAtomGrid ($rackData, $state2);
638 renderAtomGrid ($rackData);
639 echo "</table></center>\n";
640 echo "<br><input type=submit name=do_update value='${submit}'></form><br><br>\n";
642 echo "</td></tr></table>\n";
645 function renderRackDesign ($rack_id)
647 renderGridForm ($rack_id, 'applyRackDesignMask', 'Rack design', 'Set rack design', 'A', 'F');
650 function renderRackProblems ($rack_id = 0)
652 renderGridForm ($rack_id, 'applyRackProblemMask', 'Rack problems', 'Mark unusable atoms', 'F', 'U');
655 function startPortlet ($title = '')
657 echo "<div class=portlet><h2>${title}</h2>";
660 function finishPortlet ()
665 function printRefsOfType ($refs, $type, $eq)
669 foreach ($refs as $ref)
671 if ($eq($ref['type'], $type))
673 if ($gotone) echo ', ';
674 echo "<a href='${root}?page=object&object_id=${ref['object_id']}'>";
675 if (!empty ($ref['name']))
676 echo $ref['name'] . '@';
677 echo "${ref['object_name']}</a>";
683 function renderRackObject ($object_id = 0)
688 showError ('Invalid object_id', __FUNCTION__
);
691 $info = getObjectInfo ($object_id);
694 showError ('getObjectInfo() failed', __FUNCTION__
);
697 // Main layout starts.
698 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
699 echo "<tr><td colspan=2 align=center><h1>${info['dname']}</h1></td></tr>\n";
700 // left column with uknown number of portlets
701 echo "<tr><td class=pcleft>";
702 startPortlet ('Object information');
703 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
704 if (!empty ($info['name']))
705 echo "<tr><th width='50%' class=tdright>Common name:</th><td class=tdleft>${info['name']}</td></tr>\n";
706 elseif (in_array ($info['objtype_id'], explode (',', getConfigVar ('NAMEFUL_OBJTYPES'))))
707 echo "<tr><td colspan=2 class=msg_error>Common name is missing.</td></tr>\n";
708 echo "<tr><th width='50%' class=tdright>Object type:</th><td class=tdleft>${info['objtype_name']}</td></tr>\n";
709 if (!empty ($info['asset_no']))
710 echo "<tr><th width='50%' class=tdright>Asset tag:</th><td class=tdleft>${info['asset_no']}</td></tr>\n";
711 elseif (in_array ($info['objtype_id'], explode (',', getConfigVar ('REQUIRE_ASSET_TAG_FOR'))))
712 echo "<tr><td colspan=2 class=msg_error>Asset tag is missing.</td></tr>\n";
713 if (!empty ($info['label']))
714 echo "<tr><th width='50%' class=tdright>Visible label:</th><td class=tdleft>${info['label']}</td></tr>\n";
715 if (!empty ($info['barcode']))
716 echo "<tr><th width='50%' class=tdright>Barcode:</th><td class=tdleft>${info['barcode']}</td></tr>\n";
717 if ($info['has_problems'] == 'yes')
718 echo "<tr><td colspan=2 class=msg_error>Has problems</td></tr>\n";
719 foreach (getAttrValues ($object_id, TRUE) as $record)
720 if (!empty ($record['value']))
721 echo "<tr><th width='50%' class=opt_attr_th>${record['name']}:</th><td class=tdleft>${record['a_value']}</td></tr>\n";
723 echo "</table><br>\n";
726 if (!empty ($info['comment']))
728 startPortlet ('Comment');
729 echo '<div class=commentblock>' . string_insert_hrefs ($info['comment']) . '</div>';
733 $ports = getObjectPortsAndLinks ($object_id);
736 startPortlet ('Ports and links');
737 usort($ports, 'sortByName');
741 if (isset ($_REQUEST['hl_port_id']))
743 assertUIntArg ('hl_port_id', __FUNCTION__
);
744 $hl_port_id = $_REQUEST['hl_port_id'];
746 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
747 echo "<tr><th>Local name</th><th>Visible label</th><th>Port type</th><th>L2 address</th>";
748 echo "<th>Rem. Object</th><th>Rem. port</th></tr>\n";
749 foreach ($ports as $port)
752 if ($hl_port_id == $port['id'])
753 echo ' class=port_highlight';
754 echo "><td>${port['name']}</td><td>${port['label']}</td><td>${port['type']}</td>";
755 echo "<td>${port['l2address']}</td>";
756 if ($port['remote_object_id'])
758 echo "<td><a href='${root}?page=object&object_id=${port['remote_object_id']}'>${port['remote_object_name']}</a></td>";
759 echo "<td>${port['remote_name']}</td>";
761 elseif (!empty ($port['reservation_comment']))
763 echo "<td><b>Reserved;</b></td>";
764 echo "<td>${port['reservation_comment']}</td>";
767 echo '<td> </td><td> </td>';
770 echo "</table><br>\n";
774 $addresses = getObjectAddresses ($object_id);
775 usort($addresses, 'sortAddresses');
776 if (count ($addresses))
778 startPortlet ('IPv4 addresses');
779 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
780 echo "<tr><th>Interface name</th><th>IP Address</th><th>Description</th><th>Misc</th></tr>\n";
781 foreach ($addresses as $addr)
783 if (strlen($addr['address_name'])>40)
784 $address_name = substr($addr['address_name'],0,38).'...';
786 $address_name = $addr['address_name'];
788 $virtnum = countRefsOfType($addr['references'], 'virtual', 'eq');
789 $sharednum = countRefsOfType($addr['references'], 'shared', 'eq');
790 $regnum = countRefsOfType($addr['references'], 'regular', 'eq');
791 $notvirtnum = countRefsOfType($addr['references'], 'virtual', 'neq');
793 if ($addr['address_reserved']=='yes')
795 elseif ($addr['type']!='virtual' && $regnum>0)
797 elseif ($addr['type']=='regular' && $sharednum>0)
802 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";
804 if ($addr['address_reserved']=='yes')
805 echo "<b>Reserved;</b> ";
807 if ($addr['type'] == 'virtual')
813 printRefsOfType($addr['references'], 'virtual', 'neq');
816 elseif ($addr['type'] == 'shared')
822 printRefsOfType($addr['references'], 'shared', 'eq');
828 printRefsOfType($addr['references'], 'virtual', 'eq');
833 echo " Collisions: ";
834 printRefsOfType($addr['references'], 'regular', 'eq');
843 printRefsOfType($addr['references'], 'virtual', 'eq');
848 echo " Collisions: ";
849 printRefsOfType($addr['references'], 'virtual', 'neq');
855 echo "</table><br>\n";
859 $forwards = getNATv4ForObject ($object_id);
860 if (count($forwards['in']) or count($forwards['out']))
862 startPortlet('NATv4');
864 if (count($forwards['out']))
867 echo "<h3>locally performed NAT</h3>";
869 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
870 echo "<tr><th>Proto</th><th>Match endpoint</th><th>Translate to</th><th>Target object</th><th>Rule comment</th></tr>\n";
872 foreach ($forwards['out'] as $pf)
876 foreach ($addresses as $addr)
877 if ($addr['ip'] == $pf['localip'])
884 echo "<tr class='$class'>";
886 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>";
888 echo "<td class=tdleft><a href='${root}?page=ipaddress&tab=default&ip=${pf['remoteip']}'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
890 $address=getIPAddress($pf['remoteip']);
892 echo "<td class='description'>";
893 if (count ($address['bonds']))
894 foreach($address['bonds'] as $bond)
895 echo "<a href='${root}?page=object&tab=default&object_id=${bond['object_id']}'>${bond['object_name']}(${bond['name']})</a> ";
896 elseif (!empty ($pf['remote_addr_name']))
897 echo '(' . $pf['remote_addr_name'] . ')';
899 echo "</td><td class='description'>${pf['description']}</td>";
903 echo "</table><br><br>";
905 if (count($forwards['in']))
907 echo "<h3>arriving NAT connections</h3>";
909 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
910 echo "<tr><th>Matched endpoint</th><th>Source object</th><th>Translated to</th><th>Rule comment</th></tr>\n";
912 foreach ($forwards['in'] as $pf)
915 echo "<td>${pf['proto']}/<a href='${root}?page=ipaddress&tab=default&ip=${pf['localip']}'>${pf['localip']}</a>:${pf['localport']}</td>";
917 echo "<td class='description'><a href='${root}?page=object&tab=default&object_id=${pf['object_id']}'>${pf['object_name']}</a>";
919 echo "</td><td><a href='${root}?page=ipaddress&tab=default&ip=${pf['remoteip']}'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
920 echo "<td class='description'>${pf['description']}</td></tr>";
923 echo "</table><br><br>";
928 $pools = getRSPoolsForObject ($object_id);
931 startPortlet ('Real server pools');
932 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
933 echo "<tr><th>VS</th><th>RS pool</th><th>RS</th><th>VS config</th><th>RS config</th></tr>\n";
934 foreach ($pools as $vs_id => $info)
936 echo "<tr valign=top><td class=tdleft><a href='${root}?page=vservice&id=${vs_id}'>";
937 echo buildVServiceName ($info);
939 if (!empty ($info['name']))
940 echo " (${info['name']})";
941 echo "</td><td class=tdleft><a href='${root}?page=rspool&pool_id=${info['pool_id']}'>";
942 echo (empty ($info['pool_name']) ?
'ANONYMOUS' : $info['pool_name']);
943 echo '</a></td><td class=tdleft>' . $info['rscount'] . '</td>';
944 echo "<td class=tdleft><pre>${info['vsconfig']}</pre></td>";
945 echo "<td class=tdleft><pre>${info['rsconfig']}</pre></td>";
953 // After left column we have (surprise!) right column with rackspace portled only.
954 echo "<td class=pcright>";
956 startPortlet ('Rackspace allocation');
957 // FIXME: now we call getRackData() twice
958 $racks = getResidentRacksData ($object_id);
959 foreach ($racks as $rackData)
960 renderRack ($rackData['id'], $object_id);
967 function renderRackMultiSelect ($sname, $racks, $selected)
969 echo "<select name=${sname} multiple size=" . getConfigVar ('MAXSELSIZE') . " onchange='getElementById(\"racks\").submit()'>\n";
970 foreach ($racks as $rack)
972 echo "<option value=${rack['id']}";
973 if (!(array_search ($rack['id'], $selected) === FALSE))
975 echo">${rack['row_name']}: ${rack['name']}</option>\n";
980 function showMessageOrError ()
982 if (isset($_REQUEST['message']))
983 echo "<div class=msg_success>${_REQUEST['message']}</div>";
984 if (isset($_REQUEST['error']))
985 echo "<div class=msg_error>${_REQUEST['error']}</div>";
988 // This function renders a form for port edition.
989 function renderPortsForObject ($object_id = 0)
991 global $root, $pageno, $tabno;
994 showError ('Invalid object_id', __FUNCTION__
);
997 showMessageOrError();
998 startPortlet ('Ports and interfaces');
999 $ports = getObjectPortsAndLinks ($object_id);
1000 usort($ports, 'sortByName');
1001 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
1002 echo "<tr><th> </th><th>Local name</th><th>Visible label</th><th>Port type</th><th>L2 address</th>";
1003 echo "<th>Rem. object</th><th>Rem. port</th><th>(Un)link or (un)reserve</th><th> </th></tr>\n";
1004 foreach ($ports as $port)
1006 echo "<form action='${root}process.php'>";
1007 echo "<input type=hidden name=op value=editPort>";
1008 echo "<input type=hidden name=page value='${pageno}'>\n";
1009 echo "<input type=hidden name=tab value='${tabno}'>\n";
1010 echo "<input type=hidden name=port_id value='${port['id']}'>";
1011 echo "<input type=hidden name=object_id value='$object_id'>\n";
1012 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']}'>";
1013 printImageHREF ('delete', 'Unlink and Delete this port');
1015 echo "<td><input type=text name=name value='${port['name']}' size=8></td>";
1016 echo "<td><input type=text name=label value='${port['label']}' size=24></td>";
1017 echo "<td>${port['type']}</td>\n";
1018 echo "<td><input type=text name=l2address value='${port['l2address']}'></td>\n";
1019 if ($port['remote_object_id'])
1021 echo "<td><a href='${root}?page=object&object_id=${port['remote_object_id']}'>${port['remote_object_name']}</a></td>";
1022 echo "<td>${port['remote_name']}</td>";
1023 echo "<td><a href='${root}process.php?op=unlinkPort&page=${pageno}&tab=${tabno}&port_id=${port['id']}&object_id=$object_id&port_name=";
1024 echo urlencode ($port['name']);
1025 echo "&remote_port_name=${port['remote_name']}&remote_object_name=${port['remote_object_name']}'>";
1026 printImageHREF ('unlink', 'Unlink this port');
1029 elseif (!empty ($port['reservation_comment']))
1031 echo "<td><b>Reserved;</b></td>";
1032 echo "<td><input type=text name=reservation_comment value='${port['reservation_comment']}'></td>";
1033 echo "<td><a href='${root}process.php?op=useup&page=${pageno}&tab=${tabno}&port_id=${port['id']}&object_id=${object_id}'>";
1034 printImageHREF ('useup', 'Use up this port');
1039 echo "<td> </td><td> </td>";
1041 echo "<a href='javascript:;' onclick='window.open(\"${root}link_helper.php?port=${port['id']}&type=${port['type_id']}&object_id=$object_id&port_name=";
1042 echo urlencode ($port['name']);
1043 echo "\",\"findlink\",\"height=700, width=400, location=no, menubar=no, resizable=yes, scrollbars=no, status=no, titlebar=no, toolbar=no\");'>";
1044 printImageHREF ('link', 'Link this port');
1045 echo "</a> <input type=text name=reservation_comment>";
1048 echo "<td><input type='submit' value='OK'></td>";
1049 echo "</form></tr>\n";
1051 echo "<form action='${root}process.php'><tr><td>";
1052 printImageHREF ('add', '', TRUE, 104);
1053 echo "</td><td><input type=text size=8 name=port_name tabindex=100></td>\n";
1054 echo "<td><input type=text size=24 name=port_label tabindex=101></td>";
1055 echo "<input type=hidden name=op value=addPort>\n";
1056 echo "<input type=hidden name=object_id value='${object_id}'>\n";
1057 echo "<input type=hidden name=page value='${pageno}'>\n";
1058 echo "<input type=hidden name=tab value='${tabno}'>\n";
1059 echo "<td><select name='port_type_id' tabindex=102>\n";
1060 $types = getPortTypes();
1061 $default_port_type = getConfigVar ('default_port_type');
1062 foreach ($types as $typeid => $typename)
1064 echo "<option value='${typeid}'";
1065 if ($typeid == $default_port_type)
1067 echo ">${typename}</option>\n";
1069 echo "</select></td>";
1070 echo "<td><input type=text name=port_l2address tabindex=103></td>\n";
1071 echo "<td colspan=4> </td></tr></form>";
1072 echo "</table><br>\n";
1075 startPortlet ('Add/update multiple ports');
1076 echo "<form action=${root}process.php method=post>";
1077 echo "<input type=hidden name=page value='${pageno}'>\n";
1078 echo "<input type=hidden name=tab value='${tabno}'>\n";
1079 echo "<input type=hidden name=object_id value='${object_id}'>\n";
1080 echo "<input type=hidden name=op value=addMultiPorts>";
1081 echo 'Format: <select name=format>';
1082 echo '<option value=c2900 disabled>Cisco 2900 series: sh int eth</option>';
1083 echo '<option value=c3600eth disabled>Cisco 3600 ethernet: sh arp | inc -</option>';
1084 echo '<option value=c3600asy>Cisco 3600 async: sh line | inc TTY</option>';
1085 echo '<option value=fiwg selected>Foundry ServerIron/FastIron WorkGroup/Edge: sh int br</option>';
1086 echo '<option value=fiedge disabled>Foundry FastIron Edge: sh int br</option>';
1087 echo '<option value=fisxii>Foundry FastIron SuperX/II4000: sh int br</option>';
1088 echo '<option value=ssv1>SSV:<interface name> <MAC address></option>';
1090 echo 'Default port type: ';
1091 echo "<select name=port_type>\n";
1092 foreach ($types as $typeid => $typename)
1094 echo "<option value='${typeid}'";
1095 if ($typeid == $default_port_type)
1097 echo ">${typename}</option>\n";
1100 echo "<input type=submit value='Parse output'><br>\n";
1101 echo "<textarea name=input cols=100 rows=50></textarea><br>\n";
1106 function renderNetworkForObject ($object_id=0)
1108 global $root, $pageno, $tabno;
1109 if ($object_id <= 0)
1111 showError ('Invalid object_id', __FUNCTION__
);
1114 showMessageOrError();
1115 startPortlet ('Network Addresses');
1116 $addresses = getObjectAddresses ($object_id);
1117 usort($addresses, 'sortAddresses');
1118 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
1119 echo "<tr><th> </th><th>Interface name</th><th>IP Address</th><th>Description</th><th>Type</th><th>Misc</th><th> </th></tr>\n";
1120 foreach ($addresses as $addr)
1122 if (strlen($addr['address_name'])>40)
1123 $address_name = substr($addr['address_name'],0,38).'...';
1125 $address_name = $addr['address_name'];
1127 $virtnum = countRefsOfType($addr['references'], 'virtual', 'eq');
1128 $sharednum = countRefsOfType($addr['references'], 'shared', 'eq');
1129 $regnum = countRefsOfType($addr['references'], 'regular', 'eq');
1130 $notvirtnum = countRefsOfType($addr['references'], 'virtual', 'neq');
1132 if ($addr['address_reserved']=='yes')
1134 elseif ($addr['type']!='virtual' && $regnum>0)
1136 elseif ($addr['type']=='regular' && $sharednum>0)
1141 echo "<form action='process.php'>";
1142 echo "<input type=hidden name=page value='${pageno}'>\n";
1143 echo "<input type=hidden name=tab value='${tabno}'>\n";
1144 echo "<input type=hidden name=op value=editAddressFromObject>";
1145 echo "<input type=hidden name=object_id value='$object_id'>";
1146 echo "<input type=hidden name=ip value='${addr['ip']}'>";
1147 echo "<tr class='$class'><td><a href='process.php?op=delAddrFObj&page=${pageno}&tab=${tabno}&ip=${addr['ip']}&object_id=$object_id'>";
1148 printImageHREF ('delete', 'Delete this IPv4 address');
1150 echo "<td><input type='text' name='bond_name' value='${addr['name']}' size=10></td>";
1151 echo "<td><a href='${root}?page=ipaddress&ip=${addr['ip']}'>${addr['ip']}</a></td>";
1152 echo "<td class='description'>$address_name</td>\n";
1153 echo "<td><select name='bond_type'>";
1154 foreach (array('regular'=>'Regular', 'virtual'=>'Virtual', 'shared'=>'Shared') as $n => $v)
1156 echo "<option value='$n'";
1157 if ($addr['type'] == $n)
1159 echo ">$v</option>";
1162 if ($addr['address_reserved']=='yes')
1163 echo "<b>Reserved</b>; ";
1165 if ($addr['type'] == 'virtual')
1167 if ($notvirtnum > 0)
1170 printRefsOfType($addr['references'], 'virtual', 'neq');
1173 elseif ($addr['type'] == 'shared')
1178 printRefsOfType($addr['references'], 'shared', 'eq');
1184 printRefsOfType($addr['references'], 'virtual', 'eq');
1189 echo " Collisions: ";
1190 printRefsOfType($addr['references'], 'regular', 'eq');
1199 printRefsOfType($addr['references'], 'virtual', 'eq');
1202 if ($notvirtnum > 0)
1204 echo " Collisions: ";
1205 printRefsOfType($addr['references'], 'virtual', 'neq');
1209 echo "</td><td><input type=submit value='OK'></td></form></tr>\n";
1213 echo "<form action='${root}process.php'><tr><td colspan=2><input type='text' size='10' name='name' tabindex=100></td>\n";
1214 echo "<input type=hidden name=page value='${pageno}'>\n";
1215 echo "<input type=hidden name=tab value='${tabno}'>\n";
1216 echo "<input type=hidden name=op value=addAddrFObj>\n";
1217 echo "<input type=hidden name=object_id value='$object_id'>\n";
1219 echo "<td><input type=text name='ip' tabindex=101>\n";
1220 echo "</td><td><select name='type' tabindex=102>";
1221 echo "<option value='regular'>Regular</option>";
1222 echo "<option value='virtual'>Virtual</option>";
1223 echo "<option value='shared'>Shared</option>";
1225 echo "</td><td colspan=3><input type='submit' value='Add a new interface' tabindex=103></td></tr></form>";
1226 echo "</table><br>\n";
1231 function printLog ($log)
1233 foreach ($log as $record)
1234 echo "<div class=msg_${record['code']}>${record['message']}</div>";
1238 The following conditions must be followed:
1239 1. We can mount onto free atoms only. This means: if any record for an atom
1240 already exists in RackSpace, it can't be used for mounting.
1241 2. We can't unmount from 'W' atoms. Operator should review appropriate comments
1242 and either delete them before unmounting or refuse to unmount the object.
1245 // We extensively use $_REQUEST in the function.
1246 function renderRackSpaceForObject ($object_id = 0)
1248 if ($object_id <= 0)
1250 showError ('Invalid object_id', __FUNCTION__
);
1253 $is_submit = isset ($_REQUEST['got_atoms']);
1254 $is_update = isset ($_REQUEST['rackmulti'][0]);
1255 $info = getObjectInfo ($object_id);
1258 showError ('getObjectInfo() failed', __FUNCTION__
);
1261 // Always process occupied racks plus racks chosen by user. First get racks with
1262 // already allocated rackspace...
1263 $workingRacksData = getResidentRacksData ($object_id);
1264 if ($workingRacksData === NULL)
1266 print_r ($workingRacksData);
1267 showError ('getResidentRacksData() failed', __FUNCTION__
);
1271 // ...and then add those chosen by user (if any).
1273 foreach ($_REQUEST['rackmulti'] as $cand_id)
1275 if (!isset ($workingRacksData[$cand_id]))
1277 $rackData = getRackData ($cand_id);
1278 if ($rackData == NULL)
1280 showError ('getRackData() failed', __FUNCTION__
);
1283 $workingRacksData[$cand_id] = $rackData;
1287 // Do it only once...
1288 foreach ($workingRacksData as &$rackData)
1289 applyObjectMountMask ($rackData, $object_id);
1290 // Now we workaround an old caveat: http://bugs.php.net/bug.php?id=37410
1293 // Here we process form submit by trying to save all submitted info to database.
1296 $oldMolecule = getMoleculeForObject ($object_id);
1297 $worldchanged = FALSE;
1299 foreach ($workingRacksData as $rack_id => $rackData)
1301 $logrecord = processGridForm ($rackData, 'F', 'T', $object_id);
1302 $log[] = $logrecord;
1303 if ($logrecord['code'] != 300)
1305 $worldchanged = TRUE;
1306 // Reload our working copy after form processing.
1307 $rackData = getRackData ($rack_id);
1308 if ($rackData == NULL)
1309 $log[] = array ('code' => 500, 'message' => 'Working copy update failed in ', __FUNCTION__
);
1310 applyObjectMountMask ($rackData, $object_id);
1311 $workingRacksData[$rack_id] = $rackData;
1317 $newMolecule = getMoleculeForObject ($object_id);
1318 $oc = count ($oldMolecule);
1319 $nc = count ($newMolecule);
1320 $omid = $oc ?
createMolecule ($oldMolecule) : 'NULL';
1321 $nmid = $nc ?
createMolecule ($newMolecule) : 'NULL';
1322 global $remote_username;
1323 $comment = empty ($_REQUEST['comment']) ?
'NULL' : "'${_REQUEST['comment']}'";
1325 "insert into MountOperation(object_id, old_molecule_id, new_molecule_id, user_name, comment) " .
1326 "values (${object_id}, ${omid}, ${nmid}, '${remote_username}', ${comment})";
1328 $result = $dbxlink->query ($query);
1329 if ($result == NULL)
1330 $log[] = array ('code' => 'error', 'message' => 'SQL query failed during history logging.');
1332 $log[] = array ('code' => 'success', 'message' => 'History logged.');
1337 // This is the time for rendering.
1338 global $root, $pageno, $tabno;
1339 echo "<form id='racks' action='${root}'>";
1340 echo "<input type=hidden name=page value='${pageno}'>\n";
1341 echo "<input type=hidden name=tab value='${tabno}'>\n";
1342 echo "<input type=hidden name=object_id value='${object_id}'>\n";
1343 // Main layout starts.
1344 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0><tr>";
1346 // Left portlet with rack list.
1347 echo "<td class=pcleft height='1%'>";
1348 startPortlet ('Racks');
1349 $allRacksData = getRacksForRow();
1350 if (count ($allRacksData) <= getConfigVar ('RACK_PRESELECT_THRESHOLD'))
1352 foreach (array_keys ($allRacksData) as $rack_id)
1354 $rackData = getRackData ($rack_id);
1355 if ($rackData == NULL)
1357 showError ('getRackData() failed', __FUNCTION__
);
1360 $workingRacksData[$rack_id] = $rackData;
1362 foreach ($workingRacksData as &$rackData)
1363 applyObjectMountMask ($rackData, $object_id);
1366 renderRackMultiSelect ('rackmulti[]', $allRacksData, array_keys ($workingRacksData));
1372 // Middle portlet with comment and submit.
1373 echo "<td class=pcleft>";
1374 startPortlet ('Comment');
1375 echo "<textarea name=comment rows=10 cols=40></textarea><br>\n";
1376 echo "<input type=submit value='Save' name=got_atoms>\n";
1382 // Right portlet with rendered racks. If this form submit is not final, we have to
1383 // reflect the former state of the grid in current form.
1384 echo "<td class=pcright rowspan=2 height='1%'>";
1385 startPortlet ('Working copy');
1386 echo '<table border=0 cellspacing=10 align=center><tr>';
1387 foreach ($workingRacksData as $rack_id => $rackData)
1389 // Order is important here: only original allocation is highlighted.
1390 highlightObject ($rackData, $object_id);
1391 markupAtomGrid ($rackData, 'T');
1392 // If we have a form processed, discard user input and show new database
1394 if (!$is_submit and $is_update)
1395 mergeGridFormToRack ($rackData);
1396 echo "<td valign=top>";
1397 echo "<center>\n<h2>${rackData['name']}</h2>\n";
1398 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
1399 echo "<tr><th width='10%'> </th><th width='20%'>Front</th>";
1400 echo "<th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
1401 renderAtomGrid ($rackData);
1402 echo "<tr><th width='10%'> </th><th width='20%'>Front</th>";
1403 echo "<th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
1404 echo "</table></center>\n";
1407 echo "</tr></table>";
1412 echo "</tr></table>\n";
1415 function renderMolecule ($mdata, $object_id)
1418 $rackpack = array();
1420 foreach ($mdata as $dummy => $rua)
1422 $rack_id = $rua['rack_id'];
1423 $unit_no = $rua['unit_no'];
1424 $atom = $rua['atom'];
1425 if (!isset ($rackpack[$rack_id]))
1427 $rackData = getRackData ($rack_id);
1428 for ($i = $rackData['height']; $i > 0; $i--)
1429 for ($locidx = 0; $locidx < 3; $locidx++
)
1430 $rackData[$i][$locidx]['state'] = 'F';
1431 $rackpack[$rack_id] = $rackData;
1433 $rackpack[$rack_id][$unit_no][$loclist[$atom]]['state'] = 'T';
1434 $rackpack[$rack_id][$unit_no][$loclist[$atom]]['object_id'] = $object_id;
1436 // now we have some racks to render
1437 foreach ($rackpack as $dummy => $rackData)
1439 markAllSpans ($rackData);
1440 echo "<table class=molecule cellspacing=0>\n";
1441 echo "<caption>${rackData['name']}</caption>\n";
1442 echo "<tr><th width='10%'> </th><th width='20%'>Front</th><th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
1443 for ($i = $rackData['height']; $i > 0; $i--)
1445 echo "<tr><th>$i</th>";
1446 for ($locidx = 0; $locidx < 3; $locidx++
)
1448 $state = $rackData[$i][$locidx]['state'];
1449 echo "<td class=state_${state}> </td>\n";
1457 function renderUnmountedObjectsPortlet ()
1459 startPortlet ('Unmounted objects');
1460 $objs = getUnmountedObjects();
1463 showError ('getUnmountedObjects() failed', __FUNCTION__
);
1466 global $root, $nextorder;
1468 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1469 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset number</th><th>Barcode</th></tr>';
1470 foreach ($objs as $obj)
1472 echo "<tr class=row_${order}><td><a href='${root}?page=object&object_id=${obj['id']}'>${obj['dname']}</a></td>";
1473 echo "<td>${obj['label']}</td>";
1474 echo "<td>${obj['asset_no']}</td>";
1475 echo "<td>${obj['barcode']}</td></tr>";
1476 $order = $nextorder[$order];
1478 echo "</table><br>\n";
1482 function renderProblematicObjectsPortlet ()
1484 startPortlet ('Problematic objects');
1485 $objs = getProblematicObjects();
1488 showError ('getProblematicObjects() failed', __FUNCTION__
);
1491 global $root, $nextorder;
1493 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1494 echo '<tr><th>Type</th><th>Common name</th></tr>';
1495 foreach ($objs as $obj)
1497 echo "<tr class=row_${order}><td>${obj['objtype_name']}</td>";
1498 echo "<td><a href='${root}?page=object&object_id=${obj['id']}'>${obj['dname']}</a></tr>";
1499 $order = $nextorder[$order];
1501 echo "</table><br>\n";
1505 function renderObjectGroupSummary ()
1508 $tagfilter = isset ($_REQUEST['tagfilter']) ?
$_REQUEST['tagfilter'] : array();
1509 $tagfilter = complementByKids ($tagfilter);
1510 $summary = getObjectGroupInfo();
1511 if ($summary === NULL)
1513 showError ('getObjectGroupInfo() failed', __FUNCTION__
);
1516 echo "<table border=0 class=objectview>\n";
1517 echo "<tr><td class=pcleft width='25%'>";
1519 startPortlet ('Summary');
1520 foreach ($summary as $gi)
1521 echo "<a href='${root}?page=objgroup&group_id=${gi['id']}'><b>${gi['name']}</b></a> <i>(${gi['count']})</i><br>";
1524 echo '</td><td class=pcright>';
1525 renderUnmountedObjectsPortlet();
1526 echo '</td><td class=pcright>';
1527 renderProblematicObjectsPortlet();
1528 echo '</td><td class=pcright>';
1529 startPortlet ('Tag filter');
1530 renderTagFilterSelect ($tagfilter, 'object');
1532 echo "</td></tr></table>\n";
1535 function renderObjectSpace ()
1537 global $root, $taglist, $tagtree;
1538 echo "<table border=0 class=objectview>\n";
1539 echo "<tr><td class=pcleft width='50%'>";
1540 startPortlet ('View all by type');
1541 $groupInfo = getObjectGroupInfo();
1542 if ($groupInfo === NULL)
1544 showError ('getObjectGroupInfo() failed', __FUNCTION__
);
1547 if (count ($groupInfo) == 0)
1548 echo "No objects exist in DB";
1551 echo '<div align=left><ul>';
1552 foreach ($groupInfo as $gi)
1553 echo "<li><a href='${root}?page=objgroup&group_id=${gi['id']}'>${gi['name']}</a> (${gi['count']})</li>";
1558 echo '</td><td class=pcright>';
1560 startPortlet ('View all by tag');
1561 if (count ($taglist) == 0)
1562 echo "No tags exist in DB";
1564 renderTagCloud ('object');
1566 echo "</td></tr></table>\n";
1569 function renderObjectGroup ()
1571 global $root, $pageno, $tabno, $nextorder, $taglist, $tagtree;
1572 assertUIntArg ('group_id', __FUNCTION__
, TRUE);
1573 $group_id = $_REQUEST['group_id'];
1574 $tagfilter = isset ($_REQUEST['tagfilter']) ?
$_REQUEST['tagfilter'] : array();
1575 $tagfilter_str = getStringFromTrail (getExplicitTagsOnly (buildTrailFromIds ($tagfilter)));
1576 $tagfilter = complementByKids ($tagfilter);
1578 echo "<input type=hidden name=page value=${pageno}>\n";
1579 echo "<input type=hidden name=group_id value=${group_id}>\n";
1580 echo "<table border=0 class=objectview>\n";
1581 echo "<tr><td class=pcleft width='25%'>";
1582 startPortlet ('change type');
1583 $groupInfo = getObjectGroupInfo();
1584 if ($groupInfo === NULL)
1586 showError ('getObjectGroupInfo() failed', __FUNCTION__
);
1589 if (count ($groupInfo) == 0)
1590 echo "No objects exist in DB";
1593 echo '<div align=left><ul>';
1594 foreach ($groupInfo as $gi)
1596 echo "<li><a href='${root}?page=${pageno}&group_id=${gi['id']}&tagfilter[]=${tagfilter_str}'>";
1597 if ($gi['id'] == $group_id)
1599 echo "${gi['name']}</a>";
1600 if ($gi['id'] == $group_id)
1602 echo " (${gi['count']})";
1603 if ($gi['id'] == $group_id)
1611 echo '</td><td class=pcleft>';
1613 startPortlet ('Objects');
1614 $objects = getObjectList ($group_id, $tagfilter);
1615 if ($objects === NULL)
1617 showError ('getObjectList() failed', __FUNCTION__
);
1620 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1621 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>Barcode</th><th>Rack</th></tr>';
1623 foreach ($objects as $obj)
1625 echo "<tr class=row_${order}><td><a href='${root}?page=object&object_id=${obj['id']}'>${obj['dname']}</a></td>";
1626 echo "<td>${obj['label']}</td>";
1627 echo "<td>${obj['asset_no']}</td>";
1628 echo "<td>${obj['barcode']}</td>";
1629 if ($obj['rack_id'])
1630 echo "<td><a href='${root}?page=rack&rack_id=${obj['rack_id']}'>${obj['Rack_name']}</a></td>";
1632 echo '<td>Unmounted</td>';
1634 $order = $nextorder[$order];
1639 echo "</td><td class=pcright width='25%'>";
1641 startPortlet ('change filter');
1642 renderTagFilterSelect ($tagfilter, 'object');
1643 echo "<input type=submit value='Apply'>\n";
1645 echo "</td></tr></table>\n";
1649 function renderObjectGroup_old ()
1652 assertUIntArg ('group_id', __FUNCTION__
);
1653 $group_id = $_REQUEST['group_id'];
1654 $summary = getObjectGroupInfo();
1655 if ($summary == NULL)
1657 showError ('getObjectGroupInfo() failed', __FUNCTION__
);
1660 $objects = getObjectList ($group_id);
1661 if ($objects === NULL)
1663 showError ('getObjectList() failed', __FUNCTION__
);
1666 echo "<table border=0 class=objectview>\n";
1667 echo "<tr><td class=pcleft width='25%'>";
1669 startPortlet ('All objects');
1670 foreach ($summary as $gi)
1672 echo "<a href='${root}?page=objgroup&group_id=${gi['id']}'><b>${gi['name']}</b></a> <i>(${gi['count']})</i><br>";
1676 echo '</td><td class=pcright>';
1678 startPortlet ('Object group');
1679 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1680 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>Barcode</th><th>Rack</th></tr>';
1683 foreach ($objects as $obj)
1685 echo "<tr class=row_${order}><td><a href='${root}?page=object&object_id=${obj['id']}'>${obj['dname']}</a></td>";
1686 echo "<td>${obj['label']}</td>";
1687 echo "<td>${obj['asset_no']}</td>";
1688 echo "<td>${obj['barcode']}</td>";
1689 if ($obj['rack_id'])
1690 echo "<td><a href='${root}?page=rack&rack_id=${obj['rack_id']}'>${obj['Rack_name']}</a></td>";
1692 echo '<td>Unmounted</td>';
1694 $order = $nextorder[$order];
1699 echo "</td></tr></table>";
1702 function renderEmptyPortsSelect ($port_id, $type_id)
1704 $ports = getEmptyPortsOfType($type_id);
1705 usort($ports, 'sortEmptyPorts');
1706 foreach ($ports as $port)
1708 if ($port_id == $port['Port_id'])
1710 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";
1714 function renderObjectAddressesAndNames ()
1716 $addresses = getObjectAddressesAndNames();
1717 usort($addresses, 'sortObjectAddressesAndNames');
1718 foreach ($addresses as $address)
1720 echo "<option value='${address['ip']}' onclick='getElementById(\"ip\").value=\"${address['ip']}\";'>${address['object_name']} ${address['name']} ${address['ip']}</option>\n";
1724 // History viewer for history-enabled simple dictionaries.
1725 function renderHistory ($object_type, $object_id)
1727 switch ($object_type)
1730 $query = "select ctime, user_name, name, deleted, comment from RackRowHistory where id = ${object_id} order by ctime";
1731 $header = '<tr><th>change time</th><th>author</th><th>rack row name</th><th>is deleted?</th><th>rack row comment</th></tr>';
1736 "select ctime, user_name, rh.name, rh.deleted, d.dict_value as name, rh.height, rh.comment " .
1737 "from RackHistory as rh left join Dictionary as d on rh.row_id = d.dict_key " .
1738 "natural join Chapter " .
1739 "where chapter_name = 'RackRow' and rh.id = ${object_id} order by ctime";
1740 $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>';
1745 "select ctime, user_name, name, label, barcode, asset_no, deleted, has_problems, dict_value, comment " .
1746 "from RackObjectHistory inner join Dictionary on objtype_id = dict_key natural join Chapter " .
1747 "where chapter_name = 'RackObjectType' and id=${object_id} order by ctime";
1748 $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>';
1752 showError ("Uknown object type '${object_type}'", __FUNCTION__
);
1756 $result = $dbxlink->query ($query);
1757 if ($result == NULL)
1759 showError ('SQL query failed', __FUNCTION__
);
1762 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1766 while ($row = $result->fetch (PDO
::FETCH_NUM
))
1768 echo "<tr class=row_${order}><td>${row[0]}</td>";
1769 for ($i = 1; $i <= $extra; $i++
)
1770 echo "<td>" . $row[$i] . "</td>";
1772 $order = $nextorder[$order];
1774 echo "</table><br>\n";
1777 function renderRackspaceHistory ()
1779 global $root, $nextorder, $pageno, $tabno;
1781 $history = getRackspaceHistory();
1782 // Show the last operation by default.
1783 if (isset ($_REQUEST['op_id']))
1784 $op_id = $_REQUEST['op_id'];
1785 elseif (isset ($history[0]['mo_id']))
1786 $op_id = $history[0]['mo_id'];
1793 list ($omid, $nmid) = getOperationMolecules ($op_id);
1795 // Main layout starts.
1796 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
1798 // Left top portlet with old allocation.
1799 echo "<tr><td class=pcleft>";
1800 startPortlet ('Old allocation');
1803 $oldMolecule = getMolecule ($omid);
1804 renderMolecule ($oldMolecule, $object_id);
1810 echo '</td><td class=pcright>';
1812 // Right top portlet with new allocation
1813 startPortlet ('New allocation');
1816 $newMolecule = getMolecule ($nmid);
1817 renderMolecule ($newMolecule, $object_id);
1823 echo '</td></tr><tr><td colspan=2>';
1825 // Bottom portlet with list
1827 startPortlet ('Rackspace allocation history');
1828 echo "<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>\n";
1829 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";
1830 foreach ($history as $row)
1832 if ($row['mo_id'] == $op_id)
1835 $class = "row_${order}";
1836 echo "<tr class=${class}><td><a href='${root}?page=${pageno}&tab=${tabno}&op_id=${row['mo_id']}'>${row['ctime']}</a></td>";
1837 echo "<td>${row['user_name']}</td>";
1838 echo "<td>${row['ro_id']}</td><td>${row['objtype_name']}</td><td>${row['name']}</td><td>${row['comment']}</td>\n";
1840 $order = $nextorder[$order];
1845 echo '</td></tr></table>';
1849 function renderAddressspace ()
1851 global $root, $page;
1853 echo "<table border=0 class=objectview>\n";
1854 echo "<tr><td class=pcleft>";
1856 startPortlet ('Subnets');
1857 echo "<table class='widetable' border=0 cellpadding=10 cellspacing=0 align='center'>\n";
1858 $tagfilter = isset ($_REQUEST['tagfilter']) ?
$_REQUEST['tagfilter'] : array();
1859 $tagfilter = complementByKids ($tagfilter);
1860 $addrspaceList = getAddressspaceList ($tagfilter);
1861 echo "<tr><th>Subnet</th><th>Name</th><th>Utilization</th></tr>";
1862 foreach ($addrspaceList as $iprange)
1864 $range = getIPRange ($iprange['id']);
1865 $total = ($iprange['ip_bin'] |
$iprange['mask_bin_inv']) - ($iprange['ip_bin'] & $iprange['mask_bin']) +
1;
1866 $used = count ($range['addrlist']);
1867 echo "<tr><td class=tdleft><a href='${root}?page=iprange&id=${iprange['id']}'>${iprange['ip']}/${iprange['mask']}</a></td>";
1868 echo "<td class=tdleft>${iprange['name']}</td><td class=tdleft>";
1869 renderProgressBar ($used/$total);
1870 echo " ${used}/${total}</td></tr>";
1874 echo '</td><td class=pcright>';
1875 renderTagFilterPortlet ($tagfilter, 'ipv4net');
1876 echo "</td></tr></table>\n";
1879 function renderIPv4SLB ()
1881 global $root, $page, $nextorder;
1883 startPortlet ('SLB configuration');
1884 echo "<table border=0 width='100%'><tr>";
1885 foreach (array ('vservices', 'rspools', 'rservers', 'lbs') as $pno)
1886 echo "<td><h3><a href='${root}?page=${pno}'>" . $page[$pno]['title'] . "</a></h3></td>";
1887 echo '</tr></table>';
1890 $summary = getSLBSummary();
1891 startPortlet ('SLB tactical overview');
1892 // A single id-keyed array isn't used here to preserve existing
1893 // order of LBs returned by getSLBSummary()
1896 foreach ($summary as $vipdata)
1897 foreach (array_keys ($vipdata['lblist']) as $lb_object_id)
1898 if (!in_array ($lb_object_id, $lblist))
1900 $oi = getObjectInfo ($lb_object_id);
1901 $lbdname[$lb_object_id] = $oi['dname'];
1902 $lblist[] = $lb_object_id;
1904 if (!count ($summary))
1905 echo 'none configured';
1909 echo "<table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
1910 echo "<tr><th>VS ↓ LB →</th>";
1911 foreach ($lblist as $lb_object_id)
1912 echo "<th><a href='${root}?page=object&tab=default&object_id=${lb_object_id}'>" . $lbdname[$lb_object_id] . "</a></th>";
1914 foreach ($summary as $vsid => $vsdata)
1916 echo "<tr class=row_${order}><td class=tdleft><a href='$root?page=vservice&tab=default&id=${vsid}'>";
1917 echo buildVServiceName ($vsdata);
1919 if (!empty ($vsdata['name']))
1920 echo " (${vsdata['name']})";
1922 foreach ($lblist as $lb_object_id)
1924 echo '<td class=tdleft>';
1925 if (!isset ($vsdata['lblist'][$lb_object_id]))
1929 echo $vsdata['lblist'][$lb_object_id]['size'];
1930 echo " (<a href='${root}?page=rspool&pool_id=";
1931 echo $vsdata['lblist'][$lb_object_id]['id'] . "'>";
1932 echo $vsdata['lblist'][$lb_object_id]['name'] . '</a>)';
1937 $order = $nextorder[$order];
1944 function renderAddNewRange ()
1946 global $root, $pageno, $tabno;
1947 showMessageOrError();
1949 startPortlet ("Add New");
1950 echo "<table class='widetable' border=0 cellpadding=10 align='center'>\n";
1951 echo "<tr><th>Address range</th><th>Name</th><th>connected network</th><th>assign tags</th><th> </th></tr>\n";
1952 echo "<form name='add_new_range' action='process.php'>\n";
1953 echo "<input type=hidden name=op value=addRange>\n";
1954 echo "<input type=hidden name=page value='${pageno}'>\n";
1955 echo "<input type=hidden name=tab value='${tabno}'>\n";
1956 echo "<tr valign=top><td class='tdcenter'><input type=text name='range' size=18 class='live-validate' tabindex=1></td>\n";
1957 echo "<td class='tdcenter'><input type=text name='name' size='20' tabindex=2></td>\n";
1958 echo "<td class='tdcenter'><input type=checkbox name='is_bcast' tabindex=3 checked></td>\n";
1962 echo "<td class='tdcenter'><input type=submit value='Add a new range' tabindex=4></td>\n";
1963 echo "</td></tr>\n";
1964 echo "</form></table><br><br>\n";
1967 startPortlet ("Manage Existing");
1968 echo "<table class='widetable' border=0 cellpadding=10 align='center'>\n";
1969 $addrspaceList = getAddressspaceList();
1970 echo "<tr><th> </th><th>Address range</th><th>Name</th><th>Utilization</th></tr>";
1971 foreach ($addrspaceList as $iprange)
1973 $range = getIPRange($iprange['id']);
1974 $usedips = count ($range['addrlist']);
1975 $totalips = ($iprange['ip_bin'] |
$iprange['mask_bin_inv']) - ($iprange['ip_bin'] & $iprange['mask_bin']) +
1;
1979 echo "<a href='process.php?op=delRange&page=${pageno}&tab=${tabno}&id=${iprange['id']}'>";
1980 printImageHREF ('delete', 'Delete this IP range');
1984 printImageHREF ('nodelete', 'There are IP addresses allocated or reserved');
1985 echo "</td>\n<td class=tdleft><a href='${root}?page=iprange&id=${iprange['id']}'>";
1986 echo "${iprange['ip']}/${iprange['mask']}</a></td><td class=tdleft>${iprange['name']}";
1987 echo "</td><td class=tdleft>";
1988 renderProgressBar ($usedips / $totalips);
1989 echo " ${usedips}/${totalips}";
1996 function renderIPRange ($id)
1998 global $root, $pageno, $tabno;
1999 $netmaskbylen = array
2001 32 => '255.255.255.255',
2002 31 => '255.255.255.254',
2003 30 => '255.255.255.252',
2004 29 => '255.255.255.248',
2005 28 => '255.255.255.240',
2006 27 => '255.255.255.224',
2007 26 => '255.255.255.192',
2008 25 => '255.255.255.128',
2009 24 => '255.255.255.0',
2010 23 => '255.255.254.0',
2011 22 => '255.255.252.0',
2012 21 => '255.255.248.0',
2013 20 => '255.255.240.0',
2014 19 => '255.255.224.0',
2015 18 => '255.255.192.0',
2016 17 => '255.255.128.0',
2017 16 => '255.255.0.0',
2018 15 => '255.254.0.0',
2019 14 => '255.252.0.0',
2020 13 => '255.248.0.0',
2021 12 => '255.240.0.0',
2022 11 => '255.224.0.0',
2023 10 => '255.192.0.0',
2034 $wildcardbylen = array
2051 17 => '0.0.127.255',
2053 15 => '0.1.255.255',
2054 14 => '0.3.255.255',
2055 13 => '0.7.255.255',
2056 12 => '0.15.255.255',
2057 11 => '0.31.255.255',
2058 10 => '0.63.255.255',
2059 9 => '0.127.255.255',
2060 8 => '0.255.255.255',
2061 7 => '1.255.255.255',
2062 6 => '3.255.255.255',
2063 5 => '7.255.255.255',
2064 4 => '15.255.255.255',
2065 3 => '31.255.255.255',
2066 2 => '63.255.255.255',
2067 1 => '127.255.255.255'
2069 $maxperpage = getConfigVar ('IPV4_ADDRS_PER_PAGE');
2070 if (isset($_REQUEST['pg']))
2071 $page = $_REQUEST['pg'];
2075 $range = getIPRange($id);
2076 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
2077 echo "<tr><td colspan=2 align=center><h1>${range['ip']}/${range['mask']}</h1><h2>${range['name']}</h2></td></tr>\n";
2079 echo "<tr><td class=pcleft width='50%'>";
2080 startPortlet ('summary');
2081 $total = ($range['ip_bin'] |
$range['mask_bin_inv']) - ($range['ip_bin'] & $range['mask_bin']) +
1;
2082 $used = count ($range['addrlist']);
2083 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
2084 echo "<tr><th width='50%' class=tdright>Utilization:</th><td class=tdleft>";
2085 renderProgressBar ($used/$total);
2086 echo " ${used}/${total}</td></tr>\n";
2087 echo "<tr><th width='50%' class=tdright>Netmask:</th><td class=tdleft>";
2088 echo $netmaskbylen[$range['mask']];
2089 echo "</td></tr>\n";
2090 echo "<tr><th width='50%' class=tdright>Wildcard bits:</th><td class=tdleft>";
2091 echo $wildcardbylen[$range['mask']];
2092 echo "</td></tr>\n";
2094 echo "</table><br>\n";
2098 echo "<td class=pcright>";
2099 startPortlet ('details');
2100 $startip = $range['ip_bin'] & $range['mask_bin'];
2101 $endip = $range['ip_bin'] |
$range['mask_bin_inv'];
2102 $realstartip = $startip;
2103 $realendip = $endip;
2105 if($endip - $startip > $maxperpage)
2107 $numpages = ($endip - $startip)/$maxperpage;
2108 $startip = $startip +
$page * $maxperpage;
2109 $endip = $startip +
$maxperpage-1;
2113 echo '<h3>' . long2ip ($startip) . ' ~ ' . long2ip ($endip) . '</h3>';
2114 for ($i=0; $i<$numpages; $i++
)
2119 echo "<a href='${root}?page=${pageno}&tab=${tabno}&id=$id&pg=$i'>$i</a> ";
2123 echo "<table class='widetable' border=0 cellspacing=0 cellpadding=5 align='center'>\n";
2124 echo "<tr><th>Address</th><th>Name</th><th>Allocation</th></tr>\n";
2127 for($ip = $startip; $ip<=$endip; $ip++
)
2129 if (isset ($range['addrlist'][$ip]))
2131 $numshared = countRefsOfType($range['addrlist'][$ip]['references'], 'shared', 'eq');
2132 $numreg = countRefsOfType($range['addrlist'][$ip]['references'], 'regular', 'eq');
2133 $numvirt = countRefsOfType($range['addrlist'][$ip]['references'], 'virtual', 'eq');
2134 $numlb = count ($range['addrlist'][$ip]['lbrefs']);
2135 $numrs = count ($range['addrlist'][$ip]['rsrefs']);
2137 $addr = $range['addrlist'][$ip];
2138 if ( ($numshared > 0 && $numreg > 0) ||
$numreg > 1 )
2139 echo "<tr class='trerror'>";
2140 elseif ( $addr['reserved'] == 'yes' and $numshared+
$numreg+
$numvirt+
$numlb+
$numrs > 0)
2141 echo "<tr class='trerror'>";
2142 elseif ( $addr['reserved'] == 'yes')
2143 echo "<tr class='trbusy'>";
2144 elseif ( $numshared > 0 ||
$numreg > 0 ||
$numlb > 0 ||
$numrs > 0)
2145 echo "<tr class='trbusy'>";
2149 echo "<td><a href='${root}?page=ipaddress&ip=${addr['ip']}'>${addr['ip']}</a></td><td>${addr['name']}</td><td>";
2152 if ( $addr['reserved'] == 'yes')
2154 echo "<b>Reserved</b> ";
2157 foreach ($range['addrlist'][$ip]['references'] as $ref)
2159 echo "${delim}<a href='${root}?page=object&object_id=${ref['object_id']}'>";
2160 echo $ref['name'] . (empty ($ref['name']) ?
'' : '@');
2161 echo "${ref['object_name']}</a>";
2169 foreach ($range['addrlist'][$ip]['lbrefs'] as $ref)
2173 echo "${delim}<a href='${root}?page=object&object_id=${ref['object_id']}'>";
2174 echo "${ref['object_name']}</a>:<a href='${root}?page=vservice&id=${ref['vs_id']}'>";
2175 echo "${ref['vport']}/${ref['proto']}</a>→";
2183 foreach ($range['addrlist'][$ip]['rsrefs'] as $ref)
2187 echo "${delim}→${ref['rsport']}@<a href='${root}?page=rspool&pool_id=${ref['rspool_id']}'>";
2188 echo "${ref['rspool_name']}</a>";
2191 echo "</td></tr>\n";
2195 echo "<tr><td><a href='${root}?page=ipaddress&ip=".long2ip($ip)."'>".long2ip($ip)."</a></td><td> </td><td> </td></tr>\n";
2201 echo "</td></tr></table>\n";
2204 function renderIPRangeProperties ($id)
2206 global $pageno, $tabno;
2207 showMessageOrError();
2208 $range = getIPRange($id);
2209 echo "<center><h1>${range['ip']}/${range['mask']}</h1></center>\n";
2210 echo "<table border=0 cellpadding=10 cellpadding=1 align='center'>\n";
2211 echo "<form action='process.php'><input type=hidden name=op value=editRange>";
2212 echo "<input type=hidden name=page value='${pageno}'>\n";
2213 echo "<input type=hidden name=tab value='${tabno}'>\n";
2214 echo "<input type=hidden name=id value='${id}'>";
2215 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>";
2220 function renderIPAddress ()
2223 $ip = $_REQUEST['ip'];
2224 $address = getIPAddress($ip);
2225 echo "<center><h1>$ip</h1>";
2226 if ($address['exists'] == 1)
2227 echo "<h2>${address['name']}</h2>";
2230 // echo "<table width='100%' cesspadding=5 cellspacing=0 border=0 align='center'>";
2231 // echo "<tr valign='top'><td>";
2233 $numshared = countRefsOfType($address['bonds'], 'shared', 'eq');
2234 $numreg = countRefsOfType($address['bonds'], 'regular', 'eq');
2235 $numvirt = countRefsOfType($address['bonds'], 'virtual', 'eq');
2237 if ($address['reserved'] == 'yes' or ($numshared +
$numreg +
$numvirt) > 0)
2239 startPortlet ('Allocation');
2240 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
2241 echo "<tr><th>Object name</th><th>Interface name</th><th>Interface type</th></tr>\n";
2242 if ( ($numshared > 0 && $numreg > 0) ||
$numreg > 1 )
2244 elseif ( $address['reserved'] == 'yes' and $numshared+
$numreg+
$numvirt > 0)
2249 if ($address['reserved'] == 'yes')
2250 echo "<tr class='$class'><td colspan='3'><b>RESERVED</b></td></tr>";
2251 foreach ($address['bonds'] as $bond)
2253 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>";
2254 switch ($bond['type'])
2266 echo "</b></td></tr>\n";
2268 echo "</table><br><br>";
2272 if (count ($address['vslist']))
2274 startPortlet ('Virtual services (' . count ($address['vslist']) . ')');
2275 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
2276 echo "<tr><th>VS</th><th>name</th></tr>\n";
2277 foreach ($address['vslist'] as $vsinfo)
2279 echo "<tr><td class=tdleft><a href='${root}?page=vservice&id=${vsinfo['id']}'>";
2280 echo buildVServiceName ($vsinfo) . "</a></td><td class=tdleft>";
2281 echo $vsinfo['name'] . "</td></tr>\n";
2283 echo "</table><br><br>";
2287 if (count ($address['rslist']))
2289 startPortlet ('Real servers (' . count ($address['rslist']) . ')');
2290 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
2291 echo "<tr><th> </th><th>port</th><th>RS pool</th></tr>\n";
2292 foreach ($address['rslist'] as $rsinfo)
2295 if ($rsinfo['inservice'] == 'yes')
2296 printImageHREF ('inservice', 'in service');
2298 printImageHREF ('notinservice', 'NOT in service');
2299 echo "</td><td class=tdleft>${rsinfo['rsport']}</td><td class=tdleft><a href='${root}?page=rspool&pool_id=${rsinfo['pool_id']}'>";
2300 echo $rsinfo['poolname'] . "</a></td></tr>\n";
2302 echo "</table><br><br>";
2307 // echo "</td><td>";
2308 // echo "</td></tr></table>";
2311 function renderIPAddressProperties ()
2313 global $pageno, $tabno;
2314 $ip = $_REQUEST['ip'];
2315 showMessageOrError();
2316 $address = getIPAddress($ip);
2317 echo "<center><h1>$ip</h1></center>\n";
2318 echo "<table border=0 cellpadding=10 cellpadding=1 align='center'>\n";
2319 echo "<form action='process.php'><input type=hidden name=op value=editAddress>";
2320 echo "<input type=hidden name=page value='${pageno}'>\n";
2321 echo "<input type=hidden name=tab value='${tabno}'>\n";
2322 echo "<input type=hidden name=ip value='${ip}'>";
2323 echo "<tr><td class='tdright'>Name:</td><td class='tdleft'><input type=text name=name size=20 value='".($address['exists']==1?
$address['name']:'')."'></tr>";
2324 echo "<td class='tdright'>Reserved:</td><td class='tdleft'><input type=checkbox name=reserved size=20 ".($address['exists']==1?
(($address['reserved']=='yes')?
'checked':''):'')."></tr>";
2325 echo "<tr><td colspan=2 class='tdcenter'><input type=submit value='Update address'></td></form></tr>";
2330 function renderIPAddressAssignment ()
2332 global $pageno, $tabno, $root;
2333 $ip = $_REQUEST['ip'];
2334 $address = getIPAddress($ip);
2336 showMessageOrError();
2337 echo "<center><h1>$ip</h1></center>\n";
2340 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
2341 echo "<tr><th> </th><th>Object name</th><th>Interface name</th><th>Interface type</th><th> </th></tr>\n";
2343 $numshared = countRefsOfType($address['bonds'], 'shared', 'eq');
2344 $numreg = countRefsOfType($address['bonds'], 'regular', 'eq');
2345 $numvirt = countRefsOfType($address['bonds'], 'virtual', 'eq');
2348 if ( ($numshared > 0 && $numreg > 0) ||
$numreg > 1 )
2350 elseif ( $address['reserved'] == 'yes' and $numshared+
$numreg+
$numvirt > 0)
2357 if ($address['reserved'] == 'yes')
2358 echo "<tr class='$class'><td colspan='5'><b>RESERVED</b></td></tr>";
2359 foreach ($address['bonds'] as $bond)
2361 echo "<tr class='$class'><form action='process.php'>";
2362 echo "<input type=hidden name=op value='editBondForAddress'>";
2363 echo "<input type=hidden name=page value='${pageno}'>";
2364 echo "<input type=hidden name=tab value='${tabno}'>";
2365 echo "<input type=hidden name=ip value='$ip'>";
2366 echo "<input type=hidden name=object_id value='${bond['object_id']}'>";
2367 echo "<td><a href='process.php?op=delIpAssignment&page=${pageno}&tab=${tabno}&ip=$ip&object_id=${bond['object_id']}'>";
2368 printImageHREF ('delete', 'Unallocate address');
2370 echo "<td><a href='${root}?page=object&object_id=${bond['object_id']}'>${bond['object_name']}</td>";
2371 echo "<td><input type='text' name='bond_name' value='${bond['name']}' size=10></td>";
2372 echo "<td><select name='bond_type'>";
2373 switch ($bond['type'])
2376 echo "<option value='regular'>Regular</option>";
2377 echo "<option value='virtual' selected>Virtual</option>";
2378 echo "<option value='shared'>Shared</option>";
2381 echo "<option value='regular'>Regular</option>";
2382 echo "<option value='virtual'>Virtual</option>";
2383 echo "<option value='shared' selected>Shared</option>";
2386 echo "<option value='regular' selected>Regular</option>";
2387 echo "<option value='virtual'>Virtual</option>";
2388 echo "<option value='shared'>Shared</option>";
2391 echo "</select></td><td><input type='submit' value='OK'></td></form></tr>\n";
2393 echo "<form action='process.php'><input type='hidden' name='op' value='bindObjectToIp'>";
2394 echo "<input type=hidden name=page value='${pageno}'>\n";
2395 echo "<input type=hidden name=tab value='${tabno}'>\n";
2396 echo "<input type='hidden' name='ip' value='$ip'>";
2397 echo "<td colspan=2><select name='object_id'>";
2399 foreach (explode (',', getConfigVar ('IPV4_PERFORMERS')) as $type)
2400 foreach (getObjectList ($type) as $object)
2401 echo "<option value='${object['id']}'>${object['dname']}</option>";
2403 echo "</select></td><td><input type='text' name='bond_name' value='' size=10></td>";
2404 echo "<td><select name='bond_type'><option value='regular'>Regular</option><option value='virtual'>Virtual</option><option value='shared'>Shared</option></select></td>";
2405 echo "<td><input type='submit' value='Assign address'></td></form></tr>";
2406 echo "</table><br><br>";
2410 function renderNATv4ForObject ($object_id = 0)
2412 global $pageno, $tabno, $root;
2414 $info = getObjectInfo ($object_id);
2415 $forwards = getNATv4ForObject ($object_id);
2416 $addresses = getObjectAddresses ($object_id);
2417 showMessageOrError();
2418 echo "<center><h2>locally performed NAT</h2></center>";
2420 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
2421 echo "<tr><th></th><th>Match endpoint</th><th>Translate to</th><th>Target object</th><th>Comment</th></tr>\n";
2423 foreach ($forwards['out'] as $pf)
2427 foreach ($addresses as $addr)
2428 if ($addr['ip'] == $pf['localip'])
2431 $name = $addr['name'];
2435 echo "<tr class='$class'>";
2436 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}'>";
2437 printImageHREF ('delete', 'Delete NAT rule');
2439 echo "<td>${pf['proto']}/${name}: <a href='${root}?page=ipaddress&tab=default&ip=${pf['localip']}'>${pf['localip']}</a>:${pf['localport']}";
2440 if (!empty ($pf['local_addr_name']))
2441 echo ' (' . $pf['local_addr_name'] . ')';
2443 echo "<td><a href='${root}?page=ipaddress&tab=default&ip=${pf['remoteip']}'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
2445 $address=getIPAddress($pf['remoteip']);
2447 echo "<td class='description'>";
2448 if (count ($address['bonds']))
2449 foreach($address['bonds'] as $bond)
2450 echo "<a href='${root}?page=object&tab=default&object_id=${bond['object_id']}'>${bond['object_name']}(${bond['name']})</a> ";
2451 elseif (!empty ($pf['remote_addr_name']))
2452 echo '(' . $pf['remote_addr_name'] . ')';
2453 echo "</td><form action='process.php'><input type='hidden' name='op' value='updPortForwarding'><input type=hidden name=page value='${pageno}'>";
2454 echo "<input type=hidden name=tab value='${tabno}'><input type='hidden' name='object_id' value='$object_id'>";
2455 echo "<input type='hidden' name='localip' value='${pf['localip']}'><input type='hidden' name='localport' value='${pf['localport']}'>";
2456 echo "<input type='hidden' name='remoteip' value='${pf['remoteip']}'><input type='hidden' name='remoteport' value='${pf['remoteport']}'>";
2457 echo "<input type='hidden' name='proto' value='${pf['proto']}'><td class='description'>";
2458 echo "<input type='text' name='description' value='${pf['description']}'> <input type='submit' value='OK'></td></form>";
2461 echo "<form action='process.php'><input type='hidden' name='op' value='forwardPorts'>";
2462 echo "<input type='hidden' name='object_id' value='$object_id'>";
2463 echo "<input type=hidden name=page value='${pageno}'>\n";
2464 echo "<input type=hidden name=tab value='${tabno}'>\n";
2465 echo "<tr align='center'><td colspan=2>";
2466 printSelect (array ('TCP' => 'TCP', 'UDP' => 'UDP'), 'proto');
2467 echo "<select name='localip' tabindex=1>";
2469 foreach ($addresses as $addr)
2470 echo "<option value='${addr['ip']}'>" . (empty ($addr['name']) ?
'' : "${addr['name']}: ") .
2471 "${addr['ip']}" . (empty ($addr['address_name']) ?
'' : " (${addr['address_name']})") . "</option>";
2473 echo "</select>:<input type='text' name='localport' size='4' tabindex=2></td>";
2474 echo "<td><input type='text' name='remoteip' id='remoteip' size='10' tabindex=3>";
2475 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\");'>";
2476 printImageHREF ('find', 'Find object');
2478 echo ":<input type='text' name='remoteport' size='4' tabindex=4></td><td></td>";
2479 echo "<td colspan=1><input type='text' name='description' size='20' tabindex=5> <input type='submit' value='Create Forwarding' tabindex=6></td></tr>";
2482 echo "</table><br><br>";
2484 echo "<center><h2>arriving NAT connections</h2></center>";
2485 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
2486 echo "<tr><th></th><th>Source</th><th>Source objects</th><th>Target</th><th>Description</th></tr>\n";
2488 foreach ($forwards['in'] as $pf)
2490 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}'>";
2491 printImageHREF ('delete', 'Delete NAT rule');
2493 echo "<td>${pf['proto']}/<a href='${root}?page=ipaddress&tab=default&ip=${pf['localip']}'>${pf['localip']}</a>:${pf['localport']}</td>";
2494 echo "<td class='description'><a href='${root}?page=object&tab=default&object_id=${pf['object_id']}'>${pf['object_name']}</a>";
2495 echo "</td><td><a href='${root}?page=ipaddress&tab=default&ip=${pf['remoteip']}'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
2496 echo "<td class='description'>${pf['description']}</td></tr>";
2499 echo "</table><br><br>";
2503 function renderAddMultipleObjectsForm ()
2505 global $root, $pageno, $tabno, $nextorder;
2508 $global_type_id = 0;
2510 $asset_no = array();
2511 $keepvalues = FALSE;
2513 // Look for current submit.
2514 if (isset ($_REQUEST['got_fast_data']))
2517 $max = getConfigVar ('MASSCOUNT');
2518 for ($i = 0; $i < $max; $i++
)
2520 if (!isset ($_REQUEST["${i}_object_type_id"]))
2522 $log[] = array ('code' => 'error', 'message' => "Submitted form is invalid at line " . $i +
1);
2525 assertUIntArg ("${i}_object_type_id", __FUNCTION__
, TRUE);
2526 assertStringArg ("${i}_object_name", __FUNCTION__
, TRUE);
2527 assertStringArg ("${i}_object_label", __FUNCTION__
, TRUE);
2528 assertStringArg ("${i}_object_asset_no", __FUNCTION__
, TRUE);
2529 assertStringArg ("${i}_object_barcode", __FUNCTION__
, TRUE);
2530 $type_id[$i] = $_REQUEST["${i}_object_type_id"];
2531 // Save user input for possible rendering.
2532 $name[$i] = $_REQUEST["${i}_object_name"];
2533 $label[$i] = $_REQUEST["${i}_object_label"];
2534 $asset_no[$i] = $_REQUEST["${i}_object_asset_no"];
2535 $barcode[$i] = $_REQUEST["${i}_object_barcode"];
2537 // It's better to skip silently than printing a notice.
2538 if ($type_id[$i] == 0)
2540 if (commitAddObject ($name[$i], $label[$i], $barcode[$i], $type_id[$i], $asset_no[$i]) === TRUE)
2541 $log[] = array ('code' => 'success', 'message' => "Added new object '${name[$i]}'");
2543 $log[] = array ('code' => 'error', 'message' => __FUNCTION__
. ': commitAddObject() failed');
2546 elseif (isset ($_REQUEST['got_very_fast_data']))
2549 assertUIntArg ('global_type_id', __FUNCTION__
, TRUE);
2550 assertStringArg ('namelist', __FUNCTION__
, TRUE);
2551 $global_type_id = $_REQUEST['global_type_id'];
2552 if ($global_type_id == 0)
2554 if (!empty ($_REQUEST['namelist']))
2555 $log[] = array ('code' => 'error', 'message' => 'Object type is not selected, check the form below');
2557 $log[] = array ('code' => 'error', 'message' => 'Empty form has been ignored. Cheers.');
2561 // The name extractor below was stolen from ophandlers.php:addMultiPorts()
2562 $names1 = explode ('\n', $_REQUEST['namelist']);
2564 foreach ($names1 as $line)
2566 $parts = explode ('\r', $line);
2568 if (empty ($parts[0]))
2571 $names2[] = rtrim ($parts[0]);
2573 foreach ($names2 as $cname)
2574 if (commitAddObject ($cname, '', '', $global_type_id, '') === TRUE)
2575 $log[] = array ('code' => 'success', 'message' => "Added new object '${cname}'");
2577 $log[] = array ('code' => 'error', 'message' => "Could not add '${cname}'");
2582 // Render a form for the next.
2583 $typelist = getObjectTypeList();
2584 $typelist[0] = 'select type...';
2586 startPortlet ('Fast way');
2587 echo "<form name=fastform method=post action='${root}?page=${pageno}&tab=${tabno}'>";
2588 echo '<table border=0 align=center>';
2589 echo "<tr><th>Object type</th><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>Barcode</th></tr>\n";
2590 // If a user forgot to select object type on input, we keep his
2591 // previous input in the form.
2592 $max = getConfigVar ('MASSCOUNT');
2593 for ($i = 0; $i < $max; $i++
)
2596 // Don't employ DEFAULT_OBJECT_TYPE to avoid creating ghost records for pre-selected empty rows.
2597 printSelect ($typelist, "${i}_object_type_id", 0);
2599 echo "<td><input type=text size=30 name=${i}_object_name";
2600 if ($keepvalues and $type_id[$i] == 0)
2601 echo " value='${name[$i]}'";
2603 echo "<td><input type=text size=30 name=${i}_object_label";
2604 if ($keepvalues and $type_id[$i] == 0)
2605 echo " value='${label[$i]}'";
2607 echo "<td><input type=text size=20 name=${i}_object_asset_no";
2608 if ($keepvalues and $type_id[$i] == 0)
2609 echo " value='${asset_no[$i]}'";
2611 echo "<td><input type=text size=10 name=${i}_object_barcode";
2612 if ($keepvalues and $type_id[$i] == 0)
2613 echo " value='${barcode[$i]}'";
2617 echo "<tr><td class=submit colspan=5><input type=submit name=got_fast_data value='Create'></td></tr>\n";
2618 echo "</form></table>\n";
2621 startPortlet ('Very fast way');
2622 echo "<form name=veryfastform method=post action='${root}?page=${pageno}&tab=${tabno}'>";
2623 echo 'For each line shown below create an object of type ';
2624 printSelect ($typelist, "global_type_id", getConfigVar ('DEFAULT_OBJECT_TYPE'));
2625 echo " <input type=submit name=got_very_fast_data value='Go!'><br>\n";
2626 echo "<textarea name=namelist cols=40 rows=25>\n";
2627 if ($keepvalues and $global_type_id == 0)
2628 echo $_REQUEST['namelist'];
2629 echo "</textarea></form>\n";
2633 function printGreeting ()
2635 global $remote_username, $accounts, $root;
2636 $account = $accounts[$remote_username];
2637 echo "Hello, ${account['user_realname']}. This is RackTables " . CODE_VERSION
. ". Click <a href='${root}?logout'>here</a> to logout.";
2640 function renderSearchResults ()
2642 global $remote_username, $root;
2643 $terms = trim ($_REQUEST['q']);
2646 showError ('Search string cannot be empty.', __FUNCTION__
);
2649 if (!authorized ($remote_username, 'object', 'default'))
2651 showError ('You are not authorized for viewing information about objects.', __FUNCTION__
);
2655 // If we search for L2 address, we can either find one or find none.
2658 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
2659 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
2660 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
2661 // STP bridge ID: bridge priotity + port MAC address. Cut off first 4 chars and look for MAC address.
2662 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)
2664 // Search for L2 address.
2666 $terms = substr ($terms, -12);
2667 $result = searchByl2address ($terms);
2668 if ($result !== NULL)
2672 $summary['port'][] = $result;
2675 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))
2676 // Search for IP address.
2678 $result = getRangeByIp ($terms);
2679 if ($result !== NULL)
2682 $lasthit = 'ipv4address1';
2683 $summary['ipv4address1'][] = $terms;
2687 // Search for objects, addresses, networks, virtual services and RS pools by their description.
2689 $tmp = getObjectSearchResults ($terms);
2692 $nhits +
= count ($tmp);
2693 $lasthit = 'object';
2694 $summary['object'] = $tmp;
2696 $tmp = getIPv4AddressSearchResult ($terms);
2699 $nhits +
= count ($tmp);
2700 $lasthit = 'ipv4address2';
2701 $summary['ipv4address2'] = $tmp;
2703 $tmp = getIPv4PrefixSearchResult ($terms);
2706 $nhits +
= count ($tmp);
2707 $lasthit = 'ipv4network';
2708 $summary['ipv4network'] = $tmp;
2712 echo "<center><h2>Nothing found for '${terms}'</h2></center>";
2713 elseif ($nhits == 1)
2715 $record = current ($summary[$lasthit]);
2719 echo "<script language='Javascript'>document.location='${root}?page=object";
2720 echo "&hl_port_id=" . $record['port_id'];
2721 echo "&object_id=" . $record['object_id'] . "';//</script>";
2723 case 'ipv4address1':
2724 echo "<script language='Javascript'>document.location='${root}?page=ipaddress";
2725 echo "&ip=${record}";
2726 echo "';//</script>";
2728 case 'ipv4address2':
2729 echo "<script language='Javascript'>document.location='${root}?page=ipaddress";
2730 echo "&ip=${record}";
2731 echo "';//</script>";
2734 echo "<script language='Javascript'>document.location='${root}?page=iprange";
2735 echo "&id=${record['id']}";
2736 echo "';//</script>";
2739 echo "<script language='Javascript'>document.location='${root}?page=object&object_id=${record['id']}';//</script>";
2748 echo "<center><h2>${nhits} result(s) found for '${terms}'</h2></center>";
2749 foreach ($summary as $where => $what)
2753 startPortlet ('Objects');
2754 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
2755 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>barcode</th></tr>';
2756 foreach ($what as $obj)
2758 echo "<tr class=row_${order}><td><a href=\"${root}?page=object&object_id=${obj['id']}\">${obj['dname']}</a></td>";
2759 echo "<td>${obj['label']}</td>";
2760 echo "<td>${obj['asset_no']}</td>";
2761 echo "<td>${obj['barcode']}</td></tr>";
2762 $order = $nextorder[$order];
2768 startPortlet ('IPv4 networks');
2769 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
2770 echo '<tr><th>Network</th><th>Descritpion</th></tr>';
2771 foreach ($what as $net)
2773 echo "<tr class=row_${order}><td class=tdleft><a href='${root}?page=iprange&id=${net['id']}'>${net['ip']}";
2774 echo '/' . $net['mask'] . '</a></td>';
2775 echo "<td class=tdleft>${net['name']}</td></tr>";
2776 $order = $nextorder[$order];
2781 case 'ipv4address2':
2782 startPortlet ('IPv4 addresses');
2783 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
2784 echo '<tr><th>Address</th><th>Descritpion</th></tr>';
2785 foreach ($what as $addr)
2787 echo "<tr class=row_${order}><td class=tdleft><a href='${root}?page=ipaddress&ip=${addr['ip']}'>";
2788 echo "${addr['ip']}</a></td>";
2789 echo "<td class=tdleft>${addr['name']}</td></tr>";
2790 $order = $nextorder[$order];
2799 // This function prints a table of checkboxes to aid the user in toggling mount atoms
2800 // from one state to another. The first argument is rack data as
2801 // produced by getRackData(), the second is the value used for the 'unckecked' state
2802 // and the third is the value used for 'checked' state.
2804 // for mounting an object: printAtomGrid ($data, 'F', 'T')
2805 // for changing rack design: printAtomGrid ($data, 'A', 'F')
2806 // for adding rack problem: printAtomGrid ($data, 'F', 'U')
2807 // for adding object problem: printAtomGrid ($data, 'T', 'W')
2809 function renderAtomGrid ($data)
2811 $rack_id = $data['id'];
2812 for ($unit_no = $data['height']; $unit_no > 0; $unit_no--)
2814 echo "<tr><th>${unit_no}</th>";
2815 for ($locidx = 0; $locidx < 3; $locidx++
)
2817 $state = $data[$unit_no][$locidx]['state'];
2818 echo "<td class=state_${state}";
2819 if (isset ($data[$unit_no][$locidx]['hl']))
2820 echo $data[$unit_no][$locidx]['hl'];
2822 if (!($data[$unit_no][$locidx]['enabled'] === TRUE))
2823 echo '<input type=checkbox disabled>';
2825 echo "<input type=checkbox" . $data[$unit_no][$locidx]['checked'] . " name=atom_${rack_id}_${unit_no}_${locidx}>";
2832 function renderPermissions ()
2834 startPortlet ('User permissions');
2835 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
2836 echo "<tr><th>Username</th><th>Page</th><th>Tab</th><th>Access</th></tr>";
2837 global $perms, $nextorder;
2839 foreach ($perms as $username => $pages)
2840 foreach ($pages as $page => $tabs)
2841 foreach ($tabs as $tab => $access)
2843 echo "<tr class=row_${order}><td class=tdleft>$username</td><td>$page</td><td>$tab</td><td>$access</td></tr>\n";
2844 $order = $nextorder[$order];
2850 function renderAccounts ()
2852 global $nextorder, $accounts;
2853 startPortlet ('User accounts');
2854 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
2855 echo "<tr><th class=tdleft>Username</th><th class=tdleft>Real name</th></tr>";
2857 foreach ($accounts as $user)
2859 echo "<tr class=row_${order}><td class=tdleft><div title='\$userid_${user['user_id']}'>";
2860 echo "${user['user_name']}</div></td>";
2861 echo "<td class=tdleft>${user['user_realname']}</td></li>";
2862 $order = $nextorder[$order];
2868 function renderAccountsEditForm ()
2870 global $root, $pageno, $tabno, $accounts;
2871 startPortlet ('User accounts');
2872 showMessageOrError();
2873 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
2874 echo "<tr><th>op</th><th>Username</th><th>Real name</th><th>Password</th><th> </th></tr>\n";
2875 foreach ($accounts as $account)
2877 echo "<form action='${root}process.php'>";
2878 echo "<input type=hidden name=op value=updateAccount>";
2879 echo "<input type=hidden name=page value='${pageno}'>\n";
2880 echo "<input type=hidden name=tab value='${tabno}'>\n";
2881 echo "<input type=hidden name=id value='${account['user_id']}'><tr>";
2883 if ($account['user_enabled'] == 'yes' && $account['user_id'] != 1)
2885 echo "<a href='${root}process.php?op=disableAccount&page=${pageno}&tab=${tabno}&id=${account['user_id']}'>";
2886 printImageHREF ('blockuser', 'disable account');
2889 if ($account['user_enabled'] == 'no' && $account['user_id'] != 1)
2891 echo "<a href='${root}process.php?op=enableAccount&page=${pageno}&tab=${tabno}&id=${account['user_id']}'>";
2892 printImageHREF ('unblockuser', 'enable account');
2895 // Otherwise skip icon.
2897 echo "<td><input type=text name=username value='${account['user_name']}' size=16></td>";
2898 echo "<td><input type=text name=realname value='${account['user_realname']}' size=24></td>";
2899 echo "<td><input type=password name=password value='${account['user_password_hash']}' size=64></td>";
2900 echo "<td><input type='submit' value='OK'></td>";
2901 echo "</form></tr>\n";
2903 echo "<form action='${root}process.php' method=post><tr>";
2904 echo "<input type=hidden name=op value=createAccount>\n";
2905 echo "<input type=hidden name=page value='${pageno}'>\n";
2906 echo "<input type=hidden name=tab value='${tabno}'>\n";
2907 echo "<td colspan=2><input type=text size=16 name=username tabindex=100></td>\n";
2908 echo "<td><input type=text size=24 name=realname tabindex=101></td>";
2909 echo "<td><input type=password size=64 name=password tabindex=102></td>";
2910 echo "<td colspan=4><input type=submit value='Create account' tabindex=103></td></tr></form>";
2911 echo "</table><br>\n";
2915 function printChildrenAsOptions ($root, $depth = 0)
2917 echo "<option value=${root['title']}>";
2920 for ($i = 0; $i < $depth; $i++
)
2922 echo $root['title'];
2924 foreach ($root['kids'] as $kid)
2925 printChildrenAsOptions ($kid, $depth +
1);
2928 // 1. Find all parentless pages.
2929 // 2. For each of them recursively find all children.
2930 // 3. Output the tree with recursion tree display.
2931 function printPagesTree ()
2935 foreach ($page as $ctitle => $cpage)
2936 if (!isset ($cpage['parent']))
2938 $croot['title'] = $ctitle;
2939 $croot['kids'] = getAllChildPages ($ctitle);
2940 printChildrenAsOptions ($croot);
2945 function renderPermissionsEditForm ()
2947 global $root, $pageno, $tabno, $perms, $accounts;
2948 startPortlet ('User permissions');
2949 showMessageOrError();
2950 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
2951 echo "<tr><th> </th><th>Username</th><th>Page</th><th>Tab</th><th>Access</th></tr>\n";
2952 foreach ($perms as $username => $pages)
2953 foreach ($pages as $access_page => $tabs)
2954 foreach ($tabs as $access_tab => $access)
2957 if ($username != '%')
2958 $userid = $accounts[$username]['user_id'];
2961 echo "<a href='${root}process.php?op=revoke&page=${pageno}&tab=${tabno}&access_userid=${userid}&access_page=${access_page}&access_tab=${access_tab}'>";
2962 printImageHREF ('revoke', 'Revoke permission');
2964 echo "<td>${username}</td>";
2965 echo "<td>${access_page}</td>";
2966 echo "<td>${access_tab}</td>";
2967 echo "<td>${access}</td>";
2970 echo "<form action='${root}process.php' method=post><tr>";
2971 echo "<input type=hidden name=op value=grant>\n";
2972 echo "<input type=hidden name=page value='${pageno}'>\n";
2973 echo "<input type=hidden name=tab value='${tabno}'>\n";
2974 // FIXME: border=0 doesn't work here for unknown reason
2976 printImageHREF ('grant', '', TRUE, 103);
2978 echo "<td><select name=access_userid>";
2979 echo "<option value=0>ANY</option>";
2980 foreach ($accounts as $account)
2981 echo "<option value=${account['user_id']}>${account['user_name']}</option>";
2982 echo "</select></td>\n";
2983 echo "<td><select name=access_page>";
2984 echo "<option value='%'>ANY</option>";
2986 echo "</select></td>";
2987 echo "<td><input type=text size=16 name=access_tab tabindex=102 value=default></td>";
2988 echo "<td><input type=radio name=access_value value=no checked>no <input type=radio name=access_value value=yes>yes</td>";
2989 echo "</tr></form>";
2990 echo "</table><br>\n";
2994 function renderPortMapViewer ()
2996 renderPortMap (FALSE);
2999 function renderPortMapEditor ()
3001 renderPortMap (TRUE);
3004 function renderPortMap ($editable = FALSE)
3006 global $nextorder, $root, $pageno, $tabno;
3007 showMessageOrError();
3008 startPortlet ("Port compatibility map");
3009 $ptlist = getPortTypes();
3010 $pclist = getPortCompat();
3011 $pctable = buildPortCompatMatrixFromList ($ptlist, $pclist);
3014 echo "<form method=post action='${root}process.php'>";
3015 echo "<input type=hidden name=page value='${pageno}'>";
3016 echo "<input type=hidden name=tab value='${tabno}'>";
3017 echo "<input type=hidden name=op value=save>";
3019 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
3020 echo "<tr><th class=vert_th> </th>";
3021 foreach ($ptlist as $name2)
3022 echo "<th>to ${name2}</th>";
3024 // Make a copy to have an independent array pointer.
3027 foreach ($ptlistY as $type1 => $name1)
3029 echo "<tr class=row_${order}><th class=vert_th style='border-bottom: 0px;'>from $name1</th>";
3030 foreach ($ptlist as $type2 => $name2)
3032 echo '<td><input type=checkbox' . ($editable ?
" name=atom_${type1}_${type2}" : ' disabled');
3033 echo ($pctable[$type1][$type2] ?
' checked' : '') . '></td>';
3036 $order = $nextorder[$order];
3038 echo '</table><br>';
3041 echo "<input type=submit value='Save changes'>";
3047 function renderConfigMainpage ()
3049 global $pageno, $root;
3050 $children = getDirectChildPages ($pageno);
3052 // FIXME: assume all config kids to have static titles at the moment,
3053 // but use some proper abstract function later.
3054 foreach ($children as $cpageno => $child)
3055 echo "<li><a href='${root}?page=${cpageno}'>" . $child['title'] . "</li>\n";
3060 function renderRackPage ($rack_id)
3064 showError ('Invalid rack_id', __FUNCTION__
);
3067 if (($rackData = getRackData ($rack_id)) == NULL)
3069 showError ('getRackData() failed', __FUNCTION__
);
3072 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0><tr>";
3074 // Left column with information.
3075 echo "<td class=pcleft>";
3076 startPortlet ('Rack information');
3077 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
3078 echo "<tr><th width='50%' class=tdright>Rack row:</th><td class=tdleft>${rackData['row_name']}</td></tr>\n";
3079 echo "<tr><th width='50%' class=tdright>Name:</th><td class=tdleft>${rackData['name']}</td></tr>\n";
3080 echo "<tr><th width='50%' class=tdright>Height:</th><td class=tdleft>${rackData['height']}</td></tr>\n";
3081 echo "<tr><th width='50%' class=tdright>Utilization:</th><td class=tdleft>";
3082 renderProgressBar (getRSUforRack ($rackData));
3083 echo "</td></tr>\n";
3084 echo "<tr><th width='50%' class=tdright>Objects:</th><td class=tdleft>";
3085 echo getObjectCount ($rackData);
3086 echo "</td></tr>\n";
3088 if (!empty ($rackData['comment']))
3089 echo "<tr><th width='50%' class=tdright>Comment:</th><td class=tdleft>${rackData['comment']}</td></tr>\n";
3094 // Right column with rendered rack.
3096 startPortlet ('Rack diagram');
3097 renderRack ($rack_id);
3101 echo '</tr></table>';
3104 function renderDictionary ()
3107 $dict = getDict (TRUE);
3108 echo "<br><table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
3109 foreach ($dict as $chapter_no => $chapter)
3112 echo "<tr><th>Chapter</th><th>refs</th><th>Word</th></tr>\n";
3113 $wc = count ($chapter['word']);
3114 echo "<tr class=row_${order}><td class=tdleft" . ($wc ?
" rowspan = ${wc}" : '');
3115 echo "><div title='number=${chapter_no}'>${chapter['name']} (${wc} records)</div></td>";
3117 echo "<td colspan=2>none</td>";
3121 foreach ($chapter['word'] as $key => $value)
3124 echo "<tr class=row_${order}>";
3126 $chap_start = FALSE;
3127 echo '<td>' . ($chapter['refcnt'][$key] ?
$chapter['refcnt'][$key] : ' ') . '</td>';
3128 echo "<td><div title='key=${key}'>${value}</div></td></tr>\n";
3129 $order = $nextorder[$order];
3133 echo "</table>\n<br>";
3136 function renderDictionaryEditor ()
3138 global $root, $pageno, $tabno, $nextorder;
3140 showMessageOrError();
3141 echo "<br><table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
3142 foreach ($dict as $chapter_no => $chapter)
3145 echo "<tr><th>Chapter</th><th> </th><th>Word</th><th> </th></tr>\n";
3146 $wc = count ($chapter['word']);
3147 // One extra span for the new record per each chapter block.
3148 echo "<tr class=row_${order}><td class=tdleft" . ($wc ?
' rowspan = ' . ($wc +
1) : '');
3149 echo "><div title='number=${chapter_no}'>${chapter['name']} (${wc} records)</div></td>";
3150 echo "<form action='${root}process.php' method=post>";
3151 echo "<input type=hidden name=page value='${pageno}'>";
3152 echo "<input type=hidden name=tab value='${tabno}'>";
3153 echo "<input type=hidden name=op value=add>";
3154 echo "<input type=hidden name=chapter_no value='${chapter['no']}'>";
3155 echo "<td> </td>";
3156 echo "<td class=tdright><input type=text name=dict_value size=32></td>";
3157 echo "<td><input type=submit value='Add new'></td>";
3158 echo '</tr></form>';
3159 $order = $nextorder[$order];
3160 foreach ($chapter['word'] as $key => $value)
3162 echo "<form action='${root}process.php' method=post>";
3163 echo "<input type=hidden name=page value='${pageno}'>";
3164 echo "<input type=hidden name=tab value='${tabno}'>";
3165 echo "<input type=hidden name=op value='upd'>";
3166 echo "<input type=hidden name=chapter_no value='${chapter['no']}'>";
3167 echo "<input type=hidden name=dict_key value='${key}'>";
3168 echo "<tr class=row_${order}><td>";
3169 // Prevent deleting words currently used somewhere.
3170 if ($chapter['refcnt'][$key])
3171 printImageHREF ('nodelete', 'referenced ' . $chapter['refcnt'][$key] . ' time(s)');
3174 echo "<a href='${root}process.php?page=${pageno}&tab=${tabno}&op=del&chapter_no=${chapter['no']}&dict_key=${key}'>";
3175 printImageHREF ('delete', 'Delete word');
3179 echo "<td class=tdright><input type=text name=dict_value size=32 value='${value}'></td>";
3180 echo "<td><input type=submit value=OK></td>";
3181 echo "</tr></form>\n";
3182 $order = $nextorder[$order];
3183 } // foreach ($chapter['word']
3188 // We don't allow to rename/delete a sticky chapter and we don't allow
3189 // to delete a non-empty chapter.
3190 function renderChaptersEditor ()
3192 global $root, $pageno, $tabno;
3193 showMessageOrError();
3195 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
3196 echo '<tr><th> </th><th>Chapter name</th><th>Words</th><th> </th></tr>';
3197 foreach ($dict as $chapter)
3199 $wordcount = count ($chapter['word']);
3200 $sticky = $chapter['sticky'];
3201 echo "<form action='${root}process.php' method=post>";
3202 echo "<input type=hidden name=page value='${pageno}'>";
3203 echo "<input type=hidden name=tab value='${tabno}'>";
3204 echo "<input type=hidden name=op value=upd>";
3205 echo "<input type=hidden name=chapter_no value='${chapter['no']}'>";
3209 printImageHREF ('nodelete', 'system chapter');
3210 elseif ($wordcount > 0)
3211 printImageHREF ('nodelete', 'contains ' . $wordcount . ' word(s)');
3214 echo "<a href='${root}process.php?page=${pageno}&tab=${tabno}&op=del&chapter_no=${chapter['no']}'>";
3215 printImageHREF ('delete', 'Remove chapter');
3219 echo "<td><input type=text name=chapter_name value='${chapter['name']}'" . ($sticky ?
' disabled' : '') . "></td>";
3220 echo "<td class=tdleft>${wordcount}</td><td>";
3224 echo "<input type=submit value='OK'>";
3228 echo "<form action='${root}process.php' method=post>";
3229 echo "<input type=hidden name=page value='${pageno}'>";
3230 echo "<input type=hidden name=tab value='${tabno}'>";
3231 echo "<input type=hidden name=op value=add>";
3233 printImageHREF ('add', '', TRUE);
3234 echo "</td><td colspan=3><input type=text name=chapter_name></td>";
3240 function renderAttributes ()
3243 $attrMap = getAttrMap();
3244 startPortlet ('Optional attributes');
3245 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
3246 echo "<tr><th class=tdleft>Attribute name</th><th class=tdleft>Attribute type</th><th class=tdleft>Applies to</th></tr>";
3248 foreach ($attrMap as $attr)
3250 echo "<tr class=row_${order}>";
3251 echo "<td class=tdleft>${attr['name']}</td>";
3252 echo "<td class=tdleft>${attr['type']}</td>";
3253 echo '<td class=tdleft>';