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