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