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