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