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