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