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