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