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