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