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