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