r3033 - maintenance->trunk sync of changeset:3024
[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 {
64347dcf 1908 if (getConfigVar ('IPV4_TREE_SHOW_USAGE') == 'yes')
64347dcf 1909 loadIPv4AddrList ($item); // necessary to compute router list and address counter
64347dcf
DO
1910 else
1911 {
1912 $item['addrlist'] = array();
1913 $item['addrc'] = 0;
1914 }
b1e39212
DO
1915 $used = $item['addrc'];
1916 $maxdirect = $item['addrt'];
1917 $maxtotal = binInvMaskFromDec ($item['mask']) + 1;
0137d53c
DO
1918 if (isset ($item['id']))
1919 {
fec0c8da 1920 if ($item['symbol'] == 'node-collapsed')
d9f8a37a 1921 $expandurl = "${baseurl}&eid=" . $item['id'] . "#netid" . $item['id'];
fec0c8da 1922 elseif ($item['symbol'] == 'node-expanded')
d9f8a37a 1923 $expandurl = $baseurl . ($item['parent_id'] ? "&eid=${item['parent_id']}#netid${item['parent_id']}" : '');
fec0c8da
DO
1924 else
1925 $expandurl = '';
0137d53c 1926 echo "<tr valign=top>";
fec0c8da 1927 printIPv4NetInfoTDs ($item, 'tdleft', $level, $item['symbol'], $expandurl);
0137d53c 1928 echo "<td class=tdcenter>";
d9f8a37a
DO
1929 if ($target == $item['id'])
1930 echo "<a name=netid${target}></a>";
64347dcf
DO
1931 if (getConfigVar ('IPV4_TREE_SHOW_USAGE') == 'yes')
1932 {
b1e39212
DO
1933 renderProgressBar ($maxdirect ? $used/$maxdirect : 0);
1934 echo "<br><small>${used}/${maxdirect}" . ($maxdirect == $maxtotal ? '' : "/${maxtotal}") . '</small>';
64347dcf
DO
1935 }
1936 else
b1e39212 1937 echo "<small>${maxdirect}</small>";
64347dcf 1938 echo "</td>";
0137d53c 1939 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
5b886806 1940 printRoutersTD (findRouters ($item['addrlist']));
0137d53c 1941 echo "</tr>";
fec0c8da 1942 if ($item['symbol'] == 'node-expanded' or $item['symbol'] == 'node-expanded-static')
5b886806 1943 $self ($item['kids'], $baseurl, $target, $level + 1);
0137d53c
DO
1944 }
1945 else
1946 {
0137d53c 1947 echo "<tr valign=top>";
fec0c8da 1948 printIPv4NetInfoTDs ($item, 'tdleft sparenetwork', $level, $item['symbol']);
0137d53c 1949 echo "<td class=tdcenter>";
64347dcf
DO
1950 if (getConfigVar ('IPV4_TREE_SHOW_USAGE') == 'yes')
1951 {
b1e39212
DO
1952 renderProgressBar ($used/$maxtotal, 'sparenetwork');
1953 echo "<br><small>${used}/${maxtotal}</small>";
64347dcf
DO
1954 }
1955 else
b1e39212 1956 echo "<small>${maxtotal}</small>";
64347dcf 1957 echo "</td><td>&nbsp;</td></tr>";
0137d53c 1958 }
d65353ad
DO
1959 }
1960}
1961
04d619d0 1962function renderIPv4Space ()
e673ee24 1963{
4fbb5a00 1964 global $pageno, $tabno;
31c941ec
DO
1965 $cellfilter = getCellFilter();
1966 $netlist = filterCellList (listCells ('ipv4net'), $cellfilter['expression']);
573214e0 1967 array_walk ($netlist, 'amplifyCell');
4fbb5a00 1968
94a40058 1969 $netcount = count ($netlist);
5388794d
DO
1970 // expand request can take either natural values or "ALL". Zero means no expanding.
1971 $eid = isset ($_REQUEST['eid']) ? $_REQUEST['eid'] : 0;
1972 $tree = prepareIPv4Tree ($netlist, $eid);
3630d1fb
DO
1973
1974 echo "<table border=0 class=objectview>\n";
1975 echo "<tr><td class=pcleft>";
94a40058 1976 startPortlet ("networks (${netcount})");
5388794d
DO
1977 echo '<h4>';
1978 if ($eid === 0)
65085888
DO
1979 echo 'auto-collapsing at threshold ' . getConfigVar ('TREE_THRESHOLD') .
1980 " (<a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno, 'eid'=>'ALL')) .
1981 $cellfilter['urlextra'] . "'>expand all</a>)";
5388794d 1982 elseif ($eid === 'ALL')
65085888
DO
1983 echo "expanding all (<a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno)) .
1984 $cellfilter['urlextra'] . "'>auto-collapse</a>)";
5388794d
DO
1985 else
1986 {
d724d290 1987 $netinfo = spotEntity ('ipv4net', $eid);
4fbb5a00 1988 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
1989 }
1990 echo "</h4><table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
64347dcf 1991 echo "<tr><th>prefix</th><th>name/tags</th><th>capacity</th>";
f0ed1181 1992 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
57dece2f
DO
1993 echo "<th>routed by</th>";
1994 echo "</tr>\n";
a8efc03e 1995 $baseurl = makeHref(array('page'=>$pageno, 'tab'=>$tabno)) . $cellfilter['urlextra'];
5b886806 1996 renderIPv4SpaceRecords ($tree, $baseurl, $eid);
e673ee24 1997 echo "</table>\n";
a7fe7729 1998 finishPortlet();
74ccacff 1999 echo '</td><td class=pcright>';
3d670bba 2000 renderCellFilterPortlet ($cellfilter, 'ipv4net');
74ccacff 2001 echo "</td></tr></table>\n";
f973f491 2002}
a7fe7729 2003
f973f491
DO
2004function renderIPv4SLB ()
2005{
4fbb5a00 2006 global $page, $nextorder;
a7fe7729 2007
6fec9f39 2008 startPortlet ('SLB configuration');
b3c50e6c 2009 echo "<table border=0 width='100%'><tr>";
ee437dab 2010 foreach (array ('ipv4vslist', 'ipv4rsplist', 'rservers', 'lbs') as $pno)
4fbb5a00 2011 echo "<td><h3><a href='".makeHref(array('page'=>$pno))."'>" . $page[$pno]['title'] . "</a></h3></td>";
b3c50e6c
DO
2012 echo '</tr></table>';
2013 finishPortlet();
2014
c3bdc503 2015 $summary = getSLBSummary();
6fec9f39 2016 startPortlet ('SLB tactical overview');
4cadac8f
DO
2017 // A single id-keyed array isn't used here to preserve existing
2018 // order of LBs returned by getSLBSummary()
c3bdc503
DO
2019 $lblist = array();
2020 $lbdname = array();
4cadac8f 2021 foreach ($summary as $vipdata)
da04825a 2022 foreach (array_keys ($vipdata['lblist']) as $lb_object_id)
c3bdc503
DO
2023 if (!in_array ($lb_object_id, $lblist))
2024 {
fb6e2f57 2025 $oi = spotEntity ('object', $lb_object_id);
c3bdc503
DO
2026 $lbdname[$lb_object_id] = $oi['dname'];
2027 $lblist[] = $lb_object_id;
2028 }
2029 if (!count ($summary))
2030 echo 'none configured';
2031 else
2032 {
80e85ea1 2033 $order = 'odd';
c3bdc503 2034 echo "<table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
b1a970c7 2035 echo "<tr valign=top><td>&nbsp;</td>";
c3bdc503 2036 foreach ($lblist as $lb_object_id)
b1a970c7 2037 {
4fbb5a00 2038 #echo "<th><a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$lb_object_id))."'>" . $lbdname[$lb_object_id] . "</a></th>";
b1a970c7
DO
2039 echo '<td>';
2040 renderLBCell ($lb_object_id);
2041 echo '</td>';
2042 }
c3bdc503 2043 echo "</tr>\n";
4cadac8f
DO
2044 foreach ($summary as $vsid => $vsdata)
2045 {
b1a970c7 2046 echo "<tr class=row_${order}><td class=tdleft>";
6df2025d 2047 renderCell (spotEntity ('ipv4vs', $vsid));
6fec9f39 2048 echo "</td>";
4cadac8f 2049 foreach ($lblist as $lb_object_id)
da04825a 2050 {
60fbcece 2051 echo '<td class=tdleft>';
2b4eee17 2052 if (!isset ($vsdata['lblist'][$lb_object_id]))
da04825a
DO
2053 echo '&nbsp;';
2054 else
6fec9f39
DO
2055 {
2056 echo $vsdata['lblist'][$lb_object_id]['size'];
4fbb5a00 2057// echo " (<a href='".makeHref(array('page'=>'ipv4rspool', 'pool_id'=>$vsdata['lblist'][$lb_object_id]['id'])). "'>";
79a9edb4 2058// echo $vsdata['lblist'][$lb_object_id]['name'] . '</a>)';
6fec9f39 2059 }
da04825a
DO
2060 echo '</td>';
2061 }
2062 echo "</tr>\n";
80e85ea1 2063 $order = $nextorder[$order];
4cadac8f 2064 }
c3bdc503
DO
2065 echo "</table>\n";
2066 }
a7fe7729 2067 finishPortlet ();
e673ee24
DO
2068}
2069
04d619d0 2070function renderIPv4SpaceEditor ()
e673ee24 2071{
a262e150
DO
2072 // IPv4 validator
2073?>
2074 <script type="text/javascript">
2075 function init() {
2076 document.add_new_range.range.setAttribute('match', "^\\d\\d?\\d?\\.\\d\\d?\\d?\\.\\d\\d?\\d?\\.\\d\\d?\\d?\\/\\d\\d?$");
2077
2078 Validate.init();
2079 }
2080 window.onload=init;
2081 </script>
2082<?php
2083
4c0653e2 2084 startPortlet ("Add new");
04d619d0 2085 echo '<table border=0 cellpadding=10 align=center>';
7056988c
DO
2086 // This form requires a name, so JavaScript validator can find it.
2087 // No printOpFormIntro() hence
4fbb5a00 2088 echo "<form method=post name='add_new_range' action='".makeHrefProcess()."'>\n";
42023f03 2089 echo "<input type=hidden name=op value=addIPv4Prefix>\n";
04d619d0
DO
2090 // tags column
2091 echo '<tr><td rowspan=4><h3>assign tags</h3>';
a26a6ccc 2092 renderNewEntityTags ('ipv4net');
04d619d0
DO
2093 echo '</td>';
2094 // inputs column
f06fe423
DO
2095 $prefix_value = empty ($_REQUEST['set-prefix']) ? '' : $_REQUEST['set-prefix'];
2096 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 2097 echo "<tr><th class=tdright>name</th><td class=tdleft><input type=text name='name' size='20' tabindex=2></td></tr>";
0c16ef0c 2098 echo "<tr><th class=tdright>connected network</th><td class=tdleft><input type=checkbox name='is_bcast' tabindex=3></td></tr>";
04d619d0 2099 echo "<tr><td colspan=2>";
4c0653e2 2100 printImageHREF ('CREATE', 'Add a new network', TRUE, 4);
04d619d0 2101 echo '</td></tr>';
2a201216 2102 echo "</form></table><br><br>\n";
5c0bb421 2103 finishPortlet();
2a201216 2104
ab1283b7 2105 if (count ($addrspaceList = listCells ('ipv4net')))
e673ee24 2106 {
e43a2de4 2107 startPortlet ('Manage existing (' . count ($addrspaceList) . ')');
04d619d0 2108 echo "<table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
b1e39212
DO
2109 echo "<tr><th>&nbsp;</th><th>prefix</th><th>name</th><th>capacity</th></tr>";
2110 if (getConfigVar ('IPV4_JAYWALK') != 'yes')
2111 {
2112 array_walk ($addrspaceList, 'amplifyCell');
2113 $tree = prepareIPv4Tree ($addrspaceList, 'ALL');
2114 // this is only called for having "trace" set
2115 treeFromList ($addrspaceList);
2116 }
0c16ef0c 2117 foreach ($addrspaceList as $netinfo)
e673ee24 2118 {
b1e39212
DO
2119 $netinfo = peekNode ($tree, $netinfo['trace'], $netinfo['id']);
2120 // now we have all subnets listed in netinfo
2121 loadIPv4AddrList ($netinfo);
2122 $used = $netinfo['addrc'];
2123 $maxdirect = $netinfo['addrt'];
2124 $maxtotal = binInvMaskFromDec ($netinfo['mask']) + 1;
e43a2de4
DO
2125 echo "<tr valign=top><td>";
2126 if (getConfigVar ('IPV4_JAYWALK') == 'yes')
2127 {
2128 echo "<a href='".makeHrefProcess(array('op'=>'delIPv4Prefix', 'id'=>$netinfo['id']))."'>";
2129 printImageHREF ('destroy', 'Delete this prefix');
2130 echo "</a>";
2131 }
2132 else // only render clickable image for empty networks
2133 {
ab1283b7
DO
2134 if (count ($netinfo['addrlist']))
2135 printImageHREF ('nodestroy', 'There are ' . count ($netinfo['addrlist']) . ' allocations inside');
e43a2de4
DO
2136 else
2137 {
2138 echo "<a href='".makeHrefProcess(array('op'=>'delIPv4Prefix', 'id'=>$netinfo['id']))."'>";
2139 printImageHREF ('destroy', 'Delete this prefix');
2140 echo "</a>";
2141 }
2142
2143 }
ab1283b7
DO
2144 echo '</td><td class=tdleft><a href="' . makeHref (array ('page' => 'ipv4net', 'id' => $netinfo['id'])) . '">';
2145 echo "${netinfo['ip']}/${netinfo['mask']}</a></td>";
b1e39212
DO
2146 echo '<td class=tdleft>' . htmlspecialchars ($netinfo['name']) . '</td><td>';
2147 renderProgressBar ($maxdirect ? $used/$maxdirect : 0);
2148 echo "<br><small>${used}/${maxdirect}" . ($maxdirect == $maxtotal ? '' : "/${maxtotal}") . '</small></td>';
2149 echo '</tr>';
e673ee24 2150 }
04d619d0
DO
2151 echo "</table>";
2152 finishPortlet();
e673ee24 2153 }
e673ee24
DO
2154}
2155
beb9e88a 2156function renderIPv4Network ($id)
e673ee24 2157{
c8824ff4 2158 global $pageno, $tabno, $aac2, $netmaskbylen, $wildcardbylen;
b901bf1f 2159 $maxperpage = getConfigVar ('IPV4_ADDRS_PER_PAGE');
e673ee24
DO
2160 if (isset($_REQUEST['pg']))
2161 $page = $_REQUEST['pg'];
2162 else
2163 $page=0;
2164
d724d290 2165 $range = spotEntity ('ipv4net', $id);
b6b87070 2166 loadIPv4AddrList ($range);
2034d968 2167 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
99ab184f
DO
2168 echo "<tr><td colspan=2 align=center><h1>${range['ip']}/${range['mask']}</h1><h2>";
2169 echo htmlspecialchars ($range['name'], ENT_QUOTES, 'UTF-8') . "</h2></td></tr>\n";
2034d968
DO
2170
2171 echo "<tr><td class=pcleft width='50%'>";
2172 startPortlet ('summary');
2173 $total = ($range['ip_bin'] | $range['mask_bin_inv']) - ($range['ip_bin'] & $range['mask_bin']) + 1;
2174 $used = count ($range['addrlist']);
2175 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
04d619d0
DO
2176
2177 echo "<tr><th width='50%' class=tdright>%% used:</th><td class=tdleft>";
2034d968
DO
2178 renderProgressBar ($used/$total);
2179 echo "&nbsp;${used}/${total}</td></tr>\n";
04d619d0 2180
001e61fa
DO
2181 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
2182 {
3444ecf2
DO
2183 // Build a backtrace from all parent networks.
2184 $clen = $range['mask'];
2185 $backtrace = array();
2186 while (NULL !== ($upperid = getIPv4AddressNetworkId ($range['ip'], $clen)))
2187 {
d724d290 2188 $upperinfo = spotEntity ('ipv4net', $upperid);
3444ecf2 2189 $clen = $upperinfo['mask'];
d724d290 2190 $backtrace[] = $upperinfo;
3444ecf2
DO
2191 }
2192 $arrows = count ($backtrace);
d724d290 2193 foreach (array_reverse ($backtrace) as $ainfo)
001e61fa 2194 {
3444ecf2
DO
2195 echo "<tr><th width='50%' class=tdright>";
2196 for ($i = 0; $i < $arrows; $i++)
2197 echo '&uarr;';
2198 $arrows--;
5d3dcb8d 2199 echo "</th><td class=tdleft>";
6df2025d 2200 renderCell ($ainfo);
5d3dcb8d 2201 echo "</td></tr>";
001e61fa 2202 }
3444ecf2 2203 echo "<tr><th width='50%' class=tdright>&rarr;</th>";
5d3dcb8d 2204 echo "<td class=tdleft>";
6df2025d 2205 renderCell ($range);
5d3dcb8d 2206 echo "</td></tr>";
001e61fa
DO
2207 // FIXME: get and display nested networks
2208 // $theitem = pickLeaf ($ipv4tree, $id);
2209 }
2210
545478d0
DO
2211 echo "<tr><th width='50%' class=tdright>Netmask:</th><td class=tdleft>";
2212 echo $netmaskbylen[$range['mask']];
2213 echo "</td></tr>\n";
04d619d0 2214
c607ab55
DO
2215 echo "<tr><th width='50%' class=tdright>Netmask:</th><td class=tdleft>";
2216 printf ('0x%08X', binMaskFromDec ($range['mask']));
2217 echo "</td></tr>\n";
2218
545478d0
DO
2219 echo "<tr><th width='50%' class=tdright>Wildcard bits:</th><td class=tdleft>";
2220 echo $wildcardbylen[$range['mask']];
2221 echo "</td></tr>\n";
04d619d0 2222
f3d0cb20 2223 $routers = findRouters ($range['addrlist']);
f0ed1181 2224 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes' and count ($routers))
04d619d0 2225 {
57dece2f 2226 echo "<tr><th width='50%' class=tdright>Routed by:</th>";
f3d0cb20 2227 printRoutersTD ($routers);
57dece2f 2228 echo "</tr>\n";
04d619d0
DO
2229 }
2230
9b57f793 2231 printTagTRs ($range, makeHref(array('page'=>'ipv4space', 'tab'=>'default'))."&");
2034d968
DO
2232 echo "</table><br>\n";
2233 finishPortlet();
e1ae3fb4 2234
99ab184f
DO
2235 if (strlen ($range['comment']))
2236 {
2237 startPortlet ('Comment');
2238 echo '<div class=commentblock>' . string_insert_hrefs (htmlspecialchars ($range['comment'], ENT_QUOTES, 'UTF-8')) . '</div>';
2239 finishPortlet ();
2240 }
2241
e1ae3fb4 2242 renderFilesPortlet ('ipv4net', $id);
2034d968 2243 echo "</td>\n";
e673ee24 2244
2034d968
DO
2245 echo "<td class=pcright>";
2246 startPortlet ('details');
e673ee24
DO
2247 $startip = $range['ip_bin'] & $range['mask_bin'];
2248 $endip = $range['ip_bin'] | $range['mask_bin_inv'];
2249 $realstartip = $startip;
2250 $realendip = $endip;
2251 $numpages = 0;
2252 if($endip - $startip > $maxperpage)
2253 {
e673ee24
DO
2254 $numpages = ($endip - $startip)/$maxperpage;
2255 $startip = $startip + $page * $maxperpage;
2256 $endip = $startip + $maxperpage-1;
2257 }
2258 echo "<center>";
b901bf1f
DO
2259 if ($numpages)
2260 echo '<h3>' . long2ip ($startip) . ' ~ ' . long2ip ($endip) . '</h3>';
e673ee24
DO
2261 for ($i=0; $i<$numpages; $i++)
2262 {
2263 if ($i == $page)
2264 echo "<b>$i</b> ";
2265 else
4fbb5a00 2266 echo "<a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno, 'id'=>$id, 'pg'=>$i))."'>$i</a> ";
e673ee24
DO
2267 }
2268 echo "</center>";
2269
beb9e88a 2270 echo "<table class='widetable' border=0 cellspacing=0 cellpadding=5 align='center' width='100%'>\n";
e673ee24
DO
2271 echo "<tr><th>Address</th><th>Name</th><th>Allocation</th></tr>\n";
2272
2273
b2035dca
DO
2274 for ($ip = $startip; $ip <= $endip; $ip++) :
2275 if (isset ($_REQUEST['hl_ipv4_addr']) and ip2long ($_REQUEST['hl_ipv4_addr']) == $ip)
2276 $secondstyle = 'tdleft port_highlight';
2727c7df 2277 else
b2035dca
DO
2278 $secondstyle = 'tdleft';
2279 if (!isset ($range['addrlist'][$ip]))
e673ee24 2280 {
4fbb5a00 2281 echo "<tr><td class=tdleft><a href='".makeHref(array('page'=>'ipaddress', 'ip'=>ip_long2quad($ip)))."'>" . ip_long2quad($ip);
b2035dca
DO
2282 echo "</a></td><td class='${secondstyle}'>&nbsp;</td><td class='${secondstyle}'>&nbsp;</td></tr>\n";
2283 continue;
2284 }
b2035dca 2285 $addr = $range['addrlist'][$ip];
2d318652 2286 echo "<tr class='${addr['class']}'>";
e673ee24 2287
4fbb5a00 2288 echo "<td class=tdleft><a href='".makeHref(array('page'=>'ipaddress', 'ip'=>$addr['ip']))."'>${addr['ip']}</a></td>";
b2035dca
DO
2289 echo "<td class='${secondstyle}'>${addr['name']}</td><td class='${secondstyle}'>";
2290 $delim = '';
2291 $prologue = '';
2292 if ( $addr['reserved'] == 'yes')
2293 {
2d318652 2294 echo "<strong>RESERVED</strong> ";
b2035dca
DO
2295 $delim = '; ';
2296 }
2d318652 2297 foreach ($range['addrlist'][$ip]['allocs'] as $ref)
b2035dca 2298 {
beb9e88a 2299 echo $delim . $aac2[$ref['type']];
4fbb5a00 2300 echo "<a href='".makeHref(array('page'=>'object', 'object_id'=>$ref['object_id'], 'hl_ipv4_addr'=>$addr['ip']))."'>";
59a83bd8 2301 echo $ref['name'] . (!strlen ($ref['name']) ? '' : '@');
b2035dca
DO
2302 echo "${ref['object_name']}</a>";
2303 $delim = '; ';
2304 }
2305 if ($delim != '')
2306 {
6131056c 2307 $delim = '';
b2035dca
DO
2308 $prologue = '<br>';
2309 }
2d318652 2310 foreach ($range['addrlist'][$ip]['lblist'] as $ref)
b2035dca
DO
2311 {
2312 echo $prologue;
602663f4 2313 $prologue = '';
4fbb5a00
DY
2314 echo "${delim}<a href='".makeHref(array('page'=>'object', 'object_id'=>$ref['object_id']))."'>";
2315 echo "${ref['object_name']}</a>:<a href='".makeHref(array('page'=>'ipv4vs', 'vs_id'=>$ref['vs_id']))."'>";
b2035dca
DO
2316 echo "${ref['vport']}/${ref['proto']}</a>&rarr;";
2317 $delim = '; ';
2318 }
2319 if ($delim != '')
2320 {
2321 $delim = '';
2322 $prologue = '<br>';
e673ee24 2323 }
2d318652 2324 foreach ($range['addrlist'][$ip]['rslist'] as $ref)
b2035dca
DO
2325 {
2326 echo $prologue;
2327 $prologue = '';
4fbb5a00 2328 echo "${delim}&rarr;${ref['rsport']}@<a href='".makeHref(array('page'=>'ipv4rspool', 'pool_id'=>$ref['rspool_id']))."'>";
b2035dca
DO
2329 echo "${ref['rspool_name']}</a>";
2330 $delim = '; ';
2331 }
2332 echo "</td></tr>\n";
2333 endfor;
2727c7df 2334 // end of iteration
e673ee24
DO
2335
2336 echo "</table>";
2034d968
DO
2337 finishPortlet();
2338 echo "</td></tr></table>\n";
e673ee24
DO
2339}
2340
53ef3908 2341function renderIPv4NetworkProperties ($id)
e673ee24 2342{
d724d290 2343 $netdata = spotEntity ('ipv4net', $id);
53ef3908 2344 echo "<center><h1>${netdata['ip']}/${netdata['mask']}</h1></center>\n";
e673ee24 2345 echo "<table border=0 cellpadding=10 cellpadding=1 align='center'>\n";
7056988c 2346 printOpFormIntro ('editRange');
99ab184f
DO
2347 echo '<tr><td class=tdright><label for=nameinput>Name:</label></td>';
2348 echo "<td class=tdleft><input type=text name=name id=nameinput size=80 maxlength=255 value='";
2349 echo htmlspecialchars ($netdata['name'], ENT_QUOTES, 'UTF-8') . "'></tr>";
2350 echo '<tr><td class=tdright><label for=commentinput>Comment:</label></td>';
2351 echo "<td class=tdleft><textarea name=comment id=commentinput cols=80 rows=25>\n";
2352 echo htmlspecialchars ($netdata['comment'], ENT_QUOTES, 'UTF-8') . "</textarea></tr>";
53ef3908
DO
2353 echo "<tr><td colspan=2 class=tdcenter>";
2354 printImageHREF ('SAVE', 'Save changes', TRUE);
2355 echo "</td></form></tr></table>\n";
e673ee24
DO
2356}
2357
2d318652 2358function renderIPv4Address ($dottedquad)
e673ee24 2359{
46098972 2360 global $aat, $nextorder;
2d318652 2361 $address = getIPv4Address ($dottedquad);
68225375 2362 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
2d318652 2363 echo "<tr><td colspan=2 align=center><h1>${dottedquad}</h1></td></tr>\n";
59a83bd8 2364 if (strlen ($address['name']))
68225375 2365 echo "<tr><td colspan=2 align=center><h2>${address['name']}</h2></td></tr>\n";
e673ee24 2366
68225375
DO
2367 echo "<tr><td class=pcleft>";
2368 startPortlet ('summary');
2369 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
04d619d0 2370 echo "<tr><th width='50%' class=tdright>Allocations:</th><td class=tdleft>" . count ($address['allocs']) . "</td></tr>\n";
68225375
DO
2371 echo "<tr><th width='50%' class=tdright>Originated NAT connections:</th><td class=tdleft>" . count ($address['outpf']) . "</td></tr>\n";
2372 echo "<tr><th width='50%' class=tdright>Arriving NAT connections:</th><td class=tdleft>" . count ($address['inpf']) . "</td></tr>\n";
04d619d0 2373 echo "<tr><th width='50%' class=tdright>SLB virtual services:</th><td class=tdleft>" . count ($address['lblist']) . "</td></tr>\n";
68225375 2374 echo "<tr><th width='50%' class=tdright>SLB real servers:</th><td class=tdleft>" . count ($address['rslist']) . "</td></tr>\n";
68225375
DO
2375 echo "</table><br>\n";
2376 finishPortlet();
2377 echo "</td>\n";
e673ee24 2378
68225375 2379 echo "<td class=pcright>";
e673ee24 2380
f74d96c6 2381 if (isset ($address['class']))
59bebe2b 2382 {
8e700dd1 2383 startPortlet ('allocations');
2d318652
DO
2384 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
2385 echo "<tr><th>object</th><th>OS interface</th><th>allocation type</th></tr>\n";
2386 $class = $address['class'];
2387 // render all allocation records for this address the same way
59bebe2b 2388 if ($address['reserved'] == 'yes')
2d318652
DO
2389 echo "<tr class='${class}'><td colspan=2>&nbsp;</td><td class=tdleft><strong>RESERVED</strong></td></tr>";
2390 foreach ($address['allocs'] as $bond)
59bebe2b 2391 {
8e700dd1
DO
2392 if (isset ($_REQUEST['hl_object_id']) and $_REQUEST['hl_object_id'] == $bond['object_id'])
2393 $secondclass = 'tdleft port_highlight';
2394 else
2395 $secondclass = 'tdleft';
4fbb5a00 2396 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
2397 echo $aat[$bond['type']];
2398 echo "</strong></td></tr>\n";
59bebe2b
DO
2399 }
2400 echo "</table><br><br>";
2401 finishPortlet();
2402 }
e673ee24 2403
f3d0cb20
DO
2404 // FIXME: The returned list is structured differently, than we expect it to be. One of the sides
2405 // must be fixed.
2d318652 2406 if (count ($address['lblist']))
e673ee24 2407 {
2d318652
DO
2408 startPortlet ('Virtual services (' . count ($address['lblist']) . ')');
2409 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
46098972
DO
2410 echo "<tr><th>VS</th><th>LB</th></tr>\n";
2411 $order = 'odd';
2d318652 2412 foreach ($address['lblist'] as $vsinfo)
e673ee24 2413 {
46098972
DO
2414 echo "<tr valign=top class=row_${order}><td class=tdleft>";
2415 renderCell (spotEntity ('ipv4vs', $vsinfo['vs_id']));
2416 echo "</td><td class=tdleft>";
2417 renderLBCell ($vsinfo['object_id']);
2418 echo "</td></tr>";
2419 $order = $nextorder[$order];
e673ee24 2420 }
59bebe2b
DO
2421 echo "</table><br><br>";
2422 finishPortlet();
e673ee24 2423 }
5fe1ed76
DO
2424
2425 if (count ($address['rslist']))
2426 {
2427 startPortlet ('Real servers (' . count ($address['rslist']) . ')');
2d318652 2428 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
53f4b619 2429 echo "<tr><th>&nbsp;</th><th>port</th><th>RS pool</th></tr>\n";
5fe1ed76
DO
2430 foreach ($address['rslist'] as $rsinfo)
2431 {
2432 echo "<tr><td>";
2433 if ($rsinfo['inservice'] == 'yes')
2434 printImageHREF ('inservice', 'in service');
2435 else
2436 printImageHREF ('notinservice', 'NOT in service');
4fbb5a00 2437 echo "</td><td class=tdleft>${rsinfo['rsport']}</td><td class=tdleft><a href='".makeHref(array('page'=>'ipv4rspool', 'pool_id'=>$rsinfo['rspool_id']))."'>";
2d318652 2438 echo $rsinfo['rspool_name'] . "</a></td></tr>\n";
5fe1ed76
DO
2439 }
2440 echo "</table><br><br>";
2441 finishPortlet();
2442 }
2443
68225375
DO
2444 if (count ($address['outpf']))
2445 {
105a3bc8 2446 startPortlet ('departing NAT rules');
2d318652 2447 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
105a3bc8
DO
2448 echo "<tr><th>proto</th><th>from</th><th>to</th><th>comment</th></tr>\n";
2449 foreach ($address['outpf'] as $rule)
b62ff880 2450 echo "<tr><td>${rule['proto']}</td><td>${rule['localip']}:${rule['localport']}</td><td>${rule['remoteip']}:${rule['remoteport']}</td><td>${rule['description']}</td></tr>";
105a3bc8 2451 echo "</table>";
68225375
DO
2452 finishPortlet();
2453 }
105a3bc8
DO
2454
2455 if (count ($address['inpf']))
2456 {
2457 startPortlet ('arriving NAT rules');
2d318652 2458 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
105a3bc8
DO
2459 echo "<tr><th>proto</th><th>from</th><th>to</th><th>comment</th></tr>\n";
2460 foreach ($address['inpf'] as $rule)
b62ff880 2461 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
2462 echo "</table>";
2463 finishPortlet();
2464 }
2465
68225375
DO
2466 echo "</td></tr>";
2467 echo "</table>\n";
e673ee24
DO
2468}
2469
2d318652 2470function renderIPv4AddressProperties ($dottedquad)
e673ee24 2471{
2d318652
DO
2472 $address = getIPv4Address ($dottedquad);
2473 echo "<center><h1>$dottedquad</h1></center>\n";
7056988c 2474
1fbc9fd6 2475 startPortlet ('update');
e673ee24 2476 echo "<table border=0 cellpadding=10 cellpadding=1 align='center'>\n";
7056988c 2477 printOpFormIntro ('editAddress');
2d318652
DO
2478 echo "<tr><td class='tdright'>Name:</td><td class='tdleft'><input type=text name=name size=20 value='${address['name']}'></tr>";
2479 echo "<td class='tdright'>Reserved:</td><td class='tdleft'><input type=checkbox name=reserved size=20 ";
2480 echo ($address['reserved']=='yes') ? 'checked' : '';
f3d274bf 2481 echo "></tr><tr><td class=tdleft>";
53ef3908 2482 printImageHREF ('SAVE', 'Save changes', TRUE);
f3d274bf 2483 echo "</td></form><td class=tdright>";
59a83bd8 2484 if (!strlen ($address['name']) and $address['reserved'] == 'no')
f3d274bf
DO
2485 printImageHREF ('CLEAR gray');
2486 else
2487 {
2488 printOpFormIntro ('editAddress', array ('name' => '', 'reserved' => ''));
2489 printImageHREF ('CLEAR', 'Release', TRUE);
2490 echo "</form>";
2491 }
2492 echo "</td></tr></table>\n";
1fbc9fd6 2493 finishPortlet();
e673ee24
DO
2494}
2495
2d318652 2496function renderIPv4AddressAllocations ($dottedquad)
e673ee24 2497{
39b4abd0
DO
2498 function printNewItemTR ()
2499 {
2500 global $aat;
2501 printOpFormIntro ('addIPv4Allocation');
2502 echo "<tr><td>";
9318d2ef 2503 printImageHREF ('add', 'allocate', TRUE);
8d4f7d18 2504 echo "</td><td>";
c6bc0ac5 2505 printSelect (getNarrowObjectList ('IPV4OBJ_LISTSRC'), 'object_id', NULL, 100);
8d4f7d18 2506 echo "</td><td><input type=text tabindex=101 name=bond_name size=10></td><td>";
f5ff50f5 2507 printSelect ($aat, 'bond_type', NULL, 102);
9318d2ef 2508 echo "</td><td>";
f5ff50f5 2509 printImageHREF ('add', 'allocate', TRUE, 103);
9318d2ef 2510 echo "</td></form></tr>";
39b4abd0 2511 }
b82cce3f 2512 global $aat;
e673ee24 2513
2d318652 2514 $address = getIPv4Address ($dottedquad);
f74d96c6 2515
2d318652 2516 echo "<center><h1>${dottedquad}</h1></center>\n";
105a3bc8 2517 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
2d318652 2518 echo "<tr><th>&nbsp;</th><th>object</th><th>OS interface</th><th>allocation type</th><th>&nbsp;</th></tr>\n";
e673ee24 2519
39b4abd0
DO
2520 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
2521 printNewItemTR();
f74d96c6 2522 if (isset ($address['class']))
e673ee24 2523 {
f74d96c6
DO
2524 $class = $address['class'];
2525 if ($address['reserved'] == 'yes')
2526 echo "<tr class='${class}'><td colspan=3>&nbsp;</td><td class=tdleft><strong>RESERVED</strong></td><td>&nbsp;</td></tr>";
2527 foreach ($address['allocs'] as $bond)
2528 {
2529 echo "<tr class='$class'>";
2530 printOpFormIntro ('updIPv4Allocation', array ('object_id' => $bond['object_id']));
4fbb5a00 2531 echo "<td><a href='".makeHrefProcess(array('op'=>'delIPv4Allocation', 'ip'=>$dottedquad, 'object_id'=>$bond['object_id']))."'>";
f74d96c6
DO
2532 printImageHREF ('delete', 'Unallocate address');
2533 echo "</a></td>";
4fbb5a00 2534 echo "<td><a href='".makeHref(array('page'=>'object', 'object_id'=>$bond['object_id'], 'hl_ipv4_addr'=>$dottedquad))."'>${bond['object_name']}</td>";
f74d96c6
DO
2535 echo "<td><input type='text' name='bond_name' value='${bond['name']}' size=10></td><td>";
2536 printSelect ($aat, 'bond_type', $bond['type']);
2537 echo "</td><td>";
2538 printImageHREF ('save', 'Save changes', TRUE);
2539 echo "</td></form></tr>\n";
2540 }
e673ee24 2541 }
39b4abd0
DO
2542 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
2543 printNewItemTR();
e673ee24 2544 echo "</table><br><br>";
e673ee24
DO
2545}
2546
7e1db771 2547function renderNATv4ForObject ($object_id)
e673ee24 2548{
9318d2ef
DO
2549 function printNewItemTR ($alloclist)
2550 {
9318d2ef
DO
2551 printOpFormIntro ('addNATv4Rule');
2552 echo "<tr align='center'><td>";
2553 printImageHREF ('add', 'Add new NAT rule', TRUE);
2554 echo '</td><td>';
2555 printSelect (array ('TCP' => 'TCP', 'UDP' => 'UDP'), 'proto');
2556 echo "<select name='localip' tabindex=1>";
2557
2558 foreach ($alloclist as $dottedquad => $alloc)
2559 {
43eb71f1
DO
2560 $name = (!isset ($alloc['addrinfo']['name']) or !strlen ($alloc['addrinfo']['name'])) ? '' : (' (' . niftyString ($alloc['addrinfo']['name']) . ')');
2561 $osif = (!isset ($alloc['osif']) or !strlen ($alloc['osif'])) ? '' : ($alloc['osif'] . ': ');
9318d2ef
DO
2562 echo "<option value='${dottedquad}'>${osif}${dottedquad}${name}</option>";
2563 }
2564
2565 echo "</select>:<input type='text' name='localport' size='4' tabindex=2></td>";
2566 echo "<td><input type='text' name='remoteip' id='remoteip' size='10' tabindex=3>";
39106006
DO
2567 echo "<a href='javascript:;' onclick='window.open(\"" . makeHrefForHelper ('inet4list');
2568 echo "\", \"findobjectip\", \"height=700, width=400, location=no, menubar=no, resizable=yes, scrollbars=no, status=no, titlebar=no, toolbar=no\");'>";
9318d2ef
DO
2569 printImageHREF ('find', 'Find object');
2570 echo "</a>";
2571 echo ":<input type='text' name='remoteport' size='4' tabindex=4></td><td></td>";
2572 echo "<td colspan=1><input type='text' name='description' size='20' tabindex=5></td><td>";
f5ff50f5 2573 printImageHREF ('add', 'Add new NAT rule', TRUE, 6);
9318d2ef
DO
2574 echo "</td></tr></form>";
2575 }
e673ee24 2576
94fe6370
DO
2577 $focus = spotEntity ('object', $object_id);
2578 amplifyCell ($focus);
f28fbe8b 2579 echo "<center><h2>locally performed NAT</h2></center>";
e673ee24 2580
105a3bc8 2581 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
d54b9495 2582 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 2583
9318d2ef 2584 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
94fe6370
DO
2585 printNewItemTR ($focus['ipv4']);
2586 foreach ($focus['nat4']['out'] as $pf)
e673ee24 2587 {
2c817354
DO
2588 $class = 'trerror';
2589 $osif = '';
94fe6370 2590 if (isset ($focus['ipv4'][$pf['localip']]))
2c817354 2591 {
94fe6370
DO
2592 $class = $focus['ipv4'][$pf['localip']]['addrinfo']['class'];
2593 $osif = $focus['ipv4'][$pf['localip']]['osif'] . ': ';
2c817354 2594 }
e673ee24
DO
2595
2596 echo "<tr class='$class'>";
4fbb5a00
DY
2597 echo "<td><a href='".
2598 makeHrefProcess(array(
2599 'op'=>'delNATv4Rule',
2600 'localip'=>$pf['localip'],
2601 'localport'=>$pf['localport'],
2602 'remoteip'=>$pf['remoteip'],
2603 'remoteport'=>$pf['remoteport'],
2604 'proto'=>$pf['proto'],
2605 'object_id'=>$object_id)).
2606 "'>";
4de22e7e
DO
2607 printImageHREF ('delete', 'Delete NAT rule');
2608 echo "</a></td>";
4fbb5a00 2609 echo "<td>${pf['proto']}/${osif}<a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['localip']))."'>${pf['localip']}</a>:${pf['localport']}";
59a83bd8 2610 if (strlen ($pf['local_addr_name']))
f28fbe8b
DO
2611 echo ' (' . $pf['local_addr_name'] . ')';
2612 echo "</td>";
4fbb5a00 2613 echo "<td><a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['remoteip']))."'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
e673ee24 2614
53ef3908 2615 $address = getIPv4Address ($pf['remoteip']);
e673ee24
DO
2616
2617 echo "<td class='description'>";
53ef3908
DO
2618 if (count ($address['allocs']))
2619 foreach ($address['allocs'] as $bond)
4fbb5a00 2620 echo "<a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$bond['object_id']))."'>${bond['object_name']}(${bond['name']})</a> ";
59a83bd8 2621 elseif (strlen ($pf['remote_addr_name']))
f28fbe8b 2622 echo '(' . $pf['remote_addr_name'] . ')';
7056988c
DO
2623 printOpFormIntro
2624 (
2625 'updNATv4Rule',
2626 array
2627 (
2628 'localip' => $pf['localip'],
2629 'localport' => $pf['localport'],
2630 'remoteip' => $pf['remoteip'],
2631 'remoteport' => $pf['remoteport'],
2632 'proto' => $pf['proto']
2633 )
2634 );
2635 echo "</td><td class='description'>";
d54b9495
DO
2636 echo "<input type='text' name='description' value='${pf['description']}'></td><td>";
2637 printImageHREF ('save', 'Save changes', TRUE);
2638 echo "</td></form></tr>";
e673ee24 2639 }
9318d2ef 2640 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
94fe6370 2641 printNewItemTR ($focus['ipv4']);
e673ee24
DO
2642
2643 echo "</table><br><br>";
94fe6370
DO
2644 if (!count ($focus['nat4']))
2645 return;
e673ee24 2646
f28fbe8b 2647 echo "<center><h2>arriving NAT connections</h2></center>";
105a3bc8 2648 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
e673ee24
DO
2649 echo "<tr><th></th><th>Source</th><th>Source objects</th><th>Target</th><th>Description</th></tr>\n";
2650
94fe6370 2651 foreach ($focus['nat4']['in'] as $pf)
e673ee24 2652 {
4fbb5a00
DY
2653 echo "<tr><td><a href='".
2654 makeHrefProcess(array(
2655 'op'=>'delNATv4Rule',
2656 'localip'=>$pf['localip'],
2657 'localport'=>$pf['localport'],
2658 'remoteip'=>$pf['remoteip'],
2659 'remoteport'=>$pf['remoteport'],
2660 'proto'=>$pf['proto'],
2661 'object_id'=>$pf['object_id']
2662 )).
2663 "'>";
4de22e7e
DO
2664 printImageHREF ('delete', 'Delete NAT rule');
2665 echo "</a></td>";
4fbb5a00
DY
2666 echo "<td>${pf['proto']}/<a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['localip']))."'>${pf['localip']}</a>:${pf['localport']}</td>";
2667 echo "<td class='description'><a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$pf['object_id']))."'>${pf['object_name']}</a>";
2668 echo "</td><td><a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['remoteip']))."'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
e673ee24
DO
2669 echo "<td class='description'>${pf['description']}</td></tr>";
2670 }
2671
e673ee24 2672 echo "</table><br><br>";
e673ee24
DO
2673}
2674
e673ee24
DO
2675function renderAddMultipleObjectsForm ()
2676{
7fa7047a 2677 $typelist = readChapter (CHAP_OBJTYPE, 'o');
4c330a14 2678 $typelist[0] = 'select type...';
7fa7047a 2679 $typelist = cookOptgroups ($typelist);
a1886a78
DO
2680 $max = getConfigVar ('MASSCOUNT');
2681 $tabindex = 100;
7f791d1d 2682
f60bb422 2683 startPortlet ('Distinct types, same tags');
42d73cbf 2684 printOpFormIntro ('addObjects');
e673ee24 2685 echo '<table border=0 align=center>';
f60bb422
DO
2686 echo "<tr><th>Object type</th><th>Common name</th><th>Visible label</th>";
2687 echo "<th>Asset tag</th><th>Barcode</th><th>Tags</th></tr>\n";
9c0b0016 2688 for ($i = 0; $i < $max; $i++)
e673ee24 2689 {
7f791d1d 2690 echo '<tr><td>';
e7ade6bf 2691 // Don't employ DEFAULT_OBJECT_TYPE to avoid creating ghost records for pre-selected empty rows.
7fa7047a 2692 printNiftySelect ($typelist, "${i}_object_type_id", 0, $tabindex);
e673ee24 2693 echo '</td>';
a1886a78
DO
2694 echo "<td><input type=text size=30 name=${i}_object_name tabindex=${tabindex}></td>";
2695 echo "<td><input type=text size=30 name=${i}_object_label tabindex=${tabindex}></td>";
2696 echo "<td><input type=text size=20 name=${i}_object_asset_no tabindex=${tabindex}></td>";
2697 echo "<td><input type=text size=10 name=${i}_object_barcode tabindex=${tabindex}></td>";
f60bb422
DO
2698 if ($i == 0)
2699 {
2700 echo "<td valign=top rowspan=${max}>";
a26a6ccc 2701 renderNewEntityTags ('object');
f60bb422
DO
2702 echo "</td>\n";
2703 }
e673ee24 2704 echo "</tr>\n";
a1886a78 2705 $tabindex++;
e673ee24 2706 }
216c84bb 2707 echo "<tr><td class=submit colspan=5><input type=submit name=got_fast_data value='Go!'></td></tr>\n";
e673ee24
DO
2708 echo "</form></table>\n";
2709 finishPortlet();
7f791d1d 2710
f60bb422 2711 startPortlet ('Same type, same tags');
42d73cbf 2712 printOpFormIntro ('addLotOfObjects');
f60bb422
DO
2713 echo "<table border=0 align=center><tr><th>names</th><th>type</th></tr>";
2714 echo "<tr><td rowspan=3><textarea name=namelist cols=40 rows=25>\n";
f60bb422
DO
2715 echo "</textarea></td><td valign=top>";
2716 printSelect ($typelist, "global_type_id", getConfigVar ('DEFAULT_OBJECT_TYPE'));
2717 echo "</td></tr>";
2718 echo "<tr><th>Tags</th></tr>";
2719 echo "<tr><td valign=top>";
a26a6ccc 2720 renderNewEntityTags ('object');
f60bb422
DO
2721 echo "</td></tr>";
2722 echo "<tr><td colspan=2><input type=submit name=got_very_fast_data value='Go!'></td></tr></table>\n";
2723 echo "</form>\n";
7f791d1d 2724 finishPortlet();
e673ee24
DO
2725}
2726
2727function printGreeting ()
2728{
d6d79c36
DO
2729 global $root, $remote_username, $remote_displayname;
2730 echo "Hello, <a href='${root}?page=myaccount&tab=default'>${remote_displayname}</a>. This is RackTables " .
2731 CODE_VERSION .
2732 ". Click <a href='${root}?logout'>here</a> to logout.";
e673ee24
DO
2733}
2734
2735function renderSearchResults ()
2736{
0b9c98d7 2737 global $root;
e673ee24 2738 $terms = trim ($_REQUEST['q']);
59a83bd8 2739 if (!strlen ($terms))
e673ee24 2740 {
591ff2c4 2741 showError ('Search string cannot be empty.', __FUNCTION__);
e673ee24
DO
2742 return;
2743 }
c78a40ec 2744 if (!permitted ('depot', 'default'))
e673ee24 2745 {
591ff2c4 2746 showError ('You are not authorized for viewing information about objects.', __FUNCTION__);
e673ee24
DO
2747 return;
2748 }
ea5fc465 2749 $nhits = 0;
d516d719 2750 if (preg_match (RE_IP4_ADDR, $terms))
64347dcf 2751 // Search for IPv4 address.
e673ee24 2752 {
bb0a44e9 2753 if (NULL !== getIPv4AddressNetworkId ($terms))
e673ee24 2754 {
ea5fc465 2755 $nhits++;
f3d0cb20
DO
2756 $lasthit = 'ipv4addressbydq';
2757 $summary['ipv4addressbydq'][] = $terms;
e673ee24 2758 }
e673ee24 2759 }
05771508 2760 elseif (preg_match (RE_IP4_NET, $terms))
64347dcf
DO
2761 // Search for IPv4 network
2762 {
2763 list ($base, $len) = explode ('/', $terms);
2764 if (NULL !== ($tmp = getIPv4AddressNetworkId ($base, $len + 1)))
2765 {
2766 $nhits++;
2767 $lasthit = 'ipv4network';
d724d290 2768 $summary['ipv4network'][] = spotEntity ('ipv4net', $tmp);
64347dcf
DO
2769 }
2770 }
e673ee24 2771 else
ea5fc465 2772 // Search for objects, addresses, networks, virtual services and RS pools by their description.
e673ee24 2773 {
ea5fc465
DO
2774 $tmp = getObjectSearchResults ($terms);
2775 if (count ($tmp))
e673ee24 2776 {
ea5fc465
DO
2777 $nhits += count ($tmp);
2778 $lasthit = 'object';
2779 $summary['object'] = $tmp;
e673ee24 2780 }
ea5fc465
DO
2781 $tmp = getIPv4AddressSearchResult ($terms);
2782 if (count ($tmp))
e673ee24 2783 {
ea5fc465 2784 $nhits += count ($tmp);
f3d0cb20
DO
2785 $lasthit = 'ipv4addressbydescr';
2786 $summary['ipv4addressbydescr'] = $tmp;
ea5fc465
DO
2787 }
2788 $tmp = getIPv4PrefixSearchResult ($terms);
2789 if (count ($tmp))
2790 {
2791 $nhits += count ($tmp);
2792 $lasthit = 'ipv4network';
2793 $summary['ipv4network'] = $tmp;
2794 }
05411ccd
DO
2795 $tmp = getIPv4RSPoolSearchResult ($terms);
2796 if (count ($tmp))
2797 {
2798 $nhits += count ($tmp);
2799 $lasthit = 'ipv4rspool';
2800 $summary['ipv4rspool'] = $tmp;
2801 }
2802 $tmp = getIPv4VServiceSearchResult ($terms);
2803 if (count ($tmp))
2804 {
2805 $nhits += count ($tmp);
2806 $lasthit = 'ipv4vs';
2807 $summary['ipv4vs'] = $tmp;
2808 }
6a88e734
DO
2809 $tmp = getAccountSearchResult ($terms);
2810 if (count ($tmp))
2811 {
2812 $nhits += count ($tmp);
2813 $lasthit = 'user';
2814 $summary['user'] = $tmp;
2815 }
e1ae3fb4
AD
2816 $tmp = getFileSearchResult ($terms);
2817 if (count ($tmp))
2818 {
2819 $nhits += count ($tmp);
2820 $lasthit = 'file';
2821 $summary['file'] = $tmp;
2822 }
e531b4d6
DO
2823 $tmp = getRackSearchResult ($terms);
2824 if (count ($tmp))
2825 {
2826 $nhits += count ($tmp);
2827 $lasthit = 'rack';
2828 $summary['rack'] = $tmp;
2829 }
ea5fc465
DO
2830 }
2831 if ($nhits == 0)
2832 echo "<center><h2>Nothing found for '${terms}'</h2></center>";
2833 elseif ($nhits == 1)
2834 {
2835 $record = current ($summary[$lasthit]);
2836 switch ($lasthit)
2837 {
f3d0cb20
DO
2838 case 'ipv4addressbydq':
2839 $parentnet = getIPv4AddressNetworkId ($record);
2840 if ($parentnet !== NULL)
e1ae3fb4 2841 echo "<script language='Javascript'>document.location='${root}?page=ipv4net&tab=default&id=${parentnet}&hl_ipv4_addr=${record}';//</script>";
f3d0cb20
DO
2842 else
2843 echo "<script language='Javascript'>document.location='${root}?page=ipaddress&ip=${record}';//</script>";
ea5fc465 2844 break;
f3d0cb20
DO
2845 case 'ipv4addressbydescr':
2846 $parentnet = getIPv4AddressNetworkId ($record['ip']);
2847 if ($parentnet !== NULL)
e1ae3fb4 2848 echo "<script language='Javascript'>document.location='${root}?page=ipv4net&tab=default&id=${parentnet}&hl_ipv4_addr=${record['ip']}';//</script>";
f3d0cb20
DO
2849 else
2850 echo "<script language='Javascript'>document.location='${root}?page=ipaddress&ip=${record['ip']}';//</script>";
ea5fc465
DO
2851 break;
2852 case 'ipv4network':
e1ae3fb4 2853 echo "<script language='Javascript'>document.location='${root}?page=ipv4net";
ea5fc465
DO
2854 echo "&id=${record['id']}";
2855 echo "';//</script>";
2856 break;
2857 case 'object':
1b4a0a6a
DO
2858 if (isset ($record['by_port']) and 1 == count ($record['by_port']))
2859 $hl = '&hl_port_id=' . key ($record['by_port']);
2860 else
2861 $hl = '';
2862 echo "<script language='Javascript'>document.location='${root}?page=object&object_id=${record['id']}${hl}';//</script>";
ea5fc465 2863 break;
05411ccd 2864 case 'ipv4rspool':
f06fe423 2865 echo "<script language='Javascript'>document.location='${root}?page=ipv4rspool&pool_id=${record['id']}';//</script>";
05411ccd
DO
2866 break;
2867 case 'ipv4vs':
49fb2686 2868 echo "<script language='Javascript'>document.location='${root}?page=ipv4vs&vs_id=${record['id']}';//</script>";
05411ccd 2869 break;
6a88e734
DO
2870 case 'user':
2871 echo "<script language='Javascript'>document.location='${root}?page=user&user_id=${record['user_id']}';//</script>";
2872 break;
e1ae3fb4
AD
2873 case 'file':
2874 echo "<script language='Javascript'>document.location='${root}?page=file&file_id=${record['id']}';//</script>";
2875 break;
e531b4d6
DO
2876 case 'rack':
2877 echo "<script language='Javascript'>document.location='${root}?page=rack&rack_id=${record['id']}';//</script>";
2878 break;
ea5fc465
DO
2879 }
2880 return;
2881 }
2882 else
2883 {
2884 global $nextorder;
2885 $order = 'odd';
2886 echo "<center><h2>${nhits} result(s) found for '${terms}'</h2></center>";
2887 foreach ($summary as $where => $what)
2888 switch ($where)
e673ee24 2889 {
ea5fc465 2890 case 'object':
fb858947 2891 startPortlet ("<a href='${root}?page=depot'>Objects</a>");
323edbbf
DO
2892 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
2893 echo '<tr><th>what</th><th>why</th></tr>';
2894 foreach ($what as $obj)
2895 {
2896 echo "<tr class=row_${order} valign=top><td>";
2897 renderCell (spotEntity ('object', $obj['id']));
b1f60545
DO
2898 echo "</td><td class=tdleft>";
2899 if (isset ($obj['by_attr']))
2900 {
2901 // only explain non-obvious reasons for listing
2902 echo '<ul>';
2903 foreach ($obj['by_attr'] as $attr_name)
2904 if ($attr_name != 'name')
2905 echo "<li>${attr_name} matched</li>";
2906 echo '</ul>';
2907 }
323edbbf
DO
2908 if (isset ($obj['by_sticker']))
2909 {
2910 echo '<table>';
2911 $aval = getAttrValues ($obj['id']);
2912 foreach ($obj['by_sticker'] as $attr_id)
2913 {
2914 $record = array
2915 (
2916 'name' => $aval[$attr_id]['name'],
2917 'a_value' => $aval[$attr_id]['a_value']
2918 );
2919 echo "<tr><th width='50%' class=sticker>${record['name']}:</th>";
2920 echo "<td class=sticker>${record['a_value']}</td></tr>";
2921 }
2922 echo '</table>';
2923 }
d516d719 2924 if (isset ($obj['by_port']))
323edbbf
DO
2925 {
2926 echo '<table>';
2927 $ports = getObjectPortsAndLinks ($obj['id']);
1b4a0a6a 2928 foreach ($obj['by_port'] as $port_id => $text)
323edbbf
DO
2929 foreach ($ports as $port)
2930 if ($port['id'] == $port_id)
2931 {
1b4a0a6a
DO
2932 echo "<tr><td>port ${port['name']}:</td>";
2933 echo "<td class=tdleft>${text}</td></tr>";
323edbbf
DO
2934 break; // next reason
2935 }
2936 echo '</table>';
2937 }
5fd2a004
DO
2938 if (isset ($obj['by_iface']))
2939 {
2940 echo '<ul>';
2941 foreach ($obj['by_iface'] as $ifname)
2942 echo "<li>interface ${ifname}</li>";
2943 echo '</ul>';
2944 }
2945 if (isset ($obj['by_nat']))
2946 {
2947 echo '<ul>';
2948 foreach ($obj['by_nat'] as $comment)
2949 echo "<li>NAT rule: ${comment}</li>";
2950 echo '</ul>';
2951 }
323edbbf
DO
2952 echo "</td></tr>";
2953 $order = $nextorder[$order];
ea5fc465
DO
2954 }
2955 echo '</table>';
2956 finishPortlet();
2957 break;
2958 case 'ipv4network':
06adfe89 2959 startPortlet ("<a href='${root}?page=ipv4space'>IPv4 networks</a>");
ea5fc465 2960 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
6df2025d 2961 foreach ($what as $cell)
ea5fc465 2962 {
0b9c98d7 2963 echo "<tr class=row_${order} valign=top><td>";
6df2025d 2964 renderCell ($cell);
0b9c98d7 2965 echo "</td></tr>\n";
ea5fc465
DO
2966 $order = $nextorder[$order];
2967 }
2968 echo '</table>';
2969 finishPortlet();
2970 break;
f3d0cb20 2971 case 'ipv4addressbydescr':
ea5fc465
DO
2972 startPortlet ('IPv4 addresses');
2973 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
f3d0cb20 2974 // FIXME: address, parent network, routers (if extended view is enabled)
e1ae3fb4 2975 echo '<tr><th>Address</th><th>Description</th></tr>';
ea5fc465
DO
2976 foreach ($what as $addr)
2977 {
f3d0cb20
DO
2978 echo "<tr class=row_${order}><td class=tdleft>";
2979 $parentnet = getIPv4AddressNetworkId ($addr['ip']);
2980 if ($parentnet !== NULL)
e1ae3fb4 2981 echo "<a href='${root}?page=ipv4net&tab=default&id=${parentnet}&hl_ipv4_addr=${addr['ip']}'>${addr['ip']}</a></td>";
f3d0cb20
DO
2982 else
2983 echo "<a href='${root}?page=ipaddress&ip=${addr['ip']}'>${addr['ip']}</a></td>";
ea5fc465
DO
2984 echo "<td class=tdleft>${addr['name']}</td></tr>";
2985 $order = $nextorder[$order];
2986 }
2987 echo '</table>';
2988 finishPortlet();
2989 break;
05411ccd 2990 case 'ipv4rspool':
ee437dab 2991 startPortlet ("<a href='${root}?page=ipv4rsplist'>RS pools</a>");
05411ccd 2992 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
6cd32e3c 2993 foreach ($what as $cell)
05411ccd 2994 {
216136d2 2995 echo "<tr class=row_${order}><td class=tdleft>";
6cd32e3c 2996 renderCell ($cell);
216136d2 2997 echo "</td></tr>";
05411ccd
DO
2998 $order = $nextorder[$order];
2999 }
3000 echo '</table>';
3001 finishPortlet();
3002 break;
3003 case 'ipv4vs':
a239e016 3004 startPortlet ("<a href='${root}?page=ipv4vslist'>Virtual services</a>");
05411ccd 3005 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
6df2025d 3006 foreach ($what as $cell)
05411ccd 3007 {
8128c257 3008 echo "<tr class=row_${order}><td class=tdleft>";
6df2025d 3009 renderCell ($cell);
8128c257 3010 echo "</td></tr>";
6a88e734
DO
3011 $order = $nextorder[$order];
3012 }
3013 echo '</table>';
3014 finishPortlet();
3015 break;
3016 case 'user':
3017 startPortlet ("<a href='${root}?page=userlist'>Users</a>");
3018 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
6a88e734
DO
3019 foreach ($what as $item)
3020 {
19dac9c3 3021 echo "<tr class=row_${order}><td class=tdleft>";
573214e0 3022 renderCell ($item);
19dac9c3 3023 echo "</td></tr>";
05411ccd
DO
3024 $order = $nextorder[$order];
3025 }
3026 echo '</table>';
3027 finishPortlet();
3028 break;
e1ae3fb4
AD
3029 case 'file':
3030 startPortlet ("<a href='${root}?page=files'>Files</a>");
3031 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
6df2025d 3032 foreach ($what as $cell)
e1ae3fb4 3033 {
35d10b16 3034 echo "<tr class=row_${order}><td class=tdleft>";
6df2025d 3035 renderCell ($cell);
35d10b16 3036 echo "</td></tr>";
e1ae3fb4
AD
3037 $order = $nextorder[$order];
3038 }
3039 echo '</table>';
3040 finishPortlet();
3041 break;
e531b4d6
DO
3042 case 'rack':
3043 startPortlet ("<a href='${root}?page=rackspace'>Racks</a>");
3044 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
3045 foreach ($what as $cell)
3046 {
3047 echo "<tr class=row_${order}><td class=tdleft>";
3048 renderCell ($cell);
3049 echo "</td></tr>";
3050 $order = $nextorder[$order];
3051 }
3052 echo '</table>';
3053 finishPortlet();
3054 break;
e673ee24 3055 }
e673ee24
DO
3056 }
3057}
3058
3059// This function prints a table of checkboxes to aid the user in toggling mount atoms
3060// from one state to another. The first argument is rack data as
61a1d996 3061// produced by amplifyCell(), the second is the value used for the 'unckecked' state
e673ee24
DO
3062// and the third is the value used for 'checked' state.
3063// Usage contexts:
3064// for mounting an object: printAtomGrid ($data, 'F', 'T')
3065// for changing rack design: printAtomGrid ($data, 'A', 'F')
3066// for adding rack problem: printAtomGrid ($data, 'F', 'U')
3067// for adding object problem: printAtomGrid ($data, 'T', 'W')
3068
3069function renderAtomGrid ($data)
3070{
3071 $rack_id = $data['id'];
3072 for ($unit_no = $data['height']; $unit_no > 0; $unit_no--)
3073 {
57c69e9c 3074 echo "<tr><th><a href='javascript:;' onclick=\"toggleRowOfAtoms('${rack_id}','${unit_no}')\">${unit_no}</a></th>";
e673ee24
DO
3075 for ($locidx = 0; $locidx < 3; $locidx++)
3076 {
57c69e9c 3077 $name = "atom_${rack_id}_${unit_no}_${locidx}";
e673ee24
DO
3078 $state = $data[$unit_no][$locidx]['state'];
3079 echo "<td class=state_${state}";
3080 if (isset ($data[$unit_no][$locidx]['hl']))
3081 echo $data[$unit_no][$locidx]['hl'];
3082 echo ">";
3083 if (!($data[$unit_no][$locidx]['enabled'] === TRUE))
57c69e9c 3084 echo "<input type=checkbox id=${name} disabled>";
e673ee24 3085 else
57c69e9c 3086 echo "<input type=checkbox" . $data[$unit_no][$locidx]['checked'] . " name=${name} id=${name}>";
e673ee24
DO
3087 echo '</td>';
3088 }
3089 echo "</tr>\n";
3090 }
3091}
3092
abf18701 3093function renderCellList ($realm = NULL, $title = 'items', $do_amplify = FALSE)
e673ee24 3094{
573214e0
DO
3095 if ($realm === NULL)
3096 {
3097 global $pageno;
3098 $realm = $pageno;
3099 }
3100 global $nextorder;
e673ee24 3101 $order = 'odd';
31c941ec
DO
3102 $cellfilter = getCellFilter();
3103 $celllist = filterCellList (listCells ($realm), $cellfilter['expression']);
8bc5d1e4
DO
3104 if ($do_amplify)
3105 array_walk ($celllist, 'amplifyCell');
abf18701
DO
3106 echo "<table border=0 class=objectview>\n";
3107 echo "<tr><td class=pcleft>";
590e1281 3108 startPortlet ($title . ' (' . count ($celllist) . ')');
abf18701 3109 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
8bc5d1e4 3110 foreach ($celllist as $cell)
e673ee24 3111 {
70198850 3112 echo "<tr class=row_${order}><td>";
573214e0 3113 renderCell ($cell);
70198850 3114 echo "</td></tr>\n";
e673ee24
DO
3115 $order = $nextorder[$order];
3116 }
3117 echo '</table>';
3118 finishPortlet();
59427701 3119 echo '</td><td class=pcright>';
590e1281 3120 renderCellFilterPortlet ($cellfilter, $realm);
59427701 3121 echo "</td></tr></table>\n";
e673ee24
DO
3122}
3123
573214e0
DO
3124function renderUserList ()
3125{
3126 renderCellList ('user', 'User accounts');
3127}
3128
59427701 3129function renderUserListEditor ()