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