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