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