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