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