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