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