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