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