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