b28570777f949b7da90957e27d758a4cdaf2aaed
4 * This file contains frontend functions for RackTables.
8 // Interface function's special.
9 $nextorder['odd'] = 'even';
10 $nextorder['even'] = 'odd';
12 // address allocation type
15 'regular' => 'Connected',
16 'virtual' => 'Loopback',
20 // address allocation code, IPv4 addresses and objects view
24 'virtual' => '<strong>L</strong>',
25 'shared' => '<strong>S</strong>',
26 'router' => '<strong>R</strong>',
28 // address allocation code, IPv4 networks view
32 'virtual' => '<strong>L:</strong>',
33 'shared' => '<strong>S:</strong>',
34 'router' => '<strong>R:</strong>',
37 // Let's have it here, so extensions can add their own images.
39 $image['error']['path'] = 'pix/error.png';
40 $image['error']['width'] = 76;
41 $image['error']['height'] = 17;
42 $image['logo']['path'] = 'pix/defaultlogo.png';
43 $image['logo']['width'] = 210;
44 $image['logo']['height'] = 40;
45 $image['rackspace']['path'] = 'pix/racks.png';
46 $image['rackspace']['width'] = 218;
47 $image['rackspace']['height'] = 200;
48 $image['objects']['path'] = 'pix/server.png';
49 $image['objects']['width'] = 218;
50 $image['objects']['height'] = 200;
51 $image['files']['path'] = 'pix/files.png';
52 $image['files']['width'] = 218;
53 $image['files']['height'] = 200;
54 $image['ipv4space']['path'] = 'pix/addressspace.png';
55 $image['ipv4space']['width'] = 218;
56 $image['ipv4space']['height'] = 200;
57 $image['ipv4slb']['path'] = 'pix/slb.png';
58 $image['ipv4slb']['width'] = 218;
59 $image['ipv4slb']['height'] = 200;
60 $image['config']['path'] = 'pix/configuration.png';
61 $image['config']['width'] = 218;
62 $image['config']['height'] = 200;
63 $image['reports']['path'] = 'pix/report.png';
64 $image['reports']['width'] = 218;
65 $image['reports']['height'] = 200;
66 $image['download']['path'] = 'pix/download.png';
67 $image['download']['width'] = 16;
68 $image['download']['height'] = 16;
69 $image['DOWNLOAD']['path'] = 'pix/download-big.png';
70 $image['DOWNLOAD']['width'] = 32;
71 $image['DOWNLOAD']['height'] = 32;
72 $image['plug']['path'] = 'pix/tango-network-wired.png';
73 $image['plug']['width'] = 16;
74 $image['plug']['height'] = 16;
75 $image['cut']['path'] = 'pix/tango-edit-cut-16x16.png';
76 $image['cut']['width'] = 16;
77 $image['cut']['height'] = 16;
78 $image['CUT']['path'] = 'pix/tango-edit-cut-32x32.png';
79 $image['CUT']['width'] = 32;
80 $image['CUT']['height'] = 32;
81 $image['add']['path'] = 'pix/tango-list-add.png';
82 $image['add']['width'] = 16;
83 $image['add']['height'] = 16;
84 $image['ADD']['path'] = 'pix/tango-list-add-big.png';
85 $image['ADD']['width'] = 32;
86 $image['ADD']['height'] = 32;
87 $image['delete']['path'] = 'pix/tango-list-remove.png';
88 $image['delete']['width'] = 16;
89 $image['delete']['height'] = 16;
90 $image['destroy']['path'] = 'pix/tango-user-trash-16x16.png';
91 $image['destroy']['width'] = 16;
92 $image['destroy']['height'] = 16;
93 $image['nodestroy']['path'] = 'pix/tango-user-trash-16x16-gray.png';
94 $image['nodestroy']['width'] = 16;
95 $image['nodestroy']['height'] = 16;
96 $image['NODESTROY']['path'] = 'pix/tango-user-trash-32x32-gray.png';
97 $image['NODESTROY']['width'] = 32;
98 $image['NODESTROY']['height'] = 32;
99 $image['DESTROY']['path'] = 'pix/tango-user-trash-32x32.png';
100 $image['DESTROY']['width'] = 32;
101 $image['DESTROY']['height'] = 32;
102 $image['nodelete']['path'] = 'pix/tango-list-remove-shadow.png';
103 $image['nodelete']['width'] = 16;
104 $image['nodelete']['height'] = 16;
105 $image['inservice']['path'] = 'pix/tango-emblem-system.png';
106 $image['inservice']['width'] = 16;
107 $image['inservice']['height'] = 16;
108 $image['notinservice']['path'] = 'pix/tango-dialog-error.png';
109 $image['notinservice']['width'] = 16;
110 $image['notinservice']['height'] = 16;
111 $image['find']['path'] = 'pix/tango-system-search.png';
112 $image['find']['width'] = 16;
113 $image['find']['height'] = 16;
114 $image['next']['path'] = 'pix/tango-go-next.png';
115 $image['next']['width'] = 32;
116 $image['next']['height'] = 32;
117 $image['prev']['path'] = 'pix/tango-go-previous.png';
118 $image['prev']['width'] = 32;
119 $image['prev']['height'] = 32;
120 $image['clear']['path'] = 'pix/tango-edit-clear.png';
121 $image['clear']['width'] = 16;
122 $image['clear']['height'] = 16;
123 $image['CLEAR']['path'] = 'pix/tango-edit-clear-big.png';
124 $image['CLEAR']['width'] = 32;
125 $image['CLEAR']['height'] = 32;
126 $image['CLEAR gray']['path'] = 'pix/tango-edit-clear-gray-32x32.png';
127 $image['CLEAR gray']['width'] = 32;
128 $image['CLEAR gray']['height'] = 32;
129 $image['save']['path'] = 'pix/tango-document-save.png';
130 $image['save']['width'] = 16;
131 $image['save']['height'] = 16;
132 $image['SAVE']['path'] = 'pix/tango-document-save-big.png';
133 $image['SAVE']['width'] = 32;
134 $image['SAVE']['height'] = 32;
135 $image['create']['path'] = 'pix/tango-document-new.png';
136 $image['create']['width'] = 16;
137 $image['create']['height'] = 16;
138 $image['CREATE']['path'] = 'pix/tango-document-new-big.png';
139 $image['CREATE']['width'] = 32;
140 $image['CREATE']['height'] = 32;
141 $image['DENIED']['path'] = 'pix/tango-dialog-error-big.png';
142 $image['DENIED']['width'] = 32;
143 $image['DENIED']['height'] = 32;
144 $image['apply']['path'] = 'pix/tango-emblem-system.png';
145 $image['apply']['width'] = 16;
146 $image['apply']['height'] = 16;
147 $image['node-collapsed']['path'] = 'pix/node-collapsed.png';
148 $image['node-collapsed']['width'] = 16;
149 $image['node-collapsed']['height'] = 16;
150 $image['node-expanded']['path'] = 'pix/node-expanded.png';
151 $image['node-expanded']['width'] = 16;
152 $image['node-expanded']['height'] = 16;
153 $image['node-expanded-static']['path'] = 'pix/node-expanded-static.png';
154 $image['node-expanded-static']['width'] = 16;
155 $image['node-expanded-static']['height'] = 16;
156 $image['dragons']['path'] = 'pix/mitsudragon.png';
157 $image['dragons']['width'] = 125;
158 $image['dragons']['height'] = 21;
159 $image['LB']['path'] = 'pix/loadbalancer.png';
160 $image['LB']['width'] = 32;
161 $image['LB']['height'] = 32;
162 $image['RS pool']['path'] = 'pix/serverpool.png';
163 $image['RS pool']['width'] = 48;
164 $image['RS pool']['height'] = 16;
165 $image['VS']['path'] = 'pix/servicesign.png';
166 $image['VS']['width'] = 39;
167 $image['VS']['height'] = 62;
168 $image['router']['path'] = 'pix/router.png';
169 $image['router']['width'] = 32;
170 $image['router']['height'] = 32;
171 $image['ATTACH']['path'] = 'pix/crystal-attach-32x32.png';
172 $image['ATTACH']['width'] = 32;
173 $image['ATTACH']['height'] = 32;
174 $image['favorite']['path'] = 'pix/tango-emblem-favorite.png';
175 $image['favorite']['width'] = 16;
176 $image['favorite']['height'] = 16;
177 $image['computer']['path'] = 'pix/tango-computer.png';
178 $image['computer']['width'] = 16;
179 $image['computer']['height'] = 16;
180 $image['empty file']['path'] = 'pix/crystal-file-empty-32x32.png';
181 $image['empty file']['width'] = 32;
182 $image['empty file']['height'] = 32;
183 $image['text file']['path'] = 'pix/crystal-file-text-32x32.png';
184 $image['text file']['width'] = 32;
185 $image['text file']['height'] = 32;
186 $image['image file']['path'] = 'pix/crystal-file-image-32x32.png';
187 $image['image file']['width'] = 32;
188 $image['image file']['height'] = 32;
189 $image['NET']['path'] = 'pix/crystal-network-32x32.png';
190 $image['NET']['width'] = 32;
191 $image['NET']['height'] = 32;
192 $image['USER']['path'] = 'pix/crystal-edit-user-32x32.png';
193 $image['USER']['width'] = 32;
194 $image['USER']['height'] = 32;
196 // This may be populated later onsite, report rendering function will use it.
197 // See the $systemreport for structure.
198 $localreports = array();
199 $CodePressMap = array
205 'js' => 'javascript',
210 'uint' => '[U] unsigned integer',
211 'float' => '[F] floating point',
212 'string' => '[S] string',
213 'dict' => '[D] dictionary record'
216 // Rack thumbnail image width summands: "front", "interior" and "rear" elements w/o surrounding border.
225 function renderIndex ()
228 <table border
=0 cellpadding
=0 cellspacing
=0 width
='100%'>
231 <div style
='text-align: center; margin: 10px; '>
232 <table width
='100%' cellspacing
=0 cellpadding
=30 class=mainmenu border
=0>
235 <h1
><a href
='<?php echo makeHref(array('page
'=>'rackspace
')) ?>'>Rackspace
<br
>
236 <?php
printImageHREF ('rackspace'); ?
></a
></h1
>
239 <h1
><a href
='<?php echo makeHref(array('page
'=>'depot
')) ?>'>Objects
<br
>
240 <?php
printImageHREF ('objects'); ?
></a
></h1
>
243 <h1
><a href
='<?php echo makeHref(array('page
'=>'ipv4space
')) ?>'>IPv4 space
<br
>
244 <?php
printImageHREF ('ipv4space'); ?
></a
></h1
>
247 <h1
><a href
='<?php echo makeHref(array('page
'=>'files
')) ?>'>Files
<br
>
248 <?php
printImageHREF ('files'); ?
></a
></h1
>
253 <h1
><a href
='<?php echo makeHref(array('page
'=>'config
')) ?>'>Configuration
<br
>
254 <?php
printImageHREF ('config'); ?
></a
></h1
>
257 <h1
><a href
='<?php echo makeHref(array('page
'=>'reports
')) ?>'>Reports
<br
>
258 <?php
printImageHREF ('reports'); ?
></a
></h1
>
261 <h1
><a href
='<?php echo makeHref(array('page
'=>'ipv4slb
')) ?>'>IPv4 SLB
<br
>
262 <?php
printImageHREF ('ipv4slb'); ?
></a
></h1
>
274 function renderRackspace ()
276 showMessageOrError();
277 echo "<table class=objview border=0 width='100%'><tr><td class=pcleft>";
278 $cellfilter = getCellFilter();
279 renderCellFilterPortlet ($cellfilter, 'rack');
280 echo '</td><td class=pcright>';
281 echo '<table border=0 cellpadding=10 cellpadding=1>';
282 // generate thumb gallery
284 $rackwidth = getRackImageWidth();
285 // Zero value effectively disables the limit.
286 $maxPerRow = getConfigVar ('RACKS_PER_ROW');
288 foreach (getRackRows() as $row_id => $row_name)
290 $rackList = filterCellList (listCells ('rack', $row_id), $cellfilter['expression']);
291 if (!count ($rackList) and count ($cellfilter['expression']))
294 echo "<tr class=row_${order}><th class=tdleft>";
295 echo "<a href='".makeHref(array('page'=>'row', 'row_id'=>$row_id))."${cellfilter['urlextra']}'>";
296 echo "${row_name}</a></th><td><table border=0 cellspacing=5><tr>";
297 if (!count ($rackList))
298 echo "<td>(empty row)</td>";
300 foreach ($rackList as $rack)
302 if ($rackListIdx > 0 and $maxPerRow > 0 and $rackListIdx %
$maxPerRow == 0)
304 echo '</tr></table></tr>';
305 echo "<tr class=row_${order}><th class=tdleft>${row_name} (continued)";
306 echo "</th><td><table border=0 cellspacing=5><tr>";
307 $order = $nextorder[$order];
309 echo "<td align=center><a href='".makeHref(array('page'=>'rack', 'rack_id'=>$rack['id']))."'>";
310 echo "<img border=0 width=${rackwidth} height=";
311 echo getRackImageHeight ($rack['height']);
312 echo " title='${rack['height']} units'";
313 echo "src='render_image.php?img=minirack&rack_id=${rack['id']}'>";
314 echo "<br>${rack['name']}</a></td>";
317 echo "</tr></table></tr>\n";
320 echo "</td></tr></table>\n";
323 function renderRackspaceRowEditor ()
325 function printNewItemTR ()
327 printOpFormIntro ('addRow');
329 printImageHREF ('create', 'Add new row', TRUE);
330 echo "</td><td><input type=text name=name tabindex=100></td><td>";
331 printImageHREF ('create', 'Add new row', TRUE, 101);
332 echo "</td></tr></form>";
334 showMessageOrError();
335 startPortlet ('Rows');
336 echo "<table border=0 cellspacing=0 cellpadding=5 align=center class=widetable>\n";
337 echo "<tr><th> </th><th>Name</th><th> </th></tr>\n";
338 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
340 foreach (getRackRows() as $row_id => $row_name)
343 if ($rc = count (listCells ('rack', $row_id)))
344 printImageHREF ('nodestroy', "${rc} rack(s) here");
347 echo "<a href=\"".makeHrefProcess(array('op'=>'delete', 'row_id'=>$row_id))."\">";
348 printImageHREF ('destroy', 'Delete row');
351 printOpFormIntro ('updateRow', array ('row_id' => $row_id));
352 echo "</td><td><input type=text name=name value='${row_name}'></td><td>";
353 printImageHREF ('save', 'Save changes', TRUE);
354 echo "</form></td></tr>\n";
356 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
358 echo "</table><br>\n";
362 function renderRow ($row_id = 0)
366 showError ('Invalid row_id', __FUNCTION__
);
369 if (($rowInfo = getRackRowInfo ($row_id)) == NULL)
371 showError ('getRackRowInfo() failed', __FUNCTION__
);
374 $cellfilter = getCellFilter();
375 $rackList = filterCellList (listCells ('rack', $row_id), $cellfilter['expression']);
376 // Main layout starts.
377 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
379 // Left portlet with row information.
380 echo "<tr><td class=pcleft>";
381 startPortlet ($rowInfo['name']);
382 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
383 echo "<tr><th width='50%' class=tdright>Racks:</th><td class=tdleft>${rowInfo['count']}</td></tr>\n";
384 echo "<tr><th width='50%' class=tdright>Units:</th><td class=tdleft>${rowInfo['sum']}</td></tr>\n";
385 echo "<tr><th width='50%' class=tdright>%% used:</th><td class=tdleft>";
386 renderProgressBar (getRSUforRackRow ($rackList));
388 echo "</table><br>\n";
390 renderCellFilterPortlet ($cellfilter, 'rack', 'row_id', $row_id);
392 echo "</td><td class=pcright>";
395 $rackwidth = getRackImageWidth() * getConfigVar ('ROW_SCALE');
396 // Maximum number of racks per row is proportionally less, but at least 1.
397 $maxPerRow = max (floor (getConfigVar ('RACKS_PER_ROW') / getConfigVar ('ROW_SCALE')), 1);
400 startPortlet ('Racks');
401 echo "<table border=0 cellspacing=5 align='center'><tr>";
402 foreach ($rackList as $rack)
404 if ($rackListIdx %
$maxPerRow == 0)
406 if ($rackListIdx > 0)
410 echo "<td align=center class=row_${order}><a href='".makeHref(array('page'=>'rack', 'rack_id'=>$rack['id']))."'>";
411 echo "<img border=0 width=${rackwidth} height=" . (getRackImageHeight ($rack['height']) * getConfigVar ('ROW_SCALE'));
412 echo " title='${rack['height']} units'";
413 echo "src='render_image.php?img=minirack&rack_id=${rack['id']}'>";
414 echo "<br>${rack['name']}</a></td>";
415 $order = $nextorder[$order];
418 echo "</tr></table>\n";
420 echo "</td></tr></table>";
423 function showError ($info = '', $location = 'N/A')
425 if (preg_match ('/\.php$/', $location))
426 $location = basename ($location);
427 elseif ($location != 'N/A')
428 $location = $location . '()';
429 echo "<div class=msg_error>An error has occured in [${location}]. ";
431 echo 'No additional information is available.';
433 echo "Additional information:<br><p>\n<pre>\n${info}\n</pre></p>";
434 echo "Go back or try starting from <a href='".makeHref()."'>index page</a>.<br></div>\n";
437 // This function assures that specified argument was passed
438 // and is a number greater than zero.
439 function assertUIntArg ($argname, $caller = 'N/A', $allow_zero = FALSE)
441 if (!isset ($_REQUEST[$argname]))
443 showError ("Parameter '${argname}' is missing (calling function is [${caller}]).", __FUNCTION__
);
446 if (!is_numeric ($_REQUEST[$argname]))
448 showError ("Parameter '${argname}' is not a number (calling function is [${caller}]).", __FUNCTION__
);
451 if ($_REQUEST[$argname] < 0)
453 showError ("Parameter '${argname}' is less than zero (calling function is [${caller}]).", __FUNCTION__
);
456 if (!$allow_zero and $_REQUEST[$argname] == 0)
458 showError ("Parameter '${argname}' is equal to zero (calling function is [${caller}]).", __FUNCTION__
);
463 // This function assures that specified argument was passed
464 // and is a non-empty string.
465 function assertStringArg ($argname, $caller = 'N/A', $ok_if_empty = FALSE)
467 if (!isset ($_REQUEST[$argname]))
469 showError ("Parameter '${argname}' is missing (calling function is [${caller}]).", __FUNCTION__
);
472 if (!is_string ($_REQUEST[$argname]))
474 showError ("Parameter '${argname}' is not a string (calling function is [${caller}]).", __FUNCTION__
);
477 if (!$ok_if_empty and empty ($_REQUEST[$argname]))
479 showError ("Parameter '${argname}' is an empty string (calling function is [${caller}]).", __FUNCTION__
);
484 function assertBoolArg ($argname, $caller = 'N/A', $ok_if_empty = FALSE)
486 if (!isset ($_REQUEST[$argname]))
488 showError ("Parameter '${argname}' is missing (calling function is [${caller}]).", __FUNCTION__
);
491 if (!is_string ($_REQUEST[$argname]) or $_REQUEST[$argname] != 'on')
493 showError ("Parameter '${argname}' is not a string (calling function is [${caller}]).", __FUNCTION__
);
496 if (!$ok_if_empty and empty ($_REQUEST[$argname]))
498 showError ("Parameter '${argname}' is an empty string (calling function is [${caller}]).", __FUNCTION__
);
503 function assertIPv4Arg ($argname, $caller = 'N/A', $ok_if_empty = FALSE)
505 assertStringArg ($argname, $caller, $ok_if_empty);
506 if (!empty ($_REQUEST[$argname]) and long2ip (ip2long ($_REQUEST[$argname])) !== $_REQUEST[$argname])
508 showError ("IPv4 address validation failed for value '" . $_REQUEST[$argname] . "' (calling function is [${caller}]).", __FUNCTION__
);
513 // This function renders rack as HTML table.
514 function renderRack ($rack_id = 0, $hl_obj_id = 0)
518 showError ('Invalid rack_id', __FUNCTION__
);
521 if (($rackData = getRackData ($rack_id)) == NULL)
523 showError ('getRackData() failed', __FUNCTION__
);
526 markAllSpans ($rackData);
528 highlightObject ($rackData, $hl_obj_id);
529 markupObjectProblems ($rackData);
530 $prev_id = getPrevIDforRack ($rackData['row_id'], $rack_id);
531 $next_id = getNextIDforRack ($rackData['row_id'], $rack_id);
532 echo "<center><table border=0><tr valign=middle>";
533 echo "<td><h2><a href='".makeHref(array('page'=>'row', 'row_id'=>$rackData['row_id']))."'>${rackData['row_name']}</a> :</h2></td>";
534 // FIXME: use 'bypass'?
535 if ($prev_id != NULL)
537 echo "<td><a href='".makeHref(array('page'=>'rack', 'rack_id'=>$prev_id))."'>";
538 printImageHREF ('prev', 'previous rack');
541 echo "<td><h2><a href='".makeHref(array('page'=>'rack', 'rack_id'=>$rackData['id']))."'>${rackData['name']}</a></h2></td>";
542 if ($next_id != NULL)
544 echo "<td><a href='".makeHref(array('page'=>'rack', 'rack_id'=>$next_id))."'>";
545 printImageHREF ('next', 'next rack');
548 echo "</h2></td></tr></table>\n";
549 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
550 echo "<tr><th width='10%'> </th><th width='20%'>Front</th>";
551 echo "<th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
552 for ($i = $rackData['height']; $i > 0; $i--)
554 echo "<tr><th>${i}</th>";
555 for ($locidx = 0; $locidx < 3; $locidx++
)
557 if (isset ($rackData[$i][$locidx]['skipped']))
559 $state = $rackData[$i][$locidx]['state'];
560 echo "<td class=state_${state}";
561 if (isset ($rackData[$i][$locidx]['hl']))
562 echo $rackData[$i][$locidx]['hl'];
563 if (isset ($rackData[$i][$locidx]['colspan']))
564 echo ' colspan=' . $rackData[$i][$locidx]['colspan'];
565 if (isset ($rackData[$i][$locidx]['rowspan']))
566 echo ' rowspan=' . $rackData[$i][$locidx]['rowspan'];
571 $objectData = getObjectInfo ($rackData[$i][$locidx]['object_id']);
572 if (!empty ($objectData['asset_no']))
573 $prefix = "<div title='${objectData['asset_no']}";
575 $prefix = "<div title='no asset tag";
576 // Don't tell about label, if it matches common name.
577 if ($objectData['name'] != $objectData['label'] and !empty ($objectData['label']))
578 $suffix = ", visible label is \"${objectData['label']}\"'>";
581 echo $prefix . $suffix;
582 echo "<a href='".makeHref(array('page'=>'object', 'object_id'=>$objectData['id']))."'>${objectData['dname']}</a></div>";
585 echo '<div title="This rackspace does not exist"> </div>';
588 echo '<div title="Free rackspace"> </div>';
591 echo '<div title="Problematic rackspace, you CAN\'T mount here"> </div>';
594 echo '<div title="No data"> </div>';
601 echo "</table></center>\n";
604 function renderNewRackForm ($row_id)
606 showMessageOrError();
608 startPortlet ('Add one');
609 printOpFormIntro ('addRack', array ('got_data' => 'TRUE'));
610 echo '<table border=0 align=center>';
611 $defh = getConfigVar ('DEFAULT_RACK_HEIGHT');
614 echo "<tr><th class=tdright>Rack name (*):</th><td class=tdleft><input type=text name=rack_name tabindex=1></td>";
615 echo "<td rowspan=4>Assign tags:<br>";
616 renderNewEntityTags();
618 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";
619 echo "<tr><th class=tdright>Comment:</th><td class=tdleft><input type=text name=rack_comment tabindex=3></td></tr>\n";
620 echo "<tr><td class=submit colspan=2>";
621 printImageHREF ('CREATE', 'Add', TRUE);
622 echo "</td></tr></table></form>";
625 startPortlet ('Add many');
626 printOpFormIntro ('addRack', array ('got_mdata' => 'TRUE'));
627 echo '<table border=0 align=center>';
628 $defh = getConfigVar ('DEFAULT_RACK_HEIGHT');
631 echo "<tr><th class=tdright>Height in units (*):</th><td class=tdleft><input type=text name=rack_height2 value='${defh}'></td>";
632 echo "<td rowspan=3 valign=top>Assign tags:<br>";
633 renderNewEntityTags();
635 echo "<tr><th class=tdright>Rack names (*):</th><td class=tdleft><textarea name=rack_names cols=40 rows=25></textarea></td></tr>\n";
636 echo "<tr><td class=submit colspan=2>";
637 printImageHREF ('CREATE', 'Add', TRUE);
638 echo '</form></table>';
642 function renderEditObjectForm ($object_id)
644 showMessageOrError();
647 $object = getObjectInfo ($object_id);
650 showError ('getObjectInfo() failed', __FUNCTION__
);
654 printOpFormIntro ('update');
657 echo '<table border=0 cellspacing=0 cellpadding=3 align=center>';
658 echo "<tr><td> </td><th colspan=2><h2>Attributes</h2></th></tr>";
659 echo "<tr><td> </td><th class=tdright>Type:</th><td class=tdleft>";
660 printSelect (getObjectTypeList(), 'object_type_id', $object['objtype_id']);
663 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";
664 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";
665 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";
666 echo "<tr><td> </td><th class=tdright>Barcode:</th><td class=tdleft><input type=text name=object_barcode value='${object['barcode']}'></td></tr>\n";
667 // optional attributes
668 $values = getAttrValues ($object_id);
669 echo '<input type=hidden name=num_attrs value=' . count($values) . ">\n";
670 if (count($values) > 0)
673 foreach ($values as $record)
675 echo "<input type=hidden name=${i}_attr_id value=${record['id']}>";
677 if (!empty ($record['value']))
679 echo "<a href='".makeHrefProcess(array('op'=>'clearSticker', 'object_id'=>$object_id, 'attr_id'=>$record['id']))."'>";
680 printImageHREF ('clear', 'Clear value');
686 echo "<th class=sticker>${record['name']}:</th><td class=tdleft>";
687 switch ($record['type'])
692 echo "<input type=text name=${i}_value value='${record['value']}'>";
695 $chapter = readChapter ($record['chapter_name']);
696 $chapter[0] = '-- NOT SET --';
697 $chapter = cookOptgroups ($chapter, $object['objtype_id'], $record['key']);
698 printNiftySelect ($chapter, "${i}_value", $record['key']);
705 echo "<tr><td> </td><th class=tdright>Has problems:</th><td class=tdleft><input type=checkbox name=object_has_problems";
706 if ($object['has_problems'] == 'yes')
708 echo "></td></tr>\n";
709 echo "<tr><td> </td><th class=tdright>Actions:</th><td class=tdleft><a href='".
710 makeHrefProcess(array('op'=>'deleteObject', 'page'=>'depot', 'tab'=>'default', 'object_id'=>$object_id)).
711 "' onclick=\"javascript:return confirm('Are you sure you want to delete the object?')\">Delete object</a></td></tr>\n";
712 echo "<tr><td colspan=3><b>Comment:</b><br><textarea name=object_comment rows=10 cols=80>${object['comment']}</textarea></td></tr>";
714 echo "<tr><th class=submit colspan=3>";
715 printImageHREF ('SAVE', 'Save changes', TRUE);
716 echo "</form></th></tr></table>\n";
719 echo '<table border=0 width=100%><tr><td>';
720 startPortlet ('history');
721 renderHistory ($pageno, $object_id);
723 echo '</td></tr></table>';
726 // This is a clone of renderEditObjectForm().
727 function renderEditRackForm ($rack_id)
729 showMessageOrError();
731 $rack = getRackData ($rack_id);
734 showError ('getRackData() failed', __FUNCTION__
);
738 startPortlet ('Rack attributes');
739 printOpFormIntro ('updateRack');
740 echo '<table border=0 align=center>';
741 echo "<tr><th class=tdright>Rack row:</th><td class=tdleft>";
742 printSelect (getRackRows(), 'rack_row_id', $rack['row_id']);
744 echo "<tr><th class=tdright>Name (required):</th><td class=tdleft><input type=text name=rack_name value='${rack['name']}'></td></tr>\n";
745 echo "<tr><th class=tdright>Height (required):</th><td class=tdleft><input type=text name=rack_height value='${rack['height']}'></td></tr>\n";
746 echo "<tr><th class=tdright>Comment:</th><td class=tdleft><input type=text name=rack_comment value='${rack['comment']}'></td></tr>\n";
747 if (count ($rack['mountedObjects']) == 0)
749 echo "<tr><th class=tdright>Actions:</th><td class=tdleft><a href='".
750 makeHrefProcess(array('op'=>'deleteRack', 'rack_id'=>$rack_id)).
751 "' onclick=\"javascript:return confirm('Are you sure you want to delete the rack?')\">Delete rack</a></td></tr>\n";
753 echo "<tr><td class=submit colspan=2>";
754 printImageHREF ('SAVE', 'Save changes', TRUE);
756 echo '</form></table><br>';
759 startPortlet ('History');
760 renderHistory ($pageno, $rack_id);
764 // This is a helper for creators and editors.
765 // Input array keys are OPTION VALUEs and input array values are OPTION text.
766 function printSelect ($optionList, $select_name, $selected_id = NULL, $tabindex = NULL)
768 echo "<select name=${select_name}" . ($tabindex ?
" tabindex=${tabindex}" : '') . '>';
769 foreach ($optionList as $dict_key => $dict_value)
770 echo "<option value='${dict_key}'" . ($dict_key == $selected_id ?
' selected' : '') . ">${dict_value}</option>";
774 // Input is a cooked list of OPTGROUPs, each with own sub-list of OPTIONs in the same
775 // format as printSelect() expects.
776 function printNiftySelect ($groupList, $select_name, $selected_id = NULL, $tabindex = NULL)
778 // special treatment for ungrouped data
779 if (count ($groupList) == 1 and isset ($groupList['other']))
781 printSelect ($groupList['other'], $select_name, $selected_id, $tabindex);
784 echo "<select name=${select_name}" . ($tabindex ?
" tabindex=${tabindex}" : '') . '>';
785 foreach ($groupList as $groupname => $groupdata)
787 echo "<optgroup label='${groupname}'>";
788 foreach ($groupdata as $dict_key => $dict_value)
789 echo "<option value='${dict_key}'" . ($dict_key == $selected_id ?
' selected' : '') . ">${dict_value}</option>";
790 echo "</optgroup>\n";
795 // used by renderGridForm() and renderRackPage()
796 function renderRackInfoPortlet ($rackData)
798 startPortlet ('summary');
799 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
800 echo "<tr><th width='50%' class=tdright>Rack row:</th><td class=tdleft>${rackData['row_name']}</td></tr>\n";
801 echo "<tr><th width='50%' class=tdright>Name:</th><td class=tdleft>${rackData['name']}</td></tr>\n";
802 echo "<tr><th width='50%' class=tdright>Height:</th><td class=tdleft>${rackData['height']}</td></tr>\n";
803 echo "<tr><th width='50%' class=tdright>%% used:</th><td class=tdleft>";
804 renderProgressBar (getRSUforRack ($rackData));
806 echo "<tr><th width='50%' class=tdright>Objects:</th><td class=tdleft>";
807 echo count (stuffInRackspace ($rackData));
809 printTagTRs (makeHref(array('page'=>'rackspace', 'tab'=>'default'))."&");
810 if (!empty ($rackData['comment']))
811 echo "<tr><th width='50%' class=tdright>Comment:</th><td class=tdleft>${rackData['comment']}</td></tr>\n";
816 // This is a universal editor of rack design/waste.
817 // FIXME: switch to using printOpFormIntro()
818 function renderGridForm ($rack_id = 0, $filter, $header, $submit, $state1, $state2)
822 showError ('Invalid rack_id', __FUNCTION__
);
825 if (($rackData = getRackData ($rack_id)) == NULL)
827 showError ('getRackData() failed', __FUNCTION__
);
830 showMessageOrError();
832 markupObjectProblems ($rackData);
834 // Render the result whatever it is.
836 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
837 echo "<tr><td colspan=2 align=center><h1>${rackData['name']}</h1></td></tr>\n";
839 // Left column with information portlet.
840 echo "<tr><td class=pcleft height='1%' width='50%'>";
841 renderRackInfoPortlet ($rackData);
843 echo "<td class=pcright>";
846 startPortlet ($header);
848 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
849 echo "<tr><th width='10%'> </th>";
850 echo "<th width='20%'><a href='javascript:;' onclick=\"toggleColumnOfAtoms('${rack_id}', '0', ${rackData['height']})\">Front</a></th>";
851 echo "<th width='50%'><a href='javascript:;' onclick=\"toggleColumnOfAtoms('${rack_id}', '1', ${rackData['height']})\">Interior</a></th>";
852 echo "<th width='20%'><a href='javascript:;' onclick=\"toggleColumnOfAtoms('${rack_id}', '2', ${rackData['height']})\">Back</a></th></tr>\n";
853 printOpFormIntro ('updateRack');
854 markupAtomGrid ($rackData, $state2);
855 renderAtomGrid ($rackData);
856 echo "</table></center>\n";
857 echo "<br><input type=submit name=do_update value='${submit}'></form><br><br>\n";
859 echo "</td></tr></table>\n";
862 function renderRackDesign ($rack_id)
864 renderGridForm ($rack_id, 'applyRackDesignMask', 'Rack design', 'Set rack design', 'A', 'F');
867 function renderRackProblems ($rack_id = 0)
869 renderGridForm ($rack_id, 'applyRackProblemMask', 'Rack problems', 'Mark unusable atoms', 'F', 'U');
872 function startPortlet ($title = '')
874 echo "<div class=portlet><h2>${title}</h2>";
877 function finishPortlet ()
882 function renderRackObject ($object_id = 0)
884 global $nextorder, $aac;
887 showError ('Invalid object_id', __FUNCTION__
);
890 $info = getObjectInfo ($object_id);
893 showError ('getObjectInfo() failed', __FUNCTION__
);
896 // Main layout starts.
897 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
898 echo "<tr><td colspan=2 align=center><h1>${info['dname']}</h1></td></tr>\n";
899 // left column with uknown number of portlets
900 echo "<tr><td class=pcleft>";
901 startPortlet ('summary');
902 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
903 if (!empty ($info['name']))
904 echo "<tr><th width='50%' class=tdright>Common name:</th><td class=tdleft>${info['name']}</td></tr>\n";
905 elseif (considerConfiguredConstraint ('object', $object_id, 'NAMEWARN_LISTSRC'))
906 echo "<tr><td colspan=2 class=msg_error>Common name is missing.</td></tr>\n";
907 echo "<tr><th width='50%' class=tdright>Object type:</th><td class=tdleft><a href='";
908 echo makeHref (array (
911 'cfe' => '{$typeid_' . $info['objtype_id'] . '}'
913 echo "'>${info['objtype_name']}</a></td></tr>\n";
914 if (!empty ($info['asset_no']))
915 echo "<tr><th width='50%' class=tdright>Asset tag:</th><td class=tdleft>${info['asset_no']}</td></tr>\n";
916 elseif (considerConfiguredConstraint ('object', $object_id, 'ASSETWARN_LISTSRC'))
917 echo "<tr><td colspan=2 class=msg_error>Asset tag is missing.</td></tr>\n";
918 if (!empty ($info['label']))
919 echo "<tr><th width='50%' class=tdright>Visible label:</th><td class=tdleft>${info['label']}</td></tr>\n";
920 if (!empty ($info['barcode']))
921 echo "<tr><th width='50%' class=tdright>Barcode:</th><td class=tdleft>${info['barcode']}</td></tr>\n";
922 if ($info['has_problems'] == 'yes')
923 echo "<tr><td colspan=2 class=msg_error>Has problems</td></tr>\n";
924 foreach (getAttrValues ($object_id, TRUE) as $record)
925 if (!empty ($record['value']))
926 echo "<tr><th width='50%' class=sticker>${record['name']}:</th><td class=sticker>${record['a_value']}</td></tr>\n";
936 'cfe' => '{$typeid_' . $info['objtype_id'] . '}',
940 echo "</table><br>\n";
943 if (!empty ($info['comment']))
945 startPortlet ('Comment');
946 echo '<div class=commentblock>' . string_insert_hrefs ($info['comment']) . '</div>';
950 renderFilesPortlet ('object', $object_id);
952 $ports = getObjectPortsAndLinks ($object_id);
955 startPortlet ('ports and links');
956 usort($ports, 'sortByName');
960 if (isset ($_REQUEST['hl_port_id']))
962 assertUIntArg ('hl_port_id', __FUNCTION__
);
963 $hl_port_id = $_REQUEST['hl_port_id'];
965 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
966 echo "<tr><th>Local name</th><th>Visible label</th><th>Port type</th><th>L2 address</th>";
967 echo "<th>Rem. Object</th><th>Rem. port</th></tr>\n";
968 foreach ($ports as $port)
971 if ($hl_port_id == $port['id'])
972 echo ' class=port_highlight';
973 echo "><td>${port['name']}</td><td>${port['label']}</td><td>${port['type']}</td>";
974 echo "<td>${port['l2address']}</td>";
975 if ($port['remote_object_id'])
977 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>";
978 echo "<td>${port['remote_name']}</td>";
980 elseif (!empty ($port['reservation_comment']))
982 echo "<td><b>Reserved;</b></td>";
983 echo "<td>${port['reservation_comment']}</td>";
986 echo '<td> </td><td> </td>';
989 echo "</table><br>\n";
994 $alloclist = getObjectIPv4Allocations ($object_id);
995 if (count ($alloclist))
997 startPortlet ('IPv4 addresses');
998 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
999 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
1000 echo "<tr><th>OS interface</th><th>IP address</th><th>network</th><th>routed by</th><th>peers</th></tr>\n";
1002 echo "<tr><th>OS interface</th><th>IP address</th><th>peers</th></tr>\n";
1004 if (isset ($_REQUEST['hl_ipv4_addr']))
1006 assertIPv4Arg ('hl_ipv4_addr', __FUNCTION__
);
1007 $hl_ipv4_addr = $_REQUEST['hl_ipv4_addr'];
1009 foreach ($alloclist as $dottedquad => $alloc)
1011 $address_name = niftyString ($alloc['addrinfo']['name']);
1012 $class = $alloc['addrinfo']['class'];
1013 $secondclass = ($hl_ipv4_addr == $dottedquad) ?
'tdleft port_highlight' : 'tdleft';
1014 $netid = getIPv4AddressNetworkId ($dottedquad);
1015 if (NULL !== $netid)
1017 $netinfo = getIPv4NetworkInfo ($netid);
1018 loadIPv4AddrList ($netinfo);
1020 echo "<tr class='${class}' valign=top><td class=tdleft>${alloc['osif']}</td><td class='${secondclass}'>";
1021 if (NULL !== $netid)
1022 echo "<a href='".makeHref(array('page'=>'ipaddress', 'ip'=>$dottedquad, 'hl_object_id'=>$object_id))."'>${dottedquad}</a>";
1025 if (getConfigVar ('EXT_IPV4_VIEW') != 'yes')
1026 echo '<small>/' . (NULL === $netid ?
'??' : $netinfo['mask']) . '</small>';
1027 echo ' ' . $aac[$alloc['type']];
1028 if (!empty ($alloc['addrinfo']['name']))
1029 echo ' (' . niftyString ($alloc['addrinfo']['name']) . ')';
1031 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
1033 if (NULL === $netid)
1034 echo '<td class=sparenetwork>N/A</td><td class=sparenetwork>N/A</td>';
1037 echo "<td class='${secondclass}'>";
1038 renderIPv4NetCell ($netinfo);
1040 // filter out self-allocation
1041 $other_routers = array();
1042 foreach (findRouters ($netinfo['addrlist']) as $router)
1043 if ($router['id'] != $object_id)
1044 $other_routers[] = $router;
1045 if (count ($other_routers))
1046 printRoutersTD ($other_routers);
1048 echo "<td class='${secondclass}'> </td>";
1052 echo "<td class='${secondclass}'>\n";
1054 if ($alloc['addrinfo']['reserved'] == 'yes')
1056 echo $prefix . '<strong>RESERVED</strong>';
1059 foreach ($alloc['addrinfo']['allocs'] as $allocpeer)
1061 if ($allocpeer['object_id'] == $object_id)
1063 echo $prefix . "<a href='".makeHref(array('page'=>'object', 'object_id'=>$allocpeer['object_id']))."'>";
1064 if (!empty ($allocpeer['osif']))
1065 echo $allocpeer['osif'] . '@';
1066 echo $allocpeer['object_name'] . '</a>';
1069 echo "</td></tr>\n";
1071 echo "</table><br>\n";
1075 $forwards = getNATv4ForObject ($object_id);
1076 if (count($forwards['in']) or count($forwards['out']))
1078 startPortlet('NATv4');
1080 if (count($forwards['out']))
1083 echo "<h3>locally performed NAT</h3>";
1085 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
1086 echo "<tr><th>Proto</th><th>Match endpoint</th><th>Translate to</th><th>Target object</th><th>Rule comment</th></tr>\n";
1088 foreach ($forwards['out'] as $pf)
1092 if (isset ($alloclist [$pf['localip']]))
1094 $class = $alloclist [$pf['localip']]['addrinfo']['class'];
1095 $osif = $alloclist [$pf['localip']]['osif'] . ': ';
1097 echo "<tr class='$class'>";
1098 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>";
1099 echo "<td class=tdleft><a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['remoteip']))."'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
1100 $address = getIPv4Address ($pf['remoteip']);
1101 echo "<td class='description'>";
1102 if (count ($address['allocs']))
1103 foreach($address['allocs'] as $bond)
1104 echo "<a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$bond['object_id']))."'>${bond['object_name']}(${bond['name']})</a> ";
1105 elseif (!empty ($pf['remote_addr_name']))
1106 echo '(' . $pf['remote_addr_name'] . ')';
1107 echo "</td><td class='description'>${pf['description']}</td></tr>";
1109 echo "</table><br><br>";
1111 if (count($forwards['in']))
1113 echo "<h3>arriving NAT connections</h3>";
1114 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
1115 echo "<tr><th>Matched endpoint</th><th>Source object</th><th>Translated to</th><th>Rule comment</th></tr>\n";
1116 foreach ($forwards['in'] as $pf)
1119 echo "<td>${pf['proto']}/<a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['localip']))."'>${pf['localip']}</a>:${pf['localport']}</td>";
1120 echo "<td class='description'><a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$pf['object_id']))."'>${pf['object_name']}</a>";
1121 echo "</td><td><a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['remoteip']))."'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
1122 echo "<td class='description'>${pf['description']}</td></tr>";
1124 echo "</table><br><br>";
1129 $pools = getRSPoolsForObject ($object_id);
1133 startPortlet ('Real server pools (' . count ($pools) . ')');
1134 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
1135 echo "<tr><th>VS</th><th>RS pool</th><th>RS</th><th>VS config</th><th>RS config</th></tr>\n";
1136 foreach ($pools as $vs_id => $info)
1138 echo "<tr valign=top class=row_${order}><td class=tdleft>";
1139 renderVSCell ($vs_id);
1140 echo "</td><td class=tdleft>";
1141 renderRSPoolCell ($info['pool_id'], $info['pool_name']);
1142 echo '</td><td class=tdleft>' . $info['rscount'] . '</td>';
1143 echo "<td class=slbconf>${info['vsconfig']}</td>";
1144 echo "<td class=slbconf>${info['rsconfig']}</td>";
1146 $order = $nextorder[$order];
1153 // After left column we have (surprise!) right column with rackspace portlet only.
1154 echo "<td class=pcright>";
1155 // rackspace portlet
1156 startPortlet ('rackspace allocation');
1157 foreach (getResidentRacksData ($object_id, FALSE) as $rack_id)
1158 renderRack ($rack_id, $object_id);
1165 function renderRackMultiSelect ($sname, $racks, $selected)
1167 // Transform the given flat list into a list of groups, each representing a rack row.
1169 foreach ($racks as $rack)
1170 if (!isset ($rdata[$rack['row_name']]))
1171 $rdata[$rack['row_name']] = array ($rack['id'] => $rack['name']);
1173 $rdata[$rack['row_name']][$rack['id']] = $rack['name'];
1174 echo "<select name=${sname} multiple size=" . getConfigVar ('MAXSELSIZE') . " onchange='getElementsByName(\"updateObjectAllocation\")[0].submit()'>\n";
1175 foreach ($rdata as $optgroup => $racklist)
1177 echo "<optgroup label='${optgroup}'>";
1178 foreach ($racklist as $rack_id => $rack_name)
1180 echo "<option value=${rack_id}";
1181 if (!(array_search ($rack_id, $selected) === FALSE))
1183 echo">${rack_name}</option>\n";
1189 function showMessageOrError ()
1191 if (isset ($_SESSION['log']))
1193 printLog ($_SESSION['log']);
1194 unset($_SESSION['log']);
1198 // This function renders a form for port edition.
1199 function renderPortsForObject ($object_id = 0)
1201 function printNewItemTR ()
1203 printOpFormIntro ('addPort');
1205 printImageHREF ('add', 'add a port', TRUE);
1206 echo "</td><td><input type=text size=8 name=port_name tabindex=100></td>\n";
1207 echo "<td><input type=text size=24 name=port_label tabindex=101></td><td>";
1208 printSelect (getPortTypes(), 'port_type_id', getConfigVar ('default_port_type'), 102);
1209 echo "<td><input type=text name=port_l2address tabindex=103></td>\n";
1210 echo "<td colspan=3> </td><td>";
1211 printImageHREF ('add', 'add a port', TRUE, 104);
1212 echo "</td></tr></form>";
1214 if ($object_id <= 0)
1216 showError ('Invalid object_id', __FUNCTION__
);
1219 showMessageOrError();
1220 startPortlet ('Ports and interfaces');
1221 $ports = getObjectPortsAndLinks ($object_id);
1222 usort($ports, 'sortByName');
1223 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
1224 echo "<tr><th> </th><th>Local name</th><th>Visible label</th><th>Port type</th><th>L2 address</th>";
1225 echo "<th>Rem. object</th><th>Rem. port</th><th>(Un)link or (un)reserve</th><th> </th></tr>\n";
1226 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
1228 foreach ($ports as $port)
1230 printOpFormIntro ('editPort', array ('port_id' => $port['id']));
1231 echo "<tr><td><a href='".makeHrefProcess(array('op'=>'delPort', 'port_id'=>$port['id'], 'object_id'=>$object_id, 'port_name'=>$port['name']))."'>";
1232 printImageHREF ('delete', 'Unlink and Delete this port');
1234 echo "<td><input type=text name=name value='${port['name']}' size=8></td>";
1235 echo "<td><input type=text name=label value='${port['label']}' size=24></td>";
1236 if (!$port['remote_object_id'])
1239 printSelect (getPortTypes(), 'port_type_id', $port['type_id']);
1244 echo "<input type=hidden name=port_type_id value='${port['type_id']}'>";
1245 echo "<td class=tdleft>${port['type']}</td>\n";
1247 echo "<td><input type=text name=l2address value='${port['l2address']}'></td>\n";
1248 if ($port['remote_object_id'])
1250 echo "<td><a href='".makeHref(array('page'=>'object', 'object_id'=>$port['remote_object_id']))."'>${port['remote_object_name']}</a></td>";
1251 echo "<td>${port['remote_name']}</td>";
1252 echo "<td><a href='".
1253 makeHrefProcess(array(
1255 'port_id'=>$port['id'],
1256 'object_id'=>$object_id,
1257 'port_name'=>$port['name'],
1258 'remote_port_name'=>$port['remote_name'],
1259 'remote_object_name'=>$port['remote_object_name'])).
1261 printImageHREF ('cut', 'Unlink this port');
1264 elseif (!empty ($port['reservation_comment']))
1266 echo "<td><b>Reserved;</b></td>";
1267 echo "<td><input type=text name=reservation_comment value='${port['reservation_comment']}'></td>";
1268 echo "<td><a href='".
1269 makeHrefProcess(array(
1271 'port_id'=>$port['id'],
1272 'object_id'=>$object_id)).
1274 printImageHREF ('clear', 'Use up this port');
1279 echo "<td> </td><td> </td>";
1281 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\");'>";
1282 printImageHREF ('plug', 'Link this port');
1283 echo "</a> <input type=text name=reservation_comment>";
1287 printImageHREF ('save', 'Save changes', TRUE);
1288 echo "</td></form></tr>\n";
1290 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
1292 echo "</table><br>\n";
1295 startPortlet ('Add/update multiple ports');
1296 printOpFormIntro ('addMultiPorts');
1297 echo 'Format: <select name=format tabindex=201>';
1298 echo '<option value=c3600asy>Cisco 3600 async: sh line | inc TTY</option>';
1299 echo '<option value=fiwg selected>Foundry ServerIron/FastIron WorkGroup/Edge: sh int br</option>';
1300 echo '<option value=fisxii>Foundry FastIron SuperX/II4000: sh int br</option>';
1301 echo '<option value=ssv1>SSV:<interface name> <MAC address></option>';
1303 echo 'Default port type: ';
1304 printSelect (getPortTypes(), 'port_type', getConfigVar ('default_port_type'), 202);
1305 echo "<input type=submit value='Parse output' tabindex=204><br>\n";
1306 echo "<textarea name=input cols=100 rows=50 tabindex=203></textarea><br>\n";
1311 function renderIPv4ForObject ($object_id = 0)
1313 function printNewItemTR ()
1316 printOpFormIntro ('addIPv4Allocation');
1318 printImageHREF ('add', 'allocate', TRUE);
1320 echo "<td class=tdleft><input type='text' size='10' name='bond_name' tabindex=100></td>\n";
1321 echo "<td class=tdleft><input type=text name='ip' tabindex=101></td>\n";
1322 echo "<td colspan=2> </td><td>";
1323 printSelect ($aat, 'bond_type', NULL, 102);
1324 echo "</td><td> </td><td>";
1325 printImageHREF ('add', 'allocate', TRUE, 103);
1326 echo "</td></tr></form>";
1329 if ($object_id <= 0)
1331 showError ('Invalid object_id', __FUNCTION__
);
1334 showMessageOrError();
1335 startPortlet ('Allocations');
1336 $alloclist = getObjectIPv4Allocations ($object_id);
1337 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
1338 echo '<tr><th> </th><th>OS interface</th><th>IP address</th>';
1339 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
1340 echo '<th>network</th><th>routed by</th>';
1341 echo '<th>type</th><th>misc</th><th> </th></tr>';
1343 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
1345 foreach ($alloclist as $dottedquad => $alloc)
1347 $class = $alloc['addrinfo']['class'];
1348 $netid = getIPv4AddressNetworkId ($dottedquad);
1349 if (NULL !== $netid)
1351 $netinfo = getIPv4NetworkInfo ($netid);
1352 loadIPv4AddrList ($netinfo);
1354 printOpFormIntro ('updIPv4Allocation', array ('ip' => $dottedquad));
1355 echo "<tr class='$class' valign=top><td><a href='".makeHrefProcess(array('op'=>'delIPv4Allocation', 'ip'=>$dottedquad, 'object_id'=>$object_id))."'>";
1356 printImageHREF ('delete', 'Delete this IPv4 address');
1358 echo "<td class=tdleft><input type='text' name='bond_name' value='${alloc['osif']}' size=10></td><td class=tdleft>";
1359 if (NULL !== $netid)
1360 echo "<a href='".makeHref(array('page'=>'ipaddress', 'ip'=>$dottedquad))."'>${dottedquad}</a>";
1363 if (getConfigVar ('EXT_IPV4_VIEW') != 'yes')
1364 echo '<small>/' . (NULL === $netid ?
'??' : $netinfo['mask']) . '</small>';
1365 if (!empty ($alloc['addrinfo']['name']))
1366 echo ' (' . niftyString ($alloc['addrinfo']['name']) . ')';
1368 // FIXME: this a copy-and-paste from renderRackObject()
1369 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
1371 if (NULL === $netid)
1372 echo '<td class=sparenetwork>N/A</td><td class=sparenetwork>N/A</td>';
1376 renderIPv4NetCell ($netinfo);
1378 // filter out self-allocation
1379 $other_routers = array();
1380 foreach (findRouters ($netinfo['addrlist']) as $router)
1381 if ($router['id'] != $object_id)
1382 $other_routers[] = $router;
1383 if (count ($other_routers))
1384 printRoutersTD ($other_routers);
1386 echo "<td> </td>";
1390 printSelect ($aat, 'bond_type', $alloc['type']);
1393 if ($alloc['addrinfo']['reserved'] == 'yes')
1395 echo $prefix . '<strong>RESERVED</strong>';
1398 foreach ($alloc['addrinfo']['allocs'] as $allocpeer)
1400 if ($allocpeer['object_id'] == $object_id)
1402 echo $prefix . "<a href='".makeHref(array('page'=>'object', 'object_id'=>$allocpeer['object_id']))."'>";
1403 if (!empty ($allocpeer['osif']))
1404 echo $allocpeer['osif'] . '@';
1405 echo $allocpeer['object_name'] . '</a>';
1409 printImageHREF ('save', 'Save changes', TRUE);
1410 echo "</td></form></tr>\n";
1412 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
1415 echo "</table><br>\n";
1420 // Log structure versions:
1421 // 1: the whole structure is a list of code-message pairs
1422 // 2 and later: there's a "v" field set, which indicates the version
1423 // 2: there's a "m" list set to hold message code and optional arguments
1424 function printLog ($log)
1428 case !isset ($log['v']):
1429 case $log['v'] == 1:
1430 foreach ($log as $key => $record)
1432 echo "<div class=msg_${record['code']}>${record['message']}</div>";
1434 case $log['v'] == 2:
1437 // records 0~99 with success messages
1438 0 => array ('code' => 'success', 'format' => '%s'),
1439 1 => array ('code' => 'success', 'format' => '%u new records done, %u already existed'),
1440 2 => array ('code' => 'success', 'format' => 'NATv4 rule was successfully added.'),
1441 3 => array ('code' => 'success', 'format' => 'NATv4 rule was successfully deleted.'),
1442 4 => array ('code' => 'success', 'format' => 'NATv4 rule was successfully updated'),
1443 5 => array ('code' => 'success', 'format' => 'Port %s was added successfully'),
1444 6 => array ('code' => 'success', 'format' => 'Port %s was updated successfully'),
1445 7 => array ('code' => 'success', 'format' => 'Port %s was deleted successfully'),
1446 8 => array ('code' => 'success', 'format' => 'Port %s successfully linked with port %s at object %s'),
1447 9 => array ('code' => 'success', 'format' => 'Port %s was successfully unlinked from %s@%s'),
1448 10 => array ('code' => 'success', 'format' => 'Added %u ports, updated %u ports, encountered %u errors.'),
1449 11 => array ('code' => 'success', 'format' => 'Reservation removed.'),
1450 12 => array ('code' => 'success', 'format' => 'allocation updated'),
1451 13 => array ('code' => 'success', 'format' => 'allocated'),
1452 14 => array ('code' => 'success', 'format' => 'deallocated'),
1453 15 => array ('code' => 'success', 'format' => 'Reset succeeded.'),
1454 16 => array ('code' => 'success', 'format' => 'Update done'),
1455 17 => array ('code' => 'success', 'format' => 'Update(s) succeeded.'),
1456 18 => array ('code' => 'success', 'format' => 'Load balancer was successfully added'),
1457 19 => array ('code' => 'success', 'format' => 'Load balancer was successfully deleted'),
1458 20 => array ('code' => 'success', 'format' => 'Load balancer info was successfully updated'),
1459 21 => array ('code' => 'success', 'format' => 'Generation complete'),
1460 22 => array ('code' => 'success', 'format' => 'Chained %u tags'),
1461 23 => array ('code' => 'success', 'format' => 'IPv4 prefix successfully added'),
1462 24 => array ('code' => 'success', 'format' => 'IPv4 prefix deleted'),
1463 25 => array ('code' => 'success', 'format' => 'IPv4 prefix updated'),
1464 26 => array ('code' => 'success', 'format' => '%u IP address(es) were successfully updated'),
1465 27 => array ('code' => 'success', 'format' => 'IPv4 address updated'),
1466 28 => array ('code' => 'success', 'format' => 'Virtual service was successfully created'),
1467 29 => array ('code' => 'success', 'format' => 'Virtual service was successfully deleted'),
1468 30 => array ('code' => 'success', 'format' => 'Virtual service was successfully updated'),
1469 31 => array ('code' => 'success', 'format' => 'RS pool was successfully created'),
1470 32 => array ('code' => 'success', 'format' => 'RS pool was successfully deleted'),
1471 33 => array ('code' => 'success', 'format' => 'RS pool was successfully updated'),
1472 34 => array ('code' => 'success', 'format' => 'Real server was successfully added'),
1473 35 => array ('code' => 'success', 'format' => 'Real server was successfully deleted'),
1474 36 => array ('code' => 'success', 'format' => 'Real server was successfully updated'),
1475 37 => array ('code' => 'success', 'format' => 'Successfully added %u real servers'),
1476 38 => array ('code' => 'success', 'format' => '%u real server(s) were successfully (de)activated'),
1477 39 => array ('code' => 'success', 'format' => 'User account %s updated.'),
1478 40 => array ('code' => 'success', 'format' => 'User account %s created.'),
1481 43 => array ('code' => 'success', 'format' => 'Saved successfully.'),
1482 44 => array ('code' => 'success', 'format' => '%s failures and %s successfull changes.'),
1483 45 => array ('code' => 'success', 'format' => "Attribute '%s' created."),
1484 46 => array ('code' => 'success', 'format' => 'Rename successful.'),
1485 47 => array ('code' => 'success', 'format' => 'Attribute was deleted.'),
1486 48 => array ('code' => 'success', 'format' => 'Supplement succeeded.'),
1487 49 => array ('code' => 'success', 'format' => 'Reduction succeeded.'),
1488 50 => array ('code' => 'success', 'format' => 'Reduction succeeded.'),
1489 51 => array ('code' => 'success', 'format' => 'Update succeeded.'),
1490 52 => array ('code' => 'success', 'format' => 'Supplement succeeded.'),
1491 53 => array ('code' => 'success', 'format' => 'Chapter was deleted.'),
1492 54 => array ('code' => 'success', 'format' => 'Chapter was updated.'),
1493 55 => array ('code' => 'success', 'format' => 'Chapter was added.'),
1494 56 => array ('code' => 'success', 'format' => 'Update succeeded.'),
1495 57 => array ('code' => 'success', 'format' => 'Reset complete'),
1496 58 => array ('code' => 'success', 'format' => "Deleted tag '%s'."),
1497 59 => array ('code' => 'success', 'format' => "Created tag '%s'."),
1498 60 => array ('code' => 'success', 'format' => "Updated tag '%s'."),
1499 61 => array ('code' => 'success', 'format' => 'Password changed successfully.'),
1500 62 => array ('code' => 'success', 'format' => 'gw: %s'),
1501 63 => array ('code' => 'success', 'format' => '%u change request(s) have been processed'),
1502 64 => array ('code' => 'success', 'format' => 'Port %s@%s has been assigned to VLAN %u'),
1503 65 => array ('code' => 'success', 'format' => "Added new rack '%s'"),
1504 66 => array ('code' => 'success', 'format' => "File sent Ok via handler '%s'"),
1505 67 => array ('code' => 'success', 'format' => "Tag rolling done, %u objects involved"),
1506 68 => array ('code' => 'success', 'format' => "Updated rack '%s'"),
1507 69 => array ('code' => 'success', 'format' => 'File "%s" was added successfully'),
1508 70 => array ('code' => 'success', 'format' => 'File "%s" was updated successfully'),
1509 71 => array ('code' => 'success', 'format' => 'File "%s" was linked successfully'),
1510 72 => array ('code' => 'success', 'format' => 'File was unlinked successfully'),
1511 73 => array ('code' => 'success', 'format' => 'File "%s" was deleted successfully'),
1512 74 => array ('code' => 'success', 'format' => 'Row "%s" was added successfully'),
1513 75 => array ('code' => 'success', 'format' => 'Row "%s" was updated successfully'),
1514 76 => array ('code' => 'success', 'format' => 'Object "%s" was deleted successfully'),
1515 77 => array ('code' => 'success', 'format' => 'Row "%s" was deleted successfully'),
1516 78 => array ('code' => 'success', 'format' => 'File "%s" saved Ok'),
1517 79 => array ('code' => 'success', 'format' => 'Rack "%s" was deleted successfully'),
1518 80 => array ('code' => 'success', 'format' => "Added new object '%s'"),
1520 // records 100~199 with fatal error messages
1521 100 => array ('code' => 'error', 'format' => '%s'),
1522 101 => array ('code' => 'error', 'format' => 'Port name cannot be empty'),
1523 102 => array ('code' => 'error', 'format' => "Error creating user account '%s'"),
1524 103 => array ('code' => 'error', 'format' => 'User not found!'),
1525 104 => array ('code' => 'error', 'format' => "Error updating user account '%s'"),
1529 108 => array ('code' => 'error', 'format' => '%u failures and %u successfull changes.'),
1530 109 => array ('code' => 'error', 'format' => 'Update failed!'),
1531 110 => array ('code' => 'error', 'format' => 'Supplement failed!'),
1532 111 => array ('code' => 'error', 'format' => 'Reduction failed!'),
1533 112 => array ('code' => 'error', 'format' => 'Error adding chapter.'),
1534 113 => array ('code' => 'error', 'format' => 'Error updating chapter.'),
1535 114 => array ('code' => 'error', 'format' => 'Error deleting chapter.'),
1536 115 => array ('code' => 'error', 'format' => 'Error renaming attribute.'),
1537 116 => array ('code' => 'error', 'format' => 'Error creating attribute.'),
1538 117 => array ('code' => 'error', 'format' => 'Error deleting attribute.'),
1539 118 => array ('code' => 'error', 'format' => 'Supplement failed!'),
1540 119 => array ('code' => 'error', 'format' => 'Reduction failed!'),
1541 120 => array ('code' => 'error', 'format' => 'Reset failed!'),
1542 121 => array ('code' => 'error', 'format' => 'commitUpdateObject() failed'),
1543 122 => array ('code' => 'error', 'format' => 'One or more update(s) failed!'),
1544 123 => array ('code' => 'error', 'format' => 'Cannot process submitted data: unknown format code.'),
1545 124 => array ('code' => 'error', 'format' => 'Error removing reservation!'),
1546 125 => array ('code' => 'error', 'format' => "Update failed with error: '%s'"),
1547 126 => array ('code' => 'error', 'format' => 'addRStoRSPool() failed'),
1548 127 => array ('code' => 'error', 'format' => 'Added %u real servers and encountered %u errors'),
1549 128 => array ('code' => 'error', 'format' => 'commitDeleteRS() failed'),
1550 129 => array ('code' => 'error', 'format' => 'commitDeleteLB() failed'),
1551 130 => array ('code' => 'error', 'format' => 'commitDeleteVS() failed'),
1552 131 => array ('code' => 'error', 'format' => 'invalid format requested'),
1553 132 => array ('code' => 'error', 'format' => 'invalid protocol'),
1554 133 => array ('code' => 'error', 'format' => 'commitUpdateRS() failed'),
1555 134 => array ('code' => 'error', 'format' => 'commitUpdateLB() failed'),
1556 135 => array ('code' => 'error', 'format' => 'commitUpdateVS() failed'),
1557 136 => array ('code' => 'error', 'format' => 'addLBtoRSPool() failed'),
1558 137 => array ('code' => 'error', 'format' => 'addLBtoRSPool() failed'),
1559 138 => array ('code' => 'error', 'format' => 'commitDeleteRSPool() failed'),
1560 139 => array ('code' => 'error', 'format' => 'commitUpdateRSPool() failed'),
1561 140 => array ('code' => 'error', 'format' => 'Encountered %u errors, (de)activated %u real servers'),
1562 141 => array ('code' => 'error', 'format' => 'Encountered %u errors, updated %u IP address(es)'),
1563 142 => array ('code' => 'error', 'format' => 'executeAutoPorts() failed'),
1564 143 => array ('code' => 'error', 'format' => 'Tried chaining %u tags, but experienced %u errors.'),
1565 144 => array ('code' => 'error', 'format' => "Error deleting tag: '%s'"),
1566 145 => array ('code' => 'error', 'format' => "Invalid tag name '%s'"),
1568 147 => array ('code' => 'error', 'format' => "Could not create tag '%s': %s"),
1569 148 => array ('code' => 'error', 'format' => "Could not update tag '%s': %s"),
1570 149 => array ('code' => 'error', 'format' => 'Turing test failed'),
1571 150 => array ('code' => 'error', 'format' => 'Can only change password under DB authentication.'),
1572 151 => array ('code' => 'error', 'format' => 'Old password doesn\'t match.'),
1573 152 => array ('code' => 'error', 'format' => 'New passwords don\'t match.'),
1574 153 => array ('code' => 'error', 'format' => 'Password change failed.'),
1575 154 => array ('code' => 'error', 'format' => "Verification error: %s"),
1576 155 => array ('code' => 'error', 'format' => 'Save failed.'),
1577 156 => array ('code' => 'error', 'format' => 'getSwitchVLANs() failed'),
1578 157 => array ('code' => 'error', 'format' => 'operation not permitted'),
1579 158 => array ('code' => 'error', 'format' => 'Ignoring malformed record #%u in form submit'),
1580 159 => array ('code' => 'error', 'format' => 'Permission denied moving port %s from VLAN%u to VLAN%u'),
1581 160 => array ('code' => 'error', 'format' => 'Invalid arguments'),
1582 161 => array ('code' => 'error', 'format' => 'Endpoint not found. Please either set FQDN attribute or assign an IP address to the object.'),
1583 162 => array ('code' => 'error', 'format' => 'More than one IP address is assigned to this object, please configure FQDN attribute.'),
1584 163 => array ('code' => 'error', 'format' => 'Failed to get any response from queryGateway() or the gateway died'),
1585 164 => array ('code' => 'error', 'format' => 'Gateway failure: %s.'),
1586 165 => array ('code' => 'error', 'format' => 'Gateway failure: malformed reply.'),
1587 166 => array ('code' => 'error', 'format' => 'gw: %s'),
1588 167 => array ('code' => 'error', 'format' => 'Could not find port %s'),
1589 168 => array ('code' => 'error', 'format' => 'Port %s is a trunk'),
1590 169 => array ('code' => 'error', 'format' => 'Failed to configure %s, connector returned code %u'),
1591 170 => array ('code' => 'error', 'format' => 'There is no network for IP address "%s"'),
1592 171 => array ('code' => 'error', 'format' => "Failed creating rack '%s'. Already exists in this row?"),
1593 172 => array ('code' => 'error', 'format' => 'Malformed request'),
1594 173 => array ('code' => 'error', 'format' => "Invalid IPv4 prefix '%s'"),
1595 174 => array ('code' => 'error', 'format' => 'Bad IPv4 address'),
1596 175 => array ('code' => 'error', 'format' => 'Invalid netmask'),
1597 176 => array ('code' => 'error', 'format' => 'This network already exists'),
1598 177 => array ('code' => 'error', 'format' => 'commitUpdateRack() failed'),
1599 178 => array ('code' => 'error', 'format' => 'file not found'),
1600 179 => array ('code' => 'error', 'format' => 'Declining outdated text. Re-edit the file for consistency.'),
1601 180 => array ('code' => 'error', 'format' => 'Error saving file, all changes lost!'),
1602 181 => array ('code' => 'error', 'format' => "file uploads not allowed, change 'file_uploads' parameter in php.ini"),
1603 182 => array ('code' => 'error', 'format' => 'SQL query failed: %s'),
1604 183 => array ('code' => 'error', 'format' => "Tag id '%s' does not exist."),
1605 184 => array ('code' => 'error', 'format' => 'Submitted form is invalid at line %u'),
1606 185 => array ('code' => 'error', 'format' => "Failed to add object '%s'"),
1607 186 => array ('code' => 'error', 'format' => 'Incomplete form has been ignored. Cheers.'),
1608 187 => array ('code' => 'error', 'format' => "Internal error in function '%s'"),
1610 // records 200~299 with warnings
1611 200 => array ('code' => 'warning', 'format' => '%s'),
1612 201 => array ('code' => 'warning', 'format' => 'nothing happened...'),
1613 202 => array ('code' => 'warning', 'format' => 'gw: %s'),
1614 203 => array ('code' => 'warning', 'format' => 'Port %s seems to be the first in VLAN %u at this switch.'),
1615 204 => array ('code' => 'warning', 'format' => 'Check uplink/downlink configuration for proper operation.'),
1616 205 => array ('code' => 'warning', 'format' => '%u change request(s) have been ignored'),
1617 206 => array ('code' => 'warning', 'format' => 'Rack is not empty'),
1618 207 => array ('code' => 'warning', 'format' => 'Ignored empty request'),
1621 // Handle the arguments. Is there any better way to do it?
1622 foreach ($log['m'] as $record)
1624 if (!isset ($record['c']) or !isset ($msginfo[$record['c']]))
1626 echo '<div class=msg_neutral>(this message was lost)</div>';
1629 if (isset ($record['a']))
1630 switch (count ($record['a']))
1635 $msginfo[$record['c']]['format'],
1642 $msginfo[$record['c']]['format'],
1650 $msginfo[$record['c']]['format'],
1660 $msginfo[$record['c']]['format'],
1669 $msgtext = $msginfo[$record['c']]['format'];
1670 echo '<div class=msg_' . $msginfo[$record['c']]['code'] . ">${msgtext}</div>";
1674 echo '<div class=msg_error>' . __FUNCTION__
. ': internal error</div>';
1680 The following conditions must be followed:
1681 1. We can mount onto free atoms only. This means: if any record for an atom
1682 already exists in RackSpace, it can't be used for mounting.
1683 2. We can't unmount from 'W' atoms. Operator should review appropriate comments
1684 and either delete them before unmounting or refuse to unmount the object.
1687 // We extensively use $_REQUEST in the function.
1688 function renderRackSpaceForObject ($object_id = 0)
1690 if ($object_id <= 0)
1692 showError ('Invalid object_id', __FUNCTION__
);
1695 $is_update = isset ($_REQUEST['rackmulti'][0]);
1696 $info = getObjectInfo ($object_id);
1699 showError ('getObjectInfo() failed', __FUNCTION__
);
1702 // Always process occupied racks plus racks chosen by user. First get racks with
1703 // already allocated rackspace...
1704 if (NULL === ($workingRacksData = getResidentRacksData ($object_id)))
1705 die; // some error already shown
1707 // ...and then add those chosen by user (if any).
1708 if (isset($_REQUEST['rackmulti']))
1709 foreach ($_REQUEST['rackmulti'] as $cand_id)
1711 if (!isset ($workingRacksData[$cand_id]))
1713 $rackData = getRackData ($cand_id);
1714 if ($rackData == NULL)
1716 showError ('getRackData() failed', __FUNCTION__
);
1719 $workingRacksData[$cand_id] = $rackData;
1723 printOpFormIntro ('updateObjectAllocation');
1725 // Do it only once...
1726 foreach ($workingRacksData as $rackId => &$rackData)
1728 applyObjectMountMask ($rackData, $object_id);
1729 echo "<input type=\"hidden\" name=\"rackmulti[]\" value=\"$rackId\">";
1731 // Now we workaround an old caveat: http://bugs.php.net/bug.php?id=37410
1734 // This is the time for rendering.
1735 showMessageOrError();
1737 // Main layout starts.
1738 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0><tr>";
1740 // Left portlet with rack list.
1741 echo "<td class=pcleft height='1%'>";
1742 startPortlet ('Racks');
1743 $allRacksData = listCells ('rack');
1744 if (count ($allRacksData) <= getConfigVar ('RACK_PRESELECT_THRESHOLD'))
1746 foreach (array_keys ($allRacksData) as $rack_id)
1748 $rackData = getRackData ($rack_id);
1749 if ($rackData == NULL)
1751 showError ('getRackData() failed', __FUNCTION__
);
1754 $workingRacksData[$rack_id] = $rackData;
1756 foreach ($workingRacksData as &$rackData)
1757 applyObjectMountMask ($rackData, $object_id);
1760 renderRackMultiSelect ('rackmulti[]', $allRacksData, array_keys ($workingRacksData));
1766 // Middle portlet with comment and submit.
1767 echo "<td class=pcleft>";
1768 startPortlet ('Comment');
1769 echo "<textarea name=comment rows=10 cols=40></textarea><br>\n";
1770 echo "<input type=submit value='Save' name=got_atoms>\n";
1776 // Right portlet with rendered racks. If this form submit is not final, we have to
1777 // reflect the former state of the grid in current form.
1778 echo "<td class=pcright rowspan=2 height='1%'>";
1779 startPortlet ('Working copy');
1780 echo '<table border=0 cellspacing=10 align=center><tr>';
1781 foreach ($workingRacksData as $rack_id => $rackData)
1783 // Order is important here: only original allocation is highlighted.
1784 highlightObject ($rackData, $object_id);
1785 markupAtomGrid ($rackData, 'T');
1786 // If we have a form processed, discard user input and show new database
1789 mergeGridFormToRack ($rackData);
1790 echo "<td valign=top>";
1791 echo "<center>\n<h2>${rackData['name']}</h2>\n";
1792 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
1793 echo "<tr><th width='10%'> </th>";
1794 echo "<th width='20%'><a href='javascript:;' onclick=\"toggleColumnOfAtoms('${rack_id}', '0', ${rackData['height']})\">Front</a></th>";
1795 echo "<th width='50%'><a href='javascript:;' onclick=\"toggleColumnOfAtoms('${rack_id}', '1', ${rackData['height']})\">Interior</a></th>";
1796 echo "<th width='20%'><a href='javascript:;' onclick=\"toggleColumnOfAtoms('${rack_id}', '2', ${rackData['height']})\">Back</a></th></tr>\n";
1797 renderAtomGrid ($rackData);
1798 echo "<tr><th width='10%'> </th>";
1799 echo "<th width='20%'><a href='javascript:;' onclick=\"toggleColumnOfAtoms('${rack_id}', '0', ${rackData['height']})\">Front</a></th>";
1800 echo "<th width='50%'><a href='javascript:;' onclick=\"toggleColumnOfAtoms('${rack_id}', '1', ${rackData['height']})\">Interior</a></th>";
1801 echo "<th width='20%'><a href='javascript:;' onclick=\"toggleColumnOfAtoms('${rack_id}', '2', ${rackData['height']})\">Back</a></th></tr>\n";
1802 echo "</table></center>\n";
1805 echo "</tr></table>";
1811 echo "</tr></table>\n";
1814 function renderMolecule ($mdata, $object_id)
1817 $rackpack = array();
1819 foreach ($mdata as $rua)
1821 $rack_id = $rua['rack_id'];
1822 $unit_no = $rua['unit_no'];
1823 $atom = $rua['atom'];
1824 if (!isset ($rackpack[$rack_id]))
1826 $rackData = getRackData ($rack_id);
1827 for ($i = $rackData['height']; $i > 0; $i--)
1828 for ($locidx = 0; $locidx < 3; $locidx++
)
1829 $rackData[$i][$locidx]['state'] = 'F';
1830 $rackpack[$rack_id] = $rackData;
1832 $rackpack[$rack_id][$unit_no][$loclist[$atom]]['state'] = 'T';
1833 $rackpack[$rack_id][$unit_no][$loclist[$atom]]['object_id'] = $object_id;
1835 // now we have some racks to render
1836 foreach ($rackpack as $rackData)
1838 markAllSpans ($rackData);
1839 echo "<table class=molecule cellspacing=0>\n";
1840 echo "<caption>${rackData['name']}</caption>\n";
1841 echo "<tr><th width='10%'> </th><th width='20%'>Front</th><th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
1842 for ($i = $rackData['height']; $i > 0; $i--)
1844 echo "<tr><th>$i</th>";
1845 for ($locidx = 0; $locidx < 3; $locidx++
)
1847 $state = $rackData[$i][$locidx]['state'];
1848 echo "<td class=state_${state}> </td>\n";
1856 function renderEmptyPortsSelect ($port_id, $type_id)
1858 $ports = getEmptyPortsOfType($type_id);
1859 usort($ports, 'sortEmptyPorts');
1860 foreach ($ports as $port)
1862 if ($port_id == $port['Port_id'])
1864 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";
1868 function renderDepot ()
1870 global $pageno, $nextorder;
1871 showMessageOrError();
1872 $cellfilter = getCellFilter();
1873 $objects = filterCellList (listCells ('object'), $cellfilter['expression']);
1875 echo "<table border=0 class=objectview>\n";
1876 echo "<tr><td class=pcleft>";
1878 startPortlet ('Objects (' . count ($objects) . ')');
1879 if ($objects === NULL)
1881 showError ('Fatal error retrieving object list', __FUNCTION__
);
1884 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1885 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>Barcode</th><th>Row/Rack</th></tr>';
1887 foreach ($objects as $obj)
1889 if (isset ($_REQUEST['hl_object_id']) and $_REQUEST['hl_object_id'] == $obj['id'])
1890 $secondclass = 'tdleft port_highlight';
1892 $secondclass = 'tdleft';
1893 $tags = loadEntityTags ('object', $obj['id']);
1894 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>";
1896 echo '<br><small>' . serializeTags ($tags, makeHref(array('page'=>$pageno, 'tab'=>'default')) . '&') . '</small>';
1897 echo "</td><td class='${secondclass}'>${obj['label']}</td>";
1898 echo "<td class='${secondclass}'>${obj['asset_no']}</td>";
1899 echo "<td class='${secondclass}'>${obj['barcode']}</td>";
1900 if ($obj['rack_id'])
1901 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>";
1903 echo "<td class='${secondclass}'>Unmounted</td>";
1905 $order = $nextorder[$order];
1910 echo "</td><td class=pcright width='25%'>";
1912 renderCellFilterPortlet ($cellfilter, 'object');
1913 echo "</td></tr></table>\n";
1916 // History viewer for history-enabled simple dictionaries.
1917 function renderHistory ($object_type, $object_id)
1919 switch ($object_type)
1922 $query = "select ctime, user_name, name, comment from RackRowHistory where id = ${object_id} order by ctime";
1923 $header = '<tr><th>change time</th><th>author</th><th>rack row name</th><th>rack row comment</th></tr>';
1928 "select ctime, user_name, rh.name, rr.name as name, rh.height, rh.comment " .
1929 "from RackHistory as rh left join RackRow as rr on rh.row_id = rr.id " .
1930 "where rh.id = ${object_id} order by ctime";
1931 $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>';
1936 "select ctime, user_name, RackObjectHistory.name as name, label, barcode, asset_no, has_problems, dict_value, comment " .
1937 "from RackObjectHistory inner join Dictionary on objtype_id = dict_key join Chapter on Dictionary.chapter_id = Chapter.id " .
1938 "where Chapter.name = 'RackObjectType' and RackObjectHistory.id=${object_id} order by ctime";
1939 $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>';
1943 showError ("Uknown object type '${object_type}'", __FUNCTION__
);
1947 $result = $dbxlink->query ($query);
1948 if ($result == NULL)
1950 showError ('SQL query failed', __FUNCTION__
);
1953 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1957 while ($row = $result->fetch (PDO
::FETCH_NUM
))
1959 echo "<tr class=row_${order}><td>${row[0]}</td>";
1960 for ($i = 1; $i <= $extra; $i++
)
1961 echo "<td>" . $row[$i] . "</td>";
1963 $order = $nextorder[$order];
1965 echo "</table><br>\n";
1968 function renderRackspaceHistory ()
1970 global $nextorder, $pageno, $tabno;
1972 $history = getRackspaceHistory();
1973 // Show the last operation by default.
1974 if (isset ($_REQUEST['op_id']))
1975 $op_id = $_REQUEST['op_id'];
1976 elseif (isset ($history[0]['mo_id']))
1977 $op_id = $history[0]['mo_id'];
1984 list ($omid, $nmid) = getOperationMolecules ($op_id);
1986 // Main layout starts.
1987 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
1989 // Left top portlet with old allocation.
1990 echo "<tr><td class=pcleft>";
1991 startPortlet ('Old allocation');
1994 $oldMolecule = getMolecule ($omid);
1995 renderMolecule ($oldMolecule, $object_id);
2001 echo '</td><td class=pcright>';
2003 // Right top portlet with new allocation
2004 startPortlet ('New allocation');
2007 $newMolecule = getMolecule ($nmid);
2008 renderMolecule ($newMolecule, $object_id);
2014 echo '</td></tr><tr><td colspan=2>';
2016 // Bottom portlet with list
2018 startPortlet ('Rackspace allocation history');
2019 echo "<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>\n";
2020 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";
2021 foreach ($history as $row)
2023 if ($row['mo_id'] == $op_id)
2026 $class = "row_${order}";
2027 echo "<tr class=${class}><td><a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno, 'op_id'=>$row['mo_id']))."'>${row['ctime']}</a></td>";
2028 echo "<td>${row['user_name']}</td>";
2029 echo "<td>${row['ro_id']}</td><td>${row['objtype_name']}</td><td>${row['name']}</td><td>${row['comment']}</td>\n";
2031 $order = $nextorder[$order];
2036 echo '</td></tr></table>';
2039 function renderIPv4SpaceRecords ($tree, &$tagcache, $baseurl, $target = 0, $level = 1)
2041 $self = __FUNCTION__
;
2042 foreach ($tree as $item)
2044 $total = $item['addrt'];
2045 if (getConfigVar ('IPV4_TREE_SHOW_USAGE') == 'yes')
2047 loadIPv4AddrList ($item); // necessary to compute router list and address counter
2048 $used = $item['addrc'];
2052 $item['addrlist'] = array();
2055 if (isset ($item['id']))
2057 if ($item['symbol'] == 'node-collapsed')
2058 $expandurl = "${baseurl}&eid=" . $item['id'] . "#netid" . $item['id'];
2059 elseif ($item['symbol'] == 'node-expanded')
2060 $expandurl = $baseurl . ($item['parent_id'] ?
"&eid=${item['parent_id']}#netid${item['parent_id']}" : '');
2063 echo "<tr valign=top>";
2064 printIPv4NetInfoTDs ($item, 'tdleft', $level, $item['symbol'], $expandurl);
2065 echo "<td class=tdcenter>";
2066 if ($target == $item['id'])
2067 echo "<a name=netid${target}></a>";
2068 if (getConfigVar ('IPV4_TREE_SHOW_USAGE') == 'yes')
2070 renderProgressBar ($total ?
$used/$total : 0);
2071 echo "<br><small>${used}/${total}</small>";
2074 echo "<small>${total}</small>";
2076 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
2077 printRoutersTD (findRouters ($item['addrlist']), $tagcache);
2079 if ($item['symbol'] == 'node-expanded' or $item['symbol'] == 'node-expanded-static')
2080 $self ($item['kids'], $tagcache, $baseurl, $target, $level +
1);
2084 echo "<tr valign=top>";
2085 printIPv4NetInfoTDs ($item, 'tdleft sparenetwork', $level, $item['symbol']);
2086 echo "<td class=tdcenter>";
2087 if (getConfigVar ('IPV4_TREE_SHOW_USAGE') == 'yes')
2089 renderProgressBar ($used/$total, 'sparenetwork');
2090 echo "<br><small>${used}/${total}</small>";
2093 echo "<small>${total}</small>";
2094 echo "</td><td> </td></tr>";
2099 function renderIPv4Space ()
2101 global $pageno, $tabno;
2102 $cellfilter = getCellFilter();
2103 $netlist = filterCellList (listCells ('ipv4net'), $cellfilter['expression']);
2104 array_walk ($netlist, 'amplifyCell');
2106 $netcount = count ($netlist);
2107 // expand request can take either natural values or "ALL". Zero means no expanding.
2108 $eid = isset ($_REQUEST['eid']) ?
$_REQUEST['eid'] : 0;
2109 $tree = prepareIPv4Tree ($netlist, $eid);
2111 echo "<table border=0 class=objectview>\n";
2112 echo "<tr><td class=pcleft>";
2113 startPortlet ("networks (${netcount})");
2116 echo 'auto-collapsing at threshold ' . getConfigVar ('TREE_THRESHOLD') . " (<a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno, 'eid'=>'ALL'))."'>expand all</a>)";
2117 elseif ($eid === 'ALL')
2118 echo "expanding all (<a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno))."'>auto-collapse</a>)";
2121 $netinfo = getIPv4NetworkInfo ($eid);
2122 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>)";
2124 echo "</h4><table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
2125 echo "<tr><th>prefix</th><th>name/tags</th><th>capacity</th>";
2126 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
2127 echo "<th>routed by</th>";
2129 $tagcache = array();
2130 $baseurl = makeHref(array('page'=>$pageno, 'tab'=>$tabno)) . $cellfilter['urlextra'];
2131 renderIPv4SpaceRecords ($tree, $tagcache, $baseurl, $eid);
2134 echo '</td><td class=pcright>';
2135 renderCellFilterPortlet ($cellfilter, 'ipv4net');
2136 echo "</td></tr></table>\n";
2139 function renderIPv4SLB ()
2141 global $page, $nextorder;
2143 startPortlet ('SLB configuration');
2144 echo "<table border=0 width='100%'><tr>";
2145 foreach (array ('ipv4vslist', 'ipv4rsplist', 'rservers', 'lbs') as $pno)
2146 echo "<td><h3><a href='".makeHref(array('page'=>$pno))."'>" . $page[$pno]['title'] . "</a></h3></td>";
2147 echo '</tr></table>';
2150 $summary = getSLBSummary();
2151 startPortlet ('SLB tactical overview');
2152 // A single id-keyed array isn't used here to preserve existing
2153 // order of LBs returned by getSLBSummary()
2156 foreach ($summary as $vipdata)
2157 foreach (array_keys ($vipdata['lblist']) as $lb_object_id)
2158 if (!in_array ($lb_object_id, $lblist))
2160 $oi = getObjectInfo ($lb_object_id);
2161 $lbdname[$lb_object_id] = $oi['dname'];
2162 $lblist[] = $lb_object_id;
2164 if (!count ($summary))
2165 echo 'none configured';
2169 echo "<table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
2170 echo "<tr valign=top><td> </td>";
2171 foreach ($lblist as $lb_object_id)
2173 #echo "<th><a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$lb_object_id))."'>" . $lbdname[$lb_object_id] . "</a></th>";
2175 renderLBCell ($lb_object_id);
2179 foreach ($summary as $vsid => $vsdata)
2181 echo "<tr class=row_${order}><td class=tdleft>";
2182 renderVSCell ($vsid);
2184 foreach ($lblist as $lb_object_id)
2186 echo '<td class=tdleft>';
2187 if (!isset ($vsdata['lblist'][$lb_object_id]))
2191 echo $vsdata['lblist'][$lb_object_id]['size'];
2192 // echo " (<a href='".makeHref(array('page'=>'ipv4rspool', 'pool_id'=>$vsdata['lblist'][$lb_object_id]['id'])). "'>";
2193 // echo $vsdata['lblist'][$lb_object_id]['name'] . '</a>)';
2198 $order = $nextorder[$order];
2205 function renderIPv4SpaceEditor ()
2207 showMessageOrError();
2211 <script type
="text/javascript">
2213 document
.add_new_range
.range
.setAttribute('match', "^\\d\\d?\\d?\\.\\d\\d?\\d?\\.\\d\\d?\\d?\\.\\d\\d?\\d?\\/\\d\\d?$");
2221 startPortlet ("Add new");
2222 echo '<table border=0 cellpadding=10 align=center>';
2223 // This form requires a name, so JavaScript validator can find it.
2224 // No printOpFormIntro() hence
2225 echo "<form method=post name='add_new_range' action='".makeHrefProcess()."'>\n";
2226 echo "<input type=hidden name=op value=addIPv4Prefix>\n";
2228 echo '<tr><td rowspan=4><h3>assign tags</h3>';
2229 renderNewEntityTags();
2232 echo "<th class=tdright>prefix</th><td class=tdleft><input type=text name='range' size=18 class='live-validate' tabindex=1></td>";
2233 echo "<tr><th class=tdright>name</th><td class=tdleft><input type=text name='name' size='20' tabindex=2></td></tr>";
2234 echo "<tr><th class=tdright>connected network</th><td class=tdleft><input type=checkbox name='is_bcast' tabindex=3></td></tr>";
2235 echo "<tr><td colspan=2>";
2236 printImageHREF ('CREATE', 'Add a new network', TRUE, 4);
2238 echo "</form></table><br><br>\n";
2241 $addrspaceList = listCells ('ipv4net');
2242 array_walk ($addrspaceList, 'amplifyCell');
2243 if (count ($addrspaceList))
2245 startPortlet ('Manage existing (' . count ($addrspaceList) . ')');
2246 echo "<table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
2247 echo "<tr><th> </th><th>prefix</th><th>name</th><th> </th></tr>";
2248 foreach ($addrspaceList as $netinfo)
2250 echo "<form method=post action='".makeHrefProcess(array('op'=>'updIPv4Prefix', 'id'=>$netinfo['id']))."'>";
2251 echo "<tr valign=top><td>";
2252 if (getConfigVar ('IPV4_JAYWALK') == 'yes')
2254 echo "<a href='".makeHrefProcess(array('op'=>'delIPv4Prefix', 'id'=>$netinfo['id']))."'>";
2255 printImageHREF ('destroy', 'Delete this prefix');
2258 else // only render clickable image for empty networks
2260 $netdata = getIPv4NetworkInfo ($netinfo['id']);
2261 loadIPv4AddrList ($netdata);
2262 if (count ($netdata['addrlist']))
2263 printImageHREF ('nodestroy', 'There are ' . count ($netdata['addrlist']) . ' allocations inside');
2266 echo "<a href='".makeHrefProcess(array('op'=>'delIPv4Prefix', 'id'=>$netinfo['id']))."'>";
2267 printImageHREF ('destroy', 'Delete this prefix');
2272 echo "</td>\n<td class=tdleft>${netinfo['ip']}/${netinfo['mask']}</td>";
2273 echo "<td><input type=text name=name size=40 value='${netinfo['name']}'>";
2275 printImageHREF ('save', 'Save changes', TRUE);
2276 echo "</td></tr></form>\n";
2283 function renderIPv4Network ($id)
2285 global $pageno, $tabno, $aac2;
2286 $netmaskbylen = array
2288 32 => '255.255.255.255',
2289 31 => '255.255.255.254',
2290 30 => '255.255.255.252',
2291 29 => '255.255.255.248',
2292 28 => '255.255.255.240',
2293 27 => '255.255.255.224',
2294 26 => '255.255.255.192',
2295 25 => '255.255.255.128',
2296 24 => '255.255.255.0',
2297 23 => '255.255.254.0',
2298 22 => '255.255.252.0',
2299 21 => '255.255.248.0',
2300 20 => '255.255.240.0',
2301 19 => '255.255.224.0',
2302 18 => '255.255.192.0',
2303 17 => '255.255.128.0',
2304 16 => '255.255.0.0',
2305 15 => '255.254.0.0',
2306 14 => '255.252.0.0',
2307 13 => '255.248.0.0',
2308 12 => '255.240.0.0',
2309 11 => '255.224.0.0',
2310 10 => '255.192.0.0',
2321 $wildcardbylen = array
2338 17 => '0.0.127.255',
2340 15 => '0.1.255.255',
2341 14 => '0.3.255.255',
2342 13 => '0.7.255.255',
2343 12 => '0.15.255.255',
2344 11 => '0.31.255.255',
2345 10 => '0.63.255.255',
2346 9 => '0.127.255.255',
2347 8 => '0.255.255.255',
2348 7 => '1.255.255.255',
2349 6 => '3.255.255.255',
2350 5 => '7.255.255.255',
2351 4 => '15.255.255.255',
2352 3 => '31.255.255.255',
2353 2 => '63.255.255.255',
2354 1 => '127.255.255.255'
2356 $maxperpage = getConfigVar ('IPV4_ADDRS_PER_PAGE');
2357 if (isset($_REQUEST['pg']))
2358 $page = $_REQUEST['pg'];
2362 $range = getIPv4NetworkInfo ($id);
2363 loadIPv4AddrList ($range);
2364 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
2365 echo "<tr><td colspan=2 align=center><h1>${range['ip']}/${range['mask']}</h1><h2>${range['name']}</h2></td></tr>\n";
2367 echo "<tr><td class=pcleft width='50%'>";
2368 startPortlet ('summary');
2369 $total = ($range['ip_bin'] |
$range['mask_bin_inv']) - ($range['ip_bin'] & $range['mask_bin']) +
1;
2370 $used = count ($range['addrlist']);
2371 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
2373 echo "<tr><th width='50%' class=tdright>%% used:</th><td class=tdleft>";
2374 renderProgressBar ($used/$total);
2375 echo " ${used}/${total}</td></tr>\n";
2377 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
2379 // Build a backtrace from all parent networks.
2380 $clen = $range['mask'];
2381 $backtrace = array();
2382 while (NULL !== ($upperid = getIPv4AddressNetworkId ($range['ip'], $clen)))
2384 $upperinfo = getIPv4NetworkInfo ($upperid);
2385 $clen = $upperinfo['mask'];
2386 $backtrace[] = $upperid;
2388 $arrows = count ($backtrace);
2389 foreach (array_reverse ($backtrace) as $ancestorid)
2391 $ainfo = getIPv4NetworkInfo ($ancestorid);
2392 echo "<tr><th width='50%' class=tdright>";
2393 for ($i = 0; $i < $arrows; $i++
)
2396 echo "</th><td class=tdleft>";
2397 renderIPv4NetCell ($ainfo);
2400 echo "<tr><th width='50%' class=tdright>→</th>";
2401 echo "<td class=tdleft>";
2402 renderIPv4NetCell ($range);
2404 // FIXME: get and display nested networks
2405 // $theitem = pickLeaf ($ipv4tree, $id);
2408 echo "<tr><th width='50%' class=tdright>Netmask:</th><td class=tdleft>";
2409 echo $netmaskbylen[$range['mask']];
2410 echo "</td></tr>\n";
2412 echo "<tr><th width='50%' class=tdright>Netmask:</th><td class=tdleft>";
2413 printf ('0x%08X', binMaskFromDec ($range['mask']));
2414 echo "</td></tr>\n";
2416 echo "<tr><th width='50%' class=tdright>Wildcard bits:</th><td class=tdleft>";
2417 echo $wildcardbylen[$range['mask']];
2418 echo "</td></tr>\n";
2420 $routers = findRouters ($range['addrlist']);
2421 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes' and count ($routers))
2423 echo "<tr><th width='50%' class=tdright>Routed by:</th>";
2424 printRoutersTD ($routers);
2428 printTagTRs (makeHref(array('page'=>'ipv4space', 'tab'=>'default'))."&");
2429 echo "</table><br>\n";
2432 renderFilesPortlet ('ipv4net', $id);
2435 echo "<td class=pcright>";
2436 startPortlet ('details');
2437 $startip = $range['ip_bin'] & $range['mask_bin'];
2438 $endip = $range['ip_bin'] |
$range['mask_bin_inv'];
2439 $realstartip = $startip;
2440 $realendip = $endip;
2442 if($endip - $startip > $maxperpage)
2444 $numpages = ($endip - $startip)/$maxperpage;
2445 $startip = $startip +
$page * $maxperpage;
2446 $endip = $startip +
$maxperpage-1;
2450 echo '<h3>' . long2ip ($startip) . ' ~ ' . long2ip ($endip) . '</h3>';
2451 for ($i=0; $i<$numpages; $i++
)
2456 echo "<a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno, 'id'=>$id, 'pg'=>$i))."'>$i</a> ";
2460 echo "<table class='widetable' border=0 cellspacing=0 cellpadding=5 align='center' width='100%'>\n";
2461 echo "<tr><th>Address</th><th>Name</th><th>Allocation</th></tr>\n";
2464 for ($ip = $startip; $ip <= $endip; $ip++
) :
2465 if (isset ($_REQUEST['hl_ipv4_addr']) and ip2long ($_REQUEST['hl_ipv4_addr']) == $ip)
2466 $secondstyle = 'tdleft port_highlight';
2468 $secondstyle = 'tdleft';
2469 if (!isset ($range['addrlist'][$ip]))
2471 echo "<tr><td class=tdleft><a href='".makeHref(array('page'=>'ipaddress', 'ip'=>ip_long2quad($ip)))."'>" . ip_long2quad($ip);
2472 echo "</a></td><td class='${secondstyle}'> </td><td class='${secondstyle}'> </td></tr>\n";
2475 $addr = $range['addrlist'][$ip];
2476 echo "<tr class='${addr['class']}'>";
2478 echo "<td class=tdleft><a href='".makeHref(array('page'=>'ipaddress', 'ip'=>$addr['ip']))."'>${addr['ip']}</a></td>";
2479 echo "<td class='${secondstyle}'>${addr['name']}</td><td class='${secondstyle}'>";
2482 if ( $addr['reserved'] == 'yes')
2484 echo "<strong>RESERVED</strong> ";
2487 foreach ($range['addrlist'][$ip]['allocs'] as $ref)
2489 echo $delim . $aac2[$ref['type']];
2490 echo "<a href='".makeHref(array('page'=>'object', 'object_id'=>$ref['object_id'], 'hl_ipv4_addr'=>$addr['ip']))."'>";
2491 echo $ref['name'] . (empty ($ref['name']) ?
'' : '@');
2492 echo "${ref['object_name']}</a>";
2500 foreach ($range['addrlist'][$ip]['lblist'] as $ref)
2504 echo "${delim}<a href='".makeHref(array('page'=>'object', 'object_id'=>$ref['object_id']))."'>";
2505 echo "${ref['object_name']}</a>:<a href='".makeHref(array('page'=>'ipv4vs', 'vs_id'=>$ref['vs_id']))."'>";
2506 echo "${ref['vport']}/${ref['proto']}</a>→";
2514 foreach ($range['addrlist'][$ip]['rslist'] as $ref)
2518 echo "${delim}→${ref['rsport']}@<a href='".makeHref(array('page'=>'ipv4rspool', 'pool_id'=>$ref['rspool_id']))."'>";
2519 echo "${ref['rspool_name']}</a>";
2522 echo "</td></tr>\n";
2528 echo "</td></tr></table>\n";
2531 function renderIPv4NetworkProperties ($id)
2533 showMessageOrError();
2534 $netdata = getIPv4NetworkInfo ($id);
2535 echo "<center><h1>${netdata['ip']}/${netdata['mask']}</h1></center>\n";
2536 echo "<table border=0 cellpadding=10 cellpadding=1 align='center'>\n";
2537 printOpFormIntro ('editRange');
2538 echo "<tr><td class='tdright'>Name:</td><td class='tdleft'><input type=text name=name size=20 value='${netdata['name']}'></tr>";
2539 echo "<tr><td colspan=2 class=tdcenter>";
2540 printImageHREF ('SAVE', 'Save changes', TRUE);
2541 echo "</td></form></tr></table>\n";
2544 function renderIPv4Address ($dottedquad)
2547 $address = getIPv4Address ($dottedquad);
2548 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
2549 echo "<tr><td colspan=2 align=center><h1>${dottedquad}</h1></td></tr>\n";
2550 if (!empty ($address['name']))
2551 echo "<tr><td colspan=2 align=center><h2>${address['name']}</h2></td></tr>\n";
2553 echo "<tr><td class=pcleft>";
2554 startPortlet ('summary');
2555 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
2556 echo "<tr><th width='50%' class=tdright>Allocations:</th><td class=tdleft>" . count ($address['allocs']) . "</td></tr>\n";
2557 echo "<tr><th width='50%' class=tdright>Originated NAT connections:</th><td class=tdleft>" . count ($address['outpf']) . "</td></tr>\n";
2558 echo "<tr><th width='50%' class=tdright>Arriving NAT connections:</th><td class=tdleft>" . count ($address['inpf']) . "</td></tr>\n";
2559 echo "<tr><th width='50%' class=tdright>SLB virtual services:</th><td class=tdleft>" . count ($address['lblist']) . "</td></tr>\n";
2560 echo "<tr><th width='50%' class=tdright>SLB real servers:</th><td class=tdleft>" . count ($address['rslist']) . "</td></tr>\n";
2562 echo "</table><br>\n";
2566 echo "<td class=pcright>";
2568 if (isset ($address['class']))
2570 startPortlet ('allocations');
2571 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
2572 echo "<tr><th>object</th><th>OS interface</th><th>allocation type</th></tr>\n";
2573 $class = $address['class'];
2574 // render all allocation records for this address the same way
2575 if ($address['reserved'] == 'yes')
2576 echo "<tr class='${class}'><td colspan=2> </td><td class=tdleft><strong>RESERVED</strong></td></tr>";
2577 foreach ($address['allocs'] as $bond)
2579 if (isset ($_REQUEST['hl_object_id']) and $_REQUEST['hl_object_id'] == $bond['object_id'])
2580 $secondclass = 'tdleft port_highlight';
2582 $secondclass = 'tdleft';
2583 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>";
2584 echo $aat[$bond['type']];
2585 echo "</strong></td></tr>\n";
2587 echo "</table><br><br>";
2591 // FIXME: The returned list is structured differently, than we expect it to be. One of the sides
2593 if (count ($address['lblist']))
2595 startPortlet ('Virtual services (' . count ($address['lblist']) . ')');
2596 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
2597 echo "<tr><th>VS</th><th>name</th></tr>\n";
2598 foreach ($address['lblist'] as $vsinfo)
2600 echo "<tr><td class=tdleft><a href='".makeHref(array('page'=>'ipv4vs', 'vs_id'=>$vsinfo['vs_id']))."'>";
2601 echo buildVServiceName ($vsinfo) . "</a></td><td class=tdleft>";
2602 echo $vsinfo['name'] . "</td></tr>\n";
2604 echo "</table><br><br>";
2608 if (count ($address['rslist']))
2610 startPortlet ('Real servers (' . count ($address['rslist']) . ')');
2611 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
2612 echo "<tr><th> </th><th>port</th><th>RS pool</th></tr>\n";
2613 foreach ($address['rslist'] as $rsinfo)
2616 if ($rsinfo['inservice'] == 'yes')
2617 printImageHREF ('inservice', 'in service');
2619 printImageHREF ('notinservice', 'NOT in service');
2620 echo "</td><td class=tdleft>${rsinfo['rsport']}</td><td class=tdleft><a href='".makeHref(array('page'=>'ipv4rspool', 'pool_id'=>$rsinfo['rspool_id']))."'>";
2621 echo $rsinfo['rspool_name'] . "</a></td></tr>\n";
2623 echo "</table><br><br>";
2627 if (count ($address['outpf']))
2629 startPortlet ('departing NAT rules');
2630 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
2631 echo "<tr><th>proto</th><th>from</th><th>to</th><th>comment</th></tr>\n";
2632 foreach ($address['outpf'] as $rule)
2633 echo "<tr><td>${rule['proto']}</td><td>${rule['localip']}:${rule['localport']}</td><td>${rule['remoteip']}:${rule['remoteport']}</td><td>${rule['description']}</td></tr>";
2638 if (count ($address['inpf']))
2640 startPortlet ('arriving NAT rules');
2641 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
2642 echo "<tr><th>proto</th><th>from</th><th>to</th><th>comment</th></tr>\n";
2643 foreach ($address['inpf'] as $rule)
2644 echo "<tr><td>${rule['proto']}</td><td>${rule['localip']}:${rule['localport']}</td><td>${rule['remoteip']}:${rule['remoteport']}</td><td>${rule['description']}</td></tr>";
2653 function renderIPv4AddressProperties ($dottedquad)
2655 showMessageOrError();
2656 $address = getIPv4Address ($dottedquad);
2657 echo "<center><h1>$dottedquad</h1></center>\n";
2659 startPortlet ('update');
2660 echo "<table border=0 cellpadding=10 cellpadding=1 align='center'>\n";
2661 printOpFormIntro ('editAddress');
2662 echo "<tr><td class='tdright'>Name:</td><td class='tdleft'><input type=text name=name size=20 value='${address['name']}'></tr>";
2663 echo "<td class='tdright'>Reserved:</td><td class='tdleft'><input type=checkbox name=reserved size=20 ";
2664 echo ($address['reserved']=='yes') ?
'checked' : '';
2665 echo "></tr><tr><td class=tdleft>";
2666 printImageHREF ('SAVE', 'Save changes', TRUE);
2667 echo "</td></form><td class=tdright>";
2668 if (empty ($address['name']) and $address['reserved'] == 'no')
2669 printImageHREF ('CLEAR gray');
2672 printOpFormIntro ('editAddress', array ('name' => '', 'reserved' => ''));
2673 printImageHREF ('CLEAR', 'Release', TRUE);
2676 echo "</td></tr></table>\n";
2680 function renderIPv4AddressAllocations ($dottedquad)
2682 showMessageOrError();
2683 function printNewItemTR ()
2686 printOpFormIntro ('addIPv4Allocation');
2688 printImageHREF ('add', 'allocate', TRUE);
2690 printSelect (getNarrowObjectList ('IPV4OBJ_LISTSRC'), 'object_id', NULL, 100);
2691 echo "</td><td><input type=text tabindex=101 name=bond_name size=10></td><td>";
2692 printSelect ($aat, 'bond_type', NULL, 102);
2694 printImageHREF ('add', 'allocate', TRUE, 103);
2695 echo "</td></form></tr>";
2699 $address = getIPv4Address ($dottedquad);
2701 echo "<center><h1>${dottedquad}</h1></center>\n";
2702 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
2703 echo "<tr><th> </th><th>object</th><th>OS interface</th><th>allocation type</th><th> </th></tr>\n";
2705 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
2707 if (isset ($address['class']))
2709 $class = $address['class'];
2710 if ($address['reserved'] == 'yes')
2711 echo "<tr class='${class}'><td colspan=3> </td><td class=tdleft><strong>RESERVED</strong></td><td> </td></tr>";
2712 foreach ($address['allocs'] as $bond)
2714 echo "<tr class='$class'>";
2715 printOpFormIntro ('updIPv4Allocation', array ('object_id' => $bond['object_id']));
2716 echo "<td><a href='".makeHrefProcess(array('op'=>'delIPv4Allocation', 'ip'=>$dottedquad, 'object_id'=>$bond['object_id']))."'>";
2717 printImageHREF ('delete', 'Unallocate address');
2719 echo "<td><a href='".makeHref(array('page'=>'object', 'object_id'=>$bond['object_id'], 'hl_ipv4_addr'=>$dottedquad))."'>${bond['object_name']}</td>";
2720 echo "<td><input type='text' name='bond_name' value='${bond['name']}' size=10></td><td>";
2721 printSelect ($aat, 'bond_type', $bond['type']);
2723 printImageHREF ('save', 'Save changes', TRUE);
2724 echo "</td></form></tr>\n";
2727 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
2729 echo "</table><br><br>";
2732 function renderNATv4ForObject ($object_id = 0)
2734 function printNewItemTR ($alloclist)
2736 printOpFormIntro ('addNATv4Rule');
2737 echo "<tr align='center'><td>";
2738 printImageHREF ('add', 'Add new NAT rule', TRUE);
2740 printSelect (array ('TCP' => 'TCP', 'UDP' => 'UDP'), 'proto');
2741 echo "<select name='localip' tabindex=1>";
2743 foreach ($alloclist as $dottedquad => $alloc)
2745 $name = empty ($alloc['addrinfo']['name']) ?
'' : (' (' . niftyString ($alloc['addrinfo']['name']) . ')');
2746 $osif = empty ($alloc['osif']) ?
'' : ($alloc['osif'] . ': ');
2747 echo "<option value='${dottedquad}'>${osif}${dottedquad}${name}</option>";
2750 echo "</select>:<input type='text' name='localport' size='4' tabindex=2></td>";
2751 echo "<td><input type='text' name='remoteip' id='remoteip' size='10' tabindex=3>";
2752 echo "<a href='javascript:;' onclick='window.open(\"" . makeHrefForHelper ('inet4list');
2753 echo "\", \"findobjectip\", \"height=700, width=400, location=no, menubar=no, resizable=yes, scrollbars=no, status=no, titlebar=no, toolbar=no\");'>";
2754 printImageHREF ('find', 'Find object');
2756 echo ":<input type='text' name='remoteport' size='4' tabindex=4></td><td></td>";
2757 echo "<td colspan=1><input type='text' name='description' size='20' tabindex=5></td><td>";
2758 printImageHREF ('add', 'Add new NAT rule', TRUE, 6);
2759 echo "</td></tr></form>";
2762 $info = getObjectInfo ($object_id);
2763 $forwards = getNATv4ForObject ($object_id);
2764 $alloclist = getObjectIPv4Allocations ($object_id);
2765 showMessageOrError();
2766 echo "<center><h2>locally performed NAT</h2></center>";
2768 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
2769 echo "<tr><th></th><th>Match endpoint</th><th>Translate to</th><th>Target object</th><th>Comment</th><th> </th></tr>\n";
2771 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
2772 printNewItemTR ($alloclist);
2773 foreach ($forwards['out'] as $pf)
2777 if (isset ($alloclist [$pf['localip']]))
2779 $class = $alloclist [$pf['localip']]['addrinfo']['class'];
2780 $osif = $alloclist [$pf['localip']]['osif'] . ': ';
2783 echo "<tr class='$class'>";
2784 echo "<td><a href='".
2785 makeHrefProcess(array(
2786 'op'=>'delNATv4Rule',
2787 'localip'=>$pf['localip'],
2788 'localport'=>$pf['localport'],
2789 'remoteip'=>$pf['remoteip'],
2790 'remoteport'=>$pf['remoteport'],
2791 'proto'=>$pf['proto'],
2792 'object_id'=>$object_id)).
2794 printImageHREF ('delete', 'Delete NAT rule');
2796 echo "<td>${pf['proto']}/${osif}<a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['localip']))."'>${pf['localip']}</a>:${pf['localport']}";
2797 if (!empty ($pf['local_addr_name']))
2798 echo ' (' . $pf['local_addr_name'] . ')';
2800 echo "<td><a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['remoteip']))."'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
2802 $address = getIPv4Address ($pf['remoteip']);
2804 echo "<td class='description'>";
2805 if (count ($address['allocs']))
2806 foreach ($address['allocs'] as $bond)
2807 echo "<a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$bond['object_id']))."'>${bond['object_name']}(${bond['name']})</a> ";
2808 elseif (!empty ($pf['remote_addr_name']))
2809 echo '(' . $pf['remote_addr_name'] . ')';
2815 'localip' => $pf['localip'],
2816 'localport' => $pf['localport'],
2817 'remoteip' => $pf['remoteip'],
2818 'remoteport' => $pf['remoteport'],
2819 'proto' => $pf['proto']
2822 echo "</td><td class='description'>";
2823 echo "<input type='text' name='description' value='${pf['description']}'></td><td>";
2824 printImageHREF ('save', 'Save changes', TRUE);
2825 echo "</td></form></tr>";
2827 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
2828 printNewItemTR ($alloclist);
2830 echo "</table><br><br>";
2832 echo "<center><h2>arriving NAT connections</h2></center>";
2833 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
2834 echo "<tr><th></th><th>Source</th><th>Source objects</th><th>Target</th><th>Description</th></tr>\n";
2836 foreach ($forwards['in'] as $pf)
2838 echo "<tr><td><a href='".
2839 makeHrefProcess(array(
2840 'op'=>'delNATv4Rule',
2841 'localip'=>$pf['localip'],
2842 'localport'=>$pf['localport'],
2843 'remoteip'=>$pf['remoteip'],
2844 'remoteport'=>$pf['remoteport'],
2845 'proto'=>$pf['proto'],
2846 'object_id'=>$pf['object_id']
2849 printImageHREF ('delete', 'Delete NAT rule');
2851 echo "<td>${pf['proto']}/<a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['localip']))."'>${pf['localip']}</a>:${pf['localport']}</td>";
2852 echo "<td class='description'><a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$pf['object_id']))."'>${pf['object_name']}</a>";
2853 echo "</td><td><a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['remoteip']))."'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
2854 echo "<td class='description'>${pf['description']}</td></tr>";
2857 echo "</table><br><br>";
2860 function renderAddMultipleObjectsForm ()
2862 showMessageOrError();
2863 $typelist = getObjectTypeList();
2864 $typelist[0] = 'select type...';
2865 $max = getConfigVar ('MASSCOUNT');
2868 startPortlet ('Distinct types, same tags');
2869 printOpFormIntro ('addObjects');
2870 echo '<table border=0 align=center>';
2871 echo "<tr><th>Object type</th><th>Common name</th><th>Visible label</th>";
2872 echo "<th>Asset tag</th><th>Barcode</th><th>Tags</th></tr>\n";
2873 for ($i = 0; $i < $max; $i++
)
2876 // Don't employ DEFAULT_OBJECT_TYPE to avoid creating ghost records for pre-selected empty rows.
2877 printSelect ($typelist, "${i}_object_type_id", 0, $tabindex);
2879 echo "<td><input type=text size=30 name=${i}_object_name tabindex=${tabindex}></td>";
2880 echo "<td><input type=text size=30 name=${i}_object_label tabindex=${tabindex}></td>";
2881 echo "<td><input type=text size=20 name=${i}_object_asset_no tabindex=${tabindex}></td>";