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