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