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