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