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