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