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