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