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