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