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