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