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