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