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