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