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