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