r2469 - getVServiceInfo(): include 'id' in returned data
[racktables] / inc / interface.php
CommitLineData
b325120a 1<?php
e673ee24
DO
2/*
3*
4* This file contains frontend functions for RackTables.
5*
6*/
7
9c0b0016
DO
8// Interface function's special.
9$nextorder['odd'] = 'even';
10$nextorder['even'] = 'odd';
11
52c836b1
DO
12// address allocation type
13$aat = array
14(
15 'regular' => 'Connected',
16 'virtual' => 'Loopback',
17 'shared' => 'Shared',
18 'router' => 'Router',
19);
beb9e88a 20// address allocation code, IPv4 addresses and objects view
52c836b1
DO
21$aac = array
22(
23 'regular' => '',
24 'virtual' => '<strong>L</strong>',
25 'shared' => '<strong>S</strong>',
26 'router' => '<strong>R</strong>',
27);
beb9e88a
DO
28// address allocation code, IPv4 networks view
29$aac2 = array
30(
31 'regular' => '',
32 'virtual' => '<strong>L:</strong>',
29025f8e 33 'shared' => '<strong>S:</strong>',
beb9e88a
DO
34 'router' => '<strong>R:</strong>',
35);
52c836b1 36
7056988c
DO
37// Let's have it here, so extensions can add their own images.
38$image = array();
39$image['error']['path'] = 'pix/error.png';
40$image['error']['width'] = 76;
41$image['error']['height'] = 17;
42$image['logo']['path'] = 'pix/defaultlogo.png';
43$image['logo']['width'] = 210;
44$image['logo']['height'] = 40;
45$image['rackspace']['path'] = 'pix/racks.png';
46$image['rackspace']['width'] = 218;
47$image['rackspace']['height'] = 200;
48$image['objects']['path'] = 'pix/server.png';
49$image['objects']['width'] = 218;
50$image['objects']['height'] = 200;
e1ae3fb4
AD
51$image['files']['path'] = 'pix/files.png';
52$image['files']['width'] = 218;
53$image['files']['height'] = 200;
7056988c
DO
54$image['ipv4space']['path'] = 'pix/addressspace.png';
55$image['ipv4space']['width'] = 218;
56$image['ipv4space']['height'] = 200;
57$image['ipv4slb']['path'] = 'pix/slb.png';
58$image['ipv4slb']['width'] = 218;
59$image['ipv4slb']['height'] = 200;
60$image['config']['path'] = 'pix/configuration.png';
61$image['config']['width'] = 218;
62$image['config']['height'] = 200;
63$image['reports']['path'] = 'pix/report.png';
64$image['reports']['width'] = 218;
65$image['reports']['height'] = 200;
e1ae3fb4
AD
66$image['download']['path'] = 'pix/download.png';
67$image['download']['width'] = 16;
68$image['download']['height'] = 16;
08cd1902
AD
69$image['DOWNLOAD']['path'] = 'pix/download-big.png';
70$image['DOWNLOAD']['width'] = 32;
71$image['DOWNLOAD']['height'] = 32;
5ccd99a0
DO
72$image['plug']['path'] = 'pix/tango-network-wired.png';
73$image['plug']['width'] = 16;
74$image['plug']['height'] = 16;
75$image['cut']['path'] = 'pix/tango-edit-cut-16x16.png';
76$image['cut']['width'] = 16;
77$image['cut']['height'] = 16;
78$image['CUT']['path'] = 'pix/tango-edit-cut-32x32.png';
79$image['CUT']['width'] = 32;
80$image['CUT']['height'] = 32;
7056988c
DO
81$image['add']['path'] = 'pix/tango-list-add.png';
82$image['add']['width'] = 16;
83$image['add']['height'] = 16;
a685a26a
DO
84$image['ADD']['path'] = 'pix/tango-list-add-big.png';
85$image['ADD']['width'] = 32;
86$image['ADD']['height'] = 32;
7056988c
DO
87$image['delete']['path'] = 'pix/tango-list-remove.png';
88$image['delete']['width'] = 16;
89$image['delete']['height'] = 16;
d3c27c5c 90$image['destroy']['path'] = 'pix/tango-user-trash-16x16.png';
1bdc2bfc
DO
91$image['destroy']['width'] = 16;
92$image['destroy']['height'] = 16;
d3c27c5c 93$image['nodestroy']['path'] = 'pix/tango-user-trash-16x16-gray.png';
1bdc2bfc
DO
94$image['nodestroy']['width'] = 16;
95$image['nodestroy']['height'] = 16;
d3c27c5c 96$image['DESTROY']['path'] = 'pix/tango-user-trash-32x32.png';
97b1f33b
DO
97$image['DESTROY']['width'] = 32;
98$image['DESTROY']['height'] = 32;
7056988c
DO
99$image['nodelete']['path'] = 'pix/tango-list-remove-shadow.png';
100$image['nodelete']['width'] = 16;
101$image['nodelete']['height'] = 16;
7056988c
DO
102$image['inservice']['path'] = 'pix/tango-emblem-system.png';
103$image['inservice']['width'] = 16;
104$image['inservice']['height'] = 16;
105$image['notinservice']['path'] = 'pix/tango-dialog-error.png';
106$image['notinservice']['width'] = 16;
107$image['notinservice']['height'] = 16;
7056988c
DO
108$image['find']['path'] = 'pix/tango-system-search.png';
109$image['find']['width'] = 16;
110$image['find']['height'] = 16;
7056988c
DO
111$image['next']['path'] = 'pix/tango-go-next.png';
112$image['next']['width'] = 32;
113$image['next']['height'] = 32;
114$image['prev']['path'] = 'pix/tango-go-previous.png';
115$image['prev']['width'] = 32;
116$image['prev']['height'] = 32;
117$image['clear']['path'] = 'pix/tango-edit-clear.png';
118$image['clear']['width'] = 16;
119$image['clear']['height'] = 16;
61a61189
DO
120$image['CLEAR']['path'] = 'pix/tango-edit-clear-big.png';
121$image['CLEAR']['width'] = 32;
122$image['CLEAR']['height'] = 32;
7056988c
DO
123$image['save']['path'] = 'pix/tango-document-save.png';
124$image['save']['width'] = 16;
125$image['save']['height'] = 16;
126$image['SAVE']['path'] = 'pix/tango-document-save-big.png';
127$image['SAVE']['width'] = 32;
128$image['SAVE']['height'] = 32;
129$image['create']['path'] = 'pix/tango-document-new.png';
130$image['create']['width'] = 16;
131$image['create']['height'] = 16;
132$image['CREATE']['path'] = 'pix/tango-document-new-big.png';
133$image['CREATE']['width'] = 32;
134$image['CREATE']['height'] = 32;
135$image['DENIED']['path'] = 'pix/tango-dialog-error-big.png';
136$image['DENIED']['width'] = 32;
137$image['DENIED']['height'] = 32;
d28d7f4d
DO
138$image['apply']['path'] = 'pix/tango-emblem-system.png';
139$image['apply']['width'] = 16;
140$image['apply']['height'] = 16;
737a3f72
DO
141$image['node-collapsed']['path'] = 'pix/node-collapsed.png';
142$image['node-collapsed']['width'] = 16;
143$image['node-collapsed']['height'] = 16;
144$image['node-expanded']['path'] = 'pix/node-expanded.png';
145$image['node-expanded']['width'] = 16;
146$image['node-expanded']['height'] = 16;
fec0c8da
DO
147$image['node-expanded-static']['path'] = 'pix/node-expanded-static.png';
148$image['node-expanded-static']['width'] = 16;
149$image['node-expanded-static']['height'] = 16;
09620506
DO
150$image['dragons']['path'] = 'pix/mitsudragon.png';
151$image['dragons']['width'] = 125;
152$image['dragons']['height'] = 21;
b1a970c7
DO
153$image['LB']['path'] = 'pix/loadbalancer.png';
154$image['LB']['width'] = 32;
155$image['LB']['height'] = 32;
156$image['RS pool']['path'] = 'pix/serverpool.png';
157$image['RS pool']['width'] = 48;
158$image['RS pool']['height'] = 16;
159$image['VS']['path'] = 'pix/servicesign.png';
160$image['VS']['width'] = 39;
161$image['VS']['height'] = 62;
8b3874a5
DO
162$image['router']['path'] = 'pix/router.png';
163$image['router']['width'] = 32;
164$image['router']['height'] = 32;
0b9c98d7
DO
165$image['ATTACH']['path'] = 'pix/crystal-attach-32x32.png';
166$image['ATTACH']['width'] = 32;
167$image['ATTACH']['height'] = 32;
7a0f5847
DO
168$image['favorite']['path'] = 'pix/tango-emblem-favorite.png';
169$image['favorite']['width'] = 16;
170$image['favorite']['height'] = 16;
4f12d88f
DO
171$image['computer']['path'] = 'pix/tango-computer.png';
172$image['computer']['width'] = 16;
173$image['computer']['height'] = 16;
0b9c98d7
DO
174$image['empty file']['path'] = 'pix/crystal-file-empty-32x32.png';
175$image['empty file']['width'] = 32;
176$image['empty file']['height'] = 32;
177$image['text file']['path'] = 'pix/crystal-file-text-32x32.png';
178$image['text file']['width'] = 32;
179$image['text file']['height'] = 32;
180$image['image file']['path'] = 'pix/crystal-file-image-32x32.png';
181$image['image file']['width'] = 32;
182$image['image file']['height'] = 32;
183$image['NET']['path'] = 'pix/crystal-network-32x32.png';
184$image['NET']['width'] = 32;
185$image['NET']['height'] = 32;
19dac9c3
DO
186$image['USER']['path'] = 'pix/crystal-edit-user-32x32.png';
187$image['USER']['width'] = 32;
188$image['USER']['height'] = 32;
7056988c 189
e5c4506d
DO
190// This may be populated later onsite, report rendering function will use it.
191// See the $systemreport for structure.
192$localreports = array();
9db67d95
DO
193$CodePressMap = array
194(
195 'sql' => 'sql',
196 'php' => 'php',
197 'html' => 'html',
198 'css' => 'css',
199 'js' => 'javascript',
200);
e5c4506d 201
e673ee24
DO
202// Main menu.
203function renderIndex ()
204{
205 global $root;
206?>
207<table border=0 cellpadding=0 cellspacing=0 width='100%'>
208 <tr>
209 <td>
210 <div style='text-align: center; margin: 10px; '>
211 <table width='100%' cellspacing=0 cellpadding=30 class=mainmenu border=0>
212 <tr>
213 <td>
4fbb5a00 214 <h1><a href='<?php echo makeHref(array('page'=>'rackspace')) ?>'>Rackspace<br>
b325120a 215 <?php printImageHREF ('rackspace'); ?></a></h1>
e673ee24
DO
216 </td>
217 <td>
4fbb5a00 218 <h1><a href='<?php echo makeHref(array('page'=>'objects')) ?>'>Objects<br>
b325120a 219 <?php printImageHREF ('objects'); ?></a></h1>
e673ee24 220 </td>
e673ee24 221 <td>
4fbb5a00 222 <h1><a href='<?php echo makeHref(array('page'=>'ipv4space')) ?>'>IPv4 space<br>
e1ae3fb4 223 <?php printImageHREF ('ipv4space'); ?></a></h1>
e673ee24
DO
224 </td>
225 <td>
4fbb5a00 226 <h1><a href='<?php echo makeHref(array('page'=>'files')) ?>'>Files<br>
e1ae3fb4 227 <?php printImageHREF ('files'); ?></a></h1>
e673ee24 228 </td>
e1ae3fb4 229 </tr>
e1ae3fb4 230 <tr>
ae545907 231 <td>
4fbb5a00 232 <h1><a href='<?php echo makeHref(array('page'=>'config')) ?>'>Configuration<br>
f4d879a9 233 <?php printImageHREF ('config'); ?></a></h1>
ae545907 234 </td>
e1ae3fb4 235 <td>
4fbb5a00 236 <h1><a href='<?php echo makeHref(array('page'=>'reports')) ?>'>Reports<br>
f4d879a9 237 <?php printImageHREF ('reports'); ?></a></h1>
e1ae3fb4
AD
238 </td>
239 <td>
4fbb5a00 240 <h1><a href='<?php echo makeHref(array('page'=>'ipv4slb')) ?>'>IPv4 SLB<br>
f4d879a9 241 <?php printImageHREF ('ipv4slb'); ?></a></h1>
e1ae3fb4 242 </td>
f4d879a9 243 <td>&nbsp;</td>
e673ee24
DO
244 </tr>
245 </table>
246 </div>
247 </td>
248 </tr>
249</table>
b325120a 250<?php
e673ee24
DO
251}
252
253function renderRackspace ()
254{
932cf41f 255 $tagfilter = getTagFilter();
094a8e6e 256 $tagfilter_str = getTagFilterStr ($tagfilter);
c8187437 257 showMessageOrError();
489a7502
DO
258 echo "<table class=objview border=0 width='100%'><tr><td class=pcleft>";
259 renderTagFilterPortlet ($tagfilter, 'rack');
260 echo '</td><td class=pcright>';
261 echo '<table border=0 cellpadding=10 cellpadding=1>';
e673ee24 262 // generate thumb gallery
489a7502 263 $rackrowList = getRackspace ($tagfilter);
4fbb5a00 264 global $nextorder;
d5157018 265 $rackwidth = getRackImageWidth();
e673ee24
DO
266 $order = 'odd';
267 foreach ($rackrowList as $rackrow)
268 {
84466afa 269 echo "<tr class=row_${order}><th class=tdleft>";
4fbb5a00 270 echo "<a href='".makeHref(array('page'=>'row', 'row_id'=>$rackrow['row_id']))."${tagfilter_str}'>";
a0d54e7e
DO
271 echo "${rackrow['row_name']}</a></th>";
272 $rackList = getRacksForRow ($rackrow['row_id'], $tagfilter);
e673ee24 273 echo "<td><table border=0 cellspacing=5><tr>";
64b95774 274 foreach ($rackList as $rack)
e673ee24 275 {
4fbb5a00 276 echo "<td align=center><a href='".makeHref(array('page'=>'rack', 'rack_id'=>$rack['id']))."'>";
e673ee24 277 echo "<img border=0 width=${rackwidth} height=";
d5157018 278 echo getRackImageHeight ($rack['height']);
e673ee24 279 echo " title='${rack['height']} units'";
d2ec5490 280 echo "src='render_image.php?img=minirack&rack_id=${rack['id']}'>";
e673ee24
DO
281 echo "<br>${rack['name']}</a></td>";
282 }
283 echo "</tr></table></tr>\n";
284 $order = $nextorder[$order];
285 }
286 echo "</table>\n";
489a7502 287 echo "</td></tr></table>\n";
e673ee24
DO
288}
289
345fd640
AD
290function renderRackspaceRowEditor ()
291{
292 function printNewItemTR ()
293 {
294 printOpFormIntro ('addRow');
295 echo "<tr><td><input type=text name=name tabindex=100></td><td>";
296 printImageHREF ('create', 'Add new row', TRUE, 101);
9f14a7ef 297 echo "</td><td></td></tr></form>";
345fd640 298 }
4fbb5a00 299 global $pageno, $tabno;
345fd640
AD
300 startPortlet ('Rows');
301 showMessageOrError();
302 echo "<table border=0 cellspacing=0 cellpadding=5 align=center class=widetable>\n";
303 echo "<tr><th>Name</th></tr>\n";
304 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
305 printNewItemTR();
306 $rackrowList = getRackspace ();
307 foreach ($rackrowList as $rackrow)
308 {
309 printOpFormIntro ('updateRow', array ('row_id' => $rackrow['row_id']));
310 echo "<tr><td><input type=text name=name value='${rackrow['row_name']}'></td><td>";
311 printImageHREF ('save', 'Save changes', TRUE);
5af82683
DY
312 echo "</td></form><td>";
313 if ($rackrow['count'] == 0)
314 {
315 echo "<a href=\"".makeHrefProcess(array('op'=>'delete', 'row_id'=>$rackrow['row_id'], 'name'=>$rackrow['row_name']))."\">";
316 printImageHREF ('delete', 'Delete row');
317 echo "</a>";
318 }
319 echo "</td></tr>\n";
345fd640
AD
320 }
321 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
322 printNewItemTR();
323 echo "</table><br>\n";
324 finishPortlet();
325}
326
d5157018 327function renderRow ($row_id = 0)
e673ee24
DO
328{
329 if ($row_id == 0)
330 {
39a6338a 331 showError ('Invalid row_id', __FUNCTION__);
e673ee24
DO
332 return;
333 }
334 if (($rowInfo = getRackRowInfo ($row_id)) == NULL)
335 {
39a6338a 336 showError ('getRackRowInfo() failed', __FUNCTION__);
e673ee24
DO
337 return;
338 }
a0d54e7e
DO
339 $tagfilter = getTagFilter();
340 $rackList = getRacksForRow ($row_id, $tagfilter);
e673ee24
DO
341 // Main layout starts.
342 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
343
344 // Left portlet with row information.
345 echo "<tr><td class=pcleft>";
a8ce7234 346 startPortlet ($rowInfo['name']);
e673ee24 347 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
5af82683
DY
348 echo "<tr><th width='50%' class=tdright>Racks:</th><td class=tdleft>${rowInfo['count']}</td></tr>\n";
349 echo "<tr><th width='50%' class=tdright>Units:</th><td class=tdleft>${rowInfo['sum']}</td></tr>\n";
04d619d0 350 echo "<tr><th width='50%' class=tdright>%% used:</th><td class=tdleft>";
114e50af
DO
351 renderProgressBar (getRSUforRackRow ($rackList));
352 echo "</td></tr>\n";
e673ee24
DO
353 echo "</table><br>\n";
354 finishPortlet();
355
a0d54e7e 356 echo "</td><td class=pcright rowspan=2>";
e673ee24 357
4fbb5a00 358 global $nextorder;
d5157018 359 $rackwidth = getRackImageWidth() * getConfigVar ('ROW_SCALE');
e673ee24
DO
360 $order = 'odd';
361 startPortlet ('Racks');
362 echo "<table border=0 cellspacing=5 align='center'><tr>";
64b95774 363 foreach ($rackList as $rack)
e673ee24 364 {
4fbb5a00 365 echo "<td align=center class=row_${order}><a href='".makeHref(array('page'=>'rack', 'rack_id'=>$rack['id']))."'>";
d5157018 366 echo "<img border=0 width=${rackwidth} height=" . (getRackImageHeight ($rack['height']) * getConfigVar ('ROW_SCALE'));
e673ee24 367 echo " title='${rack['height']} units'";
d2ec5490 368 echo "src='render_image.php?img=minirack&rack_id=${rack['id']}'>";
e673ee24
DO
369 echo "<br>${rack['name']}</a></td>";
370 $order = $nextorder[$order];
371 }
372 echo "</tr></table>\n";
373 finishPortlet();
a0d54e7e 374 echo "</td></tr>";
e673ee24 375
a0d54e7e
DO
376 echo "<tr><td class=pcleft>";
377 renderTagFilterPortlet ($tagfilter, 'rack', 'row_id', $row_id);
e673ee24
DO
378 echo "</td></tr></table>";
379}
380
04f110a0 381function showError ($info = '', $location = 'N/A')
e673ee24 382{
04f110a0
DO
383 if (preg_match ('/\.php$/', $location))
384 $location = basename ($location);
385 elseif ($location != 'N/A')
386 $location = $location . '()';
387 echo "<div class=msg_error>An error has occured in [${location}]. ";
e673ee24
DO
388 if (empty ($info))
389 echo 'No additional information is available.';
390 else
391 echo "Additional information:<br><p>\n<pre>\n${info}\n</pre></p>";
4fbb5a00 392 echo "Go back or try starting from <a href='".makeHref()."'>index page</a>.<br></div>\n";
e673ee24
DO
393}
394
395// This function renders rack as HTML table.
396function renderRack ($rack_id = 0, $hl_obj_id = 0)
397{
398 if ($rack_id == 0)
399 {
39a6338a 400 showError ('Invalid rack_id', __FUNCTION__);
e673ee24
DO
401 return;
402 }
403 if (($rackData = getRackData ($rack_id)) == NULL)
404 {
39a6338a 405 showError ('getRackData() failed', __FUNCTION__);
e673ee24
DO
406 return;
407 }
4fbb5a00 408 global $pageno, $tabno;
e673ee24
DO
409 markAllSpans ($rackData);
410 if ($hl_obj_id > 0)
411 highlightObject ($rackData, $hl_obj_id);
412 markupObjectProblems ($rackData);
413 $prev_id = getPrevIDforRack ($rackData['row_id'], $rack_id);
414 $next_id = getNextIDforRack ($rackData['row_id'], $rack_id);
d48d8820 415 echo "<center><table border=0><tr valign=middle>";
4fbb5a00 416 echo "<td><h2><a href='".makeHref(array('page'=>'row', 'row_id'=>$rackData['row_id']))."'>${rackData['row_name']}</a> :</h2></td>";
e673ee24
DO
417 // FIXME: use 'bypass'?
418 if ($prev_id != NULL)
9803c56c 419 {
4fbb5a00 420 echo "<td><a href='".makeHref(array('page'=>'rack', 'rack_id'=>$prev_id))."'>";
9803c56c 421 printImageHREF ('prev', 'previous rack');
d48d8820 422 echo "</a></td>";
9803c56c 423 }
4fbb5a00 424 echo "<td><h2><a href='".makeHref(array('page'=>'rack', 'rack_id'=>$rackData['id']))."'>${rackData['name']}</a></h2></td>";
e673ee24 425 if ($next_id != NULL)
9803c56c 426 {
4fbb5a00 427 echo "<td><a href='".makeHref(array('page'=>'rack', 'rack_id'=>$next_id))."'>";
f444c095 428 printImageHREF ('next', 'next rack');
d48d8820 429 echo "</a></td>";
9803c56c 430 }
d48d8820 431 echo "</h2></td></tr></table>\n";
e673ee24 432 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
d08147d6
DO
433 echo "<tr><th width='10%'>&nbsp;</th><th width='20%'>Front</th>";
434 echo "<th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
e673ee24
DO
435 for ($i = $rackData['height']; $i > 0; $i--)
436 {
d08147d6 437 echo "<tr><th>${i}</th>";
e673ee24
DO
438 for ($locidx = 0; $locidx < 3; $locidx++)
439 {
440 if (isset ($rackData[$i][$locidx]['skipped']))
441 continue;
442 $state = $rackData[$i][$locidx]['state'];
443 echo "<td class=state_${state}";
444 if (isset ($rackData[$i][$locidx]['hl']))
445 echo $rackData[$i][$locidx]['hl'];
446 if (isset ($rackData[$i][$locidx]['colspan']))
447 echo ' colspan=' . $rackData[$i][$locidx]['colspan'];
448 if (isset ($rackData[$i][$locidx]['rowspan']))
449 echo ' rowspan=' . $rackData[$i][$locidx]['rowspan'];
450 echo ">";
451 switch ($state)
452 {
453 case 'T':
454 $objectData = getObjectInfo ($rackData[$i][$locidx]['object_id']);
455 if (!empty ($objectData['asset_no']))
456 $prefix = "<div title='${objectData['asset_no']}";
457 else
458 $prefix = "<div title='no asset tag";
459 // Don't tell about label, if it matches common name.
460 if ($objectData['name'] != $objectData['label'] and !empty ($objectData['label']))
461 $suffix = ", visible label is \"${objectData['label']}\"'>";
462 else
463 $suffix = "'>";
464 echo $prefix . $suffix;
4fbb5a00 465 echo "<a href='".makeHref(array('page'=>'object', 'object_id'=>$objectData['id']))."'>${objectData['dname']}</a></div>";
e673ee24
DO
466 break;
467 case 'A':
468 echo '<div title="This rackspace does not exist">&nbsp;</div>';
469 break;
470 case 'F':
471 echo '<div title="Free rackspace">&nbsp;</div>';
472 break;
473 case 'U':
474 echo '<div title="Problematic rackspace, you CAN\'T mount here">&nbsp;</div>';
475 break;
476 default:
477 echo '<div title="No data">&nbsp;</div>';
478 break;
479 }
480 echo '</td>';
481 }
482 echo "</tr>\n";
483 }
484 echo "</table></center>\n";
485}
486
e673ee24
DO
487function renderNewRackForm ($row_id)
488{
f19c75d6 489 showMessageOrError();
f19c75d6 490
50b4ba85 491 startPortlet ('Add one');
f19c75d6 492 printOpFormIntro ('addRack', array ('got_data' => 'TRUE'));
e673ee24 493 echo '<table border=0 align=center>';
b901bf1f
DO
494 $defh = getConfigVar ('DEFAULT_RACK_HEIGHT');
495 if ($defh == 0)
496 $defh = '';
72d52730
DO
497 echo "<tr><th class=tdright>Rack name (*):</th><td class=tdleft><input type=text name=rack_name tabindex=1></td>";
498 echo "<td rowspan=4>Assign tags:<br>";
499 renderTagSelect();
500 echo "</td></tr>\n";
b8094ae4 501 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 502 echo "<tr><th class=tdright>Comment:</th><td class=tdleft><input type=text name=rack_comment tabindex=3></td></tr>\n";
f19c75d6
DO
503 echo "<tr><td class=submit colspan=2>";
504 printImageHREF ('CREATE', 'Add', TRUE);
505 echo "</td></tr></table></form>";
406b54bd 506 finishPortlet();
406b54bd 507
50b4ba85 508 startPortlet ('Add many');
f19c75d6 509 printOpFormIntro ('addRack', array ('got_mdata' => 'TRUE'));
50b4ba85
DO
510 echo '<table border=0 align=center>';
511 $defh = getConfigVar ('DEFAULT_RACK_HEIGHT');
512 if ($defh == 0)
513 $defh = '';
72d52730
DO
514 echo "<tr><th class=tdright>Height in units (*):</th><td class=tdleft><input type=text name=rack_height2 value='${defh}'></td>";
515 echo "<td rowspan=3 valign=top>Assign tags:<br>";
516 renderTagSelect();
517 echo "</td></tr>\n";
50b4ba85 518 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
519 echo "<tr><td class=submit colspan=2>";
520 printImageHREF ('CREATE', 'Add', TRUE);
e673ee24
DO
521 echo '</form></table>';
522 finishPortlet();
523}
524
525function renderEditObjectForm ($object_id)
526{
527 showMessageOrError();
e673ee24 528
4fbb5a00 529 global $pageno, $tabno;
e673ee24
DO
530 $object = getObjectInfo ($object_id);
531 if ($object == NULL)
532 {
39a6338a 533 showError ('getObjectInfo() failed', __FUNCTION__);
e673ee24
DO
534 return;
535 }
cdd3efe9 536 startPortlet ();
43fb6eaf 537 printOpFormIntro ('update');
cdd3efe9
AD
538 echo '<table border=0 width=100%><tr><td class=pcleft>';
539
540 // static attributes
e673ee24 541 echo '<table border=0 align=center>';
cdd3efe9 542 echo "<tr><th colspan=2><h2>Static attributes</h2></th></tr>";
e673ee24
DO
543 echo "<tr><th class=tdright>Type:</th><td class=tdleft>";
544 printSelect (getObjectTypeList(), 'object_type_id', $object['objtype_id']);
545 echo "</td></tr>\n";
22bb04da 546 // baseline info
e673ee24
DO
547 echo "<tr><th class=tdright>Common name:</th><td class=tdleft><input type=text name=object_name value='${object['name']}'></td></tr>\n";
548 echo "<tr><th class=tdright>Visible label:</th><td class=tdleft><input type=text name=object_label value='${object['label']}'></td></tr>\n";
549 echo "<tr><th class=tdright>Asset tag:</th><td class=tdleft><input type=text name=object_asset_no value='${object['asset_no']}'></td></tr>\n";
f76c4197
DY
550 echo "<tr><th class=tdright>Barcode:</th><td class=tdleft><input type=text name=object_barcode value='${object['barcode']}'></td></tr>\n";
551 echo "<tr><th class=tdright>Has problems:</th><td class=tdleft><input type=checkbox name=object_has_problems";
e673ee24
DO
552 if ($object['has_problems'] == 'yes')
553 echo ' checked';
f76c4197 554 echo "></td></tr>\n";
4fbb5a00
DY
555 echo "<tr><th class=tdright>Actions:</th><td class=tdleft><a href='".
556 makeHrefProcess(array('op'=>'deleteObject', 'page'=>'objects', 'tab'=>'default', 'object_id'=>$object_id, 'name'=>$object['name'])).
557 "' onclick=\"javascript:return confirm('Are you sure you want to delete the object?')\">Delete object</a></td></tr>\n";
e673ee24 558 echo "<tr><td colspan=2><b>Comment:</b><br><textarea name=object_comment rows=10 cols=80>${object['comment']}</textarea></td></tr>";
cdd3efe9
AD
559 echo '</table>';
560
561 echo '</td><td class=pcright>';
e673ee24 562
cdd3efe9 563 // optional attributes
e673ee24 564 $values = getAttrValues ($object_id);
2b98d5a2 565 if (count($values) > 0)
e673ee24 566 {
2b98d5a2
AD
567 echo "<table border=0 cellspacing=0 cellpadding=5 align=center class=widetable>\n";
568 echo "<tr><th colspan=3><h2>Optional attributes</h2></th></tr>";
569 echo "<tr><th>&nbsp;</th><th>Attribute</th><th>Value</th></tr>\n";
570 echo '<input type=hidden name=num_attrs value=' . count($values) . ">\n";
571 $i = 0;
572 foreach ($values as $record)
e673ee24 573 {
2b98d5a2
AD
574 echo "<input type=hidden name=${i}_attr_id value=${record['id']}>";
575 echo '<tr><td>';
576 if (!empty ($record['value']))
577 {
4fbb5a00 578 echo "<a href='".makeHrefProcess(array('op'=>'clearSticker', 'object_id'=>$object_id, 'attr_id'=>$record['id']))."'>";
2b98d5a2
AD
579 printImageHREF ('clear', 'Clear value');
580 echo '</a>';
581 }
582 else
583 echo '&nbsp;';
584 echo '</td>';
585 echo "<td class=tdright>${record['name']}:</td><td class=tdleft>";
586 switch ($record['type'])
587 {
588 case 'uint':
589 case 'float':
590 case 'string':
591 echo "<input type=text name=${i}_value value='${record['value']}'>";
592 break;
593 case 'dict':
594 $chapter = readChapter ($record['chapter_name']);
595 $chapter[0] = '-- NOT SET --';
596 printSelect ($chapter, "${i}_value", $record['key']);
597 break;
598 }
599 echo "</td></tr>\n";
600 $i++;
e673ee24 601 }
2b98d5a2 602 echo "</table>";
e673ee24 603 }
2b98d5a2 604 echo "</td></tr>\n";
cdd3efe9
AD
605
606 echo "<tr><th class=submit colspan=2>";
5bbbeaa2 607 printImageHREF ('SAVE', 'Save changes', TRUE);
cdd3efe9 608 echo "</form></th></tr></table>\n";
e673ee24 609 finishPortlet();
e673ee24 610
cdd3efe9 611 echo '<table border=0 width=100%><tr><td>';
e673ee24
DO
612 startPortlet ('history');
613 renderHistory ($pageno, $object_id);
614 finishPortlet();
cdd3efe9 615 echo '</td></tr></table>';
e673ee24
DO
616}
617
618// This is a clone of renderEditObjectForm().
619function renderEditRackForm ($rack_id)
620{
0c2b7c4a
DO
621 showMessageOrError();
622 global $pageno;
e673ee24
DO
623 $rack = getRackData ($rack_id);
624 if ($rack == NULL)
625 {
39a6338a 626 showError ('getRackData() failed', __FUNCTION__);
e673ee24
DO
627 return;
628 }
629
e673ee24 630 startPortlet ('Rack attributes');
7056988c 631 printOpFormIntro ('updateRack');
e673ee24
DO
632 echo '<table border=0 align=center>';
633 echo "<tr><th class=tdright>Rack row:</th><td class=tdleft>";
4fbb5a00 634 printSelect (getRackRows(), 'rack_row_id', $rack['row_id']);
e673ee24
DO
635 echo "</td></tr>\n";
636 echo "<tr><th class=tdright>Name (required):</th><td class=tdleft><input type=text name=rack_name value='${rack['name']}'></td></tr>\n";
637 echo "<tr><th class=tdright>Height (required):</th><td class=tdleft><input type=text name=rack_height value='${rack['height']}'></td></tr>\n";
638 echo "<tr><th class=tdright>Comment:</th><td class=tdleft><input type=text name=rack_comment value='${rack['comment']}'></td></tr>\n";
c8187437
DY
639 if (count ($rack['mountedObjects']) == 0)
640 {
641 echo "<tr><th class=tdright>Actions:</th><td class=tdleft><a href='".
642 makeHrefProcess(array('op'=>'deleteRack', 'rack_id'=>$rack_id)).
643 "' onclick=\"javascript:return confirm('Are you sure you want to delete the rack?')\">Delete rack</a></td></tr>\n";
644 }
7056988c
DO
645 echo "<tr><td class=submit colspan=2>";
646 printImageHREF ('SAVE', 'Save changes', TRUE);
647 echo "</td></tr>\n";
e673ee24
DO
648 echo '</form></table><br>';
649 finishPortlet();
650
651 startPortlet ('History');
652 renderHistory ($pageno, $rack_id);
653 finishPortlet();
654}
655
656// This is a helper for creators and editors.
a65f9f54 657function printSelect ($rowList, $select_name, $selected_id = NULL, $tabindex = NULL)
e673ee24 658{
9e7f32a7
DO
659 // First collect all data for OPTGROUPs, then ouput it and dump
660 // the rest of records as is.
661 $optgroup = array();
662 $other = array();
4c330a14 663 foreach ($rowList as $dict_key => $dict_value)
e673ee24 664 {
f0b540a3 665 if (strpos ($dict_value, '%GSKIP%') !== FALSE)
9e7f32a7 666 {
f0b540a3 667 $tmp = explode ('%GSKIP%', $dict_value, 2);
9e7f32a7
DO
668 $optgroup[$tmp[0]][$dict_key] = $tmp[1];
669 }
f0b540a3 670 elseif (strpos ($dict_value, '%GPASS%') !== FALSE)
2613bc1c 671 {
f0b540a3 672 $tmp = explode ('%GPASS%', $dict_value, 2);
2613bc1c
DO
673 $optgroup[$tmp[0]][$dict_key] = $tmp[1];
674 }
9e7f32a7
DO
675 else
676 $other[$dict_key] = $dict_value;
677 }
a65f9f54 678 echo "<select name=${select_name}" . ($tabindex ? " tabindex=${tabindex}" : '') . '>';
9e7f32a7
DO
679 if (!count ($optgroup))
680 {
681 foreach ($other as $dict_key => $dict_value)
682 {
683 echo "<option value=${dict_key}";
0b9b1063 684 if ($dict_key == $selected_id)
9e7f32a7
DO
685 echo ' selected';
686 echo ">${dict_value}</option>";
687 }
688 }
689 else
690 {
691 foreach ($optgroup as $groupname => $groupdata)
692 {
693 echo "<optgroup label='${groupname}'>";
694 foreach ($groupdata as $dict_key => $dict_value)
695 {
696 echo "<option value=${dict_key}";
0b9b1063 697 if ($dict_key == $selected_id)
9e7f32a7
DO
698 echo ' selected';
699 echo ">${dict_value}</option>";
700 }
701 echo "</optgroup>\n";
702 }
703 if (count ($other))
704 {
705 echo "<optgroup label='other'>\n";
706 foreach ($other as $dict_key => $dict_value)
707 {
708 echo "<option value=${dict_key}";
0b9b1063 709 if ($dict_key == $selected_id)
9e7f32a7
DO
710 echo ' selected';
711 echo ">${dict_value}</option>";
712 }
713 echo "</optgroup>\n";
714 }
e673ee24
DO
715 }
716 echo "</select>";
717}
718
254673dd
DO
719// used by renderGridForm() and renderRackPage()
720function renderRackInfoPortlet ($rackData)
721{
722 startPortlet ('summary');
723 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
724 echo "<tr><th width='50%' class=tdright>Rack row:</th><td class=tdleft>${rackData['row_name']}</td></tr>\n";
725 echo "<tr><th width='50%' class=tdright>Name:</th><td class=tdleft>${rackData['name']}</td></tr>\n";
726 echo "<tr><th width='50%' class=tdright>Height:</th><td class=tdleft>${rackData['height']}</td></tr>\n";
04d619d0 727 echo "<tr><th width='50%' class=tdright>%% used:</th><td class=tdleft>";
254673dd
DO
728 renderProgressBar (getRSUforRack ($rackData));
729 echo "</td></tr>\n";
730 echo "<tr><th width='50%' class=tdright>Objects:</th><td class=tdleft>";
abef7149 731 echo count (stuffInRackspace ($rackData));
254673dd 732 echo "</td></tr>\n";
4fbb5a00 733 printTagTRs (makeHref(array('page'=>'rackspace', 'tab'=>'default'))."&");
254673dd
DO
734 if (!empty ($rackData['comment']))
735 echo "<tr><th width='50%' class=tdright>Comment:</th><td class=tdleft>${rackData['comment']}</td></tr>\n";
736 echo '</table>';
737 finishPortlet();
738}
739
e673ee24 740// This is a universal editor of rack design/waste.
7056988c 741// FIXME: switch to using printOpFormIntro()
bb09cca0 742function renderGridForm ($rack_id = 0, $filter, $header, $submit, $state1, $state2)
e673ee24
DO
743{
744 if ($rack_id == 0)
745 {
591ff2c4 746 showError ('Invalid rack_id', __FUNCTION__);
e673ee24
DO
747 return;
748 }
749 if (($rackData = getRackData ($rack_id)) == NULL)
750 {
591ff2c4 751 showError ('getRackData() failed', __FUNCTION__);
e673ee24
DO
752 return;
753 }
51690ad4 754 showMessageOrError();
4fbb5a00 755 global $pageno, $tabno;
254673dd 756 $filter ($rackData);
e673ee24
DO
757 markupObjectProblems ($rackData);
758
e673ee24
DO
759 // Render the result whatever it is.
760 // Main layout.
761 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
762 echo "<tr><td colspan=2 align=center><h1>${rackData['name']}</h1></td></tr>\n";
763
764 // Left column with information portlet.
765 echo "<tr><td class=pcleft height='1%' width='50%'>";
254673dd 766 renderRackInfoPortlet ($rackData);
e673ee24 767 echo "</td>\n";
bb09cca0 768 echo "<td class=pcright>";
e673ee24
DO
769
770 // Grid form.
771 startPortlet ($header);
772 echo "<center>\n";
773 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
774 echo "<tr><th width='10%'>&nbsp;</th><th width='20%'>Front</th>";
775 echo "<th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
4fbb5a00 776 printOpFormIntro ('updateRack');
e673ee24
DO
777 markupAtomGrid ($rackData, $state2);
778 renderAtomGrid ($rackData);
779 echo "</table></center>\n";
780 echo "<br><input type=submit name=do_update value='${submit}'></form><br><br>\n";
781 finishPortlet();
bb09cca0 782 echo "</td></tr></table>\n";
e673ee24
DO
783}
784
785function renderRackDesign ($rack_id)
786{
bb09cca0 787 renderGridForm ($rack_id, 'applyRackDesignMask', 'Rack design', 'Set rack design', 'A', 'F');
e673ee24
DO
788}
789
790function renderRackProblems ($rack_id = 0)
791{
bb09cca0 792 renderGridForm ($rack_id, 'applyRackProblemMask', 'Rack problems', 'Mark unusable atoms', 'F', 'U');
e673ee24
DO
793}
794
795function startPortlet ($title = '')
796{
797 echo "<div class=portlet><h2>${title}</h2>";
798}
799
800function finishPortlet ()
801{
802 echo "</div>\n";
803}
804
805function printRefsOfType ($refs, $type, $eq)
806{
e673ee24
DO
807 $gotone=0;
808 foreach ($refs as $ref)
809 {
810 if ($eq($ref['type'], $type))
811 {
812 if ($gotone) echo ', ';
4fbb5a00 813 echo "<a href='".makeHref(array('page'=>'object', 'object_id'=>$ref['object_id']))."'>";
4b2bf583
DO
814 if (!empty ($ref['name']))
815 echo $ref['name'] . '@';
816 echo "${ref['object_name']}</a>";
e673ee24
DO
817 $gotone=1;
818 }
819 }
820}
821
822function renderRackObject ($object_id = 0)
823{
4fbb5a00 824 global $nextorder, $aac;
e673ee24
DO
825 if ($object_id <= 0)
826 {
591ff2c4 827 showError ('Invalid object_id', __FUNCTION__);
e673ee24
DO
828 return;
829 }
830 $info = getObjectInfo ($object_id);
831 if ($info == NULL)
832 {
591ff2c4 833 showError ('getObjectInfo() failed', __FUNCTION__);
e673ee24
DO
834 return;
835 }
836 // Main layout starts.
837 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
838 echo "<tr><td colspan=2 align=center><h1>${info['dname']}</h1></td></tr>\n";
839 // left column with uknown number of portlets
840 echo "<tr><td class=pcleft>";
0ab782bc 841 startPortlet ('summary');
e673ee24
DO
842 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
843 if (!empty ($info['name']))
844 echo "<tr><th width='50%' class=tdright>Common name:</th><td class=tdleft>${info['name']}</td></tr>\n";
9c0b0016 845 elseif (in_array ($info['objtype_id'], explode (',', getConfigVar ('NAMEFUL_OBJTYPES'))))
a0ec6295 846 echo "<tr><td colspan=2 class=msg_error>Common name is missing.</td></tr>\n";
e2ac59cf 847 echo "<tr><th width='50%' class=tdright>Object type:</th>";
4fbb5a00 848 echo "<td class=tdleft><a href='".makeHref(array('page'=>'objgroup', 'group_id'=>$info['objtype_id'], 'hl_object_id'=>$object_id))."'>${info['objtype_name']}</a></td></tr>\n";
e673ee24
DO
849 if (!empty ($info['asset_no']))
850 echo "<tr><th width='50%' class=tdright>Asset tag:</th><td class=tdleft>${info['asset_no']}</td></tr>\n";
a6305acc 851 elseif (in_array ($info['objtype_id'], explode (',', getConfigVar ('REQUIRE_ASSET_TAG_FOR'))))
a0ec6295 852 echo "<tr><td colspan=2 class=msg_error>Asset tag is missing.</td></tr>\n";
e673ee24
DO
853 if (!empty ($info['label']))
854 echo "<tr><th width='50%' class=tdright>Visible label:</th><td class=tdleft>${info['label']}</td></tr>\n";
855 if (!empty ($info['barcode']))
856 echo "<tr><th width='50%' class=tdright>Barcode:</th><td class=tdleft>${info['barcode']}</td></tr>\n";
857 if ($info['has_problems'] == 'yes')
858 echo "<tr><td colspan=2 class=msg_error>Has problems</td></tr>\n";
24cbe8af 859 foreach (getAttrValues ($object_id, TRUE) as $record)
e673ee24 860 if (!empty ($record['value']))
4fb5bc8c 861 echo "<tr><th width='50%' class=tdright><span class=sticker>${record['name']}</span>:</th><td class=tdleft>${record['a_value']}</td></tr>\n";
4fbb5a00 862 printTagTRs (makeHref(array('page'=>'objgroup', 'tab'=>'default', 'group_id'=>$info['objtype_id']))."&");
e673ee24
DO
863 echo "</table><br>\n";
864 finishPortlet();
865
866 if (!empty ($info['comment']))
867 {
868 startPortlet ('Comment');
6cc5d6cd 869 echo '<div class=commentblock>' . string_insert_hrefs ($info['comment']) . '</div>';
e673ee24
DO
870 finishPortlet ();
871 }
872
e1ae3fb4
AD
873 renderFilesPortlet ('object', $object_id);
874
e673ee24
DO
875 $ports = getObjectPortsAndLinks ($object_id);
876 if (count ($ports))
877 {
0ab782bc 878 startPortlet ('ports and links');
e673ee24
DO
879 usort($ports, 'sortByName');
880 if ($ports)
881 {
882 $hl_port_id = 0;
883 if (isset ($_REQUEST['hl_port_id']))
884 {
2c6c7645 885 assertUIntArg ('hl_port_id', __FUNCTION__);
e673ee24
DO
886 $hl_port_id = $_REQUEST['hl_port_id'];
887 }
888 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
889 echo "<tr><th>Local name</th><th>Visible label</th><th>Port type</th><th>L2 address</th>";
890 echo "<th>Rem. Object</th><th>Rem. port</th></tr>\n";
891 foreach ($ports as $port)
892 {
893 echo '<tr';
894 if ($hl_port_id == $port['id'])
895 echo ' class=port_highlight';
896 echo "><td>${port['name']}</td><td>${port['label']}</td><td>${port['type']}</td>";
897 echo "<td>${port['l2address']}</td>";
898 if ($port['remote_object_id'])
899 {
4fbb5a00 900 echo "<td><a href='".makeHref(array('page'=>'object', 'object_id'=>$port['remote_object_id'], 'hl_port_id'=>$port['remote_id']))."'>${port['remote_object_name']}</a></td>";
e673ee24
DO
901 echo "<td>${port['remote_name']}</td>";
902 }
903 elseif (!empty ($port['reservation_comment']))
904 {
905 echo "<td><b>Reserved;</b></td>";
906 echo "<td>${port['reservation_comment']}</td>";
907 }
908 else
909 echo '<td>&nbsp;</td><td>&nbsp;</td>';
910 echo "</tr>\n";
911 }
912 echo "</table><br>\n";
913 }
914 finishPortlet();
915 }
85970da2 916
0ab782bc
DO
917 $alloclist = getObjectIPv4Allocations ($object_id);
918 if (count ($alloclist))
e673ee24 919 {
f28fbe8b 920 startPortlet ('IPv4 addresses');
e673ee24 921 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
f0ed1181 922 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
0b9c98d7 923 echo "<tr><th>OS interface</th><th>IP address</th><th>network</th><th>routed by</th><th>peers</th></tr>\n";
83fdf85f
DO
924 else
925 echo "<tr><th>OS interface</th><th>IP address</th><th>peers</th></tr>\n";
fc0e3978
DO
926 $hl_ipv4_addr = '';
927 if (isset ($_REQUEST['hl_ipv4_addr']))
928 {
929 assertIPv4Arg ('hl_ipv4_addr', __FUNCTION__);
930 $hl_ipv4_addr = $_REQUEST['hl_ipv4_addr'];
931 }
85970da2 932 foreach ($alloclist as $dottedquad => $alloc)
e673ee24 933 {
0ab782bc
DO
934 $address_name = niftyString ($alloc['addrinfo']['name']);
935 $class = $alloc['addrinfo']['class'];
85970da2 936 $secondclass = ($hl_ipv4_addr == $dottedquad) ? 'tdleft port_highlight' : 'tdleft';
83fdf85f 937 $netid = getIPv4AddressNetworkId ($dottedquad);
d7a8186d 938 if (NULL !== $netid)
83fdf85f 939 {
d7a8186d
DO
940 $netinfo = getIPv4NetworkInfo ($netid);
941 loadIPv4AddrList ($netinfo);
83fdf85f 942 }
d7a8186d
DO
943 echo "<tr class='${class}' valign=top><td class=tdleft>${alloc['osif']}</td><td class='${secondclass}'>";
944 if (NULL !== $netid)
4fbb5a00 945 echo "<a href='".makeHref(array('page'=>'ipaddress', 'ip'=>$dottedquad, 'hl_object_id'=>$object_id))."'>${dottedquad}</a>";
d7a8186d
DO
946 else
947 echo $dottedquad;
948 if (getConfigVar ('EXT_IPV4_VIEW') != 'yes')
949 echo '<small>/' . (NULL === $netid ? '??' : $netinfo['mask']) . '</small>';
351b1f45 950 echo '&nbsp;' . $aac[$alloc['type']];
83fdf85f 951 if (!empty ($alloc['addrinfo']['name']))
28a664e7 952 echo ' (' . niftyString ($alloc['addrinfo']['name']) . ')';
83fdf85f 953 echo '</td>';
f0ed1181 954 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
b90c3907 955 {
83fdf85f 956 if (NULL === $netid)
0b9c98d7 957 echo '<td class=sparenetwork>N/A</td><td class=sparenetwork>N/A</td>';
83fdf85f 958 else
83fdf85f 959 {
0b9c98d7
DO
960 echo "<td class='${secondclass}'>";
961 renderIPv4NetCell ($netinfo);
962 echo "</td>";
8b3874a5
DO
963 // filter out self-allocation
964 $other_routers = array();
d7a8186d 965 foreach (findRouters ($netinfo['addrlist']) as $router)
8b3874a5
DO
966 if ($router['id'] != $object_id)
967 $other_routers[] = $router;
0b9c98d7
DO
968 if (count ($other_routers))
969 printRoutersTD ($other_routers);
970 else
971 echo "<td class='${secondclass}'>&nbsp;</td>";
83fdf85f 972 }
b90c3907 973 }
83fdf85f 974 // peers
0ab782bc 975 echo "<td class='${secondclass}'>\n";
0ab782bc 976 $prefix = '';
2c817354 977 if ($alloc['addrinfo']['reserved'] == 'yes')
e673ee24 978 {
85970da2 979 echo $prefix . '<strong>RESERVED</strong>';
0ab782bc
DO
980 $prefix = '; ';
981 }
982 foreach ($alloc['addrinfo']['allocs'] as $allocpeer)
983 {
984 if ($allocpeer['object_id'] == $object_id)
985 continue;
4fbb5a00 986 echo $prefix . "<a href='".makeHref(array('page'=>'object', 'object_id'=>$allocpeer['object_id']))."'>";
0ab782bc
DO
987 if (!empty ($allocpeer['osif']))
988 echo $allocpeer['osif'] . '@';
989 echo $allocpeer['object_name'] . '</a>';
0ab782bc 990 $prefix = '; ';
e673ee24 991 }
e673ee24
DO
992 echo "</td></tr>\n";
993 }
994 echo "</table><br>\n";
995 finishPortlet();
996 }
997
eeb4a5d8 998 $forwards = getNATv4ForObject ($object_id);
e673ee24
DO
999 if (count($forwards['in']) or count($forwards['out']))
1000 {
f28fbe8b 1001 startPortlet('NATv4');
e673ee24
DO
1002
1003 if (count($forwards['out']))
1004 {
1005
f28fbe8b 1006 echo "<h3>locally performed NAT</h3>";
e673ee24 1007
105a3bc8 1008 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
f28fbe8b 1009 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
1010
1011 foreach ($forwards['out'] as $pf)
1012 {
2c817354
DO
1013 $class = 'trerror';
1014 $osif = '';
1015 if (isset ($alloclist [$pf['localip']]))
1016 {
1017 $class = $alloclist [$pf['localip']]['addrinfo']['class'];
1018 $osif = $alloclist [$pf['localip']]['osif'] . ': ';
1019 }
e673ee24 1020 echo "<tr class='$class'>";
4fbb5a00
DY
1021 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>";
1022 echo "<td class=tdleft><a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['remoteip']))."'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
53ef3908 1023 $address = getIPv4Address ($pf['remoteip']);
e673ee24 1024 echo "<td class='description'>";
53ef3908
DO
1025 if (count ($address['allocs']))
1026 foreach($address['allocs'] as $bond)
4fbb5a00 1027 echo "<a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$bond['object_id']))."'>${bond['object_name']}(${bond['name']})</a> ";
f28fbe8b
DO
1028 elseif (!empty ($pf['remote_addr_name']))
1029 echo '(' . $pf['remote_addr_name'] . ')';
53ef3908 1030 echo "</td><td class='description'>${pf['description']}</td></tr>";
e673ee24
DO
1031 }
1032 echo "</table><br><br>";
1033 }
1034 if (count($forwards['in']))
1035 {
f28fbe8b 1036 echo "<h3>arriving NAT connections</h3>";
105a3bc8 1037 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
f28fbe8b 1038 echo "<tr><th>Matched endpoint</th><th>Source object</th><th>Translated to</th><th>Rule comment</th></tr>\n";
e673ee24
DO
1039 foreach ($forwards['in'] as $pf)
1040 {
1041 echo "<tr>";
4fbb5a00
DY
1042 echo "<td>${pf['proto']}/<a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['localip']))."'>${pf['localip']}</a>:${pf['localport']}</td>";
1043 echo "<td class='description'><a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$pf['object_id']))."'>${pf['object_name']}</a>";
1044 echo "</td><td><a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['remoteip']))."'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
e673ee24
DO
1045 echo "<td class='description'>${pf['description']}</td></tr>";
1046 }
e673ee24
DO
1047 echo "</table><br><br>";
1048 }
1049 finishPortlet();
1050 }
1051
78e7b769
DO
1052 $pools = getRSPoolsForObject ($object_id);
1053 if (count ($pools))
1054 {
300826cb 1055 $order = 'odd';
8128c257 1056 startPortlet ('Real server pools (' . count ($pools) . ')');
78e7b769 1057 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
732e4578 1058 echo "<tr><th>VS</th><th>RS pool</th><th>RS</th><th>VS config</th><th>RS config</th></tr>\n";
748805bf 1059 foreach ($pools as $vs_id => $info)
78e7b769 1060 {
b1a970c7
DO
1061 echo "<tr valign=top class=row_${order}><td class=tdleft>";
1062 renderVSCell ($vs_id);
1063 echo "</td><td class=tdleft>";
1064 renderRSPoolCell ($info['pool_id'], $info['pool_name']);
1065 echo '</td><td class=tdleft>' . $info['rscount'] . '</td>';
1066 echo "<td class=slbconf>${info['vsconfig']}</td>";
1067 echo "<td class=slbconf>${info['rsconfig']}</td>";
78e7b769 1068 echo "</tr>\n";
300826cb 1069 $order = $nextorder[$order];
78e7b769
DO
1070 }
1071 echo "</table>\n";
1072 finishPortlet();
1073 }
e673ee24
DO
1074 echo "</td>\n";
1075
7056988c 1076 // After left column we have (surprise!) right column with rackspace portlet only.
e673ee24
DO
1077 echo "<td class=pcright>";
1078 // rackspace portlet
0ab782bc 1079 startPortlet ('rackspace allocation');
e673ee24
DO
1080 // FIXME: now we call getRackData() twice
1081 $racks = getResidentRacksData ($object_id);
1082 foreach ($racks as $rackData)
1083 renderRack ($rackData['id'], $object_id);
1084 echo '<br>';
1085 finishPortlet();
1086 echo "</td></tr>";
1087 echo "</table>\n";
1088}
1089
1090function renderRackMultiSelect ($sname, $racks, $selected)
1091{
04571888
DO
1092 // Transform the given flat list into a list of groups, each representing a rack row.
1093 $rdata = array();
e673ee24 1094 foreach ($racks as $rack)
04571888
DO
1095 if (!isset ($rdata[$rack['row_name']]))
1096 $rdata[$rack['row_name']] = array ($rack['id'] => $rack['name']);
1097 else
1098 $rdata[$rack['row_name']][$rack['id']] = $rack['name'];
4fbb5a00 1099 echo "<select name=${sname} multiple size=" . getConfigVar ('MAXSELSIZE') . " onchange='getElementsByName(\"updateObjectAllocation\")[0].submit()'>\n";
04571888 1100 foreach ($rdata as $optgroup => $racklist)
e673ee24 1101 {
04571888
DO
1102 echo "<optgroup label='${optgroup}'>";
1103 foreach ($racklist as $rack_id => $rack_name)
1104 {
1105 echo "<option value=${rack_id}";
1106 if (!(array_search ($rack_id, $selected) === FALSE))
1107 echo ' selected';
1108 echo">${rack_name}</option>\n";
1109 }
e673ee24
DO
1110 }
1111 echo "</select>\n";
1112}
1113
1114function showMessageOrError ()
1115{
bd49850d 1116 if (isset ($_SESSION['log']))
83555c04 1117 {
83555c04
DY
1118 printLog ($_SESSION['log']);
1119 unset($_SESSION['log']);
1120 }
e673ee24
DO
1121}
1122
1123// This function renders a form for port edition.
1124function renderPortsForObject ($object_id = 0)
1125{
39b4abd0
DO
1126 function printNewItemTR ()
1127 {
1128 printOpFormIntro ('addPort');
1129 echo "<tr><td>";
f5ff50f5 1130 printImageHREF ('add', 'add a port', TRUE);
39b4abd0 1131 echo "</td><td><input type=text size=8 name=port_name tabindex=100></td>\n";
3decd141
DO
1132 echo "<td><input type=text size=24 name=port_label tabindex=101></td><td>";
1133 printSelect (getPortTypes(), 'port_type_id', getConfigVar ('default_port_type'), 102);
39b4abd0 1134 echo "<td><input type=text name=port_l2address tabindex=103></td>\n";
9318d2ef
DO
1135 echo "<td colspan=3>&nbsp;</td><td>";
1136 printImageHREF ('add', 'add a port', TRUE, 104);
1137 echo "</td></tr></form>";
39b4abd0 1138 }
4fbb5a00 1139 global $pageno, $tabno;
e673ee24
DO
1140 if ($object_id <= 0)
1141 {
591ff2c4 1142 showError ('Invalid object_id', __FUNCTION__);
e673ee24
DO
1143 return;
1144 }
1145 showMessageOrError();
1146 startPortlet ('Ports and interfaces');
1147 $ports = getObjectPortsAndLinks ($object_id);
1148 usort($ports, 'sortByName');
1149 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
1150 echo "<tr><th>&nbsp;</th><th>Local name</th><th>Visible label</th><th>Port type</th><th>L2 address</th>";
1151 echo "<th>Rem. object</th><th>Rem. port</th><th>(Un)link or (un)reserve</th><th>&nbsp;</th></tr>\n";
39b4abd0
DO
1152 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
1153 printNewItemTR();
e673ee24
DO
1154 foreach ($ports as $port)
1155 {
7056988c 1156 printOpFormIntro ('editPort', array ('port_id' => $port['id']));
4fbb5a00 1157 echo "<tr><td><a href='".makeHrefProcess(array('op'=>'delport', 'port_id'=>$port['id'], 'object_id'=>$object_id, 'port_name'=>$port['name']))."'>";
e673ee24
DO
1158 printImageHREF ('delete', 'Unlink and Delete this port');
1159 echo "</a></td>\n";
1160 echo "<td><input type=text name=name value='${port['name']}' size=8></td>";
1161 echo "<td><input type=text name=label value='${port['label']}' size=24></td>";
611170af
AD
1162 if (!$port['remote_object_id'])
1163 {
1164 echo "<td>";
1165 printSelect (getPortTypes(), 'port_type_id', $port['type_id']);
1166 echo "</td>";
1167 }
1168 else
1169 {
1170 echo "<input type=hidden name=port_type_id value='${port['type_id']}'>";
f7a3c94a 1171 echo "<td class=tdleft>${port['type']}</td>\n";
611170af 1172 }
e673ee24
DO
1173 echo "<td><input type=text name=l2address value='${port['l2address']}'></td>\n";
1174 if ($port['remote_object_id'])
1175 {
4fbb5a00 1176 echo "<td><a href='".makeHref(array('page'=>'object', 'object_id'=>$port['remote_object_id']))."'>${port['remote_object_name']}</a></td>";
e673ee24 1177 echo "<td>${port['remote_name']}</td>";
4fbb5a00
DY
1178 echo "<td><a href='".
1179 makeHrefProcess(array(
1180 'op'=>'unlinkPort',
1181 'port_id'=>$port['id'],
1182 'object_id'=>$object_id,
1183 'port_name'=>$port['name'],
1184 'remote_port_name'=>$port['remote_name'],
1185 'remote_object_name'=>$port['remote_object_name'])).
1186 "'>";
5ccd99a0 1187 printImageHREF ('cut', 'Unlink this port');
e673ee24
DO
1188 echo "</a></td>";
1189 }
1190 elseif (!empty ($port['reservation_comment']))
1191 {
1192 echo "<td><b>Reserved;</b></td>";
1193 echo "<td><input type=text name=reservation_comment value='${port['reservation_comment']}'></td>";
4fbb5a00
DY
1194 echo "<td><a href='".
1195 makeHrefProcess(array(
1196 'op'=>'useup',
1197 'port_id'=>$port['id'],
1198 'object_id'=>$object_id)).
1199 "'>";
39be655e 1200 printImageHREF ('clear', 'Use up this port');
e673ee24
DO
1201 echo "</a></td>";
1202 }
1203 else
1204 {
1205 echo "<td>&nbsp;</td><td>&nbsp;</td>";
1206 echo "<td>";
39106006 1207 echo "<a href='javascript:;' onclick='window.open(\"".makeHrefForHelper('portlist', array('port'=>$port['id'], 'type'=>$port['type_id'], 'object_id'=>$object_id, 'port_name'=>$port['name']))."\",\"findlink\",\"height=700, width=400, location=no, menubar=no, resizable=yes, scrollbars=no, status=no, titlebar=no, toolbar=no\");'>";
5ccd99a0 1208 printImageHREF ('plug', 'Link this port');
e673ee24
DO
1209 echo "</a> <input type=text name=reservation_comment>";
1210 echo "</td>\n";
1211 }
5bbbeaa2
DO
1212 echo "<td>";
1213 printImageHREF ('save', 'Save changes', TRUE);
1214 echo "</td></form></tr>\n";
e673ee24 1215 }
39b4abd0
DO
1216 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
1217 printNewItemTR();
e673ee24
DO
1218 echo "</table><br>\n";
1219 finishPortlet();
1220
1221 startPortlet ('Add/update multiple ports');
7056988c 1222 printOpFormIntro ('addMultiPorts');
f7a3c94a 1223 echo 'Format: <select name=format tabindex=201>';
e673ee24
DO
1224 echo '<option value=c3600asy>Cisco 3600 async: sh line | inc TTY</option>';
1225 echo '<option value=fiwg selected>Foundry ServerIron/FastIron WorkGroup/Edge: sh int br</option>';
e673ee24 1226 echo '<option value=fisxii>Foundry FastIron SuperX/II4000: sh int br</option>';
351d4dbf 1227 echo '<option value=ssv1>SSV:&lt;interface name&gt; &lt;MAC address&gt;</option>';
e673ee24
DO
1228 echo "</select>";
1229 echo 'Default port type: ';
f7a3c94a
DO
1230 printSelect (getPortTypes(), 'port_type', getConfigVar ('default_port_type'), 202);
1231 echo "<input type=submit value='Parse output' tabindex=204><br>\n";
1232 echo "<textarea name=input cols=100 rows=50 tabindex=203></textarea><br>\n";
e673ee24
DO
1233 echo '</form>';
1234 finishPortlet();
1235}
1236
72d8ced3 1237function renderIPv4ForObject ($object_id = 0)
e673ee24 1238{
39b4abd0
DO
1239 function printNewItemTR ()
1240 {
1241 global $aat;
1242 printOpFormIntro ('addIPv4Allocation');
1243 echo "<tr><td>";
f5ff50f5 1244 printImageHREF ('add', 'allocate', TRUE);
39b4abd0
DO
1245 echo "</td>";
1246 echo "<td class=tdleft><input type='text' size='10' name='bond_name' tabindex=100></td>\n";
1247 echo "<td class=tdleft><input type=text name='ip' tabindex=101></td>\n";
0b9c98d7 1248 echo "<td colspan=2>&nbsp;</td><td>";
f5ff50f5 1249 printSelect ($aat, 'bond_type', NULL, 102);
9318d2ef 1250 echo "</td><td>&nbsp;</td><td>";
f5ff50f5 1251 printImageHREF ('add', 'allocate', TRUE, 103);
9318d2ef 1252 echo "</td></tr></form>";
39b4abd0 1253 }
4fbb5a00 1254 global $pageno, $tabno, $aat;
e673ee24
DO
1255 if ($object_id <= 0)
1256 {
591ff2c4 1257 showError ('Invalid object_id', __FUNCTION__);
e673ee24
DO
1258 return;
1259 }
1260 showMessageOrError();
72d8ced3 1261 startPortlet ('Allocations');
85970da2 1262 $alloclist = getObjectIPv4Allocations ($object_id);
e673ee24 1263 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
79e45b4c
DO
1264 echo '<tr><th>&nbsp;</th><th>OS interface</th><th>IP address</th>';
1265 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
0b9c98d7 1266 echo '<th>network</th><th>routed by</th>';
79e45b4c 1267 echo '<th>type</th><th>misc</th><th>&nbsp</th></tr>';
09620506 1268
39b4abd0
DO
1269 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
1270 printNewItemTR();
85970da2 1271 foreach ($alloclist as $dottedquad => $alloc)
e673ee24 1272 {
85970da2 1273 $class = $alloc['addrinfo']['class'];
79e45b4c 1274 $netid = getIPv4AddressNetworkId ($dottedquad);
d7a8186d
DO
1275 if (NULL !== $netid)
1276 {
1277 $netinfo = getIPv4NetworkInfo ($netid);
1278 loadIPv4AddrList ($netinfo);
1279 }
85970da2 1280 printOpFormIntro ('updIPv4Allocation', array ('ip' => $dottedquad));
4fbb5a00 1281 echo "<tr class='$class' valign=top><td><a href='".makeHrefProcess(array('op'=>'delIPv4Allocation', 'ip'=>$dottedquad, 'object_id'=>$object_id))."'>";
e673ee24
DO
1282 printImageHREF ('delete', 'Delete this IPv4 address');
1283 echo "</a></td>";
d7a8186d
DO
1284 echo "<td class=tdleft><input type='text' name='bond_name' value='${alloc['osif']}' size=10></td><td class=tdleft>";
1285 if (NULL !== $netid)
4fbb5a00 1286 echo "<a href='".makeHref(array('page'=>'ipaddress', 'ip'=>$dottedquad))."'>${dottedquad}</a>";
d7a8186d
DO
1287 else
1288 echo $dottedquad;
79e45b4c 1289 if (getConfigVar ('EXT_IPV4_VIEW') != 'yes')
d7a8186d 1290 echo '<small>/' . (NULL === $netid ? '??' : $netinfo['mask']) . '</small>';
79e45b4c 1291 if (!empty ($alloc['addrinfo']['name']))
28a664e7 1292 echo ' (' . niftyString ($alloc['addrinfo']['name']) . ')';
79e45b4c
DO
1293 echo '</td>';
1294 // FIXME: this a copy-and-paste from renderRackObject()
1295 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
1296 {
1297 if (NULL === $netid)
0b9c98d7 1298 echo '<td class=sparenetwork>N/A</td><td class=sparenetwork>N/A</td>';
79e45b4c 1299 else
79e45b4c 1300 {
0b9c98d7
DO
1301 echo '<td>';
1302 renderIPv4NetCell ($netinfo);
d7a8186d 1303 echo '</td>';
0b9c98d7
DO
1304 // filter out self-allocation
1305 $other_routers = array();
1306 foreach (findRouters ($netinfo['addrlist']) as $router)
1307 if ($router['id'] != $object_id)
1308 $other_routers[] = $router;
1309 if (count ($other_routers))
1310 printRoutersTD ($other_routers);
1311 else
1312 echo "<td>&nbsp;</td>";
79e45b4c 1313 }
79e45b4c
DO
1314 }
1315 echo '<td>';
85970da2 1316 printSelect ($aat, 'bond_type', $alloc['type']);
e673ee24 1317 echo "</td><td>";
85970da2 1318 $prefix = '';
4940e4d5 1319 if ($alloc['addrinfo']['reserved'] == 'yes')
e673ee24 1320 {
85970da2
DO
1321 echo $prefix . '<strong>RESERVED</strong>';
1322 $prefix = '; ';
e673ee24 1323 }
85970da2 1324 foreach ($alloc['addrinfo']['allocs'] as $allocpeer)
e673ee24 1325 {
85970da2
DO
1326 if ($allocpeer['object_id'] == $object_id)
1327 continue;
4fbb5a00 1328 echo $prefix . "<a href='".makeHref(array('page'=>'object', 'object_id'=>$allocpeer['object_id']))."'>";
85970da2
DO
1329 if (!empty ($allocpeer['osif']))
1330 echo $allocpeer['osif'] . '@';
1331 echo $allocpeer['object_name'] . '</a>';
1332 $prefix = '; ';
e673ee24 1333 }
d54b9495
DO
1334 echo "</td><td>";
1335 printImageHREF ('save', 'Save changes', TRUE);
1336 echo "</td></form></tr>\n";
e673ee24 1337 }
39b4abd0
DO
1338 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
1339 printNewItemTR();
e673ee24 1340
09620506 1341 echo "</table><br>\n";
e673ee24
DO
1342 finishPortlet();
1343
1344}
1345
baf37d01
DO
1346// Log structure versions:
1347// 1: the whole structure is a list of code-message pairs
1348// 2 and later: there's a "v" field set, which indicates the version
1349// 2: there's a "m" list set to hold message code and optional arguments
e673ee24
DO
1350function printLog ($log)
1351{
baf37d01
DO
1352 switch (TRUE)
1353 {
1354 case !isset ($log['v']):
ebb5441d 1355 case $log['v'] == 1:
baf37d01 1356 foreach ($log as $key => $record)
ebb5441d 1357 if ($key !== 'v')
baf37d01
DO
1358 echo "<div class=msg_${record['code']}>${record['message']}</div>";
1359 break;
1360 case $log['v'] == 2:
1361 $msginfo = array
1362 (
8628ae44 1363// records 0~99 with success messages
ebb5441d 1364 0 => array ('code' => 'success', 'format' => 'Success: %s'),
baf37d01
DO
1365 1 => array ('code' => 'success', 'format' => '%u new records done, %u already existed'),
1366 2 => array ('code' => 'success', 'format' => 'NATv4 rule was successfully added.'),
1367 3 => array ('code' => 'success', 'format' => 'NATv4 rule was successfully deleted.'),
1368 4 => array ('code' => 'success', 'format' => 'NATv4 rule was successfully updated'),
1369 5 => array ('code' => 'success', 'format' => 'Port %s was added successfully'),
1370 6 => array ('code' => 'success', 'format' => 'Port %s was updated successfully'),
1371 7 => array ('code' => 'success', 'format' => 'Port %s was deleted successfully'),
1372 8 => array ('code' => 'success', 'format' => 'Port %s successfully linked with port %s at object %s'),
1373 9 => array ('code' => 'success', 'format' => 'Port %s was successfully unlinked from %s@%s'),
1374 10 => array ('code' => 'success', 'format' => 'Added %u ports, updated %u ports, encountered %u errors.'),
1375 11 => array ('code' => 'success', 'format' => 'Reservation removed.'),
1376 12 => array ('code' => 'success', 'format' => 'allocation updated'),
1377 13 => array ('code' => 'success', 'format' => 'allocated'),
1378 14 => array ('code' => 'success', 'format' => 'deallocated'),
1379 15 => array ('code' => 'success', 'format' => 'Reset succeeded.'),
1380 16 => array ('code' => 'success', 'format' => 'Update done'),
1381 17 => array ('code' => 'success', 'format' => 'Update(s) succeeded.'),
1382 18 => array ('code' => 'success', 'format' => 'Load balancer was successfully added'),
1383 19 => array ('code' => 'success', 'format' => 'Load balancer was successfully deleted'),
1384 20 => array ('code' => 'success', 'format' => 'Load balancer info was successfully updated'),
1385 21 => array ('code' => 'success', 'format' => 'Generation complete'),
1386 22 => array ('code' => 'success', 'format' => 'Chained %u tags'),
1387 23 => array ('code' => 'success', 'format' => 'IPv4 prefix successfully added'),
1388 24 => array ('code' => 'success', 'format' => 'IPv4 prefix deleted'),
1389 25 => array ('code' => 'success', 'format' => 'IPv4 prefix updated'),
1390 26 => array ('code' => 'success', 'format' => '%u IP address(es) were successfully updated'),
1391 27 => array ('code' => 'success', 'format' => 'IPv4 address updated'),
1392 28 => array ('code' => 'success', 'format' => 'Virtual service was successfully created'),
1393 29 => array ('code' => 'success', 'format' => 'Virtual service was successfully deleted'),
1394 30 => array ('code' => 'success', 'format' => 'Virtual service was successfully updated'),
1395 31 => array ('code' => 'success', 'format' => 'RS pool was successfully created'),
1396 32 => array ('code' => 'success', 'format' => 'RS pool was successfully deleted'),
1397 33 => array ('code' => 'success', 'format' => 'RS pool was successfully updated'),
1398 34 => array ('code' => 'success', 'format' => 'Real server was successfully added'),
1399 35 => array ('code' => 'success', 'format' => 'Real server was successfully deleted'),
1400 36 => array ('code' => 'success', 'format' => 'Real server was successfully updated'),
1401 37 => array ('code' => 'success', 'format' => 'Successfully added %u real servers'),
1402 38 => array ('code' => 'success', 'format' => '%u real server(s) were successfully (de)activated'),
1403 39 => array ('code' => 'success', 'format' => 'User account %s updated.'),
1404 40 => array ('code' => 'success', 'format' => 'User account %s created.'),
79b8ad1e
DO
1405// ...
1406// ...
baf37d01
DO
1407 43 => array ('code' => 'success', 'format' => 'Saved successfully.'),
1408 44 => array ('code' => 'success', 'format' => '%s failures and %s successfull changes.'),
1409 45 => array ('code' => 'success', 'format' => "Attribute '%s' created."),
1410 46 => array ('code' => 'success', 'format' => 'Rename successful.'),
1411 47 => array ('code' => 'success', 'format' => 'Attribute was deleted.'),
1412 48 => array ('code' => 'success', 'format' => 'Supplement succeeded.'),
1413 49 => array ('code' => 'success', 'format' => 'Reduction succeeded.'),
1414 50 => array ('code' => 'success', 'format' => 'Reduction succeeded.'),
1415 51 => array ('code' => 'success', 'format' => 'Update succeeded.'),
1416 52 => array ('code' => 'success', 'format' => 'Supplement succeeded.'),
1417 53 => array ('code' => 'success', 'format' => 'Chapter was deleted.'),
1418 54 => array ('code' => 'success', 'format' => 'Chapter was updated.'),
1419 55 => array ('code' => 'success', 'format' => 'Chapter was added.'),
1420 56 => array ('code' => 'success', 'format' => 'Update succeeded.'),
1421 57 => array ('code' => 'success', 'format' => 'Reset complete'),
1422 58 => array ('code' => 'success', 'format' => "Successfully deleted tag ."),
1423 59 => array ('code' => 'success', 'format' => "Created tag '%s'."),
1424 60 => array ('code' => 'success', 'format' => "Updated tag '%s'."),
ebb5441d 1425 61 => array ('code' => 'success', 'format' => 'Password changed successfully.'),
24dcb9d8 1426 62 => array ('code' => 'success', 'format' => 'gw: %s'),
f0ff4930
DO
1427 63 => array ('code' => 'success', 'format' => '%u change request(s) have been processed'),
1428 64 => array ('code' => 'success', 'format' => 'Port %s@%s has been assigned to VLAN %u'),
f19c75d6 1429 65 => array ('code' => 'success', 'format' => "Added new rack '%s'"),
03e6ef01 1430 66 => array ('code' => 'success', 'format' => "File sent Ok via handler '%s'"),
abef7149 1431 67 => array ('code' => 'success', 'format' => "Tag rolling done, %u objects involved"),
0c2b7c4a 1432 68 => array ('code' => 'success', 'format' => "Updated rack '%s'"),
e1ae3fb4
AD
1433 69 => array ('code' => 'success', 'format' => 'File %s was added successfully'),
1434 70 => array ('code' => 'success', 'format' => 'File %s was updated successfully'),
1435 71 => array ('code' => 'success', 'format' => 'File %s was linked successfully'),
1436 72 => array ('code' => 'success', 'format' => 'File %s was unlinked successfully'),
1437 73 => array ('code' => 'success', 'format' => 'File %s was deleted successfully'),
52b34485
AD
1438 74 => array ('code' => 'success', 'format' => 'Row %s was added successfully'),
1439 75 => array ('code' => 'success', 'format' => 'Row %s was updated successfully'),
1440 76 => array ('code' => 'success', 'format' => 'Object %s was deleted successfully'),
8628ae44
DO
1441 77 => array ('code' => 'success', 'format' => 'Row %s was deleted successfully'),
1442 78 => array ('code' => 'success', 'format' => 'File %s saved Ok'),
c8187437 1443 79 => array ('code' => 'success', 'format' => 'Rack %s was deleted successfully'),
f0ff4930 1444
8628ae44 1445// records 100~199 with fatal error messages
ebb5441d
DO
1446 100 => array ('code' => 'error', 'format' => 'Generic error: %s'),
1447 101 => array ('code' => 'error', 'format' => 'Port name cannot be empty'),
1448 102 => array ('code' => 'error', 'format' => "Error creating user account '%s'"),
1449 103 => array ('code' => 'error', 'format' => 'getHashByID() failed'),
1450 104 => array ('code' => 'error', 'format' => "Error updating user account '%s'"),
79b8ad1e
DO
1451// ...
1452// ...
1453// ...
ebb5441d
DO
1454 108 => array ('code' => 'error', 'format' => '%u failures and %u successfull changes.'),
1455 109 => array ('code' => 'error', 'format' => 'Update failed!'),
1456 110 => array ('code' => 'error', 'format' => 'Supplement failed!'),
1457 111 => array ('code' => 'error', 'format' => 'Reduction failed!'),
1458 112 => array ('code' => 'error', 'format' => 'Error adding chapter.'),
1459 113 => array ('code' => 'error', 'format' => 'Error updating chapter.'),
1460 114 => array ('code' => 'error', 'format' => 'Error deleting chapter.'),
1461 115 => array ('code' => 'error', 'format' => 'Error renaming attribute.'),
1462 116 => array ('code' => 'error', 'format' => 'Error creating attribute.'),
1463 117 => array ('code' => 'error', 'format' => 'Error deleting attribute.'),
1464 118 => array ('code' => 'error', 'format' => 'Supplement failed!'),
1465 119 => array ('code' => 'error', 'format' => 'Reduction failed!'),
1466 120 => array ('code' => 'error', 'format' => 'Reset failed!'),
1467 121 => array ('code' => 'error', 'format' => 'commitUpdateObject() failed'),
1468 122 => array ('code' => 'error', 'format' => 'One or more update(s) failed!'),
1469 123 => array ('code' => 'error', 'format' => 'Cannot process submitted data: unknown format code.'),
1470 124 => array ('code' => 'error', 'format' => 'Error removing reservation!'),
1471 125 => array ('code' => 'error', 'format' => "Update failed with error: '%s'"),
1472 126 => array ('code' => 'error', 'format' => 'addRStoRSPool() failed'),
1473 127 => array ('code' => 'error', 'format' => 'Added %u real servers and encountered %u errors'),
1474 128 => array ('code' => 'error', 'format' => 'commitDeleteRS() failed'),
1475 129 => array ('code' => 'error', 'format' => 'commitDeleteLB() failed'),
1476 130 => array ('code' => 'error', 'format' => 'commitDeleteVS() failed'),
1477 131 => array ('code' => 'error', 'format' => 'invalid format requested'),
1478 132 => array ('code' => 'error', 'format' => 'invalid protocol'),
1479 133 => array ('code' => 'error', 'format' => 'commitUpdateRS() failed'),
1480 134 => array ('code' => 'error', 'format' => 'commitUpdateLB() failed'),
1481 135 => array ('code' => 'error', 'format' => 'commitUpdateVS() failed'),
1482 136 => array ('code' => 'error', 'format' => 'addLBtoRSPool() failed'),
1483 137 => array ('code' => 'error', 'format' => 'addLBtoRSPool() failed'),
1484 138 => array ('code' => 'error', 'format' => 'commitDeleteRSPool() failed'),
1485 139 => array ('code' => 'error', 'format' => 'commitUpdateRSPool() failed'),
1486 140 => array ('code' => 'error', 'format' => 'Encountered %u errors, (de)activated %u real servers'),
1487 141 => array ('code' => 'error', 'format' => 'Encountered %u errors, updated %u IP address(es)'),
1488 142 => array ('code' => 'error', 'format' => 'executeAutoPorts() failed'),
1489 143 => array ('code' => 'error', 'format' => 'Tried chaining %u tags, but experienced %u errors.'),
1490 144 => array ('code' => 'error', 'format' => "Error deleting tag: '%s'"),
1491 145 => array ('code' => 'error', 'format' => "Invalid tag name '%s'"),
1492 146 => array ('code' => 'error', 'format' => "Tag '%s' (or similar name) already exists"),
1493 147 => array ('code' => 'error', 'format' => "Could not create tag '%s' because of error '%s'"),
1494 148 => array ('code' => 'error', 'format' => "Could not update tag '%s' because of error '%s'"),
1495 149 => array ('code' => 'error', 'format' => 'Turing test failed'),
1496 150 => array ('code' => 'error', 'format' => 'Can only change password under DB authentication.'),
1497 151 => array ('code' => 'error', 'format' => 'Old password doesn\'t match.'),
1498 152 => array ('code' => 'error', 'format' => 'New passwords don\'t match.'),
1499 153 => array ('code' => 'error', 'format' => 'Password change failed.'),
1500 154 => array ('code' => 'error', 'format' => "Verification error: %s"),
1501 155 => array ('code' => 'error', 'format' => 'Save failed.'),
1502 156 => array ('code' => 'error', 'format' => 'getSwitchVLANs() failed'),
e81fb764 1503 157 => array ('code' => 'error', 'format' => 'operation not permitted'),
24dcb9d8
DO
1504 158 => array ('code' => 'error', 'format' => 'Ignoring malformed record #%u in form submit'),
1505 159 => array ('code' => 'error', 'format' => 'Permission denied moving port %s from VLAN%u to VLAN%u'),
1506 160 => array ('code' => 'error', 'format' => 'Invalid arguments'),
1507 161 => array ('code' => 'error', 'format' => 'Endpoint not found. Please either set FQDN attribute or assign an IP address to the object.'),
1508 162 => array ('code' => 'error', 'format' => 'More than one IP address is assigned to this object, please configure FQDN attribute.'),
1509 163 => array ('code' => 'error', 'format' => 'Failed to get any response from queryGateway() or the gateway died'),
c030232f 1510 164 => array ('code' => 'error', 'format' => 'Gateway failure: %s.'),
24dcb9d8
DO
1511 165 => array ('code' => 'error', 'format' => 'Gateway failure: malformed reply.'),
1512 166 => array ('code' => 'error', 'format' => 'gw: %s'),
f0ff4930
DO
1513 167 => array ('code' => 'error', 'format' => 'Could not find port %s'),
1514 168 => array ('code' => 'error', 'format' => 'Port %s is a trunk'),
1515 169 => array ('code' => 'error', 'format' => 'Failed to configure %s, connector returned code %u'),
5222f192 1516 170 => array ('code' => 'error', 'format' => 'There is no network for IP address "%s"'),
f19c75d6
DO
1517 171 => array ('code' => 'error', 'format' => "Failed creating rack '%s'. Already exists in this row?"),
1518 172 => array ('code' => 'error', 'format' => 'Malformed request'),
e5c4506d
DO
1519 173 => array ('code' => 'error', 'format' => "Invalid IPv4 prefix '%s'"),
1520 174 => array ('code' => 'error', 'format' => 'Bad IPv4 address'),
1521 175 => array ('code' => 'error', 'format' => 'Invalid netmask'),
1522 176 => array ('code' => 'error', 'format' => 'This network already exists'),
0c2b7c4a 1523 177 => array ('code' => 'error', 'format' => 'commitUpdateRack() failed'),
121496b6 1524 178 => array ('code' => 'error', 'format' => 'file not found'),
8628ae44 1525 179 => array ('code' => 'error', 'format' => 'Error saving file, all changes lost!'),
f0ff4930 1526
8628ae44 1527// records 200~299 with warnings
24dcb9d8
DO
1528 200 => array ('code' => 'warning', 'format' => 'generic warning: %s'),
1529 201 => array ('code' => 'warning', 'format' => 'nothing happened...'),
1530 202 => array ('code' => 'warning', 'format' => 'gw: %s'),
f0ff4930
DO
1531 203 => array ('code' => 'warning', 'format' => 'Port %s seems to be the first in VLAN %u at this switch.'),
1532 204 => array ('code' => 'warning', 'format' => 'Check uplink/downlink configuration for proper operation.'),
1533 205 => array ('code' => 'warning', 'format' => '%u change request(s) have been ignored'),
c8187437 1534 206 => array ('code' => 'warning', 'format' => 'Rack is not empty'),
baf37d01
DO
1535 );
1536 // Handle the arguments. Is there any better way to do it?
1537 foreach ($log['m'] as $record)
1538 {
5222f192
DO
1539 if (!isset ($record['c']) or !isset ($msginfo[$record['c']]))
1540 {
1541 echo '<div class=msg_neutral>(this message was lost)</div>';
1542 continue;
1543 }
baf37d01
DO
1544 if (isset ($record['a']))
1545 switch (count ($record['a']))
1546 {
1547 case 1:
1548 $msgtext = sprintf
1549 (
1550 $msginfo[$record['c']]['format'],
1551 $record['a'][0]
1552 );
1553 break;
1554 case 2:
1555 $msgtext = sprintf
1556 (
1557 $msginfo[$record['c']]['format'],
1558 $record['a'][0],
1559 $record['a'][1]
1560 );
1561 break;
1562 case 3:
1563 $msgtext = sprintf
1564 (
1565 $msginfo[$record['c']]['format'],
1566 $record['a'][0],
1567 $record['a'][1],
1568 $record['a'][2]
1569 );
1570 break;
1571 case 4:
1572 default:
1573 $msgtext = sprintf
1574 (
1575 $msginfo[$record['c']]['format'],
1576 $record['a'][0],
1577 $record['a'][1],
1578 $record['a'][2],
1579 $record['a'][3]
1580 );
1581 break;
1582 }
1583 else
1584 $msgtext = $msginfo[$record['c']]['format'];
1585 echo '<div class=msg_' . $msginfo[$record['c']]['code'] . ">${msgtext}</div>";
1586 }
1587 break;
1588 default:
1589 echo '<div class=msg_error>' . __FUNCTION__ . ': internal error</div>';
1590 break;
1591 }
e673ee24
DO
1592}
1593
1594/*
1595The following conditions must be followed:
15961. We can mount onto free atoms only. This means: if any record for an atom
1597already exists in RackSpace, it can't be used for mounting.
15982. We can't unmount from 'W' atoms. Operator should review appropriate comments
1599and either delete them before unmounting or refuse to unmount the object.
1600*/
1601
1602// We extensively use $_REQUEST in the function.
7056988c 1603// FIXME: move related code into ophandler
e673ee24
DO
1604function renderRackSpaceForObject ($object_id = 0)
1605{
1606 if ($object_id <= 0)
1607 {
591ff2c4 1608 showError ('Invalid object_id', __FUNCTION__);
e673ee24
DO
1609 return;
1610 }
1611 $is_submit = isset ($_REQUEST['got_atoms']);
1612 $is_update = isset ($_REQUEST['rackmulti'][0]);
1613 $info = getObjectInfo ($object_id);
1614 if ($info == NULL)
1615 {
591ff2c4 1616 showError ('getObjectInfo() failed', __FUNCTION__);
e673ee24
DO
1617 return;
1618 }
1619 // Always process occupied racks plus racks chosen by user. First get racks with
1620 // already allocated rackspace...
1621 $workingRacksData = getResidentRacksData ($object_id);
1622 if ($workingRacksData === NULL)
1623 {
1624 print_r ($workingRacksData);
591ff2c4 1625 showError ('getResidentRacksData() failed', __FUNCTION__);
e673ee24
DO
1626 return;
1627 }
1628
1629 // ...and then add those chosen by user (if any).
1630 if ($is_update)
1631 foreach ($_REQUEST['rackmulti'] as $cand_id)
1632 {
1633 if (!isset ($workingRacksData[$cand_id]))
1634 {
1635 $rackData = getRackData ($cand_id);
1636 if ($rackData == NULL)
1637 {
591ff2c4 1638 showError ('getRackData() failed', __FUNCTION__);
e673ee24
DO
1639 return NULL;
1640 }
1641 $workingRacksData[$cand_id] = $rackData;
1642 }
1643 }
1644
1645 // Do it only once...
1646 foreach ($workingRacksData as &$rackData)
1647 applyObjectMountMask ($rackData, $object_id);
1648 // Now we workaround an old caveat: http://bugs.php.net/bug.php?id=37410
1649 unset ($rackData);
1650
e673ee24 1651 // This is the time for rendering.
4fbb5a00
DY
1652 global $pageno, $tabno;
1653
51690ad4
DY
1654 showMessageOrError();
1655
4fbb5a00
DY
1656 printOpFormIntro ('updateObjectAllocation');
1657
e673ee24
DO
1658 // Main layout starts.
1659 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0><tr>";
1660
1661 // Left portlet with rack list.
1662 echo "<td class=pcleft height='1%'>";
1663 startPortlet ('Racks');
1664 $allRacksData = getRacksForRow();
4b8d413e
DO
1665 if (count ($allRacksData) <= getConfigVar ('RACK_PRESELECT_THRESHOLD'))
1666 {
1667 foreach (array_keys ($allRacksData) as $rack_id)
1668 {
1669 $rackData = getRackData ($rack_id);
1670 if ($rackData == NULL)
1671 {
1672 showError ('getRackData() failed', __FUNCTION__);
1673 return NULL;
1674 }
1675 $workingRacksData[$rack_id] = $rackData;
1676 }
1677 foreach ($workingRacksData as &$rackData)
1678 applyObjectMountMask ($rackData, $object_id);
1679 unset ($rackData);
1680 }
1681 renderRackMultiSelect ('rackmulti[]', $allRacksData, array_keys ($workingRacksData));
e673ee24
DO
1682 echo "<br>";
1683 echo "<br>";
1684 finishPortlet();
1685 echo "</td>";
1686
1687 // Middle portlet with comment and submit.
1688 echo "<td class=pcleft>";
1689 startPortlet ('Comment');
1690 echo "<textarea name=comment rows=10 cols=40></textarea><br>\n";
1691 echo "<input type=submit value='Save' name=got_atoms>\n";
1692 echo "<br>";
1693 echo "<br>";
1694 finishPortlet();
1695 echo "</td>";
1696
1697 // Right portlet with rendered racks. If this form submit is not final, we have to
1698 // reflect the former state of the grid in current form.
1699 echo "<td class=pcright rowspan=2 height='1%'>";
1700 startPortlet ('Working copy');
1701 echo '<table border=0 cellspacing=10 align=center><tr>';
1702 foreach ($workingRacksData as $rack_id => $rackData)
1703 {
1704 // Order is important here: only original allocation is highlighted.
1705 highlightObject ($rackData, $object_id);
1706 markupAtomGrid ($rackData, 'T');
1707 // If we have a form processed, discard user input and show new database
1708 // contents.
1709 if (!$is_submit and $is_update)
1710 mergeGridFormToRack ($rackData);
1711 echo "<td valign=top>";
1712 echo "<center>\n<h2>${rackData['name']}</h2>\n";
1713 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
1714 echo "<tr><th width='10%'>&nbsp;</th><th width='20%'>Front</th>";
1715 echo "<th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
1716 renderAtomGrid ($rackData);
9b7468b7
DO
1717 echo "<tr><th width='10%'>&nbsp;</th><th width='20%'>Front</th>";
1718 echo "<th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
e673ee24
DO
1719 echo "</table></center>\n";
1720 echo '</td>';
1721 }
1722 echo "</tr></table>";
1723 finishPortlet();
1724 echo "</td>\n";
1725
1726 echo "</form>\n";
1727 echo "</tr></table>\n";
1728}
1729
1730function renderMolecule ($mdata, $object_id)
1731{
1732 // sort data out
1733 $rackpack = array();
1734 global $loclist;
64b95774 1735 foreach ($mdata as $rua)
e673ee24
DO
1736 {
1737 $rack_id = $rua['rack_id'];
1738 $unit_no = $rua['unit_no'];
1739 $atom = $rua['atom'];
1740 if (!isset ($rackpack[$rack_id]))
1741 {
1742 $rackData = getRackData ($rack_id);
1743 for ($i = $rackData['height']; $i > 0; $i--)
1744 for ($locidx = 0; $locidx < 3; $locidx++)
1745 $rackData[$i][$locidx]['state'] = 'F';
1746 $rackpack[$rack_id] = $rackData;
1747 }
1748 $rackpack[$rack_id][$unit_no][$loclist[$atom]]['state'] = 'T';
1749 $rackpack[$rack_id][$unit_no][$loclist[$atom]]['object_id'] = $object_id;
1750 }
1751 // now we have some racks to render
64b95774 1752 foreach ($rackpack as $rackData)
e673ee24
DO
1753 {
1754 markAllSpans ($rackData);
1755 echo "<table class=molecule cellspacing=0>\n";
1756 echo "<caption>${rackData['name']}</caption>\n";
1757 echo "<tr><th width='10%'>&nbsp;</th><th width='20%'>Front</th><th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
1758 for ($i = $rackData['height']; $i > 0; $i--)
1759 {
1760 echo "<tr><th>$i</th>";
1761 for ($locidx = 0; $locidx < 3; $locidx++)
1762 {
1763 $state = $rackData[$i][$locidx]['state'];
1764 echo "<td class=state_${state}>&nbsp;</td>\n";
1765 }
1766 echo "</tr>\n";
1767 }
1768 echo "</table>\n";
1769 }
1770}
1771
1772function renderUnmountedObjectsPortlet ()
1773{
1774 startPortlet ('Unmounted objects');
1775 $objs = getUnmountedObjects();
1776 if ($objs === NULL)
1777 {
591ff2c4 1778 showError ('getUnmountedObjects() failed', __FUNCTION__);
e673ee24
DO
1779 return;
1780 }
4fbb5a00 1781 global $nextorder;
e673ee24
DO
1782 $order = 'odd';
1783 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
f76c4197 1784 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset number</th><th>Barcode</th></tr>';
e673ee24
DO
1785 foreach ($objs as $obj)
1786 {
4fbb5a00 1787 echo "<tr class=row_${order}><td><a href='".makeHref(array('page'=>'object', 'object_id'=>$obj['id']))."'>${obj['dname']}</a></td>";
e673ee24 1788 echo "<td>${obj['label']}</td>";
18d94c29 1789 echo "<td>${obj['asset_no']}</td>";
f76c4197 1790 echo "<td>${obj['barcode']}</td>";
4fbb5a00 1791 echo "</tr>";
e673ee24
DO
1792 $order = $nextorder[$order];
1793 }
1794 echo "</table><br>\n";
1795 finishPortlet();
1796}
1797
1798function renderProblematicObjectsPortlet ()
1799{
1800 startPortlet ('Problematic objects');
1801 $objs = getProblematicObjects();
1802 if ($objs === NULL)
1803 {
591ff2c4 1804 showError ('getProblematicObjects() failed', __FUNCTION__);
e673ee24
DO
1805 return;
1806 }
4fbb5a00 1807 global $nextorder;
e673ee24
DO
1808 $order = 'odd';
1809 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1810 echo '<tr><th>Type</th><th>Common name</th></tr>';
1811 foreach ($objs as $obj)
1812 {
1813 echo "<tr class=row_${order}><td>${obj['objtype_name']}</td>";
4fbb5a00 1814 echo "<td><a href='".makeHref(array('page'=>'object', 'object_id'=>$obj['id']))."'>${obj['dname']}</a></tr>";
e673ee24
DO
1815 $order = $nextorder[$order];
1816 }
1817 echo "</table><br>\n";
1818 finishPortlet();
1819}
1820
7cc02fc1
DO
1821function renderObjectSpace ()
1822{
4fbb5a00 1823 global $taglist, $tagtree;
52b34485 1824 showMessageOrError();
7cc02fc1
DO
1825 echo "<table border=0 class=objectview>\n";
1826 echo "<tr><td class=pcleft width='50%'>";
1827 startPortlet ('View all by type');
1828 $groupInfo = getObjectGroupInfo();
1829 if ($groupInfo === NULL)
1830 {
1831 showError ('getObjectGroupInfo() failed', __FUNCTION__);
1832 return;
1833 }
1834 if (count ($groupInfo) == 0)
1835 echo "No objects exist in DB";
1836 else
1837 {
1838 echo '<div align=left><ul>';
1839 foreach ($groupInfo as $gi)
4fbb5a00 1840 echo "<li><a href='".makeHref(array('page'=>'objgroup', 'group_id'=>$gi['id']))."'>${gi['name']}</a> (${gi['count']})</li>";
7cc02fc1
DO
1841 echo '</ul></div>';
1842 }
1843 finishPortlet();
1844
1845 echo '</td><td class=pcright>';
1846
1847 startPortlet ('View all by tag');
1848 if (count ($taglist) == 0)
1849 echo "No tags exist in DB";
1850 else
1851 renderTagCloud ('object');
1852 finishPortlet();
e673ee24
DO
1853 echo "</td></tr></table>\n";
1854}
1855
466dcbe6 1856function renderObjectGroup ()
7cc02fc1 1857{
4fbb5a00 1858 global $pageno, $tabno, $nextorder, $taglist, $tagtree;
52b34485 1859 showMessageOrError();
2c6c7645 1860 assertUIntArg ('group_id', __FUNCTION__, TRUE);
7cc02fc1 1861 $group_id = $_REQUEST['group_id'];
a0d54e7e
DO
1862 $tagfilter = getTagFilter();
1863 $tagfilter_str = getTagFilterStr ($tagfilter);
7cc02fc1
DO
1864 echo "<table border=0 class=objectview>\n";
1865 echo "<tr><td class=pcleft width='25%'>";
1866 startPortlet ('change type');
1867 $groupInfo = getObjectGroupInfo();
1868 if ($groupInfo === NULL)
1869 {
1870 showError ('getObjectGroupInfo() failed', __FUNCTION__);
1871 return;
1872 }
1873 if (count ($groupInfo) == 0)
1874 echo "No objects exist in DB";
1875 else
1876 {
1877 echo '<div align=left><ul>';
1878 foreach ($groupInfo as $gi)
1879 {
4fbb5a00 1880 echo "<li><a href='".makeHref(array('page'=>$pageno, 'group_id'=>$gi['id']))."${tagfilter_str}'>";
105cea6e
DO
1881 if ($gi['id'] == $group_id)
1882 echo '<strong>';
1883 echo "${gi['name']}</a>";
1884 if ($gi['id'] == $group_id)
1885 echo '</strong>';
1886 echo " (${gi['count']})";
1887 if ($gi['id'] == $group_id)
1888 echo ' &larr;';
1889 echo "</li>";
7cc02fc1
DO
1890 }
1891 echo '</ul></div>';
1892 }
1893 finishPortlet();
1894
1895 echo '</td><td class=pcleft>';
1896
11c8e4be 1897 $objects = getObjectList ($group_id, $tagfilter, getTFMode());
922b8da6 1898 startPortlet ('Objects (' . count ($objects) . ')');
7cc02fc1
DO
1899 if ($objects === NULL)
1900 {
1901 showError ('getObjectList() failed', __FUNCTION__);
1902 return;
1903 }
1904 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
f76c4197 1905 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>Barcode</th><th>Row/Rack</th><th></th></tr>';
7cc02fc1
DO
1906 $order = 'odd';
1907 foreach ($objects as $obj)
1908 {
8e700dd1
DO
1909 if (isset ($_REQUEST['hl_object_id']) and $_REQUEST['hl_object_id'] == $obj['id'])
1910 $secondclass = 'tdleft port_highlight';
1911 else
1912 $secondclass = 'tdleft';
2b3d64c5 1913 $tags = loadRackObjectTags ($obj['id']);
4fbb5a00 1914 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>";
2b3d64c5 1915 if (count ($tags))
4fbb5a00 1916 echo '<br><small>' . serializeTags ($tags, makeHref(array('page'=>$pageno, 'tab'=>'default', 'group_id'=>$group_id))."&") . '</small>';
2b3d64c5 1917 echo "</td><td class='${secondclass}'>${obj['label']}</td>";
8e700dd1 1918 echo "<td class='${secondclass}'>${obj['asset_no']}</td>";
f76c4197 1919 echo "<td class='${secondclass}'>${obj['barcode']}</td>";
7cc02fc1 1920 if ($obj['rack_id'])
4fbb5a00 1921 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>";
7cc02fc1 1922 else
8e700dd1 1923 echo "<td class='${secondclass}'>Unmounted</td>";
7cc02fc1
DO
1924 echo '</tr>';
1925 $order = $nextorder[$order];
1926 }
1927 echo '</table>';
1928 finishPortlet();
1929
1930 echo "</td><td class=pcright width='25%'>";
1931
a0d54e7e 1932 renderTagFilterPortlet ($tagfilter, 'object', 'group_id', $group_id);
7cc02fc1 1933 echo "</td></tr></table>\n";
e673ee24
DO
1934}
1935
1936function renderEmptyPortsSelect ($port_id, $type_id)
1937{
1938 $ports = getEmptyPortsOfType($type_id);
1939 usort($ports, 'sortEmptyPorts');
1940 foreach ($ports as $port)
1941 {
1942 if ($port_id == $port['Port_id'])
1943 continue;
1944 echo "<option value='${port['Port_id']}' onclick='getElementById(\"remote_port_name\").value=\"${port['Port_name']}\"; getElementById(\"remote_object_name\").value=\"${port['Object_name']}\";'>${port['Object_name']} ${port['Port_name']}</option>\n";
1945 }
1946}
1947
6ef9683b 1948function renderAllIPv4Allocations ()
e673ee24 1949{
6ef9683b 1950 $addresses = getAllIPv4Allocations();
e673ee24
DO
1951 usort($addresses, 'sortObjectAddressesAndNames');
1952 foreach ($addresses as $address)
1953 {
1954 echo "<option value='${address['ip']}' onclick='getElementById(\"ip\").value=\"${address['ip']}\";'>${address['object_name']} ${address['name']} ${address['ip']}</option>\n";
1955 }
1956}
1957
1958// History viewer for history-enabled simple dictionaries.
1959function renderHistory ($object_type, $object_id)
1960{
1961 switch ($object_type)
1962 {
1963 case 'row':
1964 $query = "select ctime, user_name, name, deleted, comment from RackRowHistory where id = ${object_id} order by ctime";
1965 $header = '<tr><th>change time</th><th>author</th><th>rack row name</th><th>is deleted?</th><th>rack row comment</th></tr>';
1966 $extra = 4;
1967 break;
1968 case 'rack':
1969 $query =
51690ad4
DY
1970 "select ctime, user_name, rh.name, rh.deleted, rr.name as name, rh.height, rh.comment " .
1971 "from RackHistory as rh left join RackRow as rr on rh.row_id = rr.id " .
1972 "where rh.id = ${object_id} order by ctime";
e673ee24
DO
1973 $header = '<tr><th>change time</th><th>author</th><th>rack name</th><th>is deleted?</th><th>rack row name</th><th>rack height</th><th>rack comment</th></tr>';
1974 $extra = 6;
1975 break;
1976 case 'object':
1977 $query =
f76c4197 1978 "select ctime, user_name, RackObjectHistory.name as name, label, barcode, asset_no, deleted, has_problems, dict_value, comment " .
00f6f1e4
DY
1979 "from RackObjectHistory inner join Dictionary on objtype_id = dict_key join Chapter on Dictionary.chapter_id = Chapter.id " .
1980 "where Chapter.name = 'RackObjectType' and RackObjectHistory.id=${object_id} order by ctime";
f76c4197 1981 $header = '<tr><th>change time</th><th>author</th><th>common name</th><th>visible label</th><th>barcode</th><th>asset no</th><th>is deleted?</th><th>has problems?</th><th>object type</th><th>comment</th></tr>';
e673ee24
DO
1982 $extra = 9;
1983 break;
1984 default:
591ff2c4 1985 showError ("Uknown object type '${object_type}'", __FUNCTION__);
e673ee24
DO
1986 return;
1987 }
1988 global $dbxlink;
1989 $result = $dbxlink->query ($query);
1990 if ($result == NULL)
1991 {
591ff2c4 1992 showError ('SQL query failed', __FUNCTION__);
e673ee24
DO
1993 return;
1994 }
1995 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1996 $order = 'odd';
1997 global $nextorder;
1998 echo $header;
1999 while ($row = $result->fetch (PDO::FETCH_NUM))
2000 {
2001 echo "<tr class=row_${order}><td>${row[0]}</td>";
2002 for ($i = 1; $i <= $extra; $i++)
2003 echo "<td>" . $row[$i] . "</td>";
2004 echo "</tr>\n";
2005 $order = $nextorder[$order];
2006 }
2007 echo "</table><br>\n";
2008}
2009
2010function renderRackspaceHistory ()
2011{
4fbb5a00 2012 global $nextorder, $pageno, $tabno;
e673ee24
DO
2013 $order = 'odd';
2014 $history = getRackspaceHistory();
2015 // Show the last operation by default.
2016 if (isset ($_REQUEST['op_id']))
2017 $op_id = $_REQUEST['op_id'];
2018 elseif (isset ($history[0]['mo_id']))
2019 $op_id = $history[0]['mo_id'];
2020 else $op_id = NULL;
2021
2022 $omid = NULL;
2023 $nmid = NULL;
2024 $object_id = 1;
2025 if ($op_id)
2026 list ($omid, $nmid) = getOperationMolecules ($op_id);
2027
2028 // Main layout starts.
2029 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
2030
2031 // Left top portlet with old allocation.
2032 echo "<tr><td class=pcleft>";
2033 startPortlet ('Old allocation');
2034 if ($omid)
2035 {
2036 $oldMolecule = getMolecule ($omid);
2037 renderMolecule ($oldMolecule, $object_id);
2038 }
2039 else
2040 echo "nothing";
2041 finishPortlet();
2042
2043 echo '</td><td class=pcright>';
2044
2045 // Right top portlet with new allocation
2046 startPortlet ('New allocation');
2047 if ($nmid)
2048 {
2049 $newMolecule = getMolecule ($nmid);
2050 renderMolecule ($newMolecule, $object_id);
2051 }
2052 else
2053 echo "nothing";
2054 finishPortlet();
737a3f72 2055
e673ee24 2056 echo '</td></tr><tr><td colspan=2>';
737a3f72 2057
e673ee24
DO
2058 // Bottom portlet with list
2059
2060 startPortlet ('Rackspace allocation history');
2061 echo "<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>\n";
2062 echo "<tr><th>timestamp</th><th>author</th><th>rack object ID</th><th>rack object type</th><th>rack object name</th><th>comment</th></tr>\n";
2063 foreach ($history as $row)
2064 {
2065 if ($row['mo_id'] == $op_id)
2066 $class = 'hl';
2067 else
2068 $class = "row_${order}";
4fbb5a00 2069 echo "<tr class=${class}><td><a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno, 'op_id'=>$row['mo_id']))."'>${row['ctime']}</a></td>";
e673ee24
DO
2070 echo "<td>${row['user_name']}</td>";
2071 echo "<td>${row['ro_id']}</td><td>${row['objtype_name']}</td><td>${row['name']}</td><td>${row['comment']}</td>\n";
2072 echo "</tr>\n";
2073 $order = $nextorder[$order];
2074 }
2075 echo "</table>\n";
2076 finishPortlet();
737a3f72 2077
e673ee24 2078 echo '</td></tr></table>';
e673ee24
DO
2079}
2080
d9f8a37a 2081function renderIPv4SpaceRecords ($tree, &$tagcache, $baseurl, $target = 0, $level = 1)
d65353ad
DO
2082{
2083 $self = __FUNCTION__;
2084 foreach ($tree as $item)
2085 {
737a3f72 2086 $total = $item['addrt'];
64347dcf
DO
2087 if (getConfigVar ('IPV4_TREE_SHOW_USAGE') == 'yes')
2088 {
2089 loadIPv4AddrList ($item); // necessary to compute router list and address counter
2090 $used = $item['addrc'];
2091 }
2092 else
2093 {
2094 $item['addrlist'] = array();
2095 $item['addrc'] = 0;
2096 }
0137d53c
DO
2097 if (isset ($item['id']))
2098 {
fec0c8da 2099 if ($item['symbol'] == 'node-collapsed')
d9f8a37a 2100 $expandurl = "${baseurl}&eid=" . $item['id'] . "#netid" . $item['id'];
fec0c8da 2101 elseif ($item['symbol'] == 'node-expanded')
d9f8a37a 2102 $expandurl = $baseurl . ($item['parent_id'] ? "&eid=${item['parent_id']}#netid${item['parent_id']}" : '');
fec0c8da
DO
2103 else
2104 $expandurl = '';
0137d53c 2105 echo "<tr valign=top>";
fec0c8da 2106 printIPv4NetInfoTDs ($item, 'tdleft', $level, $item['symbol'], $expandurl);
0137d53c 2107 echo "<td class=tdcenter>";
d9f8a37a
DO
2108 if ($target == $item['id'])
2109 echo "<a name=netid${target}></a>";
64347dcf
DO
2110 if (getConfigVar ('IPV4_TREE_SHOW_USAGE') == 'yes')
2111 {
2112 renderProgressBar ($total ? $used/$total : 0);
2113 echo "<br><small>${used}/${total}</small>";
2114 }
2115 else
2116 echo "<small>${total}</small>";
2117 echo "</td>";
0137d53c 2118 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
b6b87070 2119 printRoutersTD (findRouters ($item['addrlist']), $tagcache);
0137d53c 2120 echo "</tr>";
fec0c8da 2121 if ($item['symbol'] == 'node-expanded' or $item['symbol'] == 'node-expanded-static')
d9f8a37a 2122 $self ($item['kids'], $tagcache, $baseurl, $target, $level + 1);
0137d53c
DO
2123 }
2124 else
2125 {
0137d53c 2126 echo "<tr valign=top>";
fec0c8da 2127 printIPv4NetInfoTDs ($item, 'tdleft sparenetwork', $level, $item['symbol']);
0137d53c 2128 echo "<td class=tdcenter>";
64347dcf
DO
2129 if (getConfigVar ('IPV4_TREE_SHOW_USAGE') == 'yes')
2130 {
2131 renderProgressBar ($used/$total, 'sparenetwork');
2132 echo "<br><small>${used}/${total}</small>";
2133 }
2134 else
2135 echo "<small>${total}</small>";
2136 echo "</td><td>&nbsp;</td></tr>";
0137d53c 2137 }
d65353ad
DO
2138 }
2139}
2140
04d619d0 2141function renderIPv4Space ()
e673ee24 2142{
4fbb5a00 2143 global $pageno, $tabno;
932cf41f 2144 $tagfilter = getTagFilter();
94a40058 2145 $netlist = getIPv4NetworkList ($tagfilter, getTFMode());
4fbb5a00
DY
2146
2147
94a40058 2148 $netcount = count ($netlist);
5388794d
DO
2149 // expand request can take either natural values or "ALL". Zero means no expanding.
2150 $eid = isset ($_REQUEST['eid']) ? $_REQUEST['eid'] : 0;
2151 $tree = prepareIPv4Tree ($netlist, $eid);
3630d1fb
DO
2152
2153 echo "<table border=0 class=objectview>\n";
2154 echo "<tr><td class=pcleft>";
94a40058 2155 startPortlet ("networks (${netcount})");
5388794d
DO
2156 echo '<h4>';
2157 if ($eid === 0)
4fbb5a00 2158 echo 'auto-collapsing at threshold ' . getConfigVar ('TREE_THRESHOLD') . " (<a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno, 'eid'=>'ALL'))."'>expand all</a>)";
5388794d 2159 elseif ($eid === 'ALL')
4fbb5a00 2160 echo "expanding all (<a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno))."'>auto-collapse</a>)";
5388794d
DO
2161 else
2162 {
2163 $netinfo = getIPv4NetworkInfo ($eid);
4fbb5a00 2164 echo "expanding ${netinfo['ip']}/${netinfo['mask']} (<a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno))."'>auto-collapse</a> / <a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno, 'eid'=>'ALL'))."'>expand&nbsp;all</a>)";
5388794d
DO
2165 }
2166 echo "</h4><table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
64347dcf 2167 echo "<tr><th>prefix</th><th>name/tags</th><th>capacity</th>";
f0ed1181 2168 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
57dece2f
DO
2169 echo "<th>routed by</th>";
2170 echo "</tr>\n";
fec0c8da 2171 $tagcache = array();
4fbb5a00 2172 $baseurl = makeHref(array('page'=>$pageno, 'tab'=>$tabno)) . getTagFilterStr ($tagfilter);
5388794d 2173 renderIPv4SpaceRecords ($tree, $tagcache, $baseurl, $eid);
e673ee24 2174 echo "</table>\n";
a7fe7729 2175 finishPortlet();
74ccacff 2176 echo '</td><td class=pcright>';
5b7bd02e 2177 renderTagFilterPortlet ($tagfilter, 'ipv4net');
74ccacff 2178 echo "</td></tr></table>\n";
f973f491 2179}
a7fe7729 2180
f973f491
DO
2181function renderIPv4SLB ()
2182{
4fbb5a00 2183 global $page, $nextorder;
a7fe7729 2184
6fec9f39 2185 startPortlet ('SLB configuration');
b3c50e6c 2186 echo "<table border=0 width='100%'><tr>";
ee437dab 2187 foreach (array ('ipv4vslist', 'ipv4rsplist', 'rservers', 'lbs') as $pno)
4fbb5a00 2188 echo "<td><h3><a href='".makeHref(array('page'=>$pno))."'>" . $page[$pno]['title'] . "</a></h3></td>";
b3c50e6c
DO
2189 echo '</tr></table>';
2190 finishPortlet();
2191
c3bdc503 2192 $summary = getSLBSummary();
6fec9f39 2193 startPortlet ('SLB tactical overview');
4cadac8f
DO
2194 // A single id-keyed array isn't used here to preserve existing
2195 // order of LBs returned by getSLBSummary()
c3bdc503
DO
2196 $lblist = array();
2197 $lbdname = array();
4cadac8f 2198 foreach ($summary as $vipdata)
da04825a 2199 foreach (array_keys ($vipdata['lblist']) as $lb_object_id)
c3bdc503
DO
2200 if (!in_array ($lb_object_id, $lblist))
2201 {
2202 $oi = getObjectInfo ($lb_object_id);
2203 $lbdname[$lb_object_id] = $oi['dname'];
2204 $lblist[] = $lb_object_id;
2205 }
2206 if (!count ($summary))
2207 echo 'none configured';
2208 else
2209 {
80e85ea1 2210 $order = 'odd';
c3bdc503 2211 echo "<table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
b1a970c7 2212 echo "<tr valign=top><td>&nbsp;</td>";
c3bdc503 2213 foreach ($lblist as $lb_object_id)
b1a970c7 2214 {
4fbb5a00 2215 #echo "<th><a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$lb_object_id))."'>" . $lbdname[$lb_object_id] . "</a></th>";
b1a970c7
DO
2216 echo '<td>';
2217 renderLBCell ($lb_object_id);
2218 echo '</td>';
2219 }
c3bdc503 2220 echo "</tr>\n";
4cadac8f
DO
2221 foreach ($summary as $vsid => $vsdata)
2222 {
b1a970c7
DO
2223 echo "<tr class=row_${order}><td class=tdleft>";
2224 renderVSCell ($vsid);
6fec9f39 2225 echo "</td>";
4cadac8f 2226 foreach ($lblist as $lb_object_id)
da04825a 2227 {
60fbcece 2228 echo '<td class=tdleft>';
2b4eee17 2229 if (!isset ($vsdata['lblist'][$lb_object_id]))
da04825a
DO
2230 echo '&nbsp;';
2231 else
6fec9f39
DO
2232 {
2233 echo $vsdata['lblist'][$lb_object_id]['size'];
4fbb5a00 2234// echo " (<a href='".makeHref(array('page'=>'ipv4rspool', 'pool_id'=>$vsdata['lblist'][$lb_object_id]['id'])). "'>";
79a9edb4 2235// echo $vsdata['lblist'][$lb_object_id]['name'] . '</a>)';
6fec9f39 2236 }
da04825a
DO
2237 echo '</td>';
2238 }
2239 echo "</tr>\n";
80e85ea1 2240 $order = $nextorder[$order];
4cadac8f 2241 }
c3bdc503
DO
2242 echo "</table>\n";
2243 }
a7fe7729 2244 finishPortlet ();
e673ee24
DO
2245}
2246
04d619d0 2247function renderIPv4SpaceEditor ()
e673ee24 2248{
4fbb5a00 2249 global $pageno, $tabno;
e673ee24 2250 showMessageOrError();
2a201216 2251
a262e150
DO
2252 // IPv4 validator
2253?>
2254 <script type="text/javascript">
2255 function init() {
2256 document.add_new_range.range.setAttribute('match', "^\\d\\d?\\d?\\.\\d\\d?\\d?\\.\\d\\d?\\d?\\.\\d\\d?\\d?\\/\\d\\d?$");
2257
2258 Validate.init();
2259 }
2260 window.onload=init;
2261 </script>
2262<?php
2263
4c0653e2 2264 startPortlet ("Add new");
04d619d0 2265 echo '<table border=0 cellpadding=10 align=center>';
7056988c
DO
2266 // This form requires a name, so JavaScript validator can find it.
2267 // No printOpFormIntro() hence
4fbb5a00 2268 echo "<form method=post name='add_new_range' action='".makeHrefProcess()."'>\n";
42023f03 2269 echo "<input type=hidden name=op value=addIPv4Prefix>\n";
04d619d0
DO
2270 // tags column
2271 echo '<tr><td rowspan=4><h3>assign tags</h3>';
5c0bb421 2272 renderTagSelect();
04d619d0
DO
2273 echo '</td>';
2274 // inputs column
2275 echo "<th class=tdright>prefix</th><td class=tdleft><input type=text name='range' size=18 class='live-validate' tabindex=1></td>";
2276 echo "<tr><th class=tdright>name</th><td class=tdleft><input type=text name='name' size='20' tabindex=2></td></tr>";
0c16ef0c 2277 echo "<tr><th class=tdright>connected network</th><td class=tdleft><input type=checkbox name='is_bcast' tabindex=3></td></tr>";
04d619d0 2278 echo "<tr><td colspan=2>";
4c0653e2 2279 printImageHREF ('CREATE', 'Add a new network', TRUE, 4);
04d619d0 2280 echo '</td></tr>';
2a201216 2281 echo "</form></table><br><br>\n";
5c0bb421 2282 finishPortlet();
2a201216 2283
b18d26dc 2284 $addrspaceList = getIPv4NetworkList();
e43a2de4 2285 if (count ($addrspaceList))
e673ee24 2286 {
e43a2de4 2287 startPortlet ('Manage existing (' . count ($addrspaceList) . ')');
04d619d0
DO
2288 echo "<table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
2289 echo "<tr><th>&nbsp;</th><th>prefix</th><th>name</th><th>&nbsp;</th></tr>";
0c16ef0c 2290 foreach ($addrspaceList as $netinfo)
e673ee24 2291 {
0b9c98d7 2292 echo "<form method=post action='".makeHrefProcess(array('op'=>'updIPv4Prefix', 'id'=>$netinfo['id']))."'>";
e43a2de4
DO
2293 echo "<tr valign=top><td>";
2294 if (getConfigVar ('IPV4_JAYWALK') == 'yes')
2295 {
2296 echo "<a href='".makeHrefProcess(array('op'=>'delIPv4Prefix', 'id'=>$netinfo['id']))."'>";
2297 printImageHREF ('destroy', 'Delete this prefix');
2298 echo "</a>";
2299 }
2300 else // only render clickable image for empty networks
2301 {
2302 $netdata = getIPv4NetworkInfo ($netinfo['id']);
2303 loadIPv4AddrList ($netdata);
2304 if (count ($netdata['addrlist']))
2305 printImageHREF ('nodestroy', 'There are ' . count ($netdata['addrlist']) . ' allocations inside');
2306 else
2307 {
2308 echo "<a href='".makeHrefProcess(array('op'=>'delIPv4Prefix', 'id'=>$netinfo['id']))."'>";
2309 printImageHREF ('destroy', 'Delete this prefix');
2310 echo "</a>";
2311 }
2312
2313 }
2314 echo "</td>\n<td class=tdleft>${netinfo['ip']}/${netinfo['mask']}</td>";
0c16ef0c 2315 echo "<td><input type=text name=name size=40 value='${netinfo['name']}'>";
04d619d0
DO
2316 echo "</td><td>";
2317 printImageHREF ('save', 'Save changes', TRUE);
2318 echo "</td></tr></form>\n";
e673ee24 2319 }
04d619d0
DO
2320 echo "</table>";
2321 finishPortlet();
e673ee24 2322 }
e673ee24
DO
2323}
2324
beb9e88a 2325function renderIPv4Network ($id)
e673ee24 2326{
4fbb5a00 2327 global $pageno, $tabno, $aac2;
545478d0
DO
2328 $netmaskbylen = array
2329 (
2330 32 => '255.255.255.255',
2331 31 => '255.255.255.254',
2332 30 => '255.255.255.252',
2333 29 => '255.255.255.248',
2334 28 => '255.255.255.240',
2335 27 => '255.255.255.224',
2336 26 => '255.255.255.192',
2337 25 => '255.255.255.128',
2338 24 => '255.255.255.0',
2339 23 => '255.255.254.0',
2340 22 => '255.255.252.0',
2341 21 => '255.255.248.0',
2342 20 => '255.255.240.0',
2343 19 => '255.255.224.0',
2344 18 => '255.255.192.0',
2345 17 => '255.255.128.0',
2346 16 => '255.255.0.0',
2347 15 => '255.254.0.0',
2348 14 => '255.252.0.0',
2349 13 => '255.248.0.0',
2350 12 => '255.240.0.0',
2351 11 => '255.224.0.0',
2352 10 => '255.192.0.0',
2353 9 => '255.128.0.0',
2354 8 => '255.0.0.0',
2355 7 => '254.0.0.0',
2356 6 => '252.0.0.0',
2357 5 => '248.0.0.0',
2358 4 => '240.0.0.0',
2359 3 => '224.0.0.0',
2360 2 => '192.0.0.0',
2361 1 => '128.0.0.0'
2362 );
2363 $wildcardbylen = array
2364 (
2365 32 => '0.0.0.0',
2366 31 => '0.0.0.1',
2367 30 => '0.0.0.3',
2368 29 => '0.0.0.7',
2369 28 => '0.0.0.15',
2370 27 => '0.0.0.31',
2371 26 => '0.0.0.63',
2372 25 => '0.0.0.127',
2373 24 => '0.0.0.255',
2374 23 => '0.0.1.255',
2375 22 => '0.0.3.255',
2376 21 => '0.0.7.255',
2377 20 => '0.0.15.255',
2378 19 => '0.0.31.255',
2379 18 => '0.0.63.255',
2380 17 => '0.0.127.255',
2381 16 => '0.0.255.25',
2382 15 => '0.1.255.255',
2383 14 => '0.3.255.255',
2384 13 => '0.7.255.255',
2385 12 => '0.15.255.255',
2386 11 => '0.31.255.255',
2387 10 => '0.63.255.255',
2388 9 => '0.127.255.255',
2389 8 => '0.255.255.255',
2390 7 => '1.255.255.255',
2391 6 => '3.255.255.255',
2392 5 => '7.255.255.255',
2393 4 => '15.255.255.255',
2394 3 => '31.255.255.255',
2395 2 => '63.255.255.255',
2396 1 => '127.255.255.255'
2397 );
b901bf1f 2398 $maxperpage = getConfigVar ('IPV4_ADDRS_PER_PAGE');
e673ee24
DO
2399 if (isset($_REQUEST['pg']))
2400 $page = $_REQUEST['pg'];
2401 else
2402 $page=0;
2403
b6b87070
DO
2404 $range = getIPv4NetworkInfo ($id);
2405 loadIPv4AddrList ($range);
2034d968
DO
2406 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
2407 echo "<tr><td colspan=2 align=center><h1>${range['ip']}/${range['mask']}</h1><h2>${range['name']}</h2></td></tr>\n";
2408
2409 echo "<tr><td class=pcleft width='50%'>";
2410 startPortlet ('summary');
2411 $total = ($range['ip_bin'] | $range['mask_bin_inv']) - ($range['ip_bin'] & $range['mask_bin']) + 1;
2412 $used = count ($range['addrlist']);
2413 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
04d619d0
DO
2414
2415 echo "<tr><th width='50%' class=tdright>%% used:</th><td class=tdleft>";
2034d968
DO
2416 renderProgressBar ($used/$total);
2417 echo "&nbsp;${used}/${total}</td></tr>\n";
04d619d0 2418
001e61fa
DO
2419 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
2420 {
3444ecf2
DO
2421 // Build a backtrace from all parent networks.
2422 $clen = $range['mask'];
2423 $backtrace = array();
2424 while (NULL !== ($upperid = getIPv4AddressNetworkId ($range['ip'], $clen)))
2425 {
2426 $upperinfo = getIPv4NetworkInfo ($upperid);
2427 $clen = $upperinfo['mask'];
2428 $backtrace[] = $upperid;
2429 }
2430 $arrows = count ($backtrace);
2431 foreach (array_reverse ($backtrace) as $ancestorid)
001e61fa
DO
2432 {
2433 $ainfo = getIPv4NetworkInfo ($ancestorid);
3444ecf2
DO
2434 echo "<tr><th width='50%' class=tdright>";
2435 for ($i = 0; $i < $arrows; $i++)
2436 echo '&uarr;';
2437 $arrows--;
4fbb5a00 2438 echo "</th><td class=tdleft><a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno, 'id'=>$ainfo['id']))."'>${ainfo['ip']}/${ainfo['mask']}</a></td></tr>";
001e61fa 2439 }
3444ecf2
DO
2440 echo "<tr><th width='50%' class=tdright>&rarr;</th>";
2441 echo "<td class=tdleft>${range['ip']}/${range['mask']}</td></tr>";
001e61fa
DO
2442 // FIXME: get and display nested networks
2443 // $theitem = pickLeaf ($ipv4tree, $id);
2444 }
2445
545478d0
DO
2446 echo "<tr><th width='50%' class=tdright>Netmask:</th><td class=tdleft>";
2447 echo $netmaskbylen[$range['mask']];
2448 echo "</td></tr>\n";
04d619d0 2449
c607ab55
DO
2450 echo "<tr><th width='50%' class=tdright>Netmask:</th><td class=tdleft>";
2451 printf ('0x%08X', binMaskFromDec ($range['mask']));
2452 echo "</td></tr>\n";
2453
545478d0
DO
2454 echo "<tr><th width='50%' class=tdright>Wildcard bits:</th><td class=tdleft>";
2455 echo $wildcardbylen[$range['mask']];
2456 echo "</td></tr>\n";
04d619d0 2457
f3d0cb20 2458 $routers = findRouters ($range['addrlist']);
f0ed1181 2459 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes' and count ($routers))
04d619d0 2460 {
57dece2f 2461 echo "<tr><th width='50%' class=tdright>Routed by:</th>";
f3d0cb20 2462 printRoutersTD ($routers);
57dece2f 2463 echo "</tr>\n";
04d619d0
DO
2464 }
2465
4fbb5a00 2466 printTagTRs (makeHref(array('page'=>'ipv4space', 'tab'=>'default'))."&");
2034d968
DO
2467 echo "</table><br>\n";
2468 finishPortlet();
e1ae3fb4
AD
2469
2470 renderFilesPortlet ('ipv4net', $id);
2034d968 2471 echo "</td>\n";
e673ee24 2472
2034d968
DO
2473 echo "<td class=pcright>";
2474 startPortlet ('details');
e673ee24
DO
2475 $startip = $range['ip_bin'] & $range['mask_bin'];
2476 $endip = $range['ip_bin'] | $range['mask_bin_inv'];
2477 $realstartip = $startip;
2478 $realendip = $endip;
2479 $numpages = 0;
2480 if($endip - $startip > $maxperpage)
2481 {
e673ee24
DO
2482 $numpages = ($endip - $startip)/$maxperpage;
2483 $startip = $startip + $page * $maxperpage;
2484 $endip = $startip + $maxperpage-1;
2485 }
2486 echo "<center>";
b901bf1f
DO
2487 if ($numpages)
2488 echo '<h3>' . long2ip ($startip) . ' ~ ' . long2ip ($endip) . '</h3>';
e673ee24
DO
2489 for ($i=0; $i<$numpages; $i++)
2490 {
2491 if ($i == $page)
2492 echo "<b>$i</b> ";
2493 else
4fbb5a00 2494 echo "<a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno, 'id'=>$id, 'pg'=>$i))."'>$i</a> ";
e673ee24
DO
2495 }
2496 echo "</center>";
2497
beb9e88a 2498 echo "<table class='widetable' border=0 cellspacing=0 cellpadding=5 align='center' width='100%'>\n";
e673ee24
DO
2499 echo "<tr><th>Address</th><th>Name</th><th>Allocation</th></tr>\n";
2500
2501
b2035dca
DO
2502 for ($ip = $startip; $ip <= $endip; $ip++) :
2503 if (isset ($_REQUEST['hl_ipv4_addr']) and ip2long ($_REQUEST['hl_ipv4_addr']) == $ip)
2504 $secondstyle = 'tdleft port_highlight';
2727c7df 2505 else
b2035dca
DO
2506 $secondstyle = 'tdleft';
2507 if (!isset ($range['addrlist'][$ip]))
e673ee24 2508 {
4fbb5a00 2509 echo "<tr><td class=tdleft><a href='".makeHref(array('page'=>'ipaddress', 'ip'=>ip_long2quad($ip)))."'>" . ip_long2quad($ip);
b2035dca
DO
2510 echo "</a></td><td class='${secondstyle}'>&nbsp;</td><td class='${secondstyle}'>&nbsp;</td></tr>\n";
2511 continue;
2512 }
b2035dca 2513 $addr = $range['addrlist'][$ip];
2d318652 2514 echo "<tr class='${addr['class']}'>";
e673ee24 2515
4fbb5a00 2516 echo "<td class=tdleft><a href='".makeHref(array('page'=>'ipaddress', 'ip'=>$addr['ip']))."'>${addr['ip']}</a></td>";
b2035dca
DO
2517 echo "<td class='${secondstyle}'>${addr['name']}</td><td class='${secondstyle}'>";
2518 $delim = '';
2519 $prologue = '';
2520 if ( $addr['reserved'] == 'yes')
2521 {
2d318652 2522 echo "<strong>RESERVED</strong> ";
b2035dca
DO
2523 $delim = '; ';
2524 }
2d318652 2525 foreach ($range['addrlist'][$ip]['allocs'] as $ref)
b2035dca 2526 {
beb9e88a 2527 echo $delim . $aac2[$ref['type']];
4fbb5a00 2528 echo "<a href='".makeHref(array('page'=>'object', 'object_id'=>$ref['object_id'], 'hl_ipv4_addr'=>$addr['ip']))."'>";
b2035dca
DO
2529 echo $ref['name'] . (empty ($ref['name']) ? '' : '@');
2530 echo "${ref['object_name']}</a>";
2531 $delim = '; ';
2532 }
2533 if ($delim != '')
2534 {
6131056c 2535 $delim = '';
b2035dca
DO
2536 $prologue = '<br>';
2537 }
2d318652 2538 foreach ($range['addrlist'][$ip]['lblist'] as $ref)
b2035dca
DO
2539 {
2540 echo $prologue;
602663f4 2541 $prologue = '';
4fbb5a00
DY
2542 echo "${delim}<a href='".makeHref(array('page'=>'object', 'object_id'=>$ref['object_id']))."'>";
2543 echo "${ref['object_name']}</a>:<a href='".makeHref(array('page'=>'ipv4vs', 'vs_id'=>$ref['vs_id']))."'>";
b2035dca
DO
2544 echo "${ref['vport']}/${ref['proto']}</a>&rarr;";
2545 $delim = '; ';
2546 }
2547 if ($delim != '')
2548 {
2549 $delim = '';
2550 $prologue = '<br>';
e673ee24 2551 }
2d318652 2552 foreach ($range['addrlist'][$ip]['rslist'] as $ref)
b2035dca
DO
2553 {
2554 echo $prologue;
2555 $prologue = '';
4fbb5a00 2556 echo "${delim}&rarr;${ref['rsport']}@<a href='".makeHref(array('page'=>'ipv4rspool', 'pool_id'=>$ref['rspool_id']))."'>";
b2035dca
DO
2557 echo "${ref['rspool_name']}</a>";
2558 $delim = '; ';
2559 }
2560 echo "</td></tr>\n";
2561 endfor;
2727c7df 2562 // end of iteration
e673ee24
DO
2563
2564 echo "</table>";
2034d968
DO
2565 finishPortlet();
2566 echo "</td></tr></table>\n";
e673ee24
DO
2567}
2568
53ef3908 2569function renderIPv4NetworkProperties ($id)
e673ee24 2570{
e673ee24 2571 showMessageOrError();
53ef3908
DO
2572 $netdata = getIPv4NetworkInfo ($id);
2573 echo "<center><h1>${netdata['ip']}/${netdata['mask']}</h1></center>\n";
e673ee24 2574 echo "<table border=0 cellpadding=10 cellpadding=1 align='center'>\n";
7056988c 2575 printOpFormIntro ('editRange');
53ef3908
DO
2576 echo "<tr><td class='tdright'>Name:</td><td class='tdleft'><input type=text name=name size=20 value='${netdata['name']}'></tr>";
2577 echo "<tr><td colspan=2 class=tdcenter>";
2578 printImageHREF ('SAVE', 'Save changes', TRUE);
2579 echo "</td></form></tr></table>\n";
e673ee24
DO
2580}
2581
2d318652 2582function renderIPv4Address ($dottedquad)
e673ee24 2583{
4fbb5a00 2584 global $aat;
2d318652 2585 $address = getIPv4Address ($dottedquad);
68225375 2586 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
2d318652
DO
2587 echo "<tr><td colspan=2 align=center><h1>${dottedquad}</h1></td></tr>\n";
2588 if (!empty ($address['name']))
68225375 2589 echo "<tr><td colspan=2 align=center><h2>${address['name']}</h2></td></tr>\n";
e673ee24 2590
68225375
DO
2591 echo "<tr><td class=pcleft>";
2592 startPortlet ('summary');
2593 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
04d619d0 2594 echo "<tr><th width='50%' class=tdright>Allocations:</th><td class=tdleft>" . count ($address['allocs']) . "</td></tr>\n";
68225375
DO
2595 echo "<tr><th width='50%' class=tdright>Originated NAT connections:</th><td class=tdleft>" . count ($address['outpf']) . "</td></tr>\n";
2596 echo "<tr><th width='50%' class=tdright>Arriving NAT connections:</th><td class=tdleft>" . count ($address['inpf']) . "</td></tr>\n";
04d619d0 2597 echo "<tr><th width='50%' class=tdright>SLB virtual services:</th><td class=tdleft>" . count ($address['lblist']) . "</td></tr>\n";
68225375
DO
2598 echo "<tr><th width='50%' class=tdright>SLB real servers:</th><td class=tdleft>" . count ($address['rslist']) . "</td></tr>\n";
2599 printTagTRs();
2600 echo "</table><br>\n";
2601 finishPortlet();
2602 echo "</td>\n";
e673ee24 2603
68225375 2604 echo "<td class=pcright>";
e673ee24 2605
f74d96c6 2606 if (isset ($address['class']))
59bebe2b 2607 {
8e700dd1 2608 startPortlet ('allocations');
2d318652
DO
2609 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
2610 echo "<tr><th>object</th><th>OS interface</th><th>allocation type</th></tr>\n";
2611 $class = $address['class'];
2612 // render all allocation records for this address the same way
59bebe2b 2613 if ($address['reserved'] == 'yes')
2d318652
DO
2614 echo "<tr class='${class}'><td colspan=2>&nbsp;</td><td class=tdleft><strong>RESERVED</strong></td></tr>";
2615 foreach ($address['allocs'] as $bond)
59bebe2b 2616 {
8e700dd1
DO
2617 if (isset ($_REQUEST['hl_object_id']) and $_REQUEST['hl_object_id'] == $bond['object_id'])
2618 $secondclass = 'tdleft port_highlight';
2619 else
2620 $secondclass = 'tdleft';
4fbb5a00 2621 echo "<tr class='$class'><td class=tdleft><a href='".makeHref(array('page'=>'object', 'object_id'=>$bond['object_id'], 'hl_ipv4_addr'=>$dottedquad))."'>${bond['object_name']}</td><td class='${secondclass}'>${bond['name']}</td><td class='${secondclass}'><strong>";
52c836b1
DO
2622 echo $aat[$bond['type']];
2623 echo "</strong></td></tr>\n";
59bebe2b
DO
2624 }
2625 echo "</table><br><br>";
2626 finishPortlet();
2627 }
e673ee24 2628
f3d0cb20
DO
2629 // FIXME: The returned list is structured differently, than we expect it to be. One of the sides
2630 // must be fixed.
2d318652 2631 if (count ($address['lblist']))
e673ee24 2632 {
2d318652
DO
2633 startPortlet ('Virtual services (' . count ($address['lblist']) . ')');
2634 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
59bebe2b 2635 echo "<tr><th>VS</th><th>name</th></tr>\n";
2d318652 2636 foreach ($address['lblist'] as $vsinfo)
e673ee24 2637 {
4fbb5a00 2638 echo "<tr><td class=tdleft><a href='".makeHref(array('page'=>'ipv4vs', 'vs_id'=>$vsinfo['vs_id']))."'>";
59bebe2b 2639 echo buildVServiceName ($vsinfo) . "</a></td><td class=tdleft>";
5fe1ed76 2640 echo $vsinfo['name'] . "</td></tr>\n";
e673ee24 2641 }
59bebe2b
DO
2642 echo "</table><br><br>";
2643 finishPortlet();
e673ee24 2644 }
5fe1ed76
DO
2645
2646 if (count ($address['rslist']))
2647 {
2648 startPortlet ('Real servers (' . count ($address['rslist']) . ')');
2d318652 2649 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
53f4b619 2650 echo "<tr><th>&nbsp;</th><th>port</th><th>RS pool</th></tr>\n";
5fe1ed76
DO
2651 foreach ($address['rslist'] as $rsinfo)
2652 {
2653 echo "<tr><td>";
2654 if ($rsinfo['inservice'] == 'yes')
2655 printImageHREF ('inservice', 'in service');
2656 else
2657 printImageHREF ('notinservice', 'NOT in service');
4fbb5a00 2658 echo "</td><td class=tdleft>${rsinfo['rsport']}</td><td class=tdleft><a href='".makeHref(array('page'=>'ipv4rspool', 'pool_id'=>$rsinfo['rspool_id']))."'>";
2d318652 2659 echo $rsinfo['rspool_name'] . "</a></td></tr>\n";
5fe1ed76
DO
2660 }
2661 echo "</table><br><br>";
2662 finishPortlet();
2663 }
2664
68225375
DO
2665 if (count ($address['outpf']))
2666 {
105a3bc8 2667 startPortlet ('departing NAT rules');
2d318652 2668 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
105a3bc8
DO
2669 echo "<tr><th>proto</th><th>from</th><th>to</th><th>comment</th></tr>\n";
2670 foreach ($address['outpf'] as $rule)
b62ff880 2671 echo "<tr><td>${rule['proto']}</td><td>${rule['localip']}:${rule['localport']}</td><td>${rule['remoteip']}:${rule['remoteport']}</td><td>${rule['description']}</td></tr>";
105a3bc8 2672 echo "</table>";
68225375
DO
2673 finishPortlet();
2674 }
105a3bc8
DO
2675
2676 if (count ($address['inpf']))
2677 {
2678 startPortlet ('arriving NAT rules');
2d318652 2679 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
105a3bc8
DO
2680 echo "<tr><th>proto</th><th>from</th><th>to</th><th>comment</th></tr>\n";
2681 foreach ($address['inpf'] as $rule)
b62ff880 2682 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
2683 echo "</table>";
2684 finishPortlet();
2685 }
2686
68225375
DO
2687 echo "</td></tr>";
2688 echo "</table>\n";
e673ee24
DO
2689}
2690
2d318652 2691function renderIPv4AddressProperties ($dottedquad)
e673ee24 2692{
e673ee24 2693 showMessageOrError();
2d318652
DO
2694 $address = getIPv4Address ($dottedquad);
2695 echo "<center><h1>$dottedquad</h1></center>\n";
7056988c 2696
1fbc9fd6 2697 startPortlet ('update');
e673ee24 2698 echo "<table border=0 cellpadding=10 cellpadding=1 align='center'>\n";
7056988c 2699 printOpFormIntro ('editAddress');
2d318652
DO
2700 echo "<tr><td class='tdright'>Name:</td><td class='tdleft'><input type=text name=name size=20 value='${address['name']}'></tr>";
2701 echo "<td class='tdright'>Reserved:</td><td class='tdleft'><input type=checkbox name=reserved size=20 ";
2702 echo ($address['reserved']=='yes') ? 'checked' : '';
53ef3908
DO
2703 echo "></tr><tr><td colspan=2 class='tdcenter'>";
2704 printImageHREF ('SAVE', 'Save changes', TRUE);
2705 echo "</td></form></tr></table>\n";
1fbc9fd6
DO
2706 finishPortlet();
2707 if (empty ($address['name']) and $address['reserved'] == 'no')
2708 return;
7056988c 2709
1fbc9fd6 2710 startPortlet ('release');
7056988c 2711 printOpFormIntro ('editAddress', array ('name' => '', 'reserved' => ''));
1fbc9fd6
DO
2712 echo "<input type=submit value='release'></form>";
2713 finishPortlet();
e673ee24
DO
2714}
2715
2d318652 2716function renderIPv4AddressAllocations ($dottedquad)
e673ee24 2717{
e673ee24 2718 showMessageOrError();
39b4abd0
DO
2719 function printNewItemTR ()
2720 {
2721 global $aat;
2722 printOpFormIntro ('addIPv4Allocation');
2723 echo "<tr><td>";
9318d2ef 2724 printImageHREF ('add', 'allocate', TRUE);
f5ff50f5 2725 echo "</td><td><select name='object_id' tabindex=100>";
39b4abd0
DO
2726
2727 foreach (explode (',', getConfigVar ('IPV4_PERFORMERS')) as $type)
2728 foreach (getNarrowObjectList ($type) as $object)
2729 echo "<option value='${object['id']}'>${object['dname']}</option>";
2730
f5ff50f5
DO
2731 echo "</select></td><td><input type=text tabindex=101 name=bond_name size=10></td><td>";
2732 printSelect ($aat, 'bond_type', NULL, 102);
9318d2ef 2733 echo "</td><td>";
f5ff50f5 2734 printImageHREF ('add', 'allocate', TRUE, 103);
9318d2ef 2735 echo "</td></form></tr>";
39b4abd0 2736 }
4fbb5a00 2737 global $pageno, $tabno, $aat;
e673ee24 2738
2d318652 2739 $address = getIPv4Address ($dottedquad);
f74d96c6 2740
2d318652 2741 echo "<center><h1>${dottedquad}</h1></center>\n";
105a3bc8 2742 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
2d318652 2743 echo "<tr><th>&nbsp;</th><th>object</th><th>OS interface</th><th>allocation type</th><th>&nbsp;</th></tr>\n";
e673ee24 2744
39b4abd0
DO
2745 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
2746 printNewItemTR();
f74d96c6 2747 if (isset ($address['class']))
e673ee24 2748 {
f74d96c6
DO
2749 $class = $address['class'];
2750 if ($address['reserved'] == 'yes')
2751 echo "<tr class='${class}'><td colspan=3>&nbsp;</td><td class=tdleft><strong>RESERVED</strong></td><td>&nbsp;</td></tr>";
2752 foreach ($address['allocs'] as $bond)
2753 {
2754 echo "<tr class='$class'>";
2755 printOpFormIntro ('updIPv4Allocation', array ('object_id' => $bond['object_id']));
4fbb5a00 2756 echo "<td><a href='".makeHrefProcess(array('op'=>'delIPv4Allocation', 'ip'=>$dottedquad, 'object_id'=>$bond['object_id']))."'>";
f74d96c6
DO
2757 printImageHREF ('delete', 'Unallocate address');
2758 echo "</a></td>";
4fbb5a00 2759 echo "<td><a href='".makeHref(array('page'=>'object', 'object_id'=>$bond['object_id'], 'hl_ipv4_addr'=>$dottedquad))."'>${bond['object_name']}</td>";
f74d96c6
DO
2760 echo "<td><input type='text' name='bond_name' value='${bond['name']}' size=10></td><td>";
2761 printSelect ($aat, 'bond_type', $bond['type']);
2762 echo "</td><td>";
2763 printImageHREF ('save', 'Save changes', TRUE);
2764 echo "</td></form></tr>\n";
2765 }
e673ee24 2766 }
39b4abd0
DO
2767 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
2768 printNewItemTR();
e673ee24 2769 echo "</table><br><br>";
e673ee24
DO
2770}
2771
eeb4a5d8 2772function renderNATv4ForObject ($object_id = 0)
e673ee24 2773{
0b72ada2 2774 global $root;
9318d2ef
DO
2775 function printNewItemTR ($alloclist)
2776 {
0b72ada2 2777 global $root;
9318d2ef
DO
2778 printOpFormIntro ('addNATv4Rule');
2779 echo "<tr align='center'><td>";
2780 printImageHREF ('add', 'Add new NAT rule', TRUE);
2781 echo '</td><td>';
2782 printSelect (array ('TCP' => 'TCP', 'UDP' => 'UDP'), 'proto');
2783 echo "<select name='localip' tabindex=1>";
2784
2785 foreach ($alloclist as $dottedquad => $alloc)
2786 {
2787 $name = empty ($alloc['addrinfo']['name']) ? '' : (' (' . niftyString ($alloc['addrinfo']['name']) . ')');
2788 $osif = empty ($alloc['osif']) ? '' : ($alloc['osif'] . ': ');
2789 echo "<option value='${dottedquad}'>${osif}${dottedquad}${name}</option>";
2790 }
2791
2792 echo "</select>:<input type='text' name='localport' size='4' tabindex=2></td>";
2793 echo "<td><input type='text' name='remoteip' id='remoteip' size='10' tabindex=3>";
39106006
DO
2794 echo "<a href='javascript:;' onclick='window.open(\"" . makeHrefForHelper ('inet4list');
2795 echo "\", \"findobjectip\", \"height=700, width=400, location=no, menubar=no, resizable=yes, scrollbars=no, status=no, titlebar=no, toolbar=no\");'>";
9318d2ef
DO
2796 printImageHREF ('find', 'Find object');
2797 echo "</a>";
2798 echo ":<input type='text' name='remoteport' size='4' tabindex=4></td><td></td>";
2799 echo "<td colspan=1><input type='text' name='description' size='20' tabindex=5></td><td>";
f5ff50f5 2800 printImageHREF ('add', 'Add new NAT rule', TRUE, 6);
9318d2ef
DO
2801 echo "</td></tr></form>";
2802 }
4fbb5a00 2803 global $pageno, $tabno;
e673ee24
DO
2804
2805 $info = getObjectInfo ($object_id);
eeb4a5d8 2806 $forwards = getNATv4ForObject ($object_id);
2c817354 2807 $alloclist = getObjectIPv4Allocations ($object_id);
e673ee24 2808 showMessageOrError();
f28fbe8b 2809 echo "<center><h2>locally performed NAT</h2></center>";
e673ee24 2810
105a3bc8 2811 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
d54b9495 2812 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 2813
9318d2ef
DO
2814 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
2815 printNewItemTR ($alloclist);
e673ee24
DO
2816 foreach ($forwards['out'] as $pf)
2817 {
2c817354
DO
2818 $class = 'trerror';
2819 $osif = '';
2820 if (isset ($alloclist [$pf['localip']]))
2821 {
2822 $class = $alloclist [$pf['localip']]['addrinfo']['class'];
2823 $osif = $alloclist [$pf['localip']]['osif'] . ': ';
2824 }
e673ee24
DO
2825
2826 echo "<tr class='$class'>";
4fbb5a00
DY
2827 echo "<td><a href='".
2828 makeHrefProcess(array(
2829 'op'=>'delNATv4Rule',
2830 'localip'=>$pf['localip'],
2831 'localport'=>$pf['localport'],
2832 'remoteip'=>$pf['remoteip'],
2833 'remoteport'=>$pf['remoteport'],
2834 'proto'=>$pf['proto'],
2835 'object_id'=>$object_id)).
2836 "'>";
4de22e7e
DO
2837 printImageHREF ('delete', 'Delete NAT rule');
2838 echo "</a></td>";
4fbb5a00 2839 echo "<td>${pf['proto']}/${osif}<a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['localip']))."'>${pf['localip']}</a>:${pf['localport']}";
f28fbe8b
DO
2840 if (!empty ($pf['local_addr_name']))
2841 echo ' (' . $pf['local_addr_name'] . ')';
2842 echo "</td>";
4fbb5a00 2843 echo "<td><a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['remoteip']))."'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
e673ee24 2844
53ef3908 2845 $address = getIPv4Address ($pf['remoteip']);
e673ee24
DO
2846
2847 echo "<td class='description'>";
53ef3908
DO
2848 if (count ($address['allocs']))
2849 foreach ($address['allocs'] as $bond)
4fbb5a00 2850 echo "<a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$bond['object_id']))."'>${bond['object_name']}(${bond['name']})</a> ";
f28fbe8b
DO
2851 elseif (!empty ($pf['remote_addr_name']))
2852 echo '(' . $pf['remote_addr_name'] . ')';
7056988c
DO
2853 printOpFormIntro
2854 (
2855 'updNATv4Rule',
2856 array
2857 (
2858 'localip' => $pf['localip'],
2859 'localport' => $pf['localport'],
2860 'remoteip' => $pf['remoteip'],
2861 'remoteport' => $pf['remoteport'],
2862 'proto' => $pf['proto']
2863 )
2864 );
2865 echo "</td><td class='description'>";
d54b9495
DO
2866 echo "<input type='text' name='description' value='${pf['description']}'></td><td>";
2867 printImageHREF ('save', 'Save changes', TRUE);
2868 echo "</td></form></tr>";
e673ee24 2869 }
9318d2ef
DO
2870 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
2871 printNewItemTR ($alloclist);
e673ee24
DO
2872
2873 echo "</table><br><br>";
2874
f28fbe8b 2875 echo "<center><h2>arriving NAT connections</h2></center>";
105a3bc8 2876 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
e673ee24
DO
2877 echo "<tr><th></th><th>Source</th><th>Source objects</th><th>Target</th><th>Description</th></tr>\n";
2878
2879 foreach ($forwards['in'] as $pf)
2880 {
4fbb5a00
DY
2881 echo "<tr><td><a href='".
2882 makeHrefProcess(array(
2883 'op'=>'delNATv4Rule',
2884 'localip'=>$pf['localip'],
2885 'localport'=>$pf['localport'],
2886 'remoteip'=>$pf['remoteip'],
2887 'remoteport'=>$pf['remoteport'],
2888 'proto'=>$pf['proto'],
2889 'object_id'=>$pf['object_id']
2890 )).
2891 "'>";
4de22e7e
DO
2892 printImageHREF ('delete', 'Delete NAT rule');
2893 echo "</a></td>";
4fbb5a00
DY
2894 echo "<td>${pf['proto']}/<a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['localip']))."'>${pf['localip']}</a>:${pf['localport']}</td>";
2895 echo "<td class='description'><a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$pf['object_id']))."'>${pf['object_name']}</a>";
2896 echo "</td><td><a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['remoteip']))."'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
e673ee24
DO
2897 echo "<td class='description'>${pf['description']}</td></tr>";
2898 }
2899
e673ee24 2900 echo "</table><br><br>";
e673ee24
DO
2901}
2902
7056988c 2903// FIXME: move related code away into ophandler(s)
e673ee24
DO
2904function renderAddMultipleObjectsForm ()
2905{
20c901a7 2906 global $root, $pageno, $tabno, $nextorder;
e673ee24
DO
2907
2908 $type_id = array();
7f791d1d 2909 $global_type_id = 0;
e673ee24
DO
2910 $name = array();
2911 $asset_no = array();
ce4d1a79 2912 $keepvalues1 = $keepvalues2 = FALSE;
42d73cbf 2913 showMessageOrError();
e673ee24
DO
2914
2915 // Render a form for the next.
2916 $typelist = getObjectTypeList();
4c330a14 2917 $typelist[0] = 'select type...';
7f791d1d 2918
f60bb422
DO
2919 startPortlet ('Distinct types, same tags');
2920 $max = getConfigVar ('MASSCOUNT');
42d73cbf 2921 printOpFormIntro ('addObjects');
e673ee24 2922 echo '<table border=0 align=center>';
f60bb422
DO
2923 echo "<tr><th>Object type</th><th>Common name</th><th>Visible label</th>";
2924 echo "<th>Asset tag</th><th>Barcode</th><th>Tags</th></tr>\n";
7f791d1d 2925 // If a user forgot to select object type on input, we keep his
e673ee24 2926 // previous input in the form.
9c0b0016 2927 for ($i = 0; $i < $max; $i++)
e673ee24 2928 {
7f791d1d 2929 echo '<tr><td>';
e7ade6bf
DO
2930 // Don't employ DEFAULT_OBJECT_TYPE to avoid creating ghost records for pre-selected empty rows.
2931 printSelect ($typelist, "${i}_object_type_id", 0);
e673ee24
DO
2932 echo '</td>';
2933 echo "<td><input type=text size=30 name=${i}_object_name";
ce4d1a79 2934 if ($keepvalues1 and isset ($name[$i]) and (!isset ($type_id[$i]) or $type_id[$i] == 0))
e673ee24
DO
2935 echo " value='${name[$i]}'";
2936 echo "></td>";
2937 echo "<td><input type=text size=30 name=${i}_object_label";
ce4d1a79 2938 if ($keepvalues1 and isset ($label[$i]) and (!isset ($type_id[$i]) or $type_id[$i] == 0))
e673ee24
DO
2939 echo " value='${label[$i]}'";
2940 echo "></td>";
2941 echo "<td><input type=text size=20 name=${i}_object_asset_no";
ce4d1a79 2942 if ($keepvalues1 and isset ($asset_no[$i]) and (!isset ($type_id[$i]) or $type_id[$i] == 0))
e673ee24
DO
2943 echo " value='${asset_no[$i]}'";
2944 echo "></td>";
2945 echo "<td><input type=text size=10 name=${i}_object_barcode";
ce4d1a79 2946 if ($keepvalues1 and isset ($barcode[$i]) and (!isset ($type_id[$i]) or $type_id[$i] == 0))
e673ee24
DO
2947 echo " value='${barcode[$i]}'";
2948 echo "></td>";
f60bb422
DO
2949 if ($i == 0)
2950 {
2951 echo "<td valign=top rowspan=${max}>";
2952 renderTagSelect();
2953 echo "</td>\n";
2954 }
e673ee24 2955 echo "</tr>\n";
e673ee24 2956 }
216c84bb 2957 echo "<tr><td class=submit colspan=5><input type=submit name=got_fast_data value='Go!'></td></tr>\n";
e673ee24
DO
2958 echo "</form></table>\n";
2959 finishPortlet();
7f791d1d 2960
f60bb422 2961 startPortlet ('Same type, same tags');
42d73cbf 2962 printOpFormIntro ('addLotOfObjects');
f60bb422
DO
2963 echo "<table border=0 align=center><tr><th>names</th><th>type</th></tr>";
2964 echo "<tr><td rowspan=3><textarea name=namelist cols=40 rows=25>\n";
ce4d1a79 2965 if ($keepvalues2 and $global_type_id == 0)
7f791d1d 2966 echo $_REQUEST['namelist'];
f60bb422
DO
2967 echo "</textarea></td><td valign=top>";
2968 printSelect ($typelist, "global_type_id", getConfigVar ('DEFAULT_OBJECT_TYPE'));
2969 echo "</td></tr>";
2970 echo "<tr><th>Tags</th></tr>";
2971 echo "<tr><td valign=top>";
2972 renderTagSelect();
2973 echo "</td></tr>";
2974 echo "<tr><td colspan=2><input type=submit name=got_very_fast_data value='Go!'></td></tr></table>\n";
2975 echo "</form>\n";
7f791d1d 2976 finishPortlet();
e673ee24
DO
2977}
2978
2979function printGreeting ()
2980{
d6d79c36
DO
2981 global $root, $remote_username, $remote_displayname;
2982 echo "Hello, <a href='${root}?page=myaccount&tab=default'>${remote_displayname}</a>. This is RackTables " .
2983 CODE_VERSION .
2984 ". Click <a href='${root}?logout'>here</a> to logout.";
e673ee24
DO
2985}
2986
2987function renderSearchResults ()
2988{
0b9c98d7 2989 global $root;
e673ee24
DO
2990 $terms = trim ($_REQUEST['q']);
2991 if (empty ($terms))
2992 {
591ff2c4 2993 showError ('Search string cannot be empty.', __FUNCTION__);
e673ee24
DO
2994 return;
2995 }
54522168 2996 if (!permitted ('objects', 'default'))
e673ee24 2997 {
591ff2c4 2998 showError ('You are not authorized for viewing information about objects.', __FUNCTION__);
e673ee24
DO
2999 return;
3000 }
ea5fc465 3001 $nhits = 0;
e673ee24
DO
3002 // If we search for L2 address, we can either find one or find none.
3003 if
3004 (
05771508
DO
3005 preg_match (RE_L2_IFCFG, $terms) or
3006 preg_match (RE_L2_SOLID, $terms) or
3007 preg_match (RE_L2_CISCO, $terms) or
1930dc7f 3008 preg_match (RE_L2_IPCFG, $terms) or
05771508
DO
3009 // Foundry STP bridge ID: bridge priotity + port MAC address. Cut off first 4 chars and look for MAC address.
3010 preg_match (RE_L2_FDRYSTP, $terms)
e673ee24
DO
3011 )
3012 // Search for L2 address.
3013 {
3ec29bf4
DO
3014 $terms = str_replace ('.', '', $terms);
3015 $terms = str_replace (':', '', $terms);
1930dc7f 3016 $terms = str_replace ('-', '', $terms);
ea5fc465 3017 $terms = substr ($terms, -12);
e673ee24
DO
3018 $result = searchByl2address ($terms);
3019 if ($result !== NULL)
3020 {
ea5fc465
DO
3021 $nhits++;
3022 $lasthit = 'port';
3023 $summary['port'][] = $result;
e673ee24 3024 }
e673ee24 3025 }
05771508 3026 elseif (preg_match (RE_IP4_ADDR, $terms))
64347dcf 3027 // Search for IPv4 address.
e673ee24 3028 {
bb0a44e9 3029 if (NULL !== getIPv4AddressNetworkId ($terms))
e673ee24 3030 {
ea5fc465 3031 $nhits++;
f3d0cb20
DO
3032 $lasthit = 'ipv4addressbydq';
3033 $summary['ipv4addressbydq'][] = $terms;
e673ee24 3034 }
e673ee24 3035 }
05771508 3036 elseif (preg_match (RE_IP4_NET, $terms))
64347dcf
DO
3037 // Search for IPv4 network
3038 {
3039 list ($base, $len) = explode ('/', $terms);
3040 if (NULL !== ($tmp = getIPv4AddressNetworkId ($base, $len + 1)))
3041 {
3042 $nhits++;
3043 $lasthit = 'ipv4network';
3044 $summary['ipv4network'][] = getIPv4NetworkInfo ($tmp);
3045 }
3046 }
e673ee24 3047 else
ea5fc465 3048 // Search for objects, addresses, networks, virtual services and RS pools by their description.
e673ee24 3049 {
ea5fc465
DO
3050 $tmp = getObjectSearchResults ($terms);
3051 if (count ($tmp))
e673ee24 3052 {
ea5fc465
DO
3053 $nhits += count ($tmp);
3054 $lasthit = 'object';
3055 $summary['object'] = $tmp;
e673ee24 3056 }
ea5fc465
DO
3057 $tmp = getIPv4AddressSearchResult ($terms);
3058 if (count ($tmp))
e673ee24 3059 {
ea5fc465 3060 $nhits += count ($tmp);
f3d0cb20
DO
3061 $lasthit = 'ipv4addressbydescr';
3062 $summary['ipv4addressbydescr'] = $tmp;
ea5fc465
DO
3063 }
3064 $tmp = getIPv4PrefixSearchResult ($terms);
3065 if (count ($tmp))
3066 {
3067 $nhits += count ($tmp);
3068 $lasthit = 'ipv4network';
3069 $summary['ipv4network'] = $tmp;
3070 }
05411ccd
DO
3071 $tmp = getIPv4RSPoolSearchResult ($terms);
3072 if (count ($tmp))
3073 {
3074 $nhits += count ($tmp);
3075 $lasthit = 'ipv4rspool';
3076 $summary['ipv4rspool'] = $tmp;
3077 }
3078 $tmp = getIPv4VServiceSearchResult ($terms);
3079 if (count ($tmp))
3080 {
3081 $nhits += count ($tmp);
3082 $lasthit = 'ipv4vs';
3083 $summary['ipv4vs'] = $tmp;
3084 }
6a88e734
DO
3085 $tmp = getAccountSearchResult ($terms);
3086 if (count ($tmp))
3087 {
3088 $nhits += count ($tmp);
3089 $lasthit = 'user';
3090 $summary['user'] = $tmp;
3091 }
e1ae3fb4
AD
3092 $tmp = getFileSearchResult ($terms);
3093 if (count ($tmp))
3094 {
3095 $nhits += count ($tmp);
3096 $lasthit = 'file';
3097 $summary['file'] = $tmp;
3098 }
ea5fc465
DO
3099 }
3100 if ($nhits == 0)
3101 echo "<center><h2>Nothing found for '${terms}'</h2></center>";
3102 elseif ($nhits == 1)
3103 {
3104 $record = current ($summary[$lasthit]);
3105 switch ($lasthit)
3106 {
3107 case 'port':
3108 echo "<script language='Javascript'>document.location='${root}?page=object";
3109 echo "&hl_port_id=" . $record['port_id'];
3110 echo "&object_id=" . $record['object_id'] . "';//</script>";
3111 break;
f3d0cb20
DO
3112 case 'ipv4addressbydq':
3113 $parentnet = getIPv4AddressNetworkId ($record);
3114 if ($parentnet !== NULL)
e1ae3fb4 3115 echo "<script language='Javascript'>document.location='${root}?page=ipv4net&tab=default&id=${parentnet}&hl_ipv4_addr=${record}';//</script>";
f3d0cb20
DO
3116 else
3117 echo "<script language='Javascript'>document.location='${root}?page=ipaddress&ip=${record}';//</script>";
ea5fc465 3118 break;
f3d0cb20
DO
3119 case 'ipv4addressbydescr':
3120 $parentnet = getIPv4AddressNetworkId ($record['ip']);
3121 if ($parentnet !== NULL)
e1ae3fb4 3122 echo "<script language='Javascript'>document.location='${root}?page=ipv4net&tab=default&id=${parentnet}&hl_ipv4_addr=${record['ip']}';//</script>";
f3d0cb20
DO
3123 else
3124 echo "<script language='Javascript'>document.location='${root}?page=ipaddress&ip=${record['ip']}';//</script>";
ea5fc465
DO
3125 break;
3126 case 'ipv4network':
e1ae3fb4 3127 echo "<script language='Javascript'>document.location='${root}?page=ipv4net";
ea5fc465
DO
3128 echo "&id=${record['id']}";
3129 echo "';//</script>";
3130 break;
3131 case 'object':
3132 echo "<script language='Javascript'>document.location='${root}?page=object&object_id=${record['id']}';//</script>";
3133 break;
05411ccd 3134 case 'ipv4rspool':
e1ae3fb4 3135 echo "<script language='Javascript'>document.location='${root}?page=ipv4rspool&pool_id=${record['pool_id']}';//</script>";
05411ccd
DO
3136 break;
3137 case 'ipv4vs':
49fb2686 3138 echo "<script language='Javascript'>document.location='${root}?page=ipv4vs&vs_id=${record['id']}';//</script>";
05411ccd 3139 break;
6a88e734
DO
3140 case 'user':
3141 echo "<script language='Javascript'>document.location='${root}?page=user&user_id=${record['user_id']}';//</script>";
3142 break;
e1ae3fb4
AD
3143 case 'file':
3144 echo "<script language='Javascript'>document.location='${root}?page=file&file_id=${record['id']}';//</script>";
3145 break;
ea5fc465
DO
3146 }
3147 return;
3148 }
3149 else
3150 {
3151 global $nextorder;
3152 $order = 'odd';
3153 echo "<center><h2>${nhits} result(s) found for '${terms}'</h2></center>";
3154 foreach ($summary as $where => $what)
3155 switch ($where)
e673ee24 3156 {
ea5fc465 3157 case 'object':
06adfe89 3158 startPortlet ("<a href='${root}?page=objects'>Objects</a>");
ea5fc465 3159 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
e1ae3fb4 3160 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>Barcode</th></tr>';
ea5fc465
DO
3161 foreach ($what as $obj)
3162 {
2b3d64c5
DO
3163 $tags = loadRackObjectTags ($obj['id']);
3164 echo "<tr class=row_${order} valign=top><td class=tdleft><a href=\"${root}?page=object&object_id=${obj['id']}\">${obj['dname']}</a>";
3165 if (count ($tags))
3166 echo '<br><small>' . serializeTags ($tags) . '</small>';
3167 echo "</td><td>${obj['label']}</td>";
ea5fc465
DO
3168 echo "<td>${obj['asset_no']}</td>";
3169 echo "<td>${obj['barcode']}</td></tr>";
3170 $order = $nextorder[$order];
3171 }
3172 echo '</table>';
3173 finishPortlet();
3174 break;
3175 case 'ipv4network':
06adfe89 3176 startPortlet ("<a href='${root}?page=ipv4space'>IPv4 networks</a>");
ea5fc465 3177 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
71287f1c 3178 foreach ($what as $netinfo)
ea5fc465 3179 {
0b9c98d7
DO
3180 echo "<tr class=row_${order} valign=top><td>";
3181 renderIPv4NetCell ($netinfo);
3182 echo "</td></tr>\n";
ea5fc465
DO
3183 $order = $nextorder[$order];
3184 }
3185 echo '</table>';
3186 finishPortlet();
3187 break;
f3d0cb20 3188 case 'ipv4addressbydescr':
ea5fc465
DO
3189 startPortlet ('IPv4 addresses');
3190 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
f3d0cb20 3191 // FIXME: address, parent network, routers (if extended view is enabled)
e1ae3fb4 3192 echo '<tr><th>Address</th><th>Description</th></tr>';
ea5fc465
DO
3193 foreach ($what as $addr)
3194 {
f3d0cb20
DO
3195 echo "<tr class=row_${order}><td class=tdleft>";
3196 $parentnet = getIPv4AddressNetworkId ($addr['ip']);
3197 if ($parentnet !== NULL)
e1ae3fb4 3198 echo "<a href='${root}?page=ipv4net&tab=default&id=${parentnet}&hl_ipv4_addr=${addr['ip']}'>${addr['ip']}</a></td>";
f3d0cb20
DO
3199 else
3200 echo "<a href='${root}?page=ipaddress&ip=${addr['ip']}'>${addr['ip']}</a></td>";
ea5fc465
DO
3201 echo "<td class=tdleft>${addr['name']}</td></tr>";
3202 $order = $nextorder[$order];
3203 }
3204 echo '</table>';
3205 finishPortlet();
3206 break;
05411ccd 3207 case 'ipv4rspool':
ee437dab 3208 startPortlet ("<a href='${root}?page=ipv4rsplist'>RS pools</a>");
05411ccd
DO
3209 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
3210 foreach ($what as $rspool)
3211 {
e1ae3fb4 3212 echo "<tr class=row_${order}><td class=tdleft><a href='${root}?page=ipv4rspool&pool_id=${rspool['pool_id']}'>";
05411ccd
DO
3213 echo buildRSPoolName ($rspool);
3214 echo "</a></td></tr>";
3215 $order = $nextorder[$order];
3216 }
3217 echo '</table>';
3218 finishPortlet();
3219 break;
3220 case 'ipv4vs':
a239e016 3221 startPortlet ("<a href='${root}?page=ipv4vslist'>Virtual services</a>");
05411ccd 3222 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
8128c257 3223 foreach ($what as $vsinfo)
05411ccd 3224 {
8128c257
DO
3225 echo "<tr class=row_${order}><td class=tdleft>";
3226 renderIPv4VSCell ($vsinfo);
3227 echo "</td></tr>";
6a88e734
DO
3228 $order = $nextorder[$order];
3229 }
3230 echo '</table>';
3231 finishPortlet();
3232 break;
3233 case 'user':
3234 startPortlet ("<a href='${root}?page=userlist'>Users</a>");
3235 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
6a88e734
DO
3236 foreach ($what as $item)
3237 {
19dac9c3
DO
3238 echo "<tr class=row_${order}><td class=tdleft>";
3239 renderUserCell ($item);
3240 echo "</td></tr>";
05411ccd
DO
3241 $order = $nextorder[$order];
3242 }
3243 echo '</table>';
3244 finishPortlet();
3245 break;
e1ae3fb4
AD
3246 case 'file':
3247 startPortlet ("<a href='${root}?page=files'>Files</a>");
3248 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
3249 echo '<tr><th>Name</th><th>Comment</th></tr>';
3250 foreach ($what as $item)
3251 {
3252 echo "<tr class=row_${order}><td class=tdleft><a href='${root}?page=file&file_id=${item['id']}'>";
3253 echo $item['name'];
3254 echo "</a></td><td class=tdleft>${item['comment']}</td></tr&g