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