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