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