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