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