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