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