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