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