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