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