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