r2936 - renderSearchResults(): do not display header above object list
[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
DO
2148 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
2149 echo "<tr><td colspan=2 align=center><h1>${range['ip']}/${range['mask']}</h1><h2>${range['name']}</h2></td></tr>\n";
2150
2151 echo "<tr><td class=pcleft width='50%'>";
2152 startPortlet ('summary');
2153 $total = ($range['ip_bin'] | $range['mask_bin_inv']) - ($range['ip_bin'] & $range['mask_bin']) + 1;
2154 $used = count ($range['addrlist']);
2155 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
04d619d0
DO
2156
2157 echo "<tr><th width='50%' class=tdright>%% used:</th><td class=tdleft>";
2034d968
DO
2158 renderProgressBar ($used/$total);
2159 echo "&nbsp;${used}/${total}</td></tr>\n";
04d619d0 2160
001e61fa
DO
2161 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
2162 {
3444ecf2
DO
2163 // Build a backtrace from all parent networks.
2164 $clen = $range['mask'];
2165 $backtrace = array();
2166 while (NULL !== ($upperid = getIPv4AddressNetworkId ($range['ip'], $clen)))
2167 {
d724d290 2168 $upperinfo = spotEntity ('ipv4net', $upperid);
3444ecf2 2169 $clen = $upperinfo['mask'];
d724d290 2170 $backtrace[] = $upperinfo;
3444ecf2
DO
2171 }
2172 $arrows = count ($backtrace);
d724d290 2173 foreach (array_reverse ($backtrace) as $ainfo)
001e61fa 2174 {
3444ecf2
DO
2175 echo "<tr><th width='50%' class=tdright>";
2176 for ($i = 0; $i < $arrows; $i++)
2177 echo '&uarr;';
2178 $arrows--;
5d3dcb8d 2179 echo "</th><td class=tdleft>";
6df2025d 2180 renderCell ($ainfo);
5d3dcb8d 2181 echo "</td></tr>";
001e61fa 2182 }
3444ecf2 2183 echo "<tr><th width='50%' class=tdright>&rarr;</th>";
5d3dcb8d 2184 echo "<td class=tdleft>";
6df2025d 2185 renderCell ($range);
5d3dcb8d 2186 echo "</td></tr>";
001e61fa
DO
2187 // FIXME: get and display nested networks
2188 // $theitem = pickLeaf ($ipv4tree, $id);
2189 }
2190
545478d0
DO
2191 echo "<tr><th width='50%' class=tdright>Netmask:</th><td class=tdleft>";
2192 echo $netmaskbylen[$range['mask']];
2193 echo "</td></tr>\n";
04d619d0 2194
c607ab55
DO
2195 echo "<tr><th width='50%' class=tdright>Netmask:</th><td class=tdleft>";
2196 printf ('0x%08X', binMaskFromDec ($range['mask']));
2197 echo "</td></tr>\n";
2198
545478d0
DO
2199 echo "<tr><th width='50%' class=tdright>Wildcard bits:</th><td class=tdleft>";
2200 echo $wildcardbylen[$range['mask']];
2201 echo "</td></tr>\n";
04d619d0 2202
f3d0cb20 2203 $routers = findRouters ($range['addrlist']);
f0ed1181 2204 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes' and count ($routers))
04d619d0 2205 {
57dece2f 2206 echo "<tr><th width='50%' class=tdright>Routed by:</th>";
f3d0cb20 2207 printRoutersTD ($routers);
57dece2f 2208 echo "</tr>\n";
04d619d0
DO
2209 }
2210
9b57f793 2211 printTagTRs ($range, makeHref(array('page'=>'ipv4space', 'tab'=>'default'))."&");
2034d968
DO
2212 echo "</table><br>\n";
2213 finishPortlet();
e1ae3fb4
AD
2214
2215 renderFilesPortlet ('ipv4net', $id);
2034d968 2216 echo "</td>\n";
e673ee24 2217
2034d968
DO
2218 echo "<td class=pcright>";
2219 startPortlet ('details');
e673ee24
DO
2220 $startip = $range['ip_bin'] & $range['mask_bin'];
2221 $endip = $range['ip_bin'] | $range['mask_bin_inv'];
2222 $realstartip = $startip;
2223 $realendip = $endip;
2224 $numpages = 0;
2225 if($endip - $startip > $maxperpage)
2226 {
e673ee24
DO
2227 $numpages = ($endip - $startip)/$maxperpage;
2228 $startip = $startip + $page * $maxperpage;
2229 $endip = $startip + $maxperpage-1;
2230 }
2231 echo "<center>";
b901bf1f
DO
2232 if ($numpages)
2233 echo '<h3>' . long2ip ($startip) . ' ~ ' . long2ip ($endip) . '</h3>';
e673ee24
DO
2234 for ($i=0; $i<$numpages; $i++)
2235 {
2236 if ($i == $page)
2237 echo "<b>$i</b> ";
2238 else
4fbb5a00 2239 echo "<a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno, 'id'=>$id, 'pg'=>$i))."'>$i</a> ";
e673ee24
DO
2240 }
2241 echo "</center>";
2242
beb9e88a 2243 echo "<table class='widetable' border=0 cellspacing=0 cellpadding=5 align='center' width='100%'>\n";
e673ee24
DO
2244 echo "<tr><th>Address</th><th>Name</th><th>Allocation</th></tr>\n";
2245
2246
b2035dca
DO
2247 for ($ip = $startip; $ip <= $endip; $ip++) :
2248 if (isset ($_REQUEST['hl_ipv4_addr']) and ip2long ($_REQUEST['hl_ipv4_addr']) == $ip)
2249 $secondstyle = 'tdleft port_highlight';
2727c7df 2250 else
b2035dca
DO
2251 $secondstyle = 'tdleft';
2252 if (!isset ($range['addrlist'][$ip]))
e673ee24 2253 {
4fbb5a00 2254 echo "<tr><td class=tdleft><a href='".makeHref(array('page'=>'ipaddress', 'ip'=>ip_long2quad($ip)))."'>" . ip_long2quad($ip);
b2035dca
DO
2255 echo "</a></td><td class='${secondstyle}'>&nbsp;</td><td class='${secondstyle}'>&nbsp;</td></tr>\n";
2256 continue;
2257 }
b2035dca 2258 $addr = $range['addrlist'][$ip];
2d318652 2259 echo "<tr class='${addr['class']}'>";
e673ee24 2260
4fbb5a00 2261 echo "<td class=tdleft><a href='".makeHref(array('page'=>'ipaddress', 'ip'=>$addr['ip']))."'>${addr['ip']}</a></td>";
b2035dca
DO
2262 echo "<td class='${secondstyle}'>${addr['name']}</td><td class='${secondstyle}'>";
2263 $delim = '';
2264 $prologue = '';
2265 if ( $addr['reserved'] == 'yes')
2266 {
2d318652 2267 echo "<strong>RESERVED</strong> ";
b2035dca
DO
2268 $delim = '; ';
2269 }
2d318652 2270 foreach ($range['addrlist'][$ip]['allocs'] as $ref)
b2035dca 2271 {
beb9e88a 2272 echo $delim . $aac2[$ref['type']];
4fbb5a00 2273 echo "<a href='".makeHref(array('page'=>'object', 'object_id'=>$ref['object_id'], 'hl_ipv4_addr'=>$addr['ip']))."'>";
59a83bd8 2274 echo $ref['name'] . (!strlen ($ref['name']) ? '' : '@');
b2035dca
DO
2275 echo "${ref['object_name']}</a>";
2276 $delim = '; ';
2277 }
2278 if ($delim != '')
2279 {
6131056c 2280 $delim = '';
b2035dca
DO
2281 $prologue = '<br>';
2282 }
2d318652 2283 foreach ($range['addrlist'][$ip]['lblist'] as $ref)
b2035dca
DO
2284 {
2285 echo $prologue;
602663f4 2286 $prologue = '';
4fbb5a00
DY
2287 echo "${delim}<a href='".makeHref(array('page'=>'object', 'object_id'=>$ref['object_id']))."'>";
2288 echo "${ref['object_name']}</a>:<a href='".makeHref(array('page'=>'ipv4vs', 'vs_id'=>$ref['vs_id']))."'>";
b2035dca
DO
2289 echo "${ref['vport']}/${ref['proto']}</a>&rarr;";
2290 $delim = '; ';
2291 }
2292 if ($delim != '')
2293 {
2294 $delim = '';
2295 $prologue = '<br>';
e673ee24 2296 }
2d318652 2297 foreach ($range['addrlist'][$ip]['rslist'] as $ref)
b2035dca
DO
2298 {
2299 echo $prologue;
2300 $prologue = '';
4fbb5a00 2301 echo "${delim}&rarr;${ref['rsport']}@<a href='".makeHref(array('page'=>'ipv4rspool', 'pool_id'=>$ref['rspool_id']))."'>";
b2035dca
DO
2302 echo "${ref['rspool_name']}</a>";
2303 $delim = '; ';
2304 }
2305 echo "</td></tr>\n";
2306 endfor;
2727c7df 2307 // end of iteration
e673ee24
DO
2308
2309 echo "</table>";
2034d968
DO
2310 finishPortlet();
2311 echo "</td></tr></table>\n";
e673ee24
DO
2312}
2313
53ef3908 2314function renderIPv4NetworkProperties ($id)
e673ee24 2315{
d724d290 2316 $netdata = spotEntity ('ipv4net', $id);
53ef3908 2317 echo "<center><h1>${netdata['ip']}/${netdata['mask']}</h1></center>\n";
e673ee24 2318 echo "<table border=0 cellpadding=10 cellpadding=1 align='center'>\n";
7056988c 2319 printOpFormIntro ('editRange');
53ef3908
DO
2320 echo "<tr><td class='tdright'>Name:</td><td class='tdleft'><input type=text name=name size=20 value='${netdata['name']}'></tr>";
2321 echo "<tr><td colspan=2 class=tdcenter>";
2322 printImageHREF ('SAVE', 'Save changes', TRUE);
2323 echo "</td></form></tr></table>\n";
e673ee24
DO
2324}
2325
2d318652 2326function renderIPv4Address ($dottedquad)
e673ee24 2327{
46098972 2328 global $aat, $nextorder;
2d318652 2329 $address = getIPv4Address ($dottedquad);
68225375 2330 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
2d318652 2331 echo "<tr><td colspan=2 align=center><h1>${dottedquad}</h1></td></tr>\n";
59a83bd8 2332 if (strlen ($address['name']))
68225375 2333 echo "<tr><td colspan=2 align=center><h2>${address['name']}</h2></td></tr>\n";
e673ee24 2334
68225375
DO
2335 echo "<tr><td class=pcleft>";
2336 startPortlet ('summary');
2337 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
04d619d0 2338 echo "<tr><th width='50%' class=tdright>Allocations:</th><td class=tdleft>" . count ($address['allocs']) . "</td></tr>\n";
68225375
DO
2339 echo "<tr><th width='50%' class=tdright>Originated NAT connections:</th><td class=tdleft>" . count ($address['outpf']) . "</td></tr>\n";
2340 echo "<tr><th width='50%' class=tdright>Arriving NAT connections:</th><td class=tdleft>" . count ($address['inpf']) . "</td></tr>\n";
04d619d0 2341 echo "<tr><th width='50%' class=tdright>SLB virtual services:</th><td class=tdleft>" . count ($address['lblist']) . "</td></tr>\n";
68225375 2342 echo "<tr><th width='50%' class=tdright>SLB real servers:</th><td class=tdleft>" . count ($address['rslist']) . "</td></tr>\n";
68225375
DO
2343 echo "</table><br>\n";
2344 finishPortlet();
2345 echo "</td>\n";
e673ee24 2346
68225375 2347 echo "<td class=pcright>";
e673ee24 2348
f74d96c6 2349 if (isset ($address['class']))
59bebe2b 2350 {
8e700dd1 2351 startPortlet ('allocations');
2d318652
DO
2352 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
2353 echo "<tr><th>object</th><th>OS interface</th><th>allocation type</th></tr>\n";
2354 $class = $address['class'];
2355 // render all allocation records for this address the same way
59bebe2b 2356 if ($address['reserved'] == 'yes')
2d318652
DO
2357 echo "<tr class='${class}'><td colspan=2>&nbsp;</td><td class=tdleft><strong>RESERVED</strong></td></tr>";
2358 foreach ($address['allocs'] as $bond)
59bebe2b 2359 {
8e700dd1
DO
2360 if (isset ($_REQUEST['hl_object_id']) and $_REQUEST['hl_object_id'] == $bond['object_id'])
2361 $secondclass = 'tdleft port_highlight';
2362 else
2363 $secondclass = 'tdleft';
4fbb5a00 2364 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
2365 echo $aat[$bond['type']];
2366 echo "</strong></td></tr>\n";
59bebe2b
DO
2367 }
2368 echo "</table><br><br>";
2369 finishPortlet();
2370 }
e673ee24 2371
f3d0cb20
DO
2372 // FIXME: The returned list is structured differently, than we expect it to be. One of the sides
2373 // must be fixed.
2d318652 2374 if (count ($address['lblist']))
e673ee24 2375 {
2d318652
DO
2376 startPortlet ('Virtual services (' . count ($address['lblist']) . ')');
2377 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
46098972
DO
2378 echo "<tr><th>VS</th><th>LB</th></tr>\n";
2379 $order = 'odd';
2d318652 2380 foreach ($address['lblist'] as $vsinfo)
e673ee24 2381 {
46098972
DO
2382 echo "<tr valign=top class=row_${order}><td class=tdleft>";
2383 renderCell (spotEntity ('ipv4vs', $vsinfo['vs_id']));
2384 echo "</td><td class=tdleft>";
2385 renderLBCell ($vsinfo['object_id']);
2386 echo "</td></tr>";
2387 $order = $nextorder[$order];
e673ee24 2388 }
59bebe2b
DO
2389 echo "</table><br><br>";
2390 finishPortlet();
e673ee24 2391 }
5fe1ed76
DO
2392
2393 if (count ($address['rslist']))
2394 {
2395 startPortlet ('Real servers (' . count ($address['rslist']) . ')');
2d318652 2396 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
53f4b619 2397 echo "<tr><th>&nbsp;</th><th>port</th><th>RS pool</th></tr>\n";
5fe1ed76
DO
2398 foreach ($address['rslist'] as $rsinfo)
2399 {
2400 echo "<tr><td>";
2401 if ($rsinfo['inservice'] == 'yes')
2402 printImageHREF ('inservice', 'in service');
2403 else
2404 printImageHREF ('notinservice', 'NOT in service');
4fbb5a00 2405 echo "</td><td class=tdleft>${rsinfo['rsport']}</td><td class=tdleft><a href='".makeHref(array('page'=>'ipv4rspool', 'pool_id'=>$rsinfo['rspool_id']))."'>";
2d318652 2406 echo $rsinfo['rspool_name'] . "</a></td></tr>\n";
5fe1ed76
DO
2407 }
2408 echo "</table><br><br>";
2409 finishPortlet();
2410 }
2411
68225375
DO
2412 if (count ($address['outpf']))
2413 {
105a3bc8 2414 startPortlet ('departing NAT rules');
2d318652 2415 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
105a3bc8
DO
2416 echo "<tr><th>proto</th><th>from</th><th>to</th><th>comment</th></tr>\n";
2417 foreach ($address['outpf'] as $rule)
b62ff880 2418 echo "<tr><td>${rule['proto']}</td><td>${rule['localip']}:${rule['localport']}</td><td>${rule['remoteip']}:${rule['remoteport']}</td><td>${rule['description']}</td></tr>";
105a3bc8 2419 echo "</table>";
68225375
DO
2420 finishPortlet();
2421 }
105a3bc8
DO
2422
2423 if (count ($address['inpf']))
2424 {
2425 startPortlet ('arriving NAT rules');
2d318652 2426 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
105a3bc8
DO
2427 echo "<tr><th>proto</th><th>from</th><th>to</th><th>comment</th></tr>\n";
2428 foreach ($address['inpf'] as $rule)
b62ff880 2429 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
2430 echo "</table>";
2431 finishPortlet();
2432 }
2433
68225375
DO
2434 echo "</td></tr>";
2435 echo "</table>\n";
e673ee24
DO
2436}
2437
2d318652 2438function renderIPv4AddressProperties ($dottedquad)
e673ee24 2439{
2d318652
DO
2440 $address = getIPv4Address ($dottedquad);
2441 echo "<center><h1>$dottedquad</h1></center>\n";
7056988c 2442
1fbc9fd6 2443 startPortlet ('update');
e673ee24 2444 echo "<table border=0 cellpadding=10 cellpadding=1 align='center'>\n";
7056988c 2445 printOpFormIntro ('editAddress');
2d318652
DO
2446 echo "<tr><td class='tdright'>Name:</td><td class='tdleft'><input type=text name=name size=20 value='${address['name']}'></tr>";
2447 echo "<td class='tdright'>Reserved:</td><td class='tdleft'><input type=checkbox name=reserved size=20 ";
2448 echo ($address['reserved']=='yes') ? 'checked' : '';
f3d274bf 2449 echo "></tr><tr><td class=tdleft>";
53ef3908 2450 printImageHREF ('SAVE', 'Save changes', TRUE);
f3d274bf 2451 echo "</td></form><td class=tdright>";
59a83bd8 2452 if (!strlen ($address['name']) and $address['reserved'] == 'no')
f3d274bf
DO
2453 printImageHREF ('CLEAR gray');
2454 else
2455 {
2456 printOpFormIntro ('editAddress', array ('name' => '', 'reserved' => ''));
2457 printImageHREF ('CLEAR', 'Release', TRUE);
2458 echo "</form>";
2459 }
2460 echo "</td></tr></table>\n";
1fbc9fd6 2461 finishPortlet();
e673ee24
DO
2462}
2463
2d318652 2464function renderIPv4AddressAllocations ($dottedquad)
e673ee24 2465{
39b4abd0
DO
2466 function printNewItemTR ()
2467 {
2468 global $aat;
2469 printOpFormIntro ('addIPv4Allocation');
2470 echo "<tr><td>";
9318d2ef 2471 printImageHREF ('add', 'allocate', TRUE);
8d4f7d18 2472 echo "</td><td>";
c6bc0ac5 2473 printSelect (getNarrowObjectList ('IPV4OBJ_LISTSRC'), 'object_id', NULL, 100);
8d4f7d18 2474 echo "</td><td><input type=text tabindex=101 name=bond_name size=10></td><td>";
f5ff50f5 2475 printSelect ($aat, 'bond_type', NULL, 102);
9318d2ef 2476 echo "</td><td>";
f5ff50f5 2477 printImageHREF ('add', 'allocate', TRUE, 103);
9318d2ef 2478 echo "</td></form></tr>";
39b4abd0 2479 }
b82cce3f 2480 global $aat;
e673ee24 2481
2d318652 2482 $address = getIPv4Address ($dottedquad);
f74d96c6 2483
2d318652 2484 echo "<center><h1>${dottedquad}</h1></center>\n";
105a3bc8 2485 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
2d318652 2486 echo "<tr><th>&nbsp;</th><th>object</th><th>OS interface</th><th>allocation type</th><th>&nbsp;</th></tr>\n";
e673ee24 2487
39b4abd0
DO
2488 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
2489 printNewItemTR();
f74d96c6 2490 if (isset ($address['class']))
e673ee24 2491 {
f74d96c6
DO
2492 $class = $address['class'];
2493 if ($address['reserved'] == 'yes')
2494 echo "<tr class='${class}'><td colspan=3>&nbsp;</td><td class=tdleft><strong>RESERVED</strong></td><td>&nbsp;</td></tr>";
2495 foreach ($address['allocs'] as $bond)
2496 {
2497 echo "<tr class='$class'>";
2498 printOpFormIntro ('updIPv4Allocation', array ('object_id' => $bond['object_id']));
4fbb5a00 2499 echo "<td><a href='".makeHrefProcess(array('op'=>'delIPv4Allocation', 'ip'=>$dottedquad, 'object_id'=>$bond['object_id']))."'>";
f74d96c6
DO
2500 printImageHREF ('delete', 'Unallocate address');
2501 echo "</a></td>";
4fbb5a00 2502 echo "<td><a href='".makeHref(array('page'=>'object', 'object_id'=>$bond['object_id'], 'hl_ipv4_addr'=>$dottedquad))."'>${bond['object_name']}</td>";
f74d96c6
DO
2503 echo "<td><input type='text' name='bond_name' value='${bond['name']}' size=10></td><td>";
2504 printSelect ($aat, 'bond_type', $bond['type']);
2505 echo "</td><td>";
2506 printImageHREF ('save', 'Save changes', TRUE);
2507 echo "</td></form></tr>\n";
2508 }
e673ee24 2509 }
39b4abd0
DO
2510 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
2511 printNewItemTR();
e673ee24 2512 echo "</table><br><br>";
e673ee24
DO
2513}
2514
7e1db771 2515function renderNATv4ForObject ($object_id)
e673ee24 2516{
9318d2ef
DO
2517 function printNewItemTR ($alloclist)
2518 {
9318d2ef
DO
2519 printOpFormIntro ('addNATv4Rule');
2520 echo "<tr align='center'><td>";
2521 printImageHREF ('add', 'Add new NAT rule', TRUE);
2522 echo '</td><td>';
2523 printSelect (array ('TCP' => 'TCP', 'UDP' => 'UDP'), 'proto');
2524 echo "<select name='localip' tabindex=1>";
2525
2526 foreach ($alloclist as $dottedquad => $alloc)
2527 {
43eb71f1
DO
2528 $name = (!isset ($alloc['addrinfo']['name']) or !strlen ($alloc['addrinfo']['name'])) ? '' : (' (' . niftyString ($alloc['addrinfo']['name']) . ')');
2529 $osif = (!isset ($alloc['osif']) or !strlen ($alloc['osif'])) ? '' : ($alloc['osif'] . ': ');
9318d2ef
DO
2530 echo "<option value='${dottedquad}'>${osif}${dottedquad}${name}</option>";
2531 }
2532
2533 echo "</select>:<input type='text' name='localport' size='4' tabindex=2></td>";
2534 echo "<td><input type='text' name='remoteip' id='remoteip' size='10' tabindex=3>";
39106006
DO
2535 echo "<a href='javascript:;' onclick='window.open(\"" . makeHrefForHelper ('inet4list');
2536 echo "\", \"findobjectip\", \"height=700, width=400, location=no, menubar=no, resizable=yes, scrollbars=no, status=no, titlebar=no, toolbar=no\");'>";
9318d2ef
DO
2537 printImageHREF ('find', 'Find object');
2538 echo "</a>";
2539 echo ":<input type='text' name='remoteport' size='4' tabindex=4></td><td></td>";
2540 echo "<td colspan=1><input type='text' name='description' size='20' tabindex=5></td><td>";
f5ff50f5 2541 printImageHREF ('add', 'Add new NAT rule', TRUE, 6);
9318d2ef
DO
2542 echo "</td></tr></form>";
2543 }
e673ee24 2544
94fe6370
DO
2545 $focus = spotEntity ('object', $object_id);
2546 amplifyCell ($focus);
f28fbe8b 2547 echo "<center><h2>locally performed NAT</h2></center>";
e673ee24 2548
105a3bc8 2549 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
d54b9495 2550 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 2551
9318d2ef 2552 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
94fe6370
DO
2553 printNewItemTR ($focus['ipv4']);
2554 foreach ($focus['nat4']['out'] as $pf)
e673ee24 2555 {
2c817354
DO
2556 $class = 'trerror';
2557 $osif = '';
94fe6370 2558 if (isset ($focus['ipv4'][$pf['localip']]))
2c817354 2559 {
94fe6370
DO
2560 $class = $focus['ipv4'][$pf['localip']]['addrinfo']['class'];
2561 $osif = $focus['ipv4'][$pf['localip']]['osif'] . ': ';
2c817354 2562 }
e673ee24
DO
2563
2564 echo "<tr class='$class'>";
4fbb5a00
DY
2565 echo "<td><a href='".
2566 makeHrefProcess(array(
2567 'op'=>'delNATv4Rule',
2568 'localip'=>$pf['localip'],
2569 'localport'=>$pf['localport'],
2570 'remoteip'=>$pf['remoteip'],
2571 'remoteport'=>$pf['remoteport'],
2572 'proto'=>$pf['proto'],
2573 'object_id'=>$object_id)).
2574 "'>";
4de22e7e
DO
2575 printImageHREF ('delete', 'Delete NAT rule');
2576 echo "</a></td>";
4fbb5a00 2577 echo "<td>${pf['proto']}/${osif}<a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['localip']))."'>${pf['localip']}</a>:${pf['localport']}";
59a83bd8 2578 if (strlen ($pf['local_addr_name']))
f28fbe8b
DO
2579 echo ' (' . $pf['local_addr_name'] . ')';
2580 echo "</td>";
4fbb5a00 2581 echo "<td><a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['remoteip']))."'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
e673ee24 2582
53ef3908 2583 $address = getIPv4Address ($pf['remoteip']);
e673ee24
DO
2584
2585 echo "<td class='description'>";
53ef3908
DO
2586 if (count ($address['allocs']))
2587 foreach ($address['allocs'] as $bond)
4fbb5a00 2588 echo "<a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$bond['object_id']))."'>${bond['object_name']}(${bond['name']})</a> ";
59a83bd8 2589 elseif (strlen ($pf['remote_addr_name']))
f28fbe8b 2590 echo '(' . $pf['remote_addr_name'] . ')';
7056988c
DO
2591 printOpFormIntro
2592 (
2593 'updNATv4Rule',
2594 array
2595 (
2596 'localip' => $pf['localip'],
2597 'localport' => $pf['localport'],
2598 'remoteip' => $pf['remoteip'],
2599 'remoteport' => $pf['remoteport'],
2600 'proto' => $pf['proto']
2601 )
2602 );
2603 echo "</td><td class='description'>";
d54b9495
DO
2604 echo "<input type='text' name='description' value='${pf['description']}'></td><td>";
2605 printImageHREF ('save', 'Save changes', TRUE);
2606 echo "</td></form></tr>";
e673ee24 2607 }
9318d2ef 2608 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
94fe6370 2609 printNewItemTR ($focus['ipv4']);
e673ee24
DO
2610
2611 echo "</table><br><br>";
94fe6370
DO
2612 if (!count ($focus['nat4']))
2613 return;
e673ee24 2614
f28fbe8b 2615 echo "<center><h2>arriving NAT connections</h2></center>";
105a3bc8 2616 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
e673ee24
DO
2617 echo "<tr><th></th><th>Source</th><th>Source objects</th><th>Target</th><th>Description</th></tr>\n";
2618
94fe6370 2619 foreach ($focus['nat4']['in'] as $pf)
e673ee24 2620 {
4fbb5a00
DY
2621 echo "<tr><td><a href='".
2622 makeHrefProcess(array(
2623 'op'=>'delNATv4Rule',
2624 'localip'=>$pf['localip'],
2625 'localport'=>$pf['localport'],
2626 'remoteip'=>$pf['remoteip'],
2627 'remoteport'=>$pf['remoteport'],
2628 'proto'=>$pf['proto'],
2629 'object_id'=>$pf['object_id']
2630 )).
2631 "'>";
4de22e7e
DO
2632 printImageHREF ('delete', 'Delete NAT rule');
2633 echo "</a></td>";
4fbb5a00
DY
2634 echo "<td>${pf['proto']}/<a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['localip']))."'>${pf['localip']}</a>:${pf['localport']}</td>";
2635 echo "<td class='description'><a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$pf['object_id']))."'>${pf['object_name']}</a>";
2636 echo "</td><td><a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['remoteip']))."'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
e673ee24
DO
2637 echo "<td class='description'>${pf['description']}</td></tr>";
2638 }
2639
e673ee24 2640 echo "</table><br><br>";
e673ee24
DO
2641}
2642
e673ee24
DO
2643function renderAddMultipleObjectsForm ()
2644{
e673ee24 2645 $typelist = getObjectTypeList();
4c330a14 2646 $typelist[0] = 'select type...';
a1886a78
DO
2647 $max = getConfigVar ('MASSCOUNT');
2648 $tabindex = 100;
7f791d1d 2649
f60bb422 2650 startPortlet ('Distinct types, same tags');
42d73cbf 2651 printOpFormIntro ('addObjects');
e673ee24 2652 echo '<table border=0 align=center>';
f60bb422
DO
2653 echo "<tr><th>Object type</th><th>Common name</th><th>Visible label</th>";
2654 echo "<th>Asset tag</th><th>Barcode</th><th>Tags</th></tr>\n";
9c0b0016 2655 for ($i = 0; $i < $max; $i++)
e673ee24 2656 {
7f791d1d 2657 echo '<tr><td>';
e7ade6bf 2658 // Don't employ DEFAULT_OBJECT_TYPE to avoid creating ghost records for pre-selected empty rows.
a1886a78 2659 printSelect ($typelist, "${i}_object_type_id", 0, $tabindex);
e673ee24 2660 echo '</td>';
a1886a78
DO
2661 echo "<td><input type=text size=30 name=${i}_object_name tabindex=${tabindex}></td>";
2662 echo "<td><input type=text size=30 name=${i}_object_label tabindex=${tabindex}></td>";
2663 echo "<td><input type=text size=20 name=${i}_object_asset_no tabindex=${tabindex}></td>";
2664 echo "<td><input type=text size=10 name=${i}_object_barcode tabindex=${tabindex}></td>";
f60bb422
DO
2665 if ($i == 0)
2666 {
2667 echo "<td valign=top rowspan=${max}>";
a26a6ccc 2668 renderNewEntityTags ('object');
f60bb422
DO
2669 echo "</td>\n";
2670 }
e673ee24 2671 echo "</tr>\n";
a1886a78 2672 $tabindex++;
e673ee24 2673 }
216c84bb 2674 echo "<tr><td class=submit colspan=5><input type=submit name=got_fast_data value='Go!'></td></tr>\n";
e673ee24
DO
2675 echo "</form></table>\n";
2676 finishPortlet();
7f791d1d 2677
f60bb422 2678 startPortlet ('Same type, same tags');
42d73cbf 2679 printOpFormIntro ('addLotOfObjects');
f60bb422
DO
2680 echo "<table border=0 align=center><tr><th>names</th><th>type</th></tr>";
2681 echo "<tr><td rowspan=3><textarea name=namelist cols=40 rows=25>\n";
f60bb422
DO
2682 echo "</textarea></td><td valign=top>";
2683 printSelect ($typelist, "global_type_id", getConfigVar ('DEFAULT_OBJECT_TYPE'));
2684 echo "</td></tr>";
2685 echo "<tr><th>Tags</th></tr>";
2686 echo "<tr><td valign=top>";
a26a6ccc 2687 renderNewEntityTags ('object');
f60bb422
DO
2688 echo "</td></tr>";
2689 echo "<tr><td colspan=2><input type=submit name=got_very_fast_data value='Go!'></td></tr></table>\n";
2690 echo "</form>\n";
7f791d1d 2691 finishPortlet();
e673ee24
DO
2692}
2693
2694function printGreeting ()
2695{
d6d79c36
DO
2696 global $root, $remote_username, $remote_displayname;
2697 echo "Hello, <a href='${root}?page=myaccount&tab=default'>${remote_displayname}</a>. This is RackTables " .
2698 CODE_VERSION .
2699 ". Click <a href='${root}?logout'>here</a> to logout.";
e673ee24
DO
2700}
2701
2702function renderSearchResults ()
2703{
0b9c98d7 2704 global $root;
e673ee24 2705 $terms = trim ($_REQUEST['q']);
59a83bd8 2706 if (!strlen ($terms))
e673ee24 2707 {
591ff2c4 2708 showError ('Search string cannot be empty.', __FUNCTION__);
e673ee24
DO
2709 return;
2710 }
c78a40ec 2711 if (!permitted ('depot', 'default'))
e673ee24 2712 {
591ff2c4 2713 showError ('You are not authorized for viewing information about objects.', __FUNCTION__);
e673ee24
DO
2714 return;
2715 }
ea5fc465 2716 $nhits = 0;
e673ee24
DO
2717 // If we search for L2 address, we can either find one or find none.
2718 if
2719 (
05771508
DO
2720 preg_match (RE_L2_IFCFG, $terms) or
2721 preg_match (RE_L2_SOLID, $terms) or
2722 preg_match (RE_L2_CISCO, $terms) or
1930dc7f 2723 preg_match (RE_L2_IPCFG, $terms) or
05771508
DO
2724 // Foundry STP bridge ID: bridge priotity + port MAC address. Cut off first 4 chars and look for MAC address.
2725 preg_match (RE_L2_FDRYSTP, $terms)
e673ee24
DO
2726 )
2727 // Search for L2 address.
2728 {
3ec29bf4
DO
2729 $terms = str_replace ('.', '', $terms);
2730 $terms = str_replace (':', '', $terms);
1930dc7f 2731 $terms = str_replace ('-', '', $terms);
ea5fc465 2732 $terms = substr ($terms, -12);
e673ee24
DO
2733 $result = searchByl2address ($terms);
2734 if ($result !== NULL)
2735 {
ea5fc465
DO
2736 $nhits++;
2737 $lasthit = 'port';
2738 $summary['port'][] = $result;
e673ee24 2739 }
e673ee24 2740 }
05771508 2741 elseif (preg_match (RE_IP4_ADDR, $terms))
64347dcf 2742 // Search for IPv4 address.
e673ee24 2743 {
bb0a44e9 2744 if (NULL !== getIPv4AddressNetworkId ($terms))
e673ee24 2745 {
ea5fc465 2746 $nhits++;
f3d0cb20
DO
2747 $lasthit = 'ipv4addressbydq';
2748 $summary['ipv4addressbydq'][] = $terms;
e673ee24 2749 }
e673ee24 2750 }
05771508 2751 elseif (preg_match (RE_IP4_NET, $terms))
64347dcf
DO
2752 // Search for IPv4 network
2753 {
2754 list ($base, $len) = explode ('/', $terms);
2755 if (NULL !== ($tmp = getIPv4AddressNetworkId ($base, $len + 1)))
2756 {
2757 $nhits++;
2758 $lasthit = 'ipv4network';
d724d290 2759 $summary['ipv4network'][] = spotEntity ('ipv4net', $tmp);
64347dcf
DO
2760 }
2761 }
e673ee24 2762 else
ea5fc465 2763 // Search for objects, addresses, networks, virtual services and RS pools by their description.
e673ee24 2764 {
ea5fc465
DO
2765 $tmp = getObjectSearchResults ($terms);
2766 if (count ($tmp))
e673ee24 2767 {
ea5fc465
DO
2768 $nhits += count ($tmp);
2769 $lasthit = 'object';
2770 $summary['object'] = $tmp;
e673ee24 2771 }
ea5fc465
DO
2772 $tmp = getIPv4AddressSearchResult ($terms);
2773 if (count ($tmp))
e673ee24 2774 {
ea5fc465 2775 $nhits += count ($tmp);
f3d0cb20
DO
2776 $lasthit = 'ipv4addressbydescr';
2777 $summary['ipv4addressbydescr'] = $tmp;
ea5fc465
DO
2778 }
2779 $tmp = getIPv4PrefixSearchResult ($terms);
2780 if (count ($tmp))
2781 {
2782 $nhits += count ($tmp);
2783 $lasthit = 'ipv4network';
2784 $summary['ipv4network'] = $tmp;
2785 }
05411ccd
DO
2786 $tmp = getIPv4RSPoolSearchResult ($terms);
2787 if (count ($tmp))
2788 {
2789 $nhits += count ($tmp);
2790 $lasthit = 'ipv4rspool';
2791 $summary['ipv4rspool'] = $tmp;
2792 }
2793 $tmp = getIPv4VServiceSearchResult ($terms);
2794 if (count ($tmp))
2795 {
2796 $nhits += count ($tmp);
2797 $lasthit = 'ipv4vs';
2798 $summary['ipv4vs'] = $tmp;
2799 }
6a88e734
DO
2800 $tmp = getAccountSearchResult ($terms);
2801 if (count ($tmp))
2802 {
2803 $nhits += count ($tmp);
2804 $lasthit = 'user';
2805 $summary['user'] = $tmp;
2806 }
e1ae3fb4
AD
2807 $tmp = getFileSearchResult ($terms);
2808 if (count ($tmp))
2809 {
2810 $nhits += count ($tmp);
2811 $lasthit = 'file';
2812 $summary['file'] = $tmp;
2813 }
e531b4d6
DO
2814 $tmp = getRackSearchResult ($terms);
2815 if (count ($tmp))
2816 {
2817 $nhits += count ($tmp);
2818 $lasthit = 'rack';
2819 $summary['rack'] = $tmp;
2820 }
ea5fc465
DO
2821 }
2822 if ($nhits == 0)
2823 echo "<center><h2>Nothing found for '${terms}'</h2></center>";
2824 elseif ($nhits == 1)
2825 {
2826 $record = current ($summary[$lasthit]);
2827 switch ($lasthit)
2828 {
2829 case 'port':
2830 echo "<script language='Javascript'>document.location='${root}?page=object";
2831 echo "&hl_port_id=" . $record['port_id'];
2832 echo "&object_id=" . $record['object_id'] . "';//</script>";
2833 break;
f3d0cb20
DO
2834 case 'ipv4addressbydq':
2835 $parentnet = getIPv4AddressNetworkId ($record);
2836 if ($parentnet !== NULL)
e1ae3fb4 2837 echo "<script language='Javascript'>document.location='${root}?page=ipv4net&tab=default&id=${parentnet}&hl_ipv4_addr=${record}';//</script>";
f3d0cb20
DO
2838 else
2839 echo "<script language='Javascript'>document.location='${root}?page=ipaddress&ip=${record}';//</script>";
ea5fc465 2840 break;
f3d0cb20
DO
2841 case 'ipv4addressbydescr':
2842 $parentnet = getIPv4AddressNetworkId ($record['ip']);
2843 if ($parentnet !== NULL)
e1ae3fb4 2844 echo "<script language='Javascript'>document.location='${root}?page=ipv4net&tab=default&id=${parentnet}&hl_ipv4_addr=${record['ip']}';//</script>";
f3d0cb20
DO
2845 else
2846 echo "<script language='Javascript'>document.location='${root}?page=ipaddress&ip=${record['ip']}';//</script>";
ea5fc465
DO
2847 break;
2848 case 'ipv4network':
e1ae3fb4 2849 echo "<script language='Javascript'>document.location='${root}?page=ipv4net";
ea5fc465
DO
2850 echo "&id=${record['id']}";
2851 echo "';//</script>";
2852 break;
2853 case 'object':
2854 echo "<script language='Javascript'>document.location='${root}?page=object&object_id=${record['id']}';//</script>";
2855 break;
05411ccd 2856 case 'ipv4rspool':
f06fe423 2857 echo "<script language='Javascript'>document.location='${root}?page=ipv4rspool&pool_id=${record['id']}';//</script>";
05411ccd
DO
2858 break;
2859 case 'ipv4vs':
49fb2686 2860 echo "<script language='Javascript'>document.location='${root}?page=ipv4vs&vs_id=${record['id']}';//</script>";
05411ccd 2861 break;
6a88e734
DO
2862 case 'user':
2863 echo "<script language='Javascript'>document.location='${root}?page=user&user_id=${record['user_id']}';//</script>";
2864 break;
e1ae3fb4
AD
2865 case 'file':
2866 echo "<script language='Javascript'>document.location='${root}?page=file&file_id=${record['id']}';//</script>";
2867 break;
e531b4d6
DO
2868 case 'rack':
2869 echo "<script language='Javascript'>document.location='${root}?page=rack&rack_id=${record['id']}';//</script>";
2870 break;
ea5fc465
DO
2871 }
2872 return;
2873 }
2874 else
2875 {
2876 global $nextorder;
2877 $order = 'odd';
2878 echo "<center><h2>${nhits} result(s) found for '${terms}'</h2></center>";
2879 foreach ($summary as $where => $what)
2880 switch ($where)
e673ee24 2881 {
ea5fc465 2882 case 'object':
c78a40ec 2883 startPortlet ("<a href='${root}?page=depot'>Objects</a>");
ea5fc465 2884 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
ea5fc465
DO
2885 foreach ($what as $obj)
2886 {
cd72ee55
DO
2887 echo "<tr class=row_${order} valign=top><td>";
2888 renderCell (spotEntity ('object', $obj['id']));
2889 echo "</td></tr>\n";
ea5fc465
DO
2890 $order = $nextorder[$order];
2891 }
2892 echo '</table>';
2893 finishPortlet();
2894 break;
2895 case 'ipv4network':
06adfe89 2896 startPortlet ("<a href='${root}?page=ipv4space'>IPv4 networks</a>");
ea5fc465 2897 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
6df2025d 2898 foreach ($what as $cell)
ea5fc465 2899 {
0b9c98d7 2900 echo "<tr class=row_${order} valign=top><td>";
6df2025d 2901 renderCell ($cell);
0b9c98d7 2902 echo "</td></tr>\n";
ea5fc465
DO
2903 $order = $nextorder[$order];
2904 }
2905 echo '</table>';
2906 finishPortlet();
2907 break;
f3d0cb20 2908 case 'ipv4addressbydescr':
ea5fc465
DO
2909 startPortlet ('IPv4 addresses');
2910 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
f3d0cb20 2911 // FIXME: address, parent network, routers (if extended view is enabled)
e1ae3fb4 2912 echo '<tr><th>Address</th><th>Description</th></tr>';
ea5fc465
DO
2913 foreach ($what as $addr)
2914 {
f3d0cb20
DO
2915 echo "<tr class=row_${order}><td class=tdleft>";
2916 $parentnet = getIPv4AddressNetworkId ($addr['ip']);
2917 if ($parentnet !== NULL)
e1ae3fb4 2918 echo "<a href='${root}?page=ipv4net&tab=default&id=${parentnet}&hl_ipv4_addr=${addr['ip']}'>${addr['ip']}</a></td>";
f3d0cb20
DO
2919 else
2920 echo "<a href='${root}?page=ipaddress&ip=${addr['ip']}'>${addr['ip']}</a></td>";
ea5fc465
DO
2921 echo "<td class=tdleft>${addr['name']}</td></tr>";
2922 $order = $nextorder[$order];
2923 }
2924 echo '</table>';
2925 finishPortlet();
2926 break;
05411ccd 2927 case 'ipv4rspool':
ee437dab 2928 startPortlet ("<a href='${root}?page=ipv4rsplist'>RS pools</a>");
05411ccd 2929 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
6cd32e3c 2930 foreach ($what as $cell)
05411ccd 2931 {
216136d2 2932 echo "<tr class=row_${order}><td class=tdleft>";
6cd32e3c 2933 renderCell ($cell);
216136d2 2934 echo "</td></tr>";
05411ccd
DO
2935 $order = $nextorder[$order];
2936 }
2937 echo '</table>';
2938 finishPortlet();
2939 break;
2940 case 'ipv4vs':
a239e016 2941 startPortlet ("<a href='${root}?page=ipv4vslist'>Virtual services</a>");
05411ccd 2942 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
6df2025d 2943 foreach ($what as $cell)
05411ccd 2944 {
8128c257 2945 echo "<tr class=row_${order}><td class=tdleft>";
6df2025d 2946 renderCell ($cell);
8128c257 2947 echo "</td></tr>";
6a88e734
DO
2948 $order = $nextorder[$order];
2949 }
2950 echo '</table>';
2951 finishPortlet();
2952 break;
2953 case 'user':
2954 startPortlet ("<a href='${root}?page=userlist'>Users</a>");
2955 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
6a88e734
DO
2956 foreach ($what as $item)
2957 {
19dac9c3 2958 echo "<tr class=row_${order}><td class=tdleft>";
573214e0 2959 renderCell ($item);
19dac9c3 2960 echo "</td></tr>";
05411ccd
DO
2961 $order = $nextorder[$order];
2962 }
2963 echo '</table>';
2964 finishPortlet();
2965 break;
e1ae3fb4
AD
2966 case 'file':
2967 startPortlet ("<a href='${root}?page=files'>Files</a>");
2968 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
6df2025d 2969 foreach ($what as $cell)
e1ae3fb4 2970 {
35d10b16 2971 echo "<tr class=row_${order}><td class=tdleft>";
6df2025d 2972 renderCell ($cell);
35d10b16 2973 echo "</td></tr>";
e1ae3fb4
AD
2974 $order = $nextorder[$order];
2975 }
2976 echo '</table>';
2977 finishPortlet();
2978 break;
e531b4d6
DO
2979 case 'rack':
2980 startPortlet ("<a href='${root}?page=rackspace'>Racks</a>");
2981 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
2982 foreach ($what as $cell)
2983 {
2984 echo "<tr class=row_${order}><td class=tdleft>";
2985 renderCell ($cell);
2986 echo "</td></tr>";
2987 $order = $nextorder[$order];
2988 }
2989 echo '</table>';
2990 finishPortlet();
2991 break;
e673ee24 2992 }
e673ee24
DO
2993 }
2994}
2995
2996// This function prints a table of checkboxes to aid the user in toggling mount atoms
2997// from one state to another. The first argument is rack data as
61a1d996 2998// produced by amplifyCell(), the second is the value used for the 'unckecked' state
e673ee24
DO
2999// and the third is the value used for 'checked' state.
3000// Usage contexts:
3001// for mounting an object: printAtomGrid ($data, 'F', 'T')
3002// for changing rack design: printAtomGrid ($data, 'A', 'F')
3003// for adding rack problem: printAtomGrid ($data, 'F', 'U')
3004// for adding object problem: printAtomGrid ($data, 'T', 'W')
3005
3006function renderAtomGrid ($data)
3007{
3008 $rack_id = $data['id'];
3009 for ($unit_no = $data['height']; $unit_no > 0; $unit_no--)
3010 {
57c69e9c 3011 echo "<tr><th><a href='javascript:;' onclick=\"toggleRowOfAtoms('${rack_id}','${unit_no}')\">${unit_no}</a></th>";
e673ee24
DO
3012 for ($locidx = 0; $locidx < 3; $locidx++)
3013 {
57c69e9c 3014 $name = "atom_${rack_id}_${unit_no}_${locidx}";
e673ee24
DO
3015 $state = $data[$unit_no][$locidx]['state'];
3016 echo "<td class=state_${state}";
3017 if (isset ($data[$unit_no][$locidx]['hl']))
3018 echo $data[$unit_no][$locidx]['hl'];
3019 echo ">";
3020 if (!($data[$unit_no][$locidx]['enabled'] === TRUE))
57c69e9c 3021 echo "<input type=checkbox id=${name} disabled>";
e673ee24 3022 else
57c69e9c 3023 echo "<input type=checkbox" . $data[$unit_no][$locidx]['checked'] . " name=${name} id=${name}>";
e673ee24
DO
3024 echo '</td>';
3025 }
3026 echo "</tr>\n";
3027 }
3028}
3029
abf18701 3030function renderCellList ($realm = NULL, $title = 'items', $do_amplify = FALSE)
e673ee24 3031{
573214e0
DO
3032 if ($realm === NULL)
3033 {
3034 global $pageno;
3035 $realm = $pageno;
3036 }
3037 global $nextorder;
e673ee24 3038 $order = 'odd';
31c941ec
DO
3039 $cellfilter = getCellFilter();
3040 $celllist = filterCellList (listCells ($realm), $cellfilter['expression']);
8bc5d1e4
DO
3041 if ($do_amplify)
3042 array_walk ($celllist, 'amplifyCell');
abf18701
DO
3043 echo "<table border=0 class=objectview>\n";
3044 echo "<tr><td class=pcleft>";
590e1281 3045 startPortlet ($title . ' (' . count ($celllist) . ')');
abf18701 3046 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
8bc5d1e4 3047 foreach ($celllist as $cell)
e673ee24 3048 {
70198850 3049 echo "<tr class=row_${order}><td>";
573214e0 3050 renderCell ($cell);
70198850 3051 echo "</td></tr>\n";
e673ee24
DO
3052 $order = $nextorder[$order];
3053 }
3054 echo '</table>';
3055 finishPortlet();
59427701 3056 echo '</td><td class=pcright>';
590e1281 3057 renderCellFilterPortlet ($cellfilter, $realm);
59427701 3058 echo "</td></tr></table>\n";
e673ee24
DO
3059}
3060
573214e0
DO
3061function renderUserList ()
3062{
3063 renderCellList ('user', 'User accounts');
3064}
3065
59427701 3066function renderUserListEditor ()
e673ee24 3067{
39b4abd0
DO
3068 function printNewItemTR ()
3069 {
3070 printOpFormIntro ('createUser');
79b8ad1e 3071 echo "<tr><td><input type=text size=16 name=username tabindex=100></td>\n";
39b4abd0
DO
3072 echo "<td><input type=text size=24 name=realname tabindex=101></td>";
3073 echo "<td><input type=password size=64 name=password tabindex=102></td><td>";
3074 printImageHREF ('create', 'Add new account', TRUE, 103);
3075 echo "</td></tr></form>";
3076 }
b82cce3f
DO
3077 $accounts = listCells ('user');
3078 startPortlet ('User accounts (' . count ($accounts) . ')');
e673ee24 3079 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
79b8ad1e 3080 echo "<tr><th>Username</th><th>Real name</th><th>Password</th><th>&nbsp;</th></tr>\n";
39b4abd0
DO
3081 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
3082 printNewItemTR();
e673ee24
DO
3083 foreach ($accounts as $account)
3084 {
7056988c 3085 printOpFormIntro ('updateUser', array ('user_id' => $account['user_id']));
79b8ad1e 3086 echo "<tr><td><input type=text name=username value='${account['user_name']}' size=16></td>";
e673ee24 3087 echo "<td><input type=text name=realname value='${account['user_realname']}' size=24></td>";
8e5763a7
DO
3088 echo "<td><input type=password name=password value='${account['user_password_hash']}' size=64></td><td>";
3089 printImageHREF ('save', 'Save changes', TRUE);
3090 echo "</td></form></tr>\n";
e673ee24 3091 }
9318d2ef 3092 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
39b4abd0 3093 printNewItemTR();
e673ee24
DO
3094 echo "</table><br>\n";
3095 finishPortlet();
3096}
3097
17c32f4c
DO
3098function renderPortMapViewer ()
3099{
3100 renderPortMap (FALSE);
3101}
3102
3103function renderPortMapEditor ()
3104{
3105 renderPortMap (TRUE);
3106}
3107
e673ee24
DO
3108function renderPortMap ($editable = FALSE)
3109{
b82cce3f 3110 global $nextorder;
e673ee24
DO
3111 startPortlet ("Port compatibility map");
3112 $ptlist = getPortTypes();
3113 $pclist = getPortCompat();
3114 $pctable = buildPortCompatMatrixFromList ($ptlist, $pclist);
3115 if ($editable)
7056988c 3116 printOpFormIntro ('save');
e673ee24
DO
3117 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
3118 echo "<tr><th class=vert_th>&nbsp;</th>";
3119 foreach ($ptlist as $name2)
3120 echo "<th>to ${name2}</th>";
3121 echo "</tr>";
3122 // Make a copy to have an independent array pointer.
3123 $ptlistY = $ptlist;
3124 $order = 'odd';
3125 foreach ($ptlistY as $type1 => $name1)
3126 {
3127 echo "<tr class=row_${order}><th class=vert_th style='border-bottom: 0px;'>from $name1</th>";
3128 foreach ($ptlist as $type2 => $name2)
3129 {
92b38217 3130 echo '<td' . ($pctable[$type1][$type2] ? " class=portmap_highlight_$order" : '') . '>';
19acd465 3131 echo '<input type=checkbox' . ($editable ? " name=atom_${type1}_${type2}" : ' disabled');
e673ee24
DO
3132 echo ($pctable[$type1][$type2] ? ' checked' : '') . '></td>';
3133 }
3134 echo "</tr>\n";
3135 $order = $nextorder[$order];