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