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