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