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