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