r4861 bugfix: generic exception formatting was throwing PHP warnings
[racktables] / wwwroot / inc / interface.php
CommitLineData
b325120a 1<?php
e673ee24
DO
2/*
3*
4* This file contains frontend functions for RackTables.
5*
6*/
7
e82deb48 8require_once 'ajax-interface.php';
defd92d8 9require_once 'slb-interface.php';
65e557dd 10
9c0b0016
DO
11// Interface function's special.
12$nextorder['odd'] = 'even';
13$nextorder['even'] = 'odd';
14
52c836b1
DO
15// address allocation type
16$aat = array
17(
18 'regular' => 'Connected',
19 'virtual' => 'Loopback',
20 'shared' => 'Shared',
21 'router' => 'Router',
22);
beb9e88a 23// address allocation code, IPv4 addresses and objects view
52c836b1
DO
24$aac = array
25(
26 'regular' => '',
27 'virtual' => '<strong>L</strong>',
28 'shared' => '<strong>S</strong>',
29 'router' => '<strong>R</strong>',
30);
beb9e88a
DO
31// address allocation code, IPv4 networks view
32$aac2 = array
33(
34 'regular' => '',
35 'virtual' => '<strong>L:</strong>',
29025f8e 36 'shared' => '<strong>S:</strong>',
beb9e88a
DO
37 'router' => '<strong>R:</strong>',
38);
52c836b1 39
0dabdc53
DO
40$vtdecoder = array
41(
42 'ondemand' => '',
54b7ced3
DO
43 'compulsory' => 'P',
44# 'alien' => 'NT',
0dabdc53
DO
45);
46
47$vtoptions = array
48(
54b7ced3
DO
49 'ondemand' => 'auto',
50 'compulsory' => 'permanent',
51# 'alien' => 'never touch',
0dabdc53
DO
52);
53
e5c4506d
DO
54// This may be populated later onsite, report rendering function will use it.
55// See the $systemreport for structure.
56$localreports = array();
d6adad3e 57
9db67d95
DO
58$CodePressMap = array
59(
60 'sql' => 'sql',
61 'php' => 'php',
62 'html' => 'html',
63 'css' => 'css',
64 'js' => 'javascript',
65);
e5c4506d 66
8d4f7d18
DO
67$attrtypes = array
68(
69 'uint' => '[U] unsigned integer',
70 'float' => '[F] floating point',
71 'string' => '[S] string',
72 'dict' => '[D] dictionary record'
73);
74
a1d72d2e
AA
75$quick_links = NULL; // you can override this in your local.php, but first initialize it with getConfiguredQuickLinks()
76
77function renderQuickLinks()
78{
79 global $quick_links;
80 if (! isset ($quick_links))
81 $quick_links = getConfiguredQuickLinks();
82 echo '<ul class="qlinks">';
83 foreach ($quick_links as $link)
84 echo '<li><a href="' . $link['href'] . '">' . str_replace (' ', '&nbsp;', $link['title']) . '</a></li>';
85 echo '</ul>';
86}
87
f97df464
DO
88function renderInterfaceHTML ($pageno, $tabno, $payload)
89{
90?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
91<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
92<head><title><?php echo getTitle ($pageno); ?></title>
93<?php printPageHeaders(); ?>
94</head>
95<body>
96<table border=0 cellpadding=0 cellspacing=0 width="100%" height="100%" class="maintable">
97 <tr class="mainheader"><td>
a1d72d2e
AA
98 <?php echo getConfigVar ('enterprise') ?> RackTables <a href="http://racktables.org" title="Visit RackTables site"><?php echo CODE_VERSION ?></a><?php renderQuickLinks() ?>
99 <div style="float: right" class=greeting><a href='index.php?page=myaccount&tab=default'><?php global $remote_displayname; echo $remote_displayname ?></a> [ <a href='?logout'>logout</a> ]</div>
f97df464
DO
100 </td></tr>
101 <tr><td class="menubar">
102 <table border="0" width="100%" cellpadding="3" cellspacing="0">
103 <tr><?php showPathAndSearch ($pageno); ?></tr>
104 </table>
105 </td></tr>
106 <tr><td><?php showTabs ($pageno, $tabno); ?></td></tr>
107 <tr><td><?php showMessageOrError(); ?></td></tr>
108 <tr><td><?php echo $payload; ?></td></tr>
109</table>
110</body>
111</html>
112<?php
113}
114
e673ee24 115// Main menu.
4b680876
DO
116function renderIndexItem ($ypageno) {
117 global $page;
118 if (permitted($ypageno)) {
a1d72d2e
AA
119 $title = getPageName ($ypageno);
120 print " <td>\n";
21ee3351 121 print " <h1><a href='".makeHref(array('page'=>$ypageno))."'>".$title."<br>\n";
4b680876
DO
122 printImageHREF ($ypageno);
123 print "</a></h1>\n";
124 print " </td>\n";
125 } else {
126 print " <td>&nbsp;</td>\n";
127 }
128}
129
e673ee24
DO
130function renderIndex ()
131{
67c5c049 132 global $indexlayout;
e673ee24
DO
133?>
134<table border=0 cellpadding=0 cellspacing=0 width='100%'>
135 <tr>
136 <td>
137 <div style='text-align: center; margin: 10px; '>
a544d2c4 138 <table width='100%' cellspacing=0 cellpadding=20 class=mainmenu border=0>
4b680876 139<?php
67c5c049
DO
140foreach ($indexlayout as $row)
141{
142 echo '<tr>';
143 foreach ($row as $column)
144 if ($column === NULL)
145 echo '<td>&nbsp;</td>';
146 else
147 renderIndexItem ($column);
148 echo '</tr>';
149}
150?>
e673ee24
DO
151 </table>
152 </div>
153 </td>
154 </tr>
155</table>
b325120a 156<?php
e673ee24
DO
157}
158
f3505b35
AA
159function getRenderedAlloc ($object_id, $alloc)
160{
161 $ret = array
162 (
163 'tr_class' => '',
164 'td_ip' => '',
165 'td_network' => '',
166 'td_routed_by' => '',
167 'td_peers' => '',
168 );
169 $dottedquad = $alloc['addrinfo']['ip'];
170
171 $hl_ip_addr = '';
172 if (isset ($_REQUEST['hl_ipv6_addr']))
173 {
174 if ($hl_ipv6 = assertIPv6Arg ('hl_ipv6_addr'))
175 $hl_ip_addr = $hl_ipv6->format();
176 }
177 elseif (isset ($_REQUEST['hl_ipv4_addr']))
178 $hl_ip_addr = $_REQUEST['hl_ipv4_addr'];
179 if ($hl_ip_addr)
180 addAutoScrollScript ("ip-$hl_ip_addr");
181
182 // prepare realm and network info
183 if ($alloc['addrinfo']['version'] == 6)
184 {
185 $ipv6_address = new IPv6Address();
186 $ipv6_address->parse ($dottedquad);
187 $addr_page_name = 'ipv6address';
188 if ($netid = getIPv6AddressNetworkId ($ipv6_address))
189 {
190 $netinfo = spotEntity ('ipv6net', $netid);
191 loadIPv6AddrList ($netinfo);
192 }
193 }
194 else
195 {
196 $addr_page_name = 'ipaddress';
197 if ($netid = getIPv4AddressNetworkId ($dottedquad))
198 {
199 $netinfo = spotEntity ('ipv4net', $netid);
200 loadIPv4AddrList ($netinfo);
201 }
202 }
203
204 $ret['tr_class'] = $alloc['addrinfo']['class'];
205 $td_class = 'tdleft';
206 if ($hl_ip_addr == $dottedquad)
207 $td_class .= ' port_highlight';
208
68c91b9c
AA
209 // render IP change history
210 $ip_title = '';
211 $ip_class = '';
212 if (isset ($alloc['addrinfo']['last_log']))
213 {
214 $log = $alloc['addrinfo']['last_log'];
215 $ip_title = "title='" .
216 htmlspecialchars
217 (
218 $log['user'] . ', ' . formatAge ($log['time']),
219 ENT_QUOTES
220 ) . "'";
221 $ip_class = 'hover-history underline';
222 }
223
f3505b35
AA
224 // render IP address td
225 global $aac;
226 $ret['td_ip'] = "<td class='$td_class'>";
227 if (NULL !== $netid)
68c91b9c 228 $ret['td_ip'] .= "<a name='ip-$dottedquad' class='$ip_class' $ip_title href='" .
f3505b35
AA
229 makeHref (
230 array
231 (
232 'page' => $addr_page_name,
233 'hl_object_id' => $object_id,
234 'ip' => $dottedquad,
235 )
236 ) . "'>" . $dottedquad . "</a>";
237 else
68c91b9c 238 $ret['td_ip'] .= "<span class='$ip_class' $ip_title>$dottedquad</span>";
f3505b35
AA
239 if (getConfigVar ('EXT_IPV4_VIEW') != 'yes')
240 $ret['td_ip'] .= '<small>/' . (NULL === $netid ? '??' : $netinfo['mask']) . '</small>';
241 $ret['td_ip'] .= '&nbsp;' . $aac[$alloc['type']];
242 if (strlen ($alloc['addrinfo']['name']))
243 $ret['td_ip'] .= ' (' . niftyString ($alloc['addrinfo']['name']) . ')';
244 $ret['td_ip'] .= '</td>';
245
246 // render network and routed_by tds
247 if (NULL === $netid)
248 {
249 $ret['td_network'] = "<td class='$td_class sparenetwork'>N/A</td>";
250 $ret['td_routed_by'] = $ret['td_network'];
251 }
252 else
253 {
254 $ret['td_network'] = "<td class='$td_class'>" .
255 getOutputOf ('renderCell', $netinfo) . '</td>';
256
257 // filter out self-allocation
258 $other_routers = array();
259 foreach (findRouters ($netinfo['addrlist']) as $router)
260 if ($router['id'] != $object_id)
261 $other_routers[] = $router;
262 if (count ($other_routers))
263 $ret['td_routed_by'] = getOutputOf ('printRoutersTD', $other_routers);
264 else
265 $ret['td_routed_by'] = "<td class='$td_class'>&nbsp;</td>";
266 }
267
268 // render peers td
269 $ret['td_peers'] = "<td class='$td_class'>";
270 $prefix = '';
271 if ($alloc['addrinfo']['reserved'] == 'yes')
272 {
273 $ret['td_peers'] .= $prefix . '<strong>RESERVED</strong>';
274 $prefix = '; ';
275 }
276 foreach ($alloc['addrinfo']['allocs'] as $allocpeer)
277 {
278 if ($allocpeer['object_id'] == $object_id)
279 continue;
280 $ret['td_peers'] .= $prefix . "<a href='" . makeHref (array ('page' => 'object', 'object_id' => $allocpeer['object_id'])) . "'>";
281 if (isset ($allocpeer['osif']) and strlen ($allocpeer['osif']))
282 $ret['td_peers'] .= $allocpeer['osif'] . '@';
283 $ret['td_peers'] .= $allocpeer['object_name'] . '</a>';
284 $prefix = '; ';
285 }
286 $ret['td_peers'] .= '</td>';
287
288 return $ret;
289}
290
e673ee24
DO
291function renderRackspace ()
292{
95857b5c
DO
293 $found_racks = array();
294 $rows = array();
a8efc03e 295 $cellfilter = getCellFilter();
1ebbf889 296 $rackCount = 0;
9b8174d7 297 foreach (getRows() as $row_id => $row_name) {
95857b5c
DO
298 $rackList = filterCellList (listCells ('rack', $row_id), $cellfilter['expression']);
299 $found_racks = array_merge($found_racks, $rackList);
300 $rows[] = array(
301 'row_id' => $row_id,
302 'row_name' => $row_name,
303 'racks' => $rackList
304 );
1ebbf889 305 $rackCount += count($rackList);
95857b5c 306 }
1ebbf889 307
95857b5c
DO
308 echo "<table class=objview border=0 width='100%'><tr><td class=pcleft>";
309 renderCellFilterPortlet ($cellfilter, 'rack', $found_racks);
489a7502 310 echo '</td><td class=pcright>';
1ebbf889
AA
311
312 if (! renderEmptyResults($cellfilter, 'racks', $rackCount))
e673ee24 313 {
1ebbf889
AA
314 echo '<table border=0 cellpadding=10 cellpadding=1>';
315 // generate thumb gallery
316 global $nextorder;
317 $rackwidth = getRackImageWidth();
318 // Zero value effectively disables the limit.
319 $maxPerRow = getConfigVar ('RACKS_PER_ROW');
320 $order = 'odd';
321 foreach ($rows as $row)
322 {
323 $row_id = $row['row_id'];
324 $row_name = $row['row_name'];
325 $rackList = $row['racks'];
326
327 if (!count ($rackList) and count ($cellfilter['expression']))
328 continue;
329 $rackListIdx = 0;
330 echo "<tr class=row_${order}><th class=tdleft>";
331 echo "<a href='".makeHref(array('page'=>'row', 'row_id'=>$row_id))."${cellfilter['urlextra']}'>";
332 echo "${row_name}</a></th><td><table border=0 cellspacing=5><tr>";
333 if (!count ($rackList))
334 echo "<td>(empty row)</td>";
335 else
336 foreach ($rackList as $rack)
48325652 337 {
1ebbf889
AA
338 if ($rackListIdx > 0 and $maxPerRow > 0 and $rackListIdx % $maxPerRow == 0)
339 {
340 echo '</tr></table></tr>';
341 echo "<tr class=row_${order}><th class=tdleft>${row_name} (continued)";
342 echo "</th><td><table border=0 cellspacing=5><tr>";
343 }
344 echo "<td align=center><a href='".makeHref(array('page'=>'rack', 'rack_id'=>$rack['id']))."'>";
345 echo "<img border=0 width=${rackwidth} height=";
346 echo getRackImageHeight ($rack['height']);
347 echo " title='${rack['height']} units'";
4afb4c10 348 echo "src='?module=image&img=minirack&rack_id=${rack['id']}'>";
1ebbf889
AA
349 echo "<br>${rack['name']}</a></td>";
350 $rackListIdx++;
48325652 351 }
1ebbf889
AA
352 $order = $nextorder[$order];
353 echo "</tr></table></tr>\n";
354 }
355 echo "</table>\n";
e673ee24 356 }
489a7502 357 echo "</td></tr></table>\n";
e673ee24
DO
358}
359
345fd640
AD
360function renderRackspaceRowEditor ()
361{
362 function printNewItemTR ()
363 {
364 printOpFormIntro ('addRow');
1f02e311 365 echo "<input type=hidden name=objtype_id value=1561>\n";
7be51fea
DO
366 echo "<tr><td>";
367 printImageHREF ('create', 'Add new row', TRUE);
368 echo "</td><td><input type=text name=name tabindex=100></td><td>";
345fd640 369 printImageHREF ('create', 'Add new row', TRUE, 101);
7be51fea 370 echo "</td></tr></form>";
345fd640 371 }
d732e47e 372 startPortlet ('Rows');
345fd640 373 echo "<table border=0 cellspacing=0 cellpadding=5 align=center class=widetable>\n";
7be51fea 374 echo "<tr><th>&nbsp;</th><th>Name</th><th>&nbsp;</th></tr>\n";
345fd640
AD
375 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
376 printNewItemTR();
9b8174d7 377 foreach (getRows() as $row_id => $row_name)
345fd640 378 {
7be51fea 379 echo "<tr><td>";
a8efc03e 380 if ($rc = count (listCells ('rack', $row_id)))
6c18dd08 381 printImageHREF ('nodestroy', "${rc} rack(s) here");
7be51fea 382 else
5af82683 383 {
1f02e311 384 echo "<a href=\"".makeHrefProcess(array('op'=>'deleteRow', 'row_id'=>$row_id))."\">";
7be51fea 385 printImageHREF ('destroy', 'Delete row');
5af82683
DY
386 echo "</a>";
387 }
c40666f5
DO
388 printOpFormIntro ('updateRow', array ('row_id' => $row_id));
389 echo "</td><td><input type=text name=name value='${row_name}'></td><td>";
7be51fea
DO
390 printImageHREF ('save', 'Save changes', TRUE);
391 echo "</form></td></tr>\n";
345fd640
AD
392 }
393 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
394 printNewItemTR();
395 echo "</table><br>\n";
396 finishPortlet();
397}
398
7e1db771 399function renderRow ($row_id)
e673ee24 400{
9b8174d7 401 $rowInfo = getRowInfo ($row_id);
a8efc03e
DO
402 $cellfilter = getCellFilter();
403 $rackList = filterCellList (listCells ('rack', $row_id), $cellfilter['expression']);
e673ee24
DO
404 // Main layout starts.
405 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
406
407 // Left portlet with row information.
408 echo "<tr><td class=pcleft>";
a8ce7234 409 startPortlet ($rowInfo['name']);
e673ee24 410 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
5af82683
DY
411 echo "<tr><th width='50%' class=tdright>Racks:</th><td class=tdleft>${rowInfo['count']}</td></tr>\n";
412 echo "<tr><th width='50%' class=tdright>Units:</th><td class=tdleft>${rowInfo['sum']}</td></tr>\n";
9b8174d7
AD
413 echo "<tr><th width='50%' class=tdright>% used:</th><td class=tdleft>";
414 renderProgressBar (getRSUforRow ($rackList));
114e50af 415 echo "</td></tr>\n";
e673ee24
DO
416 echo "</table><br>\n";
417 finishPortlet();
95857b5c 418 renderCellFilterPortlet ($cellfilter, 'rack', $rackList, 'row_id', $row_id);
e673ee24 419
48325652 420 echo "</td><td class=pcright>";
e673ee24 421
4fbb5a00 422 global $nextorder;
d5157018 423 $rackwidth = getRackImageWidth() * getConfigVar ('ROW_SCALE');
f5883ec1
DO
424 // Maximum number of racks per row is proportionally less, but at least 1.
425 $maxPerRow = max (floor (getConfigVar ('RACKS_PER_ROW') / getConfigVar ('ROW_SCALE')), 1);
426 $rackListIdx = 0;
e673ee24
DO
427 $order = 'odd';
428 startPortlet ('Racks');
429 echo "<table border=0 cellspacing=5 align='center'><tr>";
64b95774 430 foreach ($rackList as $rack)
e673ee24 431 {
f5883ec1
DO
432 if ($rackListIdx % $maxPerRow == 0)
433 {
434 if ($rackListIdx > 0)
435 echo '</tr>';
436 echo '<tr>';
437 }
9b8174d7
AD
438 $class = ($rack['has_problems'] == 'yes') ? 'error' : $order;
439 echo "<td align=center class=row_${class}><a href='".makeHref(array('page'=>'rack', 'rack_id'=>$rack['id']))."'>";
d5157018 440 echo "<img border=0 width=${rackwidth} height=" . (getRackImageHeight ($rack['height']) * getConfigVar ('ROW_SCALE'));
e673ee24 441 echo " title='${rack['height']} units'";
4afb4c10 442 echo "src='?module=image&img=minirack&rack_id=${rack['id']}'>";
e673ee24
DO
443 echo "<br>${rack['name']}</a></td>";
444 $order = $nextorder[$order];
f5883ec1 445 $rackListIdx++;
e673ee24
DO
446 }
447 echo "</tr></table>\n";
448 finishPortlet();
e673ee24
DO
449 echo "</td></tr></table>";
450}
451
0a7feebb
AD
452// Used by renderRack()
453function printObjectDetailsForRenderRack ($object_id)
454{
455 $objectData = spotEntity ('object', $object_id);
456 if (strlen ($objectData['asset_no']))
457 $prefix = "<div title='${objectData['asset_no']}";
458 else
459 $prefix = "<div title='no asset tag";
460 // Don't tell about label, if it matches common name.
461 $body = '';
462 if ($objectData['name'] != $objectData['label'] and strlen ($objectData['label']))
463 $body = ", visible label is \"${objectData['label']}\"";
464 // Display list of child objects, if any
465 $objectChildren = getEntityRelatives ('children', 'object', $objectData['id']);
466 if (count($objectChildren) > 0)
467 {
468 foreach ($objectChildren as $child)
469 $childNames[] = $child['name'];
470 natsort($childNames);
471 $suffix = sprintf(", contains %s'>", implode(', ', $childNames));
472 }
473 else
474 $suffix = "'>";
475 echo $prefix . $body . $suffix;
476 echo "<a href='".makeHref(array('page'=>'object', 'object_id'=>$objectData['id']))."'>${objectData['dname']}</a></div>";
477}
478
e673ee24 479// This function renders rack as HTML table.
7e1db771 480function renderRack ($rack_id, $hl_obj_id = 0)
e673ee24 481{
61a1d996
DO
482 $rackData = spotEntity ('rack', $rack_id);
483 amplifyCell ($rackData);
e673ee24
DO
484 markAllSpans ($rackData);
485 if ($hl_obj_id > 0)
486 highlightObject ($rackData, $hl_obj_id);
487 markupObjectProblems ($rackData);
488 $prev_id = getPrevIDforRack ($rackData['row_id'], $rack_id);
489 $next_id = getNextIDforRack ($rackData['row_id'], $rack_id);
d48d8820 490 echo "<center><table border=0><tr valign=middle>";
4fbb5a00 491 echo "<td><h2><a href='".makeHref(array('page'=>'row', 'row_id'=>$rackData['row_id']))."'>${rackData['row_name']}</a> :</h2></td>";
e673ee24
DO
492 // FIXME: use 'bypass'?
493 if ($prev_id != NULL)
9803c56c 494 {
4fbb5a00 495 echo "<td><a href='".makeHref(array('page'=>'rack', 'rack_id'=>$prev_id))."'>";
9803c56c 496 printImageHREF ('prev', 'previous rack');
d48d8820 497 echo "</a></td>";
9803c56c 498 }
4fbb5a00 499 echo "<td><h2><a href='".makeHref(array('page'=>'rack', 'rack_id'=>$rackData['id']))."'>${rackData['name']}</a></h2></td>";
e673ee24 500 if ($next_id != NULL)
9803c56c 501 {
4fbb5a00 502 echo "<td><a href='".makeHref(array('page'=>'rack', 'rack_id'=>$next_id))."'>";
f444c095 503 printImageHREF ('next', 'next rack');
d48d8820 504 echo "</a></td>";
9803c56c 505 }
d48d8820 506 echo "</h2></td></tr></table>\n";
e673ee24 507 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
d08147d6
DO
508 echo "<tr><th width='10%'>&nbsp;</th><th width='20%'>Front</th>";
509 echo "<th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
65e557dd 510 addAtomCSS();
e673ee24
DO
511 for ($i = $rackData['height']; $i > 0; $i--)
512 {
d08147d6 513 echo "<tr><th>${i}</th>";
e673ee24
DO
514 for ($locidx = 0; $locidx < 3; $locidx++)
515 {
516 if (isset ($rackData[$i][$locidx]['skipped']))
517 continue;
518 $state = $rackData[$i][$locidx]['state'];
65e557dd 519 echo "<td class='atom state_${state}";
e673ee24
DO
520 if (isset ($rackData[$i][$locidx]['hl']))
521 echo $rackData[$i][$locidx]['hl'];
65e557dd 522 echo "'";
e673ee24
DO
523 if (isset ($rackData[$i][$locidx]['colspan']))
524 echo ' colspan=' . $rackData[$i][$locidx]['colspan'];
525 if (isset ($rackData[$i][$locidx]['rowspan']))
526 echo ' rowspan=' . $rackData[$i][$locidx]['rowspan'];
527 echo ">";
528 switch ($state)
529 {
530 case 'T':
0a7feebb 531 printObjectDetailsForRenderRack($rackData[$i][$locidx]['object_id']);
e673ee24
DO
532 break;
533 case 'A':
534 echo '<div title="This rackspace does not exist">&nbsp;</div>';
535 break;
536 case 'F':
537 echo '<div title="Free rackspace">&nbsp;</div>';
538 break;
539 case 'U':
540 echo '<div title="Problematic rackspace, you CAN\'T mount here">&nbsp;</div>';
541 break;
542 default:
543 echo '<div title="No data">&nbsp;</div>';
544 break;
545 }
546 echo '</td>';
547 }
548 echo "</tr>\n";
549 }
0a7feebb
AD
550 echo "</table>\n";
551 // Get a list of all of objects Zero-U mounted to this rack
552 $zeroUObjects = getEntityRelatives('children', 'rack', $rack_id);
553 if (count($zeroUObjects) > 0) {
554 echo "<br><table width='75%' class=rack border=0 cellspacing=0 cellpadding=1>\n";
555 echo "<tr><th>Zero-U:</th></tr>\n";
556 foreach ($zeroUObjects as $zeroUObject)
557 {
558 $state = ($zeroUObject['entity_id'] == $hl_obj_id) ? 'Th' : 'T';
559 echo "<tr><td class='atom state_${state}'>";
560 printObjectDetailsForRenderRack($zeroUObject['entity_id']);
561 echo "</td></tr>\n";
562 }
563 echo "</table>\n";
564 }
565 echo "</center>\n";
e673ee24
DO
566}
567
e673ee24
DO
568function renderNewRackForm ($row_id)
569{
9b8174d7
AD
570 $default_height = getConfigVar ('DEFAULT_RACK_HEIGHT');
571 if ($default_height == 0)
572 $default_height = '';
50b4ba85 573 startPortlet ('Add one');
f19c75d6 574 printOpFormIntro ('addRack', array ('got_data' => 'TRUE'));
e673ee24 575 echo '<table border=0 align=center>';
9b8174d7 576 echo "<tr><th class=tdright>Name (required):</th><td class=tdleft><input type=text name=name tabindex=1></td>";
72d52730 577 echo "<td rowspan=4>Assign tags:<br>";
a26a6ccc 578 renderNewEntityTags ('rack');
72d52730 579 echo "</td></tr>\n";
9b8174d7 580 echo "<tr><th class=tdright>Height in units (required):</th><td class=tdleft><input type=text name=height1 tabindex=2 value='${default_height}'></td></tr>\n";
9b8174d7 581 echo "<tr><th class=tdright>Asset tag:</th><td class=tdleft><input type=text name=asset_no tabindex=4></td></tr>\n";
f19c75d6
DO
582 echo "<tr><td class=submit colspan=2>";
583 printImageHREF ('CREATE', 'Add', TRUE);
584 echo "</td></tr></table></form>";
406b54bd 585 finishPortlet();
406b54bd 586
50b4ba85 587 startPortlet ('Add many');
f19c75d6 588 printOpFormIntro ('addRack', array ('got_mdata' => 'TRUE'));
50b4ba85 589 echo '<table border=0 align=center>';
9b8174d7 590 echo "<tr><th class=tdright>Height in units (*):</th><td class=tdleft><input type=text name=height2 value='${default_height}'></td>";
72d52730 591 echo "<td rowspan=3 valign=top>Assign tags:<br>";
a26a6ccc 592 renderNewEntityTags ('rack');
72d52730 593 echo "</td></tr>\n";
9b8174d7 594 echo "<tr><th class=tdright>Rack names (required):</th><td class=tdleft><textarea name=names cols=40 rows=25></textarea></td></tr>\n";
f19c75d6
DO
595 echo "<tr><td class=submit colspan=2>";
596 printImageHREF ('CREATE', 'Add', TRUE);
e673ee24
DO
597 echo '</form></table>';
598 finishPortlet();
599}
600
3825c4db 601function renderEditObjectForm()
e673ee24 602{
2c2ea5f6 603 global $pageno, $virtual_obj_types;
3825c4db 604 $object_id = getBypassValue();
fb6e2f57 605 $object = spotEntity ('object', $object_id);
cdd3efe9 606 startPortlet ();
43fb6eaf 607 printOpFormIntro ('update');
cdd3efe9
AD
608
609 // static attributes
e10f583a
DO
610 echo '<table border=0 cellspacing=0 cellpadding=3 align=center>';
611 echo "<tr><td>&nbsp;</td><th colspan=2><h2>Attributes</h2></th></tr>";
3825c4db
DO
612 echo '<tr><td>&nbsp;</td><th class=tdright>Type:</th><td class=tdleft>';
613 printSelect (getObjectTypeChangeOptions ($object['id']), array ('name' => 'object_type_id'), $object['objtype_id']);
614 echo '</td></tr>';
22bb04da 615 // baseline info
e10f583a 616 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";
2c2ea5f6 617 if (in_array($object['objtype_id'], $virtual_obj_types))
0682218d
AD
618 {
619 echo "<input type=hidden name=object_label value=''>\n";
620 echo "<input type=hidden name=object_asset_no value=''>\n";
0682218d
AD
621 }
622 else
623 {
624 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";
625 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";
0682218d
AD
626 }
627 // parent selection
9b8174d7 628 if (objectTypeMayHaveParent ($object['objtype_id']))
0682218d
AD
629 {
630 $parents = getEntityRelatives ('parents', 'object', $object_id);
631 foreach ($parents as $link_id => $parent_details)
632 {
633 if (!isset($label))
634 $label = count($parents) > 1 ? 'Containers:' : 'Container:';
635 echo "<tr><td>&nbsp;</td>";
636 echo "<th class=tdright>${label}</th><td class=tdleft>";
637 echo "<a href='".makeHref(array('page'=>'object', 'object_id'=>$parent_details['entity_id']))."'>${parent_details['name']}</a>";
638 echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
639 echo "<a href='".
640 makeHrefProcess(array(
641 'op'=>'unlinkEntities',
642 'link_id'=>$link_id,
643 'object_id'=>$object_id,
644 'page='=>'object',
645 'tab'=>'edit')).
646 "'>";
647 printImageHREF ('cut', 'Unlink container');
648 echo "</a>";
649 echo "</td></tr>\n";
650 $label = '&nbsp;';
651 }
652 echo "<tr><td>&nbsp;</td>";
653 echo "<th class=tdright>Select container:</th><td class=tdleft>";
654 echo "<span";
655 $helper_args = array ('object_id' => $object_id);
656 $popup_args = 'height=700, width=400, location=no, menubar=no, '.
657 'resizable=yes, scrollbars=yes, status=no, titlebar=no, toolbar=no';
658 echo " onclick='window.open(\"" . makeHrefForHelper ('objlist', $helper_args);
659 echo "\",\"findlink\",\"${popup_args}\");'>";
660 printImageHREF ('attach', 'Select a container');
661 echo "</span></td></tr>\n";
662 }
cdd3efe9 663 // optional attributes
e673ee24 664 $values = getAttrValues ($object_id);
0f63538a 665 echo '<input type=hidden name=num_attrs value=' . count($values) . ">\n";
2b98d5a2 666 if (count($values) > 0)
e673ee24 667 {
2b98d5a2
AD
668 $i = 0;
669 foreach ($values as $record)
e673ee24 670 {
2b98d5a2
AD
671 echo "<input type=hidden name=${i}_attr_id value=${record['id']}>";
672 echo '<tr><td>';
59a83bd8 673 if (strlen ($record['value']))
2b98d5a2 674 {
4fbb5a00 675 echo "<a href='".makeHrefProcess(array('op'=>'clearSticker', 'object_id'=>$object_id, 'attr_id'=>$record['id']))."'>";
2b98d5a2
AD
676 printImageHREF ('clear', 'Clear value');
677 echo '</a>';
678 }
679 else
680 echo '&nbsp;';
681 echo '</td>';
e10f583a 682 echo "<th class=sticker>${record['name']}:</th><td class=tdleft>";
2b98d5a2
AD
683 switch ($record['type'])
684 {
685 case 'uint':
686 case 'float':
687 case 'string':
688 echo "<input type=text name=${i}_value value='${record['value']}'>";
689 break;
690 case 'dict':
7fa7047a 691 $chapter = readChapter ($record['chapter_id'], 'o');
2b98d5a2 692 $chapter[0] = '-- NOT SET --';
f3d274bf 693 $chapter = cookOptgroups ($chapter, $object['objtype_id'], $record['key']);
cd3775e9 694 printNiftySelect ($chapter, array ('name' => "${i}_value"), $record['key']);
2b98d5a2
AD
695 break;
696 }
697 echo "</td></tr>\n";
698 $i++;
e673ee24 699 }
e673ee24 700 }
e10f583a
DO
701 echo "<tr><td>&nbsp;</td><th class=tdright>Has problems:</th><td class=tdleft><input type=checkbox name=object_has_problems";
702 if ($object['has_problems'] == 'yes')
703 echo ' checked';
704 echo "></td></tr>\n";
abd1e9ac
DO
705 echo "<tr><td>&nbsp;</td><th class=tdright>Actions:</th><td class=tdleft>";
706 echo "<a href='".
3067f362 707 makeHrefProcess(array('op'=>'deleteObject', 'page'=>'depot', 'tab'=>'addmore', 'object_id'=>$object_id)).
abd1e9ac
DO
708 "' onclick=\"javascript:return confirm('Are you sure you want to delete the object?')\">" . getImageHREF ('destroy', 'Delete object') . "</a>";
709 echo "&nbsp;";
710 echo "<a href='".
711 makeHrefProcess(array ('op'=>'resetObject', 'page' => 'object', 'tab' => 'edit', 'object_id' => $object_id)).
712 "' onclick=\"javascript:return confirm('Are you sure you want to reset most of object properties?')\">" . getImageHREF ('clear', 'Reset (cleanup) object') . "</a>";
713 echo "</td></tr>\n";
e10f583a 714 echo "<tr><td colspan=3><b>Comment:</b><br><textarea name=object_comment rows=10 cols=80>${object['comment']}</textarea></td></tr>";
cdd3efe9 715
e10f583a 716 echo "<tr><th class=submit colspan=3>";
5bbbeaa2 717 printImageHREF ('SAVE', 'Save changes', TRUE);
cdd3efe9 718 echo "</form></th></tr></table>\n";
e673ee24 719 finishPortlet();
e673ee24 720
cdd3efe9 721 echo '<table border=0 width=100%><tr><td>';
e673ee24 722 startPortlet ('history');
9b8174d7 723 renderObjectHistory ($object_id);
e673ee24 724 finishPortlet();
cdd3efe9 725 echo '</td></tr></table>';
e673ee24
DO
726}
727
728// This is a clone of renderEditObjectForm().
729function renderEditRackForm ($rack_id)
730{
0c2b7c4a 731 global $pageno;
61a1d996
DO
732 $rack = spotEntity ('rack', $rack_id);
733 amplifyCell ($rack);
e673ee24 734
9b8174d7 735 startPortlet ('Attributes');
7056988c 736 printOpFormIntro ('updateRack');
e673ee24 737 echo '<table border=0 align=center>';
9b8174d7
AD
738 echo "<tr><td>&nbsp;</td><th class=tdright>Rack row:</th><td class=tdleft>";
739 printSelect (getRows(), array ('name' => 'row_id'), $rack['row_id']);
e673ee24 740 echo "</td></tr>\n";
9b8174d7
AD
741 echo "<tr><td>&nbsp;</td><th class=tdright>Name (required):</th><td class=tdleft><input type=text name=name value='${rack['name']}'></td></tr>\n";
742 echo "<tr><td>&nbsp;</td><th class=tdright>Height (required):</th><td class=tdleft><input type=text name=height value='${rack['height']}'></td></tr>\n";
9b8174d7
AD
743 echo "<tr><td>&nbsp;</td><th class=tdright>Asset tag:</th><td class=tdleft><input type=text name=asset_no value='${rack['asset_no']}'></td></tr>\n";
744 // optional attributes
745 $values = getAttrValues ($rack_id);
746 $num_attrs = count($values);
747 $num_attrs = $num_attrs-1; // subtract for the 'height' attribute
748 echo "<input type=hidden name=num_attrs value=${num_attrs}>\n";
749 $i = 0;
750 foreach ($values as $record)
751 {
752 // Skip the 'height' attribute as it's already displayed as a required field
753 if ($record['id'] == 27)
754 continue;
755 echo "<input type=hidden name=${i}_attr_id value=${record['id']}>";
756 echo '<tr><td>';
757 if (strlen ($record['value']))
758 {
759 echo "<a href='".makeHrefProcess(array('op'=>'clearSticker', 'rack_id'=>$rack_id, 'attr_id'=>$record['id']))."'>";
760 printImageHREF ('clear', 'Clear value');
761 echo '</a>';
762 }
763 else
764 echo '&nbsp;';
765 echo '</td>';
766 echo "<th class=sticker>${record['name']}:</th><td class=tdleft>";
767 switch ($record['type'])
768 {
769 case 'uint':
770 case 'float':
771 case 'string':
772 echo "<input type=text name=${i}_value value='${record['value']}'>";
773 break;
774 case 'dict':
775 $chapter = readChapter ($record['chapter_id'], 'o');
776 $chapter[0] = '-- NOT SET --';
777 $chapter = cookOptgroups ($chapter, 1560, $record['key']);
778 printNiftySelect ($chapter, array ('name' => "${i}_value"), $record['key']);
779 break;
780 }
781 echo "</td></tr>\n";
782 $i++;
783 }
784 echo "<tr><td>&nbsp;</td><th class=tdright>Has problems:</th><td class=tdleft><input type=checkbox name=has_problems";
785 if ($rack['has_problems'] == 'yes')
786 echo ' checked';
787 echo "></td></tr>\n";
c8187437
DY
788 if (count ($rack['mountedObjects']) == 0)
789 {
9b8174d7
AD
790 echo "<tr><td>&nbsp;</td><th class=tdright>Actions:</th><td class=tdleft>";
791 echo "<a href='".
792 makeHrefProcess(array('op'=>'deleteRack', 'rack_id'=>$rack_id)).
793 "' onclick=\"javascript:return confirm('Are you sure you want to delete the rack?')\">" . getImageHREF ('destroy', 'Delete rack') . "</a>";
794 echo "&nbsp;</td></tr>\n";
c8187437 795 }
9b8174d7
AD
796 echo "<tr><td colspan=3><b>Comment:</b><br><textarea name=comment rows=10 cols=80>${rack['comment']}</textarea></td></tr>";
797 echo "<tr><td class=submit colspan=3>";
7056988c
DO
798 printImageHREF ('SAVE', 'Save changes', TRUE);
799 echo "</td></tr>\n";
e673ee24
DO
800 echo '</form></table><br>';
801 finishPortlet();
802
803 startPortlet ('History');
9b8174d7 804 renderObjectHistory ($rack_id);
e673ee24
DO
805 finishPortlet();
806}
807
254673dd
DO
808// used by renderGridForm() and renderRackPage()
809function renderRackInfoPortlet ($rackData)
810{
646272be
AA
811 $summary = array();
812 $summary['Rack row'] = $rackData['row_name'];
813 $summary['Name'] = $rackData['name'];
814 $summary['Height'] = $rackData['height'];
9b8174d7 815 if (strlen ($rackData['asset_no']))
646272be 816 $summary['Asset tag'] = $rackData['asset_no'];
9b8174d7 817 if ($rackData['has_problems'] == 'yes')
646272be 818 $summary[] = array ('<tr><td colspan=2 class=msg_error>Has problems</td></tr>');
9b8174d7
AD
819 // Display populated attributes, but skip Height since it's already displayed above
820 foreach (getAttrValues ($rackData['id']) as $record)
821 if ($record['id'] != 27 && strlen ($record['value']))
646272be
AA
822 $summary['{sticker}' . $record['name']] = formatAttributeValue ($record);
823 $summary['% used'] = getProgressBar (getRSUforRack ($rackData));
824 $summary['Objects'] = count ($rackData['mountedObjects']);
825 $summary['tags'] = '';
59a83bd8 826 if (strlen ($rackData['comment']))
646272be
AA
827 $summary['Comment'] = $rackData['comment'];
828 renderEntitySummary ($rackData, 'summary', $summary);
254673dd
DO
829}
830
e673ee24 831// This is a universal editor of rack design/waste.
7056988c 832// FIXME: switch to using printOpFormIntro()
7e1db771 833function renderGridForm ($rack_id, $filter, $header, $submit, $state1, $state2)
e673ee24 834{
61a1d996
DO
835 $rackData = spotEntity ('rack', $rack_id);
836 amplifyCell ($rackData);
254673dd 837 $filter ($rackData);
e673ee24
DO
838 markupObjectProblems ($rackData);
839
e673ee24
DO
840 // Render the result whatever it is.
841 // Main layout.
842 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
843 echo "<tr><td colspan=2 align=center><h1>${rackData['name']}</h1></td></tr>\n";
844
845 // Left column with information portlet.
846 echo "<tr><td class=pcleft height='1%' width='50%'>";
254673dd 847 renderRackInfoPortlet ($rackData);
e673ee24 848 echo "</td>\n";
bb09cca0 849 echo "<td class=pcright>";
e673ee24
DO
850
851 // Grid form.
852 startPortlet ($header);
65e557dd 853 addJS ('js/racktables.js');
e673ee24
DO
854 echo "<center>\n";
855 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
57c69e9c 856 echo "<tr><th width='10%'>&nbsp;</th>";
64259015
DO
857 echo "<th width='20%'><a href='javascript:;' oncontextmenu=\"blockToggleColumnOfAtoms('${rack_id}', '0', ${rackData['height']}); return false;\" onclick=\"toggleColumnOfAtoms('${rack_id}', '0', ${rackData['height']})\">Front</a></th>";
858 echo "<th width='50%'><a href='javascript:;' oncontextmenu=\"blockToggleColumnOfAtoms('${rack_id}', '1', ${rackData['height']}); return false;\" onclick=\"toggleColumnOfAtoms('${rack_id}', '1', ${rackData['height']})\">Interior</a></th>";
859 echo "<th width='20%'><a href='javascript:;' oncontextmenu=\"blockToggleColumnOfAtoms('${rack_id}', '2', ${rackData['height']}); return false;\" onclick=\"toggleColumnOfAtoms('${rack_id}', '2', ${rackData['height']})\">Back</a></th></tr>\n";
4fbb5a00 860 printOpFormIntro ('updateRack');
e673ee24
DO
861 markupAtomGrid ($rackData, $state2);
862 renderAtomGrid ($rackData);
863 echo "</table></center>\n";
864 echo "<br><input type=submit name=do_update value='${submit}'></form><br><br>\n";
865 finishPortlet();
bb09cca0 866 echo "</td></tr></table>\n";
e673ee24
DO
867}
868
869function renderRackDesign ($rack_id)
870{
bb09cca0 871 renderGridForm ($rack_id, 'applyRackDesignMask', 'Rack design', 'Set rack design', 'A', 'F');
e673ee24
DO
872}
873
7e1db771 874function renderRackProblems ($rack_id)
e673ee24 875{
bb09cca0 876 renderGridForm ($rack_id, 'applyRackProblemMask', 'Rack problems', 'Mark unusable atoms', 'F', 'U');
e673ee24
DO
877}
878
9b8174d7 879function renderObject ($object_id)
e673ee24 880{
f3505b35 881 global $nextorder, $virtual_obj_types;
fb6e2f57 882 $info = spotEntity ('object', $object_id);
94fe6370 883 amplifyCell ($info);
e673ee24
DO
884 // Main layout starts.
885 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
886 echo "<tr><td colspan=2 align=center><h1>${info['dname']}</h1></td></tr>\n";
887 // left column with uknown number of portlets
888 echo "<tr><td class=pcleft>";
646272be
AA
889
890 // display summary portlet
891 $summary = array();
59a83bd8 892 if (strlen ($info['name']))
646272be 893 $summary['Common name'] = $info['name'];
94fe6370 894 elseif (considerConfiguredConstraint ($info, 'NAMEWARN_LISTSRC'))
646272be
AA
895 $summary[] = array ('<tr><td colspan=2 class=msg_error>Common name is missing.</td></tr>');
896 $summary['Object type'] = '<a href="' . makeHref (array (
341fd895
DO
897 'page' => 'depot',
898 'tab' => 'default',
899 'cfe' => '{$typeid_' . $info['objtype_id'] . '}'
646272be 900 )) . '">' . decodeObjectType ($info['objtype_id'], 'o') . '</a>';
9b8174d7 901 if (strlen ($info['label']))
646272be 902 $summary['Visible label'] = $info['label'];
59a83bd8 903 if (strlen ($info['asset_no']))
646272be 904 $summary['Asset tag'] = $info['asset_no'];
d4e8ddeb 905 elseif (considerConfiguredConstraint ($info, 'ASSETWARN_LISTSRC'))
646272be
AA
906 $summary[] = array ('<tr><td colspan=2 class=msg_error>Asset tag is missing.</td></tr>');
907 $parents = getEntityRelatives ('parents', 'object', $object_id);
908 if (count ($parents))
0682218d 909 {
646272be 910 $fmt_parents = array();
0682218d 911 foreach ($parents as $parent)
8023ee39
AA
912 $fmt_parents[] = "<a href='".makeHref(array('page'=>$parent['page'], $parent['id_name'] => $parent['entity_id']))."'>${parent['name']}</a>";
913 $summary[count($parents) > 1 ? 'Containers' : 'Container'] = implode ('<br>', $fmt_parents);
0682218d 914 }
646272be
AA
915 $children = getEntityRelatives ('children', 'object', $object_id);
916 if (count ($children))
0682218d 917 {
646272be 918 $fmt_children = array();
0682218d 919 foreach ($children as $child)
8023ee39 920 $fmt_children[] = "<a href='".makeHref(array('page'=>$child['page'], $child['id_name']=>$child['entity_id']))."'>${child['name']}</a>";
646272be 921 $summary['Contains'] = implode ('<br>' . $fmt_children);
0682218d 922 }
e673ee24 923 if ($info['has_problems'] == 'yes')
646272be 924 $summary[] = array ('<tr><td colspan=2 class=msg_error>Has problems</td></tr>');
8ad59489 925 foreach (getAttrValues ($object_id) as $record)
4969aa31
DO
926 if
927 (
928 strlen ($record['value']) and
929 permitted (NULL, NULL, NULL, array (array ('tag' => '$attr_' . $record['id'])))
930 )
646272be 931 $summary['{sticker}' . $record['name']] = formatAttributeValue ($record);
a2c597ea
AA
932 $summary[] = array (getOutputOf ('printTagTRs',
933 $info,
934 makeHref
935 (
936 array
937 (
938 'page'=>'depot',
939 'tab'=>'default',
940 'andor' => 'and',
941 'cfe' => '{$typeid_' . $info['objtype_id'] . '}',
942 )
943 )."&"
944 ));
646272be 945 renderEntitySummary ($info, 'summary', $summary);
e673ee24 946
59a83bd8 947 if (strlen ($info['comment']))
e673ee24
DO
948 {
949 startPortlet ('Comment');
6cc5d6cd 950 echo '<div class=commentblock>' . string_insert_hrefs ($info['comment']) . '</div>';
e673ee24
DO
951 finishPortlet ();
952 }
953
9a90adc4
DO
954 if (count ($logrecords = getLogRecordsForObject ($_REQUEST['object_id'])))
955 {
956 startPortlet ('log records');
957 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable width='100%'>";
958 $order = 'odd';
959 foreach (getLogRecordsForObject ($_REQUEST['object_id']) as $row)
960 {
961 echo "<tr class=row_${order} valign=top>";
962 echo '<td class=tdleft>' . $row['date'] . '<br>' . $row['user'] . '</td>';
c14b5720 963 echo '<td class="slbconf rsvtext">' . string_insert_hrefs (htmlspecialchars ($row['content'], ENT_NOQUOTES)) . '</td>';
9a90adc4
DO
964 echo '</tr>';
965 $order = $nextorder[$order];
966 }
967 echo '</table>';
968 finishPortlet();
969 }
970
65e557dd 971 switchportInfoJS ($object_id); // load JS code to make portnames interactive
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 981 $hl_port_id = $_REQUEST['hl_port_id'];
65e557dd 982 addAutoScrollScript ("port-$hl_port_id");
9f75e165
DO
983 }
984 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>";
985 echo '<tr><th class=tdleft>Local name</th><th class=tdleft>Visible label</th>';
0d59a51c 986 echo '<th class=tdleft>Interface</th><th class=tdleft>L2 address</th>';
0c7c9f8b
DO
987 echo '<th class=tdcenter colspan=2>Remote object and port</th>';
988 echo '<th class=tdleft>Cable ID</th></tr>';
9f75e165
DO
989 foreach ($info['ports'] as $port)
990 {
991 echo '<tr';
992 if ($hl_port_id == $port['id'])
993 echo ' class=port_highlight';
65e557dd 994 $a_class = isEthernetPort ($port) ? 'port-menu' : '';
a8dc2982 995 echo "><td class='tdleft' NOWRAP><a name='port-${port['id']}' class='ancor interactive-portname nolink $a_class'>${port['name']}</a></td>";
65e557dd
AA
996 echo "<td class=tdleft>${port['label']}</td>";
997 echo "<td class=tdleft>" . formatPortIIFOIF ($port) . "</td><td class=tdleft><tt>${port['l2address']}</tt></td>";
9f75e165 998 if ($port['remote_object_id'])
e673ee24 999 {
5c6225b1 1000 echo "<td class=tdleft>" .
a2ea559e 1001 formatPortLink ($port['remote_object_id'], $port['remote_object_name'], $port['remote_id'], NULL) .
5c6225b1
AA
1002 "</td>";
1003 echo "<td class=tdleft>" . formatLoggedSpan ($port['last_log'], $port['remote_name'], 'underline') . "</td>";
0c7c9f8b 1004 echo "<td class='tdleft rsvtext'>${port['cableid']}</td>";
e673ee24 1005 }
9f75e165 1006 else
a8dc2982 1007 echo implode ('', formatPortReservation ($port)) . '<td></td>';
9f75e165 1008 echo "</tr>";
e673ee24 1009 }
fd5edda8 1010 if (permitted (NULL, 'ports', 'set_reserve_comment'))
a8dc2982 1011 addJS ('js/inplace-edit.js');
9f75e165 1012 echo "</table><br>";
e673ee24
DO
1013 finishPortlet();
1014 }
85970da2 1015
21ee3351 1016 if (count ($info['ipv4']) + count ($info['ipv6']))
e673ee24 1017 {
21ee3351 1018 startPortlet ('IP addresses');
e673ee24 1019 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
f0ed1181 1020 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
0b9c98d7 1021 echo "<tr><th>OS interface</th><th>IP address</th><th>network</th><th>routed by</th><th>peers</th></tr>\n";
83fdf85f
DO
1022 else
1023 echo "<tr><th>OS interface</th><th>IP address</th><th>peers</th></tr>\n";
21ee3351
AA
1024
1025 // group IP allocations by interface name instead of address family
1026 $allocs_by_iface = array();
1027 foreach (array ('ipv4', 'ipv6') as $ip_v)
1028 foreach ($info[$ip_v] as $dottedquad => $alloc)
1029 $allocs_by_iface[$alloc['osif']][$dottedquad] = $alloc;
1030
1031 // sort allocs array by portnames
1032 foreach (sortPortList ($allocs_by_iface) as $iface_name => $alloclist)
1033 {
1034 $is_first_row = TRUE;
f3505b35 1035 foreach ($alloclist as $alloc)
b90c3907 1036 {
f3505b35
AA
1037 $rendered_alloc = getRenderedAlloc ($object_id, $alloc);
1038 echo "<tr class='${rendered_alloc['tr_class']}' valign=top>";
21ee3351 1039
f3505b35 1040 // display iface name, same values are grouped into single cell
21ee3351
AA
1041 if ($is_first_row)
1042 {
1043 $rowspan = count ($alloclist) > 1 ? 'rowspan="' . count ($alloclist) . '"' : '';
1044 echo "<td class=tdleft $rowspan>$iface_name</td>";
1045 $is_first_row = FALSE;
1046 }
f3505b35 1047 echo $rendered_alloc['td_ip'];
21ee3351 1048 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
83fdf85f 1049 {
f3505b35
AA
1050 echo $rendered_alloc['td_network'];
1051 echo $rendered_alloc['td_routed_by'];
21ee3351 1052 }
f3505b35
AA
1053 echo $rendered_alloc['td_peers'];
1054
1055 echo "</tr>\n";
b90c3907 1056 }
e673ee24
DO
1057 }
1058 echo "</table><br>\n";
1059 finishPortlet();
1060 }
1061
94fe6370 1062 $forwards = $info['nat4'];
e673ee24
DO
1063 if (count($forwards['in']) or count($forwards['out']))
1064 {
f28fbe8b 1065 startPortlet('NATv4');
e673ee24
DO
1066
1067 if (count($forwards['out']))
1068 {
1069
f28fbe8b 1070 echo "<h3>locally performed NAT</h3>";
e673ee24 1071
105a3bc8 1072 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
f28fbe8b 1073 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
1074
1075 foreach ($forwards['out'] as $pf)
1076 {
2c817354
DO
1077 $class = 'trerror';
1078 $osif = '';
1079 if (isset ($alloclist [$pf['localip']]))
1080 {
1081 $class = $alloclist [$pf['localip']]['addrinfo']['class'];
1082 $osif = $alloclist [$pf['localip']]['osif'] . ': ';
1083 }
e673ee24 1084 echo "<tr class='$class'>";
4fbb5a00
DY
1085 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>";
1086 echo "<td class=tdleft><a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['remoteip']))."'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
53ef3908 1087 $address = getIPv4Address ($pf['remoteip']);
e673ee24 1088 echo "<td class='description'>";
53ef3908
DO
1089 if (count ($address['allocs']))
1090 foreach($address['allocs'] as $bond)
4fbb5a00 1091 echo "<a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$bond['object_id']))."'>${bond['object_name']}(${bond['name']})</a> ";
59a83bd8 1092 elseif (strlen ($pf['remote_addr_name']))
f28fbe8b 1093 echo '(' . $pf['remote_addr_name'] . ')';
53ef3908 1094 echo "</td><td class='description'>${pf['description']}</td></tr>";
e673ee24
DO
1095 }
1096 echo "</table><br><br>";
1097 }
1098 if (count($forwards['in']))
1099 {
f28fbe8b 1100 echo "<h3>arriving NAT connections</h3>";
105a3bc8 1101 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
f28fbe8b 1102 echo "<tr><th>Matched endpoint</th><th>Source object</th><th>Translated to</th><th>Rule comment</th></tr>\n";
e673ee24
DO
1103 foreach ($forwards['in'] as $pf)
1104 {
1105 echo "<tr>";
4fbb5a00
DY
1106 echo "<td>${pf['proto']}/<a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['localip']))."'>${pf['localip']}</a>:${pf['localport']}</td>";
1107 echo "<td class='description'><a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$pf['object_id']))."'>${pf['object_name']}</a>";
1108 echo "</td><td><a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['remoteip']))."'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
e673ee24
DO
1109 echo "<td class='description'>${pf['description']}</td></tr>";
1110 }
e673ee24
DO
1111 echo "</table><br><br>";
1112 }
1113 finishPortlet();
1114 }
1115
defd92d8 1116 renderSLBTriplets ($info);
e673ee24
DO
1117 echo "</td>\n";
1118
7056988c 1119 // After left column we have (surprise!) right column with rackspace portlet only.
e673ee24 1120 echo "<td class=pcright>";
2c2ea5f6 1121 if (!in_array($info['objtype_id'], $virtual_obj_types))
0682218d
AD
1122 {
1123 // rackspace portlet
1124 startPortlet ('rackspace allocation');
1125 foreach (getResidentRacksData ($object_id, FALSE) as $rack_id)
1126 renderRack ($rack_id, $object_id);
1127 echo '<br>';
1128 finishPortlet();
1129 }
e673ee24
DO
1130 echo "</td></tr>";
1131 echo "</table>\n";
1132}
1133
1134function renderRackMultiSelect ($sname, $racks, $selected)
1135{
04571888
DO
1136 // Transform the given flat list into a list of groups, each representing a rack row.
1137 $rdata = array();
e673ee24 1138 foreach ($racks as $rack)
04571888
DO
1139 if (!isset ($rdata[$rack['row_name']]))
1140 $rdata[$rack['row_name']] = array ($rack['id'] => $rack['name']);
1141 else
1142 $rdata[$rack['row_name']][$rack['id']] = $rack['name'];
4fbb5a00 1143 echo "<select name=${sname} multiple size=" . getConfigVar ('MAXSELSIZE') . " onchange='getElementsByName(\"updateObjectAllocation\")[0].submit()'>\n";
04571888 1144 foreach ($rdata as $optgroup => $racklist)
e673ee24 1145 {
04571888
DO
1146 echo "<optgroup label='${optgroup}'>";
1147 foreach ($racklist as $rack_id => $rack_name)
1148 {
1149 echo "<option value=${rack_id}";
1150 if (!(array_search ($rack_id, $selected) === FALSE))
1151 echo ' selected';
1152 echo">${rack_name}</option>\n";
1153 }
e673ee24
DO
1154 }
1155 echo "</select>\n";
1156}
1157
e673ee24 1158// This function renders a form for port edition.
7e1db771 1159function renderPortsForObject ($object_id)
e673ee24 1160{
3153a326
DO
1161 $prefs = getPortListPrefs();
1162 function printNewItemTR ($prefs)
39b4abd0
DO
1163 {
1164 printOpFormIntro ('addPort');
1165 echo "<tr><td>";
f5ff50f5 1166 printImageHREF ('add', 'add a port', TRUE);
65e557dd 1167 echo "</td><td class='tdleft'><input type=text size=8 name=port_name tabindex=100></td>\n";
cd3775e9
DO
1168 echo "<td><input type=text name=port_label tabindex=101></td><td>";
1169 printNiftySelect (getNewPortTypeOptions(), array ('name' => 'port_type_id', 'tabindex' => 102), $prefs['selected']);
1170 echo "<td><input type=text name=port_l2address tabindex=103 size=18 maxlength=24></td>\n";
9318d2ef
DO
1171 echo "<td colspan=3>&nbsp;</td><td>";
1172 printImageHREF ('add', 'add a port', TRUE, 104);
1173 echo "</td></tr></form>";
39b4abd0 1174 }
a1fc539a 1175 if (getConfigVar('ENABLE_MULTIPORT_FORM') == 'yes' || getConfigVar('ENABLE_BULKPORT_FORM') == 'yes' )
f44fdef9
DO
1176 startPortlet ('Ports and interfaces');
1177 else
1178 echo '<br>';
9f75e165
DO
1179 $object = spotEntity ('object', $object_id);
1180 amplifyCell ($object);
a1fc539a
RF
1181 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes' && getConfigVar('ENABLE_BULKPORT_FORM') == 'yes'){
1182 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
1183 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>";
1184 echo "<th class=tdleft>Count</th><th>&nbsp;</th></tr>\n";
1185 printOpFormIntro ('addBulkPorts');
1186 echo "<tr><td>";
1187 printImageHREF ('add', 'add ports', TRUE);
1188 echo "</td><td><input type=text size=8 name=port_name tabindex=105></td>\n";
1189 echo "<td><input type=text name=port_label tabindex=106></td><td>";
1190 printNiftySelect (getNewPortTypeOptions(), array ('name' => 'port_type_id', 'tabindex' => 107), $prefs['selected']);
1191 echo "<td><input type=text name=port_numbering_start tabindex=108 size=3 maxlength=3></td>\n";
1192 echo "<td><input type=text name=port_numbering_count tabindex=109 size=3 maxlength=3></td>\n";
1193 echo "<td>&nbsp;</td><td>";
1194 printImageHREF ('add', 'add ports', TRUE, 110);
1195 echo "</td></tr></form>";
1196 echo "</table><br>\n";
1197 }
1198
e673ee24 1199 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
0d59a51c 1200 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>";
0c7c9f8b 1201 echo "<th class=tdcenter colspan=2>Cable, Remote object and port</th><th class=tdcenter>(Un)link or (un)reserve</th><th>&nbsp;</th></tr>\n";
39b4abd0 1202 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
3153a326 1203 printNewItemTR ($prefs);
45ff9012
AA
1204
1205 // clear ports link
1206 echo "<a href='".
1207 makeHrefProcess(array ('op'=>'deleteAll', 'page' => 'object', 'tab' => 'ports', 'object_id' => $object_id)).
1208 "' onclick=\"javascript:return confirm('Are you sure you want to delete all existing ports?')\">" . getImageHREF ('clear', 'Clear port list') . " Clear port list</a>";
1209
00276508
AA
1210 if (isset ($_REQUEST['hl_port_id']))
1211 {
1212 assertUIntArg ('hl_port_id');
1213 $hl_port_id = intval ($_REQUEST['hl_port_id']);
65e557dd 1214 addAutoScrollScript ("port-$hl_port_id");
00276508 1215 }
65e557dd 1216 switchportInfoJS ($object_id); // load JS code to make portnames interactive
9f75e165 1217 foreach ($object['ports'] as $port)
e673ee24 1218 {
00276508 1219 $tr_class = isset ($hl_port_id) && $hl_port_id == $port['id'] ? 'class="port_highlight"' : '';
7056988c 1220 printOpFormIntro ('editPort', array ('port_id' => $port['id']));
10005279 1221 echo "<tr $tr_class><td><a name='port-${port['id']}' href='".makeHrefProcess(array('op'=>'delPort', 'port_id'=>$port['id'], 'object_id'=>$object_id))."'>";
e673ee24
DO
1222 printImageHREF ('delete', 'Unlink and Delete this port');
1223 echo "</a></td>\n";
65e557dd
AA
1224 $a_class = isEthernetPort ($port) ? 'port-menu' : '';
1225 echo "<td class='tdleft' NOWRAP><input type=text name=name class='interactive-portname $a_class' value='${port['name']}' size=8></td>";
cd3775e9 1226 echo "<td><input type=text name=label value='${port['label']}'></td>";
611170af
AD
1227 if (!$port['remote_object_id'])
1228 {
3153a326
DO
1229 echo '<td>';
1230 if ($port['iif_id'] != 1)
1231 echo '<label>' . $port['iif_name'] . ' ';
cd3775e9 1232 printSelect (getExistingPortTypeOptions ($port['id']), array ('name' => 'port_type_id'), $port['oif_id']);
3153a326
DO
1233 if ($port['iif_id'] != 1)
1234 echo '</label>';
1235 echo '</td>';
611170af
AD
1236 }
1237 else
1238 {
045bab87 1239 echo "<input type=hidden name=port_type_id value='${port['oif_id']}'><td class=tdleft>";
e9d357e1 1240 echo formatPortIIFOIF ($port) . '</td>';
611170af 1241 }
cd3775e9
DO
1242 // 18 is enough to fit 6-byte MAC address in its longest form,
1243 // while 24 should be Ok for WWN
1244 echo "<td><input type=text name=l2address value='${port['l2address']}' size=18 maxlength=24></td>\n";
e673ee24
DO
1245 if ($port['remote_object_id'])
1246 {
5c6225b1 1247 echo "<td>${port['cableid']} " .
a2ea559e 1248 formatLoggedSpan ($port['last_log'], formatPortLink ($port['remote_object_id'], $port['remote_object_name'], $port['remote_id'], NULL)) .
5c6225b1
AA
1249 "</td>";
1250 echo "<td> " . formatLoggedSpan ($port['last_log'], $port['remote_name'], 'underline') .
1251 "<input type=hidden name=reservation_comment value=''></td>";
3153a326 1252 echo "<td class=tdcenter><a href='".
4fbb5a00
DY
1253 makeHrefProcess(array(
1254 'op'=>'unlinkPort',
cd3775e9 1255 'port_id'=>$port['id'],
cd3775e9 1256 'object_id'=>$object_id)).
4fbb5a00 1257 "'>";
5ccd99a0 1258 printImageHREF ('cut', 'Unlink this port');
e673ee24
DO
1259 echo "</a></td>";
1260 }
59a83bd8 1261 elseif (strlen ($port['reservation_comment']))
e673ee24 1262 {
5c6225b1 1263 echo "<td>" . formatLoggedSpan ($port['last_log'], 'Reserved:', 'strong underline') . "</td>";
e673ee24 1264 echo "<td><input type=text name=reservation_comment value='${port['reservation_comment']}'></td>";
3153a326 1265 echo "<td class=tdcenter><a href='".
4fbb5a00
DY
1266 makeHrefProcess(array(
1267 'op'=>'useup',
1268 'port_id'=>$port['id'],
1269 'object_id'=>$object_id)).
1270 "'>";
39be655e 1271 printImageHREF ('clear', 'Use up this port');
e673ee24
DO
1272 echo "</a></td>";
1273 }
1274 else
1275 {
cd3775e9
DO
1276 //echo "<td>&nbsp;</td><td>&nbsp;</td><td class=tdcenter><a href='javascript:;'";
1277 echo "<td>&nbsp;</td><td>&nbsp;</td><td class=tdcenter><span";
1278 $helper_args = array
1279 (
1280 'port' => $port['id'],
cd3775e9
DO
1281 );
1282 $popup_args = 'height=700, width=400, location=no, menubar=no, '.
9e214652 1283 'resizable=yes, scrollbars=yes, status=no, titlebar=no, toolbar=no';
cd3775e9
DO
1284 echo " ondblclick='window.open(\"" . makeHrefForHelper ('portlist', $helper_args);
1285 echo "\",\"findlink\",\"${popup_args}\");'";
1286 // end of onclick=
cd3775e9
DO
1287 echo " onclick='window.open(\"" . makeHrefForHelper ('portlist', $helper_args);
1288 echo "\",\"findlink\",\"${popup_args}\");'";
1289 // end of onclick=
1290 echo '>';
1291 // end of <a>
5ccd99a0 1292 printImageHREF ('plug', 'Link this port');
cd3775e9
DO
1293 echo "</span>";
1294 echo " <input type=text name=reservation_comment></td>\n";
e673ee24 1295 }
5bbbeaa2
DO
1296 echo "<td>";
1297 printImageHREF ('save', 'Save changes', TRUE);
1298 echo "</td></form></tr>\n";
e673ee24 1299 }
39b4abd0 1300 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
3153a326 1301 printNewItemTR ($prefs);
e673ee24 1302 echo "</table><br>\n";
a1fc539a
RF
1303 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes' && getConfigVar('ENABLE_BULKPORT_FORM') == 'yes'){
1304 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
1305 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>";
1306 echo "<th class=tdleft>Count</th><th>&nbsp;</th></tr>\n";
1307 printOpFormIntro ('addBulkPorts');
1308 echo "<tr><td>";
1309 printImageHREF ('add', 'add ports', TRUE);
1310 echo "</td><td><input type=text size=8 name=port_name tabindex=105></td>\n";
1311 echo "<td><input type=text name=port_label tabindex=106></td><td>";
1312 printNiftySelect (getNewPortTypeOptions(), array ('name' => 'port_type_id', 'tabindex' => 107), $prefs['selected']);
1313 echo "<td><input type=text name=port_numbering_start tabindex=108 size=3 maxlength=3></td>\n";
1314 echo "<td><input type=text name=port_numbering_count tabindex=109 size=3 maxlength=3></td>\n";
1315 echo "<td>&nbsp;</td><td>";
1316 printImageHREF ('add', 'add ports', TRUE, 110);
1317 echo "</td></tr></form>";
1318 echo "</table><br>\n";
1319 }
f44fdef9
DO
1320 if (getConfigVar('ENABLE_MULTIPORT_FORM') == 'yes')
1321 finishPortlet();
1322 if (getConfigVar('ENABLE_MULTIPORT_FORM') != 'yes')
1323 return;
e673ee24
DO
1324
1325 startPortlet ('Add/update multiple ports');
7056988c 1326 printOpFormIntro ('addMultiPorts');
f7a3c94a 1327 echo 'Format: <select name=format tabindex=201>';
e673ee24
DO
1328 echo '<option value=c3600asy>Cisco 3600 async: sh line | inc TTY</option>';
1329 echo '<option value=fiwg selected>Foundry ServerIron/FastIron WorkGroup/Edge: sh int br</option>';
e673ee24 1330 echo '<option value=fisxii>Foundry FastIron SuperX/II4000: sh int br</option>';
351d4dbf 1331 echo '<option value=ssv1>SSV:&lt;interface name&gt; &lt;MAC address&gt;</option>';
e673ee24
DO
1332 echo "</select>";
1333 echo 'Default port type: ';
cd3775e9 1334 printNiftySelect (getNewPortTypeOptions(), array ('name' => 'port_type', 'tabindex' => 202), $prefs['selected']);
f7a3c94a
DO
1335 echo "<input type=submit value='Parse output' tabindex=204><br>\n";
1336 echo "<textarea name=input cols=100 rows=50 tabindex=203></textarea><br>\n";
e673ee24
DO
1337 echo '</form>';
1338 finishPortlet();
1339}
1340
f3505b35 1341function renderIPTabForObject ($object_id, $ip_v)
e673ee24 1342{
f3505b35 1343 function getOpnameByIPFamily ($opname, $ip_v)
e673ee24 1344 {
f3505b35
AA
1345 // do not assemble opnames from the peaces to be able to grep the code by opnames
1346 switch ($opname . '-'. $ip_v)
d7a8186d 1347 {
f3505b35
AA
1348 case 'add-4': return 'addIPv4Allocation';
1349 case 'add-6': return 'addIPv6Allocation';
1350 case 'upd-4': return 'updIPv4Allocation';
1351 case 'upd-6': return 'updIPv6Allocation';
1352 case 'del-4': return 'delIPv4Allocation';
1353 case 'del-6': return 'delIPv6Allocation';
1354 default: throw new InvalidArgException ('$opname or $ip_v', "$opname or $ip_v");
d7a8186d 1355 }
e673ee24 1356 }
710ead7e 1357 function printNewItemTR ($ip_v, $default_type)
21ee3351
AA
1358 {
1359 global $aat;
f3505b35 1360 printOpFormIntro (getOpnameByIPFamily ('add', $ip_v));
21ee3351
AA
1361 echo "<tr><td>";
1362 printImageHREF ('add', 'allocate', TRUE);
1363 echo "</td>";
1364 echo "<td class=tdleft><input type='text' size='10' name='bond_name' tabindex=100></td>\n";
1365 echo "<td class=tdleft><input type=text name='ip' tabindex=101></td>\n";
1366 echo "<td colspan=2>&nbsp;</td><td>";
710ead7e 1367 printSelect ($aat, array ('name' => 'bond_type', 'tabindex' => 102), $default_type);
21ee3351
AA
1368 echo "</td><td>&nbsp;</td><td>";
1369 printImageHREF ('add', 'allocate', TRUE, 103);
1370 echo "</td></tr></form>";
1371 }
1372 $focus = spotEntity ('object', $object_id);
1373 amplifyCell ($focus);
1374 global $aat;
1375 startPortlet ('Allocations');
1376 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
1377 echo '<tr><th>&nbsp;</th><th>OS interface</th><th>IP address</th>';
1378 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
1379 echo '<th>network</th><th>routed by</th>';
1380 echo '<th>type</th><th>misc</th><th>&nbsp</th></tr>';
1381
710ead7e
AA
1382 $alloc_list = ''; // most of the output is stored here
1383 $used_alloc_types = array();
f3505b35 1384 foreach ($focus['ipv' . $ip_v] as $alloc) // ['ipv4'] or ['ipv6']
21ee3351 1385 {
710ead7e
AA
1386 if (! isset ($used_alloc_types[$alloc['type']]))
1387 $used_alloc_types[$alloc['type']] = 0;
1388 $used_alloc_types[$alloc['type']]++;
1389
f3505b35 1390 $rendered_alloc = getRenderedAlloc ($object_id, $alloc);
710ead7e
AA
1391 $alloc_list .= getOutputOf ('printOpFormIntro', getOpnameByIPFamily ('upd', $ip_v), array ('ip' => $alloc['addrinfo']['ip']));
1392 $alloc_list .= "<tr class='${rendered_alloc['tr_class']}' valign=top>";
f3505b35 1393
710ead7e 1394 $alloc_list .= "<td><a href='" .
f3505b35
AA
1395 makeHrefProcess
1396 (
1397 array
1398 (
1399 'op' => getOpnameByIPFamily ('del', $ip_v),
1400 'ip' => $alloc['addrinfo']['ip'],
1401 'object_id' => $object_id
1402 )
1403 ) . "'>" .
1404 getImageHREF ('delete', 'Delete this IP address') .
1405 "</a></td>";
710ead7e
AA
1406 $alloc_list .= "<td class=tdleft><input type='text' name='bond_name' value='${alloc['osif']}' size=10></td>";
1407 $alloc_list .= $rendered_alloc['td_ip'];
21ee3351
AA
1408 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
1409 {
710ead7e
AA
1410 $alloc_list .= $rendered_alloc['td_network'];
1411 $alloc_list .= $rendered_alloc['td_routed_by'];
21ee3351 1412 }
710ead7e
AA
1413 $alloc_list .= '<td>' . getSelect ($aat, array ('name' => 'bond_type'), $alloc['type']) . "</td>";
1414 $alloc_list .= $rendered_alloc['td_peers'];
1415 $alloc_list .= "<td>" .getImageHREF ('save', 'Save changes', TRUE) . "</td>";
f3505b35 1416
710ead7e 1417 $alloc_list .= "</form></tr>\n";
21ee3351 1418 }
710ead7e
AA
1419 asort ($used_alloc_types, SORT_NUMERIC);
1420 $most_popular_type = empty ($used_alloc_types) ? 'regular' : array_pop (array_keys ($used_alloc_types));
1421
1422 if ($list_on_top = (getConfigVar ('ADDNEW_AT_TOP') != 'yes'))
1423 echo $alloc_list;
1424 printNewItemTR ($ip_v, $most_popular_type);
1425 if (! $list_on_top)
1426 echo $alloc_list;
21ee3351
AA
1427
1428 echo "</table><br>\n";
1429 finishPortlet();
f3505b35
AA
1430}
1431
1432function renderIPv4ForObject ($object_id)
1433{
1434 renderIPTabForObject ($object_id, '4');
1435}
21ee3351 1436
f3505b35
AA
1437function renderIPv6ForObject ($object_id)
1438{
1439 renderIPTabForObject ($object_id, '6');
21ee3351
AA
1440}
1441
08408472
AA
1442// This function is deprecated. Do not rely on its internals,
1443// it will probably be removed in the next major relese.
1444// Use new showError, showWarning, showSuccess functions.
a2b16202 1445// Log array is stored in global $log_messages. Its format is simple: plain ordered array
8ab645cf 1446// with values having keys 'c' (both message code and severity) and 'a' (sprintf arguments array)
1cb6adf5 1447function showMessageOrError ()
e673ee24 1448{
a2b16202
AA
1449 global $log_messages;
1450
1451 @session_start();
1452 if (isset ($_SESSION['log']))
1453 {
1454 $log_messages = array_merge ($_SESSION['log'], $log_messages);
1455 unset ($_SESSION['log']);
1456 }
1457 session_commit();
1458
1459 if (empty ($log_messages))
1cb6adf5 1460 return;
8ab645cf
AA
1461 $msginfo = array
1462 (
1463// records 0~99 with success messages
1464 0 => array ('code' => 'success', 'format' => '%s'),
1465 5 => array ('code' => 'success', 'format' => 'added record "%s" successfully'),
1466 6 => array ('code' => 'success', 'format' => 'updated record "%s" successfully'),
1467 7 => array ('code' => 'success', 'format' => 'deleted record "%s" successfully'),
1468 8 => array ('code' => 'success', 'format' => 'Port %s successfully linked with %s'),
1469 10 => array ('code' => 'success', 'format' => 'Added %u ports, updated %u ports, encountered %u errors.'),
1470 21 => array ('code' => 'success', 'format' => 'Generation complete'),
1471 26 => array ('code' => 'success', 'format' => 'updated %u records successfully'),
1472 37 => array ('code' => 'success', 'format' => 'added %u records successfully'),
1473 38 => array ('code' => 'success', 'format' => 'removed %u records successfully'),
8ab645cf
AA
1474 43 => array ('code' => 'success', 'format' => 'Saved successfully.'),
1475 44 => array ('code' => 'success', 'format' => '%s failures and %s successfull changes.'),
1476 48 => array ('code' => 'success', 'format' => 'added a record successfully'),
1477 49 => array ('code' => 'success', 'format' => 'deleted a record successfully'),
1478 51 => array ('code' => 'success', 'format' => 'updated a record successfully'),
1479 57 => array ('code' => 'success', 'format' => 'Reset complete'),
8ab645cf 1480 63 => array ('code' => 'success', 'format' => '%u change request(s) have been processed'),
8ab645cf
AA
1481 67 => array ('code' => 'success', 'format' => "Tag rolling done, %u objects involved"),
1482 71 => array ('code' => 'success', 'format' => 'File "%s" was linked successfully'),
1483 72 => array ('code' => 'success', 'format' => 'File was unlinked successfully'),
8ab645cf
AA
1484 82 => array ('code' => 'success', 'format' => "Bulk port creation was successful. %u ports created, %u failed"),
1485 87 => array ('code' => 'success', 'format' => '802.1Q recalculate: %d ports changed on %d switches'),
8628ae44 1486// records 100~199 with fatal error messages
8ab645cf
AA
1487 100 => array ('code' => 'error', 'format' => '%s'),
1488 109 => array ('code' => 'error', 'format' => 'failed updating a record'),
8ab645cf
AA
1489 131 => array ('code' => 'error', 'format' => 'invalid format requested'),
1490 141 => array ('code' => 'error', 'format' => 'Encountered %u errors, updated %u record(s)'),
1491 149 => array ('code' => 'error', 'format' => 'Turing test failed'),
1492 150 => array ('code' => 'error', 'format' => 'Can only change password under DB authentication.'),
1493 151 => array ('code' => 'error', 'format' => 'Old password doesn\'t match.'),
1494 152 => array ('code' => 'error', 'format' => 'New passwords don\'t match.'),
1495 154 => array ('code' => 'error', 'format' => "Verification error: %s"),
1496 155 => array ('code' => 'error', 'format' => 'Save failed.'),
1497 159 => array ('code' => 'error', 'format' => 'Permission denied moving port %s from VLAN%u to VLAN%u'),
1498 161 => array ('code' => 'error', 'format' => 'Endpoint not found. Please either set FQDN attribute or assign an IP address to the object.'),
1499 162 => array ('code' => 'error', 'format' => 'More than one IP address is assigned to this object, please configure FQDN attribute.'),
8ab645cf
AA
1500 170 => array ('code' => 'error', 'format' => 'There is no network for IP address "%s"'),
1501 172 => array ('code' => 'error', 'format' => 'Malformed request'),
1502 179 => array ('code' => 'error', 'format' => 'Expired form has been declined.'),
1503 188 => array ('code' => 'error', 'format' => "Fatal SNMP failure"),
1504 189 => array ('code' => 'error', 'format' => "Unknown OID '%s'"),
1505 191 => array ('code' => 'error', 'format' => "deploy was blocked due to conflicting configuration versions"),
f0ff4930 1506
8628ae44 1507// records 200~299 with warnings
8ab645cf
AA
1508 200 => array ('code' => 'warning', 'format' => '%s'),
1509 201 => array ('code' => 'warning', 'format' => 'nothing happened...'),
8ab645cf 1510 206 => array ('code' => 'warning', 'format' => 'Rack is not empty'),
57777e4a 1511
24d3182a 1512// records 300~399 with notices
8ab645cf 1513 300 => array ('code' => 'neutral', 'format' => '%s'),
24d3182a 1514
8ab645cf
AA
1515 );
1516 // Handle the arguments. Is there any better way to do it?
a2b16202 1517 foreach ($log_messages as $record)
8ab645cf
AA
1518 {
1519 if (!isset ($record['c']) or !isset ($msginfo[$record['c']]))
1520 {
41152018
AA
1521 $prefix = isset ($record['c']) ? $record['c'] . ': ' : '';
1522 echo "<div class=msg_neutral>(${prefix}this message was lost)</div>";
8ab645cf
AA
1523 continue;
1524 }
1525 if (isset ($record['a']))
1526 switch (count ($record['a']))
baf37d01 1527 {
8ab645cf
AA
1528 case 1:
1529 $msgtext = sprintf
1530 (
1531 $msginfo[$record['c']]['format'],
1532 $record['a'][0]
1533 );
1534 break;
1535 case 2:
1536 $msgtext = sprintf
1537 (
1538 $msginfo[$record['c']]['format'],
1539 $record['a'][0],
1540 $record['a'][1]
1541 );
1542 break;
1543 case 3:
1544 $msgtext = sprintf
1545 (
1546 $msginfo[$record['c']]['format'],
1547 $record['a'][0],
1548 $record['a'][1],
1549 $record['a'][2]
1550 );
1551 break;
1552 case 4:
1553 default:
1554 $msgtext = sprintf
1555 (
1556 $msginfo[$record['c']]['format'],
1557 $record['a'][0],
1558 $record['a'][1],
1559 $record['a'][2],
1560 $record['a'][3]
1561 );
1562 break;
baf37d01 1563 }
8ab645cf
AA
1564 else
1565 $msgtext = $msginfo[$record['c']]['format'];
1566 echo '<div class=msg_' . $msginfo[$record['c']]['code'] . ">${msgtext}</div>";
baf37d01 1567 }
a2b16202 1568 $log_messages = array();
e673ee24
DO
1569}
1570
65e557dd
AA
1571// renders two tables: port link status and learned MAC list
1572function renderPortsInfo($object_id)
1573{
1574 global $nextorder;
1575 echo "<table width='100%'><tr>";
1576
1577 if (permitted (NULL, NULL, 'get_link_status'))
1578 {
1579 try
1580 {
80019a2c 1581 $linkStatus = queryDevice ($object_id, 'getportstatus');
65e557dd
AA
1582 }
1583 catch (RackTablesError $e) {}
1584 if (! empty ($linkStatus))
1585 {
1586 echo "<td valign='top' width='50%'>";
1587 startPortlet('Link status');
1588 echo "<table width='80%' class='widetable' cellspacing=0 cellpadding='5px' align='center'><tr><th>Port<th>Link status<th>Link info</tr>";
1589 $order = 'even';
1590 foreach ($linkStatus as $pn => $link)
1591 {
1592 echo "<tr class='row_$order'>";
1593 $order = $nextorder[$order];
1594 echo '<td>' . $pn;
1595 echo '<td>' . $link['status'];
1596 $info = '';
1597 if (isset ($link['speed']))
1598 $info .= $link['speed'];
1599 if (isset ($link['duplex']))
1600 {
1601 if (! empty ($info))
1602 $info .= ', ';
1603 $info .= $link['duplex'];
1604 }
1605 echo '<td>' . $info;
1606 echo '</tr>';
1607 }
1608 echo "</table></td>";
1609 finishPortlet();
1610 }
1611 }
1612
1613 try
1614 {
80019a2c 1615 $macList = sortPortList (queryDevice ($object_id, 'getmaclist'));
65e557dd
AA
1616 }
1617 catch (RackTablesError $e) {}
1618 if (! empty ($macList))
1619 {
1620 echo "<td valign='top' width='50%'>";
1621 $rendered_macs = '';
1622 $mac_count = 0;
1623 $rendered_macs .= "<table width='80%' class='widetable' cellspacing=0 cellpadding='5px' align='center'><tr><th>MAC<th>Vlan<th>Port</tr>";
1624 $order = 'even';
1625 foreach ($macList as $pn => $list)
1626 {
1627 $order = $nextorder[$order];
1628 foreach ($list as $item)
1629 {
1630 ++$mac_count;
1631 $rendered_macs .= "<tr class='row_$order'>";
1632 $rendered_macs .= '<td style="font-family: monospace">' . $item['mac'];
1633 $rendered_macs .= '<td>' . $item['vid'];
1634 $rendered_macs .= '<td>' . $pn;
1635 $rendered_macs .= '</tr>';
1636 }
1637 }
1638 $rendered_macs .= "</table></td>";
1639
1640 startPortlet("Learned MACs ($mac_count)");
1641 echo $rendered_macs;
1642 finishPortlet();
1643 }
1644
1645 echo "</td></tr></table>";
1646}
1647
e673ee24 1648/*
51c18782 1649The following conditions must be met:
e673ee24
DO
16501. We can mount onto free atoms only. This means: if any record for an atom
1651already exists in RackSpace, it can't be used for mounting.
16522. We can't unmount from 'W' atoms. Operator should review appropriate comments
1653and either delete them before unmounting or refuse to unmount the object.
1654*/
7e1db771 1655function renderRackSpaceForObject ($object_id)
e673ee24 1656{
e673ee24
DO
1657 // Always process occupied racks plus racks chosen by user. First get racks with
1658 // already allocated rackspace...
51c18782 1659 $workingRacksData = getResidentRacksData ($object_id);
e673ee24 1660 // ...and then add those chosen by user (if any).
2135fd83 1661 if (isset($_REQUEST['rackmulti']))
e673ee24 1662 foreach ($_REQUEST['rackmulti'] as $cand_id)
e673ee24
DO
1663 if (!isset ($workingRacksData[$cand_id]))
1664 {
0cc24e9a 1665 $rackData = spotEntity ('rack', $cand_id);
61a1d996 1666 amplifyCell ($rackData);
e673ee24
DO
1667 $workingRacksData[$cand_id] = $rackData;
1668 }
51690ad4 1669
0a7feebb
AD
1670 // Get a list of all of this object's parents,
1671 // then trim the list to only include parents which are racks
1672 $objectParents = getEntityRelatives('parents', 'object', $object_id);
1673 $parentRacks = array();
1674 foreach ($objectParents as $parentData)
1675 if ($parentData['entity_type'] == 'rack')
1676 $parentRacks[] = $parentData['entity_id'];
1677
e673ee24
DO
1678 // Main layout starts.
1679 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0><tr>";
1680
1681 // Left portlet with rack list.
1682 echo "<td class=pcleft height='1%'>";
1683 startPortlet ('Racks');
a8efc03e 1684 $allRacksData = listCells ('rack');
6d42599c
AA
1685
1686 // filter rack list to match only racks having common tags with the object (reducing $allRacksData)
1687 if (! isset ($_REQUEST['show_all_racks']) and getConfigVar ('FILTER_RACKLIST_BY_TAGS') == 'yes')
1688 {
1689 $matching_racks = array();
1690 $object = spotEntity ('object', $object_id);
1691 $matched_tags = array();
1692 foreach ($allRacksData as $rack)
1693 foreach ($object['etags'] as $tag)
1694 if (tagOnChain ($tag, $rack['etags']) or tagOnChain ($tag, $rack['itags']))
1695 {
1696 $matching_racks[$rack['id']] = $rack;
1697 $matched_tags[$tag['id']] = $tag;
1698 break;
1699 }
1700 // add current object's racks even if they dont match filter
1701 foreach ($workingRacksData as $rack_id => $rack)
1702 if (! isset ($matching_racks[$rack_id]))
1703 $matching_racks[$rack_id] = $rack;
1704 // if matching racks found, and rack list is reduced, show 'show all' link
1705 if (count ($matching_racks) and count ($matching_racks) != count ($allRacksData))
1706 {
1707 $filter_text = '';
1708 foreach ($matched_tags as $tag)
1709 $filter_text .= (empty ($filter_text) ? '' : ' or ') . '{' . $tag['tag'] . '}';
1710 $href_show_all = trim($_SERVER['REQUEST_URI'], '&');
1711 $href_show_all .= htmlspecialchars('&show_all_racks=1');
1712 echo "(filtered by <span class='filter-text'>$filter_text</span>, <a href='$href_show_all'>show all</a>)<p>";
1713 $allRacksData = $matching_racks;
1714 }
1715 }
1716
4b8d413e 1717 if (count ($allRacksData) <= getConfigVar ('RACK_PRESELECT_THRESHOLD'))
61a1d996 1718 foreach ($allRacksData as $rack)
51c18782
DO
1719 if (!array_key_exists ($rack['id'], $workingRacksData))
1720 {
1721 amplifyCell ($rack);
1722 $workingRacksData[$rack['id']] = $rack;
1723 }
1724 foreach (array_keys ($workingRacksData) as $rackId)
1725 applyObjectMountMask ($workingRacksData[$rackId], $object_id);
1726 printOpFormIntro ('updateObjectAllocation');
4b8d413e 1727 renderRackMultiSelect ('rackmulti[]', $allRacksData, array_keys ($workingRacksData));
51c18782 1728 echo "<br><br>";
e673ee24
DO
1729 finishPortlet();
1730 echo "</td>";
1731
1732 // Middle portlet with comment and submit.
1733 echo "<td class=pcleft>";
1734 startPortlet ('Comment');
1735 echo "<textarea name=comment rows=10 cols=40></textarea><br>\n";
1736 echo "<input type=submit value='Save' name=got_atoms>\n";
51c18782 1737 echo "<br><br>";
e673ee24
DO
1738 finishPortlet();
1739 echo "</td>";
1740
1741 // Right portlet with rendered racks. If this form submit is not final, we have to
1742 // reflect the former state of the grid in current form.
1743 echo "<td class=pcright rowspan=2 height='1%'>";
1744 startPortlet ('Working copy');
65e557dd 1745 addJS ('js/racktables.js');
e673ee24
DO
1746 echo '<table border=0 cellspacing=10 align=center><tr>';
1747 foreach ($workingRacksData as $rack_id => $rackData)
1748 {
1749 // Order is important here: only original allocation is highlighted.
1750 highlightObject ($rackData, $object_id);
1751 markupAtomGrid ($rackData, 'T');
1752 // If we have a form processed, discard user input and show new database
1753 // contents.
51c18782 1754 if (isset ($_REQUEST['rackmulti'][0])) // is an update
e673ee24
DO
1755 mergeGridFormToRack ($rackData);
1756 echo "<td valign=top>";
1757 echo "<center>\n<h2>${rackData['name']}</h2>\n";
1758 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
57c69e9c 1759 echo "<tr><th width='10%'>&nbsp;</th>";
64259015
DO
1760 echo "<th width='20%'><a href='javascript:;' oncontextmenu=\"blockToggleColumnOfAtoms('${rack_id}', '0', ${rackData['height']}); return false;\" onclick=\"toggleColumnOfAtoms('${rack_id}', '0', ${rackData['height']})\">Front</a></th>";
1761 echo "<th width='50%'><a href='javascript:;' oncontextmenu=\"blockToggleColumnOfAtoms('${rack_id}', '1', ${rackData['height']}); return false;\" onclick=\"toggleColumnOfAtoms('${rack_id}', '1', ${rackData['height']})\">Interior</a></th>";
1762 echo "<th width='20%'><a href='javascript:;' oncontextmenu=\"blockToggleColumnOfAtoms('${rack_id}', '2', ${rackData['height']}); return false;\" onclick=\"toggleColumnOfAtoms('${rack_id}', '2', ${rackData['height']})\">Back</a></th></tr>\n";
e673ee24 1763 renderAtomGrid ($rackData);
57c69e9c 1764 echo "<tr><th width='10%'>&nbsp;</th>";
64259015
DO
1765 echo "<th width='20%'><a href='javascript:;' oncontextmenu=\"blockToggleColumnOfAtoms('${rack_id}', '0', ${rackData['height']}); return false;\" onclick=\"toggleColumnOfAtoms('${rack_id}', '0', ${rackData['height']})\">Front</a></th>";
1766 echo "<th width='50%'><a href='javascript:;' oncontextmenu=\"blockToggleColumnOfAtoms('${rack_id}', '1', ${rackData['height']}); return false;\" onclick=\"toggleColumnOfAtoms('${rack_id}', '1', ${rackData['height']})\">Interior</a></th>";
1767 echo "<th width='20%'><a href='javascript:;' oncontextmenu=\"blockToggleColumnOfAtoms('${rack_id}', '2', ${rackData['height']}); return false;\" onclick=\"toggleColumnOfAtoms('${rack_id}', '2', ${rackData['height']})\">Back</a></th></tr>\n";
0a7feebb
AD
1768 echo "</table>\n<br>\n";
1769 // Determine zero-u checkbox status.
1770 // If form has been submitted, use form data, otherwise use DB data.
1771 if (isset($_REQUEST['op']))
1772 $checked = isset($_REQUEST['zerou_'.$rack_id]) ? 'checked' : '';
1773 else
1774 $checked = in_array($rack_id, $parentRacks) ? 'checked' : '';
1775 echo "Zero-U: <input type=checkbox ${checked} name=zerou_${rack_id} id=zerou_${rack_id}>";
1776 echo '</center></td>';
e673ee24
DO
1777 }
1778 echo "</tr></table>";
1779 finishPortlet();
1780 echo "</td>\n";
1781
1782 echo "</form>\n";
1783 echo "</tr></table>\n";
1784}
1785
1786function renderMolecule ($mdata, $object_id)
1787{
1788 // sort data out
1789 $rackpack = array();
1790 global $loclist;
64b95774 1791 foreach ($mdata as $rua)
e673ee24
DO
1792 {
1793 $rack_id = $rua['rack_id'];
1794 $unit_no = $rua['unit_no'];
1795 $atom = $rua['atom'];
1796 if (!isset ($rackpack[$rack_id]))
1797 {
61a1d996
DO
1798 $rackData = spotEntity ('rack', $rack_id);
1799 amplifyCell ($rackData);
e673ee24
DO
1800 for ($i = $rackData['height']; $i > 0; $i--)
1801 for ($locidx = 0; $locidx < 3; $locidx++)
1802 $rackData[$i][$locidx]['state'] = 'F';
1803 $rackpack[$rack_id] = $rackData;
1804 }
1805 $rackpack[$rack_id][$unit_no][$loclist[$atom]]['state'] = 'T';
1806 $rackpack[$rack_id][$unit_no][$loclist[$atom]]['object_id'] = $object_id;
1807 }
1808 // now we have some racks to render
65e557dd 1809 addAtomCSS();
64b95774 1810 foreach ($rackpack as $rackData)
e673ee24
DO
1811 {
1812 markAllSpans ($rackData);
1813 echo "<table class=molecule cellspacing=0>\n";
1814 echo "<caption>${rackData['name']}</caption>\n";
1815 echo "<tr><th width='10%'>&nbsp;</th><th width='20%'>Front</th><th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
1816 for ($i = $rackData['height']; $i > 0; $i--)
1817 {
1818 echo "<tr><th>$i</th>";
1819 for ($locidx = 0; $locidx < 3; $locidx++)
1820 {
1821 $state = $rackData[$i][$locidx]['state'];
65e557dd 1822 echo "<td class='atom state_${state}'>&nbsp;</td>\n";
e673ee24
DO
1823 }
1824 echo "</tr>\n";
1825 }
1826 echo "</table>\n";
1827 }
1828}
1829
23cdc7e9 1830function renderDepot ()
e673ee24 1831{
23cdc7e9 1832 global $pageno, $nextorder;
23cdc7e9
DO
1833 $cellfilter = getCellFilter();
1834 $objects = filterCellList (listCells ('object'), $cellfilter['expression']);
1835
1836 echo "<table border=0 class=objectview>\n";
1837 echo "<tr><td class=pcleft>";
1838
1ebbf889 1839 if (! renderEmptyResults ($cellfilter, 'objects', count($objects)))
e673ee24 1840 {
4899096d 1841 if (count($objects) > 0)
1ebbf889 1842 {
4899096d
AD
1843 startPortlet ('Objects (' . count ($objects) . ')');
1844 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
81659c05 1845 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>Row/Rack</th></tr>';
4899096d 1846 $order = 'odd';
3f8a25d6
DO
1847 # gather IDs of all objects and fetch rackspace info in one pass
1848 $idlist = array();
1849 foreach ($objects as $obj)
1850 $idlist[] = $obj['id'];
1851 $mountinfo = getMountInfo ($idlist);
4899096d
AD
1852 foreach ($objects as $obj)
1853 {
1854 if (isset ($_REQUEST['hl_object_id']) and $_REQUEST['hl_object_id'] == $obj['id'])
1855 $secondclass = 'tdleft port_highlight';
1856 else
1857 $secondclass = 'tdleft';
1858 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>";
1859 if (count ($obj['etags']))
1860 echo '<br><small>' . serializeTags ($obj['etags'], makeHref(array('page'=>$pageno, 'tab'=>'default')) . '&') . '</small>';
1861 echo "</td><td class='${secondclass}'>${obj['label']}</td>";
1862 echo "<td class='${secondclass}'>${obj['asset_no']}</td>";
3f8a25d6
DO
1863 $places = array();
1864 if (! array_key_exists ($obj['id'], $mountinfo))
1865 $places[] = 'Unmounted';
4899096d 1866 else
3f8a25d6
DO
1867 foreach ($mountinfo[$obj['id']] as $mi)
1868 $places[] = mkA ($mi['row_name'], 'row', $mi['row_id']) . '/' . mkA ($mi['rack_name'], 'rack', $mi['rack_id']);
1869 echo "<td class='${secondclass}'>" . implode (', ', $places) . '</td>';
4899096d
AD
1870 echo '</tr>';
1871 $order = $nextorder[$order];
1872 }
1873 echo '</table>';
1874 finishPortlet();
1ebbf889 1875 }
4899096d
AD
1876 else
1877 echo '<h2>No objects exist</h2>';
e673ee24 1878 }
23cdc7e9
DO
1879
1880 echo "</td><td class=pcright width='25%'>";
1881
95857b5c 1882 renderCellFilterPortlet ($cellfilter, 'object', $objects);
23cdc7e9 1883 echo "</td></tr></table>\n";
e673ee24
DO
1884}
1885
1ebbf889
AA
1886// This function returns TRUE if the result set is too big to be rendered, and no filter is set.
1887// In this case it renders the describing message instead.
1888function renderEmptyResults($cellfilter, $entities_name, $count = NULL)
1889{
1890 if (!$cellfilter['is_empty'])
1891 return FALSE;
1892 if (isset ($_REQUEST['show_all_objects']))
1893 return FALSE;
1894 $max = intval(getConfigVar('MAX_UNFILTERED_ENTITIES'));
1895 if (0 == $max || $count <= $max)
1896 return FALSE;
1897
1898 $href_show_all = trim($_SERVER['REQUEST_URI'], '&');
1899 $href_show_all .= htmlspecialchars('&show_all_objects=1');
1900 $suffix = isset ($count) ? " ($count)" : '';
1901 echo <<<END
1902<p>Please set a filter to display the corresponging $entities_name.
1903<br><a href="$href_show_all">Show all $entities_name$suffix</a>
1904END;
1905 return TRUE;
1906}
1907
e673ee24 1908// History viewer for history-enabled simple dictionaries.
9b8174d7 1909function renderObjectHistory ($object_id)
e673ee24 1910{
e673ee24
DO
1911 $order = 'odd';
1912 global $nextorder;
9b8174d7
AD
1913 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1914 echo '<tr><th>change time</th><th>author</th><th>name</th><th>visible label</th><th>asset no</th><th>has problems?</th><th>comment</th></tr>';
1915 $result = usePreparedSelectBlade
1916 (
1917 'SELECT ctime, user_name, name, label, asset_no, has_problems, comment FROM ObjectHistory WHERE id=? ORDER BY ctime',
1918 array ($object_id)
1919 );
e673ee24
DO
1920 while ($row = $result->fetch (PDO::FETCH_NUM))
1921 {
1922 echo "<tr class=row_${order}><td>${row[0]}</td>";
9b8174d7 1923 for ($i = 1; $i <= 6; $i++)
e673ee24
DO
1924 echo "<td>" . $row[$i] . "</td>";
1925 echo "</tr>\n";
1926 $order = $nextorder[$order];
1927 }
1928 echo "</table><br>\n";
1929}
1930
1931function renderRackspaceHistory ()
1932{
4fbb5a00 1933 global $nextorder, $pageno, $tabno;
e673ee24
DO
1934 $order = 'odd';
1935 $history = getRackspaceHistory();
1936 // Show the last operation by default.
1937 if (isset ($_REQUEST['op_id']))
1938 $op_id = $_REQUEST['op_id'];
1939 elseif (isset ($history[0]['mo_id']))
1940 $op_id = $history[0]['mo_id'];
1941 else $op_id = NULL;
1942
1943 $omid = NULL;
1944 $nmid = NULL;
1945 $object_id = 1;
1946 if ($op_id)
1947 list ($omid, $nmid) = getOperationMolecules ($op_id);
1948
1949 // Main layout starts.
1950 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
1951
1952 // Left top portlet with old allocation.
1953 echo "<tr><td class=pcleft>";
1954 startPortlet ('Old allocation');
1955 if ($omid)
1956 {
1957 $oldMolecule = getMolecule ($omid);
1958 renderMolecule ($oldMolecule, $object_id);
1959 }
1960 else
1961 echo "nothing";
1962 finishPortlet();
1963
1964 echo '</td><td class=pcright>';
1965
1966 // Right top portlet with new allocation
1967 startPortlet ('New allocation');
1968 if ($nmid)
1969 {
1970 $newMolecule = getMolecule ($nmid);
1971 renderMolecule ($newMolecule, $object_id);
1972 }
1973 else
1974 echo "nothing";
1975 finishPortlet();
737a3f72 1976
e673ee24 1977 echo '</td></tr><tr><td colspan=2>';
737a3f72 1978
e673ee24
DO
1979 // Bottom portlet with list
1980
1981 startPortlet ('Rackspace allocation history');
1982 echo "<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>\n";
7fa7047a 1983 echo "<tr><th>timestamp</th><th>author</th><th>object</th><th>comment</th></tr>\n";
e673ee24
DO
1984 foreach ($history as $row)
1985 {
1986 if ($row['mo_id'] == $op_id)
1987 $class = 'hl';
1988 else
1989 $class = "row_${order}";
4fbb5a00 1990 echo "<tr class=${class}><td><a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno, 'op_id'=>$row['mo_id']))."'>${row['ctime']}</a></td>";
7fa7047a
DO
1991 echo "<td>${row['user_name']}</td><td>";
1992 renderCell (spotEntity ('object', $row['ro_id']));
9c6222ef 1993 echo '</td><td>' . niftyString ($row['comment'], 0) . '</td></tr>';
e673ee24
DO
1994 $order = $nextorder[$order];
1995 }
1996 echo "</table>\n";
1997 finishPortlet();
737a3f72 1998
e673ee24 1999 echo '</td></tr></table>';
e673ee24
DO
2000}
2001
1f54e1ba 2002function renderIPv4SpaceRecords ($tree, $baseurl, $target = 0, $knight, $level = 1)
d65353ad
DO
2003{
2004 $self = __FUNCTION__;
ca4eb604
DO
2005 static $vdomlist = NULL;
2006 if ($vdomlist == NULL and getConfigVar ('IPV4_TREE_SHOW_VLAN') == 'yes')
e829e76b 2007 $vdomlist = getVLANDomainOptions();
00276508
AA
2008
2009 // scroll page to the highlighted item
2010 if ($target && isset ($_REQUEST['hl_net']))
65e557dd 2011 addAutoScrollScript ("net-$target");
00276508 2012
d65353ad
DO
2013 foreach ($tree as $item)
2014 {
64347dcf 2015 if (getConfigVar ('IPV4_TREE_SHOW_USAGE') == 'yes')
64347dcf 2016 loadIPv4AddrList ($item); // necessary to compute router list and address counter
64347dcf
DO
2017 else
2018 {
2019 $item['addrlist'] = array();
2020 $item['addrc'] = 0;
2021 }
b1e39212
DO
2022 $used = $item['addrc'];
2023 $maxdirect = $item['addrt'];
2024 $maxtotal = binInvMaskFromDec ($item['mask']) + 1;
0137d53c
DO
2025 if (isset ($item['id']))
2026 {
1f54e1ba 2027 $decor = array ('indent' => $level);
fec0c8da 2028 if ($item['symbol'] == 'node-collapsed')
00276508 2029 $decor['symbolurl'] = "${baseurl}&eid=" . $item['id'];
fec0c8da 2030 elseif ($item['symbol'] == 'node-expanded')
00276508 2031 $decor['symbolurl'] = $baseurl . ($item['parent_id'] ? "&eid=${item['parent_id']}" : '');
0137d53c 2032 echo "<tr valign=top>";
21ee3351 2033 if ($target == $item['id'] && isset ($_REQUEST['hl_net']))
ee8688c4 2034 $decor['tdclass'] = 'port_highlight';
21ee3351 2035 printIPNetInfoTDs ($item, $decor);
0137d53c 2036 echo "<td class=tdcenter>";
64347dcf
DO
2037 if (getConfigVar ('IPV4_TREE_SHOW_USAGE') == 'yes')
2038 {
b1e39212
DO
2039 renderProgressBar ($maxdirect ? $used/$maxdirect : 0);
2040 echo "<br><small>${used}/${maxdirect}" . ($maxdirect == $maxtotal ? '' : "/${maxtotal}") . '</small>';
64347dcf
DO
2041 }
2042 else
b1e39212 2043 echo "<small>${maxdirect}</small>";
64347dcf 2044 echo "</td>";
ca4eb604
DO
2045 if (getConfigVar ('IPV4_TREE_SHOW_VLAN') == 'yes')
2046 {
a5f9d1ca
DO
2047 echo '<td class=tdleft>';
2048 if (count ($item['8021q']))
ca4eb604 2049 {
a5f9d1ca
DO
2050 echo '<ul>';
2051 foreach ($item['8021q'] as $binding)
2052 {
2053 echo '<li><a href="' . makeHref (array ('page' => 'vlan', 'vlan_ck' => $binding['domain_id'] . '-' . $binding['vlan_id'])) . '">';
e829e76b
DO
2054 // FIXME: would formatVLANName() do this?
2055 echo $binding['vlan_id'] . '@' . niftyString ($vdomlist[$binding['domain_id']], 15) . '</a></li>';
a5f9d1ca
DO
2056 }
2057 echo '</ul>';
ca4eb604
DO
2058 }
2059 echo '</td>';
2060 }
0137d53c 2061 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
4a47d34b 2062 printRoutersTD (findRouters ($item['addrlist']), getConfigVar ('IPV4_TREE_RTR_AS_CELL'));
0137d53c 2063 echo "</tr>";
fec0c8da 2064 if ($item['symbol'] == 'node-expanded' or $item['symbol'] == 'node-expanded-static')
1f54e1ba 2065 $self ($item['kids'], $baseurl, $target, $knight, $level + 1);
0137d53c
DO
2066 }
2067 else
2068 {
0137d53c 2069 echo "<tr valign=top>";
21ee3351 2070 printIPNetInfoTDs ($item, array ('indent' => $level, 'knight' => $knight, 'tdclass' => 'sparenetwork'));
0137d53c 2071 echo "<td class=tdcenter>";
64347dcf
DO
2072 if (getConfigVar ('IPV4_TREE_SHOW_USAGE') == 'yes')
2073 {
b1e39212
DO
2074 renderProgressBar ($used/$maxtotal, 'sparenetwork');
2075 echo "<br><small>${used}/${maxtotal}</small>";
64347dcf
DO
2076 }
2077 else
b1e39212 2078 echo "<small>${maxtotal}</small>";
ee3eac34
DO
2079 if (getConfigVar ('IPV4_TREE_SHOW_VLAN') == 'yes')
2080 echo '</td><td>&nbsp;</td>';
64347dcf 2081 echo "</td><td>&nbsp;</td></tr>";
0137d53c 2082 }
d65353ad
DO
2083 }
2084}
2085
21ee3351
AA
2086function renderIPv6SpaceRecords ($tree, $baseurl, $target = 0, $knight, $level = 1)
2087{
2088 $self = __FUNCTION__;
2089 static $vdomlist = NULL;
2090 if ($vdomlist == NULL and getConfigVar ('IPV4_TREE_SHOW_VLAN') == 'yes')
2091 $vdomlist = getVLANDomainOptions();
00276508
AA
2092
2093 // scroll page to the highlighted item
2094 if ($target && isset ($_REQUEST['hl_net']))
65e557dd 2095 addAutoScrollScript ("net-$target");
00276508 2096
21ee3351
AA
2097 foreach ($tree as $item)
2098 {
2099 if (getConfigVar ('IPV4_TREE_SHOW_USAGE') == 'yes')
2100 loadIPv6AddrList ($item); // necessary to compute router list and address counter
2101 else
2102 {
2103 $item['addrlist'] = array();
2104 $item['addrc'] = 0;
2105 }
2106 if (isset ($item['id']))
2107 {
2108 $decor = array ('indent' => $level);
2109 if ($item['symbol'] == 'node-collapsed')
00276508 2110 $decor['symbolurl'] = "${baseurl}&eid=" . $item['id'];
21ee3351
AA
2111 elseif ($item['symbol'] == 'node-expanded')
2112 $decor['symbolurl'] = $baseurl . ($item['parent_id'] ? "&eid=${item['parent_id']}#net6id${item['parent_id']}" : '');
2113 echo "<tr valign=top>";
2114 if ($target == $item['id'] && isset ($_REQUEST['hl_net']))
88317562 2115 $decor['tdclass'] = ' port_highlight';
21ee3351
AA
2116 printIPNetInfoTDs ($item, $decor);
2117 echo "<td class=tdcenter>";
21ee3351
AA
2118 // show net usage
2119 echo formatIPv6NetUsage ($item['addrc'], $item['mask']);
2120 echo "</td>";
2121 if (getConfigVar ('IPV4_TREE_SHOW_VLAN') == 'yes')
2122 {
2123 echo '<td class=tdleft>';
2124 if (count ($item['8021q']))
2125 {
2126 echo '<ul>';
2127 foreach ($item['8021q'] as $binding)
2128 {
2129 echo '<li><a href="' . makeHref (array ('page' => 'vlan', 'vlan_ck' => $binding['domain_id'] . '-' . $binding['vlan_id'])) . '">';
2130 // FIXME: would formatVLANName() do this?
2131 echo $binding['vlan_id'] . '@' . niftyString ($vdomlist[$binding['domain_id']], 15) . '</a></li>';
2132 }
2133 echo '</ul>';
2134 }
2135 echo '</td>';
2136 }
2137 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
2138 printRoutersTD (findRouters ($item['addrlist']), getConfigVar ('IPV4_TREE_RTR_AS_CELL'));
2139 echo "</tr>";
2140 if ($item['symbol'] == 'node-expanded' or $item['symbol'] == 'node-expanded-static')
2141 $self ($item['kids'], $baseurl, $target, $knight, $level + 1);
2142 }
2143 /* do not display spare networks
2144 else
2145 { // display spare networks
2146 echo "<tr valign=top>";
2147 printIPNetInfoTDs ($item, array ('indent' => $level, 'knight' => $knight, 'tdclass' => 'sparenetwork'));
2148 echo "<td class=tdcenter>";
2149 echo formatIPv6NetUsage ($item['addrc'], $item['mask']);
2150 if (getConfigVar ('IPV4_TREE_SHOW_VLAN') == 'yes')
2151 echo '</td><td>&nbsp;</td>';
2152 echo "</td><td>&nbsp;</td></tr>";
2153 }*/
2154 }
2155}
2156
2157// if $used is NULL, returns only human-formatted mask.
2158// Otherwise returns "$used in/of " . human-formatted-mask
2159function formatIPv6NetUsage ($used, $mask)
2160{
2161 $prefixes = array
2162 (
2163 0 => '',
2164 3 => 'k',
2165 6 => 'M',
2166 9 => 'G',
2167 12 => 'T',
2168 15 => 'P',
2169 18 => 'E',
2170 21 => 'Z',
2171 24 => 'Y',
2172 );
2173
2174 if ($mask <= 64)
2175 {
2176 $what = '/64 net';
2177 $preposition = 'in';
2178 $mask += 64;
2179 }
2180 else
2181 {
2182 $what = 'IP';
2183 $preposition = 'of';
2184 }
2185 $what .= (0 == $mask % 64 ? '' : 's');
2186 $addrc = isset ($used) ? "$used $preposition " : '';
2187
2188 $dec_order = intval ((128 - $mask) / 10) * 3;
2189 $mult = isset ($prefixes[$dec_order]) ? $prefixes[$dec_order] : '??';
2190
2191 $cnt = 1 << ((128 - $mask) % 10);
2192 if ($cnt == 1 && $mult == '')
2193 $cnt = 'single';
2194
2195 return "<small>${addrc}${cnt}${mult} ${what}</small>";
2196}
2197
04d619d0 2198function renderIPv4Space ()
e673ee24 2199{
4fbb5a00 2200 global $pageno, $tabno;
31c941ec 2201 $cellfilter = getCellFilter();
1f54e1ba
DO
2202 $netlist = listCells ('ipv4net');
2203 $allcount = count ($netlist);
2204 $netlist = filterCellList ($netlist, $cellfilter['expression']);
573214e0 2205 array_walk ($netlist, 'amplifyCell');
4fbb5a00 2206
94a40058 2207 $netcount = count ($netlist);
5388794d
DO
2208 // expand request can take either natural values or "ALL". Zero means no expanding.
2209 $eid = isset ($_REQUEST['eid']) ? $_REQUEST['eid'] : 0;
2210 $tree = prepareIPv4Tree ($netlist, $eid);
3630d1fb
DO
2211
2212 echo "<table border=0 class=objectview>\n";
2213 echo "<tr><td class=pcleft>";
1ebbf889
AA
2214 if (! renderEmptyResults($cellfilter, 'IPv4 nets', count($tree)))
2215 {
2216 startPortlet ("networks (${netcount})");
2217 echo '<h4>';
2218 if ($eid === 0)
2219 echo 'auto-collapsing at threshold ' . getConfigVar ('TREE_THRESHOLD') .
2220 " (<a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno, 'eid'=>'ALL')) .
2221 $cellfilter['urlextra'] . "'>expand all</a>)";
2222 elseif ($eid === 'ALL')
2223 echo "expanding all (<a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno)) .
2224 $cellfilter['urlextra'] . "'>auto-collapse</a>)";
2225 else
2226 {
2227 $netinfo = spotEntity ('ipv4net', $eid);
2228 echo "expanding ${netinfo['ip']}/${netinfo['mask']} (<a href='" .
2229 makeHref (array ('page' => $pageno, 'tab' => $tabno)) .
2230 $cellfilter['urlextra'] . "'>auto-collapse</a> / <a href='" .
2231 makeHref (array ('page' => $pageno, 'tab' => $tabno, 'eid' => 'ALL')) .
2232 $cellfilter['urlextra'] . "'>expand&nbsp;all</a>)";
2233 }
2234 echo "</h4><table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
2235 echo "<tr><th>prefix</th><th>name/tags</th><th>capacity</th>";
2236 if (getConfigVar ('IPV4_TREE_SHOW_VLAN') == 'yes')
2237 echo '<th>VLAN</th>';
2238 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
2239 echo "<th>routed by</th>";
2240 echo "</tr>\n";
2241 $baseurl = makeHref(array('page'=>$pageno, 'tab'=>$tabno)) . $cellfilter['urlextra'];
2242 renderIPv4SpaceRecords ($tree, $baseurl, $eid, $netcount == $allcount and getConfigVar ('IPV4_ENABLE_KNIGHT') == 'yes');
2243 echo "</table>\n";
2244 finishPortlet();
5388794d 2245 }
1ebbf889 2246
74ccacff 2247 echo '</td><td class=pcright>';
95857b5c 2248 renderCellFilterPortlet ($cellfilter, 'ipv4net', $netlist);
74ccacff 2249 echo "</td></tr></table>\n";
f973f491 2250}
a7fe7729 2251
21ee3351
AA
2252function renderIPv6Space ()
2253{
2254 global $pageno, $tabno;
2255 $cellfilter = getCellFilter();
2256 $netlist = listCells ('ipv6net');
2257 $allcount = count ($netlist);
2258 $netlist = filterCellList ($netlist, $cellfilter['expression']);
2259 array_walk ($netlist, 'amplifyCell');
2260
2261 $netcount = count ($netlist);
2262 // expand request can take either natural values or "ALL". Zero means no expanding.
2263 $eid = isset ($_REQUEST['eid']) ? $_REQUEST['eid'] : 0;
2264 $tree = prepareIPv6Tree ($netlist, $eid);
2265
2266 echo "<table border=0 class=objectview>\n";
2267 echo "<tr><td class=pcleft>";
2268 if (! renderEmptyResults($cellfilter, 'IPv6 nets', count($tree)))
2269 {
2270 startPortlet ("networks (${netcount})");
2271 echo '<h4>';
2272 if ($eid === 0)
2273 echo 'auto-collapsing at threshold ' . getConfigVar ('TREE_THRESHOLD') .
2274 " (<a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno, 'eid'=>'ALL')) .
2275 $cellfilter['urlextra'] . "'>expand all</a>)";
2276 elseif ($eid === 'ALL')
2277 echo "expanding all (<a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno)) .
2278 $cellfilter['urlextra'] . "'>auto-collapse</a>)";
2279 else
2280 {
2281 $netinfo = spotEntity ('ipv6net', $eid);
2282 echo "expanding ${netinfo['ip']}/${netinfo['mask']} (<a href='" .
2283 makeHref (array ('page' => $pageno, 'tab' => $tabno)) .
2284 $cellfilter['urlextra'] . "'>auto-collapse</a> / <a href='" .
2285 makeHref (array ('page' => $pageno, 'tab' => $tabno, 'eid' => 'ALL')) .
2286 $cellfilter['urlextra'] . "'>expand&nbsp;all</a>)";
2287 }
2288 echo "</h4><table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
2289 echo "<tr><th>prefix</th><th>name/tags</th><th>capacity</th>";
2290 if (getConfigVar ('IPV4_TREE_SHOW_VLAN') == 'yes')
2291 echo '<th>VLAN</th>';
2292 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
2293 echo "<th>routed by</th>";
2294 echo "</tr>\n";
2295 $baseurl = makeHref(array('page'=>$pageno, 'tab'=>$tabno)) . $cellfilter['urlextra'];
2296 renderIPv6SpaceRecords ($tree, $baseurl, $eid, $netcount == $allcount and getConfigVar ('IPV4_ENABLE_KNIGHT') == 'yes');
2297 echo "</table>\n";
2298 finishPortlet();
2299 }
2300
2301 echo '</td><td class=pcright>';
2302 renderCellFilterPortlet ($cellfilter, 'ipv6net', $netlist);
2303 echo "</td></tr></table>\n";
2304}
2305
04d619d0 2306function renderIPv4SpaceEditor ()
e673ee24 2307{
a262e150 2308 // IPv4 validator
65e557dd
AA
2309 addJs ('js/live_validation.js');
2310 $regexp = addslashes ('^(\d{1,3}\.){3}\d{1,3}/\d{1,2}$');
2311 addJs (<<<END
2312$(document).ready(function () {
2313 document.add_new_range.range.setAttribute('match', '$regexp');
2314 Validate.init();
2315});
2316END
2317 , TRUE);
a262e150 2318
f857f71f
DO
2319 function printNewItemTR ()
2320 {
2321 startPortlet ('Add new');
2322 echo '<table border=0 cellpadding=10 align=center>';
2323 // This form requires a name, so JavaScript validator can find it.
2324 // No printOpFormIntro() hence
2325 echo "<form method=post name='add_new_range' action='".makeHrefProcess()."'>\n";
2326 echo "<input type=hidden name=op value=addIPv4Prefix>\n";
2327 // tags column
52e38709 2328 echo '<tr><td rowspan=5><h3>assign tags</h3>';
f857f71f
DO
2329 renderNewEntityTags ('ipv4net');
2330 echo '</td>';
2331 // inputs column
2332 $prefix_value = empty ($_REQUEST['set-prefix']) ? '' : $_REQUEST['set-prefix'];
52e38709
DO
2333 echo "<th class=tdright>prefix</th><td class=tdleft><input type=text name='range' size=18 class='live-validate' tabindex=10 value='${prefix_value}'></td>";
2334 echo '<tr><th class=tdright>VLAN</th><td class=tdleft>';
5a9adc6f 2335 echo getOptionTree ('vlan_ck', getAllVLANOptions(), array ('select_class' => 'vertical', 'tabindex' => 20)) . '</td></tr>';
52e38709
DO
2336 echo "<tr><th class=tdright>name</th><td class=tdleft><input type=text name='name' size='20' tabindex=30></td></tr>";
2337 echo '<tr><td class=tdright><input type=checkbox name="is_bcast" tabindex=40></td><th class=tdleft>reserve network and router addresses</th></tr>';
f857f71f 2338 echo "<tr><td colspan=2>";
52e38709 2339 printImageHREF ('CREATE', 'Add a new network', TRUE, 50);
f857f71f
DO
2340 echo '</td></tr>';
2341 echo "</form></table><br><br>\n";
2342 finishPortlet();
2343 }
2a201216 2344
f857f71f
DO
2345 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
2346 printNewItemTR();
ab1283b7 2347 if (count ($addrspaceList = listCells ('ipv4net')))
e673ee24 2348 {
e43a2de4 2349 startPortlet ('Manage existing (' . count ($addrspaceList) . ')');
04d619d0 2350 echo "<table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
b1e39212 2351 echo "<tr><th>&nbsp;</th><th>prefix</th><th>name</th><th>capacity</th></tr>";
d3dcdfbb
DO
2352 array_walk ($addrspaceList, 'amplifyCell');
2353 $tree = prepareIPv4Tree ($addrspaceList, 'ALL');
2354 // this is only called for having "trace" set
2355 treeFromList ($addrspaceList);
0c16ef0c 2356 foreach ($addrspaceList as $netinfo)
e673ee24 2357 {
b1e39212
DO
2358 $netinfo = peekNode ($tree, $netinfo['trace'], $netinfo['id']);
2359 // now we have all subnets listed in netinfo
2360 loadIPv4AddrList ($netinfo);
2361 $used = $netinfo['addrc'];
2362 $maxdirect = $netinfo['addrt'];
2363 $maxtotal = binInvMaskFromDec ($netinfo['mask']) + 1;
9b646039 2364 $pure_auto = 0;
865ac176
AA
2365 foreach (array ($netinfo['db_first'] => 'network', $netinfo['db_last'] => 'broadcast') as $ip => $comment)
2366 if
2367 (
2368 array_key_exists ($ip, $netinfo['addrlist']) and
2369 $netinfo['addrlist'][$ip]['name'] == $comment and
2370 $netinfo['addrlist'][$ip]['reserved'] == 'yes' and
2371 ! count ($netinfo['addrlist'][$ip]['outpf']) and
2372 ! count ($netinfo['addrlist'][$ip]['inpf']) and
2373 ! count ($netinfo['addrlist'][$ip]['allocs']) and
2374 ! count ($netinfo['addrlist'][$ip]['rsplist']) and
2375 ! count ($netinfo['addrlist'][$ip]['vslist'])
2376 )
2377 $pure_auto++;
e43a2de4 2378 echo "<tr valign=top><td>";
9b646039 2379 if (count ($netinfo['addrlist']) > $pure_auto && getConfigVar ('IPV4_JAYWALK') == 'no')
21ee3351
AA
2380 printImageHREF ('nodestroy', 'There are ' . count ($netinfo['addrlist']) . ' allocations inside');
2381 else
e43a2de4
DO
2382 {
2383 echo "<a href='".makeHrefProcess(array('op'=>'delIPv4Prefix', 'id'=>$netinfo['id']))."'>";
2384 printImageHREF ('destroy', 'Delete this prefix');
2385 echo "</a>";
2386 }
21ee3351
AA
2387 echo '</td><td class=tdleft><a href="' . makeHref (array ('page' => 'ipv4net', 'id' => $netinfo['id'])) . '">';
2388 echo "${netinfo['ip']}/${netinfo['mask']}</a></td>";
2389 echo '<td class=tdleft>' . niftyString ($netinfo['name']);
2390 if (count ($netinfo['etags']))
2391 echo '<br><small>' . serializeTags ($netinfo['etags']) . '</small>';
2392 echo '</td><td>';
2393 renderProgressBar ($maxdirect ? $used/$maxdirect : 0);
2394 echo "<br><small>${used}/${maxdirect}" . ($maxdirect == $maxtotal ? '' : "/${maxtotal}") . '</small></td>';
2395 echo '</tr>';
2396 }
2397 echo "</table>";
2398 finishPortlet();
2399 }
2400 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
2401 printNewItemTR();
2402}
e43a2de4 2403
21ee3351
AA
2404function renderIPv6SpaceEditor ()
2405{
2406 // IPv6 validator
65e557dd
AA
2407 addJs ('js/live_validation.js');
2408 $regexp = addslashes ('^[a-fA-F0-9:]*:[a-fA-F0-9:\.]*/\d{1,3}$');
2409 addJs (<<<END
2410$(document).ready(function () {
2411 document.add_new_range.range.setAttribute('match', '$regexp');
2412 Validate.init();
2413});
2414END
2415 , TRUE);
21ee3351
AA
2416
2417 function printNewItemTR ()
2418 {
2419 startPortlet ('Add new');
2420 echo '<table border=0 cellpadding=10 align=center>';
2421 // This form requires a name, so JavaScript validator can find it.
2422 // No printOpFormIntro() hence
2423 echo "<form method=post name='add_new_range' action='".makeHrefProcess()."'>\n";
2424 echo "<input type=hidden name=op value=addIPv6Prefix>\n";
2425 // tags column
52e38709 2426 echo '<tr><td rowspan=5><h3>assign tags</h3>';
21ee3351
AA
2427 renderNewEntityTags ('ipv4net');
2428 echo '</td>';
2429 // inputs column
2430 $prefix_value = empty ($_REQUEST['set-prefix']) ? '' : $_REQUEST['set-prefix'];
52e38709
DO
2431 echo "<th class=tdright>prefix</th><td class=tdleft><input type=text name='range' size=36 class='live-validate' tabindex=10 value='${prefix_value}'></td>";
2432 echo '<tr><th class=tdright>VLAN</th><td class=tdleft>';
5a9adc6f 2433 echo getOptionTree ('vlan_ck', getAllVLANOptions(), array ('select_class' => 'vertical', 'tabindex' => 20)) . '</td></tr>';
52e38709
DO
2434 echo "<tr><th class=tdright>name</th><td class=tdleft><input type=text name='name' size='20' tabindex=30></td></tr>";
2435 echo '<tr><td class=tdright><input type=checkbox name="is_connected" tabindex=40></td><th class=tdleft>reserve subnet-router anycast address</th></tr>';
21ee3351 2436 echo "<tr><td colspan=2>";
52e38709 2437 printImageHREF ('CREATE', 'Add a new network', TRUE, 50);
21ee3351
AA
2438 echo '</td></tr>';
2439 echo "</form></table><br><br>\n";
2440 finishPortlet();
2441 }
2442
2443 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
2444 printNewItemTR();
2445 if (count ($addrspaceList = listCells ('ipv6net')))
2446 {
2447 startPortlet ('Manage existing (' . count ($addrspaceList) . ')');
2448 echo "<table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
2449 echo "<tr><th>&nbsp;</th><th>prefix</th><th>name</th><th>capacity</th></tr>";
2450 array_walk ($addrspaceList, 'amplifyCell');
2451 $tree = prepareIPv6Tree ($addrspaceList, 'ALL');
2452 // this is only called for having "trace" set
2453 treeFromList ($addrspaceList);
2454 foreach ($addrspaceList as $netinfo)
2455 {
2456 $netinfo = peekNode ($tree, $netinfo['trace'], $netinfo['id']);
2457 // now we have all subnets listed in netinfo
2458 loadIPv6AddrList ($netinfo);
2459 echo "<tr valign=top><td>";
2460 if (count ($netinfo['addrlist']) && getConfigVar ('IPV4_JAYWALK') == 'no')
2461 printImageHREF ('nodestroy', 'There are ' . count ($netinfo['addrlist']) . ' allocations inside');
2462 else
2463 {
2464 echo "<a href='".makeHrefProcess (array ('op' => 'delIPv6Prefix', 'id' => $netinfo['id'])) . "'>";
2465 printImageHREF ('destroy', 'Delete this prefix');
2466 echo "</a>";
e43a2de4 2467 }
21ee3351 2468 echo '</td><td class=tdleft><a href="' . makeHref (array ('page' => 'ipv6net', 'id' => $netinfo['id'])) . '">';
ab1283b7 2469 echo "${netinfo['ip']}/${netinfo['mask']}</a></td>";
1f54e1ba
DO
2470 echo '<td class=tdleft>' . niftyString ($netinfo['name']);
2471 if (count ($netinfo['etags']))
2472 echo '<br><small>' . serializeTags ($netinfo['etags']) . '</small>';
2473 echo '</td><td>';
21ee3351 2474 echo formatIPv6NetUsage ($netinfo['addrc'], $netinfo['mask']);
b1e39212 2475 echo '</tr>';
e673ee24 2476 }
04d619d0
DO
2477 echo "</table>";
2478 finishPortlet();
e673ee24 2479 }
f857f71f
DO
2480 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
2481 printNewItemTR();
e673ee24
DO
2482}
2483
beb9e88a 2484function renderIPv4Network ($id)
e673ee24 2485{
c8824ff4 2486 global $pageno, $tabno, $aac2, $netmaskbylen, $wildcardbylen;
e673ee24 2487
d724d290 2488 $range = spotEntity ('ipv4net', $id);
a5f9d1ca 2489 amplifyCell ($range);
b6b87070 2490 loadIPv4AddrList ($range);
2034d968 2491 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
99ab184f
DO
2492 echo "<tr><td colspan=2 align=center><h1>${range['ip']}/${range['mask']}</h1><h2>";
2493 echo htmlspecialchars ($range['name'], ENT_QUOTES, 'UTF-8') . "</h2></td></tr>\n";
2034d968
DO
2494
2495 echo "<tr><td class=pcleft width='50%'>";
646272be
AA
2496
2497 // render summary portlet
2498 $summary = array();
2034d968
DO
2499 $total = ($range['ip_bin'] | $range['mask_bin_inv']) - ($range['ip_bin'] & $range['mask_bin']) + 1;
2500 $used = count ($range['addrlist']);
646272be 2501 $summary['%% used'] = getProgressBar ($used/$total) . "&nbsp;${used}/${total}";
001e61fa
DO
2502 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
2503 {
3444ecf2
DO
2504 // Build a backtrace from all parent networks.
2505 $clen = $range['mask'];
2506 $backtrace = array();
2507 while (NULL !== ($upperid = getIPv4AddressNetworkId ($range['ip'], $clen)))
2508 {
d724d290 2509 $upperinfo = spotEntity ('ipv4net', $upperid);
3444ecf2 2510 $clen = $upperinfo['mask'];
d724d290 2511 $backtrace[] = $upperinfo;
3444ecf2
DO
2512 }
2513 $arrows = count ($backtrace);
d724d290 2514 foreach (array_reverse ($backtrace) as $ainfo)
001e61fa 2515 {
646272be 2516 $name = '';
3444ecf2 2517 for ($i = 0; $i < $arrows; $i++)
646272be 2518 $name .= '&uarr;';
3444ecf2 2519 $arrows--;
646272be 2520 $summary[] = array ($name, getOutputOf ('renderCell', $ainfo));
001e61fa 2521 }
646272be 2522 $summary[] = array ('&rarr;', getOutputOf ('renderCell', $range));
001e61fa
DO
2523 // FIXME: get and display nested networks
2524 // $theitem = pickLeaf ($ipv4tree, $id);
2525 }
646272be
AA
2526 $summary[] = array ('Netmask:', $netmaskbylen[$range['mask']]);
2527 $summary[] = array ('Netmask:', sprintf ('0x%08X', binMaskFromDec ($range['mask'])));
2528 $summary['Wildcard bits'] = $wildcardbylen[$range['mask']];
2529
a5f9d1ca 2530 foreach ($range['8021q'] as $item)
cbf78395 2531 {
a5f9d1ca 2532 $vlaninfo = getVLANInfo ($item['domain_id'] . '-' . $item['vlan_id']);
646272be 2533 $summary[] = array ('VLAN:', '<a href="' . makeHref (array ('page' => 'vlan', 'vlan_ck' => $vlaninfo['vlan_ck'])) . '">' . formatVLANName ($vlaninfo, 'markup long') . '</a>');
cbf78395 2534 }
3a4f4023 2535 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes' and count ($routers = findRouters ($range['addrlist'])))
04d619d0 2536 {
646272be
AA
2537 $summary['Routed by'] = '';
2538 foreach ($routers as $rtr)
2539 $summary['Routed by'] .= getOutputOf ('renderRouterCell', $rtr['addr'], $rtr['iface'], spotEntity ('object', $rtr['id']));
04d619d0 2540 }
646272be
AA
2541 $summary['tags'] = '';
2542 renderEntitySummary ($range, 'summary', $summary);
e1ae3fb4 2543
99ab184f
DO
2544 if (strlen ($range['comment']))
2545 {
2546 startPortlet ('Comment');
2547 echo '<div class=commentblock>' . string_insert_hrefs (htmlspecialchars ($range['comment'], ENT_QUOTES, 'UTF-8')) . '</div>';
2548 finishPortlet ();
2549 }
2550
e1ae3fb4 2551 renderFilesPortlet ('ipv4net', $id);
2034d968 2552 echo "</td>\n";
e673ee24 2553
2034d968
DO
2554 echo "<td class=pcright>";
2555 startPortlet ('details');
e673ee24
DO
2556 $startip = $range['ip_bin'] & $range['mask_bin'];
2557 $endip = $range['ip_bin'] | $range['mask_bin_inv'];
2558 $realstartip = $startip;
2559 $realendip = $endip;
e673ee24 2560
00276508
AA
2561 if (isset ($_REQUEST['hl_ipv4_addr']))
2562 {
2563 $hl_ip = ip2long ($_REQUEST['hl_ipv4_addr']);
2564 $hl_dottedquad = ip_long2quad ($hl_ip);
65e557dd 2565 addAutoScrollScript ("ip-$hl_dottedquad"); // scroll page to highlighted ip
00276508
AA
2566 }
2567
79b57b18
AA
2568 // pager
2569 $maxperpage = getConfigVar ('IPV4_ADDRS_PER_PAGE');
2570 $address_count = $endip - $startip + 1;
2571 $page = 0;
446c25c3 2572 $rendered_pager = '';
79b57b18
AA
2573 if ($address_count > $maxperpage && $maxperpage > 0)
2574 {
2575 $page = isset ($_REQUEST['pg']) ? $_REQUEST['pg'] : (isset ($hl_ip) ? intval (($hl_ip - $startip) / $maxperpage) : 0);
2576 if ($numpages = ceil ($address_count / $maxperpage))
2577 {
79b57b18
AA
2578 echo '<h3>' . long2ip ($startip) . ' ~ ' . long2ip ($endip) . '</h3>';
2579 for ($i = 0; $i < $numpages; $i++)
2580 if ($i == $page)
446c25c3 2581 $rendered_pager .= "<b>$i</b> ";
79b57b18 2582 else
446c25c3 2583 $rendered_pager .= "<a href='".makeHref (array ('page' => $pageno, 'tab' => $tabno, 'id' => $id, 'pg' => $i)) . "'>$i</a> ";
79b57b18
AA
2584 }
2585 $startip = $startip + $page * $maxperpage;
2586 $endip = min ($startip + $maxperpage - 1, $endip);
2587 }
2588
446c25c3 2589 echo $rendered_pager;
beb9e88a 2590 echo "<table class='widetable' border=0 cellspacing=0 cellpadding=5 align='center' width='100%'>\n";
e673ee24
DO
2591 echo "<tr><th>Address</th><th>Name</th><th>Allocation</th></tr>\n";
2592
b2035dca 2593 for ($ip = $startip; $ip <= $endip; $ip++) :
00276508
AA
2594 $dottedquad = ip_long2quad($ip);
2595 $secondstyle = 'tdleft' . (isset ($hl_ip) && $hl_ip == $ip ? ' port_highlight' : '');
b2035dca 2596 if (!isset ($range['addrlist'][$ip]))
e673ee24 2597 {
a8dc2982
AA
2598 echo "<tr><td class=tdleft><a class='ancor' name='ip-$dottedquad' href='" . makeHref(array('page'=>'ipaddress', 'ip' => $dottedquad)) . "'>$dottedquad</a></td>";
2599 echo "<td class='rsv-port ${secondstyle}'><span class='rsvtext'></span></td><td class='${secondstyle}'>&nbsp;</td></tr>\n";
b2035dca
DO
2600 continue;
2601 }
b2035dca 2602 $addr = $range['addrlist'][$ip];
68c91b9c
AA
2603 // render IP change history
2604 $title = '';
2605 $history_class = '';
2606 if (isset ($addr['last_log']))
2607 {
2608 $title = ' title="' . htmlspecialchars ($addr['last_log']['user'] . ', ' . formatAge ($addr['last_log']['time']) , ENT_QUOTES) . '"';
2609 $history_class = 'hover-history underline';
2610 }
2d318652 2611 echo "<tr class='${addr['class']}'>";
68c91b9c 2612 echo "<td class=tdleft><a class='ancor $history_class' $title name='ip-$dottedquad' href='".makeHref(array('page'=>'ipaddress', 'ip'=>$addr['ip']))."'>${addr['ip']}</a></td>";
a8dc2982
AA
2613 echo "<td class='${secondstyle} " .
2614 (empty ($addr['allocs']) || !empty ($addr['name']) ? 'rsv-port' : '') .
2615 "'><span class='rsvtext'>${addr['name']}</span></td><td class='${secondstyle}'>";
b2035dca 2616 $delim = '';
b2035dca
DO
2617 if ( $addr['reserved'] == 'yes')
2618 {
2d318652 2619 echo "<strong>RESERVED</strong> ";
b2035dca
DO
2620 $delim = '; ';
2621 }
212b565a 2622 foreach ($addr['allocs'] as $ref)
b2035dca 2623 {
beb9e88a 2624 echo $delim . $aac2[$ref['type']];
68c91b9c 2625 echo "<a href='".makeHref(array('page'=>'object', 'object_id'=>$ref['object_id'], 'tab' => 'default', 'hl_ipv4_addr'=>$addr['ip']))."'>";
59a83bd8 2626 echo $ref['name'] . (!strlen ($ref['name']) ? '' : '@');
b2035dca
DO
2627 echo "${ref['object_name']}</a>";
2628 $delim = '; ';
2629 }
2630 if ($delim != '')
e0d6e38e 2631 $delim = '<br>';
212b565a
AA
2632 foreach ($addr['vslist'] as $vs_id)
2633 {
2634 $vs = spotEntity ('ipv4vs', $vs_id);
2635 echo "${delim}<a href='".makeHref(array('page'=>'ipv4vs', 'vs_id'=>$vs['id']))."'>";
2636 echo "${vs['name']}:${vs['vport']}/${vs['proto']}</a>&rarr;";
2637 $delim = '<br>';
2638 }
2639 foreach ($addr['rsplist'] as $rsp_id)
2640 {
2641 $rsp = spotEntity ('ipv4rspool', $rsp_id);
2642 echo "${delim}&rarr;<a href='".makeHref(array('page'=>'ipv4rspool', 'pool_id'=>$rsp['id']))."'>";
2643 echo "${rsp['name']}</a>";
2644 $delim = '<br>';
2645 }
b2035dca
DO
2646 echo "</td></tr>\n";
2647 endfor;
2727c7df 2648 // end of iteration
a8dc2982
AA
2649 if (permitted (NULL, NULL, 'set_reserve_comment'))
2650 addJS ('js/inplace-edit.js');
e673ee24
DO
2651
2652 echo "</table>";
446c25c3
AA
2653 if (! empty ($rendered_pager))
2654 echo '<p>' . $rendered_pager . '</p>';
2655
2034d968
DO
2656 finishPortlet();
2657 echo "</td></tr></table>\n";
e673ee24
DO
2658}
2659
21ee3351
AA
2660// based on renderIPv4Network
2661function renderIPv6Network ($id)
2662{
2663 $range = spotEntity ('ipv6net', $id);
2664 amplifyCell ($range);
2665 loadIPv6AddrList ($range);
2666 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
2667 echo "<tr><td colspan=2 align=center><h1>${range['ip']}/${range['mask']}</h1><h2>";
2668 echo htmlspecialchars ($range['name'], ENT_QUOTES, 'UTF-8') . "</h2></td></tr>\n";
2669
2670 echo "<tr><td class=pcleft width='50%'>";
21ee3351 2671
646272be
AA
2672 // render summary portlet
2673 $summary = array();
2674 $summary['%% used'] = formatIPv6NetUsage (count ($range['addrlist']), $range['mask']);
21ee3351
AA
2675 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
2676 {
2677 // Build a backtrace from all parent networks.
2678 $backtrace = array();
2679 $current = $range;
2680 while ($current['parent_id'])
2681 {
2682 $current = spotEntity ('ipv6net', $current['parent_id']);
2683 $backtrace[] = $current;
2684 }
2685 $arrows = count ($backtrace);
2686 foreach (array_reverse ($backtrace) as $ainfo)
2687 {
646272be 2688 $name = '';
21ee3351 2689 for ($i = 0; $i < $arrows; $i++)
646272be 2690 $name .= '&uarr;';
21ee3351 2691 $arrows--;
646272be 2692 $summary[] = array ($name, getOutputOf ('renderCell', $ainfo));
21ee3351 2693 }
646272be 2694 $summary[] = array ('&rarr;', getOutputOf ('renderCell', $range));
21ee3351
AA
2695 // FIXME: get and display nested networks
2696 }
2697
2698 foreach ($range['8021q'] as $item)
2699 {
2700 $vlaninfo = getVLANInfo ($item['domain_id'] . '-' . $item['vlan_id']);
646272be 2701 $summary[] = array ('VLAN:', '<a href="' . makeHref (array ('page' => 'vlan', 'vlan_ck' => $vlaninfo['vlan_ck'])) . '">' . formatVLANName ($vlaninfo, 'markup long') . '</a>');
21ee3351
AA
2702 }
2703 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes' and count ($routers = findRouters ($range['addrlist'])))
2704 {
646272be
AA
2705 $summary['Routed by'] = '';
2706 foreach ($routers as $rtr)
2707 $summary['Routed by'] .= getOutputOf ('renderRouterCell', $rtr['addr'], $rtr['iface'], spotEntity ('object', $rtr['id']));
21ee3351 2708 }
646272be
AA
2709 $summary['tags'] = '';
2710 renderEntitySummary ($range, 'summary', $summary);
21ee3351
AA
2711
2712 if (strlen ($range['comment']))
2713 {
2714 startPortlet ('Comment');
2715 echo '<div class=commentblock>' . string_insert_hrefs (htmlspecialchars ($range['comment'], ENT_QUOTES, 'UTF-8')) . '</div>';
2716 finishPortlet ();
2717 }
2718
2719 renderFilesPortlet ('ipv6net', $id);
2720 echo "</td>\n";
2721
2722 // render address list
2723 echo "<td class=pcright>";
2724 startPortlet ('details');
2725 renderIPv6NetworkAddresses ($range);
2726 finishPortlet();
2727 echo "</td></tr></table>\n";
2728}
2729
2730// Used solely by renderSeparator
2731function renderEmptyIPv6 ($ip, $hl_ip)
2732{
2733 $class = 'tdleft';
2734 if (isset ($hl_ip) && $ip == $hl_ip)
2735 $class .= ' port_highlight';
2736 $fmt = $ip->format();
a8dc2982
AA
2737 echo "<tr><td class=tdleft><a class='ancor' name='ip-$fmt' href='" . makeHref (array ('page' => 'ipv6address', 'ip' => $fmt)) . "'>" . $fmt;
2738 echo "</a></td><td class='${class} rsv-port'><span class='rsvtext'></span></td><td class='${class}'>&nbsp;</td></tr>\n";
21ee3351
AA
2739}
2740
2741// Renders empty table line to shrink empty IPv6 address ranges.
2742// If the range consists of single address, renders the address instead of empty line.
2743// Renders address $hl_ip inside the range.
2744// Used solely by renderIPv6NetworkAddresses
2745function renderSeparator ($first, $after, $hl_ip)
2746{
2747 $self = __FUNCTION__;
522b6f90 2748 if (strcmp ($first->getBin(), $after->getBin()) >= 0)
21ee3351
AA
2749 return;
2750 if ($first->next() == $after)
2751 renderEmptyIPv6 ($first, $hl_ip);
522b6f90 2752 elseif (isset ($hl_ip) && strcmp ($hl_ip->getBin(), $first->getBin()) >= 0 && strcmp ($hl_ip->getBin(), $after->getBin()) < 0)
21ee3351
AA
2753 { // $hl_ip is inside the range $first - ($after-1)
2754 $self ($first, $hl_ip, $hl_ip);
2755 renderEmptyIPv6 ($hl_ip, $hl_ip);
2756 $self ($hl_ip->next(), $after, $hl_ip);
2757 }
2758 else
2759 echo "<tr><td colspan=3 class=tdleft></td></tr>\n";
2760}
2761
2762// calculates page number which contains given $ip (used by renderIPv6NetworkAddresses)
2763function getPageNumOfIPv6 ($list, $ip, $maxperpage)
2764{
2765 if (intval ($maxperpage) <= 0 || count ($list) <= $maxperpage)
2766 return 0;
522b6f90 2767 $bin_ip = $ip->getBin();
21ee3351
AA
2768 $keys = array_keys ($list);
2769 for ($i = 1; $i <= count ($keys); $i++)
2770 if (strcmp ($keys[$i-1], $bin_ip) >= 0)
2771 return intval ($i / $maxperpage);
2772 return intval (count ($list) / $maxperpage);
2773}
2774
2775function renderIPv6NetworkAddresses ($netinfo)
2776{
2777 global $pageno, $tabno, $aac2;
2778 echo "<table class='widetable' border=0 cellspacing=0 cellpadding=5 align='center' width='100%'>\n";
2779 echo "<tr><th>Address</th><th>Name</th><th>Allocation</th></tr>\n";
2780
2781 $hl_ip = new IPv6Address;
2782 if (! isset ($_REQUEST['hl_ipv6_addr']) || ! $hl_ip->parse ($_REQUEST['hl_ipv6_addr']))
2783 $hl_ip = NULL;
00276508 2784 else
65e557dd 2785 addAutoScrollScript ('ip-' . $hl_ip->format());
21ee3351
AA
2786
2787 $prev_ip = $netinfo['ip_bin']; // really this is the next to previosly seen ip.
2788 $addresses = $netinfo['addrlist'];
2789 ksort ($addresses);
2790
2791 // pager
2792 $maxperpage = getConfigVar ('IPV4_ADDRS_PER_PAGE');
2793 if (count ($addresses) > $maxperpage && $maxperpage > 0)
2794 {
2795 $page = isset ($_REQUEST['pg']) ? $_REQUEST['pg'] : (isset ($hl_ip) ? getPageNumOfIPv6 ($addresses, $hl_ip, $maxperpage) : 0);
2796 $numpages = ceil (count ($addresses) / $maxperpage);
2797 echo "<center><h3>$numpages pages:</h3>";
2798 for ($i=0; $i<$numpages; $i++)
2799 {
2800 if ($i == $page)
2801 echo "<b>$i</b> ";
2802 else
2803 echo "<a href='" . makeHref (array ('page' => $pageno, 'tab' => $tabno, 'id' => $netinfo['id'], 'pg' => $i)) . "'>$i</a> ";
2804 }
2805 echo "</center>";
2806 }
2807
2808 $i = 0;
2809 $interruped = FALSE;
2810 foreach ($addresses as $bin_ip => $addr)
2811 {
2812 if (isset ($page))
2813 {
2814 ++$i;
2815 if ($i <= $maxperpage * $page)
2816 continue;
2817 elseif ($i > $maxperpage * ($page + 1))
2818 {
2819 $interruped = TRUE;
2820 break;
2821 }
2822 }
2823
2824 $ipv6 = new IPv6Address ($bin_ip);
2825 if ($ipv6 != $prev_ip)
2826 renderSeparator ($prev_ip, $ipv6, $hl_ip);
2827 $prev_ip = $ipv6->next();
2828
2829 $secondstyle = 'tdleft';
2830 if (isset ($hl_ip) && $hl_ip == $ipv6)
2831 $secondstyle .= ' port_highlight';
2832 echo "<tr class='${addr['class']}'>";
a8dc2982
AA
2833 echo "<td class=tdleft><a class='ancor' name='ip-${addr['ip']}' href='" . makeHref (array ('page' => 'ipv6address', 'ip' => $addr['ip'])) . "'>${addr['ip']}</a></td>";
2834 echo "<td class='${secondstyle} " .
2835 (empty ($addr['allocs']) || !empty ($addr['name']) ? 'rsv-port' : '') .
2836 "'><span class='rsvtext'>${addr['name']}</span></td><td class='${secondstyle}'>";
21ee3351
AA
2837 $delim = '';
2838 $prologue = '';
2839 if ( $addr['reserved'] == 'yes')
2840 {
2841 echo "<strong>RESERVED</strong> ";
2842 $delim = '; ';
2843 }
2844 foreach ($addr['allocs'] as $ref)
2845 {
2846 echo $delim . $aac2[$ref['type']];
2847 echo "<a href='" . makeHref (array ('page' => 'object', 'object_id' => $ref['object_id'], 'hl_ipv6_addr' => $addr['ip'])) . "'>";
2848 echo $ref['name'] . (!strlen ($ref['name']) ? '' : '@');
2849 echo "${ref['object_name']}</a>";
2850 $delim = '; ';
2851 }
2852 if ($delim != '')
2853 {
2854 $delim = '';
2855 $prologue = '<br>';
2856 }
2857 echo "</td></tr>\n";
2858 }
2859 if (! $interruped)
2860 renderSeparator ($prev_ip, $netinfo['ip_bin']->get_last_subnet_address ($netinfo['mask'])->next(), $hl_ip);
2861 if (isset ($page))
2862 { // bottom pager
2863 echo "<tr><td colspan=3>";
2864 if ($page > 0)
2865 echo "<a href='" . makeHref (array ('page' => $pageno, 'tab' => $tabno, 'id' => $netinfo['id'], 'pg' => $page - 1)) . "'><< prev</a> ";
2866 if ($page < $numpages - 1)
2867 echo "<a href='" . makeHref (array ('page' => $pageno, 'tab' => $tabno, 'id' => $netinfo['id'], 'pg' => $page + 1)) . "'>next >></a> ";
2868 echo "</td></tr>";
2869 }
2870 echo "</table>";
a8dc2982
AA
2871 if (permitted (NULL, NULL, 'set_reserve_comment'))
2872 addJS ('js/inplace-edit.js');
21ee3351
AA
2873}
2874
2875function renderIPNetworkProperties ($id)
e673ee24 2876{
21ee3351
AA
2877 global $pageno;
2878 $netdata = spotEntity ($pageno, $id);
53ef3908 2879 echo "<center><h1>${netdata['ip']}/${netdata['mask']}</h1></center>\n";
e673ee24 2880 echo "<table border=0 cellpadding=10 cellpadding=1 align='center'>\n";
7056988c 2881 printOpFormIntro ('editRange');
99ab184f
DO
2882 echo '<tr><td class=tdright><label for=nameinput>Name:</label></td>';
2883 echo "<td class=tdleft><input type=text name=name id=nameinput size=80 maxlength=255 value='";
2884 echo htmlspecialchars ($netdata['name'], ENT_QUOTES, 'UTF-8') . "'></tr>";
2885 echo '<tr><td class=tdright><label for=commentinput>Comment:</label></td>';
2886 echo "<td class=tdleft><textarea name=comment id=commentinput cols=80 rows=25>\n";
2887 echo htmlspecialchars ($netdata['comment'], ENT_QUOTES, 'UTF-8') . "</textarea></tr>";
53ef3908
DO
2888 echo "<tr><td colspan=2 class=tdcenter>";
2889 printImageHREF ('SAVE', 'Save changes', TRUE);
2890 echo "</td></form></tr></table>\n";
e673ee24
DO
2891}
2892
21ee3351 2893function renderIPAddress ($dottedquad)
e673ee24 2894{
46098972 2895 global $aat, $nextorder;
21ee3351 2896 $address = getIPAddress ($dottedquad);
68225375 2897 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
21ee3351 2898 echo "<tr><td colspan=2 align=center><h1>${address['ip']}</h1></td></tr>\n";
e673ee24 2899
68225375 2900 echo "<tr><td class=pcleft>";
defd92d8
AA
2901
2902 $summary = array();
423c4216 2903 if (strlen ($address['name']))
defd92d8
AA
2904 $summary['Comment'] = $address['name'];
2905 $summary['Reserved'] = $address['reserved'];
2906 $summary['Allocations'] = count ($address['allocs']);
21ee3351
AA
2907 if ($address['version'] == 4)
2908 {
defd92d8
AA
2909 $summary['Originated NAT connections'] = count ($address['outpf']);
2910 $summary['Arriving NAT connections'] = count ($address['inpf']);
21ee3351 2911 }
defd92d8 2912 renderEntitySummary ($address, 'summary', $summary);
212b565a
AA
2913
2914 // render SLB portlet
2915 if ($address['version'] == 4 and (! empty ($address['vslist']) or ! empty ($address['rsplist'])))
2916 {
2917 startPortlet ("");
2918 if (! empty ($address['vslist']))
2919 {
2920 printf ("<h2>virtual services (%d):</h2>", count ($address['vslist']));
2921 foreach ($address['vslist'] as $vs_id)
2922 renderSLBEntityCell (spotEntity ('ipv4vs', $vs_id));
2923 }
2924
2925 if (! empty ($address['rsplist']))
2926 {
2927 printf ("<h2>RS pools (%d):</h2>", count ($address['rsplist']));
2928 foreach ($address['rsplist'] as $rsp_id)
2929 renderSLBEntityCell (spotEntity ('ipv4rspool', $rsp_id));
2930 }
2931 finishPortlet();
2932 }
68225375 2933 echo "</td>\n";
e673ee24 2934
68225375 2935 echo "<td class=pcright>";
defd92d8 2936 if (isset ($address['class']) and ! empty ($address['allocs']))
59bebe2b 2937 {
8e700dd1 2938 startPortlet ('allocations');
2d318652
DO
2939 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
2940 echo "<tr><th>object</th><th>OS interface</th><th>allocation type</th></tr>\n";
2941 $class = $address['class'];
2942 // render all allocation records for this address the same way
2d318652 2943 foreach ($address['allocs'] as $bond)
59bebe2b 2944 {
8e700dd1
DO
2945 if (isset ($_REQUEST['hl_object_id']) and $_REQUEST['hl_object_id'] == $bond['object_id'])
2946 $secondclass = 'tdleft port_highlight';
2947 else
2948 $secondclass = 'tdleft';
68c91b9c 2949 echo "<tr class='$class'><td class=tdleft><a href='" . makeHref (array ('page' => 'object', 'object_id' => $bond['object_id'], 'tab' => 'default', 'hl_ipv' . $address['version'] . '_addr' => $address['ip'])) . "'>${bond['object_name']}</td><td class='${secondclass}'>${bond['name']}</td><td class='${secondclass}'><strong>";
52c836b1
DO
2950 echo $aat[$bond['type']];
2951 echo "</strong></td></tr>\n";
59bebe2b
DO
2952 }
2953 echo "</table><br><br>";
2954 finishPortlet();
2955 }
e673ee24 2956
defd92d8
AA
2957 if ($address['version'] == 4)
2958 renderSLBTriplets ($address);
5fe1ed76 2959
21ee3351 2960 if (! empty ($address['outpf']))
68225375 2961 {
105a3bc8 2962 startPortlet ('departing NAT rules');
2d318652 2963 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
105a3bc8
DO
2964 echo "<tr><th>proto</th><th>from</th><th>to</th><th>comment</th></tr>\n";
2965 foreach ($address['outpf'] as $rule)
b62ff880 2966 echo "<tr><td>${rule['proto']}</td><td>${rule['localip']}:${rule['localport']}</td><td>${rule['remoteip']}:${rule['remoteport']}</td><td>${rule['description']}</td></tr>";
105a3bc8 2967 echo "</table>";
68225375
DO
2968 finishPortlet();
2969 }
105a3bc8 2970
21ee3351 2971 if (! empty ($address['inpf']))
105a3bc8
DO
2972 {
2973 startPortlet ('arriving NAT rules');
2d318652 2974 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
105a3bc8
DO
2975 echo "<tr><th>proto</th><th>from</th><th>to</th><th>comment</th></tr>\n";
2976 foreach ($address['inpf'] as $rule)
b62ff880 2977 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
2978 echo "</table>";
2979 finishPortlet();
2980 }
2981
68225375
DO
2982 echo "</td></tr>";
2983 echo "</table>\n";
e673ee24
DO
2984}
2985
21ee3351 2986function renderIPAddressProperties ($dottedquad)
e673ee24 2987{
21ee3351
AA
2988 $address = getIPAddress ($dottedquad);
2989 echo "<center><h1>${address['ip']}</h1></center>\n";
7056988c 2990
1fbc9fd6 2991 startPortlet ('update');
e673ee24 2992 echo "<table border=0 cellpadding=10 cellpadding=1 align='center'>\n";
7056988c 2993 printOpFormIntro ('editAddress');
2d318652
DO
2994 echo "<tr><td class='tdright'>Name:</td><td class='tdleft'><input type=text name=name size=20 value='${address['name']}'></tr>";
2995 echo "<td class='tdright'>Reserved:</td><td class='tdleft'><input type=checkbox name=reserved size=20 ";
2996 echo ($address['reserved']=='yes') ? 'checked' : '';
f3d274bf 2997 echo "></tr><tr><td class=tdleft>";
53ef3908 2998 printImageHREF ('SAVE', 'Save changes', TRUE);
f3d274bf 2999 echo "</td></form><td class=tdright>";
59a83bd8 3000 if (!strlen ($address['name']) and $address['reserved'] == 'no')
f3d274bf
DO
3001 printImageHREF ('CLEAR gray');
3002 else
3003 {
3004 printOpFormIntro ('editAddress', array ('name' => '', 'reserved' => ''));
3005 printImageHREF ('CLEAR', 'Release', TRUE);
3006 echo "</form>";
3007 }
3008 echo "</td></tr></table>\n";
1fbc9fd6 3009 finishPortlet();
e673ee24
DO
3010}
3011
21ee3351 3012function renderIPAddressAllocations ($dottedquad)
e673ee24 3013{
21ee3351 3014 function printNewItemTR ($opname)
39b4abd0
DO
3015 {
3016 global $aat;
21ee3351 3017 printOpFormIntro ($opname);
39b4abd0 3018 echo "<tr><td>";
9318d2ef 3019 printImageHREF ('add', 'allocate', TRUE);
8d4f7d18 3020 echo "</td><td>";
31babb65 3021 printSelect (getNarrowObjectList ('IPV4OBJ_LISTSRC'), array ('name' => 'object_id', 'tabindex' => 100));
8d4f7d18 3022 echo "</td><td><input type=text tabindex=101 name=bond_name size=10></td><td>";
01abf1de 3023 printSelect ($aat, array ('name' => 'bond_type', 'tabindex' => 102, 'regular'));
9318d2ef 3024 echo "</td><td>";
f5ff50f5 3025 printImageHREF ('add', 'allocate', TRUE, 103);
9318d2ef 3026 echo "</td></form></tr>";
39b4abd0 3027 }
b82cce3f 3028 global $aat;
e673ee24 3029
21ee3351
AA
3030 $address = getIPAddress ($dottedquad);
3031 $opname = $address['version'] == 6 ? 'addIPv6Allocation' : 'addIPv4Allocation';
3032 echo "<center><h1>${address['ip']}</h1></center>\n";
105a3bc8 3033 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
2d318652 3034 echo "<tr><th>&nbsp;</th><th>object</th><th>OS interface</th><th>allocation type</th><th>&nbsp;</th></tr>\n";
e673ee24 3035
39b4abd0 3036 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
21ee3351 3037 printNewItemTR($opname);
f74d96c6 3038 if (isset ($address['class']))
e673ee24 3039 {
f74d96c6
DO
3040 $class = $address['class'];
3041 if ($address['reserved'] == 'yes')
3042 echo "<tr class='${class}'><td colspan=3>&nbsp;</td><td class=tdleft><strong>RESERVED</strong></td><td>&nbsp;</td></tr>";
3043 foreach ($address['allocs'] as $bond)
3044 {
3045 echo "<tr class='$class'>";
21ee3351
AA
3046 printOpFormIntro
3047 (
3048 $address['version'] == 6 ? 'updIPv6Allocation' : 'updIPv4Allocation',
3049 array ('object_id' => $bond['object_id'])
3050 );
3051 echo "<td><a href='"
3052 . makeHrefProcess
3053 (
3054 array
3055 (
3056 'op' => $address['version'] == 6 ? 'delIPv6Allocation' : 'delIPv4Allocation',
3057 'ip' => $address['ip'],
3058 'object_id' => $bond['object_id']
3059 )
3060 )
3061 . "'>";
f74d96c6
DO
3062 printImageHREF ('delete', 'Unallocate address');
3063 echo "</a></td>";
21ee3351 3064 echo "<td><a href='" . makeHref (array ('page' => 'object', 'object_id' => $bond['object_id'], 'hl_ipv' . $address['version'] . '_addr' => $address['ip'])) . "'>${bond['object_name']}</td>";
f74d96c6 3065 echo "<td><input type='text' name='bond_name' value='${bond['name']}' size=10></td><td>";
cd3775e9 3066 printSelect ($aat, array ('name' => 'bond_type'), $bond['type']);
f74d96c6
DO
3067 echo "</td><td>";
3068 printImageHREF ('save', 'Save changes', TRUE);
3069 echo "</td></form></tr>\n";
3070 }
e673ee24 3071 }
39b4abd0 3072 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
21ee3351 3073 printNewItemTR($opname);
e673ee24 3074 echo "</table><br><br>";
e673ee24
DO
3075}
3076
7e1db771 3077function renderNATv4ForObject ($object_id)
e673ee24 3078{
9318d2ef
DO
3079 function printNewItemTR ($alloclist)
3080 {
9318d2ef
DO
3081 printOpFormIntro ('addNATv4Rule');
3082 echo "<tr align='center'><td>";
3083 printImageHREF ('add', 'Add new NAT rule', TRUE);
3084 echo '</td><td>';
cd3775e9 3085 printSelect (array ('TCP' => 'TCP', 'UDP' => 'UDP'), array ('name' => 'proto'));
9318d2ef
DO
3086 echo "<select name='localip' tabindex=1>";
3087
3088 foreach ($alloclist as $dottedquad => $alloc)
3089 {
43eb71f1
DO
3090 $name = (!isset ($alloc['addrinfo']['name']) or !strlen ($alloc['addrinfo']['name'])) ? '' : (' (' . niftyString ($alloc['addrinfo']['name']) . ')');
3091 $osif = (!isset ($alloc['osif']) or !strlen ($alloc['osif'])) ? '' : ($alloc['osif'] . ': ');
9318d2ef
DO
3092 echo "<option value='${dottedquad}'>${osif}${dottedquad}${name}</option>";
3093 }
3094
3095 echo "</select>:<input type='text' name='localport' size='4' tabindex=2></td>";
3096 echo "<td><input type='text' name='remoteip' id='remoteip' size='10' tabindex=3>";
39106006
DO
3097 echo "<a href='javascript:;' onclick='window.open(\"" . makeHrefForHelper ('inet4list');
3098 echo "\", \"findobjectip\", \"height=700, width=400, location=no, menubar=no, resizable=yes, scrollbars=no, status=no, titlebar=no, toolbar=no\");'>";
9318d2ef
DO
3099 printImageHREF ('find', 'Find object');
3100 echo "</a>";
3101 echo ":<input type='text' name='remoteport' size='4' tabindex=4></td><td></td>";
3102 echo "<td colspan=1><input type='text' name='description' size='20' tabindex=5></td><td>";
f5ff50f5 3103 printImageHREF ('add', 'Add new NAT rule', TRUE, 6);
9318d2ef
DO
3104 echo "</td></tr></form>";
3105 }
e673ee24 3106
94fe6370
DO
3107 $focus = spotEntity ('object', $object_id);
3108 amplifyCell ($focus);
f28fbe8b 3109 echo "<center><h2>locally performed NAT</h2></center>";
e673ee24 3110
105a3bc8 3111 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
d54b9495 3112 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 3113
9318d2ef 3114 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
94fe6370
DO
3115 printNewItemTR ($focus['ipv4']);
3116 foreach ($focus['nat4']['out'] as $pf)
e673ee24 3117 {
2c817354
DO
3118 $class = 'trerror';
3119 $osif = '';
94fe6370 3120 if (isset ($focus['ipv4'][$pf['localip']]))
2c817354 3121 {
94fe6370
DO
3122 $class = $focus['ipv4'][$pf['localip']]['addrinfo']['class'];
3123 $osif = $focus['ipv4'][$pf['localip']]['osif'] . ': ';
2c817354 3124 }
e673ee24
DO
3125
3126 echo "<tr class='$class'>";
4fbb5a00
DY
3127 echo "<td><a href='".
3128 makeHrefProcess(array(
3129 'op'=>'delNATv4Rule',
3130 'localip'=>$pf['localip'],
3131 'localport'=>$pf['localport'],
3132 'remoteip'=>$pf['remoteip'],
3133 'remoteport'=>$pf['remoteport'],
3134 'proto'=>$pf['proto'],
3135 'object_id'=>$object_id)).
3136 "'>";
4de22e7e
DO
3137 printImageHREF ('delete', 'Delete NAT rule');
3138 echo "</a></td>";
4fbb5a00 3139 echo "<td>${pf['proto']}/${osif}<a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['localip']))."'>${pf['localip']}</a>:${pf['localport']}";
59a83bd8 3140 if (strlen ($pf['local_addr_name']))
f28fbe8b
DO
3141 echo ' (' . $pf['local_addr_name'] . ')';
3142 echo "</td>";
4fbb5a00 3143 echo "<td><a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['remoteip']))."'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
e673ee24 3144
53ef3908 3145 $address = getIPv4Address ($pf['remoteip']);
e673ee24
DO
3146
3147 echo "<td class='description'>";
53ef3908
DO
3148 if (count ($address['allocs']))
3149 foreach ($address['allocs'] as $bond)
4fbb5a00 3150 echo "<a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$bond['object_id']))."'>${bond['object_name']}(${bond['name']})</a> ";
59a83bd8 3151 elseif (strlen ($pf['remote_addr_name']))
f28fbe8b 3152 echo '(' . $pf['remote_addr_name'] . ')';
7056988c
DO
3153 printOpFormIntro
3154 (
3155 'updNATv4Rule',
3156 array
3157 (
3158 'localip' => $pf['localip'],
3159 'localport' => $pf['localport'],
3160 'remoteip' => $pf['remoteip'],
3161 'remoteport' => $pf['remoteport'],
3162 'proto' => $pf['proto']
3163 )
3164 );
3165 echo "</td><td class='description'>";
d54b9495
DO
3166 echo "<input type='text' name='description' value='${pf['description']}'></td><td>";
3167 printImageHREF ('save', 'Save changes', TRUE);
3168 echo "</td></form></tr>";
e673ee24 3169 }
9318d2ef 3170 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
94fe6370 3171 printNewItemTR ($focus['ipv4']);
e673ee24
DO
3172
3173 echo "</table><br><br>";
94fe6370
DO
3174 if (!count ($focus['nat4']))
3175 return;
e673ee24 3176
f28fbe8b 3177 echo "<center><h2>arriving NAT connections</h2></center>";
105a3bc8 3178 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
e673ee24
DO
3179 echo "<tr><th></th><th>Source</th><th>Source objects</th><th>Target</th><th>Description</th></tr>\n";
3180
94fe6370 3181 foreach ($focus['nat4']['in'] as $pf)
e673ee24 3182 {
4fbb5a00
DY
3183 echo "<tr><td><a href='".
3184 makeHrefProcess(array(
3185 'op'=>'delNATv4Rule',
3186 'localip'=>$pf['localip'],
3187 'localport'=>$pf['localport'],
3188 'remoteip'=>$pf['remoteip'],
3189 'remoteport'=>$pf['remoteport'],
3190 'proto'=>$pf['proto'],
3191 'object_id'=>$pf['object_id']
3192 )).
3193 "'>";
4de22e7e
DO
3194 printImageHREF ('delete', 'Delete NAT rule');
3195 echo "</a></td>";
4fbb5a00
DY
3196 echo "<td>${pf['proto']}/<a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['localip']))."'>${pf['localip']}</a>:${pf['localport']}</td>";
3197 echo "<td class='description'><a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$pf['object_id']))."'>${pf['object_name']}</a>";
3198 echo "</td><td><a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['remoteip']))."'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
e673ee24
DO
3199 echo "<td class='description'>${pf['description']}</td></tr>";
3200 }
3201
e673ee24 3202 echo "</table><br><br>";
e673ee24
DO
3203}
3204
e673ee24
DO
3205function renderAddMultipleObjectsForm ()
3206{
9b8174d7 3207 global $location_obj_types, $virtual_obj_types;
7fa7047a 3208 $typelist = readChapter (CHAP_OBJTYPE, 'o');
4c330a14 3209 $typelist[0] = 'select type...';
7fa7047a 3210 $typelist = cookOptgroups ($typelist);
a1886a78
DO
3211 $max = getConfigVar ('MASSCOUNT');
3212 $tabindex = 100;
7f791d1d 3213
9b8174d7
AD
3214 // create a list of object types to exclude (virtual and location-related ones)
3215 $exclude_typelist = array_merge($location_obj_types, $virtual_obj_types);
3216
0682218d
AD
3217 $phys_typelist = $typelist;
3218 foreach ($phys_typelist['other'] as $key => $value)
3219 {
9b8174d7
AD
3220 // remove from list if type should be excluded
3221 if ($key > 0 && in_array($key, $exclude_typelist))
0682218d
AD
3222 unset($phys_typelist['other'][$key]);
3223 }
2b787762 3224 startPortlet ('Physical objects');
42d73cbf 3225 printOpFormIntro ('addObjects');
e673ee24 3226 echo '<table border=0 align=center>';
f60bb422 3227 echo "<tr><th>Object type</th><th>Common name</th><th>Visible label</th>";
dee24af6 3228 echo "<th>Asset tag</th><th>Tags</th></tr>\n";
9c0b0016 3229 for ($i = 0; $i < $max; $i++)
e673ee24 3230 {
7f791d1d 3231 echo '<tr><td>';
e7ade6bf 3232 // Don't employ DEFAULT_OBJECT_TYPE to avoid creating ghost records for pre-selected empty rows.
0682218d 3233 printNiftySelect ($phys_typelist, array ('name' => "${i}_object_type_id", 'tabindex' => $tabindex), 0);
e673ee24 3234 echo '</td>';
a1886a78
DO
3235 echo "<td><input type=text size=30 name=${i}_object_name tabindex=${tabindex}></td>";
3236 echo "<td><input type=text size=30 name=${i}_object_label tabindex=${tabindex}></td>";
3237 echo "<td><input type=text size=20 name=${i}_object_asset_no tabindex=${tabindex}></td>";
f60bb422
DO
3238 if ($i == 0)
3239 {
3240 echo "<td valign=top rowspan=${max}>";
a26a6ccc 3241 renderNewEntityTags ('object');
f60bb422
DO
3242 echo "</td>\n";
3243 }
e673ee24 3244 echo "</tr>\n";
a1886a78 3245 $tabindex++;
e673ee24 3246 }
216c84bb 3247 echo "<tr><td class=submit colspan=5><input type=submit name=got_fast_data value='Go!'></td></tr>\n";
e673ee24
DO
3248 echo "</form></table>\n";
3249 finishPortlet();
7f791d1d 3250
0682218d 3251 // create a list containing only virtual object types
0682218d
AD
3252 $virt_typelist = $typelist;
3253 foreach ($virt_typelist['other'] as $key => $value)
3254 {
2c2ea5f6 3255 if ($key > 0 && !in_array($key, $virtual_obj_types))
0682218d
AD
3256 unset($virt_typelist['other'][$key]);
3257 }
3258 startPortlet ('Virtual objects');
3259 printOpFormIntro ('addObjects');
3260 echo "<input type=hidden name=virtual_objects value=''>\n";
3261 echo '<table border=0 align=center>';
3262 echo "<tr><th>Object type</th><th>Common name</th><th>Tags</th></tr>\n";
3263 for ($i = 0; $i < $max; $i++)
3264 {
3265 echo '<tr><td>';
3266 // Don't employ DEFAULT_OBJECT_TYPE to avoid creating ghost records for pre-selected empty rows.
3267 printNiftySelect ($virt_typelist, array ('name' => "${i}_object_type_id", 'tabindex' => $tabindex), 0);
3268 echo '</td>';
3269 echo "<td><input type=text size=30 name=${i}_object_name tabindex=${tabindex}></td>";
3270 if ($i == 0)