r2547 Fixed bug from ticket:200
[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']));
b7f0eaec 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'),
70cb9b56
DO
1525 179 => array ('code' => 'error', 'format' => 'Declining outdated text. Re-edit the file for consistency.'),
1526 180 => array ('code' => 'error', 'format' => 'Error saving file, all changes lost!'),
f0ff4930 1527
8628ae44 1528// records 200~299 with warnings
24dcb9d8
DO
1529 200 => array ('code' => 'warning', 'format' => 'generic warning: %s'),
1530 201 => array ('code' => 'warning', 'format' => 'nothing happened...'),
1531 202 => array ('code' => 'warning', 'format' => 'gw: %s'),
f0ff4930
DO
1532 203 => array ('code' => 'warning', 'format' => 'Port %s seems to be the first in VLAN %u at this switch.'),
1533 204 => array ('code' => 'warning', 'format' => 'Check uplink/downlink configuration for proper operation.'),
1534 205 => array ('code' => 'warning', 'format' => '%u change request(s) have been ignored'),
c8187437 1535 206 => array ('code' => 'warning', 'format' => 'Rack is not empty'),
baf37d01
DO
1536 );
1537 // Handle the arguments. Is there any better way to do it?
1538 foreach ($log['m'] as $record)
1539 {
5222f192
DO
1540 if (!isset ($record['c']) or !isset ($msginfo[$record['c']]))
1541 {
1542 echo '<div class=msg_neutral>(this message was lost)</div>';
1543 continue;
1544 }
baf37d01
DO
1545 if (isset ($record['a']))
1546 switch (count ($record['a']))
1547 {
1548 case 1:
1549 $msgtext = sprintf
1550 (
1551 $msginfo[$record['c']]['format'],
1552 $record['a'][0]
1553 );
1554 break;
1555 case 2:
1556 $msgtext = sprintf
1557 (
1558 $msginfo[$record['c']]['format'],
1559 $record['a'][0],
1560 $record['a'][1]
1561 );
1562 break;
1563 case 3:
1564 $msgtext = sprintf
1565 (
1566 $msginfo[$record['c']]['format'],
1567 $record['a'][0],
1568 $record['a'][1],
1569 $record['a'][2]
1570 );
1571 break;
1572 case 4:
1573 default:
1574 $msgtext = sprintf
1575 (
1576 $msginfo[$record['c']]['format'],
1577 $record['a'][0],
1578 $record['a'][1],
1579 $record['a'][2],
1580 $record['a'][3]
1581 );
1582 break;
1583 }
1584 else
1585 $msgtext = $msginfo[$record['c']]['format'];
1586 echo '<div class=msg_' . $msginfo[$record['c']]['code'] . ">${msgtext}</div>";
1587 }
1588 break;
1589 default:
1590 echo '<div class=msg_error>' . __FUNCTION__ . ': internal error</div>';
1591 break;
1592 }
e673ee24
DO
1593}
1594
1595/*
1596The following conditions must be followed:
15971. We can mount onto free atoms only. This means: if any record for an atom
1598already exists in RackSpace, it can't be used for mounting.
15992. We can't unmount from 'W' atoms. Operator should review appropriate comments
1600and either delete them before unmounting or refuse to unmount the object.
1601*/
1602
1603// We extensively use $_REQUEST in the function.
7056988c 1604// FIXME: move related code into ophandler
e673ee24
DO
1605function renderRackSpaceForObject ($object_id = 0)
1606{
1607 if ($object_id <= 0)
1608 {
591ff2c4 1609 showError ('Invalid object_id', __FUNCTION__);
e673ee24
DO
1610 return;
1611 }
1612 $is_submit = isset ($_REQUEST['got_atoms']);
1613 $is_update = isset ($_REQUEST['rackmulti'][0]);
1614 $info = getObjectInfo ($object_id);
1615 if ($info == NULL)
1616 {
591ff2c4 1617 showError ('getObjectInfo() failed', __FUNCTION__);
e673ee24
DO
1618 return;
1619 }
1620 // Always process occupied racks plus racks chosen by user. First get racks with
1621 // already allocated rackspace...
1622 $workingRacksData = getResidentRacksData ($object_id);
1623 if ($workingRacksData === NULL)
1624 {
1625 print_r ($workingRacksData);
591ff2c4 1626 showError ('getResidentRacksData() failed', __FUNCTION__);
e673ee24
DO
1627 return;
1628 }
1629
1630 // ...and then add those chosen by user (if any).
2135fd83 1631 if (isset($_REQUEST['rackmulti']))
e673ee24
DO
1632 foreach ($_REQUEST['rackmulti'] as $cand_id)
1633 {
1634 if (!isset ($workingRacksData[$cand_id]))
1635 {
1636 $rackData = getRackData ($cand_id);
1637 if ($rackData == NULL)
1638 {
591ff2c4 1639 showError ('getRackData() failed', __FUNCTION__);
e673ee24
DO
1640 return NULL;
1641 }
1642 $workingRacksData[$cand_id] = $rackData;
1643 }
1644 }
1645
2135fd83
DY
1646 printOpFormIntro ('updateObjectAllocation');
1647
e673ee24 1648 // Do it only once...
2135fd83
DY
1649 foreach ($workingRacksData as $rackId => &$rackData)
1650 {
e673ee24 1651 applyObjectMountMask ($rackData, $object_id);
2135fd83
DY
1652 echo "<input type=\"hidden\" name=\"rackmulti[]\" value=\"$rackId\">";
1653 }
e673ee24
DO
1654 // Now we workaround an old caveat: http://bugs.php.net/bug.php?id=37410
1655 unset ($rackData);
1656
e673ee24 1657 // This is the time for rendering.
4fbb5a00
DY
1658 global $pageno, $tabno;
1659
51690ad4
DY
1660 showMessageOrError();
1661
4fbb5a00 1662
e673ee24
DO
1663 // Main layout starts.
1664 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0><tr>";
1665
1666 // Left portlet with rack list.
1667 echo "<td class=pcleft height='1%'>";
1668 startPortlet ('Racks');
1669 $allRacksData = getRacksForRow();
4b8d413e
DO
1670 if (count ($allRacksData) <= getConfigVar ('RACK_PRESELECT_THRESHOLD'))
1671 {
1672 foreach (array_keys ($allRacksData) as $rack_id)
1673 {
1674 $rackData = getRackData ($rack_id);
1675 if ($rackData == NULL)
1676 {
1677 showError ('getRackData() failed', __FUNCTION__);
1678 return NULL;
1679 }
1680 $workingRacksData[$rack_id] = $rackData;
1681 }
1682 foreach ($workingRacksData as &$rackData)
1683 applyObjectMountMask ($rackData, $object_id);
1684 unset ($rackData);
1685 }
1686 renderRackMultiSelect ('rackmulti[]', $allRacksData, array_keys ($workingRacksData));
e673ee24
DO
1687 echo "<br>";
1688 echo "<br>";
1689 finishPortlet();
1690 echo "</td>";
1691
1692 // Middle portlet with comment and submit.
1693 echo "<td class=pcleft>";
1694 startPortlet ('Comment');
1695 echo "<textarea name=comment rows=10 cols=40></textarea><br>\n";
1696 echo "<input type=submit value='Save' name=got_atoms>\n";
1697 echo "<br>";
1698 echo "<br>";
1699 finishPortlet();
1700 echo "</td>";
1701
1702 // Right portlet with rendered racks. If this form submit is not final, we have to
1703 // reflect the former state of the grid in current form.
1704 echo "<td class=pcright rowspan=2 height='1%'>";
1705 startPortlet ('Working copy');
1706 echo '<table border=0 cellspacing=10 align=center><tr>';
1707 foreach ($workingRacksData as $rack_id => $rackData)
1708 {
1709 // Order is important here: only original allocation is highlighted.
1710 highlightObject ($rackData, $object_id);
1711 markupAtomGrid ($rackData, 'T');
1712 // If we have a form processed, discard user input and show new database
1713 // contents.
1714 if (!$is_submit and $is_update)
1715 mergeGridFormToRack ($rackData);
1716 echo "<td valign=top>";
1717 echo "<center>\n<h2>${rackData['name']}</h2>\n";
1718 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
1719 echo "<tr><th width='10%'>&nbsp;</th><th width='20%'>Front</th>";
1720 echo "<th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
1721 renderAtomGrid ($rackData);
9b7468b7
DO
1722 echo "<tr><th width='10%'>&nbsp;</th><th width='20%'>Front</th>";
1723 echo "<th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
e673ee24
DO
1724 echo "</table></center>\n";
1725 echo '</td>';
1726 }
1727 echo "</tr></table>";
1728 finishPortlet();
1729 echo "</td>\n";
1730
2135fd83 1731
e673ee24
DO
1732 echo "</form>\n";
1733 echo "</tr></table>\n";
1734}
1735
1736function renderMolecule ($mdata, $object_id)
1737{
1738 // sort data out
1739 $rackpack = array();
1740 global $loclist;
64b95774 1741 foreach ($mdata as $rua)
e673ee24
DO
1742 {
1743 $rack_id = $rua['rack_id'];
1744 $unit_no = $rua['unit_no'];
1745 $atom = $rua['atom'];
1746 if (!isset ($rackpack[$rack_id]))
1747 {
1748 $rackData = getRackData ($rack_id);
1749 for ($i = $rackData['height']; $i > 0; $i--)
1750 for ($locidx = 0; $locidx < 3; $locidx++)
1751 $rackData[$i][$locidx]['state'] = 'F';
1752 $rackpack[$rack_id] = $rackData;
1753 }
1754 $rackpack[$rack_id][$unit_no][$loclist[$atom]]['state'] = 'T';
1755 $rackpack[$rack_id][$unit_no][$loclist[$atom]]['object_id'] = $object_id;
1756 }
1757 // now we have some racks to render
64b95774 1758 foreach ($rackpack as $rackData)
e673ee24
DO
1759 {
1760 markAllSpans ($rackData);
1761 echo "<table class=molecule cellspacing=0>\n";
1762 echo "<caption>${rackData['name']}</caption>\n";
1763 echo "<tr><th width='10%'>&nbsp;</th><th width='20%'>Front</th><th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
1764 for ($i = $rackData['height']; $i > 0; $i--)
1765 {
1766 echo "<tr><th>$i</th>";
1767 for ($locidx = 0; $locidx < 3; $locidx++)
1768 {
1769 $state = $rackData[$i][$locidx]['state'];
1770 echo "<td class=state_${state}>&nbsp;</td>\n";
1771 }
1772 echo "</tr>\n";
1773 }
1774 echo "</table>\n";
1775 }
1776}
1777
1778function renderUnmountedObjectsPortlet ()
1779{
1780 startPortlet ('Unmounted objects');
1781 $objs = getUnmountedObjects();
1782 if ($objs === NULL)
1783 {
591ff2c4 1784 showError ('getUnmountedObjects() failed', __FUNCTION__);
e673ee24
DO
1785 return;
1786 }
4fbb5a00 1787 global $nextorder;
e673ee24
DO
1788 $order = 'odd';
1789 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
f76c4197 1790 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset number</th><th>Barcode</th></tr>';
e673ee24
DO
1791 foreach ($objs as $obj)
1792 {
4fbb5a00 1793 echo "<tr class=row_${order}><td><a href='".makeHref(array('page'=>'object', 'object_id'=>$obj['id']))."'>${obj['dname']}</a></td>";
e673ee24 1794 echo "<td>${obj['label']}</td>";
18d94c29 1795 echo "<td>${obj['asset_no']}</td>";
f76c4197 1796 echo "<td>${obj['barcode']}</td>";
4fbb5a00 1797 echo "</tr>";
e673ee24
DO
1798 $order = $nextorder[$order];
1799 }
1800 echo "</table><br>\n";
1801 finishPortlet();
1802}
1803
1804function renderProblematicObjectsPortlet ()
1805{
1806 startPortlet ('Problematic objects');
1807 $objs = getProblematicObjects();
1808 if ($objs === NULL)
1809 {
591ff2c4 1810 showError ('getProblematicObjects() failed', __FUNCTION__);
e673ee24
DO
1811 return;
1812 }
4fbb5a00 1813 global $nextorder;
e673ee24
DO
1814 $order = 'odd';
1815 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1816 echo '<tr><th>Type</th><th>Common name</th></tr>';
1817 foreach ($objs as $obj)
1818 {
1819 echo "<tr class=row_${order}><td>${obj['objtype_name']}</td>";
4fbb5a00 1820 echo "<td><a href='".makeHref(array('page'=>'object', 'object_id'=>$obj['id']))."'>${obj['dname']}</a></tr>";
e673ee24
DO
1821 $order = $nextorder[$order];
1822 }
1823 echo "</table><br>\n";
1824 finishPortlet();
1825}
1826
7cc02fc1
DO
1827function renderObjectSpace ()
1828{
4fbb5a00 1829 global $taglist, $tagtree;
52b34485 1830 showMessageOrError();
7cc02fc1
DO
1831 echo "<table border=0 class=objectview>\n";
1832 echo "<tr><td class=pcleft width='50%'>";
1833 startPortlet ('View all by type');
1834 $groupInfo = getObjectGroupInfo();
1835 if ($groupInfo === NULL)
1836 {
1837 showError ('getObjectGroupInfo() failed', __FUNCTION__);
1838 return;
1839 }
1840 if (count ($groupInfo) == 0)
1841 echo "No objects exist in DB";
1842 else
1843 {
1844 echo '<div align=left><ul>';
1845 foreach ($groupInfo as $gi)
4fbb5a00 1846 echo "<li><a href='".makeHref(array('page'=>'objgroup', 'group_id'=>$gi['id']))."'>${gi['name']}</a> (${gi['count']})</li>";
7cc02fc1
DO
1847 echo '</ul></div>';
1848 }
1849 finishPortlet();
1850
1851 echo '</td><td class=pcright>';
1852
1853 startPortlet ('View all by tag');
1854 if (count ($taglist) == 0)
1855 echo "No tags exist in DB";
1856 else
1857 renderTagCloud ('object');
1858 finishPortlet();
e673ee24
DO
1859 echo "</td></tr></table>\n";
1860}
1861
466dcbe6 1862function renderObjectGroup ()
7cc02fc1 1863{
4fbb5a00 1864 global $pageno, $tabno, $nextorder, $taglist, $tagtree;
52b34485 1865 showMessageOrError();
2c6c7645 1866 assertUIntArg ('group_id', __FUNCTION__, TRUE);
7cc02fc1 1867 $group_id = $_REQUEST['group_id'];
a0d54e7e
DO
1868 $tagfilter = getTagFilter();
1869 $tagfilter_str = getTagFilterStr ($tagfilter);
7cc02fc1
DO
1870 echo "<table border=0 class=objectview>\n";
1871 echo "<tr><td class=pcleft width='25%'>";
1872 startPortlet ('change type');
1873 $groupInfo = getObjectGroupInfo();
1874 if ($groupInfo === NULL)
1875 {
1876 showError ('getObjectGroupInfo() failed', __FUNCTION__);
1877 return;
1878 }
1879 if (count ($groupInfo) == 0)
1880 echo "No objects exist in DB";
1881 else
1882 {
1883 echo '<div align=left><ul>';
1884 foreach ($groupInfo as $gi)
1885 {
4fbb5a00 1886 echo "<li><a href='".makeHref(array('page'=>$pageno, 'group_id'=>$gi['id']))."${tagfilter_str}'>";
105cea6e
DO
1887 if ($gi['id'] == $group_id)
1888 echo '<strong>';
1889 echo "${gi['name']}</a>";
1890 if ($gi['id'] == $group_id)
1891 echo '</strong>';
1892 echo " (${gi['count']})";
1893 if ($gi['id'] == $group_id)
1894 echo ' &larr;';
1895 echo "</li>";
7cc02fc1
DO
1896 }
1897 echo '</ul></div>';
1898 }
1899 finishPortlet();
1900
1901 echo '</td><td class=pcleft>';
1902
11c8e4be 1903 $objects = getObjectList ($group_id, $tagfilter, getTFMode());
922b8da6 1904 startPortlet ('Objects (' . count ($objects) . ')');
7cc02fc1
DO
1905 if ($objects === NULL)
1906 {
1907 showError ('getObjectList() failed', __FUNCTION__);
1908 return;
1909 }
1910 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
f76c4197 1911 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
1912 $order = 'odd';
1913 foreach ($objects as $obj)
1914 {
8e700dd1
DO
1915 if (isset ($_REQUEST['hl_object_id']) and $_REQUEST['hl_object_id'] == $obj['id'])
1916 $secondclass = 'tdleft port_highlight';
1917 else
1918 $secondclass = 'tdleft';
2b3d64c5 1919 $tags = loadRackObjectTags ($obj['id']);
4fbb5a00 1920 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 1921 if (count ($tags))
4fbb5a00 1922 echo '<br><small>' . serializeTags ($tags, makeHref(array('page'=>$pageno, 'tab'=>'default', 'group_id'=>$group_id))."&") . '</small>';
2b3d64c5 1923 echo "</td><td class='${secondclass}'>${obj['label']}</td>";
8e700dd1 1924 echo "<td class='${secondclass}'>${obj['asset_no']}</td>";
f76c4197 1925 echo "<td class='${secondclass}'>${obj['barcode']}</td>";
7cc02fc1 1926 if ($obj['rack_id'])
4fbb5a00 1927 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 1928 else
8e700dd1 1929 echo "<td class='${secondclass}'>Unmounted</td>";
7cc02fc1
DO
1930 echo '</tr>';
1931 $order = $nextorder[$order];
1932 }
1933 echo '</table>';
1934 finishPortlet();
1935
1936 echo "</td><td class=pcright width='25%'>";
1937
a0d54e7e 1938 renderTagFilterPortlet ($tagfilter, 'object', 'group_id', $group_id);
7cc02fc1 1939 echo "</td></tr></table>\n";
e673ee24
DO
1940}
1941
1942function renderEmptyPortsSelect ($port_id, $type_id)
1943{
1944 $ports = getEmptyPortsOfType($type_id);
1945 usort($ports, 'sortEmptyPorts');
1946 foreach ($ports as $port)
1947 {
1948 if ($port_id == $port['Port_id'])
1949 continue;
1950 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";
1951 }
1952}
1953
6ef9683b 1954function renderAllIPv4Allocations ()
e673ee24 1955{
6ef9683b 1956 $addresses = getAllIPv4Allocations();
e673ee24
DO
1957 usort($addresses, 'sortObjectAddressesAndNames');
1958 foreach ($addresses as $address)
1959 {
1960 echo "<option value='${address['ip']}' onclick='getElementById(\"ip\").value=\"${address['ip']}\";'>${address['object_name']} ${address['name']} ${address['ip']}</option>\n";
1961 }
1962}
1963
1964// History viewer for history-enabled simple dictionaries.
1965function renderHistory ($object_type, $object_id)
1966{
1967 switch ($object_type)
1968 {
1969 case 'row':
1970 $query = "select ctime, user_name, name, deleted, comment from RackRowHistory where id = ${object_id} order by ctime";
1971 $header = '<tr><th>change time</th><th>author</th><th>rack row name</th><th>is deleted?</th><th>rack row comment</th></tr>';
1972 $extra = 4;
1973 break;
1974 case 'rack':
1975 $query =
51690ad4
DY
1976 "select ctime, user_name, rh.name, rh.deleted, rr.name as name, rh.height, rh.comment " .
1977 "from RackHistory as rh left join RackRow as rr on rh.row_id = rr.id " .
1978 "where rh.id = ${object_id} order by ctime";
e673ee24
DO
1979 $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>';
1980 $extra = 6;
1981 break;
1982 case 'object':
1983 $query =
f76c4197 1984 "select ctime, user_name, RackObjectHistory.name as name, label, barcode, asset_no, deleted, has_problems, dict_value, comment " .
00f6f1e4
DY
1985 "from RackObjectHistory inner join Dictionary on objtype_id = dict_key join Chapter on Dictionary.chapter_id = Chapter.id " .
1986 "where Chapter.name = 'RackObjectType' and RackObjectHistory.id=${object_id} order by ctime";
f76c4197 1987 $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
1988 $extra = 9;
1989 break;
1990 default:
591ff2c4 1991 showError ("Uknown object type '${object_type}'", __FUNCTION__);
e673ee24
DO
1992 return;
1993 }
1994 global $dbxlink;
1995 $result = $dbxlink->query ($query);
1996 if ($result == NULL)
1997 {
591ff2c4 1998 showError ('SQL query failed', __FUNCTION__);
e673ee24
DO
1999 return;
2000 }
2001 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
2002 $order = 'odd';
2003 global $nextorder;
2004 echo $header;
2005 while ($row = $result->fetch (PDO::FETCH_NUM))
2006 {
2007 echo "<tr class=row_${order}><td>${row[0]}</td>";
2008 for ($i = 1; $i <= $extra; $i++)
2009 echo "<td>" . $row[$i] . "</td>";
2010 echo "</tr>\n";
2011 $order = $nextorder[$order];
2012 }
2013 echo "</table><br>\n";
2014}
2015
2016function renderRackspaceHistory ()
2017{
4fbb5a00 2018 global $nextorder, $pageno, $tabno;
e673ee24
DO
2019 $order = 'odd';
2020 $history = getRackspaceHistory();
2021 // Show the last operation by default.
2022 if (isset ($_REQUEST['op_id']))
2023 $op_id = $_REQUEST['op_id'];
2024 elseif (isset ($history[0]['mo_id']))
2025 $op_id = $history[0]['mo_id'];
2026 else $op_id = NULL;
2027
2028 $omid = NULL;
2029 $nmid = NULL;
2030 $object_id = 1;
2031 if ($op_id)
2032 list ($omid, $nmid) = getOperationMolecules ($op_id);
2033
2034 // Main layout starts.
2035 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
2036
2037 // Left top portlet with old allocation.
2038 echo "<tr><td class=pcleft>";
2039 startPortlet ('Old allocation');
2040 if ($omid)
2041 {
2042 $oldMolecule = getMolecule ($omid);
2043 renderMolecule ($oldMolecule, $object_id);
2044 }
2045 else
2046 echo "nothing";
2047 finishPortlet();
2048
2049 echo '</td><td class=pcright>';
2050
2051 // Right top portlet with new allocation
2052 startPortlet ('New allocation');
2053 if ($nmid)
2054 {
2055 $newMolecule = getMolecule ($nmid);
2056 renderMolecule ($newMolecule, $object_id);
2057 }
2058 else
2059 echo "nothing";
2060 finishPortlet();
737a3f72 2061
e673ee24 2062 echo '</td></tr><tr><td colspan=2>';
737a3f72 2063
e673ee24
DO
2064 // Bottom portlet with list
2065
2066 startPortlet ('Rackspace allocation history');
2067 echo "<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>\n";
2068 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";
2069 foreach ($history as $row)
2070 {
2071 if ($row['mo_id'] == $op_id)
2072 $class = 'hl';
2073 else
2074 $class = "row_${order}";
4fbb5a00 2075 echo "<tr class=${class}><td><a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno, 'op_id'=>$row['mo_id']))."'>${row['ctime']}</a></td>";
e673ee24
DO
2076 echo "<td>${row['user_name']}</td>";
2077 echo "<td>${row['ro_id']}</td><td>${row['objtype_name']}</td><td>${row['name']}</td><td>${row['comment']}</td>\n";
2078 echo "</tr>\n";
2079 $order = $nextorder[$order];
2080 }
2081 echo "</table>\n";
2082 finishPortlet();
737a3f72 2083
e673ee24 2084 echo '</td></tr></table>';
e673ee24
DO
2085}
2086
d9f8a37a 2087function renderIPv4SpaceRecords ($tree, &$tagcache, $baseurl, $target = 0, $level = 1)
d65353ad
DO
2088{
2089 $self = __FUNCTION__;
2090 foreach ($tree as $item)
2091 {
737a3f72 2092 $total = $item['addrt'];
64347dcf
DO
2093 if (getConfigVar ('IPV4_TREE_SHOW_USAGE') == 'yes')
2094 {
2095 loadIPv4AddrList ($item); // necessary to compute router list and address counter
2096 $used = $item['addrc'];
2097 }
2098 else
2099 {
2100 $item['addrlist'] = array();
2101 $item['addrc'] = 0;
2102 }
0137d53c
DO
2103 if (isset ($item['id']))
2104 {
fec0c8da 2105 if ($item['symbol'] == 'node-collapsed')
d9f8a37a 2106 $expandurl = "${baseurl}&eid=" . $item['id'] . "#netid" . $item['id'];
fec0c8da 2107 elseif ($item['symbol'] == 'node-expanded')
d9f8a37a 2108 $expandurl = $baseurl . ($item['parent_id'] ? "&eid=${item['parent_id']}#netid${item['parent_id']}" : '');
fec0c8da
DO
2109 else
2110 $expandurl = '';
0137d53c 2111 echo "<tr valign=top>";
fec0c8da 2112 printIPv4NetInfoTDs ($item, 'tdleft', $level, $item['symbol'], $expandurl);
0137d53c 2113 echo "<td class=tdcenter>";
d9f8a37a
DO
2114 if ($target == $item['id'])
2115 echo "<a name=netid${target}></a>";
64347dcf
DO
2116 if (getConfigVar ('IPV4_TREE_SHOW_USAGE') == 'yes')
2117 {
2118 renderProgressBar ($total ? $used/$total : 0);
2119 echo "<br><small>${used}/${total}</small>";
2120 }
2121 else
2122 echo "<small>${total}</small>";
2123 echo "</td>";
0137d53c 2124 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
b6b87070 2125 printRoutersTD (findRouters ($item['addrlist']), $tagcache);
0137d53c 2126 echo "</tr>";
fec0c8da 2127 if ($item['symbol'] == 'node-expanded' or $item['symbol'] == 'node-expanded-static')
d9f8a37a 2128 $self ($item['kids'], $tagcache, $baseurl, $target, $level + 1);
0137d53c
DO
2129 }
2130 else
2131 {
0137d53c 2132 echo "<tr valign=top>";
fec0c8da 2133 printIPv4NetInfoTDs ($item, 'tdleft sparenetwork', $level, $item['symbol']);
0137d53c 2134 echo "<td class=tdcenter>";
64347dcf
DO
2135 if (getConfigVar ('IPV4_TREE_SHOW_USAGE') == 'yes')
2136 {
2137 renderProgressBar ($used/$total, 'sparenetwork');
2138 echo "<br><small>${used}/${total}</small>";
2139 }
2140 else
2141 echo "<small>${total}</small>";
2142 echo "</td><td>&nbsp;</td></tr>";
0137d53c 2143 }
d65353ad
DO
2144 }
2145}
2146
04d619d0 2147function renderIPv4Space ()
e673ee24 2148{
4fbb5a00 2149 global $pageno, $tabno;
932cf41f 2150 $tagfilter = getTagFilter();
94a40058 2151 $netlist = getIPv4NetworkList ($tagfilter, getTFMode());
4fbb5a00
DY
2152
2153
94a40058 2154 $netcount = count ($netlist);
5388794d
DO
2155 // expand request can take either natural values or "ALL". Zero means no expanding.
2156 $eid = isset ($_REQUEST['eid']) ? $_REQUEST['eid'] : 0;
2157 $tree = prepareIPv4Tree ($netlist, $eid);
3630d1fb
DO
2158
2159 echo "<table border=0 class=objectview>\n";
2160 echo "<tr><td class=pcleft>";
94a40058 2161 startPortlet ("networks (${netcount})");
5388794d
DO
2162 echo '<h4>';
2163 if ($eid === 0)
4fbb5a00 2164 echo 'auto-collapsing at threshold ' . getConfigVar ('TREE_THRESHOLD') . " (<a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno, 'eid'=>'ALL'))."'>expand all</a>)";
5388794d 2165 elseif ($eid === 'ALL')
4fbb5a00 2166 echo "expanding all (<a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno))."'>auto-collapse</a>)";
5388794d
DO
2167 else
2168 {
2169 $netinfo = getIPv4NetworkInfo ($eid);
4fbb5a00 2170 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
2171 }
2172 echo "</h4><table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
64347dcf 2173 echo "<tr><th>prefix</th><th>name/tags</th><th>capacity</th>";
f0ed1181 2174 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
57dece2f
DO
2175 echo "<th>routed by</th>";
2176 echo "</tr>\n";
fec0c8da 2177 $tagcache = array();
4fbb5a00 2178 $baseurl = makeHref(array('page'=>$pageno, 'tab'=>$tabno)) . getTagFilterStr ($tagfilter);
5388794d 2179 renderIPv4SpaceRecords ($tree, $tagcache, $baseurl, $eid);
e673ee24 2180 echo "</table>\n";
a7fe7729 2181 finishPortlet();
74ccacff 2182 echo '</td><td class=pcright>';
5b7bd02e 2183 renderTagFilterPortlet ($tagfilter, 'ipv4net');
74ccacff 2184 echo "</td></tr></table>\n";
f973f491 2185}
a7fe7729 2186
f973f491
DO
2187function renderIPv4SLB ()
2188{
4fbb5a00 2189 global $page, $nextorder;
a7fe7729 2190
6fec9f39 2191 startPortlet ('SLB configuration');
b3c50e6c 2192 echo "<table border=0 width='100%'><tr>";
ee437dab 2193 foreach (array ('ipv4vslist', 'ipv4rsplist', 'rservers', 'lbs') as $pno)
4fbb5a00 2194 echo "<td><h3><a href='".makeHref(array('page'=>$pno))."'>" . $page[$pno]['title'] . "</a></h3></td>";
b3c50e6c
DO
2195 echo '</tr></table>';
2196 finishPortlet();
2197
c3bdc503 2198 $summary = getSLBSummary();
6fec9f39 2199 startPortlet ('SLB tactical overview');
4cadac8f
DO
2200 // A single id-keyed array isn't used here to preserve existing
2201 // order of LBs returned by getSLBSummary()
c3bdc503
DO
2202 $lblist = array();
2203 $lbdname = array();
4cadac8f 2204 foreach ($summary as $vipdata)
da04825a 2205 foreach (array_keys ($vipdata['lblist']) as $lb_object_id)
c3bdc503
DO
2206 if (!in_array ($lb_object_id, $lblist))
2207 {
2208 $oi = getObjectInfo ($lb_object_id);
2209 $lbdname[$lb_object_id] = $oi['dname'];
2210 $lblist[] = $lb_object_id;
2211 }
2212 if (!count ($summary))
2213 echo 'none configured';
2214 else
2215 {
80e85ea1 2216 $order = 'odd';
c3bdc503 2217 echo "<table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
b1a970c7 2218 echo "<tr valign=top><td>&nbsp;</td>";
c3bdc503 2219 foreach ($lblist as $lb_object_id)
b1a970c7 2220 {
4fbb5a00 2221 #echo "<th><a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$lb_object_id))."'>" . $lbdname[$lb_object_id] . "</a></th>";
b1a970c7
DO
2222 echo '<td>';
2223 renderLBCell ($lb_object_id);
2224 echo '</td>';
2225 }
c3bdc503 2226 echo "</tr>\n";
4cadac8f
DO
2227 foreach ($summary as $vsid => $vsdata)
2228 {
b1a970c7
DO
2229 echo "<tr class=row_${order}><td class=tdleft>";
2230 renderVSCell ($vsid);
6fec9f39 2231 echo "</td>";
4cadac8f 2232 foreach ($lblist as $lb_object_id)
da04825a 2233 {
60fbcece 2234 echo '<td class=tdleft>';
2b4eee17 2235 if (!isset ($vsdata['lblist'][$lb_object_id]))
da04825a
DO
2236 echo '&nbsp;';
2237 else
6fec9f39
DO
2238 {
2239 echo $vsdata['lblist'][$lb_object_id]['size'];
4fbb5a00 2240// echo " (<a href='".makeHref(array('page'=>'ipv4rspool', 'pool_id'=>$vsdata['lblist'][$lb_object_id]['id'])). "'>";
79a9edb4 2241// echo $vsdata['lblist'][$lb_object_id]['name'] . '</a>)';
6fec9f39 2242 }
da04825a
DO
2243 echo '</td>';
2244 }
2245 echo "</tr>\n";
80e85ea1 2246 $order = $nextorder[$order];
4cadac8f 2247 }
c3bdc503
DO
2248 echo "</table>\n";
2249 }
a7fe7729 2250 finishPortlet ();
e673ee24
DO
2251}
2252
04d619d0 2253function renderIPv4SpaceEditor ()
e673ee24 2254{
4fbb5a00 2255 global $pageno, $tabno;
e673ee24 2256 showMessageOrError();
2a201216 2257
a262e150
DO
2258 // IPv4 validator
2259?>
2260 <script type="text/javascript">
2261 function init() {
2262 document.add_new_range.range.setAttribute('match', "^\\d\\d?\\d?\\.\\d\\d?\\d?\\.\\d\\d?\\d?\\.\\d\\d?\\d?\\/\\d\\d?$");
2263
2264 Validate.init();
2265 }
2266 window.onload=init;
2267 </script>
2268<?php
2269
4c0653e2 2270 startPortlet ("Add new");
04d619d0 2271 echo '<table border=0 cellpadding=10 align=center>';
7056988c
DO
2272 // This form requires a name, so JavaScript validator can find it.
2273 // No printOpFormIntro() hence
4fbb5a00 2274 echo "<form method=post name='add_new_range' action='".makeHrefProcess()."'>\n";
42023f03 2275 echo "<input type=hidden name=op value=addIPv4Prefix>\n";
04d619d0
DO
2276 // tags column
2277 echo '<tr><td rowspan=4><h3>assign tags</h3>';
5c0bb421 2278 renderTagSelect();
04d619d0
DO
2279 echo '</td>';
2280 // inputs column
2281 echo "<th class=tdright>prefix</th><td class=tdleft><input type=text name='range' size=18 class='live-validate' tabindex=1></td>";
2282 echo "<tr><th class=tdright>name</th><td class=tdleft><input type=text name='name' size='20' tabindex=2></td></tr>";
0c16ef0c 2283 echo "<tr><th class=tdright>connected network</th><td class=tdleft><input type=checkbox name='is_bcast' tabindex=3></td></tr>";
04d619d0 2284 echo "<tr><td colspan=2>";
4c0653e2 2285 printImageHREF ('CREATE', 'Add a new network', TRUE, 4);
04d619d0 2286 echo '</td></tr>';
2a201216 2287 echo "</form></table><br><br>\n";
5c0bb421 2288 finishPortlet();
2a201216 2289
b18d26dc 2290 $addrspaceList = getIPv4NetworkList();
e43a2de4 2291 if (count ($addrspaceList))
e673ee24 2292 {
e43a2de4 2293 startPortlet ('Manage existing (' . count ($addrspaceList) . ')');
04d619d0
DO
2294 echo "<table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
2295 echo "<tr><th>&nbsp;</th><th>prefix</th><th>name</th><th>&nbsp;</th></tr>";
0c16ef0c 2296 foreach ($addrspaceList as $netinfo)
e673ee24 2297 {
0b9c98d7 2298 echo "<form method=post action='".makeHrefProcess(array('op'=>'updIPv4Prefix', 'id'=>$netinfo['id']))."'>";
e43a2de4
DO
2299 echo "<tr valign=top><td>";
2300 if (getConfigVar ('IPV4_JAYWALK') == 'yes')
2301 {
2302 echo "<a href='".makeHrefProcess(array('op'=>'delIPv4Prefix', 'id'=>$netinfo['id']))."'>";
2303 printImageHREF ('destroy', 'Delete this prefix');
2304 echo "</a>";
2305 }
2306 else // only render clickable image for empty networks
2307 {
2308 $netdata = getIPv4NetworkInfo ($netinfo['id']);
2309 loadIPv4AddrList ($netdata);
2310 if (count ($netdata['addrlist']))
2311 printImageHREF ('nodestroy', 'There are ' . count ($netdata['addrlist']) . ' allocations inside');
2312 else
2313 {
2314 echo "<a href='".makeHrefProcess(array('op'=>'delIPv4Prefix', 'id'=>$netinfo['id']))."'>";
2315 printImageHREF ('destroy', 'Delete this prefix');
2316 echo "</a>";
2317 }
2318
2319 }
2320 echo "</td>\n<td class=tdleft>${netinfo['ip']}/${netinfo['mask']}</td>";
0c16ef0c 2321 echo "<td><input type=text name=name size=40 value='${netinfo['name']}'>";
04d619d0
DO
2322 echo "</td><td>";
2323 printImageHREF ('save', 'Save changes', TRUE);
2324 echo "</td></tr></form>\n";
e673ee24 2325 }
04d619d0
DO
2326 echo "</table>";
2327 finishPortlet();
e673ee24 2328 }
e673ee24
DO
2329}
2330
beb9e88a 2331function renderIPv4Network ($id)
e673ee24 2332{
4fbb5a00 2333 global $pageno, $tabno, $aac2;
545478d0
DO
2334 $netmaskbylen = array
2335 (
2336 32 => '255.255.255.255',
2337 31 => '255.255.255.254',
2338 30 => '255.255.255.252',
2339 29 => '255.255.255.248',
2340 28 => '255.255.255.240',
2341 27 => '255.255.255.224',
2342 26 => '255.255.255.192',
2343 25 => '255.255.255.128',
2344 24 => '255.255.255.0',
2345 23 => '255.255.254.0',
2346 22 => '255.255.252.0',
2347 21 => '255.255.248.0',
2348 20 => '255.255.240.0',
2349 19 => '255.255.224.0',
2350 18 => '255.255.192.0',
2351 17 => '255.255.128.0',
2352 16 => '255.255.0.0',
2353 15 => '255.254.0.0',
2354 14 => '255.252.0.0',
2355 13 => '255.248.0.0',
2356 12 => '255.240.0.0',
2357 11 => '255.224.0.0',
2358 10 => '255.192.0.0',
2359 9 => '255.128.0.0',
2360 8 => '255.0.0.0',
2361 7 => '254.0.0.0',
2362 6 => '252.0.0.0',
2363 5 => '248.0.0.0',
2364 4 => '240.0.0.0',
2365 3 => '224.0.0.0',
2366 2 => '192.0.0.0',
2367 1 => '128.0.0.0'
2368 );
2369 $wildcardbylen = array
2370 (
2371 32 => '0.0.0.0',
2372 31 => '0.0.0.1',
2373 30 => '0.0.0.3',
2374 29 => '0.0.0.7',
2375 28 => '0.0.0.15',
2376 27 => '0.0.0.31',
2377 26 => '0.0.0.63',
2378 25 => '0.0.0.127',
2379 24 => '0.0.0.255',
2380 23 => '0.0.1.255',
2381 22 => '0.0.3.255',
2382 21 => '0.0.7.255',
2383 20 => '0.0.15.255',
2384 19 => '0.0.31.255',
2385 18 => '0.0.63.255',
2386 17 => '0.0.127.255',
2387 16 => '0.0.255.25',
2388 15 => '0.1.255.255',
2389 14 => '0.3.255.255',
2390 13 => '0.7.255.255',
2391 12 => '0.15.255.255',
2392 11 => '0.31.255.255',
2393 10 => '0.63.255.255',
2394 9 => '0.127.255.255',
2395 8 => '0.255.255.255',
2396 7 => '1.255.255.255',
2397 6 => '3.255.255.255',
2398 5 => '7.255.255.255',
2399 4 => '15.255.255.255',
2400 3 => '31.255.255.255',
2401 2 => '63.255.255.255',
2402 1 => '127.255.255.255'
2403 );
b901bf1f 2404 $maxperpage = getConfigVar ('IPV4_ADDRS_PER_PAGE');
e673ee24
DO
2405 if (isset($_REQUEST['pg']))
2406 $page = $_REQUEST['pg'];
2407 else
2408 $page=0;
2409
b6b87070
DO
2410 $range = getIPv4NetworkInfo ($id);
2411 loadIPv4AddrList ($range);
2034d968
DO
2412 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
2413 echo "<tr><td colspan=2 align=center><h1>${range['ip']}/${range['mask']}</h1><h2>${range['name']}</h2></td></tr>\n";
2414
2415 echo "<tr><td class=pcleft width='50%'>";
2416 startPortlet ('summary');
2417 $total = ($range['ip_bin'] | $range['mask_bin_inv']) - ($range['ip_bin'] & $range['mask_bin']) + 1;
2418 $used = count ($range['addrlist']);
2419 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
04d619d0
DO
2420
2421 echo "<tr><th width='50%' class=tdright>%% used:</th><td class=tdleft>";
2034d968
DO
2422 renderProgressBar ($used/$total);
2423 echo "&nbsp;${used}/${total}</td></tr>\n";
04d619d0 2424
001e61fa
DO
2425 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
2426 {
3444ecf2
DO
2427 // Build a backtrace from all parent networks.
2428 $clen = $range['mask'];
2429 $backtrace = array();
2430 while (NULL !== ($upperid = getIPv4AddressNetworkId ($range['ip'], $clen)))
2431 {
2432 $upperinfo = getIPv4NetworkInfo ($upperid);
2433 $clen = $upperinfo['mask'];
2434 $backtrace[] = $upperid;
2435 }
2436 $arrows = count ($backtrace);
2437 foreach (array_reverse ($backtrace) as $ancestorid)
001e61fa
DO
2438 {
2439 $ainfo = getIPv4NetworkInfo ($ancestorid);
3444ecf2
DO
2440 echo "<tr><th width='50%' class=tdright>";
2441 for ($i = 0; $i < $arrows; $i++)
2442 echo '&uarr;';
2443 $arrows--;
4fbb5a00 2444 echo "</th><td class=tdleft><a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno, 'id'=>$ainfo['id']))."'>${ainfo['ip']}/${ainfo['mask']}</a></td></tr>";
001e61fa 2445 }
3444ecf2
DO
2446 echo "<tr><th width='50%' class=tdright>&rarr;</th>";
2447 echo "<td class=tdleft>${range['ip']}/${range['mask']}</td></tr>";
001e61fa
DO
2448 // FIXME: get and display nested networks
2449 // $theitem = pickLeaf ($ipv4tree, $id);
2450 }
2451
545478d0
DO
2452 echo "<tr><th width='50%' class=tdright>Netmask:</th><td class=tdleft>";
2453 echo $netmaskbylen[$range['mask']];
2454 echo "</td></tr>\n";
04d619d0 2455
c607ab55
DO
2456 echo "<tr><th width='50%' class=tdright>Netmask:</th><td class=tdleft>";
2457 printf ('0x%08X', binMaskFromDec ($range['mask']));
2458 echo "</td></tr>\n";
2459
545478d0
DO
2460 echo "<tr><th width='50%' class=tdright>Wildcard bits:</th><td class=tdleft>";
2461 echo $wildcardbylen[$range['mask']];
2462 echo "</td></tr>\n";
04d619d0 2463
f3d0cb20 2464 $routers = findRouters ($range['addrlist']);
f0ed1181 2465 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes' and count ($routers))
04d619d0 2466 {
57dece2f 2467 echo "<tr><th width='50%' class=tdright>Routed by:</th>";
f3d0cb20 2468 printRoutersTD ($routers);
57dece2f 2469 echo "</tr>\n";
04d619d0
DO
2470 }
2471
4fbb5a00 2472 printTagTRs (makeHref(array('page'=>'ipv4space', 'tab'=>'default'))."&");
2034d968
DO
2473 echo "</table><br>\n";
2474 finishPortlet();
e1ae3fb4
AD
2475
2476 renderFilesPortlet ('ipv4net', $id);
2034d968 2477 echo "</td>\n";
e673ee24 2478
2034d968
DO
2479 echo "<td class=pcright>";
2480 startPortlet ('details');
e673ee24
DO
2481 $startip = $range['ip_bin'] & $range['mask_bin'];
2482 $endip = $range['ip_bin'] | $range['mask_bin_inv'];
2483 $realstartip = $startip;
2484 $realendip = $endip;
2485 $numpages = 0;
2486 if($endip - $startip > $maxperpage)
2487 {
e673ee24
DO
2488 $numpages = ($endip - $startip)/$maxperpage;
2489 $startip = $startip + $page * $maxperpage;
2490 $endip = $startip + $maxperpage-1;
2491 }
2492 echo "<center>";
b901bf1f
DO
2493 if ($numpages)
2494 echo '<h3>' . long2ip ($startip) . ' ~ ' . long2ip ($endip) . '</h3>';
e673ee24
DO
2495 for ($i=0; $i<$numpages; $i++)
2496 {
2497 if ($i == $page)
2498 echo "<b>$i</b> ";
2499 else
4fbb5a00 2500 echo "<a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno, 'id'=>$id, 'pg'=>$i))."'>$i</a> ";
e673ee24
DO
2501 }
2502 echo "</center>";
2503
beb9e88a 2504 echo "<table class='widetable' border=0 cellspacing=0 cellpadding=5 align='center' width='100%'>\n";
e673ee24
DO
2505 echo "<tr><th>Address</th><th>Name</th><th>Allocation</th></tr>\n";
2506
2507
b2035dca
DO
2508 for ($ip = $startip; $ip <= $endip; $ip++) :
2509 if (isset ($_REQUEST['hl_ipv4_addr']) and ip2long ($_REQUEST['hl_ipv4_addr']) == $ip)
2510 $secondstyle = 'tdleft port_highlight';
2727c7df 2511 else
b2035dca
DO
2512 $secondstyle = 'tdleft';
2513 if (!isset ($range['addrlist'][$ip]))
e673ee24 2514 {
4fbb5a00 2515 echo "<tr><td class=tdleft><a href='".makeHref(array('page'=>'ipaddress', 'ip'=>ip_long2quad($ip)))."'>" . ip_long2quad($ip);
b2035dca
DO
2516 echo "</a></td><td class='${secondstyle}'>&nbsp;</td><td class='${secondstyle}'>&nbsp;</td></tr>\n";
2517 continue;
2518 }
b2035dca 2519 $addr = $range['addrlist'][$ip];
2d318652 2520 echo "<tr class='${addr['class']}'>";
e673ee24 2521
4fbb5a00 2522 echo "<td class=tdleft><a href='".makeHref(array('page'=>'ipaddress', 'ip'=>$addr['ip']))."'>${addr['ip']}</a></td>";
b2035dca
DO
2523 echo "<td class='${secondstyle}'>${addr['name']}</td><td class='${secondstyle}'>";
2524 $delim = '';
2525 $prologue = '';
2526 if ( $addr['reserved'] == 'yes')
2527 {
2d318652 2528 echo "<strong>RESERVED</strong> ";
b2035dca
DO
2529 $delim = '; ';
2530 }
2d318652 2531 foreach ($range['addrlist'][$ip]['allocs'] as $ref)
b2035dca 2532 {
beb9e88a 2533 echo $delim . $aac2[$ref['type']];
4fbb5a00 2534 echo "<a href='".makeHref(array('page'=>'object', 'object_id'=>$ref['object_id'], 'hl_ipv4_addr'=>$addr['ip']))."'>";
b2035dca
DO
2535 echo $ref['name'] . (empty ($ref['name']) ? '' : '@');
2536 echo "${ref['object_name']}</a>";
2537 $delim = '; ';
2538 }
2539 if ($delim != '')
2540 {
6131056c 2541 $delim = '';
b2035dca
DO
2542 $prologue = '<br>';
2543 }
2d318652 2544 foreach ($range['addrlist'][$ip]['lblist'] as $ref)
b2035dca
DO
2545 {
2546 echo $prologue;
602663f4 2547 $prologue = '';
4fbb5a00
DY
2548 echo "${delim}<a href='".makeHref(array('page'=>'object', 'object_id'=>$ref['object_id']))."'>";
2549 echo "${ref['object_name']}</a>:<a href='".makeHref(array('page'=>'ipv4vs', 'vs_id'=>$ref['vs_id']))."'>";
b2035dca
DO
2550 echo "${ref['vport']}/${ref['proto']}</a>&rarr;";
2551 $delim = '; ';
2552 }
2553 if ($delim != '')
2554 {
2555 $delim = '';
2556 $prologue = '<br>';
e673ee24 2557 }
2d318652 2558 foreach ($range['addrlist'][$ip]['rslist'] as $ref)
b2035dca
DO
2559 {
2560 echo $prologue;
2561 $prologue = '';
4fbb5a00 2562 echo "${delim}&rarr;${ref['rsport']}@<a href='".makeHref(array('page'=>'ipv4rspool', 'pool_id'=>$ref['rspool_id']))."'>";
b2035dca
DO
2563 echo "${ref['rspool_name']}</a>";
2564 $delim = '; ';
2565 }
2566 echo "</td></tr>\n";
2567 endfor;
2727c7df 2568 // end of iteration
e673ee24
DO
2569
2570 echo "</table>";
2034d968
DO
2571 finishPortlet();
2572 echo "</td></tr></table>\n";
e673ee24
DO
2573}
2574
53ef3908 2575function renderIPv4NetworkProperties ($id)
e673ee24 2576{
e673ee24 2577 showMessageOrError();
53ef3908
DO
2578 $netdata = getIPv4NetworkInfo ($id);
2579 echo "<center><h1>${netdata['ip']}/${netdata['mask']}</h1></center>\n";
e673ee24 2580 echo "<table border=0 cellpadding=10 cellpadding=1 align='center'>\n";
7056988c 2581 printOpFormIntro ('editRange');
53ef3908
DO
2582 echo "<tr><td class='tdright'>Name:</td><td class='tdleft'><input type=text name=name size=20 value='${netdata['name']}'></tr>";
2583 echo "<tr><td colspan=2 class=tdcenter>";
2584 printImageHREF ('SAVE', 'Save changes', TRUE);
2585 echo "</td></form></tr></table>\n";
e673ee24
DO
2586}
2587
2d318652 2588function renderIPv4Address ($dottedquad)
e673ee24 2589{
4fbb5a00 2590 global $aat;
2d318652 2591 $address = getIPv4Address ($dottedquad);
68225375 2592 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
2d318652
DO
2593 echo "<tr><td colspan=2 align=center><h1>${dottedquad}</h1></td></tr>\n";
2594 if (!empty ($address['name']))
68225375 2595 echo "<tr><td colspan=2 align=center><h2>${address['name']}</h2></td></tr>\n";
e673ee24 2596
68225375
DO
2597 echo "<tr><td class=pcleft>";
2598 startPortlet ('summary');
2599 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
04d619d0 2600 echo "<tr><th width='50%' class=tdright>Allocations:</th><td class=tdleft>" . count ($address['allocs']) . "</td></tr>\n";
68225375
DO
2601 echo "<tr><th width='50%' class=tdright>Originated NAT connections:</th><td class=tdleft>" . count ($address['outpf']) . "</td></tr>\n";
2602 echo "<tr><th width='50%' class=tdright>Arriving NAT connections:</th><td class=tdleft>" . count ($address['inpf']) . "</td></tr>\n";
04d619d0 2603 echo "<tr><th width='50%' class=tdright>SLB virtual services:</th><td class=tdleft>" . count ($address['lblist']) . "</td></tr>\n";
68225375
DO
2604 echo "<tr><th width='50%' class=tdright>SLB real servers:</th><td class=tdleft>" . count ($address['rslist']) . "</td></tr>\n";
2605 printTagTRs();
2606 echo "</table><br>\n";
2607 finishPortlet();
2608 echo "</td>\n";
e673ee24 2609
68225375 2610 echo "<td class=pcright>";
e673ee24 2611
f74d96c6 2612 if (isset ($address['class']))
59bebe2b 2613 {
8e700dd1 2614 startPortlet ('allocations');
2d318652
DO
2615 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
2616 echo "<tr><th>object</th><th>OS interface</th><th>allocation type</th></tr>\n";
2617 $class = $address['class'];
2618 // render all allocation records for this address the same way
59bebe2b 2619 if ($address['reserved'] == 'yes')
2d318652
DO
2620 echo "<tr class='${class}'><td colspan=2>&nbsp;</td><td class=tdleft><strong>RESERVED</strong></td></tr>";
2621 foreach ($address['allocs'] as $bond)
59bebe2b 2622 {
8e700dd1
DO
2623 if (isset ($_REQUEST['hl_object_id']) and $_REQUEST['hl_object_id'] == $bond['object_id'])
2624 $secondclass = 'tdleft port_highlight';
2625 else
2626 $secondclass = 'tdleft';
4fbb5a00 2627 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
2628 echo $aat[$bond['type']];
2629 echo "</strong></td></tr>\n";
59bebe2b
DO
2630 }
2631 echo "</table><br><br>";
2632 finishPortlet();
2633 }
e673ee24 2634
f3d0cb20
DO
2635 // FIXME: The returned list is structured differently, than we expect it to be. One of the sides
2636 // must be fixed.
2d318652 2637 if (count ($address['lblist']))
e673ee24 2638 {
2d318652
DO
2639 startPortlet ('Virtual services (' . count ($address['lblist']) . ')');
2640 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
59bebe2b 2641 echo "<tr><th>VS</th><th>name</th></tr>\n";
2d318652 2642 foreach ($address['lblist'] as $vsinfo)
e673ee24 2643 {
4fbb5a00 2644 echo "<tr><td class=tdleft><a href='".makeHref(array('page'=>'ipv4vs', 'vs_id'=>$vsinfo['vs_id']))."'>";
59bebe2b 2645 echo buildVServiceName ($vsinfo) . "</a></td><td class=tdleft>";
5fe1ed76 2646 echo $vsinfo['name'] . "</td></tr>\n";
e673ee24 2647 }
59bebe2b
DO
2648 echo "</table><br><br>";
2649 finishPortlet();
e673ee24 2650 }
5fe1ed76
DO
2651
2652 if (count ($address['rslist']))
2653 {
2654 startPortlet ('Real servers (' . count ($address['rslist']) . ')');
2d318652 2655 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
53f4b619 2656 echo "<tr><th>&nbsp;</th><th>port</th><th>RS pool</th></tr>\n";
5fe1ed76
DO
2657 foreach ($address['rslist'] as $rsinfo)
2658 {
2659 echo "<tr><td>";
2660 if ($rsinfo['inservice'] == 'yes')
2661 printImageHREF ('inservice', 'in service');
2662 else
2663 printImageHREF ('notinservice', 'NOT in service');
4fbb5a00 2664 echo "</td><td class=tdleft>${rsinfo['rsport']}</td><td class=tdleft><a href='".makeHref(array('page'=>'ipv4rspool', 'pool_id'=>$rsinfo['rspool_id']))."'>";
2d318652 2665 echo $rsinfo['rspool_name'] . "</a></td></tr>\n";
5fe1ed76
DO
2666 }
2667 echo "</table><br><br>";
2668 finishPortlet();
2669 }
2670
68225375
DO
2671 if (count ($address['outpf']))
2672 {
105a3bc8 2673 startPortlet ('departing NAT rules');
2d318652 2674 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
105a3bc8
DO
2675 echo "<tr><th>proto</th><th>from</th><th>to</th><th>comment</th></tr>\n";
2676 foreach ($address['outpf'] as $rule)
b62ff880 2677 echo "<tr><td>${rule['proto']}</td><td>${rule['localip']}:${rule['localport']}</td><td>${rule['remoteip']}:${rule['remoteport']}</td><td>${rule['description']}</td></tr>";
105a3bc8 2678 echo "</table>";
68225375
DO
2679 finishPortlet();
2680 }
105a3bc8
DO
2681
2682 if (count ($address['inpf']))
2683 {
2684 startPortlet ('arriving NAT rules');
2d318652 2685 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
105a3bc8
DO
2686 echo "<tr><th>proto</th><th>from</th><th>to</th><th>comment</th></tr>\n";
2687 foreach ($address['inpf'] as $rule)
b62ff880 2688 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
2689 echo "</table>";
2690 finishPortlet();
2691 }
2692
68225375
DO
2693 echo "</td></tr>";
2694 echo "</table>\n";
e673ee24
DO
2695}
2696
2d318652 2697function renderIPv4AddressProperties ($dottedquad)
e673ee24 2698{
e673ee24 2699 showMessageOrError();
2d318652
DO
2700 $address = getIPv4Address ($dottedquad);
2701 echo "<center><h1>$dottedquad</h1></center>\n";
7056988c 2702
1fbc9fd6 2703 startPortlet ('update');
e673ee24 2704 echo "<table border=0 cellpadding=10 cellpadding=1 align='center'>\n";
7056988c 2705 printOpFormIntro ('editAddress');
2d318652
DO
2706 echo "<tr><td class='tdright'>Name:</td><td class='tdleft'><input type=text name=name size=20 value='${address['name']}'></tr>";
2707 echo "<td class='tdright'>Reserved:</td><td class='tdleft'><input type=checkbox name=reserved size=20 ";
2708 echo ($address['reserved']=='yes') ? 'checked' : '';
53ef3908
DO
2709 echo "></tr><tr><td colspan=2 class='tdcenter'>";
2710 printImageHREF ('SAVE', 'Save changes', TRUE);
2711 echo "</td></form></tr></table>\n";
1fbc9fd6
DO
2712 finishPortlet();
2713 if (empty ($address['name']) and $address['reserved'] == 'no')
2714 return;
7056988c 2715
1fbc9fd6 2716 startPortlet ('release');
7056988c 2717 printOpFormIntro ('editAddress', array ('name' => '', 'reserved' => ''));
1fbc9fd6
DO
2718 echo "<input type=submit value='release'></form>";
2719 finishPortlet();
e673ee24
DO
2720}
2721
2d318652 2722function renderIPv4AddressAllocations ($dottedquad)
e673ee24 2723{
e673ee24 2724 showMessageOrError();
39b4abd0
DO
2725 function printNewItemTR ()
2726 {
2727 global $aat;
2728 printOpFormIntro ('addIPv4Allocation');
2729 echo "<tr><td>";
9318d2ef 2730 printImageHREF ('add', 'allocate', TRUE);
f5ff50f5 2731 echo "</td><td><select name='object_id' tabindex=100>";
39b4abd0
DO
2732
2733 foreach (explode (',', getConfigVar ('IPV4_PERFORMERS')) as $type)
2734 foreach (getNarrowObjectList ($type) as $object)
2735 echo "<option value='${object['id']}'>${object['dname']}</option>";
2736
f5ff50f5
DO
2737 echo "</select></td><td><input type=text tabindex=101 name=bond_name size=10></td><td>";
2738 printSelect ($aat, 'bond_type', NULL, 102);
9318d2ef 2739 echo "</td><td>";
f5ff50f5 2740 printImageHREF ('add', 'allocate', TRUE, 103);
9318d2ef 2741 echo "</td></form></tr>";
39b4abd0 2742 }
4fbb5a00 2743 global $pageno, $tabno, $aat;
e673ee24 2744
2d318652 2745 $address = getIPv4Address ($dottedquad);
f74d96c6 2746
2d318652 2747 echo "<center><h1>${dottedquad}</h1></center>\n";
105a3bc8 2748 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
2d318652 2749 echo "<tr><th>&nbsp;</th><th>object</th><th>OS interface</th><th>allocation type</th><th>&nbsp;</th></tr>\n";
e673ee24 2750
39b4abd0
DO
2751 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
2752 printNewItemTR();
f74d96c6 2753 if (isset ($address['class']))
e673ee24 2754 {
f74d96c6
DO
2755 $class = $address['class'];
2756 if ($address['reserved'] == 'yes')
2757 echo "<tr class='${class}'><td colspan=3>&nbsp;</td><td class=tdleft><strong>RESERVED</strong></td><td>&nbsp;</td></tr>";
2758 foreach ($address['allocs'] as $bond)
2759 {
2760 echo "<tr class='$class'>";
2761 printOpFormIntro ('updIPv4Allocation', array ('object_id' => $bond['object_id']));
4fbb5a00 2762 echo "<td><a href='".makeHrefProcess(array('op'=>'delIPv4Allocation', 'ip'=>$dottedquad, 'object_id'=>$bond['object_id']))."'>";
f74d96c6
DO
2763 printImageHREF ('delete', 'Unallocate address');
2764 echo "</a></td>";
4fbb5a00 2765 echo "<td><a href='".makeHref(array('page'=>'object', 'object_id'=>$bond['object_id'], 'hl_ipv4_addr'=>$dottedquad))."'>${bond['object_name']}</td>";
f74d96c6
DO
2766 echo "<td><input type='text' name='bond_name' value='${bond['name']}' size=10></td><td>";
2767 printSelect ($aat, 'bond_type', $bond['type']);
2768 echo "</td><td>";
2769 printImageHREF ('save', 'Save changes', TRUE);
2770 echo "</td></form></tr>\n";
2771 }
e673ee24 2772 }
39b4abd0
DO
2773 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
2774 printNewItemTR();
e673ee24 2775 echo "</table><br><br>";
e673ee24
DO
2776}
2777
eeb4a5d8 2778function renderNATv4ForObject ($object_id = 0)
e673ee24 2779{
0b72ada2 2780 global $root;
9318d2ef
DO
2781 function printNewItemTR ($alloclist)
2782 {
0b72ada2 2783 global $root;
9318d2ef
DO
2784 printOpFormIntro ('addNATv4Rule');
2785 echo "<tr align='center'><td>";
2786 printImageHREF ('add', 'Add new NAT rule', TRUE);
2787 echo '</td><td>';
2788 printSelect (array ('TCP' => 'TCP', 'UDP' => 'UDP'), 'proto');
2789 echo "<select name='localip' tabindex=1>";
2790
2791 foreach ($alloclist as $dottedquad => $alloc)
2792 {
2793 $name = empty ($alloc['addrinfo']['name']) ? '' : (' (' . niftyString ($alloc['addrinfo']['name']) . ')');
2794 $osif = empty ($alloc['osif']) ? '' : ($alloc['osif'] . ': ');
2795 echo "<option value='${dottedquad}'>${osif}${dottedquad}${name}</option>";
2796 }
2797
2798 echo "</select>:<input type='text' name='localport' size='4' tabindex=2></td>";
2799 echo "<td><input type='text' name='remoteip' id='remoteip' size='10' tabindex=3>";
39106006
DO
2800 echo "<a href='javascript:;' onclick='window.open(\"" . makeHrefForHelper ('inet4list');
2801 echo "\", \"findobjectip\", \"height=700, width=400, location=no, menubar=no, resizable=yes, scrollbars=no, status=no, titlebar=no, toolbar=no\");'>";
9318d2ef
DO
2802 printImageHREF ('find', 'Find object');
2803 echo "</a>";
2804 echo ":<input type='text' name='remoteport' size='4' tabindex=4></td><td></td>";
2805 echo "<td colspan=1><input type='text' name='description' size='20' tabindex=5></td><td>";
f5ff50f5 2806 printImageHREF ('add', 'Add new NAT rule', TRUE, 6);
9318d2ef
DO
2807 echo "</td></tr></form>";
2808 }
4fbb5a00 2809 global $pageno, $tabno;
e673ee24
DO
2810
2811 $info = getObjectInfo ($object_id);
eeb4a5d8 2812 $forwards = getNATv4ForObject ($object_id);
2c817354 2813 $alloclist = getObjectIPv4Allocations ($object_id);
e673ee24 2814 showMessageOrError();
f28fbe8b 2815 echo "<center><h2>locally performed NAT</h2></center>";
e673ee24 2816
105a3bc8 2817 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
d54b9495 2818 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 2819
9318d2ef
DO
2820 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
2821 printNewItemTR ($alloclist);
e673ee24
DO
2822 foreach ($forwards['out'] as $pf)
2823 {
2c817354
DO
2824 $class = 'trerror';
2825 $osif = '';
2826 if (isset ($alloclist [$pf['localip']]))
2827 {
2828 $class = $alloclist [$pf['localip']]['addrinfo']['class'];
2829 $osif = $alloclist [$pf['localip']]['osif'] . ': ';
2830 }
e673ee24
DO
2831
2832 echo "<tr class='$class'>";
4fbb5a00
DY
2833 echo "<td><a href='".
2834 makeHrefProcess(array(
2835 'op'=>'delNATv4Rule',
2836 'localip'=>$pf['localip'],
2837 'localport'=>$pf['localport'],
2838 'remoteip'=>$pf['remoteip'],
2839 'remoteport'=>$pf['remoteport'],
2840 'proto'=>$pf['proto'],
2841 'object_id'=>$object_id)).
2842 "'>";
4de22e7e
DO
2843 printImageHREF ('delete', 'Delete NAT rule');
2844 echo "</a></td>";
4fbb5a00 2845 echo "<td>${pf['proto']}/${osif}<a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['localip']))."'>${pf['localip']}</a>:${pf['localport']}";
f28fbe8b
DO
2846 if (!empty ($pf['local_addr_name']))
2847 echo ' (' . $pf['local_addr_name'] . ')';
2848 echo "</td>";
4fbb5a00 2849 echo "<td><a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['remoteip']))."'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
e673ee24 2850
53ef3908 2851 $address = getIPv4Address ($pf['remoteip']);
e673ee24
DO
2852
2853 echo "<td class='description'>";
53ef3908
DO
2854 if (count ($address['allocs']))
2855 foreach ($address['allocs'] as $bond)
4fbb5a00 2856 echo "<a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$bond['object_id']))."'>${bond['object_name']}(${bond['name']})</a> ";
f28fbe8b
DO
2857 elseif (!empty ($pf['remote_addr_name']))
2858 echo '(' . $pf['remote_addr_name'] . ')';
7056988c
DO
2859 printOpFormIntro
2860 (
2861 'updNATv4Rule',
2862 array
2863 (
2864 'localip' => $pf['localip'],
2865 'localport' => $pf['localport'],
2866 'remoteip' => $pf['remoteip'],
2867 'remoteport' => $pf['remoteport'],
2868 'proto' => $pf['proto']
2869 )
2870 );
2871 echo "</td><td class='description'>";
d54b9495
DO
2872 echo "<input type='text' name='description' value='${pf['description']}'></td><td>";
2873 printImageHREF ('save', 'Save changes', TRUE);
2874 echo "</td></form></tr>";
e673ee24 2875 }
9318d2ef
DO
2876 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
2877 printNewItemTR ($alloclist);
e673ee24
DO
2878
2879 echo "</table><br><br>";
2880
f28fbe8b 2881 echo "<center><h2>arriving NAT connections</h2></center>";
105a3bc8 2882 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
e673ee24
DO
2883 echo "<tr><th></th><th>Source</th><th>Source objects</th><th>Target</th><th>Description</th></tr>\n";
2884
2885 foreach ($forwards['in'] as $pf)
2886 {
4fbb5a00
DY
2887 echo "<tr><td><a href='".
2888 makeHrefProcess(array(
2889 'op'=>'delNATv4Rule',
2890 'localip'=>$pf['localip'],
2891 'localport'=>$pf['localport'],
2892 'remoteip'=>$pf['remoteip'],
2893 'remoteport'=>$pf['remoteport'],
2894 'proto'=>$pf['proto'],
2895 'object_id'=>$pf['object_id']
2896 )).
2897 "'>";
4de22e7e
DO
2898 printImageHREF ('delete', 'Delete NAT rule');
2899 echo "</a></td>";
4fbb5a00
DY
2900 echo "<td>${pf['proto']}/<a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['localip']))."'>${pf['localip']}</a>:${pf['localport']}</td>";
2901 echo "<td class='description'><a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$pf['object_id']))."'>${pf['object_name']}</a>";
2902 echo "</td><td><a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['remoteip']))."'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
e673ee24
DO
2903 echo "<td class='description'>${pf['description']}</td></tr>";
2904 }
2905
e673ee24 2906 echo "</table><br><br>";
e673ee24
DO
2907}
2908
7056988c 2909// FIXME: move related code away into ophandler(s)
e673ee24
DO
2910function renderAddMultipleObjectsForm ()
2911{
20c901a7 2912 global $root, $pageno, $tabno, $nextorder;
e673ee24
DO
2913
2914 $type_id = array();
7f791d1d 2915 $global_type_id = 0;
e673ee24
DO
2916 $name = array();
2917 $asset_no = array();
ce4d1a79 2918 $keepvalues1 = $keepvalues2 = FALSE;
42d73cbf 2919 showMessageOrError();
e673ee24
DO
2920
2921 // Render a form for the next.
2922 $typelist = getObjectTypeList();
4c330a14 2923 $typelist[0] = 'select type...';
7f791d1d 2924
f60bb422
DO
2925 startPortlet ('Distinct types, same tags');
2926 $max = getConfigVar ('MASSCOUNT');
42d73cbf 2927 printOpFormIntro ('addObjects');
e673ee24 2928 echo '<table border=0 align=center>';
f60bb422
DO
2929 echo "<tr><th>Object type</th><th>Common name</th><th>Visible label</th>";
2930 echo "<th>Asset tag</th><th>Barcode</th><th>Tags</th></tr>\n";
7f791d1d 2931 // If a user forgot to select object type on input, we keep his
e673ee24 2932 // previous input in the form.
9c0b0016 2933 for ($i = 0; $i < $max; $i++)
e673ee24 2934 {
7f791d1d 2935 echo '<tr><td>';
e7ade6bf
DO
2936 // Don't employ DEFAULT_OBJECT_TYPE to avoid creating ghost records for pre-selected empty rows.
2937 printSelect ($typelist, "${i}_object_type_id", 0);
e673ee24
DO
2938 echo '</td>';
2939 echo "<td><input type=text size=30 name=${i}_object_name";
ce4d1a79 2940 if ($keepvalues1 and isset ($name[$i]) and (!isset ($type_id[$i]) or $type_id[$i] == 0))
e673ee24
DO
2941 echo " value='${name[$i]}'";
2942 echo "></td>";
2943 echo "<td><input type=text size=30 name=${i}_object_label";
ce4d1a79 2944 if ($keepvalues1 and isset ($label[$i]) and (!isset ($type_id[$i]) or $type_id[$i] == 0))
e673ee24
DO
2945 echo " value='${label[$i]}'";
2946 echo "></td>";
2947 echo "<td><input type=text size=20 name=${i}_object_asset_no";
ce4d1a79 2948 if ($keepvalues1 and isset ($asset_no[$i]) and (!isset ($type_id[$i]) or $type_id[$i] == 0))
e673ee24
DO
2949 echo " value='${asset_no[$i]}'";
2950 echo "></td>";
2951 echo "<td><input type=text size=10 name=${i}_object_barcode";
ce4d1a79 2952 if ($keepvalues1 and isset ($barcode[$i]) and (!isset ($type_id[$i]) or $type_id[$i] == 0))
e673ee24
DO
2953 echo " value='${barcode[$i]}'";
2954 echo "></td>";
f60bb422
DO
2955 if ($i == 0)
2956 {
2957 echo "<td valign=top rowspan=${max}>";
2958 renderTagSelect();
2959 echo "</td>\n";
2960 }
e673ee24 2961 echo "</tr>\n";
e673ee24 2962 }
216c84bb 2963 echo "<tr><td class=submit colspan=5><input type=submit name=got_fast_data value='Go!'></td></tr>\n";
e673ee24
DO
2964 echo "</form></table>\n";
2965 finishPortlet();
7f791d1d 2966
f60bb422 2967 startPortlet ('Same type, same tags');
42d73cbf 2968 printOpFormIntro ('addLotOfObjects');
f60bb422
DO
2969 echo "<table border=0 align=center><tr><th>names</th><th>type</th></tr>";
2970 echo "<tr><td rowspan=3><textarea name=namelist cols=40 rows=25>\n";
ce4d1a79 2971 if ($keepvalues2 and $global_type_id == 0)
7f791d1d 2972 echo $_REQUEST['namelist'];
f60bb422
DO
2973 echo "</textarea></td><td valign=top>";
2974 printSelect ($typelist, "global_type_id", getConfigVar ('DEFAULT_OBJECT_TYPE'));
2975 echo "</td></tr>";
2976 echo "<tr><th>Tags</th></tr>";
2977 echo "<tr><td valign=top>";
2978 renderTagSelect();
2979 echo "</td></tr>";
2980 echo "<tr><td colspan=2><input type=submit name=got_very_fast_data value='Go!'></td></tr></table>\n";
2981 echo "</form>\n";
7f791d1d 2982 finishPortlet();
e673ee24
DO
2983}
2984
2985function printGreeting ()
2986{
d6d79c36
DO
2987 global $root, $remote_username, $remote_displayname;
2988 echo "Hello, <a href='${root}?page=myaccount&tab=default'>${remote_displayname}</a>. This is RackTables " .
2989 CODE_VERSION .
2990 ". Click <a href='${root}?logout'>here</a> to logout.";
e673ee24
DO
2991}
2992
2993function renderSearchResults ()
2994{
0b9c98d7 2995 global $root;
e673ee24
DO
2996 $terms = trim ($_REQUEST['q']);
2997 if (empty ($terms))
2998 {
591ff2c4 2999 showError ('Search string cannot be empty.', __FUNCTION__);
e673ee24
DO
3000 return;
3001 }
54522168 3002 if (!permitted ('objects', 'default'))
e673ee24 3003 {
591ff2c4 3004 showError ('You are not authorized for viewing information about objects.', __FUNCTION__);
e673ee24
DO
3005 return;
3006 }
ea5fc465 3007 $nhits = 0;
e673ee24
DO
3008 // If we search for L2 address, we can either find one or find none.
3009 if
3010 (
05771508
DO
3011 preg_match (RE_L2_IFCFG, $terms) or
3012 preg_match (RE_L2_SOLID, $terms) or
3013 preg_match (RE_L2_CISCO, $terms) or
1930dc7f 3014 preg_match (RE_L2_IPCFG, $terms) or
05771508
DO
3015 // Foundry STP bridge ID: bridge priotity + port MAC address. Cut off first 4 chars and look for MAC address.
3016 preg_match (RE_L2_FDRYSTP, $terms)
e673ee24
DO
3017 )
3018 // Search for L2 address.
3019 {
3ec29bf4
DO
3020 $terms = str_replace ('.', '', $terms);
3021 $terms = str_replace (':', '', $terms);
1930dc7f 3022 $terms = str_replace ('-', '', $terms);
ea5fc465 3023 $terms = substr ($terms, -12);
e673ee24
DO
3024 $result = searchByl2address ($terms);
3025 if ($result !== NULL)
3026 {
ea5fc465
DO
3027 $nhits++;
3028 $lasthit = 'port';
3029 $summary['port'][] = $result;
e673ee24 3030 }
e673ee24 3031 }
05771508 3032 elseif (preg_match (RE_IP4_ADDR, $terms))
64347dcf 3033 // Search for IPv4 address.
e673ee24 3034 {
bb0a44e9 3035 if (NULL !== getIPv4AddressNetworkId ($terms))
e673ee24 3036 {
ea5fc465 3037 $nhits++;
f3d0cb20
DO
3038 $lasthit = 'ipv4addressbydq';
3039 $summary['ipv4addressbydq'][] = $terms;
e673ee24 3040 }
e673ee24 3041 }
05771508 3042 elseif (preg_match (RE_IP4_NET, $terms))
64347dcf
DO
3043 // Search for IPv4 network
3044 {
3045 list ($base, $len) = explode ('/', $terms);
3046 if (NULL !== ($tmp = getIPv4AddressNetworkId ($base, $len + 1)))
3047 {
3048 $nhits++;
3049 $lasthit = 'ipv4network';
3050 $summary['ipv4network'][] = getIPv4NetworkInfo ($tmp);
3051 }
3052 }
e673ee24 3053 else
ea5fc465 3054 // Search for objects, addresses, networks, virtual services and RS pools by their description.
e673ee24 3055 {
ea5fc465
DO
3056 $tmp = getObjectSearchResults ($terms);
3057 if (count ($tmp))
e673ee24 3058 {
ea5fc465
DO
3059 $nhits += count ($tmp);
3060 $lasthit = 'object';
3061 $summary['object'] = $tmp;
e673ee24 3062 }
ea5fc465
DO
3063 $tmp = getIPv4AddressSearchResult ($terms);
3064 if (count ($tmp))
e673ee24 3065 {
ea5fc465 3066 $nhits += count ($tmp);
f3d0cb20
DO
3067 $lasthit = 'ipv4addressbydescr';
3068 $summary['ipv4addressbydescr'] = $tmp;
ea5fc465
DO
3069 }
3070 $tmp = getIPv4PrefixSearchResult ($terms);
3071 if (count ($tmp))
3072 {
3073 $nhits += count ($tmp);
3074 $lasthit = 'ipv4network';
3075 $summary['ipv4network'] = $tmp;
3076 }
05411ccd
DO
3077 $tmp = getIPv4RSPoolSearchResult ($terms);
3078 if (count ($tmp))
3079 {
3080 $nhits += count ($tmp);
3081 $lasthit = 'ipv4rspool';
3082 $summary['ipv4rspool'] = $tmp;
3083 }
3084 $tmp = getIPv4VServiceSearchResult ($terms);
3085 if (count ($tmp))
3086 {
3087 $nhits += count ($tmp);
3088 $lasthit = 'ipv4vs';
3089 $summary['ipv4vs'] = $tmp;
3090 }
6a88e734
DO
3091 $tmp = getAccountSearchResult ($terms);
3092 if (count ($tmp))
3093 {
3094 $nhits += count ($tmp);
3095 $lasthit = 'user';
3096 $summary['user'] = $tmp;
3097 }
e1ae3fb4
AD
3098 $tmp = getFileSearchResult ($terms);
3099 if (count ($tmp))
3100 {
3101 $nhits += count ($tmp);
3102 $lasthit = 'file';
3103 $summary['file'] = $tmp;
3104 }
ea5fc465
DO
3105 }
3106 if ($nhits == 0)
3107 echo "<center><h2>Nothing found for '${terms}'</h2></center>";
3108 elseif ($nhits == 1)
3109 {
3110 $record = current ($summary[$lasthit]);
3111 switch ($lasthit)
3112 {
3113 case 'port':
3114 echo "<script language='Javascript'>document.location='${root}?page=object";
3115 echo "&hl_port_id=" . $record['port_id'];
3116 echo "&object_id=" . $record['object_id'] . "';//</script>";
3117 break;
f3d0cb20
DO
3118 case 'ipv4addressbydq':
3119 $parentnet = getIPv4AddressNetworkId ($record);
3120 if ($parentnet !== NULL)
e1ae3fb4 3121 echo "<script language='Javascript'>document.location='${root}?page=ipv4net&tab=default&id=${parentnet}&hl_ipv4_addr=${record}';//</script>";
f3d0cb20
DO
3122 else
3123 echo "<script language='Javascript'>document.location='${root}?page=ipaddress&ip=${record}';//</script>";
ea5fc465 3124 break;
f3d0cb20
DO
3125 case 'ipv4addressbydescr':
3126 $parentnet = getIPv4AddressNetworkId ($record['ip']);
3127 if ($parentnet !== NULL)
e1ae3fb4 3128 echo "<script language='Javascript'>document.location='${root}?page=ipv4net&tab=default&id=${parentnet}&hl_ipv4_addr=${record['ip']}';//</script>";
f3d0cb20
DO
3129 else
3130 echo "<script language='Javascript'>document.location='${root}?page=ipaddress&ip=${record['ip']}';//</script>";
ea5fc465
DO
3131 break;
3132 case 'ipv4network':
e1ae3fb4 3133 echo "<script language='Javascript'>document.location='${root}?page=ipv4net";
ea5fc465
DO
3134 echo "&id=${record['id']}";
3135 echo "';//</script>";
3136 break;
3137 case 'object':
3138 echo "<script language='Javascript'>document.location='${root}?page=object&object_id=${record['id']}';//</script>";
3139 break;
05411ccd 3140 case 'ipv4rspool':
e1ae3fb4 3141 echo "<script language='Javascript'>document.location='${root}?page=ipv4rspool&pool_id=${record['pool_id']}';//</script>";
05411ccd
DO
3142 break;
3143 case 'ipv4vs':
49fb2686 3144 echo "<script language='Javascript'>document.location='${root}?page=ipv4vs&vs_id=${record['id']}';//</script>";
05411ccd 3145 break;
6a88e734
DO
3146 case 'user':
3147 echo "<script language='Javascript'>document.location='${root}?page=user&user_id=${record['user_id']}';//</script>";
3148 break;
e1ae3fb4
AD
3149 case 'file':
3150 echo "<script language='Javascript'>document.location='${root}?page=file&file_id=${record['id']}';//</script>";
3151 break;
ea5fc465
DO
3152 }
3153 return;
3154 }
3155 else
3156 {
3157 global $nextorder;
3158 $order = 'odd';
3159 echo "<center><h2>${nhits} result(s) found for '${terms}'</h2></center>";
3160 foreach ($summary as $where => $what)
3161 switch ($where)
e673ee24 3162 {
ea5fc465 3163 case 'object':
06adfe89 3164 startPortlet ("<a href='${root}?page=objects'>Objects</a>");
ea5fc465 3165 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
e1ae3fb4 3166 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>Barcode</th></tr>';
ea5fc465
DO
3167 foreach ($what as $obj)
3168 {
2b3d64c5
DO
3169 $tags = loadRackObjectTags ($obj['id']);
3170 echo "<tr class=row_${order} valign=top><td class=tdleft><a href=\"${root}?page=object&object_id=${obj['id']}\">${obj['dname']}</a>";
3171 if (count ($tags))
3172 echo '<br><small>' . serializeTags ($tags) . '</small>';
3173 echo "</td><td>${obj['label']}</td>";
ea5fc465
DO
3174 echo "<td>${obj['asset_no']}</td>";
3175 echo "<td>${obj['barcode']}</td></tr>";
3176 $order = $nextorder[$order];
3177 }
3178 echo '</table>';
3179 finishPortlet();
3180 break;
3181 case 'ipv4network':
06adfe89 3182 startPortlet ("<a href='${root}?page=ipv4space'>IPv4 networks</a>");
ea5fc465 3183 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
71287f1c 3184 foreach ($what as $netinfo)
ea5fc465 3185 {
0b9c98d7
DO
3186 echo "<tr class=row_${order} valign=top><td>";
3187 renderIPv4NetCell ($netinfo);
3188 echo "</td></tr>\n";
ea5fc465
DO
3189 $order = $nextorder[$order];
3190 }
3191 echo '</table>';
3192 finishPortlet();
3193 break;
f3d0cb20 3194 case 'ipv4addressbydescr':
ea5fc465
DO
3195 startPortlet ('IPv4 addresses');
3196 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
f3d0cb20 3197 // FIXME: address, parent network, routers (if extended view is enabled)
e1ae3fb4 3198 echo '<tr><th>Address</th><th>Description</th></tr>';
ea5fc465
DO
3199 foreach ($what as $addr)
3200 {
f3d0cb20
DO
3201 echo "<tr class=row_${order}><td class=tdleft>";
3202 $parentnet = getIPv4AddressNetworkId ($addr['ip']);
3203 if ($parentnet !== NULL)
e1ae3fb4 3204 echo "<a href='${root}?page=ipv4net&tab=default&id=${parentnet}&hl_ipv4_addr=${addr['ip']}'>${addr['ip']}</a></td>";
f3d0cb20
DO
3205 else
3206 echo "<a href='${root}?page=ipaddress&ip=${addr['ip']}'>${addr['ip']}</a></td>";
ea5fc465
DO
3207 echo "<td class=tdleft>${addr['name']}</td></tr>";
3208 $order = $nextorder[$order];
3209 }
3210 echo '</table>';
3211 finishPortlet();
3212 break;
05411ccd 3213 case 'ipv4rspool':
ee437dab 3214 startPortlet ("<a href='${root}?page=ipv4rsplist'>RS pools</a>");
05411ccd
DO
3215 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
3216 foreach ($what as $rspool)
3217 {
216136d2
DO
3218 echo "<tr class=row_${order}><td class=tdleft>";
3219 renderRSPoolCell ($rspool['pool_id'], $rspool['name']);
3220 echo "</td></tr>";
05411ccd
DO
3221 $order = $nextorder[$order];
3222 }
3223 echo '</table>';
3224 finishPortlet();
3225 break;
3226 case 'ipv4vs':
a239e016 3227 startPortlet ("<a href='${root}?page=ipv4vslist'>Virtual services</a>");
05411ccd 3228 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
8128c257 3229 foreach ($what as $vsinfo)
05411ccd 3230 {
8128c257
DO
3231 echo "<tr class=row_${order}><td class=tdleft>";
3232 renderIPv4VSCell ($vsinfo);
3233 echo "</td></tr>";
6a88e734
DO
3234 $order = $nextorder[$order];
3235 }
3236 echo '</table>';
3237 finishPortlet();
3238 break;
3239 case 'user':
3240 startPortlet ("<a href='${root}?page=userlist'>Users</a>");
3241 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
6a88e734
DO
3242 foreach ($what as $item)
3243 {
19dac9c3
DO
3244 echo "<tr class=row_${order}><td class=tdleft>";
3245 renderUserCell ($item);
3246 echo "</td></tr>";
05411ccd
DO
3247 $order = $nextorder[$order];
3248 }</