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