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