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