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