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