r2698 - renderEditObjectForm(): always include num_attrs in the form, even if it's 0
[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.
7056988c 1688// FIXME: move related code into ophandler
e673ee24
DO
1689function renderRackSpaceForObject ($object_id = 0)
1690{
1691 if ($object_id <= 0)
1692 {
591ff2c4 1693 showError ('Invalid object_id', __FUNCTION__);
e673ee24
DO
1694 return;
1695 }
1696 $is_submit = isset ($_REQUEST['got_atoms']);
1697 $is_update = isset ($_REQUEST['rackmulti'][0]);
1698 $info = getObjectInfo ($object_id);
1699 if ($info == NULL)
1700 {
591ff2c4 1701 showError ('getObjectInfo() failed', __FUNCTION__);
e673ee24
DO
1702 return;
1703 }
1704 // Always process occupied racks plus racks chosen by user. First get racks with
1705 // already allocated rackspace...
1706 $workingRacksData = getResidentRacksData ($object_id);
1707 if ($workingRacksData === NULL)
1708 {
1709 print_r ($workingRacksData);
591ff2c4 1710 showError ('getResidentRacksData() failed', __FUNCTION__);
e673ee24
DO
1711 return;
1712 }
1713
1714 // ...and then add those chosen by user (if any).
2135fd83 1715 if (isset($_REQUEST['rackmulti']))
e673ee24
DO
1716 foreach ($_REQUEST['rackmulti'] as $cand_id)
1717 {
1718 if (!isset ($workingRacksData[$cand_id]))
1719 {
1720 $rackData = getRackData ($cand_id);
1721 if ($rackData == NULL)
1722 {
591ff2c4 1723 showError ('getRackData() failed', __FUNCTION__);
e673ee24
DO
1724 return NULL;
1725 }
1726 $workingRacksData[$cand_id] = $rackData;
1727 }
1728 }
1729
2135fd83
DY
1730 printOpFormIntro ('updateObjectAllocation');
1731
e673ee24 1732 // Do it only once...
2135fd83
DY
1733 foreach ($workingRacksData as $rackId => &$rackData)
1734 {
e673ee24 1735 applyObjectMountMask ($rackData, $object_id);
2135fd83
DY
1736 echo "<input type=\"hidden\" name=\"rackmulti[]\" value=\"$rackId\">";
1737 }
e673ee24
DO
1738 // Now we workaround an old caveat: http://bugs.php.net/bug.php?id=37410
1739 unset ($rackData);
1740
e673ee24 1741 // This is the time for rendering.
51690ad4
DY
1742 showMessageOrError();
1743
e673ee24
DO
1744 // Main layout starts.
1745 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0><tr>";
1746
1747 // Left portlet with rack list.
1748 echo "<td class=pcleft height='1%'>";
1749 startPortlet ('Racks');
a8efc03e 1750 $allRacksData = listCells ('rack');
4b8d413e
DO
1751 if (count ($allRacksData) <= getConfigVar ('RACK_PRESELECT_THRESHOLD'))
1752 {
1753 foreach (array_keys ($allRacksData) as $rack_id)
1754 {
1755 $rackData = getRackData ($rack_id);
1756 if ($rackData == NULL)
1757 {
1758 showError ('getRackData() failed', __FUNCTION__);
1759 return NULL;
1760 }
1761 $workingRacksData[$rack_id] = $rackData;
1762 }
1763 foreach ($workingRacksData as &$rackData)
1764 applyObjectMountMask ($rackData, $object_id);
1765 unset ($rackData);
1766 }
1767 renderRackMultiSelect ('rackmulti[]', $allRacksData, array_keys ($workingRacksData));
e673ee24
DO
1768 echo "<br>";
1769 echo "<br>";
1770 finishPortlet();
1771 echo "</td>";
1772
1773 // Middle portlet with comment and submit.
1774 echo "<td class=pcleft>";
1775 startPortlet ('Comment');
1776 echo "<textarea name=comment rows=10 cols=40></textarea><br>\n";
1777 echo "<input type=submit value='Save' name=got_atoms>\n";
1778 echo "<br>";
1779 echo "<br>";
1780 finishPortlet();
1781 echo "</td>";
1782
1783 // Right portlet with rendered racks. If this form submit is not final, we have to
1784 // reflect the former state of the grid in current form.
1785 echo "<td class=pcright rowspan=2 height='1%'>";
1786 startPortlet ('Working copy');
1787 echo '<table border=0 cellspacing=10 align=center><tr>';
1788 foreach ($workingRacksData as $rack_id => $rackData)
1789 {
1790 // Order is important here: only original allocation is highlighted.
1791 highlightObject ($rackData, $object_id);
1792 markupAtomGrid ($rackData, 'T');
1793 // If we have a form processed, discard user input and show new database
1794 // contents.
1795 if (!$is_submit and $is_update)
1796 mergeGridFormToRack ($rackData);
1797 echo "<td valign=top>";
1798 echo "<center>\n<h2>${rackData['name']}</h2>\n";
1799 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
57c69e9c
AD
1800 echo "<tr><th width='10%'>&nbsp;</th>";
1801 echo "<th width='20%'><a href='javascript:;' onclick=\"toggleColumnOfAtoms('${rack_id}', '0', ${rackData['height']})\">Front</a></th>";
1802 echo "<th width='50%'><a href='javascript:;' onclick=\"toggleColumnOfAtoms('${rack_id}', '1', ${rackData['height']})\">Interior</a></th>";
1803 echo "<th width='20%'><a href='javascript:;' onclick=\"toggleColumnOfAtoms('${rack_id}', '2', ${rackData['height']})\">Back</a></th></tr>\n";
e673ee24 1804 renderAtomGrid ($rackData);
57c69e9c
AD
1805 echo "<tr><th width='10%'>&nbsp;</th>";
1806 echo "<th width='20%'><a href='javascript:;' onclick=\"toggleColumnOfAtoms('${rack_id}', '0', ${rackData['height']})\">Front</a></th>";
1807 echo "<th width='50%'><a href='javascript:;' onclick=\"toggleColumnOfAtoms('${rack_id}', '1', ${rackData['height']})\">Interior</a></th>";
1808 echo "<th width='20%'><a href='javascript:;' onclick=\"toggleColumnOfAtoms('${rack_id}', '2', ${rackData['height']})\">Back</a></th></tr>\n";
e673ee24
DO
1809 echo "</table></center>\n";
1810 echo '</td>';
1811 }
1812 echo "</tr></table>";
1813 finishPortlet();
1814 echo "</td>\n";
1815
2135fd83 1816
e673ee24
DO
1817 echo "</form>\n";
1818 echo "</tr></table>\n";
1819}
1820
1821function renderMolecule ($mdata, $object_id)
1822{
1823 // sort data out
1824 $rackpack = array();
1825 global $loclist;
64b95774 1826 foreach ($mdata as $rua)
e673ee24
DO
1827 {
1828 $rack_id = $rua['rack_id'];
1829 $unit_no = $rua['unit_no'];
1830 $atom = $rua['atom'];
1831 if (!isset ($rackpack[$rack_id]))
1832 {
1833 $rackData = getRackData ($rack_id);
1834 for ($i = $rackData['height']; $i > 0; $i--)
1835 for ($locidx = 0; $locidx < 3; $locidx++)
1836 $rackData[$i][$locidx]['state'] = 'F';
1837 $rackpack[$rack_id] = $rackData;
1838 }
1839 $rackpack[$rack_id][$unit_no][$loclist[$atom]]['state'] = 'T';
1840 $rackpack[$rack_id][$unit_no][$loclist[$atom]]['object_id'] = $object_id;
1841 }
1842 // now we have some racks to render
64b95774 1843 foreach ($rackpack as $rackData)
e673ee24
DO
1844 {
1845 markAllSpans ($rackData);
1846 echo "<table class=molecule cellspacing=0>\n";
1847 echo "<caption>${rackData['name']}</caption>\n";
1848 echo "<tr><th width='10%'>&nbsp;</th><th width='20%'>Front</th><th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
1849 for ($i = $rackData['height']; $i > 0; $i--)
1850 {
1851 echo "<tr><th>$i</th>";
1852 for ($locidx = 0; $locidx < 3; $locidx++)
1853 {
1854 $state = $rackData[$i][$locidx]['state'];
1855 echo "<td class=state_${state}>&nbsp;</td>\n";
1856 }
1857 echo "</tr>\n";
1858 }
1859 echo "</table>\n";
1860 }
1861}
1862
e673ee24
DO
1863function renderEmptyPortsSelect ($port_id, $type_id)
1864{
1865 $ports = getEmptyPortsOfType($type_id);
1866 usort($ports, 'sortEmptyPorts');
1867 foreach ($ports as $port)
1868 {
1869 if ($port_id == $port['Port_id'])
1870 continue;
1871 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";
1872 }
1873}
1874
23cdc7e9 1875function renderDepot ()
e673ee24 1876{
23cdc7e9
DO
1877 global $pageno, $nextorder;
1878 showMessageOrError();
1879 $cellfilter = getCellFilter();
1880 $objects = filterCellList (listCells ('object'), $cellfilter['expression']);
1881
1882 echo "<table border=0 class=objectview>\n";
1883 echo "<tr><td class=pcleft>";
1884
1885 startPortlet ('Objects (' . count ($objects) . ')');
1886 if ($objects === NULL)
1887 {
17112e81 1888 showError ('Fatal error retrieving object list', __FUNCTION__);
23cdc7e9
DO
1889 return;
1890 }
1891 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1892 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>Barcode</th><th>Row/Rack</th></tr>';
1893 $order = 'odd';
1894 foreach ($objects as $obj)
e673ee24 1895 {
23cdc7e9
DO
1896 if (isset ($_REQUEST['hl_object_id']) and $_REQUEST['hl_object_id'] == $obj['id'])
1897 $secondclass = 'tdleft port_highlight';
1898 else
1899 $secondclass = 'tdleft';
1900 $tags = loadEntityTags ('object', $obj['id']);
1901 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>";
1902 if (count ($tags))
1903 echo '<br><small>' . serializeTags ($tags, makeHref(array('page'=>$pageno, 'tab'=>'default')) . '&') . '</small>';
1904 echo "</td><td class='${secondclass}'>${obj['label']}</td>";
1905 echo "<td class='${secondclass}'>${obj['asset_no']}</td>";
1906 echo "<td class='${secondclass}'>${obj['barcode']}</td>";
1907 if ($obj['rack_id'])
1908 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>";
1909 else
1910 echo "<td class='${secondclass}'>Unmounted</td>";
1911 echo '</tr>';
1912 $order = $nextorder[$order];
e673ee24 1913 }
23cdc7e9
DO
1914 echo '</table>';
1915 finishPortlet();
1916
1917 echo "</td><td class=pcright width='25%'>";
1918
1919 renderCellFilterPortlet ($cellfilter, 'object');
1920 echo "</td></tr></table>\n";
e673ee24
DO
1921}
1922
1923// History viewer for history-enabled simple dictionaries.
1924function renderHistory ($object_type, $object_id)
1925{
1926 switch ($object_type)
1927 {
1928 case 'row':
1929 $query = "select ctime, user_name, name, deleted, comment from RackRowHistory where id = ${object_id} order by ctime";
1930 $header = '<tr><th>change time</th><th>author</th><th>rack row name</th><th>is deleted?</th><th>rack row comment</th></tr>';
1931 $extra = 4;
1932 break;
1933 case 'rack':
1934 $query =
51690ad4
DY
1935 "select ctime, user_name, rh.name, rh.deleted, rr.name as name, rh.height, rh.comment " .
1936 "from RackHistory as rh left join RackRow as rr on rh.row_id = rr.id " .
1937 "where rh.id = ${object_id} order by ctime";
e673ee24
DO
1938 $header = '<tr><th>change time</th><th>author</th><th>rack name</th><th>is deleted?</th><th>rack row name</th><th>rack height</th><th>rack comment</th></tr>';
1939 $extra = 6;
1940 break;
1941 case 'object':
1942 $query =
f76c4197 1943 "select ctime, user_name, RackObjectHistory.name as name, label, barcode, asset_no, deleted, has_problems, dict_value, comment " .
00f6f1e4
DY
1944 "from RackObjectHistory inner join Dictionary on objtype_id = dict_key join Chapter on Dictionary.chapter_id = Chapter.id " .
1945 "where Chapter.name = 'RackObjectType' and RackObjectHistory.id=${object_id} order by ctime";
f76c4197 1946 $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>is deleted?</th><th>has problems?</th><th>object type</th><th>comment</th></tr>';
e673ee24
DO
1947 $extra = 9;
1948 break;
1949 default:
591ff2c4 1950 showError ("Uknown object type '${object_type}'", __FUNCTION__);
e673ee24
DO
1951 return;
1952 }
1953 global $dbxlink;
1954 $result = $dbxlink->query ($query);
1955 if ($result == NULL)
1956 {
591ff2c4 1957 showError ('SQL query failed', __FUNCTION__);
e673ee24
DO
1958 return;
1959 }
1960 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1961 $order = 'odd';
1962 global $nextorder;
1963 echo $header;
1964 while ($row = $result->fetch (PDO::FETCH_NUM))
1965 {
1966 echo "<tr class=row_${order}><td>${row[0]}</td>";
1967 for ($i = 1; $i <= $extra; $i++)
1968 echo "<td>" . $row[$i] . "</td>";
1969 echo "</tr>\n";
1970 $order = $nextorder[$order];
1971 }
1972 echo "</table><br>\n";
1973}
1974
1975function renderRackspaceHistory ()
1976{
4fbb5a00 1977 global $nextorder, $pageno, $tabno;
e673ee24
DO
1978 $order = 'odd';
1979 $history = getRackspaceHistory();
1980 // Show the last operation by default.
1981 if (isset ($_REQUEST['op_id']))
1982 $op_id = $_REQUEST['op_id'];
1983 elseif (isset ($history[0]['mo_id']))
1984 $op_id = $history[0]['mo_id'];
1985 else $op_id = NULL;
1986
1987 $omid = NULL;
1988 $nmid = NULL;
1989 $object_id = 1;
1990 if ($op_id)
1991 list ($omid, $nmid) = getOperationMolecules ($op_id);
1992
1993 // Main layout starts.
1994 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
1995
1996 // Left top portlet with old allocation.
1997 echo "<tr><td class=pcleft>";
1998 startPortlet ('Old allocation');
1999 if ($omid)
2000 {
2001 $oldMolecule = getMolecule ($omid);
2002 renderMolecule ($oldMolecule, $object_id);
2003 }
2004 else
2005 echo "nothing";
2006 finishPortlet();
2007
2008 echo '</td><td class=pcright>';
2009
2010 // Right top portlet with new allocation
2011 startPortlet ('New allocation');
2012 if ($nmid)
2013 {
2014 $newMolecule = getMolecule ($nmid);
2015 renderMolecule ($newMolecule, $object_id);
2016 }
2017 else
2018 echo "nothing";
2019 finishPortlet();
737a3f72 2020
e673ee24 2021 echo '</td></tr><tr><td colspan=2>';
737a3f72 2022
e673ee24
DO
2023 // Bottom portlet with list
2024
2025 startPortlet ('Rackspace allocation history');
2026 echo "<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>\n";
2027 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";
2028 foreach ($history as $row)
2029 {
2030 if ($row['mo_id'] == $op_id)
2031 $class = 'hl';
2032 else
2033 $class = "row_${order}";
4fbb5a00 2034 echo "<tr class=${class}><td><a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno, 'op_id'=>$row['mo_id']))."'>${row['ctime']}</a></td>";
e673ee24
DO
2035 echo "<td>${row['user_name']}</td>";
2036 echo "<td>${row['ro_id']}</td><td>${row['objtype_name']}</td><td>${row['name']}</td><td>${row['comment']}</td>\n";
2037 echo "</tr>\n";
2038 $order = $nextorder[$order];
2039 }
2040 echo "</table>\n";
2041 finishPortlet();
737a3f72 2042
e673ee24 2043 echo '</td></tr></table>';
e673ee24
DO
2044}
2045
d9f8a37a 2046function renderIPv4SpaceRecords ($tree, &$tagcache, $baseurl, $target = 0, $level = 1)
d65353ad
DO
2047{
2048 $self = __FUNCTION__;
2049 foreach ($tree as $item)
2050 {
737a3f72 2051 $total = $item['addrt'];
64347dcf
DO
2052 if (getConfigVar ('IPV4_TREE_SHOW_USAGE') == 'yes')
2053 {
2054 loadIPv4AddrList ($item); // necessary to compute router list and address counter
2055 $used = $item['addrc'];
2056 }
2057 else
2058 {
2059 $item['addrlist'] = array();
2060 $item['addrc'] = 0;
2061 }
0137d53c
DO
2062 if (isset ($item['id']))
2063 {
fec0c8da 2064 if ($item['symbol'] == 'node-collapsed')
d9f8a37a 2065 $expandurl = "${baseurl}&eid=" . $item['id'] . "#netid" . $item['id'];
fec0c8da 2066 elseif ($item['symbol'] == 'node-expanded')
d9f8a37a 2067 $expandurl = $baseurl . ($item['parent_id'] ? "&eid=${item['parent_id']}#netid${item['parent_id']}" : '');
fec0c8da
DO
2068 else
2069 $expandurl = '';
0137d53c 2070 echo "<tr valign=top>";
fec0c8da 2071 printIPv4NetInfoTDs ($item, 'tdleft', $level, $item['symbol'], $expandurl);
0137d53c 2072 echo "<td class=tdcenter>";
d9f8a37a
DO
2073 if ($target == $item['id'])
2074 echo "<a name=netid${target}></a>";
64347dcf
DO
2075 if (getConfigVar ('IPV4_TREE_SHOW_USAGE') == 'yes')
2076 {
2077 renderProgressBar ($total ? $used/$total : 0);
2078 echo "<br><small>${used}/${total}</small>";
2079 }
2080 else
2081 echo "<small>${total}</small>";
2082 echo "</td>";
0137d53c 2083 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
b6b87070 2084 printRoutersTD (findRouters ($item['addrlist']), $tagcache);
0137d53c 2085 echo "</tr>";
fec0c8da 2086 if ($item['symbol'] == 'node-expanded' or $item['symbol'] == 'node-expanded-static')
d9f8a37a 2087 $self ($item['kids'], $tagcache, $baseurl, $target, $level + 1);
0137d53c
DO
2088 }
2089 else
2090 {
0137d53c 2091 echo "<tr valign=top>";
fec0c8da 2092 printIPv4NetInfoTDs ($item, 'tdleft sparenetwork', $level, $item['symbol']);
0137d53c 2093 echo "<td class=tdcenter>";
64347dcf
DO
2094 if (getConfigVar ('IPV4_TREE_SHOW_USAGE') == 'yes')
2095 {
2096 renderProgressBar ($used/$total, 'sparenetwork');
2097 echo "<br><small>${used}/${total}</small>";
2098 }
2099 else
2100 echo "<small>${total}</small>";
2101 echo "</td><td>&nbsp;</td></tr>";
0137d53c 2102 }
d65353ad
DO
2103 }
2104}
2105
04d619d0 2106function renderIPv4Space ()
e673ee24 2107{
4fbb5a00 2108 global $pageno, $tabno;
31c941ec
DO
2109 $cellfilter = getCellFilter();
2110 $netlist = filterCellList (listCells ('ipv4net'), $cellfilter['expression']);
573214e0 2111 array_walk ($netlist, 'amplifyCell');
4fbb5a00 2112
94a40058 2113 $netcount = count ($netlist);
5388794d
DO
2114 // expand request can take either natural values or "ALL". Zero means no expanding.
2115 $eid = isset ($_REQUEST['eid']) ? $_REQUEST['eid'] : 0;
2116 $tree = prepareIPv4Tree ($netlist, $eid);
3630d1fb
DO
2117
2118 echo "<table border=0 class=objectview>\n";
2119 echo "<tr><td class=pcleft>";
94a40058 2120 startPortlet ("networks (${netcount})");
5388794d
DO
2121 echo '<h4>';
2122 if ($eid === 0)
4fbb5a00 2123 echo 'auto-collapsing at threshold ' . getConfigVar ('TREE_THRESHOLD') . " (<a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno, 'eid'=>'ALL'))."'>expand all</a>)";
5388794d 2124 elseif ($eid === 'ALL')
4fbb5a00 2125 echo "expanding all (<a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno))."'>auto-collapse</a>)";
5388794d
DO
2126 else
2127 {
2128 $netinfo = getIPv4NetworkInfo ($eid);
4fbb5a00 2129 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
2130 }
2131 echo "</h4><table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
64347dcf 2132 echo "<tr><th>prefix</th><th>name/tags</th><th>capacity</th>";
f0ed1181 2133 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
57dece2f
DO
2134 echo "<th>routed by</th>";
2135 echo "</tr>\n";
fec0c8da 2136 $tagcache = array();
a8efc03e 2137 $baseurl = makeHref(array('page'=>$pageno, 'tab'=>$tabno)) . $cellfilter['urlextra'];
5388794d 2138 renderIPv4SpaceRecords ($tree, $tagcache, $baseurl, $eid);
e673ee24 2139 echo "</table>\n";
a7fe7729 2140 finishPortlet();
74ccacff 2141 echo '</td><td class=pcright>';
3d670bba 2142 renderCellFilterPortlet ($cellfilter, 'ipv4net');
74ccacff 2143 echo "</td></tr></table>\n";
f973f491 2144}
a7fe7729 2145
f973f491
DO
2146function renderIPv4SLB ()
2147{
4fbb5a00 2148 global $page, $nextorder;
a7fe7729 2149
6fec9f39 2150 startPortlet ('SLB configuration');
b3c50e6c 2151 echo "<table border=0 width='100%'><tr>";
ee437dab 2152 foreach (array ('ipv4vslist', 'ipv4rsplist', 'rservers', 'lbs') as $pno)
4fbb5a00 2153 echo "<td><h3><a href='".makeHref(array('page'=>$pno))."'>" . $page[$pno]['title'] . "</a></h3></td>";
b3c50e6c
DO
2154 echo '</tr></table>';
2155 finishPortlet();
2156
c3bdc503 2157 $summary = getSLBSummary();
6fec9f39 2158 startPortlet ('SLB tactical overview');
4cadac8f
DO
2159 // A single id-keyed array isn't used here to preserve existing
2160 // order of LBs returned by getSLBSummary()
c3bdc503
DO
2161 $lblist = array();
2162 $lbdname = array();
4cadac8f 2163 foreach ($summary as $vipdata)
da04825a 2164 foreach (array_keys ($vipdata['lblist']) as $lb_object_id)
c3bdc503
DO
2165 if (!in_array ($lb_object_id, $lblist))
2166 {
2167 $oi = getObjectInfo ($lb_object_id);
2168 $lbdname[$lb_object_id] = $oi['dname'];
2169 $lblist[] = $lb_object_id;
2170 }
2171 if (!count ($summary))
2172 echo 'none configured';
2173 else
2174 {
80e85ea1 2175 $order = 'odd';
c3bdc503 2176 echo "<table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
b1a970c7 2177 echo "<tr valign=top><td>&nbsp;</td>";
c3bdc503 2178 foreach ($lblist as $lb_object_id)
b1a970c7 2179 {
4fbb5a00 2180 #echo "<th><a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$lb_object_id))."'>" . $lbdname[$lb_object_id] . "</a></th>";
b1a970c7
DO
2181 echo '<td>';
2182 renderLBCell ($lb_object_id);
2183 echo '</td>';
2184 }
c3bdc503 2185 echo "</tr>\n";
4cadac8f
DO
2186 foreach ($summary as $vsid => $vsdata)
2187 {
b1a970c7
DO
2188 echo "<tr class=row_${order}><td class=tdleft>";
2189 renderVSCell ($vsid);
6fec9f39 2190 echo "</td>";
4cadac8f 2191 foreach ($lblist as $lb_object_id)
da04825a 2192 {
60fbcece 2193 echo '<td class=tdleft>';
2b4eee17 2194 if (!isset ($vsdata['lblist'][$lb_object_id]))
da04825a
DO
2195 echo '&nbsp;';
2196 else
6fec9f39
DO
2197 {
2198 echo $vsdata['lblist'][$lb_object_id]['size'];
4fbb5a00 2199// echo " (<a href='".makeHref(array('page'=>'ipv4rspool', 'pool_id'=>$vsdata['lblist'][$lb_object_id]['id'])). "'>";
79a9edb4 2200// echo $vsdata['lblist'][$lb_object_id]['name'] . '</a>)';
6fec9f39 2201 }
da04825a
DO
2202 echo '</td>';
2203 }
2204 echo "</tr>\n";
80e85ea1 2205 $order = $nextorder[$order];
4cadac8f 2206 }
c3bdc503
DO
2207 echo "</table>\n";
2208 }
a7fe7729 2209 finishPortlet ();
e673ee24
DO
2210}
2211
04d619d0 2212function renderIPv4SpaceEditor ()
e673ee24 2213{
e673ee24 2214 showMessageOrError();
2a201216 2215
a262e150
DO
2216 // IPv4 validator
2217?>
2218 <script type="text/javascript">
2219 function init() {
2220 document.add_new_range.range.setAttribute('match', "^\\d\\d?\\d?\\.\\d\\d?\\d?\\.\\d\\d?\\d?\\.\\d\\d?\\d?\\/\\d\\d?$");
2221
2222 Validate.init();
2223 }
2224 window.onload=init;
2225 </script>
2226<?php
2227
4c0653e2 2228 startPortlet ("Add new");
04d619d0 2229 echo '<table border=0 cellpadding=10 align=center>';
7056988c
DO
2230 // This form requires a name, so JavaScript validator can find it.
2231 // No printOpFormIntro() hence
4fbb5a00 2232 echo "<form method=post name='add_new_range' action='".makeHrefProcess()."'>\n";
42023f03 2233 echo "<input type=hidden name=op value=addIPv4Prefix>\n";
04d619d0
DO
2234 // tags column
2235 echo '<tr><td rowspan=4><h3>assign tags</h3>';
25186565 2236 renderNewEntityTags();
04d619d0
DO
2237 echo '</td>';
2238 // inputs column
2239 echo "<th class=tdright>prefix</th><td class=tdleft><input type=text name='range' size=18 class='live-validate' tabindex=1></td>";
2240 echo "<tr><th class=tdright>name</th><td class=tdleft><input type=text name='name' size='20' tabindex=2></td></tr>";
0c16ef0c 2241 echo "<tr><th class=tdright>connected network</th><td class=tdleft><input type=checkbox name='is_bcast' tabindex=3></td></tr>";
04d619d0 2242 echo "<tr><td colspan=2>";
4c0653e2 2243 printImageHREF ('CREATE', 'Add a new network', TRUE, 4);
04d619d0 2244 echo '</td></tr>';
2a201216 2245 echo "</form></table><br><br>\n";
5c0bb421 2246 finishPortlet();
2a201216 2247
573214e0
DO
2248 $addrspaceList = listCells ('ipv4net');
2249 array_walk ($addrspaceList, 'amplifyCell');
e43a2de4 2250 if (count ($addrspaceList))
e673ee24 2251 {
e43a2de4 2252 startPortlet ('Manage existing (' . count ($addrspaceList) . ')');
04d619d0
DO
2253 echo "<table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
2254 echo "<tr><th>&nbsp;</th><th>prefix</th><th>name</th><th>&nbsp;</th></tr>";
0c16ef0c 2255 foreach ($addrspaceList as $netinfo)
e673ee24 2256 {
0b9c98d7 2257 echo "<form method=post action='".makeHrefProcess(array('op'=>'updIPv4Prefix', 'id'=>$netinfo['id']))."'>";
e43a2de4
DO
2258 echo "<tr valign=top><td>";
2259 if (getConfigVar ('IPV4_JAYWALK') == 'yes')
2260 {
2261 echo "<a href='".makeHrefProcess(array('op'=>'delIPv4Prefix', 'id'=>$netinfo['id']))."'>";
2262 printImageHREF ('destroy', 'Delete this prefix');
2263 echo "</a>";
2264 }
2265 else // only render clickable image for empty networks
2266 {
2267 $netdata = getIPv4NetworkInfo ($netinfo['id']);
2268 loadIPv4AddrList ($netdata);
2269 if (count ($netdata['addrlist']))
2270 printImageHREF ('nodestroy', 'There are ' . count ($netdata['addrlist']) . ' allocations inside');
2271 else
2272 {
2273 echo "<a href='".makeHrefProcess(array('op'=>'delIPv4Prefix', 'id'=>$netinfo['id']))."'>";
2274 printImageHREF ('destroy', 'Delete this prefix');
2275 echo "</a>";
2276 }
2277
2278 }
2279 echo "</td>\n<td class=tdleft>${netinfo['ip']}/${netinfo['mask']}</td>";
0c16ef0c 2280 echo "<td><input type=text name=name size=40 value='${netinfo['name']}'>";
04d619d0
DO
2281 echo "</td><td>";
2282 printImageHREF ('save', 'Save changes', TRUE);
2283 echo "</td></tr></form>\n";
e673ee24 2284 }
04d619d0
DO
2285 echo "</table>";
2286 finishPortlet();
e673ee24 2287 }
e673ee24
DO
2288}
2289
beb9e88a 2290function renderIPv4Network ($id)
e673ee24 2291{
4fbb5a00 2292 global $pageno, $tabno, $aac2;
545478d0
DO
2293 $netmaskbylen = array
2294 (
2295 32 => '255.255.255.255',
2296 31 => '255.255.255.254',
2297 30 => '255.255.255.252',
2298 29 => '255.255.255.248',
2299 28 => '255.255.255.240',
2300 27 => '255.255.255.224',
2301 26 => '255.255.255.192',
2302 25 => '255.255.255.128',
2303 24 => '255.255.255.0',
2304 23 => '255.255.254.0',
2305 22 => '255.255.252.0',
2306 21 => '255.255.248.0',
2307 20 => '255.255.240.0',
2308 19 => '255.255.224.0',
2309 18 => '255.255.192.0',
2310 17 => '255.255.128.0',
2311 16 => '255.255.0.0',
2312 15 => '255.254.0.0',
2313 14 => '255.252.0.0',
2314 13 => '255.248.0.0',
2315 12 => '255.240.0.0',
2316 11 => '255.224.0.0',
2317 10 => '255.192.0.0',
2318 9 => '255.128.0.0',
2319 8 => '255.0.0.0',
2320 7 => '254.0.0.0',
2321 6 => '252.0.0.0',
2322 5 => '248.0.0.0',
2323 4 => '240.0.0.0',
2324 3 => '224.0.0.0',
2325 2 => '192.0.0.0',
2326 1 => '128.0.0.0'
2327 );
2328 $wildcardbylen = array
2329 (
2330 32 => '0.0.0.0',
2331 31 => '0.0.0.1',
2332 30 => '0.0.0.3',
2333 29 => '0.0.0.7',
2334 28 => '0.0.0.15',
2335 27 => '0.0.0.31',
2336 26 => '0.0.0.63',
2337 25 => '0.0.0.127',
2338 24 => '0.0.0.255',
2339 23 => '0.0.1.255',
2340 22 => '0.0.3.255',
2341 21 => '0.0.7.255',
2342 20 => '0.0.15.255',
2343 19 => '0.0.31.255',
2344 18 => '0.0.63.255',
2345 17 => '0.0.127.255',
2346 16 => '0.0.255.25',
2347 15 => '0.1.255.255',
2348 14 => '0.3.255.255',
2349 13 => '0.7.255.255',
2350 12 => '0.15.255.255',
2351 11 => '0.31.255.255',
2352 10 => '0.63.255.255',
2353 9 => '0.127.255.255',
2354 8 => '0.255.255.255',
2355 7 => '1.255.255.255',
2356 6 => '3.255.255.255',
2357 5 => '7.255.255.255',
2358 4 => '15.255.255.255',
2359 3 => '31.255.255.255',
2360 2 => '63.255.255.255',
2361 1 => '127.255.255.255'
2362 );
b901bf1f 2363 $maxperpage = getConfigVar ('IPV4_ADDRS_PER_PAGE');
e673ee24
DO
2364 if (isset($_REQUEST['pg']))
2365 $page = $_REQUEST['pg'];
2366 else
2367 $page=0;
2368
b6b87070
DO
2369 $range = getIPv4NetworkInfo ($id);
2370 loadIPv4AddrList ($range);
2034d968
DO
2371 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
2372 echo "<tr><td colspan=2 align=center><h1>${range['ip']}/${range['mask']}</h1><h2>${range['name']}</h2></td></tr>\n";
2373
2374 echo "<tr><td class=pcleft width='50%'>";
2375 startPortlet ('summary');
2376 $total = ($range['ip_bin'] | $range['mask_bin_inv']) - ($range['ip_bin'] & $range['mask_bin']) + 1;
2377 $used = count ($range['addrlist']);
2378 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
04d619d0
DO
2379
2380 echo "<tr><th width='50%' class=tdright>%% used:</th><td class=tdleft>";
2034d968
DO
2381 renderProgressBar ($used/$total);
2382 echo "&nbsp;${used}/${total}</td></tr>\n";
04d619d0 2383
001e61fa
DO
2384 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
2385 {
3444ecf2
DO
2386 // Build a backtrace from all parent networks.
2387 $clen = $range['mask'];
2388 $backtrace = array();
2389 while (NULL !== ($upperid = getIPv4AddressNetworkId ($range['ip'], $clen)))
2390 {
2391 $upperinfo = getIPv4NetworkInfo ($upperid);
2392 $clen = $upperinfo['mask'];
2393 $backtrace[] = $upperid;
2394 }
2395 $arrows = count ($backtrace);
2396 foreach (array_reverse ($backtrace) as $ancestorid)
001e61fa
DO
2397 {
2398 $ainfo = getIPv4NetworkInfo ($ancestorid);
3444ecf2
DO
2399 echo "<tr><th width='50%' class=tdright>";
2400 for ($i = 0; $i < $arrows; $i++)
2401 echo '&uarr;';
2402 $arrows--;
5d3dcb8d
DO
2403 echo "</th><td class=tdleft>";
2404 renderIPv4NetCell ($ainfo);
2405 echo "</td></tr>";
001e61fa 2406 }
3444ecf2 2407 echo "<tr><th width='50%' class=tdright>&rarr;</th>";
5d3dcb8d
DO
2408 echo "<td class=tdleft>";
2409 renderIPv4NetCell ($range);
2410 echo "</td></tr>";
001e61fa
DO
2411 // FIXME: get and display nested networks
2412 // $theitem = pickLeaf ($ipv4tree, $id);
2413 }
2414
545478d0
DO
2415 echo "<tr><th width='50%' class=tdright>Netmask:</th><td class=tdleft>";
2416 echo $netmaskbylen[$range['mask']];
2417 echo "</td></tr>\n";
04d619d0 2418
c607ab55
DO
2419 echo "<tr><th width='50%' class=tdright>Netmask:</th><td class=tdleft>";
2420 printf ('0x%08X', binMaskFromDec ($range['mask']));
2421 echo "</td></tr>\n";
2422
545478d0
DO
2423 echo "<tr><th width='50%' class=tdright>Wildcard bits:</th><td class=tdleft>";
2424 echo $wildcardbylen[$range['mask']];
2425 echo "</td></tr>\n";
04d619d0 2426
f3d0cb20 2427 $routers = findRouters ($range['addrlist']);
f0ed1181 2428 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes' and count ($routers))
04d619d0 2429 {
57dece2f 2430 echo "<tr><th width='50%' class=tdright>Routed by:</th>";
f3d0cb20 2431 printRoutersTD ($routers);
57dece2f 2432 echo "</tr>\n";
04d619d0
DO
2433 }
2434
4fbb5a00 2435 printTagTRs (makeHref(array('page'=>'ipv4space', 'tab'=>'default'))."&");
2034d968
DO
2436 echo "</table><br>\n";
2437 finishPortlet();
e1ae3fb4
AD
2438
2439 renderFilesPortlet ('ipv4net', $id);
2034d968 2440 echo "</td>\n";
e673ee24 2441
2034d968
DO
2442 echo "<td class=pcright>";
2443 startPortlet ('details');
e673ee24
DO
2444 $startip = $range['ip_bin'] & $range['mask_bin'];
2445 $endip = $range['ip_bin'] | $range['mask_bin_inv'];
2446 $realstartip = $startip;
2447 $realendip = $endip;
2448 $numpages = 0;
2449 if($endip - $startip > $maxperpage)
2450 {
e673ee24
DO
2451 $numpages = ($endip - $startip)/$maxperpage;
2452 $startip = $startip + $page * $maxperpage;
2453 $endip = $startip + $maxperpage-1;
2454 }
2455 echo "<center>";
b901bf1f
DO
2456 if ($numpages)
2457 echo '<h3>' . long2ip ($startip) . ' ~ ' . long2ip ($endip) . '</h3>';
e673ee24
DO
2458 for ($i=0; $i<$numpages; $i++)
2459 {
2460 if ($i == $page)
2461 echo "<b>$i</b> ";
2462 else
4fbb5a00 2463 echo "<a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno, 'id'=>$id, 'pg'=>$i))."'>$i</a> ";
e673ee24
DO
2464 }
2465 echo "</center>";
2466
beb9e88a 2467 echo "<table class='widetable' border=0 cellspacing=0 cellpadding=5 align='center' width='100%'>\n";
e673ee24
DO
2468 echo "<tr><th>Address</th><th>Name</th><th>Allocation</th></tr>\n";
2469
2470
b2035dca
DO
2471 for ($ip = $startip; $ip <= $endip; $ip++) :
2472 if (isset ($_REQUEST['hl_ipv4_addr']) and ip2long ($_REQUEST['hl_ipv4_addr']) == $ip)
2473 $secondstyle = 'tdleft port_highlight';
2727c7df 2474 else
b2035dca
DO
2475 $secondstyle = 'tdleft';
2476 if (!isset ($range['addrlist'][$ip]))
e673ee24 2477 {
4fbb5a00 2478 echo "<tr><td class=tdleft><a href='".makeHref(array('page'=>'ipaddress', 'ip'=>ip_long2quad($ip)))."'>" . ip_long2quad($ip);
b2035dca
DO
2479 echo "</a></td><td class='${secondstyle}'>&nbsp;</td><td class='${secondstyle}'>&nbsp;</td></tr>\n";
2480 continue;
2481 }
b2035dca 2482 $addr = $range['addrlist'][$ip];
2d318652 2483 echo "<tr class='${addr['class']}'>";
e673ee24 2484
4fbb5a00 2485 echo "<td class=tdleft><a href='".makeHref(array('page'=>'ipaddress', 'ip'=>$addr['ip']))."'>${addr['ip']}</a></td>";
b2035dca
DO
2486 echo "<td class='${secondstyle}'>${addr['name']}</td><td class='${secondstyle}'>";
2487 $delim = '';
2488 $prologue = '';
2489 if ( $addr['reserved'] == 'yes')
2490 {
2d318652 2491 echo "<strong>RESERVED</strong> ";
b2035dca
DO
2492 $delim = '; ';
2493 }
2d318652 2494 foreach ($range['addrlist'][$ip]['allocs'] as $ref)
b2035dca 2495 {
beb9e88a 2496 echo $delim . $aac2[$ref['type']];
4fbb5a00 2497 echo "<a href='".makeHref(array('page'=>'object', 'object_id'=>$ref['object_id'], 'hl_ipv4_addr'=>$addr['ip']))."'>";
b2035dca
DO
2498 echo $ref['name'] . (empty ($ref['name']) ? '' : '@');
2499 echo "${ref['object_name']}</a>";
2500 $delim = '; ';
2501 }
2502 if ($delim != '')
2503 {
6131056c 2504 $delim = '';
b2035dca
DO
2505 $prologue = '<br>';
2506 }
2d318652 2507 foreach ($range['addrlist'][$ip]['lblist'] as $ref)
b2035dca
DO
2508 {
2509 echo $prologue;
602663f4 2510 $prologue = '';
4fbb5a00
DY
2511 echo "${delim}<a href='".makeHref(array('page'=>'object', 'object_id'=>$ref['object_id']))."'>";
2512 echo "${ref['object_name']}</a>:<a href='".makeHref(array('page'=>'ipv4vs', 'vs_id'=>$ref['vs_id']))."'>";
b2035dca
DO
2513 echo "${ref['vport']}/${ref['proto']}</a>&rarr;";
2514 $delim = '; ';
2515 }
2516 if ($delim != '')
2517 {
2518 $delim = '';
2519 $prologue = '<br>';
e673ee24 2520 }
2d318652 2521 foreach ($range['addrlist'][$ip]['rslist'] as $ref)
b2035dca
DO
2522 {
2523 echo $prologue;
2524 $prologue = '';
4fbb5a00 2525 echo "${delim}&rarr;${ref['rsport']}@<a href='".makeHref(array('page'=>'ipv4rspool', 'pool_id'=>$ref['rspool_id']))."'>";
b2035dca
DO
2526 echo "${ref['rspool_name']}</a>";
2527 $delim = '; ';
2528 }
2529 echo "</td></tr>\n";
2530 endfor;
2727c7df 2531 // end of iteration
e673ee24
DO
2532
2533 echo "</table>";
2034d968
DO
2534 finishPortlet();
2535 echo "</td></tr></table>\n";
e673ee24
DO
2536}
2537
53ef3908 2538function renderIPv4NetworkProperties ($id)
e673ee24 2539{
e673ee24 2540 showMessageOrError();
53ef3908
DO
2541 $netdata = getIPv4NetworkInfo ($id);
2542 echo "<center><h1>${netdata['ip']}/${netdata['mask']}</h1></center>\n";
e673ee24 2543 echo "<table border=0 cellpadding=10 cellpadding=1 align='center'>\n";
7056988c 2544 printOpFormIntro ('editRange');
53ef3908
DO
2545 echo "<tr><td class='tdright'>Name:</td><td class='tdleft'><input type=text name=name size=20 value='${netdata['name']}'></tr>";
2546 echo "<tr><td colspan=2 class=tdcenter>";
2547 printImageHREF ('SAVE', 'Save changes', TRUE);
2548 echo "</td></form></tr></table>\n";
e673ee24
DO
2549}
2550
2d318652 2551function renderIPv4Address ($dottedquad)
e673ee24 2552{
4fbb5a00 2553 global $aat;
2d318652 2554 $address = getIPv4Address ($dottedquad);
68225375 2555 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
2d318652
DO
2556 echo "<tr><td colspan=2 align=center><h1>${dottedquad}</h1></td></tr>\n";
2557 if (!empty ($address['name']))
68225375 2558 echo "<tr><td colspan=2 align=center><h2>${address['name']}</h2></td></tr>\n";
e673ee24 2559
68225375
DO
2560 echo "<tr><td class=pcleft>";
2561 startPortlet ('summary');
2562 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
04d619d0 2563 echo "<tr><th width='50%' class=tdright>Allocations:</th><td class=tdleft>" . count ($address['allocs']) . "</td></tr>\n";
68225375
DO
2564 echo "<tr><th width='50%' class=tdright>Originated NAT connections:</th><td class=tdleft>" . count ($address['outpf']) . "</td></tr>\n";
2565 echo "<tr><th width='50%' class=tdright>Arriving NAT connections:</th><td class=tdleft>" . count ($address['inpf']) . "</td></tr>\n";
04d619d0 2566 echo "<tr><th width='50%' class=tdright>SLB virtual services:</th><td class=tdleft>" . count ($address['lblist']) . "</td></tr>\n";
68225375
DO
2567 echo "<tr><th width='50%' class=tdright>SLB real servers:</th><td class=tdleft>" . count ($address['rslist']) . "</td></tr>\n";
2568 printTagTRs();
2569 echo "</table><br>\n";
2570 finishPortlet();
2571 echo "</td>\n";
e673ee24 2572
68225375 2573 echo "<td class=pcright>";
e673ee24 2574
f74d96c6 2575 if (isset ($address['class']))
59bebe2b 2576 {
8e700dd1 2577 startPortlet ('allocations');
2d318652
DO
2578 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
2579 echo "<tr><th>object</th><th>OS interface</th><th>allocation type</th></tr>\n";
2580 $class = $address['class'];
2581 // render all allocation records for this address the same way
59bebe2b 2582 if ($address['reserved'] == 'yes')
2d318652
DO
2583 echo "<tr class='${class}'><td colspan=2>&nbsp;</td><td class=tdleft><strong>RESERVED</strong></td></tr>";
2584 foreach ($address['allocs'] as $bond)
59bebe2b 2585 {
8e700dd1
DO
2586 if (isset ($_REQUEST['hl_object_id']) and $_REQUEST['hl_object_id'] == $bond['object_id'])
2587 $secondclass = 'tdleft port_highlight';
2588 else
2589 $secondclass = 'tdleft';
4fbb5a00 2590 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
2591 echo $aat[$bond['type']];
2592 echo "</strong></td></tr>\n";
59bebe2b
DO
2593 }
2594 echo "</table><br><br>";
2595 finishPortlet();
2596 }
e673ee24 2597
f3d0cb20
DO
2598 // FIXME: The returned list is structured differently, than we expect it to be. One of the sides
2599 // must be fixed.
2d318652 2600 if (count ($address['lblist']))
e673ee24 2601 {
2d318652
DO
2602 startPortlet ('Virtual services (' . count ($address['lblist']) . ')');
2603 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
59bebe2b 2604 echo "<tr><th>VS</th><th>name</th></tr>\n";
2d318652 2605 foreach ($address['lblist'] as $vsinfo)
e673ee24 2606 {
4fbb5a00 2607 echo "<tr><td class=tdleft><a href='".makeHref(array('page'=>'ipv4vs', 'vs_id'=>$vsinfo['vs_id']))."'>";
59bebe2b 2608 echo buildVServiceName ($vsinfo) . "</a></td><td class=tdleft>";
5fe1ed76 2609 echo $vsinfo['name'] . "</td></tr>\n";
e673ee24 2610 }
59bebe2b
DO
2611 echo "</table><br><br>";
2612 finishPortlet();
e673ee24 2613 }
5fe1ed76
DO
2614
2615 if (count ($address['rslist']))
2616 {
2617 startPortlet ('Real servers (' . count ($address['rslist']) . ')');
2d318652 2618 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
53f4b619 2619 echo "<tr><th>&nbsp;</th><th>port</th><th>RS pool</th></tr>\n";
5fe1ed76
DO
2620 foreach ($address['rslist'] as $rsinfo)
2621 {
2622 echo "<tr><td>";
2623 if ($rsinfo['inservice'] == 'yes')
2624 printImageHREF ('inservice', 'in service');
2625 else
2626 printImageHREF ('notinservice', 'NOT in service');
4fbb5a00 2627 echo "</td><td class=tdleft>${rsinfo['rsport']}</td><td class=tdleft><a href='".makeHref(array('page'=>'ipv4rspool', 'pool_id'=>$rsinfo['rspool_id']))."'>";
2d318652 2628 echo $rsinfo['rspool_name'] . "</a></td></tr>\n";
5fe1ed76
DO
2629 }
2630 echo "</table><br><br>";
2631 finishPortlet();
2632 }
2633
68225375
DO
2634 if (count ($address['outpf']))
2635 {
105a3bc8 2636 startPortlet ('departing NAT rules');
2d318652 2637 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
105a3bc8
DO
2638 echo "<tr><th>proto</th><th>from</th><th>to</th><th>comment</th></tr>\n";
2639 foreach ($address['outpf'] as $rule)
b62ff880 2640 echo "<tr><td>${rule['proto']}</td><td>${rule['localip']}:${rule['localport']}</td><td>${rule['remoteip']}:${rule['remoteport']}</td><td>${rule['description']}</td></tr>";
105a3bc8 2641 echo "</table>";
68225375
DO
2642 finishPortlet();
2643 }
105a3bc8
DO
2644
2645 if (count ($address['inpf']))
2646 {
2647 startPortlet ('arriving NAT rules');
2d318652 2648 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
105a3bc8
DO
2649 echo "<tr><th>proto</th><th>from</th><th>to</th><th>comment</th></tr>\n";
2650 foreach ($address['inpf'] as $rule)
b62ff880 2651 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
2652 echo "</table>";
2653 finishPortlet();
2654 }
2655
68225375
DO
2656 echo "</td></tr>";
2657 echo "</table>\n";
e673ee24
DO
2658}
2659
2d318652 2660function renderIPv4AddressProperties ($dottedquad)
e673ee24 2661{
e673ee24 2662 showMessageOrError();
2d318652
DO
2663 $address = getIPv4Address ($dottedquad);
2664 echo "<center><h1>$dottedquad</h1></center>\n";
7056988c 2665
1fbc9fd6 2666 startPortlet ('update');
e673ee24 2667 echo "<table border=0 cellpadding=10 cellpadding=1 align='center'>\n";
7056988c 2668 printOpFormIntro ('editAddress');
2d318652
DO
2669 echo "<tr><td class='tdright'>Name:</td><td class='tdleft'><input type=text name=name size=20 value='${address['name']}'></tr>";
2670 echo "<td class='tdright'>Reserved:</td><td class='tdleft'><input type=checkbox name=reserved size=20 ";
2671 echo ($address['reserved']=='yes') ? 'checked' : '';
f3d274bf 2672 echo "></tr><tr><td class=tdleft>";
53ef3908 2673 printImageHREF ('SAVE', 'Save changes', TRUE);
f3d274bf 2674 echo "</td></form><td class=tdright>";
1fbc9fd6 2675 if (empty ($address['name']) and $address['reserved'] == 'no')
f3d274bf
DO
2676 printImageHREF ('CLEAR gray');
2677 else
2678 {
2679 printOpFormIntro ('editAddress', array ('name' => '', 'reserved' => ''));
2680 printImageHREF ('CLEAR', 'Release', TRUE);
2681 echo "</form>";
2682 }
2683 echo "</td></tr></table>\n";
1fbc9fd6 2684 finishPortlet();
e673ee24
DO
2685}
2686
2d318652 2687function renderIPv4AddressAllocations ($dottedquad)
e673ee24 2688{
e673ee24 2689 showMessageOrError();
39b4abd0
DO
2690 function printNewItemTR ()
2691 {
2692 global $aat;
2693 printOpFormIntro ('addIPv4Allocation');
2694 echo "<tr><td>";
9318d2ef 2695 printImageHREF ('add', 'allocate', TRUE);
8d4f7d18 2696 echo "</td><td>";
c6bc0ac5 2697 printSelect (getNarrowObjectList ('IPV4OBJ_LISTSRC'), 'object_id', NULL, 100);
8d4f7d18 2698 echo "</td><td><input type=text tabindex=101 name=bond_name size=10></td><td>";
f5ff50f5 2699 printSelect ($aat, 'bond_type', NULL, 102);
9318d2ef 2700 echo "</td><td>";
f5ff50f5 2701 printImageHREF ('add', 'allocate', TRUE, 103);
9318d2ef 2702 echo "</td></form></tr>";
39b4abd0 2703 }
b82cce3f 2704 global $aat;
e673ee24 2705
2d318652 2706 $address = getIPv4Address ($dottedquad);
f74d96c6 2707
2d318652 2708 echo "<center><h1>${dottedquad}</h1></center>\n";
105a3bc8 2709 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
2d318652 2710 echo "<tr><th>&nbsp;</th><th>object</th><th>OS interface</th><th>allocation type</th><th>&nbsp;</th></tr>\n";
e673ee24 2711
39b4abd0
DO
2712 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
2713 printNewItemTR();
f74d96c6 2714 if (isset ($address['class']))
e673ee24 2715 {
f74d96c6
DO
2716 $class = $address['class'];
2717 if ($address['reserved'] == 'yes')
2718 echo "<tr class='${class}'><td colspan=3>&nbsp;</td><td class=tdleft><strong>RESERVED</strong></td><td>&nbsp;</td></tr>";
2719 foreach ($address['allocs'] as $bond)
2720 {
2721 echo "<tr class='$class'>";
2722 printOpFormIntro ('updIPv4Allocation', array ('object_id' => $bond['object_id']));
4fbb5a00 2723 echo "<td><a href='".makeHrefProcess(array('op'=>'delIPv4Allocation', 'ip'=>$dottedquad, 'object_id'=>$bond['object_id']))."'>";
f74d96c6
DO
2724 printImageHREF ('delete', 'Unallocate address');
2725 echo "</a></td>";
4fbb5a00 2726 echo "<td><a href='".makeHref(array('page'=>'object', 'object_id'=>$bond['object_id'], 'hl_ipv4_addr'=>$dottedquad))."'>${bond['object_name']}</td>";
f74d96c6
DO
2727 echo "<td><input type='text' name='bond_name' value='${bond['name']}' size=10></td><td>";
2728 printSelect ($aat, 'bond_type', $bond['type']);
2729 echo "</td><td>";
2730 printImageHREF ('save', 'Save changes', TRUE);
2731 echo "</td></form></tr>\n";
2732 }
e673ee24 2733 }
39b4abd0
DO
2734 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
2735 printNewItemTR();
e673ee24 2736 echo "</table><br><br>";
e673ee24
DO
2737}
2738
eeb4a5d8 2739function renderNATv4ForObject ($object_id = 0)
e673ee24 2740{
9318d2ef
DO
2741 function printNewItemTR ($alloclist)
2742 {
9318d2ef
DO
2743 printOpFormIntro ('addNATv4Rule');
2744 echo "<tr align='center'><td>";
2745 printImageHREF ('add', 'Add new NAT rule', TRUE);
2746 echo '</td><td>';
2747 printSelect (array ('TCP' => 'TCP', 'UDP' => 'UDP'), 'proto');
2748 echo "<select name='localip' tabindex=1>";
2749
2750 foreach ($alloclist as $dottedquad => $alloc)
2751 {
2752 $name = empty ($alloc['addrinfo']['name']) ? '' : (' (' . niftyString ($alloc['addrinfo']['name']) . ')');
2753 $osif = empty ($alloc['osif']) ? '' : ($alloc['osif'] . ': ');
2754 echo "<option value='${dottedquad}'>${osif}${dottedquad}${name}</option>";
2755 }
2756
2757 echo "</select>:<input type='text' name='localport' size='4' tabindex=2></td>";
2758 echo "<td><input type='text' name='remoteip' id='remoteip' size='10' tabindex=3>";
39106006
DO
2759 echo "<a href='javascript:;' onclick='window.open(\"" . makeHrefForHelper ('inet4list');
2760 echo "\", \"findobjectip\", \"height=700, width=400, location=no, menubar=no, resizable=yes, scrollbars=no, status=no, titlebar=no, toolbar=no\");'>";
9318d2ef
DO
2761 printImageHREF ('find', 'Find object');
2762 echo "</a>";
2763 echo ":<input type='text' name='remoteport' size='4' tabindex=4></td><td></td>";
2764 echo "<td colspan=1><input type='text' name='description' size='20' tabindex=5></td><td>";
f5ff50f5 2765 printImageHREF ('add', 'Add new NAT rule', TRUE, 6);
9318d2ef
DO
2766 echo "</td></tr></form>";
2767 }
e673ee24
DO
2768
2769 $info = getObjectInfo ($object_id);
eeb4a5d8 2770 $forwards = getNATv4ForObject ($object_id);
2c817354 2771 $alloclist = getObjectIPv4Allocations ($object_id);
e673ee24 2772 showMessageOrError();
f28fbe8b 2773 echo "<center><h2>locally performed NAT</h2></center>";
e673ee24 2774
105a3bc8 2775 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
d54b9495 2776 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 2777
9318d2ef
DO
2778 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
2779 printNewItemTR ($alloclist);
e673ee24
DO
2780 foreach ($forwards['out'] as $pf)
2781 {
2c817354
DO
2782 $class = 'trerror';
2783 $osif = '';
2784 if (isset ($alloclist [$pf['localip']]))
2785 {
2786 $class = $alloclist [$pf['localip']]['addrinfo']['class'];
2787 $osif = $alloclist [$pf['localip']]['osif'] . ': ';
2788 }
e673ee24
DO
2789
2790 echo "<tr class='$class'>";
4fbb5a00
DY
2791 echo "<td><a href='".
2792 makeHrefProcess(array(
2793 'op'=>'delNATv4Rule',
2794 'localip'=>$pf['localip'],
2795 'localport'=>$pf['localport'],
2796 'remoteip'=>$pf['remoteip'],
2797 'remoteport'=>$pf['remoteport'],
2798 'proto'=>$pf['proto'],
2799 'object_id'=>$object_id)).
2800 "'>";
4de22e7e
DO
2801 printImageHREF ('delete', 'Delete NAT rule');
2802 echo "</a></td>";
4fbb5a00 2803 echo "<td>${pf['proto']}/${osif}<a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['localip']))."'>${pf['localip']}</a>:${pf['localport']}";
f28fbe8b
DO
2804 if (!empty ($pf['local_addr_name']))
2805 echo ' (' . $pf['local_addr_name'] . ')';
2806 echo "</td>";
4fbb5a00 2807 echo "<td><a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['remoteip']))."'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
e673ee24 2808
53ef3908 2809 $address = getIPv4Address ($pf['remoteip']);
e673ee24
DO
2810
2811 echo "<td class='description'>";
53ef3908
DO
2812 if (count ($address['allocs']))
2813 foreach ($address['allocs'] as $bond)
4fbb5a00 2814 echo "<a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$bond['object_id']))."'>${bond['object_name']}(${bond['name']})</a> ";
f28fbe8b
DO
2815 elseif (!empty ($pf['remote_addr_name']))
2816 echo '(' . $pf['remote_addr_name'] . ')';
7056988c
DO
2817 printOpFormIntro
2818 (
2819 'updNATv4Rule',
2820 array
2821 (
2822 'localip' => $pf['localip'],
2823 'localport' => $pf['localport'],
2824 'remoteip' => $pf['remoteip'],
2825 'remoteport' => $pf['remoteport'],
2826 'proto' => $pf['proto']
2827 )
2828 );
2829 echo "</td><td class='description'>";
d54b9495
DO
2830 echo "<input type='text' name='description' value='${pf['description']}'></td><td>";
2831 printImageHREF ('save', 'Save changes', TRUE);
2832 echo "</td></form></tr>";
e673ee24 2833 }
9318d2ef
DO
2834 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
2835 printNewItemTR ($alloclist);
e673ee24
DO
2836
2837 echo "</table><br><br>";
2838
f28fbe8b 2839 echo "<center><h2>arriving NAT connections</h2></center>";
105a3bc8 2840 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
e673ee24
DO
2841 echo "<tr><th></th><th>Source</th><th>Source objects</th><th>Target</th><th>Description</th></tr>\n";
2842
2843 foreach ($forwards['in'] as $pf)
2844 {
4fbb5a00
DY
2845 echo "<tr><td><a href='".
2846 makeHrefProcess(array(
2847 'op'=>'delNATv4Rule',
2848 'localip'=>$pf['localip'],
2849 'localport'=>$pf['localport'],
2850 'remoteip'=>$pf['remoteip'],
2851 'remoteport'=>$pf['remoteport'],
2852 'proto'=>$pf['proto'],
2853 'object_id'=>$pf['object_id']
2854 )).
2855 "'>";
4de22e7e
DO
2856 printImageHREF ('delete', 'Delete NAT rule');
2857 echo "</a></td>";
4fbb5a00
DY
2858 echo "<td>${pf['proto']}/<a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['localip']))."'>${pf['localip']}</a>:${pf['localport']}</td>";
2859 echo "<td class='description'><a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$pf['object_id']))."'>${pf['object_name']}</a>";
2860 echo "</td><td><a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['remoteip']))."'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
e673ee24
DO
2861 echo "<td class='description'>${pf['description']}</td></tr>";
2862 }
2863
e673ee24 2864 echo "</table><br><br>";
e673ee24
DO
2865}
2866
e673ee24
DO
2867function renderAddMultipleObjectsForm ()
2868{
57777e4a 2869 showMessageOrError();
e673ee24 2870 $typelist = getObjectTypeList();
4c330a14 2871 $typelist[0] = 'select type...';
a1886a78
DO
2872 $max = getConfigVar ('MASSCOUNT');
2873 $tabindex = 100;
7f791d1d 2874
f60bb422 2875 startPortlet ('Distinct types, same tags');
42d73cbf 2876 printOpFormIntro ('addObjects');
e673ee24 2877 echo '<table border=0 align=center>';
f60bb422
DO
2878 echo "<tr><th>Object type</th><th>Common name</th><th>Visible label</th>";
2879 echo "<th>Asset tag</th><th>Barcode</th><th>Tags</th></tr>\n";
9c0b0016 2880 for ($i = 0; $i < $max; $i++)
e673ee24 2881 {
7f791d1d 2882 echo '<tr><td>';
e7ade6bf 2883 // Don't employ DEFAULT_OBJECT_TYPE to avoid creating ghost records for pre-selected empty rows.
a1886a78 2884 printSelect ($typelist, "${i}_object_type_id", 0, $tabindex);
e673ee24 2885 echo '</td>';
a1886a78
DO
2886 echo "<td><input type=text size=30 name=${i}_object_name tabindex=${tabindex}></td>";
2887 echo "<td><input type=text size=30 name=${i}_object_label tabindex=${tabindex}></td>";
2888 echo "<td><input type=text size=20 name=${i}_object_asset_no tabindex=${tabindex}></td>";
2889 echo "<td><input type=text size=10 name=${i}_object_barcode tabindex=${tabindex}></td>";
f60bb422
DO
2890 if ($i == 0)
2891 {
2892 echo "<td valign=top rowspan=${max}>";
25186565 2893 renderNewEntityTags();
f60bb422
DO
2894 echo "</td>\n";
2895 }
e673ee24 2896 echo "</tr>\n";
a1886a78 2897 $tabindex++;
e673ee24 2898 }
216c84bb 2899 echo "<tr><td class=submit colspan=5><input type=submit name=got_fast_data value='Go!'></td></tr>\n";
e673ee24
DO
2900 echo "</form></table>\n";
2901 finishPortlet();
7f791d1d 2902
f60bb422 2903 startPortlet ('Same type, same tags');
42d73cbf 2904 printOpFormIntro ('addLotOfObjects');
f60bb422
DO
2905 echo "<table border=0 align=center><tr><th>names</th><th>type</th></tr>";
2906 echo "<tr><td rowspan=3><textarea name=namelist cols=40 rows=25>\n";
f60bb422
DO
2907 echo "</textarea></td><td valign=top>";
2908 printSelect ($typelist, "global_type_id", getConfigVar ('DEFAULT_OBJECT_TYPE'));
2909 echo "</td></tr>";
2910 echo "<tr><th>Tags</th></tr>";
2911 echo "<tr><td valign=top>";
25186565 2912 renderNewEntityTags();
f60bb422
DO
2913 echo "</td></tr>";
2914 echo "<tr><td colspan=2><input type=submit name=got_very_fast_data value='Go!'></td></tr></table>\n";
2915 echo "</form>\n";
7f791d1d 2916 finishPortlet();
e673ee24
DO
2917}
2918
2919function printGreeting ()
2920{
d6d79c36
DO
2921 global $root, $remote_username, $remote_displayname;
2922 echo "Hello, <a href='${root}?page=myaccount&tab=default'>${remote_displayname}</a>. This is RackTables " .
2923 CODE_VERSION .
2924 ". Click <a href='${root}?logout'>here</a> to logout.";
e673ee24
DO
2925}
2926
2927function renderSearchResults ()
2928{
0b9c98d7 2929 global $root;
e673ee24
DO
2930 $terms = trim ($_REQUEST['q']);
2931 if (empty ($terms))
2932 {
591ff2c4 2933 showError ('Search string cannot be empty.', __FUNCTION__);
e673ee24
DO
2934 return;
2935 }
c78a40ec 2936 if (!permitted ('depot', 'default'))
e673ee24 2937 {
591ff2c4 2938 showError ('You are not authorized for viewing information about objects.', __FUNCTION__);
e673ee24
DO
2939 return;
2940 }
ea5fc465 2941 $nhits = 0;
e673ee24
DO
2942 // If we search for L2 address, we can either find one or find none.
2943 if
2944 (
05771508
DO
2945 preg_match (RE_L2_IFCFG, $terms) or
2946 preg_match (RE_L2_SOLID, $terms) or
2947 preg_match (RE_L2_CISCO, $terms) or
1930dc7f 2948 preg_match (RE_L2_IPCFG, $terms) or
05771508
DO
2949 // Foundry STP bridge ID: bridge priotity + port MAC address. Cut off first 4 chars and look for MAC address.
2950 preg_match (RE_L2_FDRYSTP, $terms)
e673ee24
DO
2951 )
2952 // Search for L2 address.
2953 {
3ec29bf4
DO
2954 $terms = str_replace ('.', '', $terms);
2955 $terms = str_replace (':', '', $terms);
1930dc7f 2956 $terms = str_replace ('-', '', $terms);
ea5fc465 2957 $terms = substr ($terms, -12);
e673ee24
DO
2958 $result = searchByl2address ($terms);
2959 if ($result !== NULL)
2960 {
ea5fc465
DO
2961 $nhits++;
2962 $lasthit = 'port';
2963 $summary['port'][] = $result;
e673ee24 2964 }
e673ee24 2965 }
05771508 2966 elseif (preg_match (RE_IP4_ADDR, $terms))
64347dcf 2967 // Search for IPv4 address.
e673ee24 2968 {
bb0a44e9 2969 if (NULL !== getIPv4AddressNetworkId ($terms))
e673ee24 2970 {
ea5fc465 2971 $nhits++;
f3d0cb20
DO
2972 $lasthit = 'ipv4addressbydq';
2973 $summary['ipv4addressbydq'][] = $terms;
e673ee24 2974 }
e673ee24 2975 }
05771508 2976 elseif (preg_match (RE_IP4_NET, $terms))
64347dcf
DO
2977 // Search for IPv4 network
2978 {
2979 list ($base, $len) = explode ('/', $terms);
2980 if (NULL !== ($tmp = getIPv4AddressNetworkId ($base, $len + 1)))
2981 {
2982 $nhits++;
2983 $lasthit = 'ipv4network';
2984 $summary['ipv4network'][] = getIPv4NetworkInfo ($tmp);
2985 }
2986 }
e673ee24 2987 else
ea5fc465 2988 // Search for objects, addresses, networks, virtual services and RS pools by their description.
e673ee24 2989 {
ea5fc465
DO
2990 $tmp = getObjectSearchResults ($terms);
2991 if (count ($tmp))
e673ee24 2992 {
ea5fc465
DO
2993 $nhits += count ($tmp);
2994 $lasthit = 'object';
2995 $summary['object'] = $tmp;
e673ee24 2996 }
ea5fc465
DO
2997 $tmp = getIPv4AddressSearchResult ($terms);
2998 if (count ($tmp))
e673ee24 2999 {
ea5fc465 3000 $nhits += count ($tmp);
f3d0cb20
DO
3001 $lasthit = 'ipv4addressbydescr';
3002 $summary['ipv4addressbydescr'] = $tmp;
ea5fc465
DO
3003 }
3004 $tmp = getIPv4PrefixSearchResult ($terms);
3005 if (count ($tmp))
3006 {
3007 $nhits += count ($tmp);
3008 $lasthit = 'ipv4network';
3009 $summary['ipv4network'] = $tmp;
3010 }
05411ccd
DO
3011 $tmp = getIPv4RSPoolSearchResult ($terms);
3012 if (count ($tmp))
3013 {
3014 $nhits += count ($tmp);
3015 $lasthit = 'ipv4rspool';
3016 $summary['ipv4rspool'] = $tmp;
3017 }
3018 $tmp = getIPv4VServiceSearchResult ($terms);
3019 if (count ($tmp))
3020 {
3021 $nhits += count ($tmp);
3022 $lasthit = 'ipv4vs';
3023 $summary['ipv4vs'] = $tmp;
3024 }
6a88e734
DO
3025 $tmp = getAccountSearchResult ($terms);
3026 if (count ($tmp))
3027 {
3028 $nhits += count ($tmp);
3029 $lasthit = 'user';
3030 $summary['user'] = $tmp;
3031 }
e1ae3fb4
AD
3032 $tmp = getFileSearchResult ($terms);
3033 if (count ($tmp))
3034 {
3035 $nhits += count ($tmp);
3036 $lasthit = 'file';
3037 $summary['file'] = $tmp;
3038 }
ea5fc465
DO
3039 }
3040 if ($nhits == 0)
3041 echo "<center><h2>Nothing found for '${terms}'</h2></center>";
3042 elseif ($nhits == 1)
3043 {
3044 $record = current ($summary[$lasthit]);
3045 switch ($lasthit)
3046 {
3047 case 'port':
3048 echo "<script language='Javascript'>document.location='${root}?page=object";
3049 echo "&hl_port_id=" . $record['port_id'];
3050 echo "&object_id=" . $record['object_id'] . "';//</script>";
3051 break;
f3d0cb20
DO
3052 case 'ipv4addressbydq':
3053 $parentnet = getIPv4AddressNetworkId ($record);
3054 if ($parentnet !== NULL)
e1ae3fb4 3055 echo "<script language='Javascript'>document.location='${root}?page=ipv4net&tab=default&id=${parentnet}&hl_ipv4_addr=${record}';//</script>";
f3d0cb20
DO
3056 else
3057 echo "<script language='Javascript'>document.location='${root}?page=ipaddress&ip=${record}';//</script>";
ea5fc465 3058 break;
f3d0cb20
DO
3059 case 'ipv4addressbydescr':
3060 $parentnet = getIPv4AddressNetworkId ($record['ip']);
3061 if ($parentnet !== NULL)
e1ae3fb4 3062 echo "<script language='Javascript'>document.location='${root}?page=ipv4net&tab=default&id=${parentnet}&hl_ipv4_addr=${record['ip']}';//</script>";
f3d0cb20
DO
3063 else
3064 echo "<script language='Javascript'>document.location='${root}?page=ipaddress&ip=${record['ip']}';//</script>";
ea5fc465
DO
3065 break;
3066 case 'ipv4network':
e1ae3fb4 3067 echo "<script language='Javascript'>document.location='${root}?page=ipv4net";
ea5fc465
DO
3068 echo "&id=${record['id']}";
3069 echo "';//</script>";
3070 break;
3071 case 'object':
3072 echo "<script language='Javascript'>document.location='${root}?page=object&object_id=${record['id']}';//</script>";
3073 break;
05411ccd 3074 case 'ipv4rspool':
e1ae3fb4 3075 echo "<script language='Javascript'>document.location='${root}?page=ipv4rspool&pool_id=${record['pool_id']}';//</script>";
05411ccd
DO
3076 break;
3077 case 'ipv4vs':
49fb2686 3078 echo "<script language='Javascript'>document.location='${root}?page=ipv4vs&vs_id=${record['id']}';//</script>";
05411ccd 3079 break;
6a88e734
DO
3080 case 'user':
3081 echo "<script language='Javascript'>document.location='${root}?page=user&user_id=${record['user_id']}';//</script>";
3082 break;
e1ae3fb4
AD
3083 case 'file':
3084 echo "<script language='Javascript'>document.location='${root}?page=file&file_id=${record['id']}';//</script>";
3085 break;
ea5fc465
DO
3086 }
3087 return;
3088 }
3089 else
3090 {
3091 global $nextorder;
3092 $order = 'odd';
3093 echo "<center><h2>${nhits} result(s) found for '${terms}'</h2></center>";
3094 foreach ($summary as $where => $what)
3095 switch ($where)
e673ee24 3096 {
ea5fc465 3097 case 'object':
c78a40ec 3098 startPortlet ("<a href='${root}?page=depot'>Objects</a>");
ea5fc465 3099 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
e1ae3fb4 3100 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>Barcode</th></tr>';
ea5fc465
DO
3101 foreach ($what as $obj)
3102 {
2c21a10c 3103 $tags = loadEntityTags ('object', $obj['id']);
2b3d64c5
DO
3104 echo "<tr class=row_${order} valign=top><td class=tdleft><a href=\"${root}?page=object&object_id=${obj['id']}\">${obj['dname']}</a>";
3105 if (count ($tags))
3106 echo '<br><small>' . serializeTags ($tags) . '</small>';
3107 echo "</td><td>${obj['label']}</td>";
ea5fc465
DO
3108 echo "<td>${obj['asset_no']}</td>";
3109 echo "<td>${obj['barcode']}</td></tr>";
3110 $order = $nextorder[$order];
3111 }
3112 echo '</table>';
3113 finishPortlet();
3114 break;
3115 case 'ipv4network':
06adfe89 3116 startPortlet ("<a href='${root}?page=ipv4space'>IPv4 networks</a>");
ea5fc465 3117 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
71287f1c 3118 foreach ($what as $netinfo)
ea5fc465 3119 {
0b9c98d7
DO
3120 echo "<tr class=row_${order} valign=top><td>";
3121 renderIPv4NetCell ($netinfo);
3122 echo "</td></tr>\n";
ea5fc465
DO
3123 $order = $nextorder[$order];
3124 }
3125 echo '</table>';
3126 finishPortlet();
3127 break;
f3d0cb20 3128 case 'ipv4addressbydescr':
ea5fc465
DO
3129 startPortlet ('IPv4 addresses');
3130 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
f3d0cb20 3131 // FIXME: address, parent network, routers (if extended view is enabled)
e1ae3fb4 3132 echo '<tr><th>Address</th><th>Description</th></tr>';
ea5fc465
DO
3133 foreach ($what as $addr)
3134 {
f3d0cb20
DO
3135 echo "<tr class=row_${order}><td class=tdleft>";
3136 $parentnet = getIPv4AddressNetworkId ($addr['ip']);
3137 if ($parentnet !== NULL)
e1ae3fb4 3138 echo "<a href='${root}?page=ipv4net&tab=default&id=${parentnet}&hl_ipv4_addr=${addr['ip']}'>${addr['ip']}</a></td>";
f3d0cb20
DO
3139 else
3140 echo "<a href='${root}?page=ipaddress&ip=${addr['ip']}'>${addr['ip']}</a></td>";
ea5fc465
DO
3141 echo "<td class=tdleft>${addr['name']}</td></tr>";
3142 $order = $nextorder[$order];
3143 }
3144 echo '</table>';
3145 finishPortlet();
3146 break;
05411ccd 3147 case 'ipv4rspool':
ee437dab 3148 startPortlet ("<a href='${root}?page=ipv4rsplist'>RS pools</a>");
05411ccd
DO
3149 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
3150 foreach ($what as $rspool)
3151 {
216136d2
DO
3152 echo "<tr class=row_${order}><td class=tdleft>";
3153 renderRSPoolCell ($rspool['pool_id'], $rspool['name']);
3154 echo "</td></tr>";
05411ccd
DO
3155 $order = $nextorder[$order];
3156 }
3157 echo '</table>';
3158 finishPortlet();
3159 break;
3160 case 'ipv4vs':
a239e016 3161 startPortlet ("<a href='${root}?page=ipv4vslist'>Virtual services</a>");
05411ccd 3162 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
8128c257 3163 foreach ($what as $vsinfo)
05411ccd 3164 {
8128c257
DO
3165 echo "<tr class=row_${order}><td class=tdleft>";
3166 renderIPv4VSCell ($vsinfo);
3167 echo "</td></tr>";
6a88e734
DO
3168 $order = $nextorder[$order];
3169 }
3170 echo '</table>';
3171 finishPortlet();
3172 break;
3173 case 'user':
3174 startPortlet ("<a href='${root}?page=userlist'>Users</a>");
3175 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
6a88e734
DO
3176 foreach ($what as $item)
3177 {
19dac9c3 3178 echo "<tr class=row_${order}><td class=tdleft>";
573214e0 3179 renderCell ($item);
19dac9c3 3180 echo "</td></tr>";
05411ccd
DO
3181 $order = $nextorder[$order];
3182 }
3183 echo '</table>';
3184 finishPortlet();
3185 break;
e1ae3fb4
AD
3186 case 'file':
3187 startPortlet ("<a href='${root}?page=files'>Files</a>");
3188 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
e1ae3fb4
AD
3189 foreach ($what as $item)
3190 {
35d10b16
DO
3191 echo "<tr class=row_${order}><td class=tdleft>";
3192 renderFileCell ($item);
3193 echo "</td></tr>";
e1ae3fb4
AD
3194 $order = $nextorder[$order];
3195 }
3196 echo '</table>';
3197 finishPortlet();
3198 break;
e673ee24 3199 }
e673ee24
DO
3200 }
3201}
3202
3203// This function prints a table of checkboxes to aid the user in toggling mount atoms
3204// from one state to another. The first argument is rack data as
3205// produced by getRackData(), the second is the value used for the 'unckecked' state
3206// and the third is the value used for 'checked' state.
3207// Usage contexts:
3208// for mounting an object: printAtomGrid ($data, 'F', 'T')
3209// for changing rack design: printAtomGrid ($data, 'A', 'F')
3210// for adding rack problem: printAtomGrid ($data, 'F', 'U')
3211// for adding object problem: printAtomGrid ($data, 'T', 'W')
3212
3213function renderAtomGrid ($data)
3214{
3215 $rack_id = $data['id'];
3216 for ($unit_no = $data['height']; $unit_no > 0; $unit_no--)
3217 {
57c69e9c 3218 echo "<tr><th><a href='javascript:;' onclick=\"toggleRowOfAtoms('${rack_id}','${unit_no}')\">${unit_no}</a></th>";
e673ee24
DO
3219 for ($locidx = 0; $locidx < 3; $locidx++)
3220 {
57c69e9c 3221 $name = "atom_${rack_id}_${unit_no}_${locidx}";
e673ee24
DO
3222 $state = $data[$unit_no][$locidx]['state'];
3223 echo "<td class=state_${state}";
3224 if (isset ($data[$unit_no][$locidx]['hl']))
3225 echo $data[$unit_no][$locidx]['hl'];
3226 echo ">";
3227 if (!($data[$unit_no][$locidx]['enabled'] === TRUE))
57c69e9c 3228 echo "<input type=checkbox id=${name} disabled>";
e673ee24 3229 else
57c69e9c 3230 echo "<input type=checkbox" . $data[$unit_no][$locidx]['checked'] . " name=${name} id=${name}>";
e673ee24
DO
3231 echo '</td>';
3232 }
3233 echo "</tr>\n";
3234 }
3235}
3236
abf18701 3237function renderCellList ($realm = NULL, $title = 'items', $do_amplify = FALSE)
e673ee24 3238{
573214e0
DO
3239 if ($realm === NULL)
3240 {
3241 global $pageno;
3242 $realm = $pageno;
3243 }
3244 global $nextorder;
e673ee24 3245 $order = 'odd';