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