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