4 * This file contains frontend functions for RackTables.
8 // Interface function's special.
9 $nextorder['odd'] = 'even';
10 $nextorder['even'] = 'odd';
12 // address allocation type
15 'regular' => 'Connected',
16 'virtual' => 'Loopback',
20 // address allocation code, IPv4 addresses and objects view
24 'virtual' => '<strong>L</strong>',
25 'shared' => '<strong>S</strong>',
26 'router' => '<strong>R</strong>',
28 // address allocation code, IPv4 networks view
32 'virtual' => '<strong>L:</strong>',
33 'shared' => '<strong>S:</strong>',
34 'router' => '<strong>R:</strong>',
37 // Let's have it here, so extensions can add their own images.
39 $image['error']['path'] = 'pix/error.png';
40 $image['error']['width'] = 76;
41 $image['error']['height'] = 17;
42 $image['logo']['path'] = 'pix/defaultlogo.png';
43 $image['logo']['width'] = 210;
44 $image['logo']['height'] = 40;
45 $image['rackspace']['path'] = 'pix/racks.png';
46 $image['rackspace']['width'] = 218;
47 $image['rackspace']['height'] = 200;
48 $image['objects']['path'] = 'pix/server.png';
49 $image['objects']['width'] = 218;
50 $image['objects']['height'] = 200;
51 $image['files']['path'] = 'pix/files.png';
52 $image['files']['width'] = 218;
53 $image['files']['height'] = 200;
54 $image['ipv4space']['path'] = 'pix/addressspace.png';
55 $image['ipv4space']['width'] = 218;
56 $image['ipv4space']['height'] = 200;
57 $image['ipv4slb']['path'] = 'pix/slb.png';
58 $image['ipv4slb']['width'] = 218;
59 $image['ipv4slb']['height'] = 200;
60 $image['config']['path'] = 'pix/configuration.png';
61 $image['config']['width'] = 218;
62 $image['config']['height'] = 200;
63 $image['reports']['path'] = 'pix/report.png';
64 $image['reports']['width'] = 218;
65 $image['reports']['height'] = 200;
66 $image['download']['path'] = 'pix/download.png';
67 $image['download']['width'] = 16;
68 $image['download']['height'] = 16;
69 $image['DOWNLOAD']['path'] = 'pix/download-big.png';
70 $image['DOWNLOAD']['width'] = 32;
71 $image['DOWNLOAD']['height'] = 32;
72 $image['plug']['path'] = 'pix/tango-network-wired.png';
73 $image['plug']['width'] = 16;
74 $image['plug']['height'] = 16;
75 $image['cut']['path'] = 'pix/tango-edit-cut-16x16.png';
76 $image['cut']['width'] = 16;
77 $image['cut']['height'] = 16;
78 $image['CUT']['path'] = 'pix/tango-edit-cut-32x32.png';
79 $image['CUT']['width'] = 32;
80 $image['CUT']['height'] = 32;
81 $image['add']['path'] = 'pix/tango-list-add.png';
82 $image['add']['width'] = 16;
83 $image['add']['height'] = 16;
84 $image['ADD']['path'] = 'pix/tango-list-add-big.png';
85 $image['ADD']['width'] = 32;
86 $image['ADD']['height'] = 32;
87 $image['delete']['path'] = 'pix/tango-list-remove.png';
88 $image['delete']['width'] = 16;
89 $image['delete']['height'] = 16;
90 $image['destroy']['path'] = 'pix/tango-user-trash-16x16.png';
91 $image['destroy']['width'] = 16;
92 $image['destroy']['height'] = 16;
93 $image['nodestroy']['path'] = 'pix/tango-user-trash-16x16-gray.png';
94 $image['nodestroy']['width'] = 16;
95 $image['nodestroy']['height'] = 16;
96 $image['NODESTROY']['path'] = 'pix/tango-user-trash-32x32-gray.png';
97 $image['NODESTROY']['width'] = 32;
98 $image['NODESTROY']['height'] = 32;
99 $image['DESTROY']['path'] = 'pix/tango-user-trash-32x32.png';
100 $image['DESTROY']['width'] = 32;
101 $image['DESTROY']['height'] = 32;
102 $image['nodelete']['path'] = 'pix/tango-list-remove-shadow.png';
103 $image['nodelete']['width'] = 16;
104 $image['nodelete']['height'] = 16;
105 $image['inservice']['path'] = 'pix/tango-emblem-system.png';
106 $image['inservice']['width'] = 16;
107 $image['inservice']['height'] = 16;
108 $image['notinservice']['path'] = 'pix/tango-dialog-error.png';
109 $image['notinservice']['width'] = 16;
110 $image['notinservice']['height'] = 16;
111 $image['find']['path'] = 'pix/tango-system-search.png';
112 $image['find']['width'] = 16;
113 $image['find']['height'] = 16;
114 $image['next']['path'] = 'pix/tango-go-next.png';
115 $image['next']['width'] = 32;
116 $image['next']['height'] = 32;
117 $image['prev']['path'] = 'pix/tango-go-previous.png';
118 $image['prev']['width'] = 32;
119 $image['prev']['height'] = 32;
120 $image['clear']['path'] = 'pix/tango-edit-clear.png';
121 $image['clear']['width'] = 16;
122 $image['clear']['height'] = 16;
123 $image['CLEAR']['path'] = 'pix/tango-edit-clear-big.png';
124 $image['CLEAR']['width'] = 32;
125 $image['CLEAR']['height'] = 32;
126 $image['CLEAR gray']['path'] = 'pix/tango-edit-clear-gray-32x32.png';
127 $image['CLEAR gray']['width'] = 32;
128 $image['CLEAR gray']['height'] = 32;
129 $image['save']['path'] = 'pix/tango-document-save.png';
130 $image['save']['width'] = 16;
131 $image['save']['height'] = 16;
132 $image['SAVE']['path'] = 'pix/tango-document-save-big.png';
133 $image['SAVE']['width'] = 32;
134 $image['SAVE']['height'] = 32;
135 $image['create']['path'] = 'pix/tango-document-new.png';
136 $image['create']['width'] = 16;
137 $image['create']['height'] = 16;
138 $image['CREATE']['path'] = 'pix/tango-document-new-big.png';
139 $image['CREATE']['width'] = 32;
140 $image['CREATE']['height'] = 32;
141 $image['DENIED']['path'] = 'pix/tango-dialog-error-big.png';
142 $image['DENIED']['width'] = 32;
143 $image['DENIED']['height'] = 32;
144 $image['apply']['path'] = 'pix/tango-emblem-system.png';
145 $image['apply']['width'] = 16;
146 $image['apply']['height'] = 16;
147 $image['node-collapsed']['path'] = 'pix/node-collapsed.png';
148 $image['node-collapsed']['width'] = 16;
149 $image['node-collapsed']['height'] = 16;
150 $image['node-expanded']['path'] = 'pix/node-expanded.png';
151 $image['node-expanded']['width'] = 16;
152 $image['node-expanded']['height'] = 16;
153 $image['node-expanded-static']['path'] = 'pix/node-expanded-static.png';
154 $image['node-expanded-static']['width'] = 16;
155 $image['node-expanded-static']['height'] = 16;
156 $image['dragons']['path'] = 'pix/mitsudragon.png';
157 $image['dragons']['width'] = 125;
158 $image['dragons']['height'] = 21;
159 $image['LB']['path'] = 'pix/loadbalancer.png';
160 $image['LB']['width'] = 32;
161 $image['LB']['height'] = 32;
162 $image['RS pool']['path'] = 'pix/serverpool.png';
163 $image['RS pool']['width'] = 48;
164 $image['RS pool']['height'] = 16;
165 $image['VS']['path'] = 'pix/servicesign.png';
166 $image['VS']['width'] = 39;
167 $image['VS']['height'] = 62;
168 $image['router']['path'] = 'pix/router.png';
169 $image['router']['width'] = 32;
170 $image['router']['height'] = 32;
171 $image['ATTACH']['path'] = 'pix/crystal-attach-32x32.png';
172 $image['ATTACH']['width'] = 32;
173 $image['ATTACH']['height'] = 32;
174 $image['favorite']['path'] = 'pix/tango-emblem-favorite.png';
175 $image['favorite']['width'] = 16;
176 $image['favorite']['height'] = 16;
177 $image['computer']['path'] = 'pix/tango-computer.png';
178 $image['computer']['width'] = 16;
179 $image['computer']['height'] = 16;
180 $image['empty file']['path'] = 'pix/crystal-file-empty-32x32.png';
181 $image['empty file']['width'] = 32;
182 $image['empty file']['height'] = 32;
183 $image['text file']['path'] = 'pix/crystal-file-text-32x32.png';
184 $image['text file']['width'] = 32;
185 $image['text file']['height'] = 32;
186 $image['image file']['path'] = 'pix/crystal-file-image-32x32.png';
187 $image['image file']['width'] = 32;
188 $image['image file']['height'] = 32;
189 $image['NET']['path'] = 'pix/crystal-network-32x32.png';
190 $image['NET']['width'] = 32;
191 $image['NET']['height'] = 32;
192 $image['USER']['path'] = 'pix/crystal-edit-user-32x32.png';
193 $image['USER']['width'] = 32;
194 $image['USER']['height'] = 32;
196 // This may be populated later onsite, report rendering function will use it.
197 // See the $systemreport for structure.
198 $localreports = array();
199 $CodePressMap = array
205 'js' => 'javascript',
210 'uint' => '[U] unsigned integer',
211 'float' => '[F] floating point',
212 'string' => '[S] string',
213 'dict' => '[D] dictionary record'
216 // Rack thumbnail image width summands: "front", "interior" and "rear" elements w/o surrounding border.
225 function renderIndex ()
228 <table border
=0 cellpadding
=0 cellspacing
=0 width
='100%'>
231 <div style
='text-align: center; margin: 10px; '>
232 <table width
='100%' cellspacing
=0 cellpadding
=30 class=mainmenu border
=0>
235 <h1
><a href
='<?php echo makeHref(array('page
'=>'rackspace
')) ?>'>Rackspace
<br
>
236 <?php
printImageHREF ('rackspace'); ?
></a
></h1
>
239 <h1
><a href
='<?php echo makeHref(array('page
'=>'depot
')) ?>'>Objects
<br
>
240 <?php
printImageHREF ('objects'); ?
></a
></h1
>
243 <h1
><a href
='<?php echo makeHref(array('page
'=>'ipv4space
')) ?>'>IPv4 space
<br
>
244 <?php
printImageHREF ('ipv4space'); ?
></a
></h1
>
247 <h1
><a href
='<?php echo makeHref(array('page
'=>'files
')) ?>'>Files
<br
>
248 <?php
printImageHREF ('files'); ?
></a
></h1
>
253 <h1
><a href
='<?php echo makeHref(array('page
'=>'config
')) ?>'>Configuration
<br
>
254 <?php
printImageHREF ('config'); ?
></a
></h1
>
257 <h1
><a href
='<?php echo makeHref(array('page
'=>'reports
')) ?>'>Reports
<br
>
258 <?php
printImageHREF ('reports'); ?
></a
></h1
>
261 <h1
><a href
='<?php echo makeHref(array('page
'=>'ipv4slb
')) ?>'>IPv4 SLB
<br
>
262 <?php
printImageHREF ('ipv4slb'); ?
></a
></h1
>
274 function renderRackspace ()
276 showMessageOrError();
277 echo "<table class=objview border=0 width='100%'><tr><td class=pcleft>";
278 $cellfilter = getCellFilter();
279 renderCellFilterPortlet ($cellfilter, 'rack');
280 echo '</td><td class=pcright>';
281 echo '<table border=0 cellpadding=10 cellpadding=1>';
282 // generate thumb gallery
284 $rackwidth = getRackImageWidth();
285 // Zero value effectively disables the limit.
286 $maxPerRow = getConfigVar ('RACKS_PER_ROW');
288 foreach (getRackRows() as $row_id => $row_name)
290 $rackList = filterCellList (listCells ('rack', $row_id), $cellfilter['expression']);
291 if (!count ($rackList) and count ($cellfilter['expression']))
294 echo "<tr class=row_${order}><th class=tdleft>";
295 echo "<a href='".makeHref(array('page'=>'row', 'row_id'=>$row_id))."${cellfilter['urlextra']}'>";
296 echo "${row_name}</a></th><td><table border=0 cellspacing=5><tr>";
297 if (!count ($rackList))
298 echo "<td>(empty row)</td>";
300 foreach ($rackList as $rack)
302 if ($rackListIdx > 0 and $maxPerRow > 0 and $rackListIdx %
$maxPerRow == 0)
304 echo '</tr></table></tr>';
305 echo "<tr class=row_${order}><th class=tdleft>${row_name} (continued)";
306 echo "</th><td><table border=0 cellspacing=5><tr>";
307 $order = $nextorder[$order];
309 echo "<td align=center><a href='".makeHref(array('page'=>'rack', 'rack_id'=>$rack['id']))."'>";
310 echo "<img border=0 width=${rackwidth} height=";
311 echo getRackImageHeight ($rack['height']);
312 echo " title='${rack['height']} units'";
313 echo "src='render_image.php?img=minirack&rack_id=${rack['id']}'>";
314 echo "<br>${rack['name']}</a></td>";
317 echo "</tr></table></tr>\n";
320 echo "</td></tr></table>\n";
323 function renderRackspaceRowEditor ()
325 function printNewItemTR ()
327 printOpFormIntro ('addRow');
329 printImageHREF ('create', 'Add new row', TRUE);
330 echo "</td><td><input type=text name=name tabindex=100></td><td>";
331 printImageHREF ('create', 'Add new row', TRUE, 101);
332 echo "</td></tr></form>";
334 showMessageOrError();
335 startPortlet ('Rows');
336 echo "<table border=0 cellspacing=0 cellpadding=5 align=center class=widetable>\n";
337 echo "<tr><th> </th><th>Name</th><th> </th></tr>\n";
338 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
340 foreach (getRackRows() as $row_id => $row_name)
343 if ($rc = count (listCells ('rack', $row_id)))
344 printImageHREF ('nodestroy', "${rc} rack(s) here");
347 echo "<a href=\"".makeHrefProcess(array('op'=>'delete', 'row_id'=>$row_id))."\">";
348 printImageHREF ('destroy', 'Delete row');
351 printOpFormIntro ('updateRow', array ('row_id' => $row_id));
352 echo "</td><td><input type=text name=name value='${row_name}'></td><td>";
353 printImageHREF ('save', 'Save changes', TRUE);
354 echo "</form></td></tr>\n";
356 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
358 echo "</table><br>\n";
362 function renderRow ($row_id)
364 if (($rowInfo = getRackRowInfo ($row_id)) == NULL)
366 showError ('getRackRowInfo() failed', __FUNCTION__
);
369 $cellfilter = getCellFilter();
370 $rackList = filterCellList (listCells ('rack', $row_id), $cellfilter['expression']);
371 // Main layout starts.
372 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
374 // Left portlet with row information.
375 echo "<tr><td class=pcleft>";
376 startPortlet ($rowInfo['name']);
377 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
378 echo "<tr><th width='50%' class=tdright>Racks:</th><td class=tdleft>${rowInfo['count']}</td></tr>\n";
379 echo "<tr><th width='50%' class=tdright>Units:</th><td class=tdleft>${rowInfo['sum']}</td></tr>\n";
380 echo "<tr><th width='50%' class=tdright>%% used:</th><td class=tdleft>";
381 renderProgressBar (getRSUforRackRow ($rackList));
383 echo "</table><br>\n";
385 renderCellFilterPortlet ($cellfilter, 'rack', 'row_id', $row_id);
387 echo "</td><td class=pcright>";
390 $rackwidth = getRackImageWidth() * getConfigVar ('ROW_SCALE');
391 // Maximum number of racks per row is proportionally less, but at least 1.
392 $maxPerRow = max (floor (getConfigVar ('RACKS_PER_ROW') / getConfigVar ('ROW_SCALE')), 1);
395 startPortlet ('Racks');
396 echo "<table border=0 cellspacing=5 align='center'><tr>";
397 foreach ($rackList as $rack)
399 if ($rackListIdx %
$maxPerRow == 0)
401 if ($rackListIdx > 0)
405 echo "<td align=center class=row_${order}><a href='".makeHref(array('page'=>'rack', 'rack_id'=>$rack['id']))."'>";
406 echo "<img border=0 width=${rackwidth} height=" . (getRackImageHeight ($rack['height']) * getConfigVar ('ROW_SCALE'));
407 echo " title='${rack['height']} units'";
408 echo "src='render_image.php?img=minirack&rack_id=${rack['id']}'>";
409 echo "<br>${rack['name']}</a></td>";
410 $order = $nextorder[$order];
413 echo "</tr></table>\n";
415 echo "</td></tr></table>";
418 function showError ($info = '', $location = 'N/A')
420 if (preg_match ('/\.php$/', $location))
421 $location = basename ($location);
422 elseif ($location != 'N/A')
423 $location = $location . '()';
424 echo "<div class=msg_error>An error has occured in [${location}]. ";
426 echo 'No additional information is available.';
428 echo "Additional information:<br><p>\n<pre>\n${info}\n</pre></p>";
429 echo "Go back or try starting from <a href='".makeHref()."'>index page</a>.<br></div>\n";
432 // This function assures that specified argument was passed
433 // and is a number greater than zero.
434 function assertUIntArg ($argname, $caller = 'N/A', $allow_zero = FALSE)
436 if (!isset ($_REQUEST[$argname]))
438 showError ("Parameter '${argname}' is missing (calling function is [${caller}]).", __FUNCTION__
);
441 if (!is_numeric ($_REQUEST[$argname]))
443 showError ("Parameter '${argname}' is not a number (calling function is [${caller}]).", __FUNCTION__
);
446 if ($_REQUEST[$argname] < 0)
448 showError ("Parameter '${argname}' is less than zero (calling function is [${caller}]).", __FUNCTION__
);
451 if (!$allow_zero and $_REQUEST[$argname] == 0)
453 showError ("Parameter '${argname}' is equal to zero (calling function is [${caller}]).", __FUNCTION__
);
458 // This function assures that specified argument was passed
459 // and is a non-empty string.
460 function assertStringArg ($argname, $caller = 'N/A', $ok_if_empty = FALSE)
462 if (!isset ($_REQUEST[$argname]))
464 showError ("Parameter '${argname}' is missing (calling function is [${caller}]).", __FUNCTION__
);
467 if (!is_string ($_REQUEST[$argname]))
469 showError ("Parameter '${argname}' is not a string (calling function is [${caller}]).", __FUNCTION__
);
472 if (!$ok_if_empty and empty ($_REQUEST[$argname]))
474 showError ("Parameter '${argname}' is an empty string (calling function is [${caller}]).", __FUNCTION__
);
479 function assertBoolArg ($argname, $caller = 'N/A', $ok_if_empty = FALSE)
481 if (!isset ($_REQUEST[$argname]))
483 showError ("Parameter '${argname}' is missing (calling function is [${caller}]).", __FUNCTION__
);
486 if (!is_string ($_REQUEST[$argname]) or $_REQUEST[$argname] != 'on')
488 showError ("Parameter '${argname}' is not a string (calling function is [${caller}]).", __FUNCTION__
);
491 if (!$ok_if_empty and empty ($_REQUEST[$argname]))
493 showError ("Parameter '${argname}' is an empty string (calling function is [${caller}]).", __FUNCTION__
);
498 function assertIPv4Arg ($argname, $caller = 'N/A', $ok_if_empty = FALSE)
500 assertStringArg ($argname, $caller, $ok_if_empty);
501 if (!empty ($_REQUEST[$argname]) and long2ip (ip2long ($_REQUEST[$argname])) !== $_REQUEST[$argname])
503 showError ("IPv4 address validation failed for value '" . $_REQUEST[$argname] . "' (calling function is [${caller}]).", __FUNCTION__
);
508 // This function renders rack as HTML table.
509 function renderRack ($rack_id, $hl_obj_id = 0)
511 if (($rackData = getRackData ($rack_id)) == NULL)
513 showError ('getRackData() failed', __FUNCTION__
);
516 markAllSpans ($rackData);
518 highlightObject ($rackData, $hl_obj_id);
519 markupObjectProblems ($rackData);
520 $prev_id = getPrevIDforRack ($rackData['row_id'], $rack_id);
521 $next_id = getNextIDforRack ($rackData['row_id'], $rack_id);
522 echo "<center><table border=0><tr valign=middle>";
523 echo "<td><h2><a href='".makeHref(array('page'=>'row', 'row_id'=>$rackData['row_id']))."'>${rackData['row_name']}</a> :</h2></td>";
524 // FIXME: use 'bypass'?
525 if ($prev_id != NULL)
527 echo "<td><a href='".makeHref(array('page'=>'rack', 'rack_id'=>$prev_id))."'>";
528 printImageHREF ('prev', 'previous rack');
531 echo "<td><h2><a href='".makeHref(array('page'=>'rack', 'rack_id'=>$rackData['id']))."'>${rackData['name']}</a></h2></td>";
532 if ($next_id != NULL)
534 echo "<td><a href='".makeHref(array('page'=>'rack', 'rack_id'=>$next_id))."'>";
535 printImageHREF ('next', 'next rack');
538 echo "</h2></td></tr></table>\n";
539 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
540 echo "<tr><th width='10%'> </th><th width='20%'>Front</th>";
541 echo "<th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
542 for ($i = $rackData['height']; $i > 0; $i--)
544 echo "<tr><th>${i}</th>";
545 for ($locidx = 0; $locidx < 3; $locidx++
)
547 if (isset ($rackData[$i][$locidx]['skipped']))
549 $state = $rackData[$i][$locidx]['state'];
550 echo "<td class=state_${state}";
551 if (isset ($rackData[$i][$locidx]['hl']))
552 echo $rackData[$i][$locidx]['hl'];
553 if (isset ($rackData[$i][$locidx]['colspan']))
554 echo ' colspan=' . $rackData[$i][$locidx]['colspan'];
555 if (isset ($rackData[$i][$locidx]['rowspan']))
556 echo ' rowspan=' . $rackData[$i][$locidx]['rowspan'];
561 $objectData = getObjectInfo ($rackData[$i][$locidx]['object_id']);
562 if (!empty ($objectData['asset_no']))
563 $prefix = "<div title='${objectData['asset_no']}";
565 $prefix = "<div title='no asset tag";
566 // Don't tell about label, if it matches common name.
567 if ($objectData['name'] != $objectData['label'] and !empty ($objectData['label']))
568 $suffix = ", visible label is \"${objectData['label']}\"'>";
571 echo $prefix . $suffix;
572 echo "<a href='".makeHref(array('page'=>'object', 'object_id'=>$objectData['id']))."'>${objectData['dname']}</a></div>";
575 echo '<div title="This rackspace does not exist"> </div>';
578 echo '<div title="Free rackspace"> </div>';
581 echo '<div title="Problematic rackspace, you CAN\'T mount here"> </div>';
584 echo '<div title="No data"> </div>';
591 echo "</table></center>\n";
594 function renderNewRackForm ($row_id)
596 showMessageOrError();
598 startPortlet ('Add one');
599 printOpFormIntro ('addRack', array ('got_data' => 'TRUE'));
600 echo '<table border=0 align=center>';
601 $defh = getConfigVar ('DEFAULT_RACK_HEIGHT');
604 echo "<tr><th class=tdright>Rack name (*):</th><td class=tdleft><input type=text name=rack_name tabindex=1></td>";
605 echo "<td rowspan=4>Assign tags:<br>";
606 renderNewEntityTags();
608 echo "<tr><th class=tdright>Height in units (*):</th><td class=tdleft><input type=text name=rack_height1 tabindex=2 value='${defh}'></td></tr>\n";
609 echo "<tr><th class=tdright>Comment:</th><td class=tdleft><input type=text name=rack_comment tabindex=3></td></tr>\n";
610 echo "<tr><td class=submit colspan=2>";
611 printImageHREF ('CREATE', 'Add', TRUE);
612 echo "</td></tr></table></form>";
615 startPortlet ('Add many');
616 printOpFormIntro ('addRack', array ('got_mdata' => 'TRUE'));
617 echo '<table border=0 align=center>';
618 $defh = getConfigVar ('DEFAULT_RACK_HEIGHT');
621 echo "<tr><th class=tdright>Height in units (*):</th><td class=tdleft><input type=text name=rack_height2 value='${defh}'></td>";
622 echo "<td rowspan=3 valign=top>Assign tags:<br>";
623 renderNewEntityTags();
625 echo "<tr><th class=tdright>Rack names (*):</th><td class=tdleft><textarea name=rack_names cols=40 rows=25></textarea></td></tr>\n";
626 echo "<tr><td class=submit colspan=2>";
627 printImageHREF ('CREATE', 'Add', TRUE);
628 echo '</form></table>';
632 function renderEditObjectForm ($object_id)
634 showMessageOrError();
637 $object = getObjectInfo ($object_id);
640 showError ('getObjectInfo() failed', __FUNCTION__
);
644 printOpFormIntro ('update');
647 echo '<table border=0 cellspacing=0 cellpadding=3 align=center>';
648 echo "<tr><td> </td><th colspan=2><h2>Attributes</h2></th></tr>";
649 echo "<tr><td> </td><th class=tdright>Type:</th><td class=tdleft>";
650 printSelect (getObjectTypeList(), 'object_type_id', $object['objtype_id']);
653 echo "<tr><td> </td><th class=tdright>Common name:</th><td class=tdleft><input type=text name=object_name value='${object['name']}'></td></tr>\n";
654 echo "<tr><td> </td><th class=tdright>Visible label:</th><td class=tdleft><input type=text name=object_label value='${object['label']}'></td></tr>\n";
655 echo "<tr><td> </td><th class=tdright>Asset tag:</th><td class=tdleft><input type=text name=object_asset_no value='${object['asset_no']}'></td></tr>\n";
656 echo "<tr><td> </td><th class=tdright>Barcode:</th><td class=tdleft><input type=text name=object_barcode value='${object['barcode']}'></td></tr>\n";
657 // optional attributes
658 $values = getAttrValues ($object_id);
659 echo '<input type=hidden name=num_attrs value=' . count($values) . ">\n";
660 if (count($values) > 0)
663 foreach ($values as $record)
665 echo "<input type=hidden name=${i}_attr_id value=${record['id']}>";
667 if (!empty ($record['value']))
669 echo "<a href='".makeHrefProcess(array('op'=>'clearSticker', 'object_id'=>$object_id, 'attr_id'=>$record['id']))."'>";
670 printImageHREF ('clear', 'Clear value');
676 echo "<th class=sticker>${record['name']}:</th><td class=tdleft>";
677 switch ($record['type'])
682 echo "<input type=text name=${i}_value value='${record['value']}'>";
685 $chapter = readChapter ($record['chapter_name']);
686 $chapter[0] = '-- NOT SET --';
687 $chapter = cookOptgroups ($chapter, $object['objtype_id'], $record['key']);
688 printNiftySelect ($chapter, "${i}_value", $record['key']);
695 echo "<tr><td> </td><th class=tdright>Has problems:</th><td class=tdleft><input type=checkbox name=object_has_problems";
696 if ($object['has_problems'] == 'yes')
698 echo "></td></tr>\n";
699 echo "<tr><td> </td><th class=tdright>Actions:</th><td class=tdleft><a href='".
700 makeHrefProcess(array('op'=>'deleteObject', 'page'=>'depot', 'tab'=>'default', 'object_id'=>$object_id)).
701 "' onclick=\"javascript:return confirm('Are you sure you want to delete the object?')\">Delete object</a></td></tr>\n";
702 echo "<tr><td colspan=3><b>Comment:</b><br><textarea name=object_comment rows=10 cols=80>${object['comment']}</textarea></td></tr>";
704 echo "<tr><th class=submit colspan=3>";
705 printImageHREF ('SAVE', 'Save changes', TRUE);
706 echo "</form></th></tr></table>\n";
709 echo '<table border=0 width=100%><tr><td>';
710 startPortlet ('history');
711 renderHistory ($pageno, $object_id);
713 echo '</td></tr></table>';
716 // This is a clone of renderEditObjectForm().
717 function renderEditRackForm ($rack_id)
719 showMessageOrError();
721 $rack = getRackData ($rack_id);
724 showError ('getRackData() failed', __FUNCTION__
);
728 startPortlet ('Rack attributes');
729 printOpFormIntro ('updateRack');
730 echo '<table border=0 align=center>';
731 echo "<tr><th class=tdright>Rack row:</th><td class=tdleft>";
732 printSelect (getRackRows(), 'rack_row_id', $rack['row_id']);
734 echo "<tr><th class=tdright>Name (required):</th><td class=tdleft><input type=text name=rack_name value='${rack['name']}'></td></tr>\n";
735 echo "<tr><th class=tdright>Height (required):</th><td class=tdleft><input type=text name=rack_height value='${rack['height']}'></td></tr>\n";
736 echo "<tr><th class=tdright>Comment:</th><td class=tdleft><input type=text name=rack_comment value='${rack['comment']}'></td></tr>\n";
737 if (count ($rack['mountedObjects']) == 0)
739 echo "<tr><th class=tdright>Actions:</th><td class=tdleft><a href='".
740 makeHrefProcess(array('op'=>'deleteRack', 'rack_id'=>$rack_id)).
741 "' onclick=\"javascript:return confirm('Are you sure you want to delete the rack?')\">Delete rack</a></td></tr>\n";
743 echo "<tr><td class=submit colspan=2>";
744 printImageHREF ('SAVE', 'Save changes', TRUE);
746 echo '</form></table><br>';
749 startPortlet ('History');
750 renderHistory ($pageno, $rack_id);
754 // This is a helper for creators and editors.
755 // Input array keys are OPTION VALUEs and input array values are OPTION text.
756 function printSelect ($optionList, $select_name, $selected_id = NULL, $tabindex = NULL)
758 echo "<select name=${select_name}" . ($tabindex ?
" tabindex=${tabindex}" : '') . '>';
759 foreach ($optionList as $dict_key => $dict_value)
760 echo "<option value='${dict_key}'" . ($dict_key == $selected_id ?
' selected' : '') . ">${dict_value}</option>";
764 // Input is a cooked list of OPTGROUPs, each with own sub-list of OPTIONs in the same
765 // format as printSelect() expects.
766 function printNiftySelect ($groupList, $select_name, $selected_id = NULL, $tabindex = NULL)
768 // special treatment for ungrouped data
769 if (count ($groupList) == 1 and isset ($groupList['other']))
771 printSelect ($groupList['other'], $select_name, $selected_id, $tabindex);
774 echo "<select name=${select_name}" . ($tabindex ?
" tabindex=${tabindex}" : '') . '>';
775 foreach ($groupList as $groupname => $groupdata)
777 echo "<optgroup label='${groupname}'>";
778 foreach ($groupdata as $dict_key => $dict_value)
779 echo "<option value='${dict_key}'" . ($dict_key == $selected_id ?
' selected' : '') . ">${dict_value}</option>";
780 echo "</optgroup>\n";
785 // used by renderGridForm() and renderRackPage()
786 function renderRackInfoPortlet ($rackData)
788 startPortlet ('summary');
789 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
790 echo "<tr><th width='50%' class=tdright>Rack row:</th><td class=tdleft>${rackData['row_name']}</td></tr>\n";
791 echo "<tr><th width='50%' class=tdright>Name:</th><td class=tdleft>${rackData['name']}</td></tr>\n";
792 echo "<tr><th width='50%' class=tdright>Height:</th><td class=tdleft>${rackData['height']}</td></tr>\n";
793 echo "<tr><th width='50%' class=tdright>%% used:</th><td class=tdleft>";
794 renderProgressBar (getRSUforRack ($rackData));
796 echo "<tr><th width='50%' class=tdright>Objects:</th><td class=tdleft>";
797 echo count (stuffInRackspace ($rackData));
799 printTagTRs (makeHref(array('page'=>'rackspace', 'tab'=>'default'))."&");
800 if (!empty ($rackData['comment']))
801 echo "<tr><th width='50%' class=tdright>Comment:</th><td class=tdleft>${rackData['comment']}</td></tr>\n";
806 // This is a universal editor of rack design/waste.
807 // FIXME: switch to using printOpFormIntro()
808 function renderGridForm ($rack_id, $filter, $header, $submit, $state1, $state2)
810 if (($rackData = getRackData ($rack_id)) == NULL)
812 showError ('getRackData() failed', __FUNCTION__
);
815 showMessageOrError();
817 markupObjectProblems ($rackData);
819 // Render the result whatever it is.
821 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
822 echo "<tr><td colspan=2 align=center><h1>${rackData['name']}</h1></td></tr>\n";
824 // Left column with information portlet.
825 echo "<tr><td class=pcleft height='1%' width='50%'>";
826 renderRackInfoPortlet ($rackData);
828 echo "<td class=pcright>";
831 startPortlet ($header);
833 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
834 echo "<tr><th width='10%'> </th>";
835 echo "<th width='20%'><a href='javascript:;' onclick=\"toggleColumnOfAtoms('${rack_id}', '0', ${rackData['height']})\">Front</a></th>";
836 echo "<th width='50%'><a href='javascript:;' onclick=\"toggleColumnOfAtoms('${rack_id}', '1', ${rackData['height']})\">Interior</a></th>";
837 echo "<th width='20%'><a href='javascript:;' onclick=\"toggleColumnOfAtoms('${rack_id}', '2', ${rackData['height']})\">Back</a></th></tr>\n";
838 printOpFormIntro ('updateRack');
839 markupAtomGrid ($rackData, $state2);
840 renderAtomGrid ($rackData);
841 echo "</table></center>\n";
842 echo "<br><input type=submit name=do_update value='${submit}'></form><br><br>\n";
844 echo "</td></tr></table>\n";
847 function renderRackDesign ($rack_id)
849 renderGridForm ($rack_id, 'applyRackDesignMask', 'Rack design', 'Set rack design', 'A', 'F');
852 function renderRackProblems ($rack_id)
854 renderGridForm ($rack_id, 'applyRackProblemMask', 'Rack problems', 'Mark unusable atoms', 'F', 'U');
857 function startPortlet ($title = '')
859 echo "<div class=portlet><h2>${title}</h2>";
862 function finishPortlet ()
867 function renderRackObject ($object_id)
869 global $nextorder, $aac;
870 $info = getObjectInfo ($object_id);
873 showError ('getObjectInfo() failed', __FUNCTION__
);
876 // Main layout starts.
877 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
878 echo "<tr><td colspan=2 align=center><h1>${info['dname']}</h1></td></tr>\n";
879 // left column with uknown number of portlets
880 echo "<tr><td class=pcleft>";
881 startPortlet ('summary');
882 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
883 if (!empty ($info['name']))
884 echo "<tr><th width='50%' class=tdright>Common name:</th><td class=tdleft>${info['name']}</td></tr>\n";
885 elseif (considerConfiguredConstraint ('object', $object_id, 'NAMEWARN_LISTSRC'))
886 echo "<tr><td colspan=2 class=msg_error>Common name is missing.</td></tr>\n";
887 echo "<tr><th width='50%' class=tdright>Object type:</th><td class=tdleft><a href='";
888 echo makeHref (array (
891 'cfe' => '{$typeid_' . $info['objtype_id'] . '}'
893 echo "'>${info['objtype_name']}</a></td></tr>\n";
894 if (!empty ($info['asset_no']))
895 echo "<tr><th width='50%' class=tdright>Asset tag:</th><td class=tdleft>${info['asset_no']}</td></tr>\n";
896 elseif (considerConfiguredConstraint ('object', $object_id, 'ASSETWARN_LISTSRC'))
897 echo "<tr><td colspan=2 class=msg_error>Asset tag is missing.</td></tr>\n";
898 if (!empty ($info['label']))
899 echo "<tr><th width='50%' class=tdright>Visible label:</th><td class=tdleft>${info['label']}</td></tr>\n";
900 if (!empty ($info['barcode']))
901 echo "<tr><th width='50%' class=tdright>Barcode:</th><td class=tdleft>${info['barcode']}</td></tr>\n";
902 if ($info['has_problems'] == 'yes')
903 echo "<tr><td colspan=2 class=msg_error>Has problems</td></tr>\n";
904 foreach (getAttrValues ($object_id, TRUE) as $record)
905 if (!empty ($record['value']))
906 echo "<tr><th width='50%' class=sticker>${record['name']}:</th><td class=sticker>${record['a_value']}</td></tr>\n";
916 'cfe' => '{$typeid_' . $info['objtype_id'] . '}',
920 echo "</table><br>\n";
923 if (!empty ($info['comment']))
925 startPortlet ('Comment');
926 echo '<div class=commentblock>' . string_insert_hrefs ($info['comment']) . '</div>';
930 renderFilesPortlet ('object', $object_id);
932 $ports = getObjectPortsAndLinks ($object_id);
935 startPortlet ('ports and links');
936 usort($ports, 'sortByName');
940 if (isset ($_REQUEST['hl_port_id']))
942 assertUIntArg ('hl_port_id', __FUNCTION__
);
943 $hl_port_id = $_REQUEST['hl_port_id'];
945 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
946 echo "<tr><th>Local name</th><th>Visible label</th><th>Port type</th><th>L2 address</th>";
947 echo "<th>Rem. Object</th><th>Rem. port</th></tr>\n";
948 foreach ($ports as $port)
951 if ($hl_port_id == $port['id'])
952 echo ' class=port_highlight';
953 echo "><td>${port['name']}</td><td>${port['label']}</td><td>${port['type']}</td>";
954 echo "<td>${port['l2address']}</td>";
955 if ($port['remote_object_id'])
957 echo "<td><a href='".makeHref(array('page'=>'object', 'object_id'=>$port['remote_object_id'], 'hl_port_id'=>$port['remote_id']))."'>${port['remote_object_name']}</a></td>";
958 echo "<td>${port['remote_name']}</td>";
960 elseif (!empty ($port['reservation_comment']))
962 echo "<td><b>Reserved;</b></td>";
963 echo "<td>${port['reservation_comment']}</td>";
966 echo '<td> </td><td> </td>';
969 echo "</table><br>\n";
974 $alloclist = getObjectIPv4Allocations ($object_id);
975 if (count ($alloclist))
977 startPortlet ('IPv4 addresses');
978 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
979 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
980 echo "<tr><th>OS interface</th><th>IP address</th><th>network</th><th>routed by</th><th>peers</th></tr>\n";
982 echo "<tr><th>OS interface</th><th>IP address</th><th>peers</th></tr>\n";
984 if (isset ($_REQUEST['hl_ipv4_addr']))
986 assertIPv4Arg ('hl_ipv4_addr', __FUNCTION__
);
987 $hl_ipv4_addr = $_REQUEST['hl_ipv4_addr'];
989 foreach ($alloclist as $dottedquad => $alloc)
991 $address_name = niftyString ($alloc['addrinfo']['name']);
992 $class = $alloc['addrinfo']['class'];
993 $secondclass = ($hl_ipv4_addr == $dottedquad) ?
'tdleft port_highlight' : 'tdleft';
994 $netid = getIPv4AddressNetworkId ($dottedquad);
997 $netinfo = getIPv4NetworkInfo ($netid);
998 loadIPv4AddrList ($netinfo);
1000 echo "<tr class='${class}' valign=top><td class=tdleft>${alloc['osif']}</td><td class='${secondclass}'>";
1001 if (NULL !== $netid)
1002 echo "<a href='".makeHref(array('page'=>'ipaddress', 'ip'=>$dottedquad, 'hl_object_id'=>$object_id))."'>${dottedquad}</a>";
1005 if (getConfigVar ('EXT_IPV4_VIEW') != 'yes')
1006 echo '<small>/' . (NULL === $netid ?
'??' : $netinfo['mask']) . '</small>';
1007 echo ' ' . $aac[$alloc['type']];
1008 if (!empty ($alloc['addrinfo']['name']))
1009 echo ' (' . niftyString ($alloc['addrinfo']['name']) . ')';
1011 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
1013 if (NULL === $netid)
1014 echo '<td class=sparenetwork>N/A</td><td class=sparenetwork>N/A</td>';
1017 echo "<td class='${secondclass}'>";
1018 renderIPv4NetCell ($netinfo);
1020 // filter out self-allocation
1021 $other_routers = array();
1022 foreach (findRouters ($netinfo['addrlist']) as $router)
1023 if ($router['id'] != $object_id)
1024 $other_routers[] = $router;
1025 if (count ($other_routers))
1026 printRoutersTD ($other_routers);
1028 echo "<td class='${secondclass}'> </td>";
1032 echo "<td class='${secondclass}'>\n";
1034 if ($alloc['addrinfo']['reserved'] == 'yes')
1036 echo $prefix . '<strong>RESERVED</strong>';
1039 foreach ($alloc['addrinfo']['allocs'] as $allocpeer)
1041 if ($allocpeer['object_id'] == $object_id)
1043 echo $prefix . "<a href='".makeHref(array('page'=>'object', 'object_id'=>$allocpeer['object_id']))."'>";
1044 if (!empty ($allocpeer['osif']))
1045 echo $allocpeer['osif'] . '@';
1046 echo $allocpeer['object_name'] . '</a>';
1049 echo "</td></tr>\n";
1051 echo "</table><br>\n";
1055 $forwards = getNATv4ForObject ($object_id);
1056 if (count($forwards['in']) or count($forwards['out']))
1058 startPortlet('NATv4');
1060 if (count($forwards['out']))
1063 echo "<h3>locally performed NAT</h3>";
1065 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
1066 echo "<tr><th>Proto</th><th>Match endpoint</th><th>Translate to</th><th>Target object</th><th>Rule comment</th></tr>\n";
1068 foreach ($forwards['out'] as $pf)
1072 if (isset ($alloclist [$pf['localip']]))
1074 $class = $alloclist [$pf['localip']]['addrinfo']['class'];
1075 $osif = $alloclist [$pf['localip']]['osif'] . ': ';
1077 echo "<tr class='$class'>";
1078 echo "<td>${pf['proto']}</td><td class=tdleft>${osif}<a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['localip']))."'>${pf['localip']}</a>:${pf['localport']}</td>";
1079 echo "<td class=tdleft><a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['remoteip']))."'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
1080 $address = getIPv4Address ($pf['remoteip']);
1081 echo "<td class='description'>";
1082 if (count ($address['allocs']))
1083 foreach($address['allocs'] as $bond)
1084 echo "<a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$bond['object_id']))."'>${bond['object_name']}(${bond['name']})</a> ";
1085 elseif (!empty ($pf['remote_addr_name']))
1086 echo '(' . $pf['remote_addr_name'] . ')';
1087 echo "</td><td class='description'>${pf['description']}</td></tr>";
1089 echo "</table><br><br>";
1091 if (count($forwards['in']))
1093 echo "<h3>arriving NAT connections</h3>";
1094 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
1095 echo "<tr><th>Matched endpoint</th><th>Source object</th><th>Translated to</th><th>Rule comment</th></tr>\n";
1096 foreach ($forwards['in'] as $pf)
1099 echo "<td>${pf['proto']}/<a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['localip']))."'>${pf['localip']}</a>:${pf['localport']}</td>";
1100 echo "<td class='description'><a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$pf['object_id']))."'>${pf['object_name']}</a>";
1101 echo "</td><td><a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['remoteip']))."'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
1102 echo "<td class='description'>${pf['description']}</td></tr>";
1104 echo "</table><br><br>";
1109 $pools = getRSPoolsForObject ($object_id);
1113 startPortlet ('Real server pools (' . count ($pools) . ')');
1114 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
1115 echo "<tr><th>VS</th><th>RS pool</th><th>RS</th><th>VS config</th><th>RS config</th></tr>\n";
1116 foreach ($pools as $vs_id => $info)
1118 echo "<tr valign=top class=row_${order}><td class=tdleft>";
1119 renderVSCell ($vs_id);
1120 echo "</td><td class=tdleft>";
1121 renderRSPoolCell ($info['pool_id'], $info['pool_name']);
1122 echo '</td><td class=tdleft>' . $info['rscount'] . '</td>';
1123 echo "<td class=slbconf>${info['vsconfig']}</td>";
1124 echo "<td class=slbconf>${info['rsconfig']}</td>";
1126 $order = $nextorder[$order];
1133 // After left column we have (surprise!) right column with rackspace portlet only.
1134 echo "<td class=pcright>";
1135 // rackspace portlet
1136 startPortlet ('rackspace allocation');
1137 foreach (getResidentRacksData ($object_id, FALSE) as $rack_id)
1138 renderRack ($rack_id, $object_id);
1145 function renderRackMultiSelect ($sname, $racks, $selected)
1147 // Transform the given flat list into a list of groups, each representing a rack row.
1149 foreach ($racks as $rack)
1150 if (!isset ($rdata[$rack['row_name']]))
1151 $rdata[$rack['row_name']] = array ($rack['id'] => $rack['name']);
1153 $rdata[$rack['row_name']][$rack['id']] = $rack['name'];
1154 echo "<select name=${sname} multiple size=" . getConfigVar ('MAXSELSIZE') . " onchange='getElementsByName(\"updateObjectAllocation\")[0].submit()'>\n";
1155 foreach ($rdata as $optgroup => $racklist)
1157 echo "<optgroup label='${optgroup}'>";
1158 foreach ($racklist as $rack_id => $rack_name)
1160 echo "<option value=${rack_id}";
1161 if (!(array_search ($rack_id, $selected) === FALSE))
1163 echo">${rack_name}</option>\n";
1169 function showMessageOrError ()
1171 if (isset ($_SESSION['log']))
1173 printLog ($_SESSION['log']);
1174 unset($_SESSION['log']);
1178 // This function renders a form for port edition.
1179 function renderPortsForObject ($object_id)
1181 function printNewItemTR ()
1183 printOpFormIntro ('addPort');
1185 printImageHREF ('add', 'add a port', TRUE);
1186 echo "</td><td><input type=text size=8 name=port_name tabindex=100></td>\n";
1187 echo "<td><input type=text size=24 name=port_label tabindex=101></td><td>";
1188 printSelect (getPortTypes(), 'port_type_id', getConfigVar ('default_port_type'), 102);
1189 echo "<td><input type=text name=port_l2address tabindex=103></td>\n";
1190 echo "<td colspan=3> </td><td>";
1191 printImageHREF ('add', 'add a port', TRUE, 104);
1192 echo "</td></tr></form>";
1194 showMessageOrError();
1195 startPortlet ('Ports and interfaces');
1196 $ports = getObjectPortsAndLinks ($object_id);
1197 usort($ports, 'sortByName');
1198 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
1199 echo "<tr><th> </th><th>Local name</th><th>Visible label</th><th>Port type</th><th>L2 address</th>";
1200 echo "<th>Rem. object</th><th>Rem. port</th><th>(Un)link or (un)reserve</th><th> </th></tr>\n";
1201 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
1203 foreach ($ports as $port)
1205 printOpFormIntro ('editPort', array ('port_id' => $port['id']));
1206 echo "<tr><td><a href='".makeHrefProcess(array('op'=>'delPort', 'port_id'=>$port['id'], 'object_id'=>$object_id, 'port_name'=>$port['name']))."'>";
1207 printImageHREF ('delete', 'Unlink and Delete this port');
1209 echo "<td><input type=text name=name value='${port['name']}' size=8></td>";
1210 echo "<td><input type=text name=label value='${port['label']}' size=24></td>";
1211 if (!$port['remote_object_id'])
1214 printSelect (getPortTypes(), 'port_type_id', $port['type_id']);
1219 echo "<input type=hidden name=port_type_id value='${port['type_id']}'>";
1220 echo "<td class=tdleft>${port['type']}</td>\n";
1222 echo "<td><input type=text name=l2address value='${port['l2address']}'></td>\n";
1223 if ($port['remote_object_id'])
1225 echo "<td><a href='".makeHref(array('page'=>'object', 'object_id'=>$port['remote_object_id']))."'>${port['remote_object_name']}</a></td>";
1226 echo "<td>${port['remote_name']}</td>";
1227 echo "<td><a href='".
1228 makeHrefProcess(array(
1230 'port_id'=>$port['id'],
1231 'object_id'=>$object_id,
1232 'port_name'=>$port['name'],
1233 'remote_port_name'=>$port['remote_name'],
1234 'remote_object_name'=>$port['remote_object_name'])).
1236 printImageHREF ('cut', 'Unlink this port');
1239 elseif (!empty ($port['reservation_comment']))
1241 echo "<td><b>Reserved;</b></td>";
1242 echo "<td><input type=text name=reservation_comment value='${port['reservation_comment']}'></td>";
1243 echo "<td><a href='".
1244 makeHrefProcess(array(
1246 'port_id'=>$port['id'],
1247 'object_id'=>$object_id)).
1249 printImageHREF ('clear', 'Use up this port');
1254 echo "<td> </td><td> </td>";
1256 echo "<a href='javascript:;' onclick='window.open(\"".makeHrefForHelper('portlist', array('port'=>$port['id'], 'type'=>$port['type_id'], 'object_id'=>$object_id, 'port_name'=>$port['name']))."\",\"findlink\",\"height=700, width=400, location=no, menubar=no, resizable=yes, scrollbars=no, status=no, titlebar=no, toolbar=no\");'>";
1257 printImageHREF ('plug', 'Link this port');
1258 echo "</a> <input type=text name=reservation_comment>";
1262 printImageHREF ('save', 'Save changes', TRUE);
1263 echo "</td></form></tr>\n";
1265 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
1267 echo "</table><br>\n";
1270 startPortlet ('Add/update multiple ports');
1271 printOpFormIntro ('addMultiPorts');
1272 echo 'Format: <select name=format tabindex=201>';
1273 echo '<option value=c3600asy>Cisco 3600 async: sh line | inc TTY</option>';
1274 echo '<option value=fiwg selected>Foundry ServerIron/FastIron WorkGroup/Edge: sh int br</option>';
1275 echo '<option value=fisxii>Foundry FastIron SuperX/II4000: sh int br</option>';
1276 echo '<option value=ssv1>SSV:<interface name> <MAC address></option>';
1278 echo 'Default port type: ';
1279 printSelect (getPortTypes(), 'port_type', getConfigVar ('default_port_type'), 202);
1280 echo "<input type=submit value='Parse output' tabindex=204><br>\n";
1281 echo "<textarea name=input cols=100 rows=50 tabindex=203></textarea><br>\n";
1286 function renderIPv4ForObject ($object_id)
1288 function printNewItemTR ()
1291 printOpFormIntro ('addIPv4Allocation');
1293 printImageHREF ('add', 'allocate', TRUE);
1295 echo "<td class=tdleft><input type='text' size='10' name='bond_name' tabindex=100></td>\n";
1296 echo "<td class=tdleft><input type=text name='ip' tabindex=101></td>\n";
1297 echo "<td colspan=2> </td><td>";
1298 printSelect ($aat, 'bond_type', NULL, 102);
1299 echo "</td><td> </td><td>";
1300 printImageHREF ('add', 'allocate', TRUE, 103);
1301 echo "</td></tr></form>";
1304 showMessageOrError();
1305 startPortlet ('Allocations');
1306 $alloclist = getObjectIPv4Allocations ($object_id);
1307 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
1308 echo '<tr><th> </th><th>OS interface</th><th>IP address</th>';
1309 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
1310 echo '<th>network</th><th>routed by</th>';
1311 echo '<th>type</th><th>misc</th><th> </th></tr>';
1313 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
1315 foreach ($alloclist as $dottedquad => $alloc)
1317 $class = $alloc['addrinfo']['class'];
1318 $netid = getIPv4AddressNetworkId ($dottedquad);
1319 if (NULL !== $netid)
1321 $netinfo = getIPv4NetworkInfo ($netid);
1322 loadIPv4AddrList ($netinfo);
1324 printOpFormIntro ('updIPv4Allocation', array ('ip' => $dottedquad));
1325 echo "<tr class='$class' valign=top><td><a href='".makeHrefProcess(array('op'=>'delIPv4Allocation', 'ip'=>$dottedquad, 'object_id'=>$object_id))."'>";
1326 printImageHREF ('delete', 'Delete this IPv4 address');
1328 echo "<td class=tdleft><input type='text' name='bond_name' value='${alloc['osif']}' size=10></td><td class=tdleft>";
1329 if (NULL !== $netid)
1330 echo "<a href='".makeHref(array('page'=>'ipaddress', 'ip'=>$dottedquad))."'>${dottedquad}</a>";
1333 if (getConfigVar ('EXT_IPV4_VIEW') != 'yes')
1334 echo '<small>/' . (NULL === $netid ?
'??' : $netinfo['mask']) . '</small>';
1335 if (!empty ($alloc['addrinfo']['name']))
1336 echo ' (' . niftyString ($alloc['addrinfo']['name']) . ')';
1338 // FIXME: this a copy-and-paste from renderRackObject()
1339 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
1341 if (NULL === $netid)
1342 echo '<td class=sparenetwork>N/A</td><td class=sparenetwork>N/A</td>';
1346 renderIPv4NetCell ($netinfo);
1348 // filter out self-allocation
1349 $other_routers = array();
1350 foreach (findRouters ($netinfo['addrlist']) as $router)
1351 if ($router['id'] != $object_id)
1352 $other_routers[] = $router;
1353 if (count ($other_routers))
1354 printRoutersTD ($other_routers);
1356 echo "<td> </td>";
1360 printSelect ($aat, 'bond_type', $alloc['type']);
1363 if ($alloc['addrinfo']['reserved'] == 'yes')
1365 echo $prefix . '<strong>RESERVED</strong>';
1368 foreach ($alloc['addrinfo']['allocs'] as $allocpeer)
1370 if ($allocpeer['object_id'] == $object_id)
1372 echo $prefix . "<a href='".makeHref(array('page'=>'object', 'object_id'=>$allocpeer['object_id']))."'>";
1373 if (!empty ($allocpeer['osif']))
1374 echo $allocpeer['osif'] . '@';
1375 echo $allocpeer['object_name'] . '</a>';
1379 printImageHREF ('save', 'Save changes', TRUE);
1380 echo "</td></form></tr>\n";
1382 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
1385 echo "</table><br>\n";
1390 // Log structure versions:
1391 // 1: the whole structure is a list of code-message pairs
1392 // 2 and later: there's a "v" field set, which indicates the version
1393 // 2: there's a "m" list set to hold message code and optional arguments
1394 function printLog ($log)
1398 case !isset ($log['v']):
1399 case $log['v'] == 1:
1400 foreach ($log as $key => $record)
1402 echo "<div class=msg_${record['code']}>${record['message']}</div>";
1404 case $log['v'] == 2:
1407 // records 0~99 with success messages
1408 0 => array ('code' => 'success', 'format' => '%s'),
1409 1 => array ('code' => 'success', 'format' => '%u new records done, %u already existed'),
1410 2 => array ('code' => 'success', 'format' => 'NATv4 rule was successfully added.'),
1411 3 => array ('code' => 'success', 'format' => 'NATv4 rule was successfully deleted.'),
1412 4 => array ('code' => 'success', 'format' => 'NATv4 rule was successfully updated'),
1413 5 => array ('code' => 'success', 'format' => 'Port %s was added successfully'),
1414 6 => array ('code' => 'success', 'format' => 'Port %s was updated successfully'),
1415 7 => array ('code' => 'success', 'format' => 'Port %s was deleted successfully'),
1416 8 => array ('code' => 'success', 'format' => 'Port %s successfully linked with port %s at object %s'),
1417 9 => array ('code' => 'success', 'format' => 'Port %s was successfully unlinked from %s@%s'),
1418 10 => array ('code' => 'success', 'format' => 'Added %u ports, updated %u ports, encountered %u errors.'),
1419 11 => array ('code' => 'success', 'format' => 'Reservation removed.'),
1420 12 => array ('code' => 'success', 'format' => 'allocation updated'),
1421 13 => array ('code' => 'success', 'format' => 'allocated'),
1422 14 => array ('code' => 'success', 'format' => 'deallocated'),
1423 15 => array ('code' => 'success', 'format' => 'Reset succeeded.'),
1424 16 => array ('code' => 'success', 'format' => 'Update done'),
1425 17 => array ('code' => 'success', 'format' => 'Update(s) succeeded.'),
1426 18 => array ('code' => 'success', 'format' => 'Load balancer was successfully added'),
1427 19 => array ('code' => 'success', 'format' => 'Load balancer was successfully deleted'),
1428 20 => array ('code' => 'success', 'format' => 'Load balancer info was successfully updated'),
1429 21 => array ('code' => 'success', 'format' => 'Generation complete'),
1430 22 => array ('code' => 'success', 'format' => 'Chained %u tags'),
1431 23 => array ('code' => 'success', 'format' => 'IPv4 prefix successfully added'),
1432 24 => array ('code' => 'success', 'format' => 'IPv4 prefix deleted'),
1433 25 => array ('code' => 'success', 'format' => 'IPv4 prefix updated'),
1434 26 => array ('code' => 'success', 'format' => '%u IP address(es) were successfully updated'),
1435 27 => array ('code' => 'success', 'format' => 'IPv4 address updated'),
1436 28 => array ('code' => 'success', 'format' => 'Virtual service was successfully created'),
1437 29 => array ('code' => 'success', 'format' => 'Virtual service was successfully deleted'),
1438 30 => array ('code' => 'success', 'format' => 'Virtual service was successfully updated'),
1439 31 => array ('code' => 'success', 'format' => 'RS pool was successfully created'),
1440 32 => array ('code' => 'success', 'format' => 'RS pool was successfully deleted'),
1441 33 => array ('code' => 'success', 'format' => 'RS pool was successfully updated'),
1442 34 => array ('code' => 'success', 'format' => 'Real server was successfully added'),
1443 35 => array ('code' => 'success', 'format' => 'Real server was successfully deleted'),
1444 36 => array ('code' => 'success', 'format' => 'Real server was successfully updated'),
1445 37 => array ('code' => 'success', 'format' => 'Successfully added %u real servers'),
1446 38 => array ('code' => 'success', 'format' => '%u real server(s) were successfully (de)activated'),
1447 39 => array ('code' => 'success', 'format' => 'User account %s updated.'),
1448 40 => array ('code' => 'success', 'format' => 'User account %s created.'),
1451 43 => array ('code' => 'success', 'format' => 'Saved successfully.'),
1452 44 => array ('code' => 'success', 'format' => '%s failures and %s successfull changes.'),
1453 45 => array ('code' => 'success', 'format' => "Attribute '%s' created."),
1454 46 => array ('code' => 'success', 'format' => 'Rename successful.'),
1455 47 => array ('code' => 'success', 'format' => 'Attribute was deleted.'),
1456 48 => array ('code' => 'success', 'format' => 'Supplement succeeded.'),
1457 49 => array ('code' => 'success', 'format' => 'Reduction succeeded.'),
1458 50 => array ('code' => 'success', 'format' => 'Reduction succeeded.'),
1459 51 => array ('code' => 'success', 'format' => 'Update succeeded.'),
1460 52 => array ('code' => 'success', 'format' => 'Supplement succeeded.'),
1461 53 => array ('code' => 'success', 'format' => 'Chapter was deleted.'),
1462 54 => array ('code' => 'success', 'format' => 'Chapter was updated.'),
1463 55 => array ('code' => 'success', 'format' => 'Chapter was added.'),
1464 56 => array ('code' => 'success', 'format' => 'Update succeeded.'),
1465 57 => array ('code' => 'success', 'format' => 'Reset complete'),
1466 58 => array ('code' => 'success', 'format' => "Deleted tag '%s'."),
1467 59 => array ('code' => 'success', 'format' => "Created tag '%s'."),
1468 60 => array ('code' => 'success', 'format' => "Updated tag '%s'."),
1469 61 => array ('code' => 'success', 'format' => 'Password changed successfully.'),
1470 62 => array ('code' => 'success', 'format' => 'gw: %s'),
1471 63 => array ('code' => 'success', 'format' => '%u change request(s) have been processed'),
1472 64 => array ('code' => 'success', 'format' => 'Port %s@%s has been assigned to VLAN %u'),
1473 65 => array ('code' => 'success', 'format' => "Added new rack '%s'"),
1474 66 => array ('code' => 'success', 'format' => "File sent Ok via handler '%s'"),
1475 67 => array ('code' => 'success', 'format' => "Tag rolling done, %u objects involved"),
1476 68 => array ('code' => 'success', 'format' => "Updated rack '%s'"),
1477 69 => array ('code' => 'success', 'format' => 'File "%s" was added successfully'),
1478 70 => array ('code' => 'success', 'format' => 'File "%s" was updated successfully'),
1479 71 => array ('code' => 'success', 'format' => 'File "%s" was linked successfully'),
1480 72 => array ('code' => 'success', 'format' => 'File was unlinked successfully'),
1481 73 => array ('code' => 'success', 'format' => 'File "%s" was deleted successfully'),
1482 74 => array ('code' => 'success', 'format' => 'Row "%s" was added successfully'),
1483 75 => array ('code' => 'success', 'format' => 'Row "%s" was updated successfully'),
1484 76 => array ('code' => 'success', 'format' => 'Object "%s" was deleted successfully'),
1485 77 => array ('code' => 'success', 'format' => 'Row "%s" was deleted successfully'),
1486 78 => array ('code' => 'success', 'format' => 'File "%s" saved Ok'),
1487 79 => array ('code' => 'success', 'format' => 'Rack "%s" was deleted successfully'),
1488 80 => array ('code' => 'success', 'format' => "Added new object '%s'"),
1490 // records 100~199 with fatal error messages
1491 100 => array ('code' => 'error', 'format' => '%s'),
1492 101 => array ('code' => 'error', 'format' => 'Port name cannot be empty'),
1493 102 => array ('code' => 'error', 'format' => "Error creating user account '%s'"),
1494 103 => array ('code' => 'error', 'format' => 'User not found!'),
1495 104 => array ('code' => 'error', 'format' => "Error updating user account '%s'"),
1499 108 => array ('code' => 'error', 'format' => '%u failures and %u successfull changes.'),
1500 109 => array ('code' => 'error', 'format' => 'Update failed!'),
1501 110 => array ('code' => 'error', 'format' => 'Supplement failed!'),
1502 111 => array ('code' => 'error', 'format' => 'Reduction failed!'),
1503 112 => array ('code' => 'error', 'format' => 'Error adding chapter.'),
1504 113 => array ('code' => 'error', 'format' => 'Error updating chapter.'),
1505 114 => array ('code' => 'error', 'format' => 'Error deleting chapter.'),
1506 115 => array ('code' => 'error', 'format' => 'Error renaming attribute.'),
1507 116 => array ('code' => 'error', 'format' => 'Error creating attribute.'),
1508 117 => array ('code' => 'error', 'format' => 'Error deleting attribute.'),
1509 118 => array ('code' => 'error', 'format' => 'Supplement failed!'),
1510 119 => array ('code' => 'error', 'format' => 'Reduction failed!'),
1511 120 => array ('code' => 'error', 'format' => 'Reset failed!'),
1512 121 => array ('code' => 'error', 'format' => 'commitUpdateObject() failed'),
1513 122 => array ('code' => 'error', 'format' => 'One or more update(s) failed!'),
1514 123 => array ('code' => 'error', 'format' => 'Cannot process submitted data: unknown format code.'),
1515 124 => array ('code' => 'error', 'format' => 'Error removing reservation!'),
1516 125 => array ('code' => 'error', 'format' => "Update failed with error: '%s'"),
1517 126 => array ('code' => 'error', 'format' => 'addRStoRSPool() failed'),
1518 127 => array ('code' => 'error', 'format' => 'Added %u real servers and encountered %u errors'),
1519 128 => array ('code' => 'error', 'format' => 'commitDeleteRS() failed'),
1520 129 => array ('code' => 'error', 'format' => 'commitDeleteLB() failed'),
1521 130 => array ('code' => 'error', 'format' => 'commitDeleteVS() failed'),
1522 131 => array ('code' => 'error', 'format' => 'invalid format requested'),
1523 132 => array ('code' => 'error', 'format' => 'invalid protocol'),
1524 133 => array ('code' => 'error', 'format' => 'commitUpdateRS() failed'),
1525 134 => array ('code' => 'error', 'format' => 'commitUpdateLB() failed'),
1526 135 => array ('code' => 'error', 'format' => 'commitUpdateVS() failed'),
1527 136 => array ('code' => 'error', 'format' => 'addLBtoRSPool() failed'),
1528 137 => array ('code' => 'error', 'format' => 'addLBtoRSPool() failed'),
1529 138 => array ('code' => 'error', 'format' => 'commitDeleteRSPool() failed'),
1530 139 => array ('code' => 'error', 'format' => 'commitUpdateRSPool() failed'),
1531 140 => array ('code' => 'error', 'format' => 'Encountered %u errors, (de)activated %u real servers'),
1532 141 => array ('code' => 'error', 'format' => 'Encountered %u errors, updated %u IP address(es)'),
1533 142 => array ('code' => 'error', 'format' => 'executeAutoPorts() failed'),
1534 143 => array ('code' => 'error', 'format' => 'Tried chaining %u tags, but experienced %u errors.'),
1535 144 => array ('code' => 'error', 'format' => "Error deleting tag: '%s'"),
1536 145 => array ('code' => 'error', 'format' => "Invalid tag name '%s'"),
1538 147 => array ('code' => 'error', 'format' => "Could not create tag '%s': %s"),
1539 148 => array ('code' => 'error', 'format' => "Could not update tag '%s': %s"),
1540 149 => array ('code' => 'error', 'format' => 'Turing test failed'),
1541 150 => array ('code' => 'error', 'format' => 'Can only change password under DB authentication.'),
1542 151 => array ('code' => 'error', 'format' => 'Old password doesn\'t match.'),
1543 152 => array ('code' => 'error', 'format' => 'New passwords don\'t match.'),
1544 153 => array ('code' => 'error', 'format' => 'Password change failed.'),
1545 154 => array ('code' => 'error', 'format' => "Verification error: %s"),
1546 155 => array ('code' => 'error', 'format' => 'Save failed.'),
1547 156 => array ('code' => 'error', 'format' => 'getSwitchVLANs() failed'),
1548 157 => array ('code' => 'error', 'format' => 'operation not permitted'),
1549 158 => array ('code' => 'error', 'format' => 'Ignoring malformed record #%u in form submit'),
1550 159 => array ('code' => 'error', 'format' => 'Permission denied moving port %s from VLAN%u to VLAN%u'),
1551 160 => array ('code' => 'error', 'format' => 'Invalid arguments'),
1552 161 => array ('code' => 'error', 'format' => 'Endpoint not found. Please either set FQDN attribute or assign an IP address to the object.'),
1553 162 => array ('code' => 'error', 'format' => 'More than one IP address is assigned to this object, please configure FQDN attribute.'),
1554 163 => array ('code' => 'error', 'format' => 'Failed to get any response from queryGateway() or the gateway died'),
1555 164 => array ('code' => 'error', 'format' => 'Gateway failure: %s.'),
1556 165 => array ('code' => 'error', 'format' => 'Gateway failure: malformed reply.'),
1557 166 => array ('code' => 'error', 'format' => 'gw: %s'),
1558 167 => array ('code' => 'error', 'format' => 'Could not find port %s'),
1559 168 => array ('code' => 'error', 'format' => 'Port %s is a trunk'),
1560 169 => array ('code' => 'error', 'format' => 'Failed to configure %s, connector returned code %u'),
1561 170 => array ('code' => 'error', 'format' => 'There is no network for IP address "%s"'),
1562 171 => array ('code' => 'error', 'format' => "Failed creating rack '%s'. Already exists in this row?"),
1563 172 => array ('code' => 'error', 'format' => 'Malformed request'),
1564 173 => array ('code' => 'error', 'format' => "Invalid IPv4 prefix '%s'"),
1565 174 => array ('code' => 'error', 'format' => 'Bad IPv4 address'),
1566 175 => array ('code' => 'error', 'format' => 'Invalid netmask'),
1567 176 => array ('code' => 'error', 'format' => 'This network already exists'),
1568 177 => array ('code' => 'error', 'format' => 'commitUpdateRack() failed'),
1569 178 => array ('code' => 'error', 'format' => 'file not found'),
1570 179 => array ('code' => 'error', 'format' => 'Declining outdated text. Re-edit the file for consistency.'),
1571 180 => array ('code' => 'error', 'format' => 'Error saving file, all changes lost!'),
1572 181 => array ('code' => 'error', 'format' => "file uploads not allowed, change 'file_uploads' parameter in php.ini"),
1573 182 => array ('code' => 'error', 'format' => 'SQL query failed: %s'),
1574 183 => array ('code' => 'error', 'format' => "Tag id '%s' does not exist."),
1575 184 => array ('code' => 'error', 'format' => 'Submitted form is invalid at line %u'),
1576 185 => array ('code' => 'error', 'format' => "Failed to add object '%s'"),
1577 186 => array ('code' => 'error', 'format' => 'Incomplete form has been ignored. Cheers.'),
1578 187 => array ('code' => 'error', 'format' => "Internal error in function '%s'"),
1580 // records 200~299 with warnings
1581 200 => array ('code' => 'warning', 'format' => '%s'),
1582 201 => array ('code' => 'warning', 'format' => 'nothing happened...'),
1583 202 => array ('code' => 'warning', 'format' => 'gw: %s'),
1584 203 => array ('code' => 'warning', 'format' => 'Port %s seems to be the first in VLAN %u at this switch.'),
1585 204 => array ('code' => 'warning', 'format' => 'Check uplink/downlink configuration for proper operation.'),
1586 205 => array ('code' => 'warning', 'format' => '%u change request(s) have been ignored'),
1587 206 => array ('code' => 'warning', 'format' => 'Rack is not empty'),
1588 207 => array ('code' => 'warning', 'format' => 'Ignored empty request'),
1591 // Handle the arguments. Is there any better way to do it?
1592 foreach ($log['m'] as $record)
1594 if (!isset ($record['c']) or !isset ($msginfo[$record['c']]))
1596 echo '<div class=msg_neutral>(this message was lost)</div>';
1599 if (isset ($record['a']))
1600 switch (count ($record['a']))
1605 $msginfo[$record['c']]['format'],
1612 $msginfo[$record['c']]['format'],
1620 $msginfo[$record['c']]['format'],
1630 $msginfo[$record['c']]['format'],
1639 $msgtext = $msginfo[$record['c']]['format'];
1640 echo '<div class=msg_' . $msginfo[$record['c']]['code'] . ">${msgtext}</div>";
1644 echo '<div class=msg_error>' . __FUNCTION__
. ': internal error</div>';
1650 The following conditions must be followed:
1651 1. We can mount onto free atoms only. This means: if any record for an atom
1652 already exists in RackSpace, it can't be used for mounting.
1653 2. We can't unmount from 'W' atoms. Operator should review appropriate comments
1654 and either delete them before unmounting or refuse to unmount the object.
1657 // We extensively use $_REQUEST in the function.
1658 function renderRackSpaceForObject ($object_id)
1660 $is_update = isset ($_REQUEST['rackmulti'][0]);
1661 $info = getObjectInfo ($object_id);
1664 showError ('getObjectInfo() failed', __FUNCTION__
);
1667 // Always process occupied racks plus racks chosen by user. First get racks with
1668 // already allocated rackspace...
1669 if (NULL === ($workingRacksData = getResidentRacksData ($object_id)))
1670 die; // some error already shown
1672 // ...and then add those chosen by user (if any).
1673 if (isset($_REQUEST['rackmulti']))
1674 foreach ($_REQUEST['rackmulti'] as $cand_id)
1676 if (!isset ($workingRacksData[$cand_id]))
1678 $rackData = getRackData ($cand_id);
1679 if ($rackData == NULL)
1681 showError ('getRackData() failed', __FUNCTION__
);
1684 $workingRacksData[$cand_id] = $rackData;
1688 printOpFormIntro ('updateObjectAllocation');
1690 // Do it only once...
1691 foreach ($workingRacksData as $rackId => &$rackData)
1693 applyObjectMountMask ($rackData, $object_id);
1694 echo "<input type=\"hidden\" name=\"rackmulti[]\" value=\"$rackId\">";
1696 // Now we workaround an old caveat: http://bugs.php.net/bug.php?id=37410
1699 // This is the time for rendering.
1700 showMessageOrError();
1702 // Main layout starts.
1703 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0><tr>";
1705 // Left portlet with rack list.
1706 echo "<td class=pcleft height='1%'>";
1707 startPortlet ('Racks');
1708 $allRacksData = listCells ('rack');
1709 if (count ($allRacksData) <= getConfigVar ('RACK_PRESELECT_THRESHOLD'))
1711 foreach (array_keys ($allRacksData) as $rack_id)
1713 $rackData = getRackData ($rack_id);
1714 if ($rackData == NULL)
1716 showError ('getRackData() failed', __FUNCTION__
);
1719 $workingRacksData[$rack_id] = $rackData;
1721 foreach ($workingRacksData as &$rackData)
1722 applyObjectMountMask ($rackData, $object_id);
1725 renderRackMultiSelect ('rackmulti[]', $allRacksData, array_keys ($workingRacksData));
1731 // Middle portlet with comment and submit.
1732 echo "<td class=pcleft>";
1733 startPortlet ('Comment');
1734 echo "<textarea name=comment rows=10 cols=40></textarea><br>\n";
1735 echo "<input type=submit value='Save' name=got_atoms>\n";
1741 // Right portlet with rendered racks. If this form submit is not final, we have to
1742 // reflect the former state of the grid in current form.
1743 echo "<td class=pcright rowspan=2 height='1%'>";
1744 startPortlet ('Working copy');
1745 echo '<table border=0 cellspacing=10 align=center><tr>';
1746 foreach ($workingRacksData as $rack_id => $rackData)
1748 // Order is important here: only original allocation is highlighted.
1749 highlightObject ($rackData, $object_id);
1750 markupAtomGrid ($rackData, 'T');
1751 // If we have a form processed, discard user input and show new database
1754 mergeGridFormToRack ($rackData);
1755 echo "<td valign=top>";
1756 echo "<center>\n<h2>${rackData['name']}</h2>\n";
1757 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
1758 echo "<tr><th width='10%'> </th>";
1759 echo "<th width='20%'><a href='javascript:;' onclick=\"toggleColumnOfAtoms('${rack_id}', '0', ${rackData['height']})\">Front</a></th>";
1760 echo "<th width='50%'><a href='javascript:;' onclick=\"toggleColumnOfAtoms('${rack_id}', '1', ${rackData['height']})\">Interior</a></th>";
1761 echo "<th width='20%'><a href='javascript:;' onclick=\"toggleColumnOfAtoms('${rack_id}', '2', ${rackData['height']})\">Back</a></th></tr>\n";
1762 renderAtomGrid ($rackData);
1763 echo "<tr><th width='10%'> </th>";
1764 echo "<th width='20%'><a href='javascript:;' onclick=\"toggleColumnOfAtoms('${rack_id}', '0', ${rackData['height']})\">Front</a></th>";
1765 echo "<th width='50%'><a href='javascript:;' onclick=\"toggleColumnOfAtoms('${rack_id}', '1', ${rackData['height']})\">Interior</a></th>";
1766 echo "<th width='20%'><a href='javascript:;' onclick=\"toggleColumnOfAtoms('${rack_id}', '2', ${rackData['height']})\">Back</a></th></tr>\n";
1767 echo "</table></center>\n";
1770 echo "</tr></table>";
1776 echo "</tr></table>\n";
1779 function renderMolecule ($mdata, $object_id)
1782 $rackpack = array();
1784 foreach ($mdata as $rua)
1786 $rack_id = $rua['rack_id'];
1787 $unit_no = $rua['unit_no'];
1788 $atom = $rua['atom'];
1789 if (!isset ($rackpack[$rack_id]))
1791 $rackData = getRackData ($rack_id);
1792 for ($i = $rackData['height']; $i > 0; $i--)
1793 for ($locidx = 0; $locidx < 3; $locidx++
)
1794 $rackData[$i][$locidx]['state'] = 'F';
1795 $rackpack[$rack_id] = $rackData;
1797 $rackpack[$rack_id][$unit_no][$loclist[$atom]]['state'] = 'T';
1798 $rackpack[$rack_id][$unit_no][$loclist[$atom]]['object_id'] = $object_id;
1800 // now we have some racks to render
1801 foreach ($rackpack as $rackData)
1803 markAllSpans ($rackData);
1804 echo "<table class=molecule cellspacing=0>\n";
1805 echo "<caption>${rackData['name']}</caption>\n";
1806 echo "<tr><th width='10%'> </th><th width='20%'>Front</th><th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
1807 for ($i = $rackData['height']; $i > 0; $i--)
1809 echo "<tr><th>$i</th>";
1810 for ($locidx = 0; $locidx < 3; $locidx++
)
1812 $state = $rackData[$i][$locidx]['state'];
1813 echo "<td class=state_${state}> </td>\n";
1821 function renderEmptyPortsSelect ($port_id, $type_id)
1823 $ports = getEmptyPortsOfType($type_id);
1824 usort($ports, 'sortEmptyPorts');
1825 foreach ($ports as $port)
1827 if ($port_id == $port['Port_id'])
1829 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";
1833 function renderDepot ()
1835 global $pageno, $nextorder;
1836 showMessageOrError();
1837 $cellfilter = getCellFilter();
1838 $objects = filterCellList (listCells ('object'), $cellfilter['expression']);
1840 echo "<table border=0 class=objectview>\n";
1841 echo "<tr><td class=pcleft>";
1843 startPortlet ('Objects (' . count ($objects) . ')');
1844 if ($objects === NULL)
1846 showError ('Fatal error retrieving object list', __FUNCTION__
);
1849 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1850 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>Barcode</th><th>Row/Rack</th></tr>';
1852 foreach ($objects as $obj)
1854 if (isset ($_REQUEST['hl_object_id']) and $_REQUEST['hl_object_id'] == $obj['id'])
1855 $secondclass = 'tdleft port_highlight';
1857 $secondclass = 'tdleft';
1858 $tags = loadEntityTags ('object', $obj['id']);
1859 echo "<tr class=row_${order} valign=top><td class='${secondclass}'><a href='".makeHref(array('page'=>'object', 'object_id'=>$obj['id']))."'><strong>${obj['dname']}</strong></a>";
1861 echo '<br><small>' . serializeTags ($tags, makeHref(array('page'=>$pageno, 'tab'=>'default')) . '&') . '</small>';
1862 echo "</td><td class='${secondclass}'>${obj['label']}</td>";
1863 echo "<td class='${secondclass}'>${obj['asset_no']}</td>";
1864 echo "<td class='${secondclass}'>${obj['barcode']}</td>";
1865 if ($obj['rack_id'])
1866 echo "<td class='${secondclass}'><a href='".makeHref(array('page'=>'row', 'row_id'=>$obj['row_id']))."'>${obj['Row_name']}</a>/<a href='".makeHref(array('page'=>'rack', 'rack_id'=>$obj['rack_id']))."'>${obj['Rack_name']}</a></td>";
1868 echo "<td class='${secondclass}'>Unmounted</td>";
1870 $order = $nextorder[$order];
1875 echo "</td><td class=pcright width='25%'>";
1877 renderCellFilterPortlet ($cellfilter, 'object');
1878 echo "</td></tr></table>\n";
1881 // History viewer for history-enabled simple dictionaries.
1882 function renderHistory ($object_type, $object_id)
1884 switch ($object_type)
1887 $query = "select ctime, user_name, name, comment from RackRowHistory where id = ${object_id} order by ctime";
1888 $header = '<tr><th>change time</th><th>author</th><th>rack row name</th><th>rack row comment</th></tr>';
1893 "select ctime, user_name, rh.name, rr.name as name, rh.height, rh.comment " .
1894 "from RackHistory as rh left join RackRow as rr on rh.row_id = rr.id " .
1895 "where rh.id = ${object_id} order by ctime";
1896 $header = '<tr><th>change time</th><th>author</th><th>rack name</th><th>rack row name</th><th>rack height</th><th>rack comment</th></tr>';
1901 "select ctime, user_name, RackObjectHistory.name as name, label, barcode, asset_no, has_problems, dict_value, comment " .
1902 "from RackObjectHistory inner join Dictionary on objtype_id = dict_key join Chapter on Dictionary.chapter_id = Chapter.id " .
1903 "where Chapter.name = 'RackObjectType' and RackObjectHistory.id=${object_id} order by ctime";
1904 $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>has problems?</th><th>object type</th><th>comment</th></tr>';
1908 showError ("Uknown object type '${object_type}'", __FUNCTION__
);
1912 $result = $dbxlink->query ($query);
1913 if ($result == NULL)
1915 showError ('SQL query failed', __FUNCTION__
);
1918 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1922 while ($row = $result->fetch (PDO
::FETCH_NUM
))
1924 echo "<tr class=row_${order}><td>${row[0]}</td>";
1925 for ($i = 1; $i <= $extra; $i++
)
1926 echo "<td>" . $row[$i] . "</td>";
1928 $order = $nextorder[$order];
1930 echo "</table><br>\n";
1933 function renderRackspaceHistory ()
1935 global $nextorder, $pageno, $tabno;
1937 $history = getRackspaceHistory();
1938 // Show the last operation by default.
1939 if (isset ($_REQUEST['op_id']))
1940 $op_id = $_REQUEST['op_id'];
1941 elseif (isset ($history[0]['mo_id']))
1942 $op_id = $history[0]['mo_id'];
1949 list ($omid, $nmid) = getOperationMolecules ($op_id);
1951 // Main layout starts.
1952 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
1954 // Left top portlet with old allocation.
1955 echo "<tr><td class=pcleft>";
1956 startPortlet ('Old allocation');
1959 $oldMolecule = getMolecule ($omid);
1960 renderMolecule ($oldMolecule, $object_id);
1966 echo '</td><td class=pcright>';
1968 // Right top portlet with new allocation
1969 startPortlet ('New allocation');
1972 $newMolecule = getMolecule ($nmid);
1973 renderMolecule ($newMolecule, $object_id);
1979 echo '</td></tr><tr><td colspan=2>';
1981 // Bottom portlet with list
1983 startPortlet ('Rackspace allocation history');
1984 echo "<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>\n";
1985 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";
1986 foreach ($history as $row)
1988 if ($row['mo_id'] == $op_id)
1991 $class = "row_${order}";
1992 echo "<tr class=${class}><td><a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno, 'op_id'=>$row['mo_id']))."'>${row['ctime']}</a></td>";
1993 echo "<td>${row['user_name']}</td>";
1994 echo "<td>${row['ro_id']}</td><td>${row['objtype_name']}</td><td>${row['name']}</td><td>${row['comment']}</td>\n";
1996 $order = $nextorder[$order];
2001 echo '</td></tr></table>';
2004 function renderIPv4SpaceRecords ($tree, &$tagcache, $baseurl, $target = 0, $level = 1)
2006 $self = __FUNCTION__
;
2007 foreach ($tree as $item)
2009 $total = $item['addrt'];
2010 if (getConfigVar ('IPV4_TREE_SHOW_USAGE') == 'yes')
2012 loadIPv4AddrList ($item); // necessary to compute router list and address counter
2013 $used = $item['addrc'];
2017 $item['addrlist'] = array();
2020 if (isset ($item['id']))
2022 if ($item['symbol'] == 'node-collapsed')
2023 $expandurl = "${baseurl}&eid=" . $item['id'] . "#netid" . $item['id'];
2024 elseif ($item['symbol'] == 'node-expanded')
2025 $expandurl = $baseurl . ($item['parent_id'] ?
"&eid=${item['parent_id']}#netid${item['parent_id']}" : '');
2028 echo "<tr valign=top>";
2029 printIPv4NetInfoTDs ($item, 'tdleft', $level, $item['symbol'], $expandurl);
2030 echo "<td class=tdcenter>";
2031 if ($target == $item['id'])
2032 echo "<a name=netid${target}></a>";
2033 if (getConfigVar ('IPV4_TREE_SHOW_USAGE') == 'yes')
2035 renderProgressBar ($total ?
$used/$total : 0);
2036 echo "<br><small>${used}/${total}</small>";
2039 echo "<small>${total}</small>";
2041 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
2042 printRoutersTD (findRouters ($item['addrlist']), $tagcache);
2044 if ($item['symbol'] == 'node-expanded' or $item['symbol'] == 'node-expanded-static')
2045 $self ($item['kids'], $tagcache, $baseurl, $target, $level +
1);
2049 echo "<tr valign=top>";
2050 printIPv4NetInfoTDs ($item, 'tdleft sparenetwork', $level, $item['symbol']);
2051 echo "<td class=tdcenter>";
2052 if (getConfigVar ('IPV4_TREE_SHOW_USAGE') == 'yes')
2054 renderProgressBar ($used/$total, 'sparenetwork');
2055 echo "<br><small>${used}/${total}</small>";
2058 echo "<small>${total}</small>";
2059 echo "</td><td> </td></tr>";
2064 function renderIPv4Space ()
2066 global $pageno, $tabno;
2067 $cellfilter = getCellFilter();
2068 $netlist = filterCellList (listCells ('ipv4net'), $cellfilter['expression']);
2069 array_walk ($netlist, 'amplifyCell');
2071 $netcount = count ($netlist);
2072 // expand request can take either natural values or "ALL". Zero means no expanding.
2073 $eid = isset ($_REQUEST['eid']) ?
$_REQUEST['eid'] : 0;
2074 $tree = prepareIPv4Tree ($netlist, $eid);
2076 echo "<table border=0 class=objectview>\n";
2077 echo "<tr><td class=pcleft>";
2078 startPortlet ("networks (${netcount})");
2081 echo 'auto-collapsing at threshold ' . getConfigVar ('TREE_THRESHOLD') . " (<a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno, 'eid'=>'ALL'))."'>expand all</a>)";
2082 elseif ($eid === 'ALL')
2083 echo "expanding all (<a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno))."'>auto-collapse</a>)";
2086 $netinfo = getIPv4NetworkInfo ($eid);
2087 echo "expanding ${netinfo['ip']}/${netinfo['mask']} (<a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno))."'>auto-collapse</a> / <a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno, 'eid'=>'ALL'))."'>expand all</a>)";
2089 echo "</h4><table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
2090 echo "<tr><th>prefix</th><th>name/tags</th><th>capacity</th>";
2091 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
2092 echo "<th>routed by</th>";
2094 $tagcache = array();
2095 $baseurl = makeHref(array('page'=>$pageno, 'tab'=>$tabno)) . $cellfilter['urlextra'];
2096 renderIPv4SpaceRecords ($tree, $tagcache, $baseurl, $eid);
2099 echo '</td><td class=pcright>';
2100 renderCellFilterPortlet ($cellfilter, 'ipv4net');
2101 echo "</td></tr></table>\n";
2104 function renderIPv4SLB ()
2106 global $page, $nextorder;
2108 startPortlet ('SLB configuration');
2109 echo "<table border=0 width='100%'><tr>";
2110 foreach (array ('ipv4vslist', 'ipv4rsplist', 'rservers', 'lbs') as $pno)
2111 echo "<td><h3><a href='".makeHref(array('page'=>$pno))."'>" . $page[$pno]['title'] . "</a></h3></td>";
2112 echo '</tr></table>';
2115 $summary = getSLBSummary();
2116 startPortlet ('SLB tactical overview');
2117 // A single id-keyed array isn't used here to preserve existing
2118 // order of LBs returned by getSLBSummary()
2121 foreach ($summary as $vipdata)
2122 foreach (array_keys ($vipdata['lblist']) as $lb_object_id)
2123 if (!in_array ($lb_object_id, $lblist))
2125 $oi = getObjectInfo ($lb_object_id);
2126 $lbdname[$lb_object_id] = $oi['dname'];
2127 $lblist[] = $lb_object_id;
2129 if (!count ($summary))
2130 echo 'none configured';
2134 echo "<table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
2135 echo "<tr valign=top><td> </td>";
2136 foreach ($lblist as $lb_object_id)
2138 #echo "<th><a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$lb_object_id))."'>" . $lbdname[$lb_object_id] . "</a></th>";
2140 renderLBCell ($lb_object_id);
2144 foreach ($summary as $vsid => $vsdata)
2146 echo "<tr class=row_${order}><td class=tdleft>";
2147 renderVSCell ($vsid);
2149 foreach ($lblist as $lb_object_id)
2151 echo '<td class=tdleft>';
2152 if (!isset ($vsdata['lblist'][$lb_object_id]))
2156 echo $vsdata['lblist'][$lb_object_id]['size'];
2157 // echo " (<a href='".makeHref(array('page'=>'ipv4rspool', 'pool_id'=>$vsdata['lblist'][$lb_object_id]['id'])). "'>";
2158 // echo $vsdata['lblist'][$lb_object_id]['name'] . '</a>)';
2163 $order = $nextorder[$order];
2170 function renderIPv4SpaceEditor ()
2172 showMessageOrError();
2176 <script type
="text/javascript">
2178 document
.add_new_range
.range
.setAttribute('match', "^\\d\\d?\\d?\\.\\d\\d?\\d?\\.\\d\\d?\\d?\\.\\d\\d?\\d?\\/\\d\\d?$");
2186 startPortlet ("Add new");
2187 echo '<table border=0 cellpadding=10 align=center>';
2188 // This form requires a name, so JavaScript validator can find it.
2189 // No printOpFormIntro() hence
2190 echo "<form method=post name='add_new_range' action='".makeHrefProcess()."'>\n";
2191 echo "<input type=hidden name=op value=addIPv4Prefix>\n";
2193 echo '<tr><td rowspan=4><h3>assign tags</h3>';
2194 renderNewEntityTags();
2197 echo "<th class=tdright>prefix</th><td class=tdleft><input type=text name='range' size=18 class='live-validate' tabindex=1></td>";
2198 echo "<tr><th class=tdright>name</th><td class=tdleft><input type=text name='name' size='20' tabindex=2></td></tr>";
2199 echo "<tr><th class=tdright>connected network</th><td class=tdleft><input type=checkbox name='is_bcast' tabindex=3></td></tr>";
2200 echo "<tr><td colspan=2>";
2201 printImageHREF ('CREATE', 'Add a new network', TRUE, 4);
2203 echo "</form></table><br><br>\n";
2206 $addrspaceList = listCells ('ipv4net');
2207 array_walk ($addrspaceList, 'amplifyCell');
2208 if (count ($addrspaceList))
2210 startPortlet ('Manage existing (' . count ($addrspaceList) . ')');
2211 echo "<table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
2212 echo "<tr><th> </th><th>prefix</th><th>name</th><th> </th></tr>";
2213 foreach ($addrspaceList as $netinfo)
2215 echo "<form method=post action='".makeHrefProcess(array('op'=>'updIPv4Prefix', 'id'=>$netinfo['id']))."'>";
2216 echo "<tr valign=top><td>";
2217 if (getConfigVar ('IPV4_JAYWALK') == 'yes')
2219 echo "<a href='".makeHrefProcess(array('op'=>'delIPv4Prefix', 'id'=>$netinfo['id']))."'>";
2220 printImageHREF ('destroy', 'Delete this prefix');
2223 else // only render clickable image for empty networks
2225 $netdata = getIPv4NetworkInfo ($netinfo['id']);
2226 loadIPv4AddrList ($netdata);
2227 if (count ($netdata['addrlist']))
2228 printImageHREF ('nodestroy', 'There are ' . count ($netdata['addrlist']) . ' allocations inside');
2231 echo "<a href='".makeHrefProcess(array('op'=>'delIPv4Prefix', 'id'=>$netinfo['id']))."'>";
2232 printImageHREF ('destroy', 'Delete this prefix');
2237 echo "</td>\n<td class=tdleft>${netinfo['ip']}/${netinfo['mask']}</td>";
2238 echo "<td><input type=text name=name size=40 value='${netinfo['name']}'>";
2240 printImageHREF ('save', 'Save changes', TRUE);
2241 echo "</td></tr></form>\n";
2248 function renderIPv4Network ($id)
2250 global $pageno, $tabno, $aac2;
2251 $netmaskbylen = array
2253 32 => '255.255.255.255',
2254 31 => '255.255.255.254',
2255 30 => '255.255.255.252',
2256 29 => '255.255.255.248',
2257 28 => '255.255.255.240',
2258 27 => '255.255.255.224',
2259 26 => '255.255.255.192',
2260 25 => '255.255.255.128',
2261 24 => '255.255.255.0',
2262 23 => '255.255.254.0',
2263 22 => '255.255.252.0',
2264 21 => '255.255.248.0',
2265 20 => '255.255.240.0',
2266 19 => '255.255.224.0',
2267 18 => '255.255.192.0',
2268 17 => '255.255.128.0',
2269 16 => '255.255.0.0',
2270 15 => '255.254.0.0',
2271 14 => '255.252.0.0',
2272 13 => '255.248.0.0',
2273 12 => '255.240.0.0',
2274 11 => '255.224.0.0',
2275 10 => '255.192.0.0',
2286 $wildcardbylen = array
2303 17 => '0.0.127.255',
2305 15 => '0.1.255.255',
2306 14 => '0.3.255.255',
2307 13 => '0.7.255.255',
2308 12 => '0.15.255.255',
2309 11 => '0.31.255.255',
2310 10 => '0.63.255.255',
2311 9 => '0.127.255.255',
2312 8 => '0.255.255.255',
2313 7 => '1.255.255.255',
2314 6 => '3.255.255.255',
2315 5 => '7.255.255.255',
2316 4 => '15.255.255.255',
2317 3 => '31.255.255.255',
2318 2 => '63.255.255.255',
2319 1 => '127.255.255.255'
2321 $maxperpage = getConfigVar ('IPV4_ADDRS_PER_PAGE');
2322 if (isset($_REQUEST['pg']))
2323 $page = $_REQUEST['pg'];
2327 $range = getIPv4NetworkInfo ($id);
2328 loadIPv4AddrList ($range);
2329 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
2330 echo "<tr><td colspan=2 align=center><h1>${range['ip']}/${range['mask']}</h1><h2>${range['name']}</h2></td></tr>\n";
2332 echo "<tr><td class=pcleft width='50%'>";
2333 startPortlet ('summary');
2334 $total = ($range['ip_bin'] |
$range['mask_bin_inv']) - ($range['ip_bin'] & $range['mask_bin']) +
1;
2335 $used = count ($range['addrlist']);
2336 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
2338 echo "<tr><th width='50%' class=tdright>%% used:</th><td class=tdleft>";
2339 renderProgressBar ($used/$total);
2340 echo " ${used}/${total}</td></tr>\n";
2342 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
2344 // Build a backtrace from all parent networks.
2345 $clen = $range['mask'];
2346 $backtrace = array();
2347 while (NULL !== ($upperid = getIPv4AddressNetworkId ($range['ip'], $clen)))
2349 $upperinfo = getIPv4NetworkInfo ($upperid);
2350 $clen = $upperinfo['mask'];
2351 $backtrace[] = $upperid;
2353 $arrows = count ($backtrace);
2354 foreach (array_reverse ($backtrace) as $ancestorid)
2356 $ainfo = getIPv4NetworkInfo ($ancestorid);
2357 echo "<tr><th width='50%' class=tdright>";
2358 for ($i = 0; $i < $arrows; $i++
)
2361 echo "</th><td class=tdleft>";
2362 renderIPv4NetCell ($ainfo);
2365 echo "<tr><th width='50%' class=tdright>→</th>";
2366 echo "<td class=tdleft>";
2367 renderIPv4NetCell ($range);
2369 // FIXME: get and display nested networks
2370 // $theitem = pickLeaf ($ipv4tree, $id);
2373 echo "<tr><th width='50%' class=tdright>Netmask:</th><td class=tdleft>";
2374 echo $netmaskbylen[$range['mask']];
2375 echo "</td></tr>\n";
2377 echo "<tr><th width='50%' class=tdright>Netmask:</th><td class=tdleft>";
2378 printf ('0x%08X', binMaskFromDec ($range['mask']));
2379 echo "</td></tr>\n";
2381 echo "<tr><th width='50%' class=tdright>Wildcard bits:</th><td class=tdleft>";
2382 echo $wildcardbylen[$range['mask']];
2383 echo "</td></tr>\n";
2385 $routers = findRouters ($range['addrlist']);
2386 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes' and count ($routers))
2388 echo "<tr><th width='50%' class=tdright>Routed by:</th>";
2389 printRoutersTD ($routers);
2393 printTagTRs (makeHref(array('page'=>'ipv4space', 'tab'=>'default'))."&");
2394 echo "</table><br>\n";
2397 renderFilesPortlet ('ipv4net', $id);
2400 echo "<td class=pcright>";
2401 startPortlet ('details');
2402 $startip = $range['ip_bin'] & $range['mask_bin'];
2403 $endip = $range['ip_bin'] |
$range['mask_bin_inv'];
2404 $realstartip = $startip;
2405 $realendip = $endip;
2407 if($endip - $startip > $maxperpage)
2409 $numpages = ($endip - $startip)/$maxperpage;
2410 $startip = $startip +
$page * $maxperpage;
2411 $endip = $startip +
$maxperpage-1;
2415 echo '<h3>' . long2ip ($startip) . ' ~ ' . long2ip ($endip) . '</h3>';
2416 for ($i=0; $i<$numpages; $i++
)
2421 echo "<a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno, 'id'=>$id, 'pg'=>$i))."'>$i</a> ";
2425 echo "<table class='widetable' border=0 cellspacing=0 cellpadding=5 align='center' width='100%'>\n";
2426 echo "<tr><th>Address</th><th>Name</th><th>Allocation</th></tr>\n";
2429 for ($ip = $startip; $ip <= $endip; $ip++
) :
2430 if (isset ($_REQUEST['hl_ipv4_addr']) and ip2long ($_REQUEST['hl_ipv4_addr']) == $ip)
2431 $secondstyle = 'tdleft port_highlight';
2433 $secondstyle = 'tdleft';
2434 if (!isset ($range['addrlist'][$ip]))
2436 echo "<tr><td class=tdleft><a href='".makeHref(array('page'=>'ipaddress', 'ip'=>ip_long2quad($ip)))."'>" . ip_long2quad($ip);
2437 echo "</a></td><td class='${secondstyle}'> </td><td class='${secondstyle}'> </td></tr>\n";
2440 $addr = $range['addrlist'][$ip];
2441 echo "<tr class='${addr['class']}'>";
2443 echo "<td class=tdleft><a href='".makeHref(array('page'=>'ipaddress', 'ip'=>$addr['ip']))."'>${addr['ip']}</a></td>";
2444 echo "<td class='${secondstyle}'>${addr['name']}</td><td class='${secondstyle}'>";
2447 if ( $addr['reserved'] == 'yes')
2449 echo "<strong>RESERVED</strong> ";
2452 foreach ($range['addrlist'][$ip]['allocs'] as $ref)
2454 echo $delim . $aac2[$ref['type']];
2455 echo "<a href='".makeHref(array('page'=>'object', 'object_id'=>$ref['object_id'], 'hl_ipv4_addr'=>$addr['ip']))."'>";
2456 echo $ref['name'] . (empty ($ref['name']) ?
'' : '@');
2457 echo "${ref['object_name']}</a>";
2465 foreach ($range['addrlist'][$ip]['lblist'] as $ref)
2469 echo "${delim}<a href='".makeHref(array('page'=>'object', 'object_id'=>$ref['object_id']))."'>";
2470 echo "${ref['object_name']}</a>:<a href='".makeHref(array('page'=>'ipv4vs', 'vs_id'=>$ref['vs_id']))."'>";
2471 echo "${ref['vport']}/${ref['proto']}</a>→";
2479 foreach ($range['addrlist'][$ip]['rslist'] as $ref)
2483 echo "${delim}→${ref['rsport']}@<a href='".makeHref(array('page'=>'ipv4rspool', 'pool_id'=>$ref['rspool_id']))."'>";
2484 echo "${ref['rspool_name']}</a>";
2487 echo "</td></tr>\n";
2493 echo "</td></tr></table>\n";
2496 function renderIPv4NetworkProperties ($id)
2498 showMessageOrError();
2499 $netdata = getIPv4NetworkInfo ($id);
2500 echo "<center><h1>${netdata['ip']}/${netdata['mask']}</h1></center>\n";
2501 echo "<table border=0 cellpadding=10 cellpadding=1 align='center'>\n";
2502 printOpFormIntro ('editRange');
2503 echo "<tr><td class='tdright'>Name:</td><td class='tdleft'><input type=text name=name size=20 value='${netdata['name']}'></tr>";
2504 echo "<tr><td colspan=2 class=tdcenter>";
2505 printImageHREF ('SAVE', 'Save changes', TRUE);
2506 echo "</td></form></tr></table>\n";
2509 function renderIPv4Address ($dottedquad)
2512 $address = getIPv4Address ($dottedquad);
2513 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
2514 echo "<tr><td colspan=2 align=center><h1>${dottedquad}</h1></td></tr>\n";
2515 if (!empty ($address['name']))
2516 echo "<tr><td colspan=2 align=center><h2>${address['name']}</h2></td></tr>\n";
2518 echo "<tr><td class=pcleft>";
2519 startPortlet ('summary');
2520 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
2521 echo "<tr><th width='50%' class=tdright>Allocations:</th><td class=tdleft>" . count ($address['allocs']) . "</td></tr>\n";
2522 echo "<tr><th width='50%' class=tdright>Originated NAT connections:</th><td class=tdleft>" . count ($address['outpf']) . "</td></tr>\n";
2523 echo "<tr><th width='50%' class=tdright>Arriving NAT connections:</th><td class=tdleft>" . count ($address['inpf']) . "</td></tr>\n";
2524 echo "<tr><th width='50%' class=tdright>SLB virtual services:</th><td class=tdleft>" . count ($address['lblist']) . "</td></tr>\n";
2525 echo "<tr><th width='50%' class=tdright>SLB real servers:</th><td class=tdleft>" . count ($address['rslist']) . "</td></tr>\n";
2527 echo "</table><br>\n";
2531 echo "<td class=pcright>";
2533 if (isset ($address['class']))
2535 startPortlet ('allocations');
2536 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
2537 echo "<tr><th>object</th><th>OS interface</th><th>allocation type</th></tr>\n";
2538 $class = $address['class'];
2539 // render all allocation records for this address the same way
2540 if ($address['reserved'] == 'yes')
2541 echo "<tr class='${class}'><td colspan=2> </td><td class=tdleft><strong>RESERVED</strong></td></tr>";
2542 foreach ($address['allocs'] as $bond)
2544 if (isset ($_REQUEST['hl_object_id']) and $_REQUEST['hl_object_id'] == $bond['object_id'])
2545 $secondclass = 'tdleft port_highlight';
2547 $secondclass = 'tdleft';
2548 echo "<tr class='$class'><td class=tdleft><a href='".makeHref(array('page'=>'object', 'object_id'=>$bond['object_id'], 'hl_ipv4_addr'=>$dottedquad))."'>${bond['object_name']}</td><td class='${secondclass}'>${bond['name']}</td><td class='${secondclass}'><strong>";
2549 echo $aat[$bond['type']];
2550 echo "</strong></td></tr>\n";
2552 echo "</table><br><br>";
2556 // FIXME: The returned list is structured differently, than we expect it to be. One of the sides
2558 if (count ($address['lblist']))
2560 startPortlet ('Virtual services (' . count ($address['lblist']) . ')');
2561 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
2562 echo "<tr><th>VS</th><th>name</th></tr>\n";
2563 foreach ($address['lblist'] as $vsinfo)
2565 echo "<tr><td class=tdleft><a href='".makeHref(array('page'=>'ipv4vs', 'vs_id'=>$vsinfo['vs_id']))."'>";
2566 echo buildVServiceName ($vsinfo) . "</a></td><td class=tdleft>";
2567 echo $vsinfo['name'] . "</td></tr>\n";
2569 echo "</table><br><br>";
2573 if (count ($address['rslist']))
2575 startPortlet ('Real servers (' . count ($address['rslist']) . ')');
2576 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
2577 echo "<tr><th> </th><th>port</th><th>RS pool</th></tr>\n";
2578 foreach ($address['rslist'] as $rsinfo)
2581 if ($rsinfo['inservice'] == 'yes')
2582 printImageHREF ('inservice', 'in service');
2584 printImageHREF ('notinservice', 'NOT in service');
2585 echo "</td><td class=tdleft>${rsinfo['rsport']}</td><td class=tdleft><a href='".makeHref(array('page'=>'ipv4rspool', 'pool_id'=>$rsinfo['rspool_id']))."'>";
2586 echo $rsinfo['rspool_name'] . "</a></td></tr>\n";
2588 echo "</table><br><br>";
2592 if (count ($address['outpf']))
2594 startPortlet ('departing NAT rules');
2595 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
2596 echo "<tr><th>proto</th><th>from</th><th>to</th><th>comment</th></tr>\n";
2597 foreach ($address['outpf'] as $rule)
2598 echo "<tr><td>${rule['proto']}</td><td>${rule['localip']}:${rule['localport']}</td><td>${rule['remoteip']}:${rule['remoteport']}</td><td>${rule['description']}</td></tr>";
2603 if (count ($address['inpf']))
2605 startPortlet ('arriving NAT rules');
2606 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
2607 echo "<tr><th>proto</th><th>from</th><th>to</th><th>comment</th></tr>\n";
2608 foreach ($address['inpf'] as $rule)
2609 echo "<tr><td>${rule['proto']}</td><td>${rule['localip']}:${rule['localport']}</td><td>${rule['remoteip']}:${rule['remoteport']}</td><td>${rule['description']}</td></tr>";
2618 function renderIPv4AddressProperties ($dottedquad)
2620 showMessageOrError();
2621 $address = getIPv4Address ($dottedquad);
2622 echo "<center><h1>$dottedquad</h1></center>\n";
2624 startPortlet ('update');
2625 echo "<table border=0 cellpadding=10 cellpadding=1 align='center'>\n";
2626 printOpFormIntro ('editAddress');
2627 echo "<tr><td class='tdright'>Name:</td><td class='tdleft'><input type=text name=name size=20 value='${address['name']}'></tr>";
2628 echo "<td class='tdright'>Reserved:</td><td class='tdleft'><input type=checkbox name=reserved size=20 ";
2629 echo ($address['reserved']=='yes') ?
'checked' : '';
2630 echo "></tr><tr><td class=tdleft>";
2631 printImageHREF ('SAVE', 'Save changes', TRUE);
2632 echo "</td></form><td class=tdright>";
2633 if (empty ($address['name']) and $address['reserved'] == 'no')
2634 printImageHREF ('CLEAR gray');
2637 printOpFormIntro ('editAddress', array ('name' => '', 'reserved' => ''));
2638 printImageHREF ('CLEAR', 'Release', TRUE);
2641 echo "</td></tr></table>\n";
2645 function renderIPv4AddressAllocations ($dottedquad)
2647 showMessageOrError();
2648 function printNewItemTR ()
2651 printOpFormIntro ('addIPv4Allocation');
2653 printImageHREF ('add', 'allocate', TRUE);
2655 printSelect (getNarrowObjectList ('IPV4OBJ_LISTSRC'), 'object_id', NULL, 100);
2656 echo "</td><td><input type=text tabindex=101 name=bond_name size=10></td><td>";
2657 printSelect ($aat, 'bond_type', NULL, 102);
2659 printImageHREF ('add', 'allocate', TRUE, 103);
2660 echo "</td></form></tr>";
2664 $address = getIPv4Address ($dottedquad);
2666 echo "<center><h1>${dottedquad}</h1></center>\n";
2667 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
2668 echo "<tr><th> </th><th>object</th><th>OS interface</th><th>allocation type</th><th> </th></tr>\n";
2670 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
2672 if (isset ($address['class']))
2674 $class = $address['class'];
2675 if ($address['reserved'] == 'yes')
2676 echo "<tr class='${class}'><td colspan=3> </td><td class=tdleft><strong>RESERVED</strong></td><td> </td></tr>";
2677 foreach ($address['allocs'] as $bond)
2679 echo "<tr class='$class'>";
2680 printOpFormIntro ('updIPv4Allocation', array ('object_id' => $bond['object_id']));
2681 echo "<td><a href='".makeHrefProcess(array('op'=>'delIPv4Allocation', 'ip'=>$dottedquad, 'object_id'=>$bond['object_id']))."'>";
2682 printImageHREF ('delete', 'Unallocate address');
2684 echo "<td><a href='".makeHref(array('page'=>'object', 'object_id'=>$bond['object_id'], 'hl_ipv4_addr'=>$dottedquad))."'>${bond['object_name']}</td>";
2685 echo "<td><input type='text' name='bond_name' value='${bond['name']}' size=10></td><td>";
2686 printSelect ($aat, 'bond_type', $bond['type']);
2688 printImageHREF ('save', 'Save changes', TRUE);
2689 echo "</td></form></tr>\n";
2692 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
2694 echo "</table><br><br>";
2697 function renderNATv4ForObject ($object_id)
2699 function printNewItemTR ($alloclist)
2701 printOpFormIntro ('addNATv4Rule');
2702 echo "<tr align='center'><td>";
2703 printImageHREF ('add', 'Add new NAT rule', TRUE);
2705 printSelect (array ('TCP' => 'TCP', 'UDP' => 'UDP'), 'proto');
2706 echo "<select name='localip' tabindex=1>";
2708 foreach ($alloclist as $dottedquad => $alloc)
2710 $name = empty ($alloc['addrinfo']['name']) ?
'' : (' (' . niftyString ($alloc['addrinfo']['name']) . ')');
2711 $osif = empty ($alloc['osif']) ?
'' : ($alloc['osif'] . ': ');
2712 echo "<option value='${dottedquad}'>${osif}${dottedquad}${name}</option>";
2715 echo "</select>:<input type='text' name='localport' size='4' tabindex=2></td>";
2716 echo "<td><input type='text' name='remoteip' id='remoteip' size='10' tabindex=3>";
2717 echo "<a href='javascript:;' onclick='window.open(\"" . makeHrefForHelper ('inet4list');
2718 echo "\", \"findobjectip\", \"height=700, width=400, location=no, menubar=no, resizable=yes, scrollbars=no, status=no, titlebar=no, toolbar=no\");'>";
2719 printImageHREF ('find', 'Find object');
2721 echo ":<input type='text' name='remoteport' size='4' tabindex=4></td><td></td>";
2722 echo "<td colspan=1><input type='text' name='description' size='20' tabindex=5></td><td>";
2723 printImageHREF ('add', 'Add new NAT rule', TRUE, 6);
2724 echo "</td></tr></form>";
2727 $info = getObjectInfo ($object_id);
2728 $forwards = getNATv4ForObject ($object_id);
2729 $alloclist = getObjectIPv4Allocations ($object_id);
2730 showMessageOrError();
2731 echo "<center><h2>locally performed NAT</h2></center>";
2733 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
2734 echo "<tr><th></th><th>Match endpoint</th><th>Translate to</th><th>Target object</th><th>Comment</th><th> </th></tr>\n";
2736 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
2737 printNewItemTR ($alloclist);
2738 foreach ($forwards['out'] as $pf)
2742 if (isset ($alloclist [$pf['localip']]))
2744 $class = $alloclist [$pf['localip']]['addrinfo']['class'];
2745 $osif = $alloclist [$pf['localip']]['osif'] . ': ';
2748 echo "<tr class='$class'>";
2749 echo "<td><a href='".
2750 makeHrefProcess(array(
2751 'op'=>'delNATv4Rule',
2752 'localip'=>$pf['localip'],
2753 'localport'=>$pf['localport'],
2754 'remoteip'=>$pf['remoteip'],
2755 'remoteport'=>$pf['remoteport'],
2756 'proto'=>$pf['proto'],
2757 'object_id'=>$object_id)).
2759 printImageHREF ('delete', 'Delete NAT rule');
2761 echo "<td>${pf['proto']}/${osif}<a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['localip']))."'>${pf['localip']}</a>:${pf['localport']}";
2762 if (!empty ($pf['local_addr_name']))
2763 echo ' (' . $pf['local_addr_name'] . ')';
2765 echo "<td><a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['remoteip']))."'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
2767 $address = getIPv4Address ($pf['remoteip']);
2769 echo "<td class='description'>";
2770 if (count ($address['allocs']))
2771 foreach ($address['allocs'] as $bond)
2772 echo "<a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$bond['object_id']))."'>${bond['object_name']}(${bond['name']})</a> ";
2773 elseif (!empty ($pf['remote_addr_name']))
2774 echo '(' . $pf['remote_addr_name'] . ')';
2780 'localip' => $pf['localip'],
2781 'localport' => $pf['localport'],
2782 'remoteip' => $pf['remoteip'],
2783 'remoteport' => $pf['remoteport'],
2784 'proto' => $pf['proto']
2787 echo "</td><td class='description'>";
2788 echo "<input type='text' name='description' value='${pf['description']}'></td><td>";
2789 printImageHREF ('save', 'Save changes', TRUE);
2790 echo "</td></form></tr>";
2792 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
2793 printNewItemTR ($alloclist);
2795 echo "</table><br><br>";
2797 echo "<center><h2>arriving NAT connections</h2></center>";
2798 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
2799 echo "<tr><th></th><th>Source</th><th>Source objects</th><th>Target</th><th>Description</th></tr>\n";
2801 foreach ($forwards['in'] as $pf)
2803 echo "<tr><td><a href='".
2804 makeHrefProcess(array(
2805 'op'=>'delNATv4Rule',
2806 'localip'=>$pf['localip'],
2807 'localport'=>$pf['localport'],
2808 'remoteip'=>$pf['remoteip'],
2809 'remoteport'=>$pf['remoteport'],
2810 'proto'=>$pf['proto'],
2811 'object_id'=>$pf['object_id']
2814 printImageHREF ('delete', 'Delete NAT rule');
2816 echo "<td>${pf['proto']}/<a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['localip']))."'>${pf['localip']}</a>:${pf['localport']}</td>";
2817 echo "<td class='description'><a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$pf['object_id']))."'>${pf['object_name']}</a>";
2818 echo "</td><td><a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['remoteip']))."'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
2819 echo "<td class='description'>${pf['description']}</td></tr>";
2822 echo "</table><br><br>";
2825 function renderAddMultipleObjectsForm ()
2827 showMessageOrError();
2828 $typelist = getObjectTypeList();
2829 $typelist[0] = 'select type...';
2830 $max = getConfigVar ('MASSCOUNT');
2833 startPortlet ('Distinct types, same tags');
2834 printOpFormIntro ('addObjects');
2835 echo '<table border=0 align=center>';
2836 echo "<tr><th>Object type</th><th>Common name</th><th>Visible label</th>";
2837 echo "<th>Asset tag</th><th>Barcode</th><th>Tags</th></tr>\n";
2838 for ($i = 0; $i < $max; $i++
)
2841 // Don't employ DEFAULT_OBJECT_TYPE to avoid creating ghost records for pre-selected empty rows.
2842 printSelect ($typelist, "${i}_object_type_id", 0, $tabindex);
2844 echo "<td><input type=text size=30 name=${i}_object_name tabindex=${tabindex}></td>";
2845 echo "<td><input type=text size=30 name=${i}_object_label tabindex=${tabindex}></td>";
2846 echo "<td><input type=text size=20 name=${i}_object_asset_no tabindex=${tabindex}></td>";
2847 echo "<td><input type=text size=10 name=${i}_object_barcode tabindex=${tabindex}></td>";
2850 echo "<td valign=top rowspan=${max}>";
2851 renderNewEntityTags();
2857 echo "<tr><td class=submit colspan=5><input type=submit name=got_fast_data value='Go!'></td></tr>\n";
2858 echo "</form></table>\n";
2861 startPortlet ('Same type, same tags');
2862 printOpFormIntro ('addLotOfObjects');
2863 echo "<table border=0 align=center><tr><th>names</th><th>type</th></tr>";
2864 echo "<tr><td rowspan=3><textarea name=namelist cols=40 rows=25>\n";
2865 echo "</textarea></td><td valign=top>";
2866 printSelect ($typelist, "global_type_id", getConfigVar ('DEFAULT_OBJECT_TYPE'));
2868 echo "<tr><th>Tags</th></tr>";
2869 echo "<tr><td valign=top>";
2870 renderNewEntityTags();
2872 echo "<tr><td colspan=2><input type=submit name=got_very_fast_data value='Go!'></td></tr></table>\n";
2877 function printGreeting ()
2879 global $root, $remote_username, $remote_displayname;
2880 echo "Hello, <a href='${root}?page=myaccount&tab=default'>${remote_displayname}</a>. This is RackTables " .
2882 ". Click <a href='${root}?logout'>here</a> to logout.";
2885 function renderSearchResults ()