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