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