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