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