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