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