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