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