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