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