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 echo "<table class=objview border=0 width='100%'><tr><td class=pcleft>";
277 $cellfilter = getCellFilter();
278 renderCellFilterPortlet ($cellfilter, 'rack');
279 echo '</td><td class=pcright>';
280 echo '<table border=0 cellpadding=10 cellpadding=1>';
281 // generate thumb gallery
283 $rackwidth = getRackImageWidth();
284 // Zero value effectively disables the limit.
285 $maxPerRow = getConfigVar ('RACKS_PER_ROW');
287 foreach (getRackRows() as $row_id => $row_name)
289 $rackList = filterCellList (listCells ('rack', $row_id), $cellfilter['expression']);
290 if (!count ($rackList) and count ($cellfilter['expression']))
293 echo "<tr class=row_${order}><th class=tdleft>";
294 echo "<a href='".makeHref(array('page'=>'row', 'row_id'=>$row_id))."${cellfilter['urlextra']}'>";
295 echo "${row_name}</a></th><td><table border=0 cellspacing=5><tr>";
296 if (!count ($rackList))
297 echo "<td>(empty row)</td>";
299 foreach ($rackList as $rack)
301 if ($rackListIdx > 0 and $maxPerRow > 0 and $rackListIdx %
$maxPerRow == 0)
303 echo '</tr></table></tr>';
304 echo "<tr class=row_${order}><th class=tdleft>${row_name} (continued)";
305 echo "</th><td><table border=0 cellspacing=5><tr>";
306 $order = $nextorder[$order];
308 echo "<td align=center><a href='".makeHref(array('page'=>'rack', 'rack_id'=>$rack['id']))."'>";
309 echo "<img border=0 width=${rackwidth} height=";
310 echo getRackImageHeight ($rack['height']);
311 echo " title='${rack['height']} units'";
312 echo "src='render_image.php?img=minirack&rack_id=${rack['id']}'>";
313 echo "<br>${rack['name']}</a></td>";
316 echo "</tr></table></tr>\n";
319 echo "</td></tr></table>\n";
322 function renderRackspaceRowEditor ()
324 function printNewItemTR ()
326 printOpFormIntro ('addRow');
328 printImageHREF ('create', 'Add new row', TRUE);
329 echo "</td><td><input type=text name=name tabindex=100></td><td>";
330 printImageHREF ('create', 'Add new row', TRUE, 101);
331 echo "</td></tr></form>";
333 startPortlet ('Rows');
334 echo "<table border=0 cellspacing=0 cellpadding=5 align=center class=widetable>\n";
335 echo "<tr><th> </th><th>Name</th><th> </th></tr>\n";
336 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
338 foreach (getRackRows() as $row_id => $row_name)
341 if ($rc = count (listCells ('rack', $row_id)))
342 printImageHREF ('nodestroy', "${rc} rack(s) here");
345 echo "<a href=\"".makeHrefProcess(array('op'=>'delete', 'row_id'=>$row_id))."\">";
346 printImageHREF ('destroy', 'Delete row');
349 printOpFormIntro ('updateRow', array ('row_id' => $row_id));
350 echo "</td><td><input type=text name=name value='${row_name}'></td><td>";
351 printImageHREF ('save', 'Save changes', TRUE);
352 echo "</form></td></tr>\n";
354 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
356 echo "</table><br>\n";
360 function renderRow ($row_id)
362 if (($rowInfo = getRackRowInfo ($row_id)) == NULL)
364 showError ('getRackRowInfo() failed', __FUNCTION__
);
367 $cellfilter = getCellFilter();
368 $rackList = filterCellList (listCells ('rack', $row_id), $cellfilter['expression']);
369 // Main layout starts.
370 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
372 // Left portlet with row information.
373 echo "<tr><td class=pcleft>";
374 startPortlet ($rowInfo['name']);
375 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
376 echo "<tr><th width='50%' class=tdright>Racks:</th><td class=tdleft>${rowInfo['count']}</td></tr>\n";
377 echo "<tr><th width='50%' class=tdright>Units:</th><td class=tdleft>${rowInfo['sum']}</td></tr>\n";
378 echo "<tr><th width='50%' class=tdright>%% used:</th><td class=tdleft>";
379 renderProgressBar (getRSUforRackRow ($rackList));
381 echo "</table><br>\n";
383 renderCellFilterPortlet ($cellfilter, 'rack', 'row_id', $row_id);
385 echo "</td><td class=pcright>";
388 $rackwidth = getRackImageWidth() * getConfigVar ('ROW_SCALE');
389 // Maximum number of racks per row is proportionally less, but at least 1.
390 $maxPerRow = max (floor (getConfigVar ('RACKS_PER_ROW') / getConfigVar ('ROW_SCALE')), 1);
393 startPortlet ('Racks');
394 echo "<table border=0 cellspacing=5 align='center'><tr>";
395 foreach ($rackList as $rack)
397 if ($rackListIdx %
$maxPerRow == 0)
399 if ($rackListIdx > 0)
403 echo "<td align=center class=row_${order}><a href='".makeHref(array('page'=>'rack', 'rack_id'=>$rack['id']))."'>";
404 echo "<img border=0 width=${rackwidth} height=" . (getRackImageHeight ($rack['height']) * getConfigVar ('ROW_SCALE'));
405 echo " title='${rack['height']} units'";
406 echo "src='render_image.php?img=minirack&rack_id=${rack['id']}'>";
407 echo "<br>${rack['name']}</a></td>";
408 $order = $nextorder[$order];
411 echo "</tr></table>\n";
413 echo "</td></tr></table>";
416 function showError ($info = '', $location = 'N/A')
418 if (preg_match ('/\.php$/', $location))
419 $location = basename ($location);
420 elseif ($location != 'N/A')
421 $location = $location . '()';
422 echo "<div class=msg_error>An error has occured in [${location}]. ";
424 echo 'No additional information is available.';
426 echo "Additional information:<br><p>\n<pre>\n${info}\n</pre></p>";
427 echo "Go back or try starting from <a href='".makeHref()."'>index page</a>.<br></div>\n";
430 // This function assures that specified argument was passed
431 // and is a number greater than zero.
432 function assertUIntArg ($argname, $caller = 'N/A', $allow_zero = FALSE)
434 if (!isset ($_REQUEST[$argname]))
436 showError ("Parameter '${argname}' is missing (calling function is [${caller}]).", __FUNCTION__
);
439 if (!is_numeric ($_REQUEST[$argname]))
441 showError ("Parameter '${argname}' is not a number (calling function is [${caller}]).", __FUNCTION__
);
444 if ($_REQUEST[$argname] < 0)
446 showError ("Parameter '${argname}' is less than zero (calling function is [${caller}]).", __FUNCTION__
);
449 if (!$allow_zero and $_REQUEST[$argname] == 0)
451 showError ("Parameter '${argname}' is equal to zero (calling function is [${caller}]).", __FUNCTION__
);
456 // This function assures that specified argument was passed
457 // and is a non-empty string.
458 function assertStringArg ($argname, $caller = 'N/A', $ok_if_empty = FALSE)
460 if (!isset ($_REQUEST[$argname]))
462 showError ("Parameter '${argname}' is missing (calling function is [${caller}]).", __FUNCTION__
);
465 if (!is_string ($_REQUEST[$argname]))
467 showError ("Parameter '${argname}' is not a string (calling function is [${caller}]).", __FUNCTION__
);
470 if (!$ok_if_empty and empty ($_REQUEST[$argname]))
472 showError ("Parameter '${argname}' is an empty string (calling function is [${caller}]).", __FUNCTION__
);
477 function assertBoolArg ($argname, $caller = 'N/A', $ok_if_empty = FALSE)
479 if (!isset ($_REQUEST[$argname]))
481 showError ("Parameter '${argname}' is missing (calling function is [${caller}]).", __FUNCTION__
);
484 if (!is_string ($_REQUEST[$argname]) or $_REQUEST[$argname] != 'on')
486 showError ("Parameter '${argname}' is not a string (calling function is [${caller}]).", __FUNCTION__
);
489 if (!$ok_if_empty and empty ($_REQUEST[$argname]))
491 showError ("Parameter '${argname}' is an empty string (calling function is [${caller}]).", __FUNCTION__
);
496 function assertIPv4Arg ($argname, $caller = 'N/A', $ok_if_empty = FALSE)
498 assertStringArg ($argname, $caller, $ok_if_empty);
499 if (!empty ($_REQUEST[$argname]) and long2ip (ip2long ($_REQUEST[$argname])) !== $_REQUEST[$argname])
501 showError ("IPv4 address validation failed for value '" . $_REQUEST[$argname] . "' (calling function is [${caller}]).", __FUNCTION__
);
506 // This function renders rack as HTML table.
507 function renderRack ($rack_id, $hl_obj_id = 0)
509 if (($rackData = getRackData ($rack_id)) == NULL)
511 showError ('getRackData() failed', __FUNCTION__
);
514 markAllSpans ($rackData);
516 highlightObject ($rackData, $hl_obj_id);
517 markupObjectProblems ($rackData);
518 $prev_id = getPrevIDforRack ($rackData['row_id'], $rack_id);
519 $next_id = getNextIDforRack ($rackData['row_id'], $rack_id);
520 echo "<center><table border=0><tr valign=middle>";
521 echo "<td><h2><a href='".makeHref(array('page'=>'row', 'row_id'=>$rackData['row_id']))."'>${rackData['row_name']}</a> :</h2></td>";
522 // FIXME: use 'bypass'?
523 if ($prev_id != NULL)
525 echo "<td><a href='".makeHref(array('page'=>'rack', 'rack_id'=>$prev_id))."'>";
526 printImageHREF ('prev', 'previous rack');
529 echo "<td><h2><a href='".makeHref(array('page'=>'rack', 'rack_id'=>$rackData['id']))."'>${rackData['name']}</a></h2></td>";
530 if ($next_id != NULL)
532 echo "<td><a href='".makeHref(array('page'=>'rack', 'rack_id'=>$next_id))."'>";
533 printImageHREF ('next', 'next rack');
536 echo "</h2></td></tr></table>\n";
537 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
538 echo "<tr><th width='10%'> </th><th width='20%'>Front</th>";
539 echo "<th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
540 for ($i = $rackData['height']; $i > 0; $i--)
542 echo "<tr><th>${i}</th>";
543 for ($locidx = 0; $locidx < 3; $locidx++
)
545 if (isset ($rackData[$i][$locidx]['skipped']))
547 $state = $rackData[$i][$locidx]['state'];
548 echo "<td class=state_${state}";
549 if (isset ($rackData[$i][$locidx]['hl']))
550 echo $rackData[$i][$locidx]['hl'];
551 if (isset ($rackData[$i][$locidx]['colspan']))
552 echo ' colspan=' . $rackData[$i][$locidx]['colspan'];
553 if (isset ($rackData[$i][$locidx]['rowspan']))
554 echo ' rowspan=' . $rackData[$i][$locidx]['rowspan'];
559 $objectData = getObjectInfo ($rackData[$i][$locidx]['object_id']);
560 if (!empty ($objectData['asset_no']))
561 $prefix = "<div title='${objectData['asset_no']}";
563 $prefix = "<div title='no asset tag";
564 // Don't tell about label, if it matches common name.
565 if ($objectData['name'] != $objectData['label'] and !empty ($objectData['label']))
566 $suffix = ", visible label is \"${objectData['label']}\"'>";
569 echo $prefix . $suffix;
570 echo "<a href='".makeHref(array('page'=>'object', 'object_id'=>$objectData['id']))."'>${objectData['dname']}</a></div>";
573 echo '<div title="This rackspace does not exist"> </div>';
576 echo '<div title="Free rackspace"> </div>';
579 echo '<div title="Problematic rackspace, you CAN\'T mount here"> </div>';
582 echo '<div title="No data"> </div>';
589 echo "</table></center>\n";
592 function renderNewRackForm ($row_id)
594 startPortlet ('Add one');
595 printOpFormIntro ('addRack', array ('got_data' => 'TRUE'));
596 echo '<table border=0 align=center>';
597 $defh = getConfigVar ('DEFAULT_RACK_HEIGHT');
600 echo "<tr><th class=tdright>Rack name (*):</th><td class=tdleft><input type=text name=rack_name tabindex=1></td>";
601 echo "<td rowspan=4>Assign tags:<br>";
602 renderNewEntityTags();
604 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";
605 echo "<tr><th class=tdright>Comment:</th><td class=tdleft><input type=text name=rack_comment tabindex=3></td></tr>\n";
606 echo "<tr><td class=submit colspan=2>";
607 printImageHREF ('CREATE', 'Add', TRUE);
608 echo "</td></tr></table></form>";
611 startPortlet ('Add many');
612 printOpFormIntro ('addRack', array ('got_mdata' => 'TRUE'));
613 echo '<table border=0 align=center>';
614 $defh = getConfigVar ('DEFAULT_RACK_HEIGHT');
617 echo "<tr><th class=tdright>Height in units (*):</th><td class=tdleft><input type=text name=rack_height2 value='${defh}'></td>";
618 echo "<td rowspan=3 valign=top>Assign tags:<br>";
619 renderNewEntityTags();
621 echo "<tr><th class=tdright>Rack names (*):</th><td class=tdleft><textarea name=rack_names cols=40 rows=25></textarea></td></tr>\n";
622 echo "<tr><td class=submit colspan=2>";
623 printImageHREF ('CREATE', 'Add', TRUE);
624 echo '</form></table>';
628 function renderEditObjectForm ($object_id)
631 $object = getObjectInfo ($object_id);
634 showError ('getObjectInfo() failed', __FUNCTION__
);
638 printOpFormIntro ('update');
641 echo '<table border=0 cellspacing=0 cellpadding=3 align=center>';
642 echo "<tr><td> </td><th colspan=2><h2>Attributes</h2></th></tr>";
643 echo "<tr><td> </td><th class=tdright>Type:</th><td class=tdleft>";
644 printSelect (getObjectTypeList(), 'object_type_id', $object['objtype_id']);
647 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";
648 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";
649 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";
650 echo "<tr><td> </td><th class=tdright>Barcode:</th><td class=tdleft><input type=text name=object_barcode value='${object['barcode']}'></td></tr>\n";
651 // optional attributes
652 $values = getAttrValues ($object_id);
653 echo '<input type=hidden name=num_attrs value=' . count($values) . ">\n";
654 if (count($values) > 0)
657 foreach ($values as $record)
659 echo "<input type=hidden name=${i}_attr_id value=${record['id']}>";
661 if (!empty ($record['value']))
663 echo "<a href='".makeHrefProcess(array('op'=>'clearSticker', 'object_id'=>$object_id, 'attr_id'=>$record['id']))."'>";
664 printImageHREF ('clear', 'Clear value');
670 echo "<th class=sticker>${record['name']}:</th><td class=tdleft>";
671 switch ($record['type'])
676 echo "<input type=text name=${i}_value value='${record['value']}'>";
679 $chapter = readChapter ($record['chapter_name']);
680 $chapter[0] = '-- NOT SET --';
681 $chapter = cookOptgroups ($chapter, $object['objtype_id'], $record['key']);
682 printNiftySelect ($chapter, "${i}_value", $record['key']);
689 echo "<tr><td> </td><th class=tdright>Has problems:</th><td class=tdleft><input type=checkbox name=object_has_problems";
690 if ($object['has_problems'] == 'yes')
692 echo "></td></tr>\n";
693 echo "<tr><td> </td><th class=tdright>Actions:</th><td class=tdleft><a href='".
694 makeHrefProcess(array('op'=>'deleteObject', 'page'=>'depot', 'tab'=>'default', 'object_id'=>$object_id)).
695 "' onclick=\"javascript:return confirm('Are you sure you want to delete the object?')\">Delete object</a></td></tr>\n";
696 echo "<tr><td colspan=3><b>Comment:</b><br><textarea name=object_comment rows=10 cols=80>${object['comment']}</textarea></td></tr>";
698 echo "<tr><th class=submit colspan=3>";
699 printImageHREF ('SAVE', 'Save changes', TRUE);
700 echo "</form></th></tr></table>\n";
703 echo '<table border=0 width=100%><tr><td>';
704 startPortlet ('history');
705 renderHistory ($pageno, $object_id);
707 echo '</td></tr></table>';
710 // This is a clone of renderEditObjectForm().
711 function renderEditRackForm ($rack_id)
714 $rack = getRackData ($rack_id);
717 showError ('getRackData() failed', __FUNCTION__
);
721 startPortlet ('Rack attributes');
722 printOpFormIntro ('updateRack');
723 echo '<table border=0 align=center>';
724 echo "<tr><th class=tdright>Rack row:</th><td class=tdleft>";
725 printSelect (getRackRows(), 'rack_row_id', $rack['row_id']);
727 echo "<tr><th class=tdright>Name (required):</th><td class=tdleft><input type=text name=rack_name value='${rack['name']}'></td></tr>\n";
728 echo "<tr><th class=tdright>Height (required):</th><td class=tdleft><input type=text name=rack_height value='${rack['height']}'></td></tr>\n";
729 echo "<tr><th class=tdright>Comment:</th><td class=tdleft><input type=text name=rack_comment value='${rack['comment']}'></td></tr>\n";
730 if (count ($rack['mountedObjects']) == 0)
732 echo "<tr><th class=tdright>Actions:</th><td class=tdleft><a href='".
733 makeHrefProcess(array('op'=>'deleteRack', 'rack_id'=>$rack_id)).
734 "' onclick=\"javascript:return confirm('Are you sure you want to delete the rack?')\">Delete rack</a></td></tr>\n";
736 echo "<tr><td class=submit colspan=2>";
737 printImageHREF ('SAVE', 'Save changes', TRUE);
739 echo '</form></table><br>';
742 startPortlet ('History');
743 renderHistory ($pageno, $rack_id);
747 // This is a helper for creators and editors.
748 // Input array keys are OPTION VALUEs and input array values are OPTION text.
749 function printSelect ($optionList, $select_name, $selected_id = NULL, $tabindex = NULL)
751 echo "<select name=${select_name}" . ($tabindex ?
" tabindex=${tabindex}" : '') . '>';
752 foreach ($optionList as $dict_key => $dict_value)
753 echo "<option value='${dict_key}'" . ($dict_key == $selected_id ?
' selected' : '') . ">${dict_value}</option>";
757 // Input is a cooked list of OPTGROUPs, each with own sub-list of OPTIONs in the same
758 // format as printSelect() expects.
759 function printNiftySelect ($groupList, $select_name, $selected_id = NULL, $tabindex = NULL)
761 // special treatment for ungrouped data
762 if (count ($groupList) == 1 and isset ($groupList['other']))
764 printSelect ($groupList['other'], $select_name, $selected_id, $tabindex);
767 echo "<select name=${select_name}" . ($tabindex ?
" tabindex=${tabindex}" : '') . '>';
768 foreach ($groupList as $groupname => $groupdata)
770 echo "<optgroup label='${groupname}'>";
771 foreach ($groupdata as $dict_key => $dict_value)
772 echo "<option value='${dict_key}'" . ($dict_key == $selected_id ?
' selected' : '') . ">${dict_value}</option>";
773 echo "</optgroup>\n";
778 // used by renderGridForm() and renderRackPage()
779 function renderRackInfoPortlet ($rackData)
781 startPortlet ('summary');
782 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
783 echo "<tr><th width='50%' class=tdright>Rack row:</th><td class=tdleft>${rackData['row_name']}</td></tr>\n";
784 echo "<tr><th width='50%' class=tdright>Name:</th><td class=tdleft>${rackData['name']}</td></tr>\n";
785 echo "<tr><th width='50%' class=tdright>Height:</th><td class=tdleft>${rackData['height']}</td></tr>\n";
786 echo "<tr><th width='50%' class=tdright>%% used:</th><td class=tdleft>";
787 renderProgressBar (getRSUforRack ($rackData));
789 echo "<tr><th width='50%' class=tdright>Objects:</th><td class=tdleft>";
790 echo count (stuffInRackspace ($rackData));
792 printTagTRs (makeHref(array('page'=>'rackspace', 'tab'=>'default'))."&");
793 if (!empty ($rackData['comment']))
794 echo "<tr><th width='50%' class=tdright>Comment:</th><td class=tdleft>${rackData['comment']}</td></tr>\n";
799 // This is a universal editor of rack design/waste.
800 // FIXME: switch to using printOpFormIntro()
801 function renderGridForm ($rack_id, $filter, $header, $submit, $state1, $state2)
803 if (($rackData = getRackData ($rack_id)) == NULL)
805 showError ('getRackData() failed', __FUNCTION__
);
809 markupObjectProblems ($rackData);
811 // Render the result whatever it is.
813 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
814 echo "<tr><td colspan=2 align=center><h1>${rackData['name']}</h1></td></tr>\n";
816 // Left column with information portlet.
817 echo "<tr><td class=pcleft height='1%' width='50%'>";
818 renderRackInfoPortlet ($rackData);
820 echo "<td class=pcright>";
823 startPortlet ($header);
825 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
826 echo "<tr><th width='10%'> </th>";
827 echo "<th width='20%'><a href='javascript:;' onclick=\"toggleColumnOfAtoms('${rack_id}', '0', ${rackData['height']})\">Front</a></th>";
828 echo "<th width='50%'><a href='javascript:;' onclick=\"toggleColumnOfAtoms('${rack_id}', '1', ${rackData['height']})\">Interior</a></th>";
829 echo "<th width='20%'><a href='javascript:;' onclick=\"toggleColumnOfAtoms('${rack_id}', '2', ${rackData['height']})\">Back</a></th></tr>\n";
830 printOpFormIntro ('updateRack');
831 markupAtomGrid ($rackData, $state2);
832 renderAtomGrid ($rackData);
833 echo "</table></center>\n";
834 echo "<br><input type=submit name=do_update value='${submit}'></form><br><br>\n";
836 echo "</td></tr></table>\n";
839 function renderRackDesign ($rack_id)
841 renderGridForm ($rack_id, 'applyRackDesignMask', 'Rack design', 'Set rack design', 'A', 'F');
844 function renderRackProblems ($rack_id)
846 renderGridForm ($rack_id, 'applyRackProblemMask', 'Rack problems', 'Mark unusable atoms', 'F', 'U');
849 function startPortlet ($title = '')
851 echo "<div class=portlet><h2>${title}</h2>";
854 function finishPortlet ()
859 function renderRackObject ($object_id)
861 global $nextorder, $aac;
862 $info = getObjectInfo ($object_id);
865 showError ('getObjectInfo() failed', __FUNCTION__
);
868 // Main layout starts.
869 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
870 echo "<tr><td colspan=2 align=center><h1>${info['dname']}</h1></td></tr>\n";
871 // left column with uknown number of portlets
872 echo "<tr><td class=pcleft>";
873 startPortlet ('summary');
874 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
875 if (!empty ($info['name']))
876 echo "<tr><th width='50%' class=tdright>Common name:</th><td class=tdleft>${info['name']}</td></tr>\n";
877 elseif (considerConfiguredConstraint ('object', $object_id, 'NAMEWARN_LISTSRC'))
878 echo "<tr><td colspan=2 class=msg_error>Common name is missing.</td></tr>\n";
879 echo "<tr><th width='50%' class=tdright>Object type:</th><td class=tdleft><a href='";
880 echo makeHref (array (
883 'cfe' => '{$typeid_' . $info['objtype_id'] . '}'
885 echo "'>${info['objtype_name']}</a></td></tr>\n";
886 if (!empty ($info['asset_no']))
887 echo "<tr><th width='50%' class=tdright>Asset tag:</th><td class=tdleft>${info['asset_no']}</td></tr>\n";
888 elseif (considerConfiguredConstraint ('object', $object_id, 'ASSETWARN_LISTSRC'))
889 echo "<tr><td colspan=2 class=msg_error>Asset tag is missing.</td></tr>\n";
890 if (!empty ($info['label']))
891 echo "<tr><th width='50%' class=tdright>Visible label:</th><td class=tdleft>${info['label']}</td></tr>\n";
892 if (!empty ($info['barcode']))
893 echo "<tr><th width='50%' class=tdright>Barcode:</th><td class=tdleft>${info['barcode']}</td></tr>\n";
894 if ($info['has_problems'] == 'yes')
895 echo "<tr><td colspan=2 class=msg_error>Has problems</td></tr>\n";
896 foreach (getAttrValues ($object_id, TRUE) as $record)
897 if (!empty ($record['value']))
898 echo "<tr><th width='50%' class=sticker>${record['name']}:</th><td class=sticker>${record['a_value']}</td></tr>\n";
908 'cfe' => '{$typeid_' . $info['objtype_id'] . '}',
912 echo "</table><br>\n";
915 if (!empty ($info['comment']))
917 startPortlet ('Comment');
918 echo '<div class=commentblock>' . string_insert_hrefs ($info['comment']) . '</div>';
922 renderFilesPortlet ('object', $object_id);
924 $ports = getObjectPortsAndLinks ($object_id);
927 startPortlet ('ports and links');
928 usort($ports, 'sortByName');
932 if (isset ($_REQUEST['hl_port_id']))
934 assertUIntArg ('hl_port_id', __FUNCTION__
);
935 $hl_port_id = $_REQUEST['hl_port_id'];
937 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
938 echo "<tr><th>Local name</th><th>Visible label</th><th>Port type</th><th>L2 address</th>";
939 echo "<th>Rem. Object</th><th>Rem. port</th></tr>\n";
940 foreach ($ports as $port)
943 if ($hl_port_id == $port['id'])
944 echo ' class=port_highlight';
945 echo "><td>${port['name']}</td><td>${port['label']}</td><td>${port['type']}</td>";
946 echo "<td>${port['l2address']}</td>";
947 if ($port['remote_object_id'])
949 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>";
950 echo "<td>${port['remote_name']}</td>";
952 elseif (!empty ($port['reservation_comment']))
954 echo "<td><b>Reserved;</b></td>";
955 echo "<td>${port['reservation_comment']}</td>";
958 echo '<td> </td><td> </td>';
961 echo "</table><br>\n";
966 $alloclist = getObjectIPv4Allocations ($object_id);
967 if (count ($alloclist))
969 startPortlet ('IPv4 addresses');
970 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
971 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
972 echo "<tr><th>OS interface</th><th>IP address</th><th>network</th><th>routed by</th><th>peers</th></tr>\n";
974 echo "<tr><th>OS interface</th><th>IP address</th><th>peers</th></tr>\n";
976 if (isset ($_REQUEST['hl_ipv4_addr']))
978 assertIPv4Arg ('hl_ipv4_addr', __FUNCTION__
);
979 $hl_ipv4_addr = $_REQUEST['hl_ipv4_addr'];
981 foreach ($alloclist as $dottedquad => $alloc)
983 $address_name = niftyString ($alloc['addrinfo']['name']);
984 $class = $alloc['addrinfo']['class'];
985 $secondclass = ($hl_ipv4_addr == $dottedquad) ?
'tdleft port_highlight' : 'tdleft';
986 $netid = getIPv4AddressNetworkId ($dottedquad);
989 $netinfo = getIPv4NetworkInfo ($netid);
990 loadIPv4AddrList ($netinfo);
992 echo "<tr class='${class}' valign=top><td class=tdleft>${alloc['osif']}</td><td class='${secondclass}'>";
994 echo "<a href='".makeHref(array('page'=>'ipaddress', 'ip'=>$dottedquad, 'hl_object_id'=>$object_id))."'>${dottedquad}</a>";
997 if (getConfigVar ('EXT_IPV4_VIEW') != 'yes')
998 echo '<small>/' . (NULL === $netid ?
'??' : $netinfo['mask']) . '</small>';
999 echo ' ' . $aac[$alloc['type']];
1000 if (!empty ($alloc['addrinfo']['name']))
1001 echo ' (' . niftyString ($alloc['addrinfo']['name']) . ')';
1003 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
1005 if (NULL === $netid)
1006 echo '<td class=sparenetwork>N/A</td><td class=sparenetwork>N/A</td>';
1009 echo "<td class='${secondclass}'>";
1010 renderIPv4NetCell ($netinfo);
1012 // filter out self-allocation
1013 $other_routers = array();
1014 foreach (findRouters ($netinfo['addrlist']) as $router)
1015 if ($router['id'] != $object_id)
1016 $other_routers[] = $router;
1017 if (count ($other_routers))
1018 printRoutersTD ($other_routers);
1020 echo "<td class='${secondclass}'> </td>";
1024 echo "<td class='${secondclass}'>\n";
1026 if ($alloc['addrinfo']['reserved'] == 'yes')
1028 echo $prefix . '<strong>RESERVED</strong>';
1031 foreach ($alloc['addrinfo']['allocs'] as $allocpeer)
1033 if ($allocpeer['object_id'] == $object_id)
1035 echo $prefix . "<a href='".makeHref(array('page'=>'object', 'object_id'=>$allocpeer['object_id']))."'>";
1036 if (!empty ($allocpeer['osif']))
1037 echo $allocpeer['osif'] . '@';
1038 echo $allocpeer['object_name'] . '</a>';
1041 echo "</td></tr>\n";
1043 echo "</table><br>\n";
1047 $forwards = getNATv4ForObject ($object_id);
1048 if (count($forwards['in']) or count($forwards['out']))
1050 startPortlet('NATv4');
1052 if (count($forwards['out']))
1055 echo "<h3>locally performed NAT</h3>";
1057 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
1058 echo "<tr><th>Proto</th><th>Match endpoint</th><th>Translate to</th><th>Target object</th><th>Rule comment</th></tr>\n";
1060 foreach ($forwards['out'] as $pf)
1064 if (isset ($alloclist [$pf['localip']]))
1066 $class = $alloclist [$pf['localip']]['addrinfo']['class'];
1067 $osif = $alloclist [$pf['localip']]['osif'] . ': ';
1069 echo "<tr class='$class'>";
1070 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>";
1071 echo "<td class=tdleft><a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['remoteip']))."'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
1072 $address = getIPv4Address ($pf['remoteip']);
1073 echo "<td class='description'>";
1074 if (count ($address['allocs']))
1075 foreach($address['allocs'] as $bond)
1076 echo "<a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$bond['object_id']))."'>${bond['object_name']}(${bond['name']})</a> ";
1077 elseif (!empty ($pf['remote_addr_name']))
1078 echo '(' . $pf['remote_addr_name'] . ')';
1079 echo "</td><td class='description'>${pf['description']}</td></tr>";
1081 echo "</table><br><br>";
1083 if (count($forwards['in']))
1085 echo "<h3>arriving NAT connections</h3>";
1086 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
1087 echo "<tr><th>Matched endpoint</th><th>Source object</th><th>Translated to</th><th>Rule comment</th></tr>\n";
1088 foreach ($forwards['in'] as $pf)
1091 echo "<td>${pf['proto']}/<a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['localip']))."'>${pf['localip']}</a>:${pf['localport']}</td>";
1092 echo "<td class='description'><a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$pf['object_id']))."'>${pf['object_name']}</a>";
1093 echo "</td><td><a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['remoteip']))."'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
1094 echo "<td class='description'>${pf['description']}</td></tr>";
1096 echo "</table><br><br>";
1101 $pools = getRSPoolsForObject ($object_id);
1105 startPortlet ('Real server pools (' . count ($pools) . ')');
1106 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
1107 echo "<tr><th>VS</th><th>RS pool</th><th>RS</th><th>VS config</th><th>RS config</th></tr>\n";
1108 foreach ($pools as $vs_id => $info)
1110 echo "<tr valign=top class=row_${order}><td class=tdleft>";
1111 renderVSCell ($vs_id);
1112 echo "</td><td class=tdleft>";
1113 renderRSPoolCell ($info['pool_id'], $info['pool_name']);
1114 echo '</td><td class=tdleft>' . $info['rscount'] . '</td>';
1115 echo "<td class=slbconf>${info['vsconfig']}</td>";
1116 echo "<td class=slbconf>${info['rsconfig']}</td>";
1118 $order = $nextorder[$order];
1125 // After left column we have (surprise!) right column with rackspace portlet only.
1126 echo "<td class=pcright>";
1127 // rackspace portlet
1128 startPortlet ('rackspace allocation');
1129 foreach (getResidentRacksData ($object_id, FALSE) as $rack_id)
1130 renderRack ($rack_id, $object_id);
1137 function renderRackMultiSelect ($sname, $racks, $selected)
1139 // Transform the given flat list into a list of groups, each representing a rack row.
1141 foreach ($racks as $rack)
1142 if (!isset ($rdata[$rack['row_name']]))
1143 $rdata[$rack['row_name']] = array ($rack['id'] => $rack['name']);
1145 $rdata[$rack['row_name']][$rack['id']] = $rack['name'];
1146 echo "<select name=${sname} multiple size=" . getConfigVar ('MAXSELSIZE') . " onchange='getElementsByName(\"updateObjectAllocation\")[0].submit()'>\n";
1147 foreach ($rdata as $optgroup => $racklist)
1149 echo "<optgroup label='${optgroup}'>";
1150 foreach ($racklist as $rack_id => $rack_name)
1152 echo "<option value=${rack_id}";
1153 if (!(array_search ($rack_id, $selected) === FALSE))
1155 echo">${rack_name}</option>\n";
1161 function showMessageOrError ()
1163 if (isset ($_SESSION['log']))
1165 printLog ($_SESSION['log']);
1166 unset($_SESSION['log']);
1170 // This function renders a form for port edition.
1171 function renderPortsForObject ($object_id)
1173 function printNewItemTR ()
1175 printOpFormIntro ('addPort');
1177 printImageHREF ('add', 'add a port', TRUE);
1178 echo "</td><td><input type=text size=8 name=port_name tabindex=100></td>\n";
1179 echo "<td><input type=text size=24 name=port_label tabindex=101></td><td>";
1180 printSelect (getPortTypes(), 'port_type_id', getConfigVar ('default_port_type'), 102);
1181 echo "<td><input type=text name=port_l2address tabindex=103></td>\n";
1182 echo "<td colspan=3> </td><td>";
1183 printImageHREF ('add', 'add a port', TRUE, 104);
1184 echo "</td></tr></form>";
1186 startPortlet ('Ports and interfaces');
1187 $ports = getObjectPortsAndLinks ($object_id);
1188 usort($ports, 'sortByName');
1189 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
1190 echo "<tr><th> </th><th>Local name</th><th>Visible label</th><th>Port type</th><th>L2 address</th>";
1191 echo "<th>Rem. object</th><th>Rem. port</th><th>(Un)link or (un)reserve</th><th> </th></tr>\n";
1192 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
1194 foreach ($ports as $port)
1196 printOpFormIntro ('editPort', array ('port_id' => $port['id']));
1197 echo "<tr><td><a href='".makeHrefProcess(array('op'=>'delPort', 'port_id'=>$port['id'], 'object_id'=>$object_id, 'port_name'=>$port['name']))."'>";
1198 printImageHREF ('delete', 'Unlink and Delete this port');
1200 echo "<td><input type=text name=name value='${port['name']}' size=8></td>";
1201 echo "<td><input type=text name=label value='${port['label']}' size=24></td>";
1202 if (!$port['remote_object_id'])
1205 printSelect (getPortTypes(), 'port_type_id', $port['type_id']);
1210 echo "<input type=hidden name=port_type_id value='${port['type_id']}'>";
1211 echo "<td class=tdleft>${port['type']}</td>\n";
1213 echo "<td><input type=text name=l2address value='${port['l2address']}'></td>\n";
1214 if ($port['remote_object_id'])
1216 echo "<td><a href='".makeHref(array('page'=>'object', 'object_id'=>$port['remote_object_id']))."'>${port['remote_object_name']}</a></td>";
1217 echo "<td>${port['remote_name']}</td>";
1218 echo "<td><a href='".
1219 makeHrefProcess(array(
1221 'port_id'=>$port['id'],
1222 'object_id'=>$object_id,
1223 'port_name'=>$port['name'],
1224 'remote_port_name'=>$port['remote_name'],
1225 'remote_object_name'=>$port['remote_object_name'])).
1227 printImageHREF ('cut', 'Unlink this port');
1230 elseif (!empty ($port['reservation_comment']))
1232 echo "<td><b>Reserved;</b></td>";
1233 echo "<td><input type=text name=reservation_comment value='${port['reservation_comment']}'></td>";
1234 echo "<td><a href='".
1235 makeHrefProcess(array(
1237 'port_id'=>$port['id'],
1238 'object_id'=>$object_id)).
1240 printImageHREF ('clear', 'Use up this port');
1245 echo "<td> </td><td> </td>";
1247 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\");'>";
1248 printImageHREF ('plug', 'Link this port');
1249 echo "</a> <input type=text name=reservation_comment>";
1253 printImageHREF ('save', 'Save changes', TRUE);
1254 echo "</td></form></tr>\n";
1256 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
1258 echo "</table><br>\n";
1261 startPortlet ('Add/update multiple ports');
1262 printOpFormIntro ('addMultiPorts');
1263 echo 'Format: <select name=format tabindex=201>';
1264 echo '<option value=c3600asy>Cisco 3600 async: sh line | inc TTY</option>';
1265 echo '<option value=fiwg selected>Foundry ServerIron/FastIron WorkGroup/Edge: sh int br</option>';
1266 echo '<option value=fisxii>Foundry FastIron SuperX/II4000: sh int br</option>';
1267 echo '<option value=ssv1>SSV:<interface name> <MAC address></option>';
1269 echo 'Default port type: ';
1270 printSelect (getPortTypes(), 'port_type', getConfigVar ('default_port_type'), 202);
1271 echo "<input type=submit value='Parse output' tabindex=204><br>\n";
1272 echo "<textarea name=input cols=100 rows=50 tabindex=203></textarea><br>\n";
1277 function renderIPv4ForObject ($object_id)
1279 function printNewItemTR ()
1282 printOpFormIntro ('addIPv4Allocation');
1284 printImageHREF ('add', 'allocate', TRUE);
1286 echo "<td class=tdleft><input type='text' size='10' name='bond_name' tabindex=100></td>\n";
1287 echo "<td class=tdleft><input type=text name='ip' tabindex=101></td>\n";
1288 echo "<td colspan=2> </td><td>";
1289 printSelect ($aat, 'bond_type', NULL, 102);
1290 echo "</td><td> </td><td>";
1291 printImageHREF ('add', 'allocate', TRUE, 103);
1292 echo "</td></tr></form>";
1295 startPortlet ('Allocations');
1296 $alloclist = getObjectIPv4Allocations ($object_id);
1297 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
1298 echo '<tr><th> </th><th>OS interface</th><th>IP address</th>';
1299 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
1300 echo '<th>network</th><th>routed by</th>';
1301 echo '<th>type</th><th>misc</th><th> </th></tr>';
1303 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
1305 foreach ($alloclist as $dottedquad => $alloc)
1307 $class = $alloc['addrinfo']['class'];
1308 $netid = getIPv4AddressNetworkId ($dottedquad);
1309 if (NULL !== $netid)
1311 $netinfo = getIPv4NetworkInfo ($netid);
1312 loadIPv4AddrList ($netinfo);
1314 printOpFormIntro ('updIPv4Allocation', array ('ip' => $dottedquad));
1315 echo "<tr class='$class' valign=top><td><a href='".makeHrefProcess(array('op'=>'delIPv4Allocation', 'ip'=>$dottedquad, 'object_id'=>$object_id))."'>";
1316 printImageHREF ('delete', 'Delete this IPv4 address');
1318 echo "<td class=tdleft><input type='text' name='bond_name' value='${alloc['osif']}' size=10></td><td class=tdleft>";
1319 if (NULL !== $netid)
1320 echo "<a href='".makeHref(array('page'=>'ipaddress', 'ip'=>$dottedquad))."'>${dottedquad}</a>";
1323 if (getConfigVar ('EXT_IPV4_VIEW') != 'yes')
1324 echo '<small>/' . (NULL === $netid ?
'??' : $netinfo['mask']) . '</small>';
1325 if (!empty ($alloc['addrinfo']['name']))
1326 echo ' (' . niftyString ($alloc['addrinfo']['name']) . ')';
1328 // FIXME: this a copy-and-paste from renderRackObject()
1329 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
1331 if (NULL === $netid)
1332 echo '<td class=sparenetwork>N/A</td><td class=sparenetwork>N/A</td>';
1336 renderIPv4NetCell ($netinfo);
1338 // filter out self-allocation
1339 $other_routers = array();
1340 foreach (findRouters ($netinfo['addrlist']) as $router)
1341 if ($router['id'] != $object_id)
1342 $other_routers[] = $router;
1343 if (count ($other_routers))
1344 printRoutersTD ($other_routers);
1346 echo "<td> </td>";
1350 printSelect ($aat, 'bond_type', $alloc['type']);
1353 if ($alloc['addrinfo']['reserved'] == 'yes')
1355 echo $prefix . '<strong>RESERVED</strong>';
1358 foreach ($alloc['addrinfo']['allocs'] as $allocpeer)
1360 if ($allocpeer['object_id'] == $object_id)
1362 echo $prefix . "<a href='".makeHref(array('page'=>'object', 'object_id'=>$allocpeer['object_id']))."'>";
1363 if (!empty ($allocpeer['osif']))
1364 echo $allocpeer['osif'] . '@';
1365 echo $allocpeer['object_name'] . '</a>';
1369 printImageHREF ('save', 'Save changes', TRUE);
1370 echo "</td></form></tr>\n";
1372 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
1375 echo "</table><br>\n";
1380 // Log structure versions:
1381 // 1: the whole structure is a list of code-message pairs
1382 // 2 and later: there's a "v" field set, which indicates the version
1383 // 2: there's a "m" list set to hold message code and optional arguments
1384 function printLog ($log)
1388 case !isset ($log['v']):
1389 case $log['v'] == 1:
1390 foreach ($log as $key => $record)
1392 echo "<div class=msg_${record['code']}>${record['message']}</div>";
1394 case $log['v'] == 2:
1397 // records 0~99 with success messages
1398 0 => array ('code' => 'success', 'format' => '%s'),
1399 1 => array ('code' => 'success', 'format' => '%u new records done, %u already existed'),
1400 2 => array ('code' => 'success', 'format' => 'NATv4 rule was successfully added.'),
1401 3 => array ('code' => 'success', 'format' => 'NATv4 rule was successfully deleted.'),
1402 4 => array ('code' => 'success', 'format' => 'NATv4 rule was successfully updated'),
1403 5 => array ('code' => 'success', 'format' => 'Port %s was added successfully'),
1404 6 => array ('code' => 'success', 'format' => 'Port %s was updated successfully'),
1405 7 => array ('code' => 'success', 'format' => 'Port %s was deleted successfully'),
1406 8 => array ('code' => 'success', 'format' => 'Port %s successfully linked with port %s at object %s'),
1407 9 => array ('code' => 'success', 'format' => 'Port %s was successfully unlinked from %s@%s'),
1408 10 => array ('code' => 'success', 'format' => 'Added %u ports, updated %u ports, encountered %u errors.'),
1409 11 => array ('code' => 'success', 'format' => 'Reservation removed.'),
1410 12 => array ('code' => 'success', 'format' => 'allocation updated'),
1411 13 => array ('code' => 'success', 'format' => 'allocated'),
1412 14 => array ('code' => 'success', 'format' => 'deallocated'),
1413 15 => array ('code' => 'success', 'format' => 'Reset succeeded.'),
1414 16 => array ('code' => 'success', 'format' => 'Update done'),
1415 17 => array ('code' => 'success', 'format' => 'Update(s) succeeded.'),
1416 18 => array ('code' => 'success', 'format' => 'Load balancer was successfully added'),
1417 19 => array ('code' => 'success', 'format' => 'Load balancer was successfully deleted'),
1418 20 => array ('code' => 'success', 'format' => 'Load balancer info was successfully updated'),
1419 21 => array ('code' => 'success', 'format' => 'Generation complete'),
1420 22 => array ('code' => 'success', 'format' => 'Chained %u tags'),
1421 23 => array ('code' => 'success', 'format' => 'IPv4 prefix successfully added'),
1422 24 => array ('code' => 'success', 'format' => 'IPv4 prefix deleted'),
1423 25 => array ('code' => 'success', 'format' => 'IPv4 prefix updated'),
1424 26 => array ('code' => 'success', 'format' => '%u IP address(es) were successfully updated'),
1425 27 => array ('code' => 'success', 'format' => 'IPv4 address updated'),
1426 28 => array ('code' => 'success', 'format' => 'Virtual service was successfully created'),
1427 29 => array ('code' => 'success', 'format' => 'Virtual service was successfully deleted'),
1428 30 => array ('code' => 'success', 'format' => 'Virtual service was successfully updated'),
1429 31 => array ('code' => 'success', 'format' => 'RS pool was successfully created'),
1430 32 => array ('code' => 'success', 'format' => 'RS pool was successfully deleted'),
1431 33 => array ('code' => 'success', 'format' => 'RS pool was successfully updated'),
1432 34 => array ('code' => 'success', 'format' => 'Real server was successfully added'),
1433 35 => array ('code' => 'success', 'format' => 'Real server was successfully deleted'),
1434 36 => array ('code' => 'success', 'format' => 'Real server was successfully updated'),
1435 37 => array ('code' => 'success', 'format' => 'Successfully added %u real servers'),
1436 38 => array ('code' => 'success', 'format' => '%u real server(s) were successfully (de)activated'),
1437 39 => array ('code' => 'success', 'format' => 'User account %s updated.'),
1438 40 => array ('code' => 'success', 'format' => 'User account %s created.'),
1441 43 => array ('code' => 'success', 'format' => 'Saved successfully.'),
1442 44 => array ('code' => 'success', 'format' => '%s failures and %s successfull changes.'),
1443 45 => array ('code' => 'success', 'format' => "Attribute '%s' created."),
1444 46 => array ('code' => 'success', 'format' => 'Rename successful.'),
1445 47 => array ('code' => 'success', 'format' => 'Attribute was deleted.'),
1446 48 => array ('code' => 'success', 'format' => 'Supplement succeeded.'),
1447 49 => array ('code' => 'success', 'format' => 'Reduction succeeded.'),
1448 50 => array ('code' => 'success', 'format' => 'Reduction succeeded.'),
1449 51 => array ('code' => 'success', 'format' => 'Update succeeded.'),
1450 52 => array ('code' => 'success', 'format' => 'Supplement succeeded.'),
1451 53 => array ('code' => 'success', 'format' => 'Chapter was deleted.'),
1452 54 => array ('code' => 'success', 'format' => 'Chapter was updated.'),
1453 55 => array ('code' => 'success', 'format' => 'Chapter was added.'),
1454 56 => array ('code' => 'success', 'format' => 'Update succeeded.'),
1455 57 => array ('code' => 'success', 'format' => 'Reset complete'),
1456 58 => array ('code' => 'success', 'format' => "Deleted tag '%s'."),
1457 59 => array ('code' => 'success', 'format' => "Created tag '%s'."),
1458 60 => array ('code' => 'success', 'format' => "Updated tag '%s'."),
1459 61 => array ('code' => 'success', 'format' => 'Password changed successfully.'),
1460 62 => array ('code' => 'success', 'format' => 'gw: %s'),
1461 63 => array ('code' => 'success', 'format' => '%u change request(s) have been processed'),
1462 64 => array ('code' => 'success', 'format' => 'Port %s@%s has been assigned to VLAN %u'),
1463 65 => array ('code' => 'success', 'format' => "Added new rack '%s'"),
1464 66 => array ('code' => 'success', 'format' => "File sent Ok via handler '%s'"),
1465 67 => array ('code' => 'success', 'format' => "Tag rolling done, %u objects involved"),
1466 68 => array ('code' => 'success', 'format' => "Updated rack '%s'"),
1467 69 => array ('code' => 'success', 'format' => 'File "%s" was added successfully'),
1468 70 => array ('code' => 'success', 'format' => 'File "%s" was updated successfully'),
1469 71 => array ('code' => 'success', 'format' => 'File "%s" was linked successfully'),
1470 72 => array ('code' => 'success', 'format' => 'File was unlinked successfully'),
1471 73 => array ('code' => 'success', 'format' => 'File "%s" was deleted successfully'),
1472 74 => array ('code' => 'success', 'format' => 'Row "%s" was added successfully'),
1473 75 => array ('code' => 'success', 'format' => 'Row "%s" was updated successfully'),
1474 76 => array ('code' => 'success', 'format' => 'Object "%s" was deleted successfully'),
1475 77 => array ('code' => 'success', 'format' => 'Row "%s" was deleted successfully'),
1476 78 => array ('code' => 'success', 'format' => 'File "%s" saved Ok'),
1477 79 => array ('code' => 'success', 'format' => 'Rack "%s" was deleted successfully'),
1478 80 => array ('code' => 'success', 'format' => "Added new object '%s'"),
1480 // records 100~199 with fatal error messages
1481 100 => array ('code' => 'error', 'format' => '%s'),
1482 101 => array ('code' => 'error', 'format' => 'Port name cannot be empty'),
1483 102 => array ('code' => 'error', 'format' => "Error creating user account '%s'"),
1484 103 => array ('code' => 'error', 'format' => 'User not found!'),
1485 104 => array ('code' => 'error', 'format' => "Error updating user account '%s'"),
1489 108 => array ('code' => 'error', 'format' => '%u failures and %u successfull changes.'),
1490 109 => array ('code' => 'error', 'format' => 'Update failed!'),
1491 110 => array ('code' => 'error', 'format' => 'Supplement failed!'),
1492 111 => array ('code' => 'error', 'format' => 'Reduction failed!'),
1493 112 => array ('code' => 'error', 'format' => 'Error adding chapter.'),
1494 113 => array ('code' => 'error', 'format' => 'Error updating chapter.'),
1495 114 => array ('code' => 'error', 'format' => 'Error deleting chapter.'),
1496 115 => array ('code' => 'error', 'format' => 'Error renaming attribute.'),
1497 116 => array ('code' => 'error', 'format' => 'Error creating attribute.'),
1498 117 => array ('code' => 'error', 'format' => 'Error deleting attribute.'),
1499 118 => array ('code' => 'error', 'format' => 'Supplement failed!'),
1500 119 => array ('code' => 'error', 'format' => 'Reduction failed!'),
1501 120 => array ('code' => 'error', 'format' => 'Reset failed!'),
1502 121 => array ('code' => 'error', 'format' => 'commitUpdateObject() failed'),
1503 122 => array ('code' => 'error', 'format' => 'One or more update(s) failed!'),
1504 123 => array ('code' => 'error', 'format' => 'Cannot process submitted data: unknown format code.'),
1505 124 => array ('code' => 'error', 'format' => 'Error removing reservation!'),
1506 125 => array ('code' => 'error', 'format' => "Update failed with error: '%s'"),
1507 126 => array ('code' => 'error', 'format' => 'addRStoRSPool() failed'),
1508 127 => array ('code' => 'error', 'format' => 'Added %u real servers and encountered %u errors'),
1509 128 => array ('code' => 'error', 'format' => 'commitDeleteRS() failed'),
1510 129 => array ('code' => 'error', 'format' => 'commitDeleteLB() failed'),
1511 130 => array ('code' => 'error', 'format' => 'commitDeleteVS() failed'),
1512 131 => array ('code' => 'error', 'format' => 'invalid format requested'),
1513 132 => array ('code' => 'error', 'format' => 'invalid protocol'),
1514 133 => array ('code' => 'error', 'format' => 'commitUpdateRS() failed'),
1515 134 => array ('code' => 'error', 'format' => 'commitUpdateLB() failed'),
1516 135 => array ('code' => 'error', 'format' => 'commitUpdateVS() failed'),
1517 136 => array ('code' => 'error', 'format' => 'addLBtoRSPool() failed'),
1518 137 => array ('code' => 'error', 'format' => 'addLBtoRSPool() failed'),
1519 138 => array ('code' => 'error', 'format' => 'commitDeleteRSPool() failed'),
1520 139 => array ('code' => 'error', 'format' => 'commitUpdateRSPool() failed'),
1521 140 => array ('code' => 'error', 'format' => 'Encountered %u errors, (de)activated %u real servers'),
1522 141 => array ('code' => 'error', 'format' => 'Encountered %u errors, updated %u IP address(es)'),
1523 142 => array ('code' => 'error', 'format' => 'executeAutoPorts() failed'),
1524 143 => array ('code' => 'error', 'format' => 'Tried chaining %u tags, but experienced %u errors.'),
1525 144 => array ('code' => 'error', 'format' => "Error deleting tag: '%s'"),
1526 145 => array ('code' => 'error', 'format' => "Invalid tag name '%s'"),
1528 147 => array ('code' => 'error', 'format' => "Could not create tag '%s': %s"),
1529 148 => array ('code' => 'error', 'format' => "Could not update tag '%s': %s"),
1530 149 => array ('code' => 'error', 'format' => 'Turing test failed'),
1531 150 => array ('code' => 'error', 'format' => 'Can only change password under DB authentication.'),
1532 151 => array ('code' => 'error', 'format' => 'Old password doesn\'t match.'),
1533 152 => array ('code' => 'error', 'format' => 'New passwords don\'t match.'),
1534 153 => array ('code' => 'error', 'format' => 'Password change failed.'),
1535 154 => array ('code' => 'error', 'format' => "Verification error: %s"),
1536 155 => array ('code' => 'error', 'format' => 'Save failed.'),
1537 156 => array ('code' => 'error', 'format' => 'getSwitchVLANs() failed'),
1538 157 => array ('code' => 'error', 'format' => 'operation not permitted'),
1539 158 => array ('code' => 'error', 'format' => 'Ignoring malformed record #%u in form submit'),
1540 159 => array ('code' => 'error', 'format' => 'Permission denied moving port %s from VLAN%u to VLAN%u'),
1541 160 => array ('code' => 'error', 'format' => 'Invalid arguments'),
1542 161 => array ('code' => 'error', 'format' => 'Endpoint not found. Please either set FQDN attribute or assign an IP address to the object.'),
1543 162 => array ('code' => 'error', 'format' => 'More than one IP address is assigned to this object, please configure FQDN attribute.'),
1544 163 => array ('code' => 'error', 'format' => 'Failed to get any response from queryGateway() or the gateway died'),
1545 164 => array ('code' => 'error', 'format' => 'Gateway failure: %s.'),
1546 165 => array ('code' => 'error', 'format' => 'Gateway failure: malformed reply.'),
1547 166 => array ('code' => 'error', 'format' => 'gw: %s'),
1548 167 => array ('code' => 'error', 'format' => 'Could not find port %s'),
1549 168 => array ('code' => 'error', 'format' => 'Port %s is a trunk'),
1550 169 => array ('code' => 'error', 'format' => 'Failed to configure %s, connector returned code %u'),
1551 170 => array ('code' => 'error', 'format' => 'There is no network for IP address "%s"'),
1552 171 => array ('code' => 'error', 'format' => "Failed creating rack '%s'. Already exists in this row?"),
1553 172 => array ('code' => 'error', 'format' => 'Malformed request'),
1554 173 => array ('code' => 'error', 'format' => "Invalid IPv4 prefix '%s'"),
1555 174 => array ('code' => 'error', 'format' => 'Bad IPv4 address'),
1556 175 => array ('code' => 'error', 'format' => 'Invalid netmask'),
1557 176 => array ('code' => 'error', 'format' => 'This network already exists'),
1558 177 => array ('code' => 'error', 'format' => 'commitUpdateRack() failed'),
1559 178 => array ('code' => 'error', 'format' => 'file not found'),
1560 179 => array ('code' => 'error', 'format' => 'Declining outdated text. Re-edit the file for consistency.'),
1561 180 => array ('code' => 'error', 'format' => 'Error saving file, all changes lost!'),
1562 181 => array ('code' => 'error', 'format' => "file uploads not allowed, change 'file_uploads' parameter in php.ini"),
1563 182 => array ('code' => 'error', 'format' => 'SQL query failed: %s'),
1564 183 => array ('code' => 'error', 'format' => "Tag id '%s' does not exist."),
1565 184 => array ('code' => 'error', 'format' => 'Submitted form is invalid at line %u'),
1566 185 => array ('code' => 'error', 'format' => "Failed to add object '%s'"),
1567 186 => array ('code' => 'error', 'format' => 'Incomplete form has been ignored. Cheers.'),
1568 187 => array ('code' => 'error', 'format' => "Internal error in function '%s'"),
1570 // records 200~299 with warnings
1571 200 => array ('code' => 'warning', 'format' => '%s'),
1572 201 => array ('code' => 'warning', 'format' => 'nothing happened...'),
1573 202 => array ('code' => 'warning', 'format' => 'gw: %s'),
1574 203 => array ('code' => 'warning', 'format' => 'Port %s seems to be the first in VLAN %u at this switch.'),
1575 204 => array ('code' => 'warning', 'format' => 'Check uplink/downlink configuration for proper operation.'),
1576 205 => array ('code' => 'warning', 'format' => '%u change request(s) have been ignored'),
1577 206 => array ('code' => 'warning', 'format' => 'Rack is not empty'),
1578 207 => array ('code' => 'warning', 'format' => 'Ignored empty request'),
1581 // Handle the arguments. Is there any better way to do it?
1582 foreach ($log['m'] as $record)
1584 if (!isset ($record['c']) or !isset ($msginfo[$record['c']]))
1586 echo '<div class=msg_neutral>(this message was lost)</div>';
1589 if (isset ($record['a']))
1590 switch (count ($record['a']))
1595 $msginfo[$record['c']]['format'],
1602 $msginfo[$record['c']]['format'],
1610 $msginfo[$record['c']]['format'],
1620 $msginfo[$record['c']]['format'],
1629 $msgtext = $msginfo[$record['c']]['format'];
1630 echo '<div class=msg_' . $msginfo[$record['c']]['code'] . ">${msgtext}</div>";
1634 echo '<div class=msg_error>' . __FUNCTION__
. ': internal error</div>';
1640 The following conditions must be followed:
1641 1. We can mount onto free atoms only. This means: if any record for an atom
1642 already exists in RackSpace, it can't be used for mounting.
1643 2. We can't unmount from 'W' atoms. Operator should review appropriate comments
1644 and either delete them before unmounting or refuse to unmount the object.
1647 // We extensively use $_REQUEST in the function.
1648 function renderRackSpaceForObject ($object_id)
1650 $is_update = isset ($_REQUEST['rackmulti'][0]);
1651 $info = getObjectInfo ($object_id);
1654 showError ('getObjectInfo() failed', __FUNCTION__
);
1657 // Always process occupied racks plus racks chosen by user. First get racks with
1658 // already allocated rackspace...
1659 if (NULL === ($workingRacksData = getResidentRacksData ($object_id)))
1660 die; // some error already shown
1662 // ...and then add those chosen by user (if any).
1663 if (isset($_REQUEST['rackmulti']))
1664 foreach ($_REQUEST['rackmulti'] as $cand_id)
1666 if (!isset ($workingRacksData[$cand_id]))
1668 $rackData = getRackData ($cand_id);
1669 if ($rackData == NULL)
1671 showError ('getRackData() failed', __FUNCTION__
);
1674 $workingRacksData[$cand_id] = $rackData;
1678 printOpFormIntro ('updateObjectAllocation');
1680 // Do it only once...
1681 foreach ($workingRacksData as $rackId => &$rackData)
1683 applyObjectMountMask ($rackData, $object_id);
1684 echo "<input type=\"hidden\" name=\"rackmulti[]\" value=\"$rackId\">";
1686 // Now we workaround an old caveat: http://bugs.php.net/bug.php?id=37410
1689 // This is the time for rendering.
1691 // Main layout starts.
1692 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0><tr>";
1694 // Left portlet with rack list.
1695 echo "<td class=pcleft height='1%'>";
1696 startPortlet ('Racks');
1697 $allRacksData = listCells ('rack');
1698 if (count ($allRacksData) <= getConfigVar ('RACK_PRESELECT_THRESHOLD'))
1700 foreach (array_keys ($allRacksData) as $rack_id)
1702 $rackData = getRackData ($rack_id);
1703 if ($rackData == NULL)
1705 showError ('getRackData() failed', __FUNCTION__
);
1708 $workingRacksData[$rack_id] = $rackData;
1710 foreach ($workingRacksData as &$rackData)
1711 applyObjectMountMask ($rackData, $object_id);
1714 renderRackMultiSelect ('rackmulti[]', $allRacksData, array_keys ($workingRacksData));
1720 // Middle portlet with comment and submit.
1721 echo "<td class=pcleft>";
1722 startPortlet ('Comment');
1723 echo "<textarea name=comment rows=10 cols=40></textarea><br>\n";
1724 echo "<input type=submit value='Save' name=got_atoms>\n";
1730 // Right portlet with rendered racks. If this form submit is not final, we have to
1731 // reflect the former state of the grid in current form.
1732 echo "<td class=pcright rowspan=2 height='1%'>";
1733 startPortlet ('Working copy');
1734 echo '<table border=0 cellspacing=10 align=center><tr>';
1735 foreach ($workingRacksData as $rack_id => $rackData)
1737 // Order is important here: only original allocation is highlighted.
1738 highlightObject ($rackData, $object_id);
1739 markupAtomGrid ($rackData, 'T');
1740 // If we have a form processed, discard user input and show new database
1743 mergeGridFormToRack ($rackData);
1744 echo "<td valign=top>";
1745 echo "<center>\n<h2>${rackData['name']}</h2>\n";
1746 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
1747 echo "<tr><th width='10%'> </th>";
1748 echo "<th width='20%'><a href='javascript:;' onclick=\"toggleColumnOfAtoms('${rack_id}', '0', ${rackData['height']})\">Front</a></th>";
1749 echo "<th width='50%'><a href='javascript:;' onclick=\"toggleColumnOfAtoms('${rack_id}', '1', ${rackData['height']})\">Interior</a></th>";
1750 echo "<th width='20%'><a href='javascript:;' onclick=\"toggleColumnOfAtoms('${rack_id}', '2', ${rackData['height']})\">Back</a></th></tr>\n";
1751 renderAtomGrid ($rackData);
1752 echo "<tr><th width='10%'> </th>";
1753 echo "<th width='20%'><a href='javascript:;' onclick=\"toggleColumnOfAtoms('${rack_id}', '0', ${rackData['height']})\">Front</a></th>";
1754 echo "<th width='50%'><a href='javascript:;' onclick=\"toggleColumnOfAtoms('${rack_id}', '1', ${rackData['height']})\">Interior</a></th>";
1755 echo "<th width='20%'><a href='javascript:;' onclick=\"toggleColumnOfAtoms('${rack_id}', '2', ${rackData['height']})\">Back</a></th></tr>\n";
1756 echo "</table></center>\n";
1759 echo "</tr></table>";
1765 echo "</tr></table>\n";
1768 function renderMolecule ($mdata, $object_id)
1771 $rackpack = array();
1773 foreach ($mdata as $rua)
1775 $rack_id = $rua['rack_id'];
1776 $unit_no = $rua['unit_no'];
1777 $atom = $rua['atom'];
1778 if (!isset ($rackpack[$rack_id]))
1780 $rackData = getRackData ($rack_id);
1781 for ($i = $rackData['height']; $i > 0; $i--)
1782 for ($locidx = 0; $locidx < 3; $locidx++
)
1783 $rackData[$i][$locidx]['state'] = 'F';
1784 $rackpack[$rack_id] = $rackData;
1786 $rackpack[$rack_id][$unit_no][$loclist[$atom]]['state'] = 'T';
1787 $rackpack[$rack_id][$unit_no][$loclist[$atom]]['object_id'] = $object_id;
1789 // now we have some racks to render
1790 foreach ($rackpack as $rackData)
1792 markAllSpans ($rackData);
1793 echo "<table class=molecule cellspacing=0>\n";
1794 echo "<caption>${rackData['name']}</caption>\n";
1795 echo "<tr><th width='10%'> </th><th width='20%'>Front</th><th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
1796 for ($i = $rackData['height']; $i > 0; $i--)
1798 echo "<tr><th>$i</th>";
1799 for ($locidx = 0; $locidx < 3; $locidx++
)
1801 $state = $rackData[$i][$locidx]['state'];
1802 echo "<td class=state_${state}> </td>\n";
1810 function renderEmptyPortsSelect ($port_id, $type_id)
1812 $ports = getEmptyPortsOfType($type_id);
1813 usort($ports, 'sortEmptyPorts');
1814 foreach ($ports as $port)
1816 if ($port_id == $port['Port_id'])
1818 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";
1822 function renderDepot ()
1824 global $pageno, $nextorder;
1825 $cellfilter = getCellFilter();
1826 $objects = filterCellList (listCells ('object'), $cellfilter['expression']);
1828 echo "<table border=0 class=objectview>\n";
1829 echo "<tr><td class=pcleft>";
1831 startPortlet ('Objects (' . count ($objects) . ')');
1832 if ($objects === NULL)
1834 showError ('Fatal error retrieving object list', __FUNCTION__
);
1837 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1838 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>Barcode</th><th>Row/Rack</th></tr>';
1840 foreach ($objects as $obj)
1842 if (isset ($_REQUEST['hl_object_id']) and $_REQUEST['hl_object_id'] == $obj['id'])
1843 $secondclass = 'tdleft port_highlight';
1845 $secondclass = 'tdleft';
1846 $tags = loadEntityTags ('object', $obj['id']);
1847 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>";
1849 echo '<br><small>' . serializeTags ($tags, makeHref(array('page'=>$pageno, 'tab'=>'default')) . '&') . '</small>';
1850 echo "</td><td class='${secondclass}'>${obj['label']}</td>";
1851 echo "<td class='${secondclass}'>${obj['asset_no']}</td>";
1852 echo "<td class='${secondclass}'>${obj['barcode']}</td>";
1853 if ($obj['rack_id'])
1854 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>";
1856 echo "<td class='${secondclass}'>Unmounted</td>";
1858 $order = $nextorder[$order];
1863 echo "</td><td class=pcright width='25%'>";
1865 renderCellFilterPortlet ($cellfilter, 'object');
1866 echo "</td></tr></table>\n";
1869 // History viewer for history-enabled simple dictionaries.
1870 function renderHistory ($object_type, $object_id)
1872 switch ($object_type)
1875 $query = "select ctime, user_name, name, comment from RackRowHistory where id = ${object_id} order by ctime";
1876 $header = '<tr><th>change time</th><th>author</th><th>rack row name</th><th>rack row comment</th></tr>';
1881 "select ctime, user_name, rh.name, rr.name as name, rh.height, rh.comment " .
1882 "from RackHistory as rh left join RackRow as rr on rh.row_id = rr.id " .
1883 "where rh.id = ${object_id} order by ctime";
1884 $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>';
1889 "select ctime, user_name, RackObjectHistory.name as name, label, barcode, asset_no, has_problems, dict_value, comment " .
1890 "from RackObjectHistory inner join Dictionary on objtype_id = dict_key join Chapter on Dictionary.chapter_id = Chapter.id " .
1891 "where Chapter.name = 'RackObjectType' and RackObjectHistory.id=${object_id} order by ctime";
1892 $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>';
1896 showError ("Uknown object type '${object_type}'", __FUNCTION__
);
1900 $result = $dbxlink->query ($query);
1901 if ($result == NULL)
1903 showError ('SQL query failed', __FUNCTION__
);
1906 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1910 while ($row = $result->fetch (PDO
::FETCH_NUM
))
1912 echo "<tr class=row_${order}><td>${row[0]}</td>";
1913 for ($i = 1; $i <= $extra; $i++
)
1914 echo "<td>" . $row[$i] . "</td>";
1916 $order = $nextorder[$order];
1918 echo "</table><br>\n";
1921 function renderRackspaceHistory ()
1923 global $nextorder, $pageno, $tabno;
1925 $history = getRackspaceHistory();
1926 // Show the last operation by default.
1927 if (isset ($_REQUEST['op_id']))
1928 $op_id = $_REQUEST['op_id'];
1929 elseif (isset ($history[0]['mo_id']))
1930 $op_id = $history[0]['mo_id'];
1937 list ($omid, $nmid) = getOperationMolecules ($op_id);
1939 // Main layout starts.
1940 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
1942 // Left top portlet with old allocation.
1943 echo "<tr><td class=pcleft>";
1944 startPortlet ('Old allocation');
1947 $oldMolecule = getMolecule ($omid);
1948 renderMolecule ($oldMolecule, $object_id);
1954 echo '</td><td class=pcright>';
1956 // Right top portlet with new allocation
1957 startPortlet ('New allocation');
1960 $newMolecule = getMolecule ($nmid);
1961 renderMolecule ($newMolecule, $object_id);
1967 echo '</td></tr><tr><td colspan=2>';
1969 // Bottom portlet with list
1971 startPortlet ('Rackspace allocation history');
1972 echo "<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>\n";
1973 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";
1974 foreach ($history as $row)
1976 if ($row['mo_id'] == $op_id)
1979 $class = "row_${order}";
1980 echo "<tr class=${class}><td><a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno, 'op_id'=>$row['mo_id']))."'>${row['ctime']}</a></td>";
1981 echo "<td>${row['user_name']}</td>";
1982 echo "<td>${row['ro_id']}</td><td>${row['objtype_name']}</td><td>${row['name']}</td><td>${row['comment']}</td>\n";
1984 $order = $nextorder[$order];
1989 echo '</td></tr></table>';
1992 function renderIPv4SpaceRecords ($tree, &$tagcache, $baseurl, $target = 0, $level = 1)
1994 $self = __FUNCTION__
;
1995 foreach ($tree as $item)
1997 $total = $item['addrt'];
1998 if (getConfigVar ('IPV4_TREE_SHOW_USAGE') == 'yes')
2000 loadIPv4AddrList ($item); // necessary to compute router list and address counter
2001 $used = $item['addrc'];
2005 $item['addrlist'] = array();
2008 if (isset ($item['id']))
2010 if ($item['symbol'] == 'node-collapsed')
2011 $expandurl = "${baseurl}&eid=" . $item['id'] . "#netid" . $item['id'];
2012 elseif ($item['symbol'] == 'node-expanded')
2013 $expandurl = $baseurl . ($item['parent_id'] ?
"&eid=${item['parent_id']}#netid${item['parent_id']}" : '');
2016 echo "<tr valign=top>";
2017 printIPv4NetInfoTDs ($item, 'tdleft', $level, $item['symbol'], $expandurl);
2018 echo "<td class=tdcenter>";
2019 if ($target == $item['id'])
2020 echo "<a name=netid${target}></a>";
2021 if (getConfigVar ('IPV4_TREE_SHOW_USAGE') == 'yes')
2023 renderProgressBar ($total ?
$used/$total : 0);
2024 echo "<br><small>${used}/${total}</small>";
2027 echo "<small>${total}</small>";
2029 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
2030 printRoutersTD (findRouters ($item['addrlist']), $tagcache);
2032 if ($item['symbol'] == 'node-expanded' or $item['symbol'] == 'node-expanded-static')
2033 $self ($item['kids'], $tagcache, $baseurl, $target, $level +
1);
2037 echo "<tr valign=top>";
2038 printIPv4NetInfoTDs ($item, 'tdleft sparenetwork', $level, $item['symbol']);
2039 echo "<td class=tdcenter>";
2040 if (getConfigVar ('IPV4_TREE_SHOW_USAGE') == 'yes')
2042 renderProgressBar ($used/$total, 'sparenetwork');
2043 echo "<br><small>${used}/${total}</small>";
2046 echo "<small>${total}</small>";
2047 echo "</td><td> </td></tr>";
2052 function renderIPv4Space ()
2054 global $pageno, $tabno;
2055 $cellfilter = getCellFilter();
2056 $netlist = filterCellList (listCells ('ipv4net'), $cellfilter['expression']);
2057 array_walk ($netlist, 'amplifyCell');
2059 $netcount = count ($netlist);
2060 // expand request can take either natural values or "ALL". Zero means no expanding.
2061 $eid = isset ($_REQUEST['eid']) ?
$_REQUEST['eid'] : 0;
2062 $tree = prepareIPv4Tree ($netlist, $eid);
2064 echo "<table border=0 class=objectview>\n";
2065 echo "<tr><td class=pcleft>";
2066 startPortlet ("networks (${netcount})");
2069 echo 'auto-collapsing at threshold ' . getConfigVar ('TREE_THRESHOLD') .
2070 " (<a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno, 'eid'=>'ALL')) .
2071 $cellfilter['urlextra'] . "'>expand all</a>)";
2072 elseif ($eid === 'ALL')
2073 echo "expanding all (<a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno)) .
2074 $cellfilter['urlextra'] . "'>auto-collapse</a>)";
2077 $netinfo = getIPv4NetworkInfo ($eid);
2078 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>)";
2080 echo "</h4><table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
2081 echo "<tr><th>prefix</th><th>name/tags</th><th>capacity</th>";
2082 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
2083 echo "<th>routed by</th>";
2085 $tagcache = array();
2086 $baseurl = makeHref(array('page'=>$pageno, 'tab'=>$tabno)) . $cellfilter['urlextra'];
2087 renderIPv4SpaceRecords ($tree, $tagcache, $baseurl, $eid);
2090 echo '</td><td class=pcright>';
2091 renderCellFilterPortlet ($cellfilter, 'ipv4net');
2092 echo "</td></tr></table>\n";
2095 function renderIPv4SLB ()
2097 global $page, $nextorder;
2099 startPortlet ('SLB configuration');
2100 echo "<table border=0 width='100%'><tr>";
2101 foreach (array ('ipv4vslist', 'ipv4rsplist', 'rservers', 'lbs') as $pno)
2102 echo "<td><h3><a href='".makeHref(array('page'=>$pno))."'>" . $page[$pno]['title'] . "</a></h3></td>";
2103 echo '</tr></table>';
2106 $summary = getSLBSummary();
2107 startPortlet ('SLB tactical overview');
2108 // A single id-keyed array isn't used here to preserve existing
2109 // order of LBs returned by getSLBSummary()
2112 foreach ($summary as $vipdata)
2113 foreach (array_keys ($vipdata['lblist']) as $lb_object_id)
2114 if (!in_array ($lb_object_id, $lblist))
2116 $oi = getObjectInfo ($lb_object_id);
2117 $lbdname[$lb_object_id] = $oi['dname'];
2118 $lblist[] = $lb_object_id;
2120 if (!count ($summary))
2121 echo 'none configured';
2125 echo "<table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
2126 echo "<tr valign=top><td> </td>";
2127 foreach ($lblist as $lb_object_id)
2129 #echo "<th><a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$lb_object_id))."'>" . $lbdname[$lb_object_id] . "</a></th>";
2131 renderLBCell ($lb_object_id);
2135 foreach ($summary as $vsid => $vsdata)
2137 echo "<tr class=row_${order}><td class=tdleft>";
2138 renderVSCell ($vsid);
2140 foreach ($lblist as $lb_object_id)
2142 echo '<td class=tdleft>';
2143 if (!isset ($vsdata['lblist'][$lb_object_id]))
2147 echo $vsdata['lblist'][$lb_object_id]['size'];
2148 // echo " (<a href='".makeHref(array('page'=>'ipv4rspool', 'pool_id'=>$vsdata['lblist'][$lb_object_id]['id'])). "'>";
2149 // echo $vsdata['lblist'][$lb_object_id]['name'] . '</a>)';
2154 $order = $nextorder[$order];
2161 function renderIPv4SpaceEditor ()
2165 <script type
="text/javascript">
2167 document
.add_new_range
.range
.setAttribute('match', "^\\d\\d?\\d?\\.\\d\\d?\\d?\\.\\d\\d?\\d?\\.\\d\\d?\\d?\\/\\d\\d?$");
2175 startPortlet ("Add new");
2176 echo '<table border=0 cellpadding=10 align=center>';
2177 // This form requires a name, so JavaScript validator can find it.
2178 // No printOpFormIntro() hence
2179 echo "<form method=post name='add_new_range' action='".makeHrefProcess()."'>\n";
2180 echo "<input type=hidden name=op value=addIPv4Prefix>\n";
2182 echo '<tr><td rowspan=4><h3>assign tags</h3>';
2183 renderNewEntityTags();
2186 echo "<th class=tdright>prefix</th><td class=tdleft><input type=text name='range' size=18 class='live-validate' tabindex=1></td>";
2187 echo "<tr><th class=tdright>name</th><td class=tdleft><input type=text name='name' size='20' tabindex=2></td></tr>";
2188 echo "<tr><th class=tdright>connected network</th><td class=tdleft><input type=checkbox name='is_bcast' tabindex=3></td></tr>";
2189 echo "<tr><td colspan=2>";
2190 printImageHREF ('CREATE', 'Add a new network', TRUE, 4);
2192 echo "</form></table><br><br>\n";
2195 $addrspaceList = listCells ('ipv4net');
2196 array_walk ($addrspaceList, 'amplifyCell');
2197 if (count ($addrspaceList))
2199 startPortlet ('Manage existing (' . count ($addrspaceList) . ')');
2200 echo "<table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
2201 echo "<tr><th> </th><th>prefix</th><th>name</th><th> </th></tr>";
2202 foreach ($addrspaceList as $netinfo)
2204 echo "<form method=post action='".makeHrefProcess(array('op'=>'updIPv4Prefix', 'id'=>$netinfo['id']))."'>";
2205 echo "<tr valign=top><td>";
2206 if (getConfigVar ('IPV4_JAYWALK') == 'yes')
2208 echo "<a href='".makeHrefProcess(array('op'=>'delIPv4Prefix', 'id'=>$netinfo['id']))."'>";
2209 printImageHREF ('destroy', 'Delete this prefix');
2212 else // only render clickable image for empty networks
2214 $netdata = getIPv4NetworkInfo ($netinfo['id']);
2215 loadIPv4AddrList ($netdata);
2216 if (count ($netdata['addrlist']))
2217 printImageHREF ('nodestroy', 'There are ' . count ($netdata['addrlist']) . ' allocations inside');
2220 echo "<a href='".makeHrefProcess(array('op'=>'delIPv4Prefix', 'id'=>$netinfo['id']))."'>";
2221 printImageHREF ('destroy', 'Delete this prefix');
2226 echo "</td>\n<td class=tdleft>${netinfo['ip']}/${netinfo['mask']}</td>";
2227 echo "<td><input type=text name=name size=40 value='${netinfo['name']}'>";
2229 printImageHREF ('save', 'Save changes', TRUE);
2230 echo "</td></tr></form>\n";
2237 function renderIPv4Network ($id)
2239 global $pageno, $tabno, $aac2;
2240 $netmaskbylen = array
2242 32 => '255.255.255.255',
2243 31 => '255.255.255.254',
2244 30 => '255.255.255.252',
2245 29 => '255.255.255.248',
2246 28 => '255.255.255.240',
2247 27 => '255.255.255.224',
2248 26 => '255.255.255.192',
2249 25 => '255.255.255.128',
2250 24 => '255.255.255.0',
2251 23 => '255.255.254.0',
2252 22 => '255.255.252.0',
2253 21 => '255.255.248.0',
2254 20 => '255.255.240.0',
2255 19 => '255.255.224.0',
2256 18 => '255.255.192.0',
2257 17 => '255.255.128.0',
2258 16 => '255.255.0.0',
2259 15 => '255.254.0.0',
2260 14 => '255.252.0.0',
2261 13 => '255.248.0.0',
2262 12 => '255.240.0.0',
2263 11 => '255.224.0.0',
2264 10 => '255.192.0.0',
2275 $wildcardbylen = array
2292 17 => '0.0.127.255',
2294 15 => '0.1.255.255',
2295 14 => '0.3.255.255',
2296 13 => '0.7.255.255',
2297 12 => '0.15.255.255',
2298 11 => '0.31.255.255',
2299 10 => '0.63.255.255',
2300 9 => '0.127.255.255',
2301 8 => '0.255.255.255',
2302 7 => '1.255.255.255',
2303 6 => '3.255.255.255',
2304 5 => '7.255.255.255',
2305 4 => '15.255.255.255',
2306 3 => '31.255.255.255',
2307 2 => '63.255.255.255',
2308 1 => '127.255.255.255'
2310 $maxperpage = getConfigVar ('IPV4_ADDRS_PER_PAGE');
2311 if (isset($_REQUEST['pg']))
2312 $page = $_REQUEST['pg'];
2316 $range = getIPv4NetworkInfo ($id);
2317 loadIPv4AddrList ($range);
2318 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
2319 echo "<tr><td colspan=2 align=center><h1>${range['ip']}/${range['mask']}</h1><h2>${range['name']}</h2></td></tr>\n";
2321 echo "<tr><td class=pcleft width='50%'>";
2322 startPortlet ('summary');
2323 $total = ($range['ip_bin'] |
$range['mask_bin_inv']) - ($range['ip_bin'] & $range['mask_bin']) +
1;
2324 $used = count ($range['addrlist']);
2325 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
2327 echo "<tr><th width='50%' class=tdright>%% used:</th><td class=tdleft>";
2328 renderProgressBar ($used/$total);
2329 echo " ${used}/${total}</td></tr>\n";
2331 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
2333 // Build a backtrace from all parent networks.
2334 $clen = $range['mask'];
2335 $backtrace = array();
2336 while (NULL !== ($upperid = getIPv4AddressNetworkId ($range['ip'], $clen)))
2338 $upperinfo = getIPv4NetworkInfo ($upperid);
2339 $clen = $upperinfo['mask'];
2340 $backtrace[] = $upperid;
2342 $arrows = count ($backtrace);
2343 foreach (array_reverse ($backtrace) as $ancestorid)
2345 $ainfo = getIPv4NetworkInfo ($ancestorid);
2346 echo "<tr><th width='50%' class=tdright>";
2347 for ($i = 0; $i < $arrows; $i++
)
2350 echo "</th><td class=tdleft>";
2351 renderIPv4NetCell ($ainfo);
2354 echo "<tr><th width='50%' class=tdright>→</th>";
2355 echo "<td class=tdleft>";
2356 renderIPv4NetCell ($range);
2358 // FIXME: get and display nested networks
2359 // $theitem = pickLeaf ($ipv4tree, $id);
2362 echo "<tr><th width='50%' class=tdright>Netmask:</th><td class=tdleft>";
2363 echo $netmaskbylen[$range['mask']];
2364 echo "</td></tr>\n";
2366 echo "<tr><th width='50%' class=tdright>Netmask:</th><td class=tdleft>";
2367 printf ('0x%08X', binMaskFromDec ($range['mask']));
2368 echo "</td></tr>\n";
2370 echo "<tr><th width='50%' class=tdright>Wildcard bits:</th><td class=tdleft>";
2371 echo $wildcardbylen[$range['mask']];
2372 echo "</td></tr>\n";
2374 $routers = findRouters ($range['addrlist']);
2375 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes' and count ($routers))
2377 echo "<tr><th width='50%' class=tdright>Routed by:</th>";
2378 printRoutersTD ($routers);
2382 printTagTRs (makeHref(array('page'=>'ipv4space', 'tab'=>'default'))."&");
2383 echo "</table><br>\n";
2386 renderFilesPortlet ('ipv4net', $id);
2389 echo "<td class=pcright>";
2390 startPortlet ('details');
2391 $startip = $range['ip_bin'] & $range['mask_bin'];
2392 $endip = $range['ip_bin'] |
$range['mask_bin_inv'];
2393 $realstartip = $startip;
2394 $realendip = $endip;
2396 if($endip - $startip > $maxperpage)
2398 $numpages = ($endip - $startip)/$maxperpage;
2399 $startip = $startip +
$page * $maxperpage;
2400 $endip = $startip +
$maxperpage-1;
2404 echo '<h3>' . long2ip ($startip) . ' ~ ' . long2ip ($endip) . '</h3>';
2405 for ($i=0; $i<$numpages; $i++
)
2410 echo "<a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno, 'id'=>$id, 'pg'=>$i))."'>$i</a> ";
2414 echo "<table class='widetable' border=0 cellspacing=0 cellpadding=5 align='center' width='100%'>\n";
2415 echo "<tr><th>Address</th><th>Name</th><th>Allocation</th></tr>\n";
2418 for ($ip = $startip; $ip <= $endip; $ip++
) :
2419 if (isset ($_REQUEST['hl_ipv4_addr']) and ip2long ($_REQUEST['hl_ipv4_addr']) == $ip)
2420 $secondstyle = 'tdleft port_highlight';
2422 $secondstyle = 'tdleft';
2423 if (!isset ($range['addrlist'][$ip]))
2425 echo "<tr><td class=tdleft><a href='".makeHref(array('page'=>'ipaddress', 'ip'=>ip_long2quad($ip)))."'>" . ip_long2quad($ip);
2426 echo "</a></td><td class='${secondstyle}'> </td><td class='${secondstyle}'> </td></tr>\n";
2429 $addr = $range['addrlist'][$ip];
2430 echo "<tr class='${addr['class']}'>";
2432 echo "<td class=tdleft><a href='".makeHref(array('page'=>'ipaddress', 'ip'=>$addr['ip']))."'>${addr['ip']}</a></td>";
2433 echo "<td class='${secondstyle}'>${addr['name']}</td><td class='${secondstyle}'>";
2436 if ( $addr['reserved'] == 'yes')
2438 echo "<strong>RESERVED</strong> ";
2441 foreach ($range['addrlist'][$ip]['allocs'] as $ref)
2443 echo $delim . $aac2[$ref['type']];
2444 echo "<a href='".makeHref(array('page'=>'object', 'object_id'=>$ref['object_id'], 'hl_ipv4_addr'=>$addr['ip']))."'>";
2445 echo $ref['name'] . (empty ($ref['name']) ?
'' : '@');
2446 echo "${ref['object_name']}</a>";
2454 foreach ($range['addrlist'][$ip]['lblist'] as $ref)
2458 echo "${delim}<a href='".makeHref(array('page'=>'object', 'object_id'=>$ref['object_id']))."'>";
2459 echo "${ref['object_name']}</a>:<a href='".makeHref(array('page'=>'ipv4vs', 'vs_id'=>$ref['vs_id']))."'>";
2460 echo "${ref['vport']}/${ref['proto']}</a>→";
2468 foreach ($range['addrlist'][$ip]['rslist'] as $ref)
2472 echo "${delim}→${ref['rsport']}@<a href='".makeHref(array('page'=>'ipv4rspool', 'pool_id'=>$ref['rspool_id']))."'>";
2473 echo "${ref['rspool_name']}</a>";
2476 echo "</td></tr>\n";
2482 echo "</td></tr></table>\n";
2485 function renderIPv4NetworkProperties ($id)
2487 $netdata = getIPv4NetworkInfo ($id);
2488 echo "<center><h1>${netdata['ip']}/${netdata['mask']}</h1></center>\n";
2489 echo "<table border=0 cellpadding=10 cellpadding=1 align='center'>\n";
2490 printOpFormIntro ('editRange');
2491 echo "<tr><td class='tdright'>Name:</td><td class='tdleft'><input type=text name=name size=20 value='${netdata['name']}'></tr>";
2492 echo "<tr><td colspan=2 class=tdcenter>";
2493 printImageHREF ('SAVE', 'Save changes', TRUE);
2494 echo "</td></form></tr></table>\n";
2497 function renderIPv4Address ($dottedquad)
2500 $address = getIPv4Address ($dottedquad);
2501 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
2502 echo "<tr><td colspan=2 align=center><h1>${dottedquad}</h1></td></tr>\n";
2503 if (!empty ($address['name']))
2504 echo "<tr><td colspan=2 align=center><h2>${address['name']}</h2></td></tr>\n";
2506 echo "<tr><td class=pcleft>";
2507 startPortlet ('summary');
2508 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
2509 echo "<tr><th width='50%' class=tdright>Allocations:</th><td class=tdleft>" . count ($address['allocs']) . "</td></tr>\n";
2510 echo "<tr><th width='50%' class=tdright>Originated NAT connections:</th><td class=tdleft>" . count ($address['outpf']) . "</td></tr>\n";
2511 echo "<tr><th width='50%' class=tdright>Arriving NAT connections:</th><td class=tdleft>" . count ($address['inpf']) . "</td></tr>\n";
2512 echo "<tr><th width='50%' class=tdright>SLB virtual services:</th><td class=tdleft>" . count ($address['lblist']) . "</td></tr>\n";
2513 echo "<tr><th width='50%' class=tdright>SLB real servers:</th><td class=tdleft>" . count ($address['rslist']) . "</td></tr>\n";
2515 echo "</table><br>\n";
2519 echo "<td class=pcright>";
2521 if (isset ($address['class']))
2523 startPortlet ('allocations');
2524 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
2525 echo "<tr><th>object</th><th>OS interface</th><th>allocation type</th></tr>\n";
2526 $class = $address['class'];
2527 // render all allocation records for this address the same way
2528 if ($address['reserved'] == 'yes')
2529 echo "<tr class='${class}'><td colspan=2> </td><td class=tdleft><strong>RESERVED</strong></td></tr>";
2530 foreach ($address['allocs'] as $bond)
2532 if (isset ($_REQUEST['hl_object_id']) and $_REQUEST['hl_object_id'] == $bond['object_id'])
2533 $secondclass = 'tdleft port_highlight';
2535 $secondclass = 'tdleft';
2536 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>";
2537 echo $aat[$bond['type']];
2538 echo "</strong></td></tr>\n";
2540 echo "</table><br><br>";
2544 // FIXME: The returned list is structured differently, than we expect it to be. One of the sides
2546 if (count ($address['lblist']))
2548 startPortlet ('Virtual services (' . count ($address['lblist']) . ')');
2549 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
2550 echo "<tr><th>VS</th><th>name</th></tr>\n";
2551 foreach ($address['lblist'] as $vsinfo)
2553 echo "<tr><td class=tdleft><a href='".makeHref(array('page'=>'ipv4vs', 'vs_id'=>$vsinfo['vs_id']))."'>";
2554 echo buildVServiceName ($vsinfo) . "</a></td><td class=tdleft>";
2555 echo $vsinfo['name'] . "</td></tr>\n";
2557 echo "</table><br><br>";
2561 if (count ($address['rslist']))
2563 startPortlet ('Real servers (' . count ($address['rslist']) . ')');
2564 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
2565 echo "<tr><th> </th><th>port</th><th>RS pool</th></tr>\n";
2566 foreach ($address['rslist'] as $rsinfo)
2569 if ($rsinfo['inservice'] == 'yes')
2570 printImageHREF ('inservice', 'in service');
2572 printImageHREF ('notinservice', 'NOT in service');
2573 echo "</td><td class=tdleft>${rsinfo['rsport']}</td><td class=tdleft><a href='".makeHref(array('page'=>'ipv4rspool', 'pool_id'=>$rsinfo['rspool_id']))."'>";
2574 echo $rsinfo['rspool_name'] . "</a></td></tr>\n";
2576 echo "</table><br><br>";
2580 if (count ($address['outpf']))
2582 startPortlet ('departing NAT rules');
2583 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
2584 echo "<tr><th>proto</th><th>from</th><th>to</th><th>comment</th></tr>\n";
2585 foreach ($address['outpf'] as $rule)
2586 echo "<tr><td>${rule['proto']}</td><td>${rule['localip']}:${rule['localport']}</td><td>${rule['remoteip']}:${rule['remoteport']}</td><td>${rule['description']}</td></tr>";
2591 if (count ($address['inpf']))
2593 startPortlet ('arriving NAT rules');
2594 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
2595 echo "<tr><th>proto</th><th>from</th><th>to</th><th>comment</th></tr>\n";
2596 foreach ($address['inpf'] as $rule)
2597 echo "<tr><td>${rule['proto']}</td><td>${rule['localip']}:${rule['localport']}</td><td>${rule['remoteip']}:${rule['remoteport']}</td><td>${rule['description']}</td></tr>";
2606 function renderIPv4AddressProperties ($dottedquad)
2608 $address = getIPv4Address ($dottedquad);
2609 echo "<center><h1>$dottedquad</h1></center>\n";
2611 startPortlet ('update');
2612 echo "<table border=0 cellpadding=10 cellpadding=1 align='center'>\n";
2613 printOpFormIntro ('editAddress');
2614 echo "<tr><td class='tdright'>Name:</td><td class='tdleft'><input type=text name=name size=20 value='${address['name']}'></tr>";
2615 echo "<td class='tdright'>Reserved:</td><td class='tdleft'><input type=checkbox name=reserved size=20 ";
2616 echo ($address['reserved']=='yes') ?
'checked' : '';
2617 echo "></tr><tr><td class=tdleft>";
2618 printImageHREF ('SAVE', 'Save changes', TRUE);
2619 echo "</td></form><td class=tdright>";
2620 if (empty ($address['name']) and $address['reserved'] == 'no')
2621 printImageHREF ('CLEAR gray');
2624 printOpFormIntro ('editAddress', array ('name' => '', 'reserved' => ''));
2625 printImageHREF ('CLEAR', 'Release', TRUE);
2628 echo "</td></tr></table>\n";
2632 function renderIPv4AddressAllocations ($dottedquad)
2634 function printNewItemTR ()
2637 printOpFormIntro ('addIPv4Allocation');
2639 printImageHREF ('add', 'allocate', TRUE);
2641 printSelect (getNarrowObjectList ('IPV4OBJ_LISTSRC'), 'object_id', NULL, 100);
2642 echo "</td><td><input type=text tabindex=101 name=bond_name size=10></td><td>";
2643 printSelect ($aat, 'bond_type', NULL, 102);
2645 printImageHREF ('add', 'allocate', TRUE, 103);
2646 echo "</td></form></tr>";
2650 $address = getIPv4Address ($dottedquad);
2652 echo "<center><h1>${dottedquad}</h1></center>\n";
2653 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
2654 echo "<tr><th> </th><th>object</th><th>OS interface</th><th>allocation type</th><th> </th></tr>\n";
2656 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
2658 if (isset ($address['class']))
2660 $class = $address['class'];
2661 if ($address['reserved'] == 'yes')
2662 echo "<tr class='${class}'><td colspan=3> </td><td class=tdleft><strong>RESERVED</strong></td><td> </td></tr>";
2663 foreach ($address['allocs'] as $bond)
2665 echo "<tr class='$class'>";
2666 printOpFormIntro ('updIPv4Allocation', array ('object_id' => $bond['object_id']));
2667 echo "<td><a href='".makeHrefProcess(array('op'=>'delIPv4Allocation', 'ip'=>$dottedquad, 'object_id'=>$bond['object_id']))."'>";
2668 printImageHREF ('delete', 'Unallocate address');
2670 echo "<td><a href='".makeHref(array('page'=>'object', 'object_id'=>$bond['object_id'], 'hl_ipv4_addr'=>$dottedquad))."'>${bond['object_name']}</td>";
2671 echo "<td><input type='text' name='bond_name' value='${bond['name']}' size=10></td><td>";
2672 printSelect ($aat, 'bond_type', $bond['type']);
2674 printImageHREF ('save', 'Save changes', TRUE);
2675 echo "</td></form></tr>\n";
2678 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
2680 echo "</table><br><br>";
2683 function renderNATv4ForObject ($object_id)
2685 function printNewItemTR ($alloclist)
2687 printOpFormIntro ('addNATv4Rule');
2688 echo "<tr align='center'><td>";
2689 printImageHREF ('add', 'Add new NAT rule', TRUE);
2691 printSelect (array ('TCP' => 'TCP', 'UDP' => 'UDP'), 'proto');
2692 echo "<select name='localip' tabindex=1>";
2694 foreach ($alloclist as $dottedquad => $alloc)
2696 $name = empty ($alloc['addrinfo']['name']) ?
'' : (' (' . niftyString ($alloc['addrinfo']['name']) . ')');
2697 $osif = empty ($alloc['osif']) ?
'' : ($alloc['osif'] . ': ');
2698 echo "<option value='${dottedquad}'>${osif}${dottedquad}${name}</option>";
2701 echo "</select>:<input type='text' name='localport' size='4' tabindex=2></td>";
2702 echo "<td><input type='text' name='remoteip' id='remoteip' size='10' tabindex=3>";
2703 echo "<a href='javascript:;' onclick='window.open(\"" . makeHrefForHelper ('inet4list');
2704 echo "\", \"findobjectip\", \"height=700, width=400, location=no, menubar=no, resizable=yes, scrollbars=no, status=no, titlebar=no, toolbar=no\");'>";
2705 printImageHREF ('find', 'Find object');
2707 echo ":<input type='text' name='remoteport' size='4' tabindex=4></td><td></td>";
2708 echo "<td colspan=1><input type='text' name='description' size='20' tabindex=5></td><td>";
2709 printImageHREF ('add', 'Add new NAT rule', TRUE, 6);
2710 echo "</td></tr></form>";
2713 $info = getObjectInfo ($object_id);
2714 $forwards = getNATv4ForObject ($object_id);
2715 $alloclist = getObjectIPv4Allocations ($object_id);
2716 echo "<center><h2>locally performed NAT</h2></center>";
2718 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
2719 echo "<tr><th></th><th>Match endpoint</th><th>Translate to</th><th>Target object</th><th>Comment</th><th> </th></tr>\n";
2721 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
2722 printNewItemTR ($alloclist);
2723 foreach ($forwards['out'] as $pf)
2727 if (isset ($alloclist [$pf['localip']]))
2729 $class = $alloclist [$pf['localip']]['addrinfo']['class'];
2730 $osif = $alloclist [$pf['localip']]['osif'] . ': ';
2733 echo "<tr class='$class'>";
2734 echo "<td><a href='".
2735 makeHrefProcess(array(
2736 'op'=>'delNATv4Rule',
2737 'localip'=>$pf['localip'],
2738 'localport'=>$pf['localport'],
2739 'remoteip'=>$pf['remoteip'],
2740 'remoteport'=>$pf['remoteport'],
2741 'proto'=>$pf['proto'],
2742 'object_id'=>$object_id)).
2744 printImageHREF ('delete', 'Delete NAT rule');
2746 echo "<td>${pf['proto']}/${osif}<a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['localip']))."'>${pf['localip']}</a>:${pf['localport']}";
2747 if (!empty ($pf['local_addr_name']))
2748 echo ' (' . $pf['local_addr_name'] . ')';
2750 echo "<td><a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['remoteip']))."'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
2752 $address = getIPv4Address ($pf['remoteip']);
2754 echo "<td class='description'>";
2755 if (count ($address['allocs']))
2756 foreach ($address['allocs'] as $bond)
2757 echo "<a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$bond['object_id']))."'>${bond['object_name']}(${bond['name']})</a> ";
2758 elseif (!empty ($pf['remote_addr_name']))
2759 echo '(' . $pf['remote_addr_name'] . ')';
2765 'localip' => $pf['localip'],
2766 'localport' => $pf['localport'],
2767 'remoteip' => $pf['remoteip'],
2768 'remoteport' => $pf['remoteport'],
2769 'proto' => $pf['proto']
2772 echo "</td><td class='description'>";
2773 echo "<input type='text' name='description' value='${pf['description']}'></td><td>";
2774 printImageHREF ('save', 'Save changes', TRUE);
2775 echo "</td></form></tr>";
2777 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
2778 printNewItemTR ($alloclist);
2780 echo "</table><br><br>";
2782 echo "<center><h2>arriving NAT connections</h2></center>";
2783 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
2784 echo "<tr><th></th><th>Source</th><th>Source objects</th><th>Target</th><th>Description</th></tr>\n";
2786 foreach ($forwards['in'] as $pf)
2788 echo "<tr><td><a href='".
2789 makeHrefProcess(array(
2790 'op'=>'delNATv4Rule',
2791 'localip'=>$pf['localip'],
2792 'localport'=>$pf['localport'],
2793 'remoteip'=>$pf['remoteip'],
2794 'remoteport'=>$pf['remoteport'],
2795 'proto'=>$pf['proto'],
2796 'object_id'=>$pf['object_id']
2799 printImageHREF ('delete', 'Delete NAT rule');
2801 echo "<td>${pf['proto']}/<a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['localip']))."'>${pf['localip']}</a>:${pf['localport']}</td>";
2802 echo "<td class='description'><a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$pf['object_id']))."'>${pf['object_name']}</a>";
2803 echo "</td><td><a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['remoteip']))."'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
2804 echo "<td class='description'>${pf['description']}</td></tr>";
2807 echo "</table><br><br>";
2810 function renderAddMultipleObjectsForm ()
2812 $typelist = getObjectTypeList();
2813 $typelist[0] = 'select type...';
2814 $max = getConfigVar ('MASSCOUNT');
2817 startPortlet ('Distinct types, same tags');
2818 printOpFormIntro ('addObjects');
2819 echo '<table border=0 align=center>';
2820 echo "<tr><th>Object type</th><th>Common name</th><th>Visible label</th>";
2821 echo "<th>Asset tag</th><th>Barcode</th><th>Tags</th></tr>\n";
2822 for ($i = 0; $i < $max; $i++
)
2825 // Don't employ DEFAULT_OBJECT_TYPE to avoid creating ghost records for pre-selected empty rows.
2826 printSelect ($typelist, "${i}_object_type_id", 0, $tabindex);
2828 echo "<td><input type=text size=30 name=${i}_object_name tabindex=${tabindex}></td>";
2829 echo "<td><input type=text size=30 name=${i}_object_label tabindex=${tabindex}></td>";
2830 echo "<td><input type=text size=20 name=${i}_object_asset_no tabindex=${tabindex}></td>";
2831 echo "<td><input type=text size=10 name=${i}_object_barcode tabindex=${tabindex}></td>";
2834 echo "<td valign=top rowspan=${max}>";
2835 renderNewEntityTags();
2841 echo "<tr><td class=submit colspan=5><input type=submit name=got_fast_data value='Go!'></td></tr>\n";
2842 echo "</form></table>\n";
2845 startPortlet ('Same type, same tags');
2846 printOpFormIntro ('addLotOfObjects');
2847 echo "<table border=0 align=center><tr><th>names</th><th>type</th></tr>";
2848 echo "<tr><td rowspan=3><textarea name=namelist cols=40 rows=25>\n";
2849 echo "</textarea></td><td valign=top>";
2850 printSelect ($typelist, "global_type_id", getConfigVar ('DEFAULT_OBJECT_TYPE'));
2852 echo "<tr><th>Tags</th></tr>";
2853 echo "<tr><td valign=top>";
2854 renderNewEntityTags();
2856 echo "<tr><td colspan=2><input type=submit name=got_very_fast_data value='Go!'></td></tr></table>\n";
2861 function printGreeting ()
2863 global $root, $remote_username, $remote_displayname;
2864 echo "Hello, <a href='${root}?page=myaccount&tab=default'>${remote_displayname}</a>. This is RackTables " .
2866 ". Click <a href='${root}?logout'>here</a> to logout.";
2869 function renderSearchResults ()
2872 $terms = trim ($_REQUEST['q']);
2875 showError ('Search string cannot be empty.', __FUNCTION__
);
2878 if (!permitted ('depot', 'default'))
2880 showError ('You are not authorized for viewing information about objects.', __FUNCTION__
);