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