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