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