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