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