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