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