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