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