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