r2760 - getRackSearchResult(): another variation of a standard helper (cloned from...
[racktables] / inc / interface.php
CommitLineData
b325120a 1<?php
e673ee24
DO
2/*
3*
4* This file contains frontend functions for RackTables.
5*
6*/
7
9c0b0016
DO
8// Interface function's special.
9$nextorder['odd'] = 'even';
10$nextorder['even'] = 'odd';
11
52c836b1
DO
12// address allocation type
13$aat = array
14(
15 'regular' => 'Connected',
16 'virtual' => 'Loopback',
17 'shared' => 'Shared',
18 'router' => 'Router',
19);
beb9e88a 20// address allocation code, IPv4 addresses and objects view
52c836b1
DO
21$aac = array
22(
23 'regular' => '',
24 'virtual' => '<strong>L</strong>',
25 'shared' => '<strong>S</strong>',
26 'router' => '<strong>R</strong>',
27);
beb9e88a
DO
28// address allocation code, IPv4 networks view
29$aac2 = array
30(
31 'regular' => '',
32 'virtual' => '<strong>L:</strong>',
29025f8e 33 'shared' => '<strong>S:</strong>',
beb9e88a
DO
34 'router' => '<strong>R:</strong>',
35);
52c836b1 36
7056988c
DO
37// Let's have it here, so extensions can add their own images.
38$image = array();
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;
e1ae3fb4
AD
51$image['files']['path'] = 'pix/files.png';
52$image['files']['width'] = 218;
53$image['files']['height'] = 200;
7056988c
DO
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;
e1ae3fb4
AD
66$image['download']['path'] = 'pix/download.png';
67$image['download']['width'] = 16;
68$image['download']['height'] = 16;
08cd1902
AD
69$image['DOWNLOAD']['path'] = 'pix/download-big.png';
70$image['DOWNLOAD']['width'] = 32;
71$image['DOWNLOAD']['height'] = 32;
5ccd99a0
DO
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;
7056988c
DO
81$image['add']['path'] = 'pix/tango-list-add.png';
82$image['add']['width'] = 16;
83$image['add']['height'] = 16;
a685a26a
DO
84$image['ADD']['path'] = 'pix/tango-list-add-big.png';
85$image['ADD']['width'] = 32;
86$image['ADD']['height'] = 32;
7056988c
DO
87$image['delete']['path'] = 'pix/tango-list-remove.png';
88$image['delete']['width'] = 16;
89$image['delete']['height'] = 16;
d3c27c5c 90$image['destroy']['path'] = 'pix/tango-user-trash-16x16.png';
1bdc2bfc
DO
91$image['destroy']['width'] = 16;
92$image['destroy']['height'] = 16;
d3c27c5c 93$image['nodestroy']['path'] = 'pix/tango-user-trash-16x16-gray.png';
1bdc2bfc
DO
94$image['nodestroy']['width'] = 16;
95$image['nodestroy']['height'] = 16;
8bc5d1e4
DO
96$image['NODESTROY']['path'] = 'pix/tango-user-trash-32x32-gray.png';
97$image['NODESTROY']['width'] = 32;
98$image['NODESTROY']['height'] = 32;
d3c27c5c 99$image['DESTROY']['path'] = 'pix/tango-user-trash-32x32.png';
97b1f33b
DO
100$image['DESTROY']['width'] = 32;
101$image['DESTROY']['height'] = 32;
7056988c
DO
102$image['nodelete']['path'] = 'pix/tango-list-remove-shadow.png';
103$image['nodelete']['width'] = 16;
104$image['nodelete']['height'] = 16;
7056988c
DO
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;
7056988c
DO
111$image['find']['path'] = 'pix/tango-system-search.png';
112$image['find']['width'] = 16;
113$image['find']['height'] = 16;
7056988c
DO
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;
61a61189
DO
123$image['CLEAR']['path'] = 'pix/tango-edit-clear-big.png';
124$image['CLEAR']['width'] = 32;
125$image['CLEAR']['height'] = 32;
f3d274bf
DO
126$image['CLEAR gray']['path'] = 'pix/tango-edit-clear-gray-32x32.png';
127$image['CLEAR gray']['width'] = 32;
128$image['CLEAR gray']['height'] = 32;
7056988c
DO
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;
d28d7f4d
DO
144$image['apply']['path'] = 'pix/tango-emblem-system.png';
145$image['apply']['width'] = 16;
146$image['apply']['height'] = 16;
737a3f72
DO
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;
fec0c8da
DO
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;
09620506
DO
156$image['dragons']['path'] = 'pix/mitsudragon.png';
157$image['dragons']['width'] = 125;
158$image['dragons']['height'] = 21;
b1a970c7
DO
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;
8b3874a5
DO
168$image['router']['path'] = 'pix/router.png';
169$image['router']['width'] = 32;
170$image['router']['height'] = 32;
0b9c98d7
DO
171$image['ATTACH']['path'] = 'pix/crystal-attach-32x32.png';
172$image['ATTACH']['width'] = 32;
173$image['ATTACH']['height'] = 32;
7a0f5847
DO
174$image['favorite']['path'] = 'pix/tango-emblem-favorite.png';
175$image['favorite']['width'] = 16;
176$image['favorite']['height'] = 16;
4f12d88f
DO
177$image['computer']['path'] = 'pix/tango-computer.png';
178$image['computer']['width'] = 16;
179$image['computer']['height'] = 16;
0b9c98d7
DO
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;
19dac9c3
DO
192$image['USER']['path'] = 'pix/crystal-edit-user-32x32.png';
193$image['USER']['width'] = 32;
194$image['USER']['height'] = 32;
7056988c 195
e5c4506d
DO
196// This may be populated later onsite, report rendering function will use it.
197// See the $systemreport for structure.
198$localreports = array();
9db67d95
DO
199$CodePressMap = array
200(
201 'sql' => 'sql',
202 'php' => 'php',
203 'html' => 'html',
204 'css' => 'css',
205 'js' => 'javascript',
206);
e5c4506d 207
8d4f7d18
DO
208$attrtypes = array
209(
210 'uint' => '[U] unsigned integer',
211 'float' => '[F] floating point',
212 'string' => '[S] string',
213 'dict' => '[D] dictionary record'
214);
215
529eac25
DO
216// Rack thumbnail image width summands: "front", "interior" and "rear" elements w/o surrounding border.
217$rtwidth = array
218(
219 0 => 9,
220 1 => 21,
221 2 => 9
222);
223
e673ee24
DO
224// Main menu.
225function renderIndex ()
226{
e673ee24
DO
227?>
228<table border=0 cellpadding=0 cellspacing=0 width='100%'>
229 <tr>
230 <td>
231 <div style='text-align: center; margin: 10px; '>
232 <table width='100%' cellspacing=0 cellpadding=30 class=mainmenu border=0>
233 <tr>
234 <td>
4fbb5a00 235 <h1><a href='<?php echo makeHref(array('page'=>'rackspace')) ?>'>Rackspace<br>
b325120a 236 <?php printImageHREF ('rackspace'); ?></a></h1>
e673ee24
DO
237 </td>
238 <td>
341fd895 239 <h1><a href='<?php echo makeHref(array('page'=>'depot')) ?>'>Objects<br>
b325120a 240 <?php printImageHREF ('objects'); ?></a></h1>
e673ee24 241 </td>
e673ee24 242 <td>
4fbb5a00 243 <h1><a href='<?php echo makeHref(array('page'=>'ipv4space')) ?>'>IPv4 space<br>
e1ae3fb4 244 <?php printImageHREF ('ipv4space'); ?></a></h1>
e673ee24
DO
245 </td>
246 <td>
4fbb5a00 247 <h1><a href='<?php echo makeHref(array('page'=>'files')) ?>'>Files<br>
e1ae3fb4 248 <?php printImageHREF ('files'); ?></a></h1>
e673ee24 249 </td>
e1ae3fb4 250 </tr>
e1ae3fb4 251 <tr>
ae545907 252 <td>
4fbb5a00 253 <h1><a href='<?php echo makeHref(array('page'=>'config')) ?>'>Configuration<br>
f4d879a9 254 <?php printImageHREF ('config'); ?></a></h1>
ae545907 255 </td>
e1ae3fb4 256 <td>
4fbb5a00 257 <h1><a href='<?php echo makeHref(array('page'=>'reports')) ?>'>Reports<br>
f4d879a9 258 <?php printImageHREF ('reports'); ?></a></h1>
e1ae3fb4
AD
259 </td>
260 <td>
4fbb5a00 261 <h1><a href='<?php echo makeHref(array('page'=>'ipv4slb')) ?>'>IPv4 SLB<br>
f4d879a9 262 <?php printImageHREF ('ipv4slb'); ?></a></h1>
e1ae3fb4 263 </td>
f4d879a9 264 <td>&nbsp;</td>
e673ee24
DO
265 </tr>
266 </table>
267 </div>
268 </td>
269 </tr>
270</table>
b325120a 271<?php
e673ee24
DO
272}
273
274function renderRackspace ()
275{
489a7502 276 echo "<table class=objview border=0 width='100%'><tr><td class=pcleft>";
a8efc03e
DO
277 $cellfilter = getCellFilter();
278 renderCellFilterPortlet ($cellfilter, 'rack');
489a7502
DO
279 echo '</td><td class=pcright>';
280 echo '<table border=0 cellpadding=10 cellpadding=1>';
e673ee24 281 // generate thumb gallery
4fbb5a00 282 global $nextorder;
d5157018 283 $rackwidth = getRackImageWidth();
f5883ec1
DO
284 // Zero value effectively disables the limit.
285 $maxPerRow = getConfigVar ('RACKS_PER_ROW');
e673ee24 286 $order = 'odd';
6c18dd08 287 foreach (getRackRows() as $row_id => $row_name)
e673ee24 288 {
a8efc03e
DO
289 $rackList = filterCellList (listCells ('rack', $row_id), $cellfilter['expression']);
290 if (!count ($rackList) and count ($cellfilter['expression']))
6c18dd08 291 continue;
f5883ec1 292 $rackListIdx = 0;
48325652 293 echo "<tr class=row_${order}><th class=tdleft>";
a8efc03e 294 echo "<a href='".makeHref(array('page'=>'row', 'row_id'=>$row_id))."${cellfilter['urlextra']}'>";
48325652
DO
295 echo "${row_name}</a></th><td><table border=0 cellspacing=5><tr>";
296 if (!count ($rackList))
297 echo "<td>(empty row)</td>";
298 else
299 foreach ($rackList as $rack)
f5883ec1 300 {
48325652
DO
301 if ($rackListIdx > 0 and $maxPerRow > 0 and $rackListIdx % $maxPerRow == 0)
302 {
f5883ec1 303 echo '</tr></table></tr>';
48325652
DO
304 echo "<tr class=row_${order}><th class=tdleft>${row_name} (continued)";
305 echo "</th><td><table border=0 cellspacing=5><tr>";
306 $order = $nextorder[$order];
307 }
308 echo "<td align=center><a href='".makeHref(array('page'=>'rack', 'rack_id'=>$rack['id']))."'>";
309 echo "<img border=0 width=${rackwidth} height=";
310 echo getRackImageHeight ($rack['height']);
311 echo " title='${rack['height']} units'";
312 echo "src='render_image.php?img=minirack&rack_id=${rack['id']}'>";
313 echo "<br>${rack['name']}</a></td>";
314 $rackListIdx++;
f5883ec1 315 }
e673ee24 316 echo "</tr></table></tr>\n";
e673ee24
DO
317 }
318 echo "</table>\n";
489a7502 319 echo "</td></tr></table>\n";
e673ee24
DO
320}
321
345fd640
AD
322function renderRackspaceRowEditor ()
323{
324 function printNewItemTR ()
325 {
326 printOpFormIntro ('addRow');
7be51fea
DO
327 echo "<tr><td>";
328 printImageHREF ('create', 'Add new row', TRUE);
329 echo "</td><td><input type=text name=name tabindex=100></td><td>";
345fd640 330 printImageHREF ('create', 'Add new row', TRUE, 101);
7be51fea 331 echo "</td></tr></form>";
345fd640 332 }
d732e47e 333 startPortlet ('Rows');
345fd640 334 echo "<table border=0 cellspacing=0 cellpadding=5 align=center class=widetable>\n";
7be51fea 335 echo "<tr><th>&nbsp;</th><th>Name</th><th>&nbsp;</th></tr>\n";
345fd640
AD
336 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
337 printNewItemTR();
c40666f5 338 foreach (getRackRows() as $row_id => $row_name)
345fd640 339 {
7be51fea 340 echo "<tr><td>";
a8efc03e 341 if ($rc = count (listCells ('rack', $row_id)))
6c18dd08 342 printImageHREF ('nodestroy', "${rc} rack(s) here");
7be51fea 343 else
5af82683 344 {
c40666f5 345 echo "<a href=\"".makeHrefProcess(array('op'=>'delete', 'row_id'=>$row_id))."\">";
7be51fea 346 printImageHREF ('destroy', 'Delete row');
5af82683
DY
347 echo "</a>";
348 }
c40666f5
DO
349 printOpFormIntro ('updateRow', array ('row_id' => $row_id));
350 echo "</td><td><input type=text name=name value='${row_name}'></td><td>";
7be51fea
DO
351 printImageHREF ('save', 'Save changes', TRUE);
352 echo "</form></td></tr>\n";
345fd640
AD
353 }
354 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
355 printNewItemTR();
356 echo "</table><br>\n";
357 finishPortlet();
358}
359
7e1db771 360function renderRow ($row_id)
e673ee24 361{
e673ee24
DO
362 if (($rowInfo = getRackRowInfo ($row_id)) == NULL)
363 {
39a6338a 364 showError ('getRackRowInfo() failed', __FUNCTION__);
e673ee24
DO
365 return;
366 }
a8efc03e
DO
367 $cellfilter = getCellFilter();
368 $rackList = filterCellList (listCells ('rack', $row_id), $cellfilter['expression']);
e673ee24
DO
369 // Main layout starts.
370 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
371
372 // Left portlet with row information.
373 echo "<tr><td class=pcleft>";
a8ce7234 374 startPortlet ($rowInfo['name']);
e673ee24 375 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
5af82683
DY
376 echo "<tr><th width='50%' class=tdright>Racks:</th><td class=tdleft>${rowInfo['count']}</td></tr>\n";
377 echo "<tr><th width='50%' class=tdright>Units:</th><td class=tdleft>${rowInfo['sum']}</td></tr>\n";
04d619d0 378 echo "<tr><th width='50%' class=tdright>%% used:</th><td class=tdleft>";
114e50af
DO
379 renderProgressBar (getRSUforRackRow ($rackList));
380 echo "</td></tr>\n";
e673ee24
DO
381 echo "</table><br>\n";
382 finishPortlet();
a8efc03e 383 renderCellFilterPortlet ($cellfilter, 'rack', 'row_id', $row_id);
e673ee24 384
48325652 385 echo "</td><td class=pcright>";
e673ee24 386
4fbb5a00 387 global $nextorder;
d5157018 388 $rackwidth = getRackImageWidth() * getConfigVar ('ROW_SCALE');
f5883ec1
DO
389 // Maximum number of racks per row is proportionally less, but at least 1.
390 $maxPerRow = max (floor (getConfigVar ('RACKS_PER_ROW') / getConfigVar ('ROW_SCALE')), 1);
391 $rackListIdx = 0;
e673ee24
DO
392 $order = 'odd';
393 startPortlet ('Racks');
394 echo "<table border=0 cellspacing=5 align='center'><tr>";
64b95774 395 foreach ($rackList as $rack)
e673ee24 396 {
f5883ec1
DO
397 if ($rackListIdx % $maxPerRow == 0)
398 {
399 if ($rackListIdx > 0)
400 echo '</tr>';
401 echo '<tr>';
402 }
4fbb5a00 403 echo "<td align=center class=row_${order}><a href='".makeHref(array('page'=>'rack', 'rack_id'=>$rack['id']))."'>";
d5157018 404 echo "<img border=0 width=${rackwidth} height=" . (getRackImageHeight ($rack['height']) * getConfigVar ('ROW_SCALE'));
e673ee24 405 echo " title='${rack['height']} units'";
d2ec5490 406 echo "src='render_image.php?img=minirack&rack_id=${rack['id']}'>";
e673ee24
DO
407 echo "<br>${rack['name']}</a></td>";
408 $order = $nextorder[$order];
f5883ec1 409 $rackListIdx++;
e673ee24
DO
410 }
411 echo "</tr></table>\n";
412 finishPortlet();
e673ee24
DO
413 echo "</td></tr></table>";
414}
415
04f110a0 416function showError ($info = '', $location = 'N/A')
e673ee24 417{
04f110a0
DO
418 if (preg_match ('/\.php$/', $location))
419 $location = basename ($location);
420 elseif ($location != 'N/A')
421 $location = $location . '()';
422 echo "<div class=msg_error>An error has occured in [${location}]. ";
e673ee24
DO
423 if (empty ($info))
424 echo 'No additional information is available.';
425 else
426 echo "Additional information:<br><p>\n<pre>\n${info}\n</pre></p>";
4fbb5a00 427 echo "Go back or try starting from <a href='".makeHref()."'>index page</a>.<br></div>\n";
e673ee24
DO
428}
429
b6a7d936
DO
430// This function assures that specified argument was passed
431// and is a number greater than zero.
432function assertUIntArg ($argname, $caller = 'N/A', $allow_zero = FALSE)
433{
434 if (!isset ($_REQUEST[$argname]))
435 {
436 showError ("Parameter '${argname}' is missing (calling function is [${caller}]).", __FUNCTION__);
437 die();
438 }
439 if (!is_numeric ($_REQUEST[$argname]))
440 {
441 showError ("Parameter '${argname}' is not a number (calling function is [${caller}]).", __FUNCTION__);
442 die();
443 }
444 if ($_REQUEST[$argname] < 0)
445 {
446 showError ("Parameter '${argname}' is less than zero (calling function is [${caller}]).", __FUNCTION__);
447 die();
448 }
449 if (!$allow_zero and $_REQUEST[$argname] == 0)
450 {
451 showError ("Parameter '${argname}' is equal to zero (calling function is [${caller}]).", __FUNCTION__);
452 die();
453 }
454}
455
456// This function assures that specified argument was passed
457// and is a non-empty string.
458function assertStringArg ($argname, $caller = 'N/A', $ok_if_empty = FALSE)
459{
460 if (!isset ($_REQUEST[$argname]))
461 {
462 showError ("Parameter '${argname}' is missing (calling function is [${caller}]).", __FUNCTION__);
463 die();
464 }
465 if (!is_string ($_REQUEST[$argname]))
466 {
467 showError ("Parameter '${argname}' is not a string (calling function is [${caller}]).", __FUNCTION__);
468 die();
469 }
470 if (!$ok_if_empty and empty ($_REQUEST[$argname]))
471 {
472 showError ("Parameter '${argname}' is an empty string (calling function is [${caller}]).", __FUNCTION__);
473 die();
474 }
475}
476
477function assertBoolArg ($argname, $caller = 'N/A', $ok_if_empty = FALSE)
478{
479 if (!isset ($_REQUEST[$argname]))
480 {
481 showError ("Parameter '${argname}' is missing (calling function is [${caller}]).", __FUNCTION__);
482 die();
483 }
484 if (!is_string ($_REQUEST[$argname]) or $_REQUEST[$argname] != 'on')
485 {
486 showError ("Parameter '${argname}' is not a string (calling function is [${caller}]).", __FUNCTION__);
487 die();
488 }
489 if (!$ok_if_empty and empty ($_REQUEST[$argname]))
490 {
491 showError ("Parameter '${argname}' is an empty string (calling function is [${caller}]).", __FUNCTION__);
492 die();
493 }
494}
495
496function assertIPv4Arg ($argname, $caller = 'N/A', $ok_if_empty = FALSE)
497{
498 assertStringArg ($argname, $caller, $ok_if_empty);
499 if (!empty ($_REQUEST[$argname]) and long2ip (ip2long ($_REQUEST[$argname])) !== $_REQUEST[$argname])
500 {
501 showError ("IPv4 address validation failed for value '" . $_REQUEST[$argname] . "' (calling function is [${caller}]).", __FUNCTION__);
502 die();
503 }
504}
505
e673ee24 506// This function renders rack as HTML table.
7e1db771 507function renderRack ($rack_id, $hl_obj_id = 0)
e673ee24 508{
61a1d996
DO
509 $rackData = spotEntity ('rack', $rack_id);
510 amplifyCell ($rackData);
e673ee24
DO
511 markAllSpans ($rackData);
512 if ($hl_obj_id > 0)
513 highlightObject ($rackData, $hl_obj_id);
514 markupObjectProblems ($rackData);
515 $prev_id = getPrevIDforRack ($rackData['row_id'], $rack_id);
516 $next_id = getNextIDforRack ($rackData['row_id'], $rack_id);
d48d8820 517 echo "<center><table border=0><tr valign=middle>";
4fbb5a00 518 echo "<td><h2><a href='".makeHref(array('page'=>'row', 'row_id'=>$rackData['row_id']))."'>${rackData['row_name']}</a> :</h2></td>";
e673ee24
DO
519 // FIXME: use 'bypass'?
520 if ($prev_id != NULL)
9803c56c 521 {
4fbb5a00 522 echo "<td><a href='".makeHref(array('page'=>'rack', 'rack_id'=>$prev_id))."'>";
9803c56c 523 printImageHREF ('prev', 'previous rack');
d48d8820 524 echo "</a></td>";
9803c56c 525 }
4fbb5a00 526 echo "<td><h2><a href='".makeHref(array('page'=>'rack', 'rack_id'=>$rackData['id']))."'>${rackData['name']}</a></h2></td>";
e673ee24 527 if ($next_id != NULL)
9803c56c 528 {
4fbb5a00 529 echo "<td><a href='".makeHref(array('page'=>'rack', 'rack_id'=>$next_id))."'>";
f444c095 530 printImageHREF ('next', 'next rack');
d48d8820 531 echo "</a></td>";
9803c56c 532 }
d48d8820 533 echo "</h2></td></tr></table>\n";
e673ee24 534 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
d08147d6
DO
535 echo "<tr><th width='10%'>&nbsp;</th><th width='20%'>Front</th>";
536 echo "<th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
e673ee24
DO
537 for ($i = $rackData['height']; $i > 0; $i--)
538 {
d08147d6 539 echo "<tr><th>${i}</th>";
e673ee24
DO
540 for ($locidx = 0; $locidx < 3; $locidx++)
541 {
542 if (isset ($rackData[$i][$locidx]['skipped']))
543 continue;
544 $state = $rackData[$i][$locidx]['state'];
545 echo "<td class=state_${state}";
546 if (isset ($rackData[$i][$locidx]['hl']))
547 echo $rackData[$i][$locidx]['hl'];
548 if (isset ($rackData[$i][$locidx]['colspan']))
549 echo ' colspan=' . $rackData[$i][$locidx]['colspan'];
550 if (isset ($rackData[$i][$locidx]['rowspan']))
551 echo ' rowspan=' . $rackData[$i][$locidx]['rowspan'];
552 echo ">";
553 switch ($state)
554 {
555 case 'T':
556 $objectData = getObjectInfo ($rackData[$i][$locidx]['object_id']);
557 if (!empty ($objectData['asset_no']))
558 $prefix = "<div title='${objectData['asset_no']}";
559 else
560 $prefix = "<div title='no asset tag";
561 // Don't tell about label, if it matches common name.
562 if ($objectData['name'] != $objectData['label'] and !empty ($objectData['label']))
563 $suffix = ", visible label is \"${objectData['label']}\"'>";
564 else
565 $suffix = "'>";
566 echo $prefix . $suffix;
4fbb5a00 567 echo "<a href='".makeHref(array('page'=>'object', 'object_id'=>$objectData['id']))."'>${objectData['dname']}</a></div>";
e673ee24
DO
568 break;
569 case 'A':
570 echo '<div title="This rackspace does not exist">&nbsp;</div>';
571 break;
572 case 'F':
573 echo '<div title="Free rackspace">&nbsp;</div>';
574 break;
575 case 'U':
576 echo '<div title="Problematic rackspace, you CAN\'T mount here">&nbsp;</div>';
577 break;
578 default:
579 echo '<div title="No data">&nbsp;</div>';
580 break;
581 }
582 echo '</td>';
583 }
584 echo "</tr>\n";
585 }
586 echo "</table></center>\n";
587}
588
e673ee24
DO
589function renderNewRackForm ($row_id)
590{
50b4ba85 591 startPortlet ('Add one');
f19c75d6 592 printOpFormIntro ('addRack', array ('got_data' => 'TRUE'));
e673ee24 593 echo '<table border=0 align=center>';
b901bf1f
DO
594 $defh = getConfigVar ('DEFAULT_RACK_HEIGHT');
595 if ($defh == 0)
596 $defh = '';
72d52730
DO
597 echo "<tr><th class=tdright>Rack name (*):</th><td class=tdleft><input type=text name=rack_name tabindex=1></td>";
598 echo "<td rowspan=4>Assign tags:<br>";
25186565 599 renderNewEntityTags();
72d52730 600 echo "</td></tr>\n";
b8094ae4 601 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";
4134b5c0 602 echo "<tr><th class=tdright>Comment:</th><td class=tdleft><input type=text name=rack_comment tabindex=3></td></tr>\n";
f19c75d6
DO
603 echo "<tr><td class=submit colspan=2>";
604 printImageHREF ('CREATE', 'Add', TRUE);
605 echo "</td></tr></table></form>";
406b54bd 606 finishPortlet();
406b54bd 607
50b4ba85 608 startPortlet ('Add many');
f19c75d6 609 printOpFormIntro ('addRack', array ('got_mdata' => 'TRUE'));
50b4ba85
DO
610 echo '<table border=0 align=center>';
611 $defh = getConfigVar ('DEFAULT_RACK_HEIGHT');
612 if ($defh == 0)
613 $defh = '';
72d52730
DO
614 echo "<tr><th class=tdright>Height in units (*):</th><td class=tdleft><input type=text name=rack_height2 value='${defh}'></td>";
615 echo "<td rowspan=3 valign=top>Assign tags:<br>";
25186565 616 renderNewEntityTags();
72d52730 617 echo "</td></tr>\n";
50b4ba85 618 echo "<tr><th class=tdright>Rack names (*):</th><td class=tdleft><textarea name=rack_names cols=40 rows=25></textarea></td></tr>\n";
f19c75d6
DO
619 echo "<tr><td class=submit colspan=2>";
620 printImageHREF ('CREATE', 'Add', TRUE);
e673ee24
DO
621 echo '</form></table>';
622 finishPortlet();
623}
624
625function renderEditObjectForm ($object_id)
626{
e10f583a 627 global $pageno;
e673ee24
DO
628 $object = getObjectInfo ($object_id);
629 if ($object == NULL)
630 {
39a6338a 631 showError ('getObjectInfo() failed', __FUNCTION__);
e673ee24
DO
632 return;
633 }
cdd3efe9 634 startPortlet ();
43fb6eaf 635 printOpFormIntro ('update');
cdd3efe9
AD
636
637 // static attributes
e10f583a
DO
638 echo '<table border=0 cellspacing=0 cellpadding=3 align=center>';
639 echo "<tr><td>&nbsp;</td><th colspan=2><h2>Attributes</h2></th></tr>";
640 echo "<tr><td>&nbsp;</td><th class=tdright>Type:</th><td class=tdleft>";
e673ee24
DO
641 printSelect (getObjectTypeList(), 'object_type_id', $object['objtype_id']);
642 echo "</td></tr>\n";
22bb04da 643 // baseline info
e10f583a
DO
644 echo "<tr><td>&nbsp;</td><th class=tdright>Common name:</th><td class=tdleft><input type=text name=object_name value='${object['name']}'></td></tr>\n";
645 echo "<tr><td>&nbsp;</td><th class=tdright>Visible label:</th><td class=tdleft><input type=text name=object_label value='${object['label']}'></td></tr>\n";
646 echo "<tr><td>&nbsp;</td><th class=tdright>Asset tag:</th><td class=tdleft><input type=text name=object_asset_no value='${object['asset_no']}'></td></tr>\n";
647 echo "<tr><td>&nbsp;</td><th class=tdright>Barcode:</th><td class=tdleft><input type=text name=object_barcode value='${object['barcode']}'></td></tr>\n";
cdd3efe9 648 // optional attributes
e673ee24 649 $values = getAttrValues ($object_id);
0f63538a 650 echo '<input type=hidden name=num_attrs value=' . count($values) . ">\n";
2b98d5a2 651 if (count($values) > 0)
e673ee24 652 {
2b98d5a2
AD
653 $i = 0;
654 foreach ($values as $record)
e673ee24 655 {
2b98d5a2
AD
656 echo "<input type=hidden name=${i}_attr_id value=${record['id']}>";
657 echo '<tr><td>';
658 if (!empty ($record['value']))
659 {
4fbb5a00 660 echo "<a href='".makeHrefProcess(array('op'=>'clearSticker', 'object_id'=>$object_id, 'attr_id'=>$record['id']))."'>";
2b98d5a2
AD
661 printImageHREF ('clear', 'Clear value');
662 echo '</a>';
663 }
664 else
665 echo '&nbsp;';
666 echo '</td>';
e10f583a 667 echo "<th class=sticker>${record['name']}:</th><td class=tdleft>";
2b98d5a2
AD
668 switch ($record['type'])
669 {
670 case 'uint':
671 case 'float':
672 case 'string':
673 echo "<input type=text name=${i}_value value='${record['value']}'>";
674 break;
675 case 'dict':
676 $chapter = readChapter ($record['chapter_name']);
677 $chapter[0] = '-- NOT SET --';
f3d274bf
DO
678 $chapter = cookOptgroups ($chapter, $object['objtype_id'], $record['key']);
679 printNiftySelect ($chapter, "${i}_value", $record['key']);
2b98d5a2
AD
680 break;
681 }
682 echo "</td></tr>\n";
683 $i++;
e673ee24 684 }
e673ee24 685 }
e10f583a
DO
686 echo "<tr><td>&nbsp;</td><th class=tdright>Has problems:</th><td class=tdleft><input type=checkbox name=object_has_problems";
687 if ($object['has_problems'] == 'yes')
688 echo ' checked';
689 echo "></td></tr>\n";
690 echo "<tr><td>&nbsp;</td><th class=tdright>Actions:</th><td class=tdleft><a href='".
c78a40ec 691 makeHrefProcess(array('op'=>'deleteObject', 'page'=>'depot', 'tab'=>'default', 'object_id'=>$object_id)).
e10f583a
DO
692 "' onclick=\"javascript:return confirm('Are you sure you want to delete the object?')\">Delete object</a></td></tr>\n";
693 echo "<tr><td colspan=3><b>Comment:</b><br><textarea name=object_comment rows=10 cols=80>${object['comment']}</textarea></td></tr>";
cdd3efe9 694
e10f583a 695 echo "<tr><th class=submit colspan=3>";
5bbbeaa2 696 printImageHREF ('SAVE', 'Save changes', TRUE);
cdd3efe9 697 echo "</form></th></tr></table>\n";
e673ee24 698 finishPortlet();
e673ee24 699
cdd3efe9 700 echo '<table border=0 width=100%><tr><td>';
e673ee24
DO
701 startPortlet ('history');
702 renderHistory ($pageno, $object_id);
703 finishPortlet();
cdd3efe9 704 echo '</td></tr></table>';
e673ee24
DO
705}
706
707// This is a clone of renderEditObjectForm().
708function renderEditRackForm ($rack_id)
709{
0c2b7c4a 710 global $pageno;
61a1d996
DO
711 $rack = spotEntity ('rack', $rack_id);
712 amplifyCell ($rack);
e673ee24 713
e673ee24 714 startPortlet ('Rack attributes');
7056988c 715 printOpFormIntro ('updateRack');
e673ee24
DO
716 echo '<table border=0 align=center>';
717 echo "<tr><th class=tdright>Rack row:</th><td class=tdleft>";
4fbb5a00 718 printSelect (getRackRows(), 'rack_row_id', $rack['row_id']);
e673ee24
DO
719 echo "</td></tr>\n";
720 echo "<tr><th class=tdright>Name (required):</th><td class=tdleft><input type=text name=rack_name value='${rack['name']}'></td></tr>\n";
721 echo "<tr><th class=tdright>Height (required):</th><td class=tdleft><input type=text name=rack_height value='${rack['height']}'></td></tr>\n";
722 echo "<tr><th class=tdright>Comment:</th><td class=tdleft><input type=text name=rack_comment value='${rack['comment']}'></td></tr>\n";
c8187437
DY
723 if (count ($rack['mountedObjects']) == 0)
724 {
725 echo "<tr><th class=tdright>Actions:</th><td class=tdleft><a href='".
726 makeHrefProcess(array('op'=>'deleteRack', 'rack_id'=>$rack_id)).
727 "' onclick=\"javascript:return confirm('Are you sure you want to delete the rack?')\">Delete rack</a></td></tr>\n";
728 }
7056988c
DO
729 echo "<tr><td class=submit colspan=2>";
730 printImageHREF ('SAVE', 'Save changes', TRUE);
731 echo "</td></tr>\n";
e673ee24
DO
732 echo '</form></table><br>';
733 finishPortlet();
734
735 startPortlet ('History');
736 renderHistory ($pageno, $rack_id);
737 finishPortlet();
738}
739
740// This is a helper for creators and editors.
f3d274bf
DO
741// Input array keys are OPTION VALUEs and input array values are OPTION text.
742function printSelect ($optionList, $select_name, $selected_id = NULL, $tabindex = NULL)
e673ee24 743{
f3d274bf
DO
744 echo "<select name=${select_name}" . ($tabindex ? " tabindex=${tabindex}" : '') . '>';
745 foreach ($optionList as $dict_key => $dict_value)
ca0cc77e 746 echo "<option value='${dict_key}'" . ($dict_key == $selected_id ? ' selected' : '') . ">${dict_value}</option>";
f3d274bf
DO
747 echo "</select>";
748}
749
750// Input is a cooked list of OPTGROUPs, each with own sub-list of OPTIONs in the same
751// format as printSelect() expects.
752function printNiftySelect ($groupList, $select_name, $selected_id = NULL, $tabindex = NULL)
753{
754 // special treatment for ungrouped data
755 if (count ($groupList) == 1 and isset ($groupList['other']))
e673ee24 756 {
f3d274bf
DO
757 printSelect ($groupList['other'], $select_name, $selected_id, $tabindex);
758 return;
9e7f32a7 759 }
a65f9f54 760 echo "<select name=${select_name}" . ($tabindex ? " tabindex=${tabindex}" : '') . '>';
f3d274bf 761 foreach ($groupList as $groupname => $groupdata)
9e7f32a7 762 {
f3d274bf
DO
763 echo "<optgroup label='${groupname}'>";
764 foreach ($groupdata as $dict_key => $dict_value)
ca0cc77e 765 echo "<option value='${dict_key}'" . ($dict_key == $selected_id ? ' selected' : '') . ">${dict_value}</option>";
f3d274bf 766 echo "</optgroup>\n";
e673ee24
DO
767 }
768 echo "</select>";
769}
770
254673dd
DO
771// used by renderGridForm() and renderRackPage()
772function renderRackInfoPortlet ($rackData)
773{
774 startPortlet ('summary');
775 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
776 echo "<tr><th width='50%' class=tdright>Rack row:</th><td class=tdleft>${rackData['row_name']}</td></tr>\n";
777 echo "<tr><th width='50%' class=tdright>Name:</th><td class=tdleft>${rackData['name']}</td></tr>\n";
778 echo "<tr><th width='50%' class=tdright>Height:</th><td class=tdleft>${rackData['height']}</td></tr>\n";
04d619d0 779 echo "<tr><th width='50%' class=tdright>%% used:</th><td class=tdleft>";
254673dd
DO
780 renderProgressBar (getRSUforRack ($rackData));
781 echo "</td></tr>\n";
782 echo "<tr><th width='50%' class=tdright>Objects:</th><td class=tdleft>";
61a1d996 783 echo count ($rackData['mountedObjects']);
254673dd 784 echo "</td></tr>\n";
4fbb5a00 785 printTagTRs (makeHref(array('page'=>'rackspace', 'tab'=>'default'))."&");
254673dd
DO
786 if (!empty ($rackData['comment']))
787 echo "<tr><th width='50%' class=tdright>Comment:</th><td class=tdleft>${rackData['comment']}</td></tr>\n";
788 echo '</table>';
789 finishPortlet();
790}
791
e673ee24 792// This is a universal editor of rack design/waste.
7056988c 793// FIXME: switch to using printOpFormIntro()
7e1db771 794function renderGridForm ($rack_id, $filter, $header, $submit, $state1, $state2)
e673ee24 795{
61a1d996
DO
796 $rackData = spotEntity ('rack', $rack_id);
797 amplifyCell ($rackData);
254673dd 798 $filter ($rackData);
e673ee24
DO
799 markupObjectProblems ($rackData);
800
e673ee24
DO
801 // Render the result whatever it is.
802 // Main layout.
803 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
804 echo "<tr><td colspan=2 align=center><h1>${rackData['name']}</h1></td></tr>\n";
805
806 // Left column with information portlet.
807 echo "<tr><td class=pcleft height='1%' width='50%'>";
254673dd 808 renderRackInfoPortlet ($rackData);
e673ee24 809 echo "</td>\n";
bb09cca0 810 echo "<td class=pcright>";
e673ee24
DO
811
812 // Grid form.
813 startPortlet ($header);
814 echo "<center>\n";
815 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
57c69e9c
AD
816 echo "<tr><th width='10%'>&nbsp;</th>";
817 echo "<th width='20%'><a href='javascript:;' onclick=\"toggleColumnOfAtoms('${rack_id}', '0', ${rackData['height']})\">Front</a></th>";
818 echo "<th width='50%'><a href='javascript:;' onclick=\"toggleColumnOfAtoms('${rack_id}', '1', ${rackData['height']})\">Interior</a></th>";
819 echo "<th width='20%'><a href='javascript:;' onclick=\"toggleColumnOfAtoms('${rack_id}', '2', ${rackData['height']})\">Back</a></th></tr>\n";
4fbb5a00 820 printOpFormIntro ('updateRack');
e673ee24
DO
821 markupAtomGrid ($rackData, $state2);
822 renderAtomGrid ($rackData);
823 echo "</table></center>\n";
824 echo "<br><input type=submit name=do_update value='${submit}'></form><br><br>\n";
825 finishPortlet();
bb09cca0 826 echo "</td></tr></table>\n";
e673ee24
DO
827}
828
829function renderRackDesign ($rack_id)
830{
bb09cca0 831 renderGridForm ($rack_id, 'applyRackDesignMask', 'Rack design', 'Set rack design', 'A', 'F');
e673ee24
DO
832}
833
7e1db771 834function renderRackProblems ($rack_id)
e673ee24 835{
bb09cca0 836 renderGridForm ($rack_id, 'applyRackProblemMask', 'Rack problems', 'Mark unusable atoms', 'F', 'U');
e673ee24
DO
837}
838
839function startPortlet ($title = '')
840{
841 echo "<div class=portlet><h2>${title}</h2>";
842}
843
844function finishPortlet ()
845{
846 echo "</div>\n";
847}
848
7e1db771 849function renderRackObject ($object_id)
e673ee24 850{
4fbb5a00 851 global $nextorder, $aac;
e673ee24
DO
852 $info = getObjectInfo ($object_id);
853 if ($info == NULL)
854 {
591ff2c4 855 showError ('getObjectInfo() failed', __FUNCTION__);
e673ee24
DO
856 return;
857 }
858 // Main layout starts.
859 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
860 echo "<tr><td colspan=2 align=center><h1>${info['dname']}</h1></td></tr>\n";
861 // left column with uknown number of portlets
862 echo "<tr><td class=pcleft>";
0ab782bc 863 startPortlet ('summary');
e673ee24
DO
864 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
865 if (!empty ($info['name']))
866 echo "<tr><th width='50%' class=tdright>Common name:</th><td class=tdleft>${info['name']}</td></tr>\n";
212c9d8a
DO
867 // FIXME: don't call spotEntity() each time, do it once in the beginning.
868 elseif (considerConfiguredConstraint (spotEntity ('object', $object_id), 'NAMEWARN_LISTSRC'))
a0ec6295 869 echo "<tr><td colspan=2 class=msg_error>Common name is missing.</td></tr>\n";
341fd895
DO
870 echo "<tr><th width='50%' class=tdright>Object type:</th><td class=tdleft><a href='";
871 echo makeHref (array (
872 'page' => 'depot',
873 'tab' => 'default',
874 'cfe' => '{$typeid_' . $info['objtype_id'] . '}'
875 ));
876 echo "'>${info['objtype_name']}</a></td></tr>\n";
e673ee24
DO
877 if (!empty ($info['asset_no']))
878 echo "<tr><th width='50%' class=tdright>Asset tag:</th><td class=tdleft>${info['asset_no']}</td></tr>\n";
212c9d8a
DO
879 // FIXME: ditto
880 elseif (considerConfiguredConstraint (spotEntity ('object', $object_id), 'ASSETWARN_LISTSRC'))
a0ec6295 881 echo "<tr><td colspan=2 class=msg_error>Asset tag is missing.</td></tr>\n";
e673ee24
DO
882 if (!empty ($info['label']))
883 echo "<tr><th width='50%' class=tdright>Visible label:</th><td class=tdleft>${info['label']}</td></tr>\n";
884 if (!empty ($info['barcode']))
885 echo "<tr><th width='50%' class=tdright>Barcode:</th><td class=tdleft>${info['barcode']}</td></tr>\n";
886 if ($info['has_problems'] == 'yes')
887 echo "<tr><td colspan=2 class=msg_error>Has problems</td></tr>\n";
24cbe8af 888 foreach (getAttrValues ($object_id, TRUE) as $record)
e673ee24 889 if (!empty ($record['value']))
57777e4a 890 echo "<tr><th width='50%' class=sticker>${record['name']}:</th><td class=sticker>${record['a_value']}</td></tr>\n";
341fd895
DO
891 printTagTRs
892 (
893 makeHref
894 (
895 array
896 (
897 'page'=>'depot',
898 'tab'=>'default',
899 'andor' => 'and',
a8efc03e 900 'cfe' => '{$typeid_' . $info['objtype_id'] . '}',
341fd895
DO
901 )
902 )."&"
903 );
e673ee24
DO
904 echo "</table><br>\n";
905 finishPortlet();
906
907 if (!empty ($info['comment']))
908 {
909 startPortlet ('Comment');
6cc5d6cd 910 echo '<div class=commentblock>' . string_insert_hrefs ($info['comment']) . '</div>';
e673ee24
DO
911 finishPortlet ();
912 }
913
e1ae3fb4
AD
914 renderFilesPortlet ('object', $object_id);
915
e673ee24
DO
916 $ports = getObjectPortsAndLinks ($object_id);
917 if (count ($ports))
918 {
0ab782bc 919 startPortlet ('ports and links');
e673ee24
DO
920 usort($ports, 'sortByName');
921 if ($ports)
922 {
923 $hl_port_id = 0;
924 if (isset ($_REQUEST['hl_port_id']))
925 {
2c6c7645 926 assertUIntArg ('hl_port_id', __FUNCTION__);
e673ee24
DO
927 $hl_port_id = $_REQUEST['hl_port_id'];
928 }
929 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
930 echo "<tr><th>Local name</th><th>Visible label</th><th>Port type</th><th>L2 address</th>";
931 echo "<th>Rem. Object</th><th>Rem. port</th></tr>\n";
932 foreach ($ports as $port)
933 {
934 echo '<tr';
935 if ($hl_port_id == $port['id'])
936 echo ' class=port_highlight';
937 echo "><td>${port['name']}</td><td>${port['label']}</td><td>${port['type']}</td>";
938 echo "<td>${port['l2address']}</td>";
939 if ($port['remote_object_id'])
940 {
4fbb5a00 941 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>";
e673ee24
DO
942 echo "<td>${port['remote_name']}</td>";
943 }
944 elseif (!empty ($port['reservation_comment']))
945 {
946 echo "<td><b>Reserved;</b></td>";
947 echo "<td>${port['reservation_comment']}</td>";
948 }
949 else
950 echo '<td>&nbsp;</td><td>&nbsp;</td>';
951 echo "</tr>\n";
952 }
953 echo "</table><br>\n";
954 }
955 finishPortlet();
956 }
85970da2 957
0ab782bc
DO
958 $alloclist = getObjectIPv4Allocations ($object_id);
959 if (count ($alloclist))
e673ee24 960 {
f28fbe8b 961 startPortlet ('IPv4 addresses');
e673ee24 962 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
f0ed1181 963 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
0b9c98d7 964 echo "<tr><th>OS interface</th><th>IP address</th><th>network</th><th>routed by</th><th>peers</th></tr>\n";
83fdf85f
DO
965 else
966 echo "<tr><th>OS interface</th><th>IP address</th><th>peers</th></tr>\n";
fc0e3978
DO
967 $hl_ipv4_addr = '';
968 if (isset ($_REQUEST['hl_ipv4_addr']))
969 {
970 assertIPv4Arg ('hl_ipv4_addr', __FUNCTION__);
971 $hl_ipv4_addr = $_REQUEST['hl_ipv4_addr'];
972 }
85970da2 973 foreach ($alloclist as $dottedquad => $alloc)
e673ee24 974 {
0ab782bc
DO
975 $address_name = niftyString ($alloc['addrinfo']['name']);
976 $class = $alloc['addrinfo']['class'];
85970da2 977 $secondclass = ($hl_ipv4_addr == $dottedquad) ? 'tdleft port_highlight' : 'tdleft';
83fdf85f 978 $netid = getIPv4AddressNetworkId ($dottedquad);
d7a8186d 979 if (NULL !== $netid)
83fdf85f 980 {
d724d290 981 $netinfo = spotEntity ('ipv4net', $netid);
d7a8186d 982 loadIPv4AddrList ($netinfo);
83fdf85f 983 }
d7a8186d
DO
984 echo "<tr class='${class}' valign=top><td class=tdleft>${alloc['osif']}</td><td class='${secondclass}'>";
985 if (NULL !== $netid)
4fbb5a00 986 echo "<a href='".makeHref(array('page'=>'ipaddress', 'ip'=>$dottedquad, 'hl_object_id'=>$object_id))."'>${dottedquad}</a>";
d7a8186d
DO
987 else
988 echo $dottedquad;
989 if (getConfigVar ('EXT_IPV4_VIEW') != 'yes')
990 echo '<small>/' . (NULL === $netid ? '??' : $netinfo['mask']) . '</small>';
351b1f45 991 echo '&nbsp;' . $aac[$alloc['type']];
83fdf85f 992 if (!empty ($alloc['addrinfo']['name']))
28a664e7 993 echo ' (' . niftyString ($alloc['addrinfo']['name']) . ')';
83fdf85f 994 echo '</td>';
f0ed1181 995 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
b90c3907 996 {
83fdf85f 997 if (NULL === $netid)
0b9c98d7 998 echo '<td class=sparenetwork>N/A</td><td class=sparenetwork>N/A</td>';
83fdf85f 999 else
83fdf85f 1000 {
0b9c98d7 1001 echo "<td class='${secondclass}'>";
6df2025d 1002 renderCell ($netinfo);
0b9c98d7 1003 echo "</td>";
8b3874a5
DO
1004 // filter out self-allocation
1005 $other_routers = array();
d7a8186d 1006 foreach (findRouters ($netinfo['addrlist']) as $router)
8b3874a5
DO
1007 if ($router['id'] != $object_id)
1008 $other_routers[] = $router;
0b9c98d7
DO
1009 if (count ($other_routers))
1010 printRoutersTD ($other_routers);
1011 else
1012 echo "<td class='${secondclass}'>&nbsp;</td>";
83fdf85f 1013 }
b90c3907 1014 }
83fdf85f 1015 // peers
0ab782bc 1016 echo "<td class='${secondclass}'>\n";
0ab782bc 1017 $prefix = '';
2c817354 1018 if ($alloc['addrinfo']['reserved'] == 'yes')
e673ee24 1019 {
85970da2 1020 echo $prefix . '<strong>RESERVED</strong>';
0ab782bc
DO
1021 $prefix = '; ';
1022 }
1023 foreach ($alloc['addrinfo']['allocs'] as $allocpeer)
1024 {
1025 if ($allocpeer['object_id'] == $object_id)
1026 continue;
4fbb5a00 1027 echo $prefix . "<a href='".makeHref(array('page'=>'object', 'object_id'=>$allocpeer['object_id']))."'>";
0ab782bc
DO
1028 if (!empty ($allocpeer['osif']))
1029 echo $allocpeer['osif'] . '@';
1030 echo $allocpeer['object_name'] . '</a>';
0ab782bc 1031 $prefix = '; ';
e673ee24 1032 }
e673ee24
DO
1033 echo "</td></tr>\n";
1034 }
1035 echo "</table><br>\n";
1036 finishPortlet();
1037 }
1038
eeb4a5d8 1039 $forwards = getNATv4ForObject ($object_id);
e673ee24
DO
1040 if (count($forwards['in']) or count($forwards['out']))
1041 {
f28fbe8b 1042 startPortlet('NATv4');
e673ee24
DO
1043
1044 if (count($forwards['out']))
1045 {
1046
f28fbe8b 1047 echo "<h3>locally performed NAT</h3>";
e673ee24 1048
105a3bc8 1049 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
f28fbe8b 1050 echo "<tr><th>Proto</th><th>Match endpoint</th><th>Translate to</th><th>Target object</th><th>Rule comment</th></tr>\n";
e673ee24
DO
1051
1052 foreach ($forwards['out'] as $pf)
1053 {
2c817354
DO
1054 $class = 'trerror';
1055 $osif = '';
1056 if (isset ($alloclist [$pf['localip']]))
1057 {
1058 $class = $alloclist [$pf['localip']]['addrinfo']['class'];
1059 $osif = $alloclist [$pf['localip']]['osif'] . ': ';
1060 }
e673ee24 1061 echo "<tr class='$class'>";
4fbb5a00
DY
1062 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>";
1063 echo "<td class=tdleft><a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['remoteip']))."'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
53ef3908 1064 $address = getIPv4Address ($pf['remoteip']);
e673ee24 1065 echo "<td class='description'>";
53ef3908
DO
1066 if (count ($address['allocs']))
1067 foreach($address['allocs'] as $bond)
4fbb5a00 1068 echo "<a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$bond['object_id']))."'>${bond['object_name']}(${bond['name']})</a> ";
f28fbe8b
DO
1069 elseif (!empty ($pf['remote_addr_name']))
1070 echo '(' . $pf['remote_addr_name'] . ')';
53ef3908 1071 echo "</td><td class='description'>${pf['description']}</td></tr>";
e673ee24
DO
1072 }
1073 echo "</table><br><br>";
1074 }
1075 if (count($forwards['in']))
1076 {
f28fbe8b 1077 echo "<h3>arriving NAT connections</h3>";
105a3bc8 1078 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
f28fbe8b 1079 echo "<tr><th>Matched endpoint</th><th>Source object</th><th>Translated to</th><th>Rule comment</th></tr>\n";
e673ee24
DO
1080 foreach ($forwards['in'] as $pf)
1081 {
1082 echo "<tr>";
4fbb5a00
DY
1083 echo "<td>${pf['proto']}/<a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['localip']))."'>${pf['localip']}</a>:${pf['localport']}</td>";
1084 echo "<td class='description'><a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$pf['object_id']))."'>${pf['object_name']}</a>";
1085 echo "</td><td><a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['remoteip']))."'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
e673ee24
DO
1086 echo "<td class='description'>${pf['description']}</td></tr>";
1087 }
e673ee24
DO
1088 echo "</table><br><br>";
1089 }
1090 finishPortlet();
1091 }
1092
78e7b769
DO
1093 $pools = getRSPoolsForObject ($object_id);
1094 if (count ($pools))
1095 {
300826cb 1096 $order = 'odd';
8128c257 1097 startPortlet ('Real server pools (' . count ($pools) . ')');
78e7b769 1098 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
732e4578 1099 echo "<tr><th>VS</th><th>RS pool</th><th>RS</th><th>VS config</th><th>RS config</th></tr>\n";
748805bf 1100 foreach ($pools as $vs_id => $info)
78e7b769 1101 {
b1a970c7 1102 echo "<tr valign=top class=row_${order}><td class=tdleft>";
6df2025d 1103 renderCell (spotEntity ('ipv4vs', $vs_id));
b1a970c7
DO
1104 echo "</td><td class=tdleft>";
1105 renderRSPoolCell ($info['pool_id'], $info['pool_name']);
1106 echo '</td><td class=tdleft>' . $info['rscount'] . '</td>';
1107 echo "<td class=slbconf>${info['vsconfig']}</td>";
1108 echo "<td class=slbconf>${info['rsconfig']}</td>";
78e7b769 1109 echo "</tr>\n";
300826cb 1110 $order = $nextorder[$order];
78e7b769
DO
1111 }
1112 echo "</table>\n";
1113 finishPortlet();
1114 }
e673ee24
DO
1115 echo "</td>\n";
1116
7056988c 1117 // After left column we have (surprise!) right column with rackspace portlet only.
e673ee24
DO
1118 echo "<td class=pcright>";
1119 // rackspace portlet
0ab782bc 1120 startPortlet ('rackspace allocation');
932e8cc2
DO
1121 foreach (getResidentRacksData ($object_id, FALSE) as $rack_id)
1122 renderRack ($rack_id, $object_id);
e673ee24
DO
1123 echo '<br>';
1124 finishPortlet();
1125 echo "</td></tr>";
1126 echo "</table>\n";
1127}
1128
1129function renderRackMultiSelect ($sname, $racks, $selected)
1130{
04571888
DO
1131 // Transform the given flat list into a list of groups, each representing a rack row.
1132 $rdata = array();
e673ee24 1133 foreach ($racks as $rack)
04571888
DO
1134 if (!isset ($rdata[$rack['row_name']]))
1135 $rdata[$rack['row_name']] = array ($rack['id'] => $rack['name']);
1136 else
1137 $rdata[$rack['row_name']][$rack['id']] = $rack['name'];
4fbb5a00 1138 echo "<select name=${sname} multiple size=" . getConfigVar ('MAXSELSIZE') . " onchange='getElementsByName(\"updateObjectAllocation\")[0].submit()'>\n";
04571888 1139 foreach ($rdata as $optgroup => $racklist)
e673ee24 1140 {
04571888
DO
1141 echo "<optgroup label='${optgroup}'>";
1142 foreach ($racklist as $rack_id => $rack_name)
1143 {
1144 echo "<option value=${rack_id}";
1145 if (!(array_search ($rack_id, $selected) === FALSE))
1146 echo ' selected';
1147 echo">${rack_name}</option>\n";
1148 }
e673ee24
DO
1149 }
1150 echo "</select>\n";
1151}
1152
1153function showMessageOrError ()
1154{
bd49850d 1155 if (isset ($_SESSION['log']))
83555c04 1156 {
83555c04
DY
1157 printLog ($_SESSION['log']);
1158 unset($_SESSION['log']);
1159 }
e673ee24
DO
1160}
1161
1162// This function renders a form for port edition.
7e1db771 1163function renderPortsForObject ($object_id)
e673ee24 1164{
39b4abd0
DO
1165 function printNewItemTR ()
1166 {
1167 printOpFormIntro ('addPort');
1168 echo "<tr><td>";
f5ff50f5 1169 printImageHREF ('add', 'add a port', TRUE);
39b4abd0 1170 echo "</td><td><input type=text size=8 name=port_name tabindex=100></td>\n";
3decd141
DO
1171 echo "<td><input type=text size=24 name=port_label tabindex=101></td><td>";
1172 printSelect (getPortTypes(), 'port_type_id', getConfigVar ('default_port_type'), 102);
39b4abd0 1173 echo "<td><input type=text name=port_l2address tabindex=103></td>\n";
9318d2ef
DO
1174 echo "<td colspan=3>&nbsp;</td><td>";
1175 printImageHREF ('add', 'add a port', TRUE, 104);
1176 echo "</td></tr></form>";
39b4abd0 1177 }
e673ee24
DO
1178 startPortlet ('Ports and interfaces');
1179 $ports = getObjectPortsAndLinks ($object_id);
1180 usort($ports, 'sortByName');
1181 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
1182 echo "<tr><th>&nbsp;</th><th>Local name</th><th>Visible label</th><th>Port type</th><th>L2 address</th>";
1183 echo "<th>Rem. object</th><th>Rem. port</th><th>(Un)link or (un)reserve</th><th>&nbsp;</th></tr>\n";
39b4abd0
DO
1184 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
1185 printNewItemTR();
e673ee24
DO
1186 foreach ($ports as $port)
1187 {
7056988c 1188 printOpFormIntro ('editPort', array ('port_id' => $port['id']));
b7f0eaec 1189 echo "<tr><td><a href='".makeHrefProcess(array('op'=>'delPort', 'port_id'=>$port['id'], 'object_id'=>$object_id, 'port_name'=>$port['name']))."'>";
e673ee24
DO
1190 printImageHREF ('delete', 'Unlink and Delete this port');
1191 echo "</a></td>\n";
1192 echo "<td><input type=text name=name value='${port['name']}' size=8></td>";
1193 echo "<td><input type=text name=label value='${port['label']}' size=24></td>";
611170af
AD
1194 if (!$port['remote_object_id'])
1195 {
1196 echo "<td>";
1197 printSelect (getPortTypes(), 'port_type_id', $port['type_id']);
1198 echo "</td>";
1199 }
1200 else
1201 {
1202 echo "<input type=hidden name=port_type_id value='${port['type_id']}'>";
f7a3c94a 1203 echo "<td class=tdleft>${port['type']}</td>\n";
611170af 1204 }
e673ee24
DO
1205 echo "<td><input type=text name=l2address value='${port['l2address']}'></td>\n";
1206 if ($port['remote_object_id'])
1207 {
4fbb5a00 1208 echo "<td><a href='".makeHref(array('page'=>'object', 'object_id'=>$port['remote_object_id']))."'>${port['remote_object_name']}</a></td>";
e673ee24 1209 echo "<td>${port['remote_name']}</td>";
4fbb5a00
DY
1210 echo "<td><a href='".
1211 makeHrefProcess(array(
1212 'op'=>'unlinkPort',
1213 'port_id'=>$port['id'],
1214 'object_id'=>$object_id,
1215 'port_name'=>$port['name'],
1216 'remote_port_name'=>$port['remote_name'],
1217 'remote_object_name'=>$port['remote_object_name'])).
1218 "'>";
5ccd99a0 1219 printImageHREF ('cut', 'Unlink this port');
e673ee24
DO
1220 echo "</a></td>";
1221 }
1222 elseif (!empty ($port['reservation_comment']))
1223 {
1224 echo "<td><b>Reserved;</b></td>";
1225 echo "<td><input type=text name=reservation_comment value='${port['reservation_comment']}'></td>";
4fbb5a00
DY
1226 echo "<td><a href='".
1227 makeHrefProcess(array(
1228 'op'=>'useup',
1229 'port_id'=>$port['id'],
1230 'object_id'=>$object_id)).
1231 "'>";
39be655e 1232 printImageHREF ('clear', 'Use up this port');
e673ee24
DO
1233 echo "</a></td>";
1234 }
1235 else
1236 {
1237 echo "<td>&nbsp;</td><td>&nbsp;</td>";
1238 echo "<td>";
39106006 1239 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\");'>";
5ccd99a0 1240 printImageHREF ('plug', 'Link this port');
e673ee24
DO
1241 echo "</a> <input type=text name=reservation_comment>";
1242 echo "</td>\n";
1243 }
5bbbeaa2
DO
1244 echo "<td>";
1245 printImageHREF ('save', 'Save changes', TRUE);
1246 echo "</td></form></tr>\n";
e673ee24 1247 }
39b4abd0
DO
1248 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
1249 printNewItemTR();
e673ee24
DO
1250 echo "</table><br>\n";
1251 finishPortlet();
1252
1253 startPortlet ('Add/update multiple ports');
7056988c 1254 printOpFormIntro ('addMultiPorts');
f7a3c94a 1255 echo 'Format: <select name=format tabindex=201>';
e673ee24
DO
1256 echo '<option value=c3600asy>Cisco 3600 async: sh line | inc TTY</option>';
1257 echo '<option value=fiwg selected>Foundry ServerIron/FastIron WorkGroup/Edge: sh int br</option>';
e673ee24 1258 echo '<option value=fisxii>Foundry FastIron SuperX/II4000: sh int br</option>';
351d4dbf 1259 echo '<option value=ssv1>SSV:&lt;interface name&gt; &lt;MAC address&gt;</option>';
e673ee24
DO
1260 echo "</select>";
1261 echo 'Default port type: ';
f7a3c94a
DO
1262 printSelect (getPortTypes(), 'port_type', getConfigVar ('default_port_type'), 202);
1263 echo "<input type=submit value='Parse output' tabindex=204><br>\n";
1264 echo "<textarea name=input cols=100 rows=50 tabindex=203></textarea><br>\n";
e673ee24
DO
1265 echo '</form>';
1266 finishPortlet();
1267}
1268
7e1db771 1269function renderIPv4ForObject ($object_id)
e673ee24 1270{
39b4abd0
DO
1271 function printNewItemTR ()
1272 {
1273 global $aat;
1274 printOpFormIntro ('addIPv4Allocation');
1275 echo "<tr><td>";
f5ff50f5 1276 printImageHREF ('add', 'allocate', TRUE);
39b4abd0
DO
1277 echo "</td>";
1278 echo "<td class=tdleft><input type='text' size='10' name='bond_name' tabindex=100></td>\n";
1279 echo "<td class=tdleft><input type=text name='ip' tabindex=101></td>\n";
0b9c98d7 1280 echo "<td colspan=2>&nbsp;</td><td>";
f5ff50f5 1281 printSelect ($aat, 'bond_type', NULL, 102);
9318d2ef 1282 echo "</td><td>&nbsp;</td><td>";
f5ff50f5 1283 printImageHREF ('add', 'allocate', TRUE, 103);
9318d2ef 1284 echo "</td></tr></form>";
39b4abd0 1285 }
b82cce3f 1286 global $aat;
72d8ced3 1287 startPortlet ('Allocations');
85970da2 1288 $alloclist = getObjectIPv4Allocations ($object_id);
e673ee24 1289 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
79e45b4c
DO
1290 echo '<tr><th>&nbsp;</th><th>OS interface</th><th>IP address</th>';
1291 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
0b9c98d7 1292 echo '<th>network</th><th>routed by</th>';
79e45b4c 1293 echo '<th>type</th><th>misc</th><th>&nbsp</th></tr>';
09620506 1294
39b4abd0
DO
1295 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
1296 printNewItemTR();
85970da2 1297 foreach ($alloclist as $dottedquad => $alloc)
e673ee24 1298 {
85970da2 1299 $class = $alloc['addrinfo']['class'];
79e45b4c 1300 $netid = getIPv4AddressNetworkId ($dottedquad);
d7a8186d
DO
1301 if (NULL !== $netid)
1302 {
d724d290 1303 $netinfo = spotEntity ('ipv4net', $netid);
d7a8186d
DO
1304 loadIPv4AddrList ($netinfo);
1305 }
85970da2 1306 printOpFormIntro ('updIPv4Allocation', array ('ip' => $dottedquad));
4fbb5a00 1307 echo "<tr class='$class' valign=top><td><a href='".makeHrefProcess(array('op'=>'delIPv4Allocation', 'ip'=>$dottedquad, 'object_id'=>$object_id))."'>";
e673ee24
DO
1308 printImageHREF ('delete', 'Delete this IPv4 address');
1309 echo "</a></td>";
d7a8186d
DO
1310 echo "<td class=tdleft><input type='text' name='bond_name' value='${alloc['osif']}' size=10></td><td class=tdleft>";
1311 if (NULL !== $netid)
4fbb5a00 1312 echo "<a href='".makeHref(array('page'=>'ipaddress', 'ip'=>$dottedquad))."'>${dottedquad}</a>";
d7a8186d
DO
1313 else
1314 echo $dottedquad;
79e45b4c 1315 if (getConfigVar ('EXT_IPV4_VIEW') != 'yes')
d7a8186d 1316 echo '<small>/' . (NULL === $netid ? '??' : $netinfo['mask']) . '</small>';
79e45b4c 1317 if (!empty ($alloc['addrinfo']['name']))
28a664e7 1318 echo ' (' . niftyString ($alloc['addrinfo']['name']) . ')';
79e45b4c
DO
1319 echo '</td>';
1320 // FIXME: this a copy-and-paste from renderRackObject()
1321 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
1322 {
1323 if (NULL === $netid)
0b9c98d7 1324 echo '<td class=sparenetwork>N/A</td><td class=sparenetwork>N/A</td>';
79e45b4c 1325 else
79e45b4c 1326 {
0b9c98d7 1327 echo '<td>';
6df2025d 1328 renderCell ($netinfo);
d7a8186d 1329 echo '</td>';
0b9c98d7
DO
1330 // filter out self-allocation
1331 $other_routers = array();
1332 foreach (findRouters ($netinfo['addrlist']) as $router)
1333 if ($router['id'] != $object_id)
1334 $other_routers[] = $router;
1335 if (count ($other_routers))
1336 printRoutersTD ($other_routers);
1337 else
1338 echo "<td>&nbsp;</td>";
79e45b4c 1339 }
79e45b4c
DO
1340 }
1341 echo '<td>';
85970da2 1342 printSelect ($aat, 'bond_type', $alloc['type']);
e673ee24 1343 echo "</td><td>";
85970da2 1344 $prefix = '';
4940e4d5 1345 if ($alloc['addrinfo']['reserved'] == 'yes')
e673ee24 1346 {
85970da2
DO
1347 echo $prefix . '<strong>RESERVED</strong>';
1348 $prefix = '; ';
e673ee24 1349 }
85970da2 1350 foreach ($alloc['addrinfo']['allocs'] as $allocpeer)
e673ee24 1351 {
85970da2
DO
1352 if ($allocpeer['object_id'] == $object_id)
1353 continue;
4fbb5a00 1354 echo $prefix . "<a href='".makeHref(array('page'=>'object', 'object_id'=>$allocpeer['object_id']))."'>";
85970da2
DO
1355 if (!empty ($allocpeer['osif']))
1356 echo $allocpeer['osif'] . '@';
1357 echo $allocpeer['object_name'] . '</a>';
1358 $prefix = '; ';
e673ee24 1359 }
d54b9495
DO
1360 echo "</td><td>";
1361 printImageHREF ('save', 'Save changes', TRUE);
1362 echo "</td></form></tr>\n";
e673ee24 1363 }
39b4abd0
DO
1364 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
1365 printNewItemTR();
e673ee24 1366
09620506 1367 echo "</table><br>\n";
e673ee24
DO
1368 finishPortlet();
1369
1370}
1371
baf37d01
DO
1372// Log structure versions:
1373// 1: the whole structure is a list of code-message pairs
1374// 2 and later: there's a "v" field set, which indicates the version
1375// 2: there's a "m" list set to hold message code and optional arguments
e673ee24
DO
1376function printLog ($log)
1377{
baf37d01
DO
1378 switch (TRUE)
1379 {
1380 case !isset ($log['v']):
ebb5441d 1381 case $log['v'] == 1:
baf37d01 1382 foreach ($log as $key => $record)
ebb5441d 1383 if ($key !== 'v')
baf37d01
DO
1384 echo "<div class=msg_${record['code']}>${record['message']}</div>";
1385 break;
1386 case $log['v'] == 2:
1387 $msginfo = array
1388 (
8628ae44 1389// records 0~99 with success messages
950a1887 1390 0 => array ('code' => 'success', 'format' => '%s'),
baf37d01
DO
1391 1 => array ('code' => 'success', 'format' => '%u new records done, %u already existed'),
1392 2 => array ('code' => 'success', 'format' => 'NATv4 rule was successfully added.'),
1393 3 => array ('code' => 'success', 'format' => 'NATv4 rule was successfully deleted.'),
1394 4 => array ('code' => 'success', 'format' => 'NATv4 rule was successfully updated'),
1395 5 => array ('code' => 'success', 'format' => 'Port %s was added successfully'),
1396 6 => array ('code' => 'success', 'format' => 'Port %s was updated successfully'),
1397 7 => array ('code' => 'success', 'format' => 'Port %s was deleted successfully'),
1398 8 => array ('code' => 'success', 'format' => 'Port %s successfully linked with port %s at object %s'),
1399 9 => array ('code' => 'success', 'format' => 'Port %s was successfully unlinked from %s@%s'),
1400 10 => array ('code' => 'success', 'format' => 'Added %u ports, updated %u ports, encountered %u errors.'),
1401 11 => array ('code' => 'success', 'format' => 'Reservation removed.'),
1402 12 => array ('code' => 'success', 'format' => 'allocation updated'),
1403 13 => array ('code' => 'success', 'format' => 'allocated'),
1404 14 => array ('code' => 'success', 'format' => 'deallocated'),
1405 15 => array ('code' => 'success', 'format' => 'Reset succeeded.'),
1406 16 => array ('code' => 'success', 'format' => 'Update done'),
1407 17 => array ('code' => 'success', 'format' => 'Update(s) succeeded.'),
1408 18 => array ('code' => 'success', 'format' => 'Load balancer was successfully added'),
1409 19 => array ('code' => 'success', 'format' => 'Load balancer was successfully deleted'),
1410 20 => array ('code' => 'success', 'format' => 'Load balancer info was successfully updated'),
1411 21 => array ('code' => 'success', 'format' => 'Generation complete'),
1412 22 => array ('code' => 'success', 'format' => 'Chained %u tags'),
1413 23 => array ('code' => 'success', 'format' => 'IPv4 prefix successfully added'),
1414 24 => array ('code' => 'success', 'format' => 'IPv4 prefix deleted'),
1415 25 => array ('code' => 'success', 'format' => 'IPv4 prefix updated'),
1416 26 => array ('code' => 'success', 'format' => '%u IP address(es) were successfully updated'),
1417 27 => array ('code' => 'success', 'format' => 'IPv4 address updated'),
1418 28 => array ('code' => 'success', 'format' => 'Virtual service was successfully created'),
1419 29 => array ('code' => 'success', 'format' => 'Virtual service was successfully deleted'),
1420 30 => array ('code' => 'success', 'format' => 'Virtual service was successfully updated'),
1421 31 => array ('code' => 'success', 'format' => 'RS pool was successfully created'),
1422 32 => array ('code' => 'success', 'format' => 'RS pool was successfully deleted'),
1423 33 => array ('code' => 'success', 'format' => 'RS pool was successfully updated'),
1424 34 => array ('code' => 'success', 'format' => 'Real server was successfully added'),
1425 35 => array ('code' => 'success', 'format' => 'Real server was successfully deleted'),
1426 36 => array ('code' => 'success', 'format' => 'Real server was successfully updated'),
1427 37 => array ('code' => 'success', 'format' => 'Successfully added %u real servers'),
1428 38 => array ('code' => 'success', 'format' => '%u real server(s) were successfully (de)activated'),
1429 39 => array ('code' => 'success', 'format' => 'User account %s updated.'),
1430 40 => array ('code' => 'success', 'format' => 'User account %s created.'),
79b8ad1e
DO
1431// ...
1432// ...
baf37d01
DO
1433 43 => array ('code' => 'success', 'format' => 'Saved successfully.'),
1434 44 => array ('code' => 'success', 'format' => '%s failures and %s successfull changes.'),
1435 45 => array ('code' => 'success', 'format' => "Attribute '%s' created."),
1436 46 => array ('code' => 'success', 'format' => 'Rename successful.'),
1437 47 => array ('code' => 'success', 'format' => 'Attribute was deleted.'),
1438 48 => array ('code' => 'success', 'format' => 'Supplement succeeded.'),
1439 49 => array ('code' => 'success', 'format' => 'Reduction succeeded.'),
1440 50 => array ('code' => 'success', 'format' => 'Reduction succeeded.'),
1441 51 => array ('code' => 'success', 'format' => 'Update succeeded.'),
1442 52 => array ('code' => 'success', 'format' => 'Supplement succeeded.'),
1443 53 => array ('code' => 'success', 'format' => 'Chapter was deleted.'),
1444 54 => array ('code' => 'success', 'format' => 'Chapter was updated.'),
1445 55 => array ('code' => 'success', 'format' => 'Chapter was added.'),
1446 56 => array ('code' => 'success', 'format' => 'Update succeeded.'),
1447 57 => array ('code' => 'success', 'format' => 'Reset complete'),
c615a655 1448 58 => array ('code' => 'success', 'format' => "Deleted tag '%s'."),
baf37d01
DO
1449 59 => array ('code' => 'success', 'format' => "Created tag '%s'."),
1450 60 => array ('code' => 'success', 'format' => "Updated tag '%s'."),
ebb5441d 1451 61 => array ('code' => 'success', 'format' => 'Password changed successfully.'),
24dcb9d8 1452 62 => array ('code' => 'success', 'format' => 'gw: %s'),
f0ff4930
DO
1453 63 => array ('code' => 'success', 'format' => '%u change request(s) have been processed'),
1454 64 => array ('code' => 'success', 'format' => 'Port %s@%s has been assigned to VLAN %u'),
f19c75d6 1455 65 => array ('code' => 'success', 'format' => "Added new rack '%s'"),
03e6ef01 1456 66 => array ('code' => 'success', 'format' => "File sent Ok via handler '%s'"),
abef7149 1457 67 => array ('code' => 'success', 'format' => "Tag rolling done, %u objects involved"),
0c2b7c4a 1458 68 => array ('code' => 'success', 'format' => "Updated rack '%s'"),
7be51fea
DO
1459 69 => array ('code' => 'success', 'format' => 'File "%s" was added successfully'),
1460 70 => array ('code' => 'success', 'format' => 'File "%s" was updated successfully'),
1461 71 => array ('code' => 'success', 'format' => 'File "%s" was linked successfully'),
8bc5d1e4 1462 72 => array ('code' => 'success', 'format' => 'File was unlinked successfully'),
7be51fea
DO
1463 73 => array ('code' => 'success', 'format' => 'File "%s" was deleted successfully'),
1464 74 => array ('code' => 'success', 'format' => 'Row "%s" was added successfully'),
1465 75 => array ('code' => 'success', 'format' => 'Row "%s" was updated successfully'),
1466 76 => array ('code' => 'success', 'format' => 'Object "%s" was deleted successfully'),
1467 77 => array ('code' => 'success', 'format' => 'Row "%s" was deleted successfully'),
1468 78 => array ('code' => 'success', 'format' => 'File "%s" saved Ok'),
1469 79 => array ('code' => 'success', 'format' => 'Rack "%s" was deleted successfully'),
57777e4a 1470 80 => array ('code' => 'success', 'format' => "Added new object '%s'"),
f0ff4930 1471
8628ae44 1472// records 100~199 with fatal error messages
950a1887 1473 100 => array ('code' => 'error', 'format' => '%s'),
ebb5441d
DO
1474 101 => array ('code' => 'error', 'format' => 'Port name cannot be empty'),
1475 102 => array ('code' => 'error', 'format' => "Error creating user account '%s'"),
b82cce3f 1476 103 => array ('code' => 'error', 'format' => 'User not found!'),
ebb5441d 1477 104 => array ('code' => 'error', 'format' => "Error updating user account '%s'"),
79b8ad1e
DO
1478// ...
1479// ...
1480// ...
ebb5441d
DO
1481 108 => array ('code' => 'error', 'format' => '%u failures and %u successfull changes.'),
1482 109 => array ('code' => 'error', 'format' => 'Update failed!'),
1483 110 => array ('code' => 'error', 'format' => 'Supplement failed!'),
1484 111 => array ('code' => 'error', 'format' => 'Reduction failed!'),
1485 112 => array ('code' => 'error', 'format' => 'Error adding chapter.'),
1486 113 => array ('code' => 'error', 'format' => 'Error updating chapter.'),
1487 114 => array ('code' => 'error', 'format' => 'Error deleting chapter.'),
1488 115 => array ('code' => 'error', 'format' => 'Error renaming attribute.'),
1489 116 => array ('code' => 'error', 'format' => 'Error creating attribute.'),
1490 117 => array ('code' => 'error', 'format' => 'Error deleting attribute.'),
1491 118 => array ('code' => 'error', 'format' => 'Supplement failed!'),
1492 119 => array ('code' => 'error', 'format' => 'Reduction failed!'),
1493 120 => array ('code' => 'error', 'format' => 'Reset failed!'),
1494 121 => array ('code' => 'error', 'format' => 'commitUpdateObject() failed'),
1495 122 => array ('code' => 'error', 'format' => 'One or more update(s) failed!'),
1496 123 => array ('code' => 'error', 'format' => 'Cannot process submitted data: unknown format code.'),
1497 124 => array ('code' => 'error', 'format' => 'Error removing reservation!'),
1498 125 => array ('code' => 'error', 'format' => "Update failed with error: '%s'"),
1499 126 => array ('code' => 'error', 'format' => 'addRStoRSPool() failed'),
1500 127 => array ('code' => 'error', 'format' => 'Added %u real servers and encountered %u errors'),
1501 128 => array ('code' => 'error', 'format' => 'commitDeleteRS() failed'),
1502 129 => array ('code' => 'error', 'format' => 'commitDeleteLB() failed'),
1503 130 => array ('code' => 'error', 'format' => 'commitDeleteVS() failed'),
1504 131 => array ('code' => 'error', 'format' => 'invalid format requested'),
1505 132 => array ('code' => 'error', 'format' => 'invalid protocol'),
1506 133 => array ('code' => 'error', 'format' => 'commitUpdateRS() failed'),
1507 134 => array ('code' => 'error', 'format' => 'commitUpdateLB() failed'),
1508 135 => array ('code' => 'error', 'format' => 'commitUpdateVS() failed'),
1509 136 => array ('code' => 'error', 'format' => 'addLBtoRSPool() failed'),
1510 137 => array ('code' => 'error', 'format' => 'addLBtoRSPool() failed'),
1511 138 => array ('code' => 'error', 'format' => 'commitDeleteRSPool() failed'),
1512 139 => array ('code' => 'error', 'format' => 'commitUpdateRSPool() failed'),
1513 140 => array ('code' => 'error', 'format' => 'Encountered %u errors, (de)activated %u real servers'),
1514 141 => array ('code' => 'error', 'format' => 'Encountered %u errors, updated %u IP address(es)'),
1515 142 => array ('code' => 'error', 'format' => 'executeAutoPorts() failed'),
1516 143 => array ('code' => 'error', 'format' => 'Tried chaining %u tags, but experienced %u errors.'),
1517 144 => array ('code' => 'error', 'format' => "Error deleting tag: '%s'"),
1518 145 => array ('code' => 'error', 'format' => "Invalid tag name '%s'"),
590e1281
DO
1519// ...
1520 147 => array ('code' => 'error', 'format' => "Could not create tag '%s': %s"),
1521 148 => array ('code' => 'error', 'format' => "Could not update tag '%s': %s"),
ebb5441d
DO
1522 149 => array ('code' => 'error', 'format' => 'Turing test failed'),
1523 150 => array ('code' => 'error', 'format' => 'Can only change password under DB authentication.'),
1524 151 => array ('code' => 'error', 'format' => 'Old password doesn\'t match.'),
1525 152 => array ('code' => 'error', 'format' => 'New passwords don\'t match.'),
1526 153 => array ('code' => 'error', 'format' => 'Password change failed.'),
1527 154 => array ('code' => 'error', 'format' => "Verification error: %s"),
1528 155 => array ('code' => 'error', 'format' => 'Save failed.'),
1529 156 => array ('code' => 'error', 'format' => 'getSwitchVLANs() failed'),
e81fb764 1530 157 => array ('code' => 'error', 'format' => 'operation not permitted'),
24dcb9d8
DO
1531 158 => array ('code' => 'error', 'format' => 'Ignoring malformed record #%u in form submit'),
1532 159 => array ('code' => 'error', 'format' => 'Permission denied moving port %s from VLAN%u to VLAN%u'),
1533 160 => array ('code' => 'error', 'format' => 'Invalid arguments'),
1534 161 => array ('code' => 'error', 'format' => 'Endpoint not found. Please either set FQDN attribute or assign an IP address to the object.'),
1535 162 => array ('code' => 'error', 'format' => 'More than one IP address is assigned to this object, please configure FQDN attribute.'),
1536 163 => array ('code' => 'error', 'format' => 'Failed to get any response from queryGateway() or the gateway died'),
c030232f 1537 164 => array ('code' => 'error', 'format' => 'Gateway failure: %s.'),
24dcb9d8
DO
1538 165 => array ('code' => 'error', 'format' => 'Gateway failure: malformed reply.'),
1539 166 => array ('code' => 'error', 'format' => 'gw: %s'),
f0ff4930
DO
1540 167 => array ('code' => 'error', 'format' => 'Could not find port %s'),
1541 168 => array ('code' => 'error', 'format' => 'Port %s is a trunk'),
1542 169 => array ('code' => 'error', 'format' => 'Failed to configure %s, connector returned code %u'),
5222f192 1543 170 => array ('code' => 'error', 'format' => 'There is no network for IP address "%s"'),
f19c75d6
DO
1544 171 => array ('code' => 'error', 'format' => "Failed creating rack '%s'. Already exists in this row?"),
1545 172 => array ('code' => 'error', 'format' => 'Malformed request'),
e5c4506d
DO
1546 173 => array ('code' => 'error', 'format' => "Invalid IPv4 prefix '%s'"),
1547 174 => array ('code' => 'error', 'format' => 'Bad IPv4 address'),
1548 175 => array ('code' => 'error', 'format' => 'Invalid netmask'),
1549 176 => array ('code' => 'error', 'format' => 'This network already exists'),
0c2b7c4a 1550 177 => array ('code' => 'error', 'format' => 'commitUpdateRack() failed'),
121496b6 1551 178 => array ('code' => 'error', 'format' => 'file not found'),
70cb9b56
DO
1552 179 => array ('code' => 'error', 'format' => 'Declining outdated text. Re-edit the file for consistency.'),
1553 180 => array ('code' => 'error', 'format' => 'Error saving file, all changes lost!'),
db55cf54
DO
1554 181 => array ('code' => 'error', 'format' => "file uploads not allowed, change 'file_uploads' parameter in php.ini"),
1555 182 => array ('code' => 'error', 'format' => 'SQL query failed: %s'),
c615a655 1556 183 => array ('code' => 'error', 'format' => "Tag id '%s' does not exist."),
57777e4a
DO
1557 184 => array ('code' => 'error', 'format' => 'Submitted form is invalid at line %u'),
1558 185 => array ('code' => 'error', 'format' => "Failed to add object '%s'"),
1559 186 => array ('code' => 'error', 'format' => 'Incomplete form has been ignored. Cheers.'),
9a61c175 1560 187 => array ('code' => 'error', 'format' => "Internal error in function '%s'"),
f0ff4930 1561
8628ae44 1562// records 200~299 with warnings
950a1887 1563 200 => array ('code' => 'warning', 'format' => '%s'),
24dcb9d8
DO
1564 201 => array ('code' => 'warning', 'format' => 'nothing happened...'),
1565 202 => array ('code' => 'warning', 'format' => 'gw: %s'),
f0ff4930
DO
1566 203 => array ('code' => 'warning', 'format' => 'Port %s seems to be the first in VLAN %u at this switch.'),
1567 204 => array ('code' => 'warning', 'format' => 'Check uplink/downlink configuration for proper operation.'),
1568 205 => array ('code' => 'warning', 'format' => '%u change request(s) have been ignored'),
c8187437 1569 206 => array ('code' => 'warning', 'format' => 'Rack is not empty'),
db55cf54 1570 207 => array ('code' => 'warning', 'format' => 'Ignored empty request'),
57777e4a 1571
baf37d01
DO
1572 );
1573 // Handle the arguments. Is there any better way to do it?
1574 foreach ($log['m'] as $record)
1575 {
5222f192
DO
1576 if (!isset ($record['c']) or !isset ($msginfo[$record['c']]))
1577 {
1578 echo '<div class=msg_neutral>(this message was lost)</div>';
1579 continue;
1580 }
baf37d01
DO
1581 if (isset ($record['a']))
1582 switch (count ($record['a']))
1583 {
1584 case 1:
1585 $msgtext = sprintf
1586 (
1587 $msginfo[$record['c']]['format'],
1588 $record['a'][0]
1589 );
1590 break;
1591 case 2:
1592 $msgtext = sprintf
1593 (
1594 $msginfo[$record['c']]['format'],
1595 $record['a'][0],
1596 $record['a'][1]
1597 );
1598 break;
1599 case 3:
1600 $msgtext = sprintf
1601 (
1602 $msginfo[$record['c']]['format'],
1603 $record['a'][0],
1604 $record['a'][1],
1605 $record['a'][2]
1606 );
1607 break;
1608 case 4:
1609 default:
1610 $msgtext = sprintf
1611 (
1612 $msginfo[$record['c']]['format'],
1613 $record['a'][0],
1614 $record['a'][1],
1615 $record['a'][2],
1616 $record['a'][3]
1617 );
1618 break;
1619 }
1620 else
1621 $msgtext = $msginfo[$record['c']]['format'];
1622 echo '<div class=msg_' . $msginfo[$record['c']]['code'] . ">${msgtext}</div>";
1623 }
1624 break;
1625 default:
1626 echo '<div class=msg_error>' . __FUNCTION__ . ': internal error</div>';
1627 break;
1628 }
e673ee24
DO
1629}
1630
1631/*
1632The following conditions must be followed:
16331. We can mount onto free atoms only. This means: if any record for an atom
1634already exists in RackSpace, it can't be used for mounting.
16352. We can't unmount from 'W' atoms. Operator should review appropriate comments
1636and either delete them before unmounting or refuse to unmount the object.
1637*/
1638
1639// We extensively use $_REQUEST in the function.
7e1db771 1640function renderRackSpaceForObject ($object_id)
e673ee24 1641{
e673ee24
DO
1642 $is_update = isset ($_REQUEST['rackmulti'][0]);
1643 $info = getObjectInfo ($object_id);
1644 if ($info == NULL)
1645 {
591ff2c4 1646 showError ('getObjectInfo() failed', __FUNCTION__);
e673ee24
DO
1647 return;
1648 }
1649 // Always process occupied racks plus racks chosen by user. First get racks with
1650 // already allocated rackspace...
f0e2c99f
DO
1651 if (NULL === ($workingRacksData = getResidentRacksData ($object_id)))
1652 die; // some error already shown
e673ee24
DO
1653
1654 // ...and then add those chosen by user (if any).
2135fd83 1655 if (isset($_REQUEST['rackmulti']))
e673ee24
DO
1656 foreach ($_REQUEST['rackmulti'] as $cand_id)
1657 {
1658 if (!isset ($workingRacksData[$cand_id]))
1659 {
61a1d996 1660 if (NULL == ($rackData = spotEntity ('rack', $cand_id)))
e673ee24 1661 {
61a1d996 1662 showError ('Rack not found', __FUNCTION__);
e673ee24
DO
1663 return NULL;
1664 }
61a1d996 1665 amplifyCell ($rackData);
e673ee24
DO
1666 $workingRacksData[$cand_id] = $rackData;
1667 }
1668 }
1669
2135fd83
DY
1670 printOpFormIntro ('updateObjectAllocation');
1671
e673ee24 1672 // Do it only once...
2135fd83
DY
1673 foreach ($workingRacksData as $rackId => &$rackData)
1674 {
e673ee24 1675 applyObjectMountMask ($rackData, $object_id);
2135fd83
DY
1676 echo "<input type=\"hidden\" name=\"rackmulti[]\" value=\"$rackId\">";
1677 }
e673ee24
DO
1678 // Now we workaround an old caveat: http://bugs.php.net/bug.php?id=37410
1679 unset ($rackData);
1680
e673ee24 1681 // This is the time for rendering.
51690ad4 1682
e673ee24
DO
1683 // Main layout starts.
1684 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0><tr>";
1685
1686 // Left portlet with rack list.
1687 echo "<td class=pcleft height='1%'>";
1688 startPortlet ('Racks');
a8efc03e 1689 $allRacksData = listCells ('rack');
4b8d413e
DO
1690 if (count ($allRacksData) <= getConfigVar ('RACK_PRESELECT_THRESHOLD'))
1691 {
61a1d996 1692 foreach ($allRacksData as $rack)
4b8d413e 1693 {
61a1d996
DO
1694 amplifyCell ($rack);
1695 $workingRacksData[$rack_id] = $rack;
4b8d413e
DO
1696 }
1697 foreach ($workingRacksData as &$rackData)
1698 applyObjectMountMask ($rackData, $object_id);
1699 unset ($rackData);
1700 }
1701 renderRackMultiSelect ('rackmulti[]', $allRacksData, array_keys ($workingRacksData));
e673ee24
DO
1702 echo "<br>";
1703 echo "<br>";
1704 finishPortlet();
1705 echo "</td>";
1706
1707 // Middle portlet with comment and submit.
1708 echo "<td class=pcleft>";
1709 startPortlet ('Comment');
1710 echo "<textarea name=comment rows=10 cols=40></textarea><br>\n";
1711 echo "<input type=submit value='Save' name=got_atoms>\n";
1712 echo "<br>";
1713 echo "<br>";
1714 finishPortlet();
1715 echo "</td>";
1716
1717 // Right portlet with rendered racks. If this form submit is not final, we have to
1718 // reflect the former state of the grid in current form.
1719 echo "<td class=pcright rowspan=2 height='1%'>";
1720 startPortlet ('Working copy');
1721 echo '<table border=0 cellspacing=10 align=center><tr>';
1722 foreach ($workingRacksData as $rack_id => $rackData)
1723 {
1724 // Order is important here: only original allocation is highlighted.
1725 highlightObject ($rackData, $object_id);
1726 markupAtomGrid ($rackData, 'T');
1727 // If we have a form processed, discard user input and show new database
1728 // contents.
f0e2c99f 1729 if ($is_update)
e673ee24
DO
1730 mergeGridFormToRack ($rackData);
1731 echo "<td valign=top>";
1732 echo "<center>\n<h2>${rackData['name']}</h2>\n";
1733 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
57c69e9c
AD
1734 echo "<tr><th width='10%'>&nbsp;</th>";
1735 echo "<th width='20%'><a href='javascript:;' onclick=\"toggleColumnOfAtoms('${rack_id}', '0', ${rackData['height']})\">Front</a></th>";
1736 echo "<th width='50%'><a href='javascript:;' onclick=\"toggleColumnOfAtoms('${rack_id}', '1', ${rackData['height']})\">Interior</a></th>";
1737 echo "<th width='20%'><a href='javascript:;' onclick=\"toggleColumnOfAtoms('${rack_id}', '2', ${rackData['height']})\">Back</a></th></tr>\n";
e673ee24 1738 renderAtomGrid ($rackData);
57c69e9c
AD
1739 echo "<tr><th width='10%'>&nbsp;</th>";
1740 echo "<th width='20%'><a href='javascript:;' onclick=\"toggleColumnOfAtoms('${rack_id}', '0', ${rackData['height']})\">Front</a></th>";
1741 echo "<th width='50%'><a href='javascript:;' onclick=\"toggleColumnOfAtoms('${rack_id}', '1', ${rackData['height']})\">Interior</a></th>";
1742 echo "<th width='20%'><a href='javascript:;' onclick=\"toggleColumnOfAtoms('${rack_id}', '2', ${rackData['height']})\">Back</a></th></tr>\n";
e673ee24
DO
1743 echo "</table></center>\n";
1744 echo '</td>';
1745 }
1746 echo "</tr></table>";
1747 finishPortlet();
1748 echo "</td>\n";
1749
2135fd83 1750
e673ee24
DO
1751 echo "</form>\n";
1752 echo "</tr></table>\n";
1753}
1754
1755function renderMolecule ($mdata, $object_id)
1756{
1757 // sort data out
1758 $rackpack = array();
1759 global $loclist;
64b95774 1760 foreach ($mdata as $rua)
e673ee24
DO
1761 {
1762 $rack_id = $rua['rack_id'];
1763 $unit_no = $rua['unit_no'];
1764 $atom = $rua['atom'];
1765 if (!isset ($rackpack[$rack_id]))
1766 {
61a1d996
DO
1767 $rackData = spotEntity ('rack', $rack_id);
1768 amplifyCell ($rackData);
e673ee24
DO
1769 for ($i = $rackData['height']; $i > 0; $i--)
1770 for ($locidx = 0; $locidx < 3; $locidx++)
1771 $rackData[$i][$locidx]['state'] = 'F';
1772 $rackpack[$rack_id] = $rackData;
1773 }
1774 $rackpack[$rack_id][$unit_no][$loclist[$atom]]['state'] = 'T';
1775 $rackpack[$rack_id][$unit_no][$loclist[$atom]]['object_id'] = $object_id;
1776 }
1777 // now we have some racks to render
64b95774 1778 foreach ($rackpack as $rackData)
e673ee24
DO
1779 {
1780 markAllSpans ($rackData);
1781 echo "<table class=molecule cellspacing=0>\n";
1782 echo "<caption>${rackData['name']}</caption>\n";
1783 echo "<tr><th width='10%'>&nbsp;</th><th width='20%'>Front</th><th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
1784 for ($i = $rackData['height']; $i > 0; $i--)
1785 {
1786 echo "<tr><th>$i</th>";
1787 for ($locidx = 0; $locidx < 3; $locidx++)
1788 {
1789 $state = $rackData[$i][$locidx]['state'];
1790 echo "<td class=state_${state}>&nbsp;</td>\n";
1791 }
1792 echo "</tr>\n";
1793 }
1794 echo "</table>\n";
1795 }
1796}
1797
e673ee24
DO
1798function renderEmptyPortsSelect ($port_id, $type_id)
1799{
1800 $ports = getEmptyPortsOfType($type_id);
1801 usort($ports, 'sortEmptyPorts');
1802 foreach ($ports as $port)
1803 {
1804 if ($port_id == $port['Port_id'])
1805 continue;
1806 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";
1807 }
1808}
1809
23cdc7e9 1810function renderDepot ()
e673ee24 1811{
23cdc7e9 1812 global $pageno, $nextorder;
23cdc7e9
DO
1813 $cellfilter = getCellFilter();
1814 $objects = filterCellList (listCells ('object'), $cellfilter['expression']);
1815
1816 echo "<table border=0 class=objectview>\n";
1817 echo "<tr><td class=pcleft>";
1818
1819 startPortlet ('Objects (' . count ($objects) . ')');
1820 if ($objects === NULL)
1821 {
17112e81 1822 showError ('Fatal error retrieving object list', __FUNCTION__);
23cdc7e9
DO
1823 return;
1824 }
1825 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1826 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>Barcode</th><th>Row/Rack</th></tr>';
1827 $order = 'odd';
1828 foreach ($objects as $obj)
e673ee24 1829 {
23cdc7e9
DO
1830 if (isset ($_REQUEST['hl_object_id']) and $_REQUEST['hl_object_id'] == $obj['id'])
1831 $secondclass = 'tdleft port_highlight';
1832 else
1833 $secondclass = 'tdleft';
1834 $tags = loadEntityTags ('object', $obj['id']);
1835 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>";
1836 if (count ($tags))
1837 echo '<br><small>' . serializeTags ($tags, makeHref(array('page'=>$pageno, 'tab'=>'default')) . '&') . '</small>';
1838 echo "</td><td class='${secondclass}'>${obj['label']}</td>";
1839 echo "<td class='${secondclass}'>${obj['asset_no']}</td>";
1840 echo "<td class='${secondclass}'>${obj['barcode']}</td>";
1841 if ($obj['rack_id'])
1842 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>";
1843 else
1844 echo "<td class='${secondclass}'>Unmounted</td>";
1845 echo '</tr>';
1846 $order = $nextorder[$order];
e673ee24 1847 }
23cdc7e9
DO
1848 echo '</table>';
1849 finishPortlet();
1850
1851 echo "</td><td class=pcright width='25%'>";
1852
1853 renderCellFilterPortlet ($cellfilter, 'object');
1854 echo "</td></tr></table>\n";
e673ee24
DO
1855}
1856
1857// History viewer for history-enabled simple dictionaries.
1858function renderHistory ($object_type, $object_id)
1859{
1860 switch ($object_type)
1861 {
1862 case 'row':
aa9a0fb4
DO
1863 $query = "select ctime, user_name, name, comment from RackRowHistory where id = ${object_id} order by ctime";
1864 $header = '<tr><th>change time</th><th>author</th><th>rack row name</th><th>rack row comment</th></tr>';
1865 $extra = 3;
e673ee24
DO
1866 break;
1867 case 'rack':
1868 $query =
aa9a0fb4 1869 "select ctime, user_name, rh.name, rr.name as name, rh.height, rh.comment " .
51690ad4
DY
1870 "from RackHistory as rh left join RackRow as rr on rh.row_id = rr.id " .
1871 "where rh.id = ${object_id} order by ctime";
aa9a0fb4
DO
1872 $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>';
1873 $extra = 5;
e673ee24
DO
1874 break;
1875 case 'object':
1876 $query =
aa9a0fb4 1877 "select ctime, user_name, RackObjectHistory.name as name, label, barcode, asset_no, has_problems, dict_value, comment " .
00f6f1e4
DY
1878 "from RackObjectHistory inner join Dictionary on objtype_id = dict_key join Chapter on Dictionary.chapter_id = Chapter.id " .
1879 "where Chapter.name = 'RackObjectType' and RackObjectHistory.id=${object_id} order by ctime";
aa9a0fb4
DO
1880 $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>';
1881 $extra = 8;
e673ee24
DO
1882 break;
1883 default:
591ff2c4 1884 showError ("Uknown object type '${object_type}'", __FUNCTION__);
e673ee24
DO
1885 return;
1886 }
1887 global $dbxlink;
1888 $result = $dbxlink->query ($query);
1889 if ($result == NULL)
1890 {
591ff2c4 1891 showError ('SQL query failed', __FUNCTION__);
e673ee24
DO
1892 return;
1893 }
1894 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1895 $order = 'odd';
1896 global $nextorder;
1897 echo $header;
1898 while ($row = $result->fetch (PDO::FETCH_NUM))
1899 {
1900 echo "<tr class=row_${order}><td>${row[0]}</td>";
1901 for ($i = 1; $i <= $extra; $i++)
1902 echo "<td>" . $row[$i] . "</td>";
1903 echo "</tr>\n";
1904 $order = $nextorder[$order];
1905 }
1906 echo "</table><br>\n";
1907}
1908
1909function renderRackspaceHistory ()
1910{
4fbb5a00 1911 global $nextorder, $pageno, $tabno;
e673ee24
DO
1912 $order = 'odd';
1913 $history = getRackspaceHistory();
1914 // Show the last operation by default.
1915 if (isset ($_REQUEST['op_id']))
1916 $op_id = $_REQUEST['op_id'];
1917 elseif (isset ($history[0]['mo_id']))
1918 $op_id = $history[0]['mo_id'];
1919 else $op_id = NULL;
1920
1921 $omid = NULL;
1922 $nmid = NULL;
1923 $object_id = 1;
1924 if ($op_id)
1925 list ($omid, $nmid) = getOperationMolecules ($op_id);
1926
1927 // Main layout starts.
1928 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
1929
1930 // Left top portlet with old allocation.
1931 echo "<tr><td class=pcleft>";
1932 startPortlet ('Old allocation');
1933 if ($omid)
1934 {
1935 $oldMolecule = getMolecule ($omid);
1936 renderMolecule ($oldMolecule, $object_id);
1937 }
1938 else
1939 echo "nothing";
1940 finishPortlet();
1941
1942 echo '</td><td class=pcright>';
1943
1944 // Right top portlet with new allocation
1945 startPortlet ('New allocation');
1946 if ($nmid)
1947 {
1948 $newMolecule = getMolecule ($nmid);
1949 renderMolecule ($newMolecule, $object_id);
1950 }
1951 else
1952 echo "nothing";
1953 finishPortlet();
737a3f72 1954
e673ee24 1955 echo '</td></tr><tr><td colspan=2>';
737a3f72 1956
e673ee24
DO
1957 // Bottom portlet with list
1958
1959 startPortlet ('Rackspace allocation history');
1960 echo "<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>\n";
1961 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";
1962 foreach ($history as $row)
1963 {
1964 if ($row['mo_id'] == $op_id)
1965 $class = 'hl';
1966 else
1967 $class = "row_${order}";
4fbb5a00 1968 echo "<tr class=${class}><td><a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno, 'op_id'=>$row['mo_id']))."'>${row['ctime']}</a></td>";
e673ee24
DO
1969 echo "<td>${row['user_name']}</td>";
1970 echo "<td>${row['ro_id']}</td><td>${row['objtype_name']}</td><td>${row['name']}</td><td>${row['comment']}</td>\n";
1971 echo "</tr>\n";
1972 $order = $nextorder[$order];
1973 }
1974 echo "</table>\n";
1975 finishPortlet();
737a3f72 1976
e673ee24 1977 echo '</td></tr></table>';
e673ee24
DO
1978}
1979
d9f8a37a 1980function renderIPv4SpaceRecords ($tree, &$tagcache, $baseurl, $target = 0, $level = 1)
d65353ad
DO
1981{
1982 $self = __FUNCTION__;
1983 foreach ($tree as $item)
1984 {
737a3f72 1985 $total = $item['addrt'];
64347dcf
DO
1986 if (getConfigVar ('IPV4_TREE_SHOW_USAGE') == 'yes')
1987 {
1988 loadIPv4AddrList ($item); // necessary to compute router list and address counter
1989 $used = $item['addrc'];
1990 }
1991 else
1992 {
1993 $item['addrlist'] = array();
1994 $item['addrc'] = 0;
1995 }
0137d53c
DO
1996 if (isset ($item['id']))
1997 {
fec0c8da 1998 if ($item['symbol'] == 'node-collapsed')
d9f8a37a 1999 $expandurl = "${baseurl}&eid=" . $item['id'] . "#netid" . $item['id'];
fec0c8da 2000 elseif ($item['symbol'] == 'node-expanded')
d9f8a37a 2001 $expandurl = $baseurl . ($item['parent_id'] ? "&eid=${item['parent_id']}#netid${item['parent_id']}" : '');
fec0c8da
DO
2002 else
2003 $expandurl = '';
0137d53c 2004 echo "<tr valign=top>";
fec0c8da 2005 printIPv4NetInfoTDs ($item, 'tdleft', $level, $item['symbol'], $expandurl);
0137d53c 2006 echo "<td class=tdcenter>";
d9f8a37a
DO
2007 if ($target == $item['id'])
2008 echo "<a name=netid${target}></a>";
64347dcf
DO
2009 if (getConfigVar ('IPV4_TREE_SHOW_USAGE') == 'yes')
2010 {
2011 renderProgressBar ($total ? $used/$total : 0);
2012 echo "<br><small>${used}/${total}</small>";
2013 }
2014 else
2015 echo "<small>${total}</small>";
2016 echo "</td>";
0137d53c 2017 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
b6b87070 2018 printRoutersTD (findRouters ($item['addrlist']), $tagcache);
0137d53c 2019 echo "</tr>";
fec0c8da 2020 if ($item['symbol'] == 'node-expanded' or $item['symbol'] == 'node-expanded-static')
d9f8a37a 2021 $self ($item['kids'], $tagcache, $baseurl, $target, $level + 1);
0137d53c
DO
2022 }
2023 else
2024 {
0137d53c 2025 echo "<tr valign=top>";
fec0c8da 2026 printIPv4NetInfoTDs ($item, 'tdleft sparenetwork', $level, $item['symbol']);
0137d53c 2027 echo "<td class=tdcenter>";
64347dcf
DO
2028 if (getConfigVar ('IPV4_TREE_SHOW_USAGE') == 'yes')
2029 {
2030 renderProgressBar ($used/$total, 'sparenetwork');
2031 echo "<br><small>${used}/${total}</small>";
2032 }
2033 else
2034 echo "<small>${total}</small>";
2035 echo "</td><td>&nbsp;</td></tr>";
0137d53c 2036 }
d65353ad
DO
2037 }
2038}
2039
04d619d0 2040function renderIPv4Space ()
e673ee24 2041{
4fbb5a00 2042 global $pageno, $tabno;
31c941ec
DO
2043 $cellfilter = getCellFilter();
2044 $netlist = filterCellList (listCells ('ipv4net'), $cellfilter['expression']);
573214e0 2045 array_walk ($netlist, 'amplifyCell');
4fbb5a00 2046
94a40058 2047 $netcount = count ($netlist);
5388794d
DO
2048 // expand request can take either natural values or "ALL". Zero means no expanding.
2049 $eid = isset ($_REQUEST['eid']) ? $_REQUEST['eid'] : 0;
2050 $tree = prepareIPv4Tree ($netlist, $eid);
3630d1fb
DO
2051
2052 echo "<table border=0 class=objectview>\n";
2053 echo "<tr><td class=pcleft>";
94a40058 2054 startPortlet ("networks (${netcount})");
5388794d
DO
2055 echo '<h4>';
2056 if ($eid === 0)
65085888
DO
2057 echo 'auto-collapsing at threshold ' . getConfigVar ('TREE_THRESHOLD') .
2058 " (<a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno, 'eid'=>'ALL')) .
2059 $cellfilter['urlextra'] . "'>expand all</a>)";
5388794d 2060 elseif ($eid === 'ALL')
65085888
DO
2061 echo "expanding all (<a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno)) .
2062 $cellfilter['urlextra'] . "'>auto-collapse</a>)";
5388794d
DO
2063 else
2064 {
d724d290 2065 $netinfo = spotEntity ('ipv4net', $eid);
4fbb5a00 2066 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&nbsp;all</a>)";
5388794d
DO
2067 }
2068 echo "</h4><table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
64347dcf 2069 echo "<tr><th>prefix</th><th>name/tags</th><th>capacity</th>";
f0ed1181 2070 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
57dece2f
DO
2071 echo "<th>routed by</th>";
2072 echo "</tr>\n";
fec0c8da 2073 $tagcache = array();
a8efc03e 2074 $baseurl = makeHref(array('page'=>$pageno, 'tab'=>$tabno)) . $cellfilter['urlextra'];
5388794d 2075 renderIPv4SpaceRecords ($tree, $tagcache, $baseurl, $eid);
e673ee24 2076 echo "</table>\n";
a7fe7729 2077 finishPortlet();
74ccacff 2078 echo '</td><td class=pcright>';
3d670bba 2079 renderCellFilterPortlet ($cellfilter, 'ipv4net');
74ccacff 2080 echo "</td></tr></table>\n";
f973f491 2081}
a7fe7729 2082
f973f491
DO
2083function renderIPv4SLB ()
2084{
4fbb5a00 2085 global $page, $nextorder;
a7fe7729 2086
6fec9f39 2087 startPortlet ('SLB configuration');
b3c50e6c 2088 echo "<table border=0 width='100%'><tr>";
ee437dab 2089 foreach (array ('ipv4vslist', 'ipv4rsplist', 'rservers', 'lbs') as $pno)
4fbb5a00 2090 echo "<td><h3><a href='".makeHref(array('page'=>$pno))."'>" . $page[$pno]['title'] . "</a></h3></td>";
b3c50e6c
DO
2091 echo '</tr></table>';
2092 finishPortlet();
2093
c3bdc503 2094 $summary = getSLBSummary();
6fec9f39 2095 startPortlet ('SLB tactical overview');
4cadac8f
DO
2096 // A single id-keyed array isn't used here to preserve existing
2097 // order of LBs returned by getSLBSummary()
c3bdc503
DO
2098 $lblist = array();
2099 $lbdname = array();
4cadac8f 2100 foreach ($summary as $vipdata)
da04825a 2101 foreach (array_keys ($vipdata['lblist']) as $lb_object_id)
c3bdc503
DO
2102 if (!in_array ($lb_object_id, $lblist))
2103 {
2104 $oi = getObjectInfo ($lb_object_id);
2105 $lbdname[$lb_object_id] = $oi['dname'];
2106 $lblist[] = $lb_object_id;
2107 }
2108 if (!count ($summary))
2109 echo 'none configured';
2110 else
2111 {
80e85ea1 2112 $order = 'odd';
c3bdc503 2113 echo "<table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
b1a970c7 2114 echo "<tr valign=top><td>&nbsp;</td>";
c3bdc503 2115 foreach ($lblist as $lb_object_id)
b1a970c7 2116 {
4fbb5a00 2117 #echo "<th><a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$lb_object_id))."'>" . $lbdname[$lb_object_id] . "</a></th>";
b1a970c7
DO
2118 echo '<td>';
2119 renderLBCell ($lb_object_id);
2120 echo '</td>';
2121 }
c3bdc503 2122 echo "</tr>\n";
4cadac8f
DO
2123 foreach ($summary as $vsid => $vsdata)
2124 {
b1a970c7 2125 echo "<tr class=row_${order}><td class=tdleft>";
6df2025d 2126 renderCell (spotEntity ('ipv4vs', $vsid));
6fec9f39 2127 echo "</td>";
4cadac8f 2128 foreach ($lblist as $lb_object_id)
da04825a 2129 {
60fbcece 2130 echo '<td class=tdleft>';
2b4eee17 2131 if (!isset ($vsdata['lblist'][$lb_object_id]))
da04825a
DO
2132 echo '&nbsp;';
2133 else
6fec9f39
DO
2134 {
2135 echo $vsdata['lblist'][$lb_object_id]['size'];
4fbb5a00 2136// echo " (<a href='".makeHref(array('page'=>'ipv4rspool', 'pool_id'=>$vsdata['lblist'][$lb_object_id]['id'])). "'>";
79a9edb4 2137// echo $vsdata['lblist'][$lb_object_id]['name'] . '</a>)';
6fec9f39 2138 }
da04825a
DO
2139 echo '</td>';
2140 }
2141 echo "</tr>\n";
80e85ea1 2142 $order = $nextorder[$order];
4cadac8f 2143 }
c3bdc503
DO
2144 echo "</table>\n";
2145 }
a7fe7729 2146 finishPortlet ();
e673ee24
DO
2147}
2148
04d619d0 2149function renderIPv4SpaceEditor ()
e673ee24 2150{
a262e150
DO
2151 // IPv4 validator
2152?>
2153 <script type="text/javascript">
2154 function init() {
2155 document.add_new_range.range.setAttribute('match', "^\\d\\d?\\d?\\.\\d\\d?\\d?\\.\\d\\d?\\d?\\.\\d\\d?\\d?\\/\\d\\d?$");
2156
2157 Validate.init();
2158 }
2159 window.onload=init;
2160 </script>
2161<?php
2162
4c0653e2 2163 startPortlet ("Add new");
04d619d0 2164 echo '<table border=0 cellpadding=10 align=center>';
7056988c
DO
2165 // This form requires a name, so JavaScript validator can find it.
2166 // No printOpFormIntro() hence
4fbb5a00 2167 echo "<form method=post name='add_new_range' action='".makeHrefProcess()."'>\n";
42023f03 2168 echo "<input type=hidden name=op value=addIPv4Prefix>\n";
04d619d0
DO
2169 // tags column
2170 echo '<tr><td rowspan=4><h3>assign tags</h3>';
25186565 2171 renderNewEntityTags();
04d619d0
DO
2172 echo '</td>';
2173 // inputs column
2174 echo "<th class=tdright>prefix</th><td class=tdleft><input type=text name='range' size=18 class='live-validate' tabindex=1></td>";
2175 echo "<tr><th class=tdright>name</th><td class=tdleft><input type=text name='name' size='20' tabindex=2></td></tr>";
0c16ef0c 2176 echo "<tr><th class=tdright>connected network</th><td class=tdleft><input type=checkbox name='is_bcast' tabindex=3></td></tr>";
04d619d0 2177 echo "<tr><td colspan=2>";
4c0653e2 2178 printImageHREF ('CREATE', 'Add a new network', TRUE, 4);
04d619d0 2179 echo '</td></tr>';
2a201216 2180 echo "</form></table><br><br>\n";
5c0bb421 2181 finishPortlet();
2a201216 2182
573214e0
DO
2183 $addrspaceList = listCells ('ipv4net');
2184 array_walk ($addrspaceList, 'amplifyCell');
e43a2de4 2185 if (count ($addrspaceList))
e673ee24 2186 {
e43a2de4 2187 startPortlet ('Manage existing (' . count ($addrspaceList) . ')');
04d619d0
DO
2188 echo "<table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
2189 echo "<tr><th>&nbsp;</th><th>prefix</th><th>name</th><th>&nbsp;</th></tr>";
0c16ef0c 2190 foreach ($addrspaceList as $netinfo)
e673ee24 2191 {
0b9c98d7 2192 echo "<form method=post action='".makeHrefProcess(array('op'=>'updIPv4Prefix', 'id'=>$netinfo['id']))."'>";
e43a2de4
DO
2193 echo "<tr valign=top><td>";
2194 if (getConfigVar ('IPV4_JAYWALK') == 'yes')
2195 {
2196 echo "<a href='".makeHrefProcess(array('op'=>'delIPv4Prefix', 'id'=>$netinfo['id']))."'>";
2197 printImageHREF ('destroy', 'Delete this prefix');
2198 echo "</a>";
2199 }
2200 else // only render clickable image for empty networks
2201 {
d724d290 2202 $netdata = spotEntity ('ipv4net', $netinfo['id']);
e43a2de4
DO
2203 loadIPv4AddrList ($netdata);
2204 if (count ($netdata['addrlist']))
2205 printImageHREF ('nodestroy', 'There are ' . count ($netdata['addrlist']) . ' allocations inside');
2206 else
2207 {
2208 echo "<a href='".makeHrefProcess(array('op'=>'delIPv4Prefix', 'id'=>$netinfo['id']))."'>";
2209 printImageHREF ('destroy', 'Delete this prefix');
2210 echo "</a>";
2211 }
2212
2213 }
2214 echo "</td>\n<td class=tdleft>${netinfo['ip']}/${netinfo['mask']}</td>";
0c16ef0c 2215 echo "<td><input type=text name=name size=40 value='${netinfo['name']}'>";
04d619d0
DO
2216 echo "</td><td>";
2217 printImageHREF ('save', 'Save changes', TRUE);
2218 echo "</td></tr></form>\n";
e673ee24 2219 }
04d619d0
DO
2220 echo "</table>";
2221 finishPortlet();
e673ee24 2222 }
e673ee24
DO
2223}
2224
beb9e88a 2225function renderIPv4Network ($id)
e673ee24 2226{
4fbb5a00 2227 global $pageno, $tabno, $aac2;
545478d0
DO
2228 $netmaskbylen = array
2229 (
2230 32 => '255.255.255.255',
2231 31 => '255.255.255.254',
2232 30 => '255.255.255.252',
2233 29 => '255.255.255.248',
2234 28 => '255.255.255.240',
2235 27 => '255.255.255.224',
2236 26 => '255.255.255.192',
2237 25 => '255.255.255.128',
2238 24 => '255.255.255.0',
2239 23 => '255.255.254.0',
2240 22 => '255.255.252.0',
2241 21 => '255.255.248.0',
2242 20 => '255.255.240.0',
2243 19 => '255.255.224.0',
2244 18 => '255.255.192.0',
2245 17 => '255.255.128.0',
2246 16 => '255.255.0.0',
2247 15 => '255.254.0.0',
2248 14 => '255.252.0.0',
2249 13 => '255.248.0.0',
2250 12 => '255.240.0.0',
2251 11 => '255.224.0.0',
2252 10 => '255.192.0.0',
2253 9 => '255.128.0.0',
2254 8 => '255.0.0.0',
2255 7 => '254.0.0.0',
2256 6 => '252.0.0.0',
2257 5 => '248.0.0.0',
2258 4 => '240.0.0.0',
2259 3 => '224.0.0.0',
2260 2 => '192.0.0.0',
2261 1 => '128.0.0.0'
2262 );
2263 $wildcardbylen = array
2264 (
2265 32 => '0.0.0.0',
2266 31 => '0.0.0.1',
2267 30 => '0.0.0.3',
2268 29 => '0.0.0.7',
2269 28 => '0.0.0.15',
2270 27 => '0.0.0.31',
2271 26 => '0.0.0.63',
2272 25 => '0.0.0.127',
2273 24 => '0.0.0.255',
2274 23 => '0.0.1.255',
2275 22 => '0.0.3.255',
2276 21 => '0.0.7.255',
2277 20 => '0.0.15.255',
2278 19 => '0.0.31.255',
2279 18 => '0.0.63.255',
2280 17 => '0.0.127.255',
2281 16 => '0.0.255.25',
2282 15 => '0.1.255.255',
2283 14 => '0.3.255.255',
2284 13 => '0.7.255.255',
2285 12 => '0.15.255.255',
2286 11 => '0.31.255.255',
2287 10 => '0.63.255.255',
2288 9 => '0.127.255.255',
2289 8 => '0.255.255.255',
2290 7 => '1.255.255.255',
2291 6 => '3.255.255.255',
2292 5 => '7.255.255.255',
2293 4 => '15.255.255.255',
2294 3 => '31.255.255.255',
2295 2 => '63.255.255.255',
2296 1 => '127.255.255.255'
2297 );
b901bf1f 2298 $maxperpage = getConfigVar ('IPV4_ADDRS_PER_PAGE');
e673ee24
DO
2299 if (isset($_REQUEST['pg']))
2300 $page = $_REQUEST['pg'];
2301 else
2302 $page=0;
2303
d724d290 2304 $range = spotEntity ('ipv4net', $id);
b6b87070 2305 loadIPv4AddrList ($range);
2034d968
DO
2306 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
2307 echo "<tr><td colspan=2 align=center><h1>${range['ip']}/${range['mask']}</h1><h2>${range['name']}</h2></td></tr>\n";
2308
2309 echo "<tr><td class=pcleft width='50%'>";
2310 startPortlet ('summary');
2311 $total = ($range['ip_bin'] | $range['mask_bin_inv']) - ($range['ip_bin'] & $range['mask_bin']) + 1;
2312 $used = count ($range['addrlist']);
2313 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
04d619d0
DO
2314
2315 echo "<tr><th width='50%' class=tdright>%% used:</th><td class=tdleft>";
2034d968
DO
2316 renderProgressBar ($used/$total);
2317 echo "&nbsp;${used}/${total}</td></tr>\n";
04d619d0 2318
001e61fa
DO
2319 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
2320 {
3444ecf2
DO
2321 // Build a backtrace from all parent networks.
2322 $clen = $range['mask'];
2323 $backtrace = array();
2324 while (NULL !== ($upperid = getIPv4AddressNetworkId ($range['ip'], $clen)))
2325 {
d724d290 2326 $upperinfo = spotEntity ('ipv4net', $upperid);
3444ecf2 2327 $clen = $upperinfo['mask'];
d724d290 2328 $backtrace[] = $upperinfo;
3444ecf2
DO
2329 }
2330 $arrows = count ($backtrace);
d724d290 2331 foreach (array_reverse ($backtrace) as $ainfo)
001e61fa 2332 {
3444ecf2
DO
2333 echo "<tr><th width='50%' class=tdright>";
2334 for ($i = 0; $i < $arrows; $i++)
2335 echo '&uarr;';
2336 $arrows--;
5d3dcb8d 2337 echo "</th><td class=tdleft>";
6df2025d 2338 renderCell ($ainfo);
5d3dcb8d 2339 echo "</td></tr>";
001e61fa 2340 }
3444ecf2 2341 echo "<tr><th width='50%' class=tdright>&rarr;</th>";
5d3dcb8d 2342 echo "<td class=tdleft>";
6df2025d 2343 renderCell ($range);
5d3dcb8d 2344 echo "</td></tr>";
001e61fa
DO
2345 // FIXME: get and display nested networks
2346 // $theitem = pickLeaf ($ipv4tree, $id);
2347 }
2348
545478d0
DO
2349 echo "<tr><th width='50%' class=tdright>Netmask:</th><td class=tdleft>";
2350 echo $netmaskbylen[$range['mask']];
2351 echo "</td></tr>\n";
04d619d0 2352
c607ab55
DO
2353 echo "<tr><th width='50%' class=tdright>Netmask:</th><td class=tdleft>";
2354 printf ('0x%08X', binMaskFromDec ($range['mask']));
2355 echo "</td></tr>\n";
2356
545478d0
DO
2357 echo "<tr><th width='50%' class=tdright>Wildcard bits:</th><td class=tdleft>";
2358 echo $wildcardbylen[$range['mask']];
2359 echo "</td></tr>\n";
04d619d0 2360
f3d0cb20 2361 $routers = findRouters ($range['addrlist']);
f0ed1181 2362 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes' and count ($routers))
04d619d0 2363 {
57dece2f 2364 echo "<tr><th width='50%' class=tdright>Routed by:</th>";
f3d0cb20 2365 printRoutersTD ($routers);
57dece2f 2366 echo "</tr>\n";
04d619d0
DO
2367 }
2368
4fbb5a00 2369 printTagTRs (makeHref(array('page'=>'ipv4space', 'tab'=>'default'))."&");
2034d968
DO
2370 echo "</table><br>\n";
2371 finishPortlet();
e1ae3fb4
AD
2372
2373 renderFilesPortlet ('ipv4net', $id);
2034d968 2374 echo "</td>\n";
e673ee24 2375
2034d968
DO
2376 echo "<td class=pcright>";
2377 startPortlet ('details');
e673ee24
DO
2378 $startip = $range['ip_bin'] & $range['mask_bin'];
2379 $endip = $range['ip_bin'] | $range['mask_bin_inv'];
2380 $realstartip = $startip;
2381 $realendip = $endip;
2382 $numpages = 0;
2383 if($endip - $startip > $maxperpage)
2384 {
e673ee24
DO
2385 $numpages = ($endip - $startip)/$maxperpage;
2386 $startip = $startip + $page * $maxperpage;
2387 $endip = $startip + $maxperpage-1;
2388 }
2389 echo "<center>";
b901bf1f
DO
2390 if ($numpages)
2391 echo '<h3>' . long2ip ($startip) . ' ~ ' . long2ip ($endip) . '</h3>';
e673ee24
DO
2392 for ($i=0; $i<$numpages; $i++)
2393 {
2394 if ($i == $page)
2395 echo "<b>$i</b> ";
2396 else
4fbb5a00 2397 echo "<a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno, 'id'=>$id, 'pg'=>$i))."'>$i</a> ";
e673ee24
DO
2398 }
2399 echo "</center>";
2400
beb9e88a 2401 echo "<table class='widetable' border=0 cellspacing=0 cellpadding=5 align='center' width='100%'>\n";
e673ee24
DO
2402 echo "<tr><th>Address</th><th>Name</th><th>Allocation</th></tr>\n";
2403
2404
b2035dca
DO
2405 for ($ip = $startip; $ip <= $endip; $ip++) :
2406 if (isset ($_REQUEST['hl_ipv4_addr']) and ip2long ($_REQUEST['hl_ipv4_addr']) == $ip)
2407 $secondstyle = 'tdleft port_highlight';
2727c7df 2408 else
b2035dca
DO
2409 $secondstyle = 'tdleft';
2410 if (!isset ($range['addrlist'][$ip]))
e673ee24 2411 {
4fbb5a00 2412 echo "<tr><td class=tdleft><a href='".makeHref(array('page'=>'ipaddress', 'ip'=>ip_long2quad($ip)))."'>" . ip_long2quad($ip);
b2035dca
DO
2413 echo "</a></td><td class='${secondstyle}'>&nbsp;</td><td class='${secondstyle}'>&nbsp;</td></tr>\n";
2414 continue;
2415 }
b2035dca 2416 $addr = $range['addrlist'][$ip];
2d318652 2417 echo "<tr class='${addr['class']}'>";
e673ee24 2418
4fbb5a00 2419 echo "<td class=tdleft><a href='".makeHref(array('page'=>'ipaddress', 'ip'=>$addr['ip']))."'>${addr['ip']}</a></td>";
b2035dca
DO
2420 echo "<td class='${secondstyle}'>${addr['name']}</td><td class='${secondstyle}'>";
2421 $delim = '';
2422 $prologue = '';
2423 if ( $addr['reserved'] == 'yes')
2424 {
2d318652 2425 echo "<strong>RESERVED</strong> ";
b2035dca
DO
2426 $delim = '; ';
2427 }
2d318652 2428 foreach ($range['addrlist'][$ip]['allocs'] as $ref)
b2035dca 2429 {
beb9e88a 2430 echo $delim . $aac2[$ref['type']];
4fbb5a00 2431 echo "<a href='".makeHref(array('page'=>'object', 'object_id'=>$ref['object_id'], 'hl_ipv4_addr'=>$addr['ip']))."'>";
b2035dca
DO
2432 echo $ref['name'] . (empty ($ref['name']) ? '' : '@');
2433 echo "${ref['object_name']}</a>";
2434 $delim = '; ';
2435 }
2436 if ($delim != '')
2437 {
6131056c 2438 $delim = '';
b2035dca
DO
2439 $prologue = '<br>';
2440 }
2d318652 2441 foreach ($range['addrlist'][$ip]['lblist'] as $ref)
b2035dca
DO
2442 {
2443 echo $prologue;
602663f4 2444 $prologue = '';
4fbb5a00
DY
2445 echo "${delim}<a href='".makeHref(array('page'=>'object', 'object_id'=>$ref['object_id']))."'>";
2446 echo "${ref['object_name']}</a>:<a href='".makeHref(array('page'=>'ipv4vs', 'vs_id'=>$ref['vs_id']))."'>";
b2035dca
DO
2447 echo "${ref['vport']}/${ref['proto']}</a>&rarr;";
2448 $delim = '; ';
2449 }
2450 if ($delim != '')
2451 {
2452 $delim = '';
2453 $prologue = '<br>';
e673ee24 2454 }
2d318652 2455 foreach ($range['addrlist'][$ip]['rslist'] as $ref)
b2035dca
DO
2456 {
2457 echo $prologue;
2458 $prologue = '';
4fbb5a00 2459 echo "${delim}&rarr;${ref['rsport']}@<a href='".makeHref(array('page'=>'ipv4rspool', 'pool_id'=>$ref['rspool_id']))."'>";
b2035dca
DO
2460 echo "${ref['rspool_name']}</a>";
2461 $delim = '; ';
2462 }
2463 echo "</td></tr>\n";
2464 endfor;
2727c7df 2465 // end of iteration
e673ee24
DO
2466
2467 echo "</table>";
2034d968
DO
2468 finishPortlet();
2469 echo "</td></tr></table>\n";
e673ee24
DO
2470}
2471
53ef3908 2472function renderIPv4NetworkProperties ($id)
e673ee24 2473{
d724d290 2474 $netdata = spotEntity ('ipv4net', $id);
53ef3908 2475 echo "<center><h1>${netdata['ip']}/${netdata['mask']}</h1></center>\n";
e673ee24 2476 echo "<table border=0 cellpadding=10 cellpadding=1 align='center'>\n";
7056988c 2477 printOpFormIntro ('editRange');
53ef3908
DO
2478 echo "<tr><td class='tdright'>Name:</td><td class='tdleft'><input type=text name=name size=20 value='${netdata['name']}'></tr>";
2479 echo "<tr><td colspan=2 class=tdcenter>";
2480 printImageHREF ('SAVE', 'Save changes', TRUE);
2481 echo "</td></form></tr></table>\n";
e673ee24
DO
2482}
2483
2d318652 2484function renderIPv4Address ($dottedquad)
e673ee24 2485{
4fbb5a00 2486 global $aat;
2d318652 2487 $address = getIPv4Address ($dottedquad);
68225375 2488 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
2d318652
DO
2489 echo "<tr><td colspan=2 align=center><h1>${dottedquad}</h1></td></tr>\n";
2490 if (!empty ($address['name']))
68225375 2491 echo "<tr><td colspan=2 align=center><h2>${address['name']}</h2></td></tr>\n";
e673ee24 2492
68225375
DO
2493 echo "<tr><td class=pcleft>";
2494 startPortlet ('summary');
2495 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
04d619d0 2496 echo "<tr><th width='50%' class=tdright>Allocations:</th><td class=tdleft>" . count ($address['allocs']) . "</td></tr>\n";
68225375
DO
2497 echo "<tr><th width='50%' class=tdright>Originated NAT connections:</th><td class=tdleft>" . count ($address['outpf']) . "</td></tr>\n";
2498 echo "<tr><th width='50%' class=tdright>Arriving NAT connections:</th><td class=tdleft>" . count ($address['inpf']) . "</td></tr>\n";
04d619d0 2499 echo "<tr><th width='50%' class=tdright>SLB virtual services:</th><td class=tdleft>" . count ($address['lblist']) . "</td></tr>\n";
68225375
DO
2500 echo "<tr><th width='50%' class=tdright>SLB real servers:</th><td class=tdleft>" . count ($address['rslist']) . "</td></tr>\n";
2501 printTagTRs();
2502 echo "</table><br>\n";
2503 finishPortlet();
2504 echo "</td>\n";
e673ee24 2505
68225375 2506 echo "<td class=pcright>";
e673ee24 2507
f74d96c6 2508 if (isset ($address['class']))
59bebe2b 2509 {
8e700dd1 2510 startPortlet ('allocations');
2d318652
DO
2511 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
2512 echo "<tr><th>object</th><th>OS interface</th><th>allocation type</th></tr>\n";
2513 $class = $address['class'];
2514 // render all allocation records for this address the same way
59bebe2b 2515 if ($address['reserved'] == 'yes')
2d318652
DO
2516 echo "<tr class='${class}'><td colspan=2>&nbsp;</td><td class=tdleft><strong>RESERVED</strong></td></tr>";
2517 foreach ($address['allocs'] as $bond)
59bebe2b 2518 {
8e700dd1
DO
2519 if (isset ($_REQUEST['hl_object_id']) and $_REQUEST['hl_object_id'] == $bond['object_id'])
2520 $secondclass = 'tdleft port_highlight';
2521 else
2522 $secondclass = 'tdleft';
4fbb5a00 2523 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>";
52c836b1
DO
2524 echo $aat[$bond['type']];
2525 echo "</strong></td></tr>\n";
59bebe2b
DO
2526 }
2527 echo "</table><br><br>";
2528 finishPortlet();
2529 }
e673ee24 2530
f3d0cb20
DO
2531 // FIXME: The returned list is structured differently, than we expect it to be. One of the sides
2532 // must be fixed.
2d318652 2533 if (count ($address['lblist']))
e673ee24 2534 {
2d318652
DO
2535 startPortlet ('Virtual services (' . count ($address['lblist']) . ')');
2536 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
59bebe2b 2537 echo "<tr><th>VS</th><th>name</th></tr>\n";
2d318652 2538 foreach ($address['lblist'] as $vsinfo)
e673ee24 2539 {
4fbb5a00 2540 echo "<tr><td class=tdleft><a href='".makeHref(array('page'=>'ipv4vs', 'vs_id'=>$vsinfo['vs_id']))."'>";
59bebe2b 2541 echo buildVServiceName ($vsinfo) . "</a></td><td class=tdleft>";
5fe1ed76 2542 echo $vsinfo['name'] . "</td></tr>\n";
e673ee24 2543 }
59bebe2b
DO
2544 echo "</table><br><br>";
2545 finishPortlet();
e673ee24 2546 }
5fe1ed76
DO
2547
2548 if (count ($address['rslist']))
2549 {
2550 startPortlet ('Real servers (' . count ($address['rslist']) . ')');
2d318652 2551 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
53f4b619 2552 echo "<tr><th>&nbsp;</th><th>port</th><th>RS pool</th></tr>\n";
5fe1ed76
DO
2553 foreach ($address['rslist'] as $rsinfo)
2554 {
2555 echo "<tr><td>";
2556 if ($rsinfo['inservice'] == 'yes')
2557 printImageHREF ('inservice', 'in service');
2558 else
2559 printImageHREF ('notinservice', 'NOT in service');
4fbb5a00 2560 echo "</td><td class=tdleft>${rsinfo['rsport']}</td><td class=tdleft><a href='".makeHref(array('page'=>'ipv4rspool', 'pool_id'=>$rsinfo['rspool_id']))."'>";
2d318652 2561 echo $rsinfo['rspool_name'] . "</a></td></tr>\n";
5fe1ed76
DO
2562 }
2563 echo "</table><br><br>";
2564 finishPortlet();
2565 }
2566
68225375
DO
2567 if (count ($address['outpf']))
2568 {
105a3bc8 2569 startPortlet ('departing NAT rules');
2d318652 2570 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
105a3bc8
DO
2571 echo "<tr><th>proto</th><th>from</th><th>to</th><th>comment</th></tr>\n";
2572 foreach ($address['outpf'] as $rule)
b62ff880 2573 echo "<tr><td>${rule['proto']}</td><td>${rule['localip']}:${rule['localport']}</td><td>${rule['remoteip']}:${rule['remoteport']}</td><td>${rule['description']}</td></tr>";
105a3bc8 2574 echo "</table>";
68225375
DO
2575 finishPortlet();
2576 }
105a3bc8
DO
2577
2578 if (count ($address['inpf']))
2579 {
2580 startPortlet ('arriving NAT rules');
2d318652 2581 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
105a3bc8
DO
2582 echo "<tr><th>proto</th><th>from</th><th>to</th><th>comment</th></tr>\n";
2583 foreach ($address['inpf'] as $rule)
b62ff880 2584 echo "<tr><td>${rule['proto']}</td><td>${rule['localip']}:${rule['localport']}</td><td>${rule['remoteip']}:${rule['remoteport']}</td><td>${rule['description']}</td></tr>";
105a3bc8
DO
2585 echo "</table>";
2586 finishPortlet();
2587 }
2588
68225375
DO
2589 echo "</td></tr>";
2590 echo "</table>\n";
e673ee24
DO
2591}
2592
2d318652 2593function renderIPv4AddressProperties ($dottedquad)
e673ee24 2594{
2d318652
DO
2595 $address = getIPv4Address ($dottedquad);
2596 echo "<center><h1>$dottedquad</h1></center>\n";
7056988c 2597
1fbc9fd6 2598 startPortlet ('update');
e673ee24 2599 echo "<table border=0 cellpadding=10 cellpadding=1 align='center'>\n";
7056988c 2600 printOpFormIntro ('editAddress');
2d318652
DO
2601 echo "<tr><td class='tdright'>Name:</td><td class='tdleft'><input type=text name=name size=20 value='${address['name']}'></tr>";
2602 echo "<td class='tdright'>Reserved:</td><td class='tdleft'><input type=checkbox name=reserved size=20 ";
2603 echo ($address['reserved']=='yes') ? 'checked' : '';
f3d274bf 2604 echo "></tr><tr><td class=tdleft>";
53ef3908 2605 printImageHREF ('SAVE', 'Save changes', TRUE);
f3d274bf 2606 echo "</td></form><td class=tdright>";
1fbc9fd6 2607 if (empty ($address['name']) and $address['reserved'] == 'no')
f3d274bf
DO
2608 printImageHREF ('CLEAR gray');
2609 else
2610 {
2611 printOpFormIntro ('editAddress', array ('name' => '', 'reserved' => ''));
2612 printImageHREF ('CLEAR', 'Release', TRUE);
2613 echo "</form>";
2614 }
2615 echo "</td></tr></table>\n";
1fbc9fd6 2616 finishPortlet();
e673ee24
DO
2617}
2618
2d318652 2619function renderIPv4AddressAllocations ($dottedquad)
e673ee24 2620{
39b4abd0
DO
2621 function printNewItemTR ()
2622 {
2623 global $aat;
2624 printOpFormIntro ('addIPv4Allocation');
2625 echo "<tr><td>";
9318d2ef 2626 printImageHREF ('add', 'allocate', TRUE);
8d4f7d18 2627 echo "</td><td>";
c6bc0ac5 2628 printSelect (getNarrowObjectList ('IPV4OBJ_LISTSRC'), 'object_id', NULL, 100);
8d4f7d18 2629 echo "</td><td><input type=text tabindex=101 name=bond_name size=10></td><td>";
f5ff50f5 2630 printSelect ($aat, 'bond_type', NULL, 102);
9318d2ef 2631 echo "</td><td>";
f5ff50f5 2632 printImageHREF ('add', 'allocate', TRUE, 103);
9318d2ef 2633 echo "</td></form></tr>";
39b4abd0 2634 }
b82cce3f 2635 global $aat;
e673ee24 2636
2d318652 2637 $address = getIPv4Address ($dottedquad);
f74d96c6 2638
2d318652 2639 echo "<center><h1>${dottedquad}</h1></center>\n";
105a3bc8 2640 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
2d318652 2641 echo "<tr><th>&nbsp;</th><th>object</th><th>OS interface</th><th>allocation type</th><th>&nbsp;</th></tr>\n";
e673ee24 2642
39b4abd0
DO
2643 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
2644 printNewItemTR();
f74d96c6 2645 if (isset ($address['class']))
e673ee24 2646 {
f74d96c6
DO
2647 $class = $address['class'];
2648 if ($address['reserved'] == 'yes')
2649 echo "<tr class='${class}'><td colspan=3>&nbsp;</td><td class=tdleft><strong>RESERVED</strong></td><td>&nbsp;</td></tr>";
2650 foreach ($address['allocs'] as $bond)
2651 {
2652 echo "<tr class='$class'>";
2653 printOpFormIntro ('updIPv4Allocation', array ('object_id' => $bond['object_id']));
4fbb5a00 2654 echo "<td><a href='".makeHrefProcess(array('op'=>'delIPv4Allocation', 'ip'=>$dottedquad, 'object_id'=>$bond['object_id']))."'>";
f74d96c6
DO
2655 printImageHREF ('delete', 'Unallocate address');
2656 echo "</a></td>";
4fbb5a00 2657 echo "<td><a href='".makeHref(array('page'=>'object', 'object_id'=>$bond['object_id'], 'hl_ipv4_addr'=>$dottedquad))."'>${bond['object_name']}</td>";
f74d96c6
DO
2658 echo "<td><input type='text' name='bond_name' value='${bond['name']}' size=10></td><td>";
2659 printSelect ($aat, 'bond_type', $bond['type']);
2660 echo "</td><td>";
2661 printImageHREF ('save', 'Save changes', TRUE);
2662 echo "</td></form></tr>\n";
2663 }
e673ee24 2664 }
39b4abd0
DO
2665 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
2666 printNewItemTR();
e673ee24 2667 echo "</table><br><br>";
e673ee24
DO
2668}
2669
7e1db771 2670function renderNATv4ForObject ($object_id)
e673ee24 2671{
9318d2ef
DO
2672 function printNewItemTR ($alloclist)
2673 {
9318d2ef
DO
2674 printOpFormIntro ('addNATv4Rule');
2675 echo "<tr align='center'><td>";
2676 printImageHREF ('add', 'Add new NAT rule', TRUE);
2677 echo '</td><td>';
2678 printSelect (array ('TCP' => 'TCP', 'UDP' => 'UDP'), 'proto');
2679 echo "<select name='localip' tabindex=1>";
2680
2681 foreach ($alloclist as $dottedquad => $alloc)
2682 {
2683 $name = empty ($alloc['addrinfo']['name']) ? '' : (' (' . niftyString ($alloc['addrinfo']['name']) . ')');
2684 $osif = empty ($alloc['osif']) ? '' : ($alloc['osif'] . ': ');
2685 echo "<option value='${dottedquad}'>${osif}${dottedquad}${name}</option>";
2686 }
2687
2688 echo "</select>:<input type='text' name='localport' size='4' tabindex=2></td>";
2689 echo "<td><input type='text' name='remoteip' id='remoteip' size='10' tabindex=3>";
39106006
DO
2690 echo "<a href='javascript:;' onclick='window.open(\"" . makeHrefForHelper ('inet4list');
2691 echo "\", \"findobjectip\", \"height=700, width=400, location=no, menubar=no, resizable=yes, scrollbars=no, status=no, titlebar=no, toolbar=no\");'>";
9318d2ef
DO
2692 printImageHREF ('find', 'Find object');
2693 echo "</a>";
2694 echo ":<input type='text' name='remoteport' size='4' tabindex=4></td><td></td>";
2695 echo "<td colspan=1><input type='text' name='description' size='20' tabindex=5></td><td>";
f5ff50f5 2696 printImageHREF ('add', 'Add new NAT rule', TRUE, 6);
9318d2ef
DO
2697 echo "</td></tr></form>";
2698 }
e673ee24
DO
2699
2700 $info = getObjectInfo ($object_id);
eeb4a5d8 2701 $forwards = getNATv4ForObject ($object_id);
2c817354 2702 $alloclist = getObjectIPv4Allocations ($object_id);
f28fbe8b 2703 echo "<center><h2>locally performed NAT</h2></center>";
e673ee24 2704
105a3bc8 2705 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
d54b9495 2706 echo "<tr><th></th><th>Match endpoint</th><th>Translate to</th><th>Target object</th><th>Comment</th><th>&nbsp;</th></tr>\n";
e673ee24 2707
9318d2ef
DO
2708 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
2709 printNewItemTR ($alloclist);
e673ee24
DO
2710 foreach ($forwards['out'] as $pf)
2711 {
2c817354
DO
2712 $class = 'trerror';
2713 $osif = '';
2714 if (isset ($alloclist [$pf['localip']]))
2715 {
2716 $class = $alloclist [$pf['localip']]['addrinfo']['class'];
2717 $osif = $alloclist [$pf['localip']]['osif'] . ': ';
2718 }
e673ee24
DO
2719
2720 echo "<tr class='$class'>";
4fbb5a00
DY
2721 echo "<td><a href='".
2722 makeHrefProcess(array(
2723 'op'=>'delNATv4Rule',
2724 'localip'=>$pf['localip'],
2725 'localport'=>$pf['localport'],
2726 'remoteip'=>$pf['remoteip'],
2727 'remoteport'=>$pf['remoteport'],
2728 'proto'=>$pf['proto'],
2729 'object_id'=>$object_id)).
2730 "'>";
4de22e7e
DO
2731 printImageHREF ('delete', 'Delete NAT rule');
2732 echo "</a></td>";
4fbb5a00 2733 echo "<td>${pf['proto']}/${osif}<a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['localip']))."'>${pf['localip']}</a>:${pf['localport']}";
f28fbe8b
DO
2734 if (!empty ($pf['local_addr_name']))
2735 echo ' (' . $pf['local_addr_name'] . ')';
2736 echo "</td>";
4fbb5a00 2737 echo "<td><a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['remoteip']))."'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
e673ee24 2738
53ef3908 2739 $address = getIPv4Address ($pf['remoteip']);
e673ee24
DO
2740
2741 echo "<td class='description'>";
53ef3908
DO
2742 if (count ($address['allocs']))
2743 foreach ($address['allocs'] as $bond)
4fbb5a00 2744 echo "<a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$bond['object_id']))."'>${bond['object_name']}(${bond['name']})</a> ";
f28fbe8b
DO
2745 elseif (!empty ($pf['remote_addr_name']))
2746 echo '(' . $pf['remote_addr_name'] . ')';
7056988c
DO
2747 printOpFormIntro
2748 (
2749 'updNATv4Rule',
2750 array
2751 (
2752 'localip' => $pf['localip'],
2753 'localport' => $pf['localport'],
2754 'remoteip' => $pf['remoteip'],
2755 'remoteport' => $pf['remoteport'],
2756 'proto' => $pf['proto']
2757 )
2758 );
2759 echo "</td><td class='description'>";
d54b9495
DO
2760 echo "<input type='text' name='description' value='${pf['description']}'></td><td>";
2761 printImageHREF ('save', 'Save changes', TRUE);
2762 echo "</td></form></tr>";
e673ee24 2763 }
9318d2ef
DO
2764 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
2765 printNewItemTR ($alloclist);
e673ee24
DO
2766
2767 echo "</table><br><br>";
2768
f28fbe8b 2769 echo "<center><h2>arriving NAT connections</h2></center>";
105a3bc8 2770 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
e673ee24
DO
2771 echo "<tr><th></th><th>Source</th><th>Source objects</th><th>Target</th><th>Description</th></tr>\n";
2772
2773 foreach ($forwards['in'] as $pf)
2774 {
4fbb5a00
DY
2775 echo "<tr><td><a href='".
2776 makeHrefProcess(array(
2777 'op'=>'delNATv4Rule',
2778 'localip'=>$pf['localip'],
2779 'localport'=>$pf['localport'],
2780 'remoteip'=>$pf['remoteip'],
2781 'remoteport'=>$pf['remoteport'],
2782 'proto'=>$pf['proto'],
2783 'object_id'=>$pf['object_id']
2784 )).
2785 "'>";
4de22e7e
DO
2786 printImageHREF ('delete', 'Delete NAT rule');
2787 echo "</a></td>";
4fbb5a00
DY
2788 echo "<td>${pf['proto']}/<a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['localip']))."'>${pf['localip']}</a>:${pf['localport']}</td>";
2789 echo "<td class='description'><a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$pf['object_id']))."'>${pf['object_name']}</a>";
2790 echo "</td><td><a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['remoteip']))."'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
e673ee24
DO
2791 echo "<td class='description'>${pf['description']}</td></tr>";
2792 }
2793
e673ee24 2794 echo "</table><br><br>";
e673ee24
DO
2795}
2796
e673ee24
DO
2797function renderAddMultipleObjectsForm ()
2798{
e673ee24 2799 $typelist = getObjectTypeList();
4c330a14 2800 $typelist[0] = 'select type...';
a1886a78
DO
2801 $max = getConfigVar ('MASSCOUNT');
2802 $tabindex = 100;
7f791d1d 2803
f60bb422 2804 startPortlet ('Distinct types, same tags');
42d73cbf 2805 printOpFormIntro ('addObjects');
e673ee24 2806 echo '<table border=0 align=center>';
f60bb422
DO
2807 echo "<tr><th>Object type</th><th>Common name</th><th>Visible label</th>";
2808 echo "<th>Asset tag</th><th>Barcode</th><th>Tags</th></tr>\n";
9c0b0016 2809 for ($i = 0; $i < $max; $i++)
e673ee24 2810 {
7f791d1d 2811 echo '<tr><td>';
e7ade6bf 2812 // Don't employ DEFAULT_OBJECT_TYPE to avoid creating ghost records for pre-selected empty rows.
a1886a78 2813 printSelect ($typelist, "${i}_object_type_id", 0, $tabindex);
e673ee24 2814 echo '</td>';
a1886a78
DO
2815 echo "<td><input type=text size=30 name=${i}_object_name tabindex=${tabindex}></td>";
2816 echo "<td><input type=text size=30 name=${i}_object_label tabindex=${tabindex}></td>";
2817 echo "<td><input type=text size=20 name=${i}_object_asset_no tabindex=${tabindex}></td>";
2818 echo "<td><input type=text size=10 name=${i}_object_barcode tabindex=${tabindex}></td>";
f60bb422
DO
2819 if ($i == 0)
2820 {
2821 echo "<td valign=top rowspan=${max}>";
25186565 2822 renderNewEntityTags();
f60bb422
DO
2823 echo "</td>\n";
2824 }
e673ee24 2825 echo "</tr>\n";
a1886a78 2826 $tabindex++;
e673ee24 2827 }
216c84bb 2828 echo "<tr><td class=submit colspan=5><input type=submit name=got_fast_data value='Go!'></td></tr>\n";
e673ee24
DO
2829 echo "</form></table>\n";
2830 finishPortlet();
7f791d1d 2831
f60bb422 2832 startPortlet ('Same type, same tags');
42d73cbf 2833 printOpFormIntro ('addLotOfObjects');
f60bb422
DO
2834 echo "<table border=0 align=center><tr><th>names</th><th>type</th></tr>";
2835 echo "<tr><td rowspan=3><textarea name=namelist cols=40 rows=25>\n";
f60bb422
DO
2836 echo "</textarea></td><td valign=top>";
2837 printSelect ($typelist, "global_type_id", getConfigVar ('DEFAULT_OBJECT_TYPE'));
2838 echo "</td></tr>";
2839 echo "<tr><th>Tags</th></tr>";
2840 echo "<tr><td valign=top>";
25186565 2841 renderNewEntityTags();
f60bb422
DO
2842 echo "</td></tr>";
2843 echo "<tr><td colspan=2><input type=submit name=got_very_fast_data value='Go!'></td></tr></table>\n";
2844 echo "</form>\n";
7f791d1d 2845 finishPortlet();
e673ee24
DO
2846}
2847
2848function printGreeting ()
2849{
d6d79c36
DO
2850 global $root, $remote_username, $remote_displayname;
2851 echo "Hello, <a href='${root}?page=myaccount&tab=default'>${remote_displayname}</a>. This is RackTables " .
2852 CODE_VERSION .
2853 ". Click <a href='${root}?logout'>here</a> to logout.";
e673ee24
DO
2854}
2855
2856function renderSearchResults ()
2857{
0b9c98d7 2858 global $root;
e673ee24
DO
2859 $terms = trim ($_REQUEST['q']);
2860 if (empty ($terms))
2861 {
591ff2c4 2862 showError ('Search string cannot be empty.', __FUNCTION__);
e673ee24
DO
2863 return;
2864 }
c78a40ec 2865 if (!permitted ('depot', 'default'))
e673ee24 2866 {
591ff2c4 2867 showError ('You are not authorized for viewing information about objects.', __FUNCTION__);
e673ee24
DO
2868 return;
2869 }
ea5fc465 2870 $nhits = 0;
e673ee24
DO
2871 // If we search for L2 address, we can either find one or find none.
2872 if
2873 (
05771508
DO
2874 preg_match (RE_L2_IFCFG, $terms) or
2875 preg_match (RE_L2_SOLID, $terms) or
2876 preg_match (RE_L2_CISCO, $terms) or
1930dc7f 2877 preg_match (RE_L2_IPCFG, $terms) or
05771508
DO
2878 // Foundry STP bridge ID: bridge priotity + port MAC address. Cut off first 4 chars and look for MAC address.
2879 preg_match (RE_L2_FDRYSTP, $terms)
e673ee24
DO
2880 )
2881 // Search for L2 address.
2882 {
3ec29bf4
DO
2883 $terms = str_replace ('.', '', $terms);
2884 $terms = str_replace (':', '', $terms);
1930dc7f 2885 $terms = str_replace ('-', '', $terms);
ea5fc465 2886 $terms = substr ($terms, -12);
e673ee24
DO
2887 $result = searchByl2address ($terms);
2888 if ($result !== NULL)
2889 {
ea5fc465
DO
2890 $nhits++;
2891 $lasthit = 'port';
2892 $summary['port'][] = $result;
e673ee24 2893 }
e673ee24 2894 }
05771508 2895 elseif (preg_match (RE_IP4_ADDR, $terms))
64347dcf 2896 // Search for IPv4 address.
e673ee24 2897 {
bb0a44e9 2898 if (NULL !== getIPv4AddressNetworkId ($terms))
e673ee24 2899 {
ea5fc465 2900 $nhits++;
f3d0cb20
DO
2901 $lasthit = 'ipv4addressbydq';
2902 $summary['ipv4addressbydq'][] = $terms;
e673ee24 2903 }
e673ee24 2904 }
05771508 2905 elseif (preg_match (RE_IP4_NET, $terms))
64347dcf
DO
2906 // Search for IPv4 network
2907 {
2908 list ($base, $len) = explode ('/', $terms);
2909 if (NULL !== ($tmp = getIPv4AddressNetworkId ($base, $len + 1)))
2910 {
2911 $nhits++;
2912 $lasthit = 'ipv4network';
d724d290 2913 $summary['ipv4network'][] = spotEntity ('ipv4net', $tmp);
64347dcf
DO
2914 }
2915 }
e673ee24 2916 else
ea5fc465 2917 // Search for objects, addresses, networks, virtual services and RS pools by their description.
e673ee24 2918 {
ea5fc465
DO
2919 $tmp = getObjectSearchResults ($terms);
2920 if (count ($tmp))
e673ee24 2921 {
ea5fc465
DO
2922 $nhits += count ($tmp);
2923 $lasthit = 'object';
2924 $summary['object'] = $tmp;
e673ee24 2925 }
ea5fc465
DO
2926 $tmp = getIPv4AddressSearchResult ($terms);
2927 if (count ($tmp))
e673ee24 2928 {
ea5fc465 2929 $nhits += count ($tmp);
f3d0cb20
DO
2930 $lasthit = 'ipv4addressbydescr';
2931 $summary['ipv4addressbydescr'] = $tmp;
ea5fc465
DO
2932 }
2933 $tmp = getIPv4PrefixSearchResult ($terms);
2934 if (count ($tmp))
2935 {
2936 $nhits += count ($tmp);
2937 $lasthit = 'ipv4network';
2938 $summary['ipv4network'] = $tmp;
2939 }
05411ccd
DO
2940 $tmp = getIPv4RSPoolSearchResult ($terms);
2941 if (count ($tmp))
2942 {
2943 $nhits += count ($tmp);
2944 $lasthit = 'ipv4rspool';
2945 $summary['ipv4rspool'] = $tmp;
2946 }
2947 $tmp = getIPv4VServiceSearchResult ($terms);
2948 if (count ($tmp))
2949 {
2950 $nhits += count ($tmp);
2951 $lasthit = 'ipv4vs';
2952 $summary['ipv4vs'] = $tmp;
2953 }
6a88e734
DO
2954 $tmp = getAccountSearchResult ($terms);
2955 if (count ($tmp))
2956 {
2957 $nhits += count ($tmp);
2958 $lasthit = 'user';
2959 $summary['user'] = $tmp;
2960 }
e1ae3fb4
AD
2961 $tmp = getFileSearchResult ($terms);
2962 if (count ($tmp))
2963 {
2964 $nhits += count ($tmp);
2965 $lasthit = 'file';
2966 $summary['file'] = $tmp;
2967 }
e531b4d6
DO
2968 $tmp = getRackSearchResult ($terms);
2969 if (count ($tmp))
2970 {
2971 $nhits += count ($tmp);
2972 $lasthit = 'rack';
2973 $summary['rack'] = $tmp;
2974 }
ea5fc465
DO
2975 }
2976 if ($nhits == 0)
2977 echo "<center><h2>Nothing found for '${terms}'</h2></center>";
2978 elseif ($nhits == 1)
2979 {
2980 $record = current ($summary[$lasthit]);
2981 switch ($lasthit)
2982 {
2983 case 'port':
2984 echo "<script language='Javascript'>document.location='${root}?page=object";
2985 echo "&hl_port_id=" . $record['port_id'];
2986 echo "&object_id=" . $record['object_id'] . "';//</script>";
2987 break;
f3d0cb20
DO
2988 case 'ipv4addressbydq':
2989 $parentnet = getIPv4AddressNetworkId ($record);
2990 if ($parentnet !== NULL)
e1ae3fb4 2991 echo "<script language='Javascript'>document.location='${root}?page=ipv4net&tab=default&id=${parentnet}&hl_ipv4_addr=${record}';//</script>";
f3d0cb20
DO
2992 else
2993 echo "<script language='Javascript'>document.location='${root}?page=ipaddress&ip=${record}';//</script>";
ea5fc465 2994 break;
f3d0cb20
DO
2995 case 'ipv4addressbydescr':
2996 $parentnet = getIPv4AddressNetworkId ($record['ip']);
2997 if ($parentnet !== NULL)
e1ae3fb4 2998 echo "<script language='Javascript'>document.location='${root}?page=ipv4net&tab=default&id=${parentnet}&hl_ipv4_addr=${record['ip']}';//</script>";
f3d0cb20
DO
2999 else
3000 echo "<script language='Javascript'>document.location='${root}?page=ipaddress&ip=${record['ip']}';//</script>";
ea5fc465
DO
3001 break;
3002 case 'ipv4network':
e1ae3fb4 3003 echo "<script language='Javascript'>document.location='${root}?page=ipv4net";
ea5fc465
DO
3004 echo "&id=${record['id']}";
3005 echo "';//</script>";
3006 break;
3007 case 'object':
3008 echo "<script language='Javascript'>document.location='${root}?page=object&object_id=${record['id']}';//</script>";
3009 break;
05411ccd 3010 case 'ipv4rspool':
e1ae3fb4 3011 echo "<script language='Javascript'>document.location='${root}?page=ipv4rspool&pool_id=${record['pool_id']}';//</script>";
05411ccd
DO
3012 break;
3013 case 'ipv4vs':
49fb2686 3014 echo "<script language='Javascript'>document.location='${root}?page=ipv4vs&vs_id=${record['id']}';//</script>";
05411ccd 3015 break;
6a88e734
DO
3016 case 'user':
3017 echo "<script language='Javascript'>document.location='${root}?page=user&user_id=${record['user_id']}';//</script>";
3018 break;
e1ae3fb4
AD
3019 case 'file':
3020 echo "<script language='Javascript'>document.location='${root}?page=file&file_id=${record['id']}';//</script>";
3021 break;
e531b4d6
DO
3022 case 'rack':
3023 echo "<script language='Javascript'>document.location='${root}?page=rack&rack_id=${record['id']}';//</script>";
3024 break;
ea5fc465
DO
3025 }
3026 return;
3027 }
3028 else
3029 {
3030 global $nextorder;
3031 $order = 'odd';
3032 echo "<center><h2>${nhits} result(s) found for '${terms}'</h2></center>";
3033 foreach ($summary as $where => $what)
3034 switch ($where)
e673ee24 3035 {
ea5fc465 3036 case 'object':
c78a40ec 3037 startPortlet ("<a href='${root}?page=depot'>Objects</a>");
ea5fc465 3038 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
e1ae3fb4 3039 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>Barcode</th></tr>';
ea5fc465
DO
3040 foreach ($what as $obj)
3041 {
2c21a10c 3042 $tags = loadEntityTags ('object', $obj['id']);
2b3d64c5
DO
3043 echo "<tr class=row_${order} valign=top><td class=tdleft><a href=\"${root}?page=object&object_id=${obj['id']}\">${obj['dname']}</a>";
3044 if (count ($tags))
3045 echo '<br><small>' . serializeTags ($tags) . '</small>';
3046 echo "</td><td>${obj['label']}</td>";
ea5fc465
DO
3047 echo "<td>${obj['asset_no']}</td>";
3048 echo "<td>${obj['barcode']}</td></tr>";
3049 $order = $nextorder[$order];
3050 }
3051 echo '</table>';
3052 finishPortlet();
3053 break;
3054 case 'ipv4network':
06adfe89 3055 startPortlet ("<a href='${root}?page=ipv4space'>IPv4 networks</a>");
ea5fc465 3056 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
6df2025d 3057 foreach ($what as $cell)
ea5fc465 3058 {
0b9c98d7 3059 echo "<tr class=row_${order} valign=top><td>";
6df2025d 3060 renderCell ($cell);
0b9c98d7 3061 echo "</td></tr>\n";
ea5fc465
DO
3062 $order = $nextorder[$order];
3063 }
3064 echo '</table>';
3065 finishPortlet();
3066 break;
f3d0cb20 3067 case 'ipv4addressbydescr':
ea5fc465
DO
3068 startPortlet ('IPv4 addresses');
3069 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
f3d0cb20 3070 // FIXME: address, parent network, routers (if extended view is enabled)
e1ae3fb4 3071 echo '<tr><th>Address</th><th>Description</th></tr>';
ea5fc465
DO
3072 foreach ($what as $addr)
3073 {
f3d0cb20
DO
3074 echo "<tr class=row_${order}><td class=tdleft>";
3075 $parentnet = getIPv4AddressNetworkId ($addr['ip']);
3076 if ($parentnet !== NULL)
e1ae3fb4 3077 echo "<a href='${root}?page=ipv4net&tab=default&id=${parentnet}&hl_ipv4_addr=${addr['ip']}'>${addr['ip']}</a></td>";
f3d0cb20
DO
3078 else
3079 echo "<a href='${root}?page=ipaddress&ip=${addr['ip']}'>${addr['ip']}</a></td>";
ea5fc465
DO
3080 echo "<td class=tdleft>${addr['name']}</td></tr>";
3081 $order = $nextorder[$order];
3082 }
3083 echo '</table>';
3084 finishPortlet();
3085 break;
05411ccd 3086 case 'ipv4rspool':
ee437dab 3087 startPortlet ("<a href='${root}?page=ipv4rsplist'>RS pools</a>");
05411ccd
DO
3088 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
3089 foreach ($what as $rspool)
3090 {
216136d2
DO
3091 echo "<tr class=row_${order}><td class=tdleft>";
3092 renderRSPoolCell ($rspool['pool_id'], $rspool['name']);
3093 echo "</td></tr>";
05411ccd
DO
3094 $order = $nextorder[$order];
3095 }
3096 echo '</table>';
3097 finishPortlet();
3098 break;
3099 case 'ipv4vs':
a239e016 3100 startPortlet ("<a href='${root}?page=ipv4vslist'>Virtual services</a>");
05411ccd 3101 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
6df2025d 3102 foreach ($what as $cell)
05411ccd 3103 {
8128c257 3104 echo "<tr class=row_${order}><td class=tdleft>";
6df2025d 3105 renderCell ($cell);
8128c257 3106 echo "</td></tr>";
6a88e734
DO
3107 $order = $nextorder[$order];
3108 }
3109 echo '</table>';
3110 finishPortlet();
3111 break;
3112 case 'user':
3113 startPortlet ("<a href='${root}?page=userlist'>Users</a>");
3114 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
6a88e734
DO
3115 foreach ($what as $item)
3116 {
19dac9c3 3117 echo "<tr class=row_${order}><td class=tdleft>";
573214e0 3118 renderCell ($item);
19dac9c3 3119 echo "</td></tr>";
05411ccd
DO
3120 $order = $nextorder[$order];
3121 }
3122 echo '</table>';
3123 finishPortlet();
3124 break;
e1ae3fb4
AD
3125 case 'file':
3126 startPortlet ("<a href='${root}?page=files'>Files</a>");
3127 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
6df2025d 3128 foreach ($what as $cell)
e1ae3fb4 3129 {
35d10b16 3130 echo "<tr class=row_${order}><td class=tdleft>";
6df2025d 3131 renderCell ($cell);
35d10b16 3132 echo "</td></tr>";
e1ae3fb4
AD
3133 $order = $nextorder[$order];
3134 }
3135 echo '</table>';
3136 finishPortlet();
3137 break;
e531b4d6
DO
3138 case 'rack':
3139 startPortlet ("<a href='${root}?page=rackspace'>Racks</a>");
3140 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
3141 foreach ($what as $cell)
3142 {
3143 echo "<tr class=row_${order}><td class=tdleft>";
3144 renderCell ($cell);
3145 echo "</td></tr>";
3146 $order = $nextorder[$order];
3147 }
3148 echo '</table>';
3149 finishPortlet();
3150 break;
e673ee24 3151 }
e673ee24
DO
3152 }
3153}
3154
3155// This function prints a table of checkboxes to aid the user in toggling mount atoms
3156// from one state to another. The first argument is rack data as
61a1d996 3157// produced by amplifyCell(), the second is the value used for the 'unckecked' state
e673ee24
DO
3158// and the third is the value used for 'checked' state.
3159// Usage contexts:
3160// for mounting an object: printAtomGrid ($data, 'F', 'T')
3161// for changing rack design: printAtomGrid ($data, 'A', 'F')
3162// for adding rack problem: printAtomGrid ($data, 'F', 'U')
3163// for adding object problem: printAtomGrid ($data, 'T', 'W')
3164
3165function renderAtomGrid ($data)
3166{
3167 $rack_id = $data['id'];
3168 for ($unit_no = $data['height']; $unit_no > 0; $unit_no--)
3169 {
57c69e9c 3170 echo "<tr><th><a href='javascript:;' onclick=\"toggleRowOfAtoms('${rack_id}','${unit_no}')\">${unit_no}</a></th>";
e673ee24
DO
3171 for ($locidx = 0; $locidx < 3; $locidx++)
3172 {
57c69e9c 3173 $name = "atom_${rack_id}_${unit_no}_${locidx}";
e673ee24
DO
3174 $state = $data[$unit_no][$locidx]['state'];
3175 echo "<td class=state_${state}";
3176 if (isset ($data[$unit_no][$locidx]['hl']))
3177 echo $data[$unit_no][$locidx]['hl'];
3178 echo ">";
3179 if (!($data[$unit_no][$locidx]['enabled'] === TRUE))
57c69e9c 3180 echo "<input type=checkbox id=${name} disabled>";
e673ee24 3181 else
57c69e9c 3182 echo "<input type=checkbox" . $data[$unit_no][$locidx]['checked'] . " name=${name} id=${name}>";
e673ee24
DO
3183 echo '</td>';
3184 }
3185 echo "</tr>\n";
3186 }
3187}
3188
abf18701 3189function renderCellList ($realm = NULL, $title = 'items', $do_amplify = FALSE)
e673ee24 3190{
573214e0
DO
3191 if ($realm === NULL)
3192 {
3193 global $pageno;
3194 $realm = $pageno;
3195 }
3196 global $nextorder;
e673ee24 3197 $order = 'odd';
31c941ec
DO
3198 $cellfilter = getCellFilter();
3199 $celllist = filterCellList (listCells ($realm), $cellfilter['expression']);
8bc5d1e4
DO
3200 if ($do_amplify)
3201 array_walk ($celllist, 'amplifyCell');
abf18701
DO
3202 echo "<table border=0 class=objectview>\n";
3203 echo "<tr><td class=pcleft>";
590e1281 3204 startPortlet ($title . ' (' . count ($celllist) . ')');
abf18701 3205 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
8bc5d1e4 3206 foreach ($celllist as $cell)
e673ee24 3207 {
70198850 3208 echo "<tr class=row_${order}><td>";
573214e0 3209 renderCell ($cell);
70198850 3210 echo "</td></tr>\n";
e673ee24
DO