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