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