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