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