r1458 + introduce dummy counter to avoid warning in getRSUforRack()
[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 {
39a6338a 94 showError ('Invalid row_id', __FUNCTION__);
e673ee24
DO
95 return;
96 }
97 if (($rowInfo = getRackRowInfo ($row_id)) == NULL)
98 {
39a6338a 99 showError ('getRackRowInfo() failed', __FUNCTION__);
e673ee24
DO
100 return;
101 }
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
39a6338a 138function showError ($info = '', $funcname = 'N/A')
e673ee24
DO
139{
140 global $root;
b1cae282 141 echo "<div class=msg_error>An error has occured in function [${funcname}]. ";
e673ee24
DO
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 {
39a6338a 154 showError ('Invalid rack_id', __FUNCTION__);
e673ee24
DO
155 return;
156 }
157 if (($rackData = getRackData ($rack_id)) == NULL)
158 {
39a6338a 159 showError ('getRackData() failed', __FUNCTION__);
e673ee24
DO
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";
9ddfe309
DO
182 echo "<tr><th width='10%'>&nbsp;</th><th width='20%'>${markup['left']}</th>";
183 echo "<th width='50%'>Interior</th><th width='20%'>${markup['right']}</th></tr>\n";
e673ee24
DO
184 for ($i = $rackData['height']; $i > 0; $i--)
185 {
9ddfe309 186 echo '<tr><th>' . ($rackData['bottom_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 {
39a6338a 355 showError ('getObjectInfo() failed', __FUNCTION__);
e673ee24
DO
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 {
39a6338a 469 showError ('getRackData() failed', __FUNCTION__);
e673ee24
DO
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 {
591ff2c4 514 showError ('Invalid rack_id', __FUNCTION__);
e673ee24
DO
515 return;
516 }
517 if (($rackData = getRackData ($rack_id)) == NULL)
518 {
591ff2c4 519 showError ('getRackData() failed', __FUNCTION__);
e673ee24
DO
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 {
591ff2c4 614 showError ('Invalid object_id', __FUNCTION__);
e673ee24
DO
615 return;
616 }
617 $info = getObjectInfo ($object_id);
618 if ($info == NULL)
619 {
591ff2c4 620 showError ('getObjectInfo() failed', __FUNCTION__);
e673ee24
DO
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 {
591ff2c4 896 showError ('Invalid object_id', __FUNCTION__);
e673ee24
DO
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 {
591ff2c4 1011 showError ('Invalid object_id', __FUNCTION__);
e673ee24
DO
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 {
591ff2c4 1150 showError ('Invalid object_id', __FUNCTION__);
e673ee24
DO
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 {
591ff2c4 1158 showError ('getObjectInfo() failed', __FUNCTION__);
e673ee24
DO
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);
591ff2c4 1167 showError ('getResidentRacksData() failed', __FUNCTION__);
e673ee24
DO
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 {
591ff2c4 1180 showError ('getRackData() failed', __FUNCTION__);
e673ee24
DO
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 {
591ff2c4 1347 showError ('getUnmountedObjects() failed', __FUNCTION__);
e673ee24
DO
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 {
591ff2c4 1372 showError ('getProblematicObjects() failed', __FUNCTION__);
e673ee24
DO
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 {
591ff2c4 1395 showError ('getObjectGroupInfo() failed', __FUNCTION__);
e673ee24
DO
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 {
591ff2c4 1421 showError ('getObjectGroupInfo() failed', __FUNCTION__);
e673ee24
DO
1422 return;
1423 }
1424 $objects = getObjectList ($group_id);
1425 if ($objects === NULL)
1426 {
591ff2c4 1427 showError ('getObjectList() failed', __FUNCTION__);
e673ee24
DO
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:
591ff2c4 1516 showError ("Uknown object type '${object_type}'", __FUNCTION__);
e673ee24
DO
1517 return;
1518 }
1519 global $dbxlink;
1520 $result = $dbxlink->query ($query);
1521 if ($result == NULL)
1522 {
591ff2c4 1523 showError ('SQL query failed', __FUNCTION__);
e673ee24
DO
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;
a7fe7729
DO
1616 echo '<table border=0 class=objectview cellspacing=0 cellpadding=0><tr><td class=pcleft>';
1617
1618 startPortlet ('Subnets');
e673ee24
DO
1619 echo "<table class='widetable' border=0 cellpadding=10 cellspacing=0 align='center'>\n";
1620 $addrspaceList = getAddressspaceList();
a7fe7729 1621 echo "<tr><th>Subnet</th><th>Name</th><th>Total/used addresses</th></tr>";
e673ee24
DO
1622 foreach ($addrspaceList as $iprange)
1623 {
d6207e1a 1624 echo "<tr><td class=tdleft><a href='${root}?page=iprange&id=${iprange['id']}'>${iprange['ip']}/${iprange['mask']}</a></td><td>${iprange['name']}</td><td>";
e673ee24
DO
1625 echo ($iprange['ip_bin'] | $iprange['mask_bin_inv']) - ($iprange['ip_bin'] & $iprange['mask_bin'])+1;
1626 $range = getIPRange($iprange['id']);
1627 echo "/";
1628 echo count($range['addrlist']);
1629 echo "</td></tr>";
1630 }
1631 echo "</table>\n";
a7fe7729
DO
1632 finishPortlet();
1633
1634 echo "</td>\n<td class=pcright>";
1635
1636 startPortlet ('SLB summary');
c3bdc503 1637 $summary = getSLBSummary();
4cadac8f
DO
1638#echo '<pre>';
1639#print_r ($summary);
1640#echo '</pre>';
1641 // A single id-keyed array isn't used here to preserve existing
1642 // order of LBs returned by getSLBSummary()
c3bdc503
DO
1643 $lblist = array();
1644 $lbdname = array();
4cadac8f
DO
1645 foreach ($summary as $vipdata)
1646 foreach (array_keys ($vipdata['rspools']) as $lb_object_id)
c3bdc503
DO
1647 if (!in_array ($lb_object_id, $lblist))
1648 {
1649 $oi = getObjectInfo ($lb_object_id);
1650 $lbdname[$lb_object_id] = $oi['dname'];
1651 $lblist[] = $lb_object_id;
1652 }
1653 if (!count ($summary))
1654 echo 'none configured';
1655 else
1656 {
1657 echo "<table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
13bffb29 1658 echo "<tr><th>VIP</th><th>Name</th>";
c3bdc503
DO
1659 foreach ($lblist as $lb_object_id)
1660 echo "<th><a href='$root?page=object&tab=default&object_id=${lb_object_id}'>" . $lbdname[$lb_object_id] . "</a></th>";
1661 echo "</tr>\n";
4cadac8f
DO
1662 foreach ($summary as $vsid => $vsdata)
1663 {
1664 echo "<tr><td class=tdleft><a href='$root?page=vservice&tab=default&id=${vsid}'>";
8d790216 1665 echo buildVServiceName ($vsdata);
13bffb29 1666 echo "<td>${vsdata['name']}</td>";
4cadac8f
DO
1667 foreach ($lblist as $lb_object_id)
1668 echo '<td>' . (isset ($vsdata['rspools'][$lb_object_id]) ? $vsdata['rspools'][$lb_object_id] : '&nbsp;') . '</td>';
1669 echo "</tr>";
1670 }
c3bdc503
DO
1671 echo "</table>\n";
1672 }
a7fe7729
DO
1673 finishPortlet ();
1674
1675 echo '</td></tr></table>';
e673ee24
DO
1676}
1677
1678function renderAddNewRange ()
1679{
1680 global $root, $pageno, $tabno;
1681 showMessageOrError();
2a201216 1682
a7fe7729 1683 echo "<center><h2>Add New</h2></center>\n";
2a201216 1684 echo "<table class='widetable' border=0 cellpadding=10 align='center'>\n";
2dee289e 1685 echo "<tr><th>Address range</th><th>Name</th><th>C&gt;*</th><th>&nbsp;</th></tr>\n";
2a201216
DY
1686 echo "<form name='add_new_range' action='process.php'>\n";
1687 echo "<input type=hidden name=op value=addRange>\n";
1688 echo "<input type=hidden name=page value='${pageno}'>\n";
1689 echo "<input type=hidden name=tab value='${tabno}'>\n";
1690 echo "<tr><td class='tdcenter'><input type=text name='range' size=18 class='live-validate'></td>\n";
1691 echo "<td class='tdcenter'><input type=text name='name' size='20'></td>\n";
2dee289e 1692 echo "<td class='tdcenter'><input type=checkbox name='is_bcast' checked></td>\n";
2a201216
DY
1693 echo "<td class='tdcenter'><input type=submit value='Add a new range'></td></tr>\n";
1694 echo "</form></table><br><br>\n";
1695
a7fe7729 1696 echo "<center><h2>Manage Existing</h2></center>\n";
2a201216 1697 echo "<table class='widetable' border=0 cellpadding=10 align='center'>\n";
e673ee24
DO
1698 $addrspaceList = getAddressspaceList();
1699 echo "<tr><th>&nbsp;</th><th>Address range</th><th>Name</th><th>Total/used addresses</th></tr>";
1700 foreach ($addrspaceList as $iprange)
1701 {
1702 $range = getIPRange($iprange['id']);
dc462202 1703 $usedips = count ($range['addrlist']);
e673ee24
DO
1704 echo "<tr>";
1705 if ($usedips == 0)
1706 {
1707 echo "<td><a href='process.php?op=delRange&page=${pageno}&tab=${tabno}&id=${iprange['id']}'>";
1708 printImageHREF ('delete', 'Delete this IP range');
1709 echo "</a></td>\n";
1710 }
1711 else
1712 echo "<td>&nbsp</td>";
1713 echo "<td><a href='${root}?page=iprange&id=${iprange['id']}'>${iprange['ip']}/${iprange['mask']}</a></td><td>${iprange['name']}</td><td>";
1714 echo ($iprange['ip_bin'] | $iprange['mask_bin_inv']) - ($iprange['ip_bin'] & $iprange['mask_bin'])+1;
1715 echo "/";
1716 echo $usedips;
2a201216 1717 #echo "</td></tr></table>";
e673ee24
DO
1718 echo "</td></tr>";
1719 }
e673ee24
DO
1720}
1721
1722function renderIPRange ()
1723{
1724 global $root;
b901bf1f 1725 $maxperpage = getConfigVar ('IPV4_ADDRS_PER_PAGE');
e673ee24
DO
1726 $id = $_REQUEST['id'];
1727 if (isset($_REQUEST['pg']))
1728 $page = $_REQUEST['pg'];
1729 else
1730 $page=0;
1731
e673ee24
DO
1732 $range = getIPRange($id);
1733 echo "<center><h1>${range['ip']}/${range['mask']}</h1><h2>${range['name']}</h2></center>\n";
1734
e673ee24
DO
1735 $startip = $range['ip_bin'] & $range['mask_bin'];
1736 $endip = $range['ip_bin'] | $range['mask_bin_inv'];
1737 $realstartip = $startip;
1738 $realendip = $endip;
1739 $numpages = 0;
1740 if($endip - $startip > $maxperpage)
1741 {
e673ee24
DO
1742 $numpages = ($endip - $startip)/$maxperpage;
1743 $startip = $startip + $page * $maxperpage;
1744 $endip = $startip + $maxperpage-1;
1745 }
1746 echo "<center>";
b901bf1f
DO
1747 if ($numpages)
1748 echo '<h3>' . long2ip ($startip) . ' ~ ' . long2ip ($endip) . '</h3>';
e673ee24
DO
1749 for ($i=0; $i<$numpages; $i++)
1750 {
1751 if ($i == $page)
1752 echo "<b>$i</b> ";
1753 else
1754 echo "<a href='${root}?page=iprange&id=$id&pg=$i'>$i</a> ";
1755 }
1756 echo "</center>";
1757
1758 echo "<table class='widetable' border=0 cellspacing=0 cellpadding=5 align='center'>\n";
1759 echo "<tr><th>Address</th><th>Name</th><th>Allocation</th></tr>\n";
1760
1761
1762 for($ip = $startip; $ip<=$endip; $ip++)
1763 {
dcee8072 1764 if (isset ($range['addrlist'][$ip]))
e673ee24
DO
1765 {
1766 $numshared = countRefsOfType($range['addrlist'][$ip]['references'], 'shared', 'eq');
1767 $numreg = countRefsOfType($range['addrlist'][$ip]['references'], 'regular', 'eq');
1768 $numvirt = countRefsOfType($range['addrlist'][$ip]['references'], 'virtual', 'eq');
1769
1770 $addr = $range['addrlist'][$ip];
1771 if ( ($numshared > 0 && $numreg > 0) || $numreg > 1 )
1772 echo "<tr class='trwarning'>";
1773 elseif ( $addr['reserved'] == 'yes' and $numshared+$numreg+$numvirt > 0)
1774 echo "<tr class='trwarning'>";
1775 elseif ( $addr['reserved'] == 'yes')
1776 echo "<tr class='trbusy'>";
1777 elseif ( $numshared > 0 || $numreg > 0)
1778 echo "<tr class='trbusy'>";
1779 else
1780 echo "<tr>";
1781
1782 echo "<td><a href='${root}?page=ipaddress&ip=${addr['ip']}'>${addr['ip']}</a></td><td>${addr['name']}</td><td>";
1783 if ( $addr['reserved'] == 'yes')
1784 echo "<b>Reserved;</b> ";
1785 foreach ($range['addrlist'][$ip]['references'] as $ref)
1786 {
db88e2de
DO
1787 echo "<a href='${root}?page=object&object_id=${ref['object_id']}'>";
1788 echo $ref['name'] . (empty ($ref['name']) ? '' : '@');
1789 echo "${ref['object_name']}</a>; ";
e673ee24
DO
1790 }
1791 echo "</td></tr>\n";
1792 }
1793 else
1794 {
1795 echo "<tr><td><a href='${root}?page=ipaddress&ip=".long2ip($ip)."'>".long2ip($ip)."</a></td><td>&nbsp;</td><td>&nbsp;</td></tr>\n";
1796 }
1797 }
1798
1799 echo "</table>";
1800
1801}
1802
1803function renderIPRangeProperties ()
1804{
1805 global $pageno, $tabno;
1806 $id = $_REQUEST['id'];
1807 showMessageOrError();
1808 $range = getIPRange($id);
1809 echo "<center><h1>${range['ip']}/${range['mask']}</h1></center>\n";
1810 echo "<table border=0 cellpadding=10 cellpadding=1 align='center'>\n";
1811 echo "<form action='process.php'><input type=hidden name=op value=editRange>";
1812 echo "<input type=hidden name=page value='${pageno}'>\n";
1813 echo "<input type=hidden name=tab value='${tabno}'>\n";
1814 echo "<input type=hidden name=id value='${id}'>";
1815 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>";
1816 echo "</table>\n";
1817
1818}
1819
1820function renderIPAddress ()
1821{
1822 global $root;
1823 $ip = $_REQUEST['ip'];
1824 $address = getIPAddress($ip);
1825 echo "<center><h1>$ip</h1>";
1826 if ($address['exists'] == 1)
1827 echo "<h2>${address['name']}</h2>";
1828 echo "</center>\n";
1829
1830// echo "<table width='100%' cesspadding=5 cellspacing=0 border=0 align='center'>";
1831// echo "<tr valign='top'><td>";
1832
1833 startPortlet ('Address assignment');
1834 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
1835 echo "<tr><th>Object name</th><th>Interface name</th><th>Interface type</th></tr>\n";
1836
1837 $numshared = countRefsOfType($address['bonds'], 'shared', 'eq');
1838 $numreg = countRefsOfType($address['bonds'], 'regular', 'eq');
1839 $numvirt = countRefsOfType($address['bonds'], 'virtual', 'eq');
1840
1841
1842 if ( ($numshared > 0 && $numreg > 0) || $numreg > 1 )
1843 $class='trwarning';
1844 elseif ( $address['reserved'] == 'yes' and $numshared+$numreg+$numvirt > 0)
1845 $class='trwarning';
1846 else
1847 $class='';
1848
1849
1850
1851 if ($address['reserved'] == 'yes')
1852 echo "<tr class='$class'><td colspan='3'><b>RESERVED</b></td></tr>";
1853 foreach ($address['bonds'] as $bond)
1854 {
1855 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>";
1856 switch ($bond['type'])
1857 {
1858 case 'virtual':
1859 echo "Virtual";
1860 break;
1861 case 'shared':
1862 echo "Shared";
1863 break;
1864 case 'regular':
1865 echo "Regular";
1866 break;
1867 }
1868 echo "</b></td></tr>\n";
1869 }
1870 echo "</table><br><br>";
1871 finishPortlet();
1872
1873// echo "</td><td>";
1874// echo "</td></tr></table>";
1875}
1876
1877function renderIPAddressProperties ()
1878{
1879 global $pageno, $tabno;
1880 $ip = $_REQUEST['ip'];
1881 showMessageOrError();
1882 $address = getIPAddress($ip);
1883 echo "<center><h1>$ip</h1></center>\n";
1884 echo "<table border=0 cellpadding=10 cellpadding=1 align='center'>\n";
1885 echo "<form action='process.php'><input type=hidden name=op value=editAddress>";
1886 echo "<input type=hidden name=page value='${pageno}'>\n";
1887 echo "<input type=hidden name=tab value='${tabno}'>\n";
1888 echo "<input type=hidden name=ip value='${ip}'>";
1889 echo "<tr><td class='tdright'>Name:</td><td class='tdleft'><input type=text name=name size=20 value='".($address['exists']==1?$address['name']:'')."'></tr>";
1890 echo "<td class='tdright'>Reserved:</td><td class='tdleft'><input type=checkbox name=reserved size=20 ".($address['exists']==1?(($address['reserved']=='yes')?'checked':''):'')."></tr>";
1891 echo "<tr><td colspan=2 class='tdcenter'><input type=submit value='Update address'></td></form></tr>";
1892 echo "</table>\n";
1893
1894}
1895
1896function renderIPAddressAssignment ()
1897{
1898 global $pageno, $tabno, $root;
1899 $ip = $_REQUEST['ip'];
1900 $address = getIPAddress($ip);
1901
1902 showMessageOrError();
1903 echo "<center><h1>$ip</h1></center>\n";
1904
1905
1906 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
1907 echo "<tr><th>&nbsp;</th><th>Object name</th><th>Interface name</th><th>Interface type</th><th>&nbsp;</th></tr>\n";
1908
1909 $numshared = countRefsOfType($address['bonds'], 'shared', 'eq');
1910 $numreg = countRefsOfType($address['bonds'], 'regular', 'eq');
1911 $numvirt = countRefsOfType($address['bonds'], 'virtual', 'eq');
1912
1913
1914 if ( ($numshared > 0 && $numreg > 0) || $numreg > 1 )
1915 $class='trwarning';
1916 elseif ( $address['reserved'] == 'yes' and $numshared+$numreg+$numvirt > 0)
1917 $class='trwarning';
1918 else
1919 $class='';
1920
1921
1922
1923 if ($address['reserved'] == 'yes')
1924 echo "<tr class='$class'><td colspan='5'><b>RESERVED</b></td></tr>";
1925 foreach ($address['bonds'] as $bond)
1926 {
1927 echo "<tr class='$class'><form action='process.php'>";
1928 echo "<input type=hidden name=op value='editBondForAddress'>";
1929 echo "<input type=hidden name=page value='${pageno}'>";
1930 echo "<input type=hidden name=tab value='${tabno}'>";
1931 echo "<input type=hidden name=ip value='$ip'>";
1932 echo "<input type=hidden name=object_id value='${bond['object_id']}'>";
1933 echo "<td><a href='process.php?op=delIpAssignment&page=${pageno}&tab=${tabno}&ip=$ip&object_id=${bond['object_id']}'>";
1934 printImageHREF ('delete', 'Unallocate address');
1935 echo "</a></td>";
1936 echo "<td><a href='${root}?page=object&object_id=${bond['object_id']}'>${bond['object_name']}</td>";
1937 echo "<td><input type='text' name='bond_name' value='${bond['name']}' size=10></td>";
1938 echo "<td><select name='bond_type'>";
1939 switch ($bond['type'])
1940 {
1941 case 'virtual':
1942 echo "<option value='regular'>Regular</option>";
1943 echo "<option value='virtual' selected>Virtual</option>";
1944 echo "<option value='shared'>Shared</option>";
1945 break;
1946 case 'shared':
1947 echo "<option value='regular'>Regular</option>";
1948 echo "<option value='virtual'>Virtual</option>";
1949 echo "<option value='shared' selected>Shared</option>";
1950 break;
1951 case 'regular':
1952 echo "<option value='regular' selected>Regular</option>";
1953 echo "<option value='virtual'>Virtual</option>";
1954 echo "<option value='shared'>Shared</option>";
1955 break;
1956 }
1957 echo "</select></td><td><input type='submit' value='OK'></td></form></tr>\n";
1958 }
1959 echo "<form action='process.php'><input type='hidden' name='op' value='bindObjectToIp'>";
1960 echo "<input type=hidden name=page value='${pageno}'>\n";
1961 echo "<input type=hidden name=tab value='${tabno}'>\n";
1962 echo "<input type='hidden' name='ip' value='$ip'>";
1963 echo "<td colspan=2><select name='object_id'>";
1964
1965 foreach (array(1, 4, 7, 8, 12, 14) as $type)
1966 {
1967 //get all Balck Boxes, Servers, Routers, Switches, UPS, Modems
1968 $objects = getObjectList($type);
1969 foreach ($objects as $object)
1970 echo "<option value='${object['id']}'>${object['dname']}</option>";
1971 }
1972
1973 echo "</select></td><td><input type='text' name='bond_name' value='' size=10></td>";
1974 echo "<td><select name='bond_type'><option value='regular'>Regular</option><option value='virtual'>Virtual</option><option value='shared'>Shared</option></select></td>";
1975 echo "<td><input type='submit' value='Assign address'></td></form></tr>";
1976 echo "</table><br><br>";
1977
1978}
1979
1980function renderIPAddressPortForwarding ($object_id=0)
1981{
1982 global $pageno, $tabno, $root;
1983
1984 $info = getObjectInfo ($object_id);
1985 $forwards = getObjectForwards ($object_id);
1986 $addresses = getObjectAddresses ($object_id);
1987 showMessageOrError();
f28fbe8b 1988 echo "<center><h2>locally performed NAT</h2></center>";
e673ee24
DO
1989
1990 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
f28fbe8b 1991 echo "<tr><th></th><th>Match endpoint</th><th>Translate to</th><th>Target object</th><th>Comment</th></tr>\n";
e673ee24
DO
1992
1993 foreach ($forwards['out'] as $pf)
1994 {
1995 $class='trwarning';
1996 $name='';
1997 foreach ($addresses as $addr)
1998 if ($addr['ip'] == $pf['localip'])
1999 {
2000 $class='';
2001 $name = $addr['name'];
2002 break;
2003 }
2004
2005 echo "<tr class='$class'>";
2006 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
2007 echo "<td>${pf['proto']}/${name}: <a href='${root}?page=ipaddress&tab=default&ip=${pf['localip']}'>${pf['localip']}</a>:${pf['localport']}";
2008 if (!empty ($pf['local_addr_name']))
2009 echo ' (' . $pf['local_addr_name'] . ')';
2010 echo "</td>";
e673ee24
DO
2011 echo "<td><a href='${root}?page=ipaddress&tab=default&ip=${pf['remoteip']}'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
2012
2013 $address=getIPAddress($pf['remoteip']);
2014
2015 echo "<td class='description'>";
f28fbe8b
DO
2016 if (count ($address['bonds']))
2017 foreach($address['bonds'] as $bond)
2018 echo "<a href='${root}?page=object&tab=default&object_id=${bond['object_id']}'>${bond['object_name']}(${bond['name']})</a> ";
2019 elseif (!empty ($pf['remote_addr_name']))
2020 echo '(' . $pf['remote_addr_name'] . ')';
e673ee24
DO
2021 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>";
2022 echo "</tr>";
2023 }
2024 echo "<form action='process.php'><input type='hidden' name='op' value='forwardPorts'>";
2025 echo "<input type='hidden' name='object_id' value='$object_id'>";
2026 echo "<input type=hidden name=page value='${pageno}'>\n";
2027 echo "<input type=hidden name=tab value='${tabno}'>\n";
436605a7
DO
2028 echo "<tr align='center'><td colspan=2>";
2029 printSelect (readChapter ('Protocols'), 'proto');
2030 echo "<select name='localip'>";
e673ee24
DO
2031
2032 foreach ($addresses as $addr)
09992c16
DO
2033 echo "<option value='${addr['ip']}'>" . (empty ($addr['name']) ? '' : "${addr['name']}: ") .
2034 "${addr['ip']}" . (empty ($addr['address_name']) ? '' : " (${addr['address_name']})") . "</option>";
e673ee24
DO
2035
2036 echo "</select>:<input type='text' name='localport' size='4'></td><td><input type='text' name='remoteip' id='remoteip' size='10'>";
2037 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>";
2038 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>";
2039 echo "</form>";
2040
2041 echo "</table><br><br>";
2042
2043
f28fbe8b 2044 echo "<center><h2>arriving NAT connections</h2></center>";
e673ee24
DO
2045 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
2046 echo "<tr><th></th><th>Source</th><th>Source objects</th><th>Target</th><th>Description</th></tr>\n";
2047
2048 foreach ($forwards['in'] as $pf)
2049 {
2050 echo "<tr>";
2051
2052 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>";
2053 echo "<td>${pf['proto']}/<a href='${root}?page=ipaddress&tab=default&ip=${pf['localip']}'>${pf['localip']}</a>:${pf['localport']}</td>";
2054 echo "<td class='description'><a href='${root}?page=object&tab=default&object_id=${pf['object_id']}'>${pf['object_name']}</a>";
2055 echo "</td><td><a href='${root}?page=ipaddress&tab=default&ip=${pf['remoteip']}'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
2056 echo "<td class='description'>${pf['description']}</td></tr>";
2057 }
2058
2059// echo "<form action='process.php'><input type='hidden' name='op' value='forwardPorts'>";
2060// echo "<input type='hidden' name='object_id' value='$object_id'>";
2061// echo "<input type=hidden name=page value='${pageno}'>\n";
2062// echo "<input type=hidden name=tab value='${tabno}'>\n";
2063// 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'>";
2064// foreach ($addresses as $addr)
2065// echo "<option value='${addr['ip']}'>${addr['ip']}</option>";
2066//
2067// 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>";
2068// echo "</form>";
2069 echo "</table><br><br>";
2070
2071
2072}
2073
2074
2075function renderAddMultipleObjectsForm ()
2076{
2077 global $pageno, $tabno, $nextorder;
2078
2079 $type_id = array();
7f791d1d 2080 $global_type_id = 0;
e673ee24
DO
2081 $name = array();
2082 $asset_no = array();
2083 $keepvalues = FALSE;
7f791d1d 2084 $log = array();
e673ee24 2085 // Look for current submit.
7f791d1d 2086 if (isset ($_REQUEST['got_fast_data']))
e673ee24
DO
2087 {
2088 $keepvalues = TRUE;
9c0b0016
DO
2089 $max = getConfigVar ('MASSCOUNT');
2090 for ($i = 0; $i < $max; $i++)
e673ee24
DO
2091 {
2092 if (!isset ($_REQUEST["${i}_object_type_id"]))
2093 {
2094 $log[] = array ('code' => 'error', 'message' => "Submitted form is invalid at line " . $i + 1);
2095 break;
2096 }
2097 assertUIntArg ("${i}_object_type_id", TRUE);
2098 assertStringArg ("${i}_object_name", TRUE);
2099 assertStringArg ("${i}_object_label", TRUE);
2100 assertStringArg ("${i}_object_asset_no", TRUE);
2101 assertStringArg ("${i}_object_barcode", TRUE);
2102 $type_id[$i] = $_REQUEST["${i}_object_type_id"];
2103 // Save user input for possible rendering.
2104 $name[$i] = $_REQUEST["${i}_object_name"];
2105 $label[$i] = $_REQUEST["${i}_object_label"];
2106 $asset_no[$i] = $_REQUEST["${i}_object_asset_no"];
2107 $barcode[$i] = $_REQUEST["${i}_object_barcode"];
2108
2109 // It's better to skip silently than printing a notice.
2110 if ($type_id[$i] == 0)
2111 continue;
2112 if (commitAddObject ($name[$i], $label[$i], $barcode[$i], $type_id[$i], $asset_no[$i]) === TRUE)
2113 $log[] = array ('code' => 'success', 'message' => "Added new object '${name[$i]}'");
2114 else
2115 $log[] = array ('code' => 'error', 'message' => 'commitAddObject() failed in renderAddMultipleObjectsForm()');
2116 }
e673ee24 2117 }
7f791d1d
DO
2118 elseif (isset ($_REQUEST['got_very_fast_data']))
2119 {
2120 $keepvalues = TRUE;
2121 assertUIntArg ('global_type_id', TRUE);
2122 assertStringArg ('namelist', TRUE);
2123 $global_type_id = $_REQUEST['global_type_id'];
2124 if ($global_type_id == 0)
2125 {
2126 if (!empty ($_REQUEST['namelist']))
2127 $log[] = array ('code' => 'error', 'message' => 'Object type is not selected, check the form below');
2128 else
2129 $log[] = array ('code' => 'error', 'message' => 'Empty form has been ignored. Cheers.');
2130 }
2131 else
2132 {
2133 // The name extractor below was stolen from ophandlers.php:addMultiPorts()
2134 $names1 = explode ('\n', $_REQUEST['namelist']);
2135 $names2 = array();
2136 foreach ($names1 as $line)
2137 {
2138 $parts = explode ('\r', $line);
2139 reset ($parts);
2140 if (empty ($parts[0]))
2141 continue;
2142 else
2143 $names2[] = rtrim ($parts[0]);
2144 }
2145 foreach ($names2 as $cname)
2146 if (commitAddObject ($cname, '', '', $global_type_id, '') === TRUE)
2147 $log[] = array ('code' => 'success', 'message' => "Added new object '${cname}'");
2148 else
2149 $log[] = array ('code' => 'error', 'message' => "Could not add '${cname}'");
2150 }
2151 }
2152 printLog ($log);
e673ee24
DO
2153
2154 // Render a form for the next.
2155 $typelist = getObjectTypeList();
4c330a14 2156 $typelist[0] = 'select type...';
7f791d1d
DO
2157
2158 startPortlet ('Fast way');
e673ee24
DO
2159 echo '<form>';
2160 echo "<input type=hidden name=page value=${pageno}>";
2161 echo "<input type=hidden name=tab value=${tabno}>";
2162 echo '<table border=0 align=center>';
2163 echo "<tr><th>Object type</th><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>Barcode</th></tr>\n";
7f791d1d 2164 // If a user forgot to select object type on input, we keep his
e673ee24 2165 // previous input in the form.
9c0b0016
DO
2166 $max = getConfigVar ('MASSCOUNT');
2167 for ($i = 0; $i < $max; $i++)
e673ee24 2168 {
7f791d1d 2169 echo '<tr><td>';
e673ee24
DO
2170 printSelect ($typelist, "${i}_object_type_id", 0);
2171 echo '</td>';
2172 echo "<td><input type=text size=30 name=${i}_object_name";
2173 if ($keepvalues and $type_id[$i] == 0)
2174 echo " value='${name[$i]}'";
2175 echo "></td>";
2176 echo "<td><input type=text size=30 name=${i}_object_label";
2177 if ($keepvalues and $type_id[$i] == 0)
2178 echo " value='${label[$i]}'";
2179 echo "></td>";
2180 echo "<td><input type=text size=20 name=${i}_object_asset_no";
2181 if ($keepvalues and $type_id[$i] == 0)
2182 echo " value='${asset_no[$i]}'";
2183 echo "></td>";
2184 echo "<td><input type=text size=10 name=${i}_object_barcode";
2185 if ($keepvalues and $type_id[$i] == 0)
2186 echo " value='${barcode[$i]}'";
2187 echo "></td>";
2188 echo "</tr>\n";
e673ee24 2189 }
7f791d1d 2190 echo "<tr><td class=submit colspan=5><input type=submit name=got_fast_data value='Create'></td></tr>\n";
e673ee24
DO
2191 echo "</form></table>\n";
2192 finishPortlet();
7f791d1d
DO
2193
2194 startPortlet ('Very fast way');
2195 echo '<form>';
2196 echo "<input type=hidden name=page value=${pageno}>";
2197 echo "<input type=hidden name=tab value=${tabno}>";
2198 echo 'For each line shown below create an object of type ';
2199 printSelect ($typelist, "global_type_id", 0);
2200 echo " <input type=submit name=got_very_fast_data value='Go!'><br>\n";
2201 echo "<textarea name=namelist cols=40 rows=25>\n";
2202 if ($keepvalues and $global_type_id == 0)
2203 echo $_REQUEST['namelist'];
2204 echo "</textarea></form>\n";
2205 finishPortlet();
e673ee24
DO
2206}
2207
2208function printGreeting ()
2209{
59cd003e 2210 global $remote_username, $accounts, $root;
e673ee24 2211 $account = $accounts[$remote_username];
4eb5efb7 2212 echo "Hello, ${account['user_realname']}. This is RackTables " . CODE_VERSION . ". Click <a href='${root}?logout'>here</a> to logout.";
e673ee24
DO
2213}
2214
2215function renderSearchResults ()
2216{
2217 global $remote_username, $root;
2218 $terms = trim ($_REQUEST['q']);
2219 if (empty ($terms))
2220 {
591ff2c4 2221 showError ('Search string cannot be empty.', __FUNCTION__);
e673ee24
DO
2222 return;
2223 }
2224 if (!authorized ($remote_username, 'object', 'default'))
2225 {
591ff2c4 2226 showError ('You are not authorized for viewing information about objects.', __FUNCTION__);
e673ee24
DO
2227 return;
2228 }
2229 // If we search for L2 address, we can either find one or find none.
2230 if
2231 (
2232 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
2233 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
2234 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)
2235 )
2236 // Search for L2 address.
2237 {
2238 $result = searchByl2address ($terms);
2239 if ($result !== NULL)
2240 {
2241 echo "<script language='Javascript'>document.location='${root}?page=object";
2242 echo "&hl_port_id=${result['port_id']}";
2243 echo "&object_id=${result['object_id']}';//</script>";
2244 }
2245 else
2246 echo "L2 address '${terms}' not found!";
2247 }
2248 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))
2249 // STP bridge ID: bridge priotity + port MAC address. Cut off first 4 chars and look for MAC address.
2250 {
2251 $terms = substr ($terms, 4);
2252 $result = searchByl2address ($terms);
2253 if ($result !== NULL)
2254 {
2255 echo "<script language='Javascript'>document.location='${root}?page=object";
2256 echo "&hl_port_id=${result['port_id']}";
2257 echo "&object_id=${result['object_id']}';//</script>";
2258 }
2259 else
2260 echo "L2 address '${terms}' not found!";
2261 }
2262 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))
2263 // Search for IP address.
2264 {
2265 $result = getRangeByIp ($terms);
2266 if ($result !== NULL)
2267 {
2268 echo "<script language='Javascript'>document.location='${root}?page=ipaddress";
2269 echo "&ip=${terms}";
2270 echo "';//</script>";
2271 }
2272 else
2273 echo "IP address '${terms}' not found!";
2274 return;
2275 }
2276 else
2277 // Search for objects.
2278 {
2279 $objects = getSearchResults ($terms);
2280 if (count ($objects) == 1)
2281 {
2282 $obj = current ($objects);
2283 echo "<script language='Javascript'>document.location='${root}?page=object&object_id=${obj['id']}';//</script>";
2284 }
2285 elseif (count ($objects) > 1)
2286 {
2287 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
2288 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>barcode</th></tr>';
2289 $order = 'odd';
2290 global $nextorder;
2291 foreach ($objects as $obj)
2292 {
2293 echo "<tr class=row_${order}><td><a href=\"${root}?page=object&object_id=${obj['id']}\">${obj['dname']}</a></td>";
2294 echo "<td>${obj['label']}</td>";
2295 echo "<td>${obj['asset_no']}</td>";
2296 echo "<td>${obj['barcode']}</td></tr>";
2297 $order = $nextorder[$order];
2298 }
2299 echo '</table>';
2300 }
2301 else
2302 echo "Object '${terms}' not found!";
2303 }
2304}
2305
2306// This function prints a table of checkboxes to aid the user in toggling mount atoms
2307// from one state to another. The first argument is rack data as
2308// produced by getRackData(), the second is the value used for the 'unckecked' state
2309// and the third is the value used for 'checked' state.
2310// Usage contexts:
2311// for mounting an object: printAtomGrid ($data, 'F', 'T')
2312// for changing rack design: printAtomGrid ($data, 'A', 'F')
2313// for adding rack problem: printAtomGrid ($data, 'F', 'U')
2314// for adding object problem: printAtomGrid ($data, 'T', 'W')
2315
2316function renderAtomGrid ($data)
2317{
2318 $rack_id = $data['id'];
2319 for ($unit_no = $data['height']; $unit_no > 0; $unit_no--)
2320 {
2321 echo "<tr><th>${unit_no}</th>";
2322 for ($locidx = 0; $locidx < 3; $locidx++)
2323 {
2324 $state = $data[$unit_no][$locidx]['state'];
2325 echo "<td class=state_${state}";
2326 if (isset ($data[$unit_no][$locidx]['hl']))
2327 echo $data[$unit_no][$locidx]['hl'];
2328 echo ">";
2329 if (!($data[$unit_no][$locidx]['enabled'] === TRUE))
2330 echo '<input type=checkbox disabled>';
2331 else
2332 echo "<input type=checkbox" . $data[$unit_no][$locidx]['checked'] . " name=atom_${rack_id}_${unit_no}_${locidx}>";
2333 echo '</td>';
2334 }
2335 echo "</tr>\n";
2336 }
2337}
2338
2339function renderPermissions ()
2340{
2341 startPortlet ('User permissions');
2342 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
2343 echo "<tr><th>Username</th><th>Page</th><th>Tab</th><th>Access</th></tr>";
2344 global $perms, $nextorder;
2345 $order = 'odd';
2346 foreach ($perms as $username => $pages)
2347 foreach ($pages as $page => $tabs)
2348 foreach ($tabs as $tab => $access)
2349 {
2350 echo "<tr class=row_${order}><td class=tdleft>$username</td><td>$page</td><td>$tab</td><td>$access</td></tr>\n";
2351 $order = $nextorder[$order];
2352 }
2353 echo "</table>\n";
2354 finishPortlet();
2355}
2356
2357function renderAccounts ()
2358{
2359 global $nextorder, $accounts;
2360 startPortlet ('User accounts');
2361 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
2362 echo "<tr><th class=tdleft>Username</th><th class=tdleft>Real name</th></tr>";
2363 $order = 'odd';
2364 foreach ($accounts as $user)
2365 {
2366 echo "<tr class=row_${order}><td class=tdleft>${user['user_name']}</td><td class=tdleft>${user['user_realname']}</td></li>";
2367 $order = $nextorder[$order];
2368 }
2369 echo '</table>';
2370 finishPortlet();
2371}
2372
2373function renderAccountsEditForm ()
2374{
2375 global $root, $pageno, $tabno, $accounts;
2376 startPortlet ('User accounts');
2377 showMessageOrError();
2378 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
2379 echo "<tr><th>op</th><th>Username</th><th>Real name</th><th>Password</th><th>&nbsp;</th></tr>\n";
2380 foreach ($accounts as $account)
2381 {
2382 echo "<form action='${root}process.php'>";
2383 echo "<input type=hidden name=op value=updateAccount>";
2384 echo "<input type=hidden name=page value='${pageno}'>\n";
2385 echo "<input type=hidden name=tab value='${tabno}'>\n";
2386 echo "<input type=hidden name=id value='${account['user_id']}'><tr>";
2387 echo "<td>";
2388 if ($account['user_enabled'] == 'yes' && $account['user_id'] != 1)
2389 {
2390 echo "<a href='${root}process.php?op=disableAccount&page=${pageno}&tab=${tabno}&id=${account['user_id']}'>";
2391 printImageHREF ('blockuser', 'disable account');
2392 echo "</a>\n";
2393 }
2394 if ($account['user_enabled'] == 'no' && $account['user_id'] != 1)
2395 {
2396 echo "<a href='${root}process.php?op=enableAccount&page=${pageno}&tab=${tabno}&id=${account['user_id']}'>";
2397 printImageHREF ('unblockuser', 'enable account');
2398 echo "</a>\n";
2399 }
2400 // Otherwise skip icon.
2401 echo "</td>";
2402 echo "<td><input type=text name=username value='${account['user_name']}' size=16></td>";
2403 echo "<td><input type=text name=realname value='${account['user_realname']}' size=24></td>";
2404 echo "<td><input type=password name=password value='${account['user_password_hash']}' size=64></td>";
2405 echo "<td><input type='submit' value='OK'></td>";
2406 echo "</form></tr>\n";
2407 }
2408 echo "<form action='${root}process.php' method=post><tr>";
2409 echo "<input type=hidden name=op value=createAccount>\n";
2410 echo "<input type=hidden name=page value='${pageno}'>\n";
2411 echo "<input type=hidden name=tab value='${tabno}'>\n";
2412 echo "<td colspan=2><input type=text size=16 name=username tabindex=100></td>\n";
2413 echo "<td><input type=text size=24 name=realname tabindex=101></td>";
2414 echo "<td><input type=password size=64 name=password tabindex=102></td>";
2415 echo "<td colspan=4><input type=submit value='Create account' tabindex=103></td></tr></form>";
2416 echo "</table><br>\n";
2417 finishPortlet();
2418}
2419
2420function printChildrenAsOptions ($root, $depth = 0)
2421{
2422 echo "<option value=${root['title']}>";
2423 if ($depth == 0)
2424 echo '* ';
2425 for ($i = 0; $i < $depth; $i++)
2426 echo '-- ';
2427 echo $root['title'];
2428 echo "</option>\n";
2429 foreach ($root['kids'] as $kid)
2430 printChildrenAsOptions ($kid, $depth + 1);
2431}
2432
2433// 1. Find all parentless pages.
2434// 2. For each of them recursively find all children.
2435// 3. Output the tree with recursion tree display.
2436function printPagesTree ()
2437{
2438 global $page;
2439 echo '<pre>';
2440 foreach ($page as $ctitle => $cpage)
2441 if (!isset ($cpage['parent']))
2442 {
2443 $croot['title'] = $ctitle;
2444 $croot['kids'] = getAllChildPages ($ctitle);
2445 printChildrenAsOptions ($croot);
2446 }
2447 echo '</pre>';
2448}
2449
2450function renderPermissionsEditForm ()
2451{
2452 global $root, $pageno, $tabno, $perms, $accounts;
2453 startPortlet ('User permissions');
2454 showMessageOrError();
2455 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
2456 echo "<tr><th>&nbsp;</th><th>Username</th><th>Page</th><th>Tab</th><th>Access</th></tr>\n";
2457 foreach ($perms as $username => $pages)
2458 foreach ($pages as $access_page => $tabs)
2459 foreach ($tabs as $access_tab => $access)
2460 {
2461 echo "<td>";
2462 if ($username != '%')
2463 $userid = $accounts[$username]['user_id'];
2464 else
2465 $userid = 0;
2466 echo "<a href='${root}process.php?op=revoke&page=${pageno}&tab=${tabno}&access_userid=${userid}&access_page=${access_page}&access_tab=${access_tab}'>";
2467 printImageHREF ('revoke', 'Revoke permission');
2468 echo "</a></td>";
2469 echo "<td>${username}</td>";
2470 echo "<td>${access_page}</td>";
2471 echo "<td>${access_tab}</td>";
2472 echo "<td>${access}</td>";
2473 echo "</tr>\n";
2474 }
2475 echo "<form action='${root}process.php' method=post><tr>";
2476 echo "<input type=hidden name=op value=grant>\n";
2477 echo "<input type=hidden name=page value='${pageno}'>\n";
2478 echo "<input type=hidden name=tab value='${tabno}'>\n";
2479 // FIXME: border=0 doesn't work here for unknown reason
2480 echo "<td>";
a5ae8c2a 2481 printImageHREF ('grant', '', TRUE, 103);
e673ee24
DO
2482 echo "</td>";
2483 echo "<td><select name=access_userid>";
2484 echo "<option value=0>ANY</option>";
2485 foreach ($accounts as $account)
2486 echo "<option value=${account['user_id']}>${account['user_name']}</option>";
2487 echo "</select></td>\n";
2488 echo "<td><select name=access_page>";
2489 echo "<option value='%'>ANY</option>";
2490 printPagesTree();
2491 echo "</select></td>";
2492 echo "<td><input type=text size=16 name=access_tab tabindex=102 value=default></td>";
2493 echo "<td><input type=radio name=access_value value=no checked>no <input type=radio name=access_value value=yes>yes</td>";
2494 echo "</tr></form>";
2495 echo "</table><br>\n";
2496 finishPortlet();
2497}
2498
e673ee24
DO
2499function renderPortMap ($editable = FALSE)
2500{
2501 global $nextorder, $root, $pageno, $tabno;
2502 showMessageOrError();
2503 startPortlet ("Port compatibility map");
2504 $ptlist = getPortTypes();
2505 $pclist = getPortCompat();
2506 $pctable = buildPortCompatMatrixFromList ($ptlist, $pclist);
2507 if ($editable)
2508 {
2509 echo "<form method=post action='${root}process.php'>";
2510 echo "<input type=hidden name=page value='${pageno}'>";
2511 echo "<input type=hidden name=tab value='${tabno}'>";
2512 echo "<input type=hidden name=op value=save>";
2513 }
2514 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
2515 echo "<tr><th class=vert_th>&nbsp;</th>";
2516 foreach ($ptlist as $name2)
2517 echo "<th>to ${name2}</th>";
2518 echo "</tr>";
2519 // Make a copy to have an independent array pointer.
2520 $ptlistY = $ptlist;
2521 $order = 'odd';
2522 foreach ($ptlistY as $type1 => $name1)
2523 {
2524 echo "<tr class=row_${order}><th class=vert_th style='border-bottom: 0px;'>from $name1</th>";
2525 foreach ($ptlist as $type2 => $name2)
2526 {
2527 echo '<td><input type=checkbox' . ($editable ? " name=atom_${type1}_${type2}" : ' disabled');
2528 echo ($pctable[$type1][$type2] ? ' checked' : '') . '></td>';
2529 }
2530 echo "</tr>\n";
2531 $order = $nextorder[$order];
2532 }
2533 echo '</table><br>';
2534 if ($editable)
2535 {
2536 echo "<input type=submit value='Save changes'>";
2537 echo "</form>";
2538 }
2539 finishPortlet();
2540}
2541
2542function renderConfigMainpage ()
2543{
2544 global $pageno, $root;
2545 $children = getDirectChildPages ($pageno);
2546 echo '<ul>';
2547 foreach ($children as $cpageno => $child)
2548 {
2549 $ctitle = $child['title']($cpageno);
2550 echo "<li><a href='${root}?page=${cpageno}'>" . $ctitle['name'] . "</li>\n";
2551 }
2552 echo '';
2553 echo '</ul>';
2554}
2555
2556function renderRackPage ($rack_id)
2557{
2558 if ($rack_id == 0)
2559 {
591ff2c4 2560 showError ('Invalid rack_id', __FUNCTION__);
e673ee24
DO
2561 return;
2562 }
2563 if (($rackData = getRackData ($rack_id)) == NULL)
2564 {
591ff2c4 2565 showError ('getRackData() failed', __FUNCTION__);
e673ee24
DO
2566 return;
2567 }
2568 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0><tr>";
2569
2570 // Left column with information.
2571 echo "<td class=pcleft>";
2572 startPortlet ('Rack information');
2573 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
2574 echo "<tr><th width='50%' class=tdright>Rack row:</th><td class=tdleft>${rackData['row_name']}</td></tr>\n";
2575 echo "<tr><th width='50%' class=tdright>Name:</th><td class=tdleft>${rackData['name']}</td></tr>\n";
2576 echo "<tr><th width='50%' class=tdright>Height:</th><td class=tdleft>${rackData['height']}</td></tr>\n";
8a1b387d
DO
2577 echo "<tr><th width='50%' class=tdright>Utilization:</th><td class=tdleft>";
2578 renderProgressBar (getRSUforRack ($rack_id));
2579 echo "</td></tr>\n";
e673ee24
DO
2580 if (!empty ($rackData['comment']))
2581 echo "<tr><th width='50%' class=tdright>Comment:</th><td class=tdleft>${rackData['comment']}</td></tr>\n";
2582 echo '</table>';
2583 finishPortlet();
2584 echo '</td>';
2585
2586 // Right column with rendered rack.
2587 echo '<td>';
2588 startPortlet ('Rack diagram');
2589 renderRack ($rack_id);
2590 finishPortlet();
2591 echo '</td>';
2592
2593 echo '</tr></table>';
2594}
2595
2596function renderDictionary ()
2597{
2598 global $nextorder;
2599 $dict = getDict();
2600 echo "<table border=0><tr>";
2601 foreach ($dict as $chapter)
2602 {
2603 echo "<td class=pcleft>";
2604 startPortlet ($chapter['name'] . ' (' . count ($chapter['word']) . ')');
2605 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
2606 $order = 'odd';
cfadde04 2607 foreach ($chapter['word'] as $key => $value)
e673ee24 2608 {
cfadde04 2609 echo "<tr class=row_${order}><td class=tdleft><div title='key=${key}'>${value}</div></td></tr>";
e673ee24
DO
2610 $order = $nextorder[$order];
2611 }
2612 echo "</table>";
2613 finishPortlet();
2614 echo "</td>";
2615 }
2616 echo "</tr></table>";
2617}
2618
2619function renderDictionaryEditor ()
2620{
2621 global $root, $pageno, $tabno;
2622 showMessageOrError();
2623 $dict = getDict();
2624 echo "<table border=0><tr>";
2625 foreach ($dict as $chapter)
2626 {
2627 echo "<td class=pcleft>";
2628 startPortlet ($chapter['name'] . ' (' . count ($chapter['word']) . ')');
2629 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
2630 foreach ($chapter['word'] as $key => $value)
2631 {
2632 echo "<form action='${root}process.php' method=post>";
2633 echo "<input type=hidden name=page value='${pageno}'>";
2634 echo "<input type=hidden name=tab value='${tabno}'>";
2635 echo "<input type=hidden name=op value='upd'>";
2636 echo "<input type=hidden name=chapter_no value='${chapter['no']}'>";
2637 echo "<input type=hidden name=dict_key value='${key}'>";
2638 echo '<tr>';
2639 echo "<td><a href='${root}process.php?page=${pageno}&tab=${tabno}&op=del&chapter_no=${chapter['no']}&dict_key=${key}'>";
2640 printImageHREF ('delete', 'Delete word');
2641 echo "</a></td>";
2642 echo "<td class=tdright><input type=text name=dict_value size=32 value='${value}'></td>";
2643 echo "<td><input type=submit value=OK></td>";
2644 echo '</tr></form>';
2645 }
2646 echo "<form action='${root}process.php' method=post>";
2647 echo "<input type=hidden name=page value='${pageno}'>";
2648 echo "<input type=hidden name=tab value='${tabno}'>";
2649 echo "<input type=hidden name=op value=add>";
2650 echo "<input type=hidden name=chapter_no value='${chapter['no']}'>";
2651 echo '<tr>';
2652 echo "<td>&nbsp;</td>";
2653 echo "<td class=tdright><input type=text name=dict_value size=32></td>";
2654 echo "<td><input type=submit value=OK></td>";
2655 echo '</tr></form>';
2656 echo "</table>";
2657 finishPortlet();
2658 echo "</td>";
2659 }
2660 echo "</tr></table>";
2661}
2662
2663// We don't allow to rename/delete a sticky chapter and we don't allow
2664// to delete a non-empty chapter.
2665function renderChaptersEditor ()
2666{
2667 global $root, $pageno, $tabno;
2668 showMessageOrError();
2669 $dict = getDict();
2670 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
2671 echo '<tr><th>&nbsp;</th><th>Chapter name</th><th>Words</th><th>&nbsp;</th></tr>';
2672 foreach ($dict as $chapter)
2673 {
2674 $wordcount = count ($chapter['word']);
2675 $sticky = $chapter['sticky'];
2676 echo "<form action='${root}process.php' method=post>";
2677 echo "<input type=hidden name=page value='${pageno}'>";
2678 echo "<input type=hidden name=tab value='${tabno}'>";
2679 echo "<input type=hidden name=op value=upd>";
2680 echo "<input type=hidden name=chapter_no value='${chapter['no']}'>";
2681 echo '<tr>';
2682 echo '<td>';
2683 if ($sticky or $wordcount > 0)
2684 echo '&nbsp;';
2685 else
2686 {
2687 echo "<a href='${root}process.php?page=${pageno}&tab=${tabno}&op=del&chapter_no=${chapter['no']}'>";
2688 printImageHREF ('delete', 'Remove chapter');
2689 echo "</a>";
2690 }
2691 echo '</td>';
2692 echo "<td><input type=text name=chapter_name value='${chapter['name']}'" . ($sticky ? ' disabled' : '') . "></td>";
2693 echo "<td class=tdleft>${wordcount}</td><td>";
2694 if ($sticky)
2695 echo '&nbsp;';
2696 else
2697 echo "<input type=submit value='OK'>";
2698 echo '</td></tr>';
2699 echo '</form>';
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=add>";
2705 echo '<tr><td>';
a5ae8c2a 2706 printImageHREF ('add', '', TRUE);
e673ee24
DO
2707 echo "</td><td colspan=3><input type=text name=chapter_name></td>";
2708 echo '</tr>';
2709 echo '</form>';
2710 echo "</table>\n";
2711}
2712
2713function renderAttributes ()
2714{
2715 global $nextorder;
2716 $attrMap = getAttrMap();
2717 startPortlet ('Optional attributes');
2718 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
2719 echo "<tr><th class=tdleft>Attribute name</th><th class=tdleft>Attribute type</th><th class=tdleft>Applies to</th></tr>";
2720 $order = 'odd';
2721 foreach ($attrMap as $attr)
2722 {
2723 echo "<tr class=row_${order}>";
2724 echo "<td class=tdleft>${attr['name']}</td>";
2725 echo "<td class=tdleft>${attr['type']}</td>";
2726 echo '<td class=tdleft>';
2727 if (count ($attr['application']) == 0)
2728 echo '&nbsp;';
2729 else
2730 foreach ($attr['application'] as $app)
2731 if ($attr['type'] == 'dict')
2732 echo "${app['objtype_name']} (values from '${app['chapter_name']}')<br>";
2733 else
2734 echo "${app['objtype_name']}<br>";
2735 echo '</td>';
2736 echo "</tr>\n";
2737 $order = $nextorder[$order];
2738 }
2739 echo "</table><br>\n";
2740 finishPortlet();
2741}
2742
2743function renderEditAttributesForm ()
2744{
2745 global $root, $pageno, $tabno;
2746 $attrMap = getAttrMap();
2747 showMessageOrError();
2748 startPortlet ('Optional attributes');
2749 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
2750 echo '<tr><th>&nbsp;</th><th>Name</th><th>Type</th><th>&nbsp;</th></tr>';
2751 foreach ($attrMap as $attr)
2752 {
2753 echo "<form action='${root}process.php' method=post>";
2754 echo "<input type=hidden name=page value='${pageno}'>";
2755 echo "<input type=hidden name=tab value='${tabno}'>";
2756 echo "<input type=hidden name=op value=upd>";
2757 echo "<input type=hidden name=attr_id value='${attr['id']}'>";
2758 echo '<tr>';
2759 echo "<td><a href='${root}process.php?page=${pageno}&tab=${tabno}&op=del&attr_id=${attr['id']}'>";
2760 printImageHREF ('delete', 'Remove attribute');
2761 echo '</a></td>';
2762 echo "<td><input type=text name=attr_name value='${attr['name']}'></td>";
2763 echo "<td>${attr['type']}</td>";
2764 echo "<td><input type=submit value='OK'></td>";
2765 echo '</tr>';
2766 echo '</form>';
2767 }
2768 echo "<form action='${root}process.php' method=post>";
2769 echo "<input type=hidden name=page value='${pageno}'>";
2770 echo "<input type=hidden name=tab value='${tabno}'>";
2771 echo "<input type=hidden name=op value=add>";
2772 echo '<tr><td>';
a5ae8c2a 2773 printImageHREF ('add', '', TRUE);
e673ee24
DO
2774 echo "</td><td><input type=text name=attr_name></td>";
2775 echo '<td><select name=attr_type>';
2776 echo '<option value=uint>uint</option>';
2777 echo '<option value=float>float</option>';
2778 echo '<option value=string>string</option>';
2779 echo '<option value=dict>dict</option>';
2780 echo '</select></td>';
2781 echo '</tr>';
2782 echo '</form>';
2783 echo "</table>\n";
2784 finishPortlet();
2785}
2786
2787function renderEditAttrMapForm ()
2788{
2789 global $root, $pageno, $tabno;
2790 $attrMap = getAttrMap();
2791 showMessageOrError();
2792 startPortlet ('Attribute map');
2793 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
2794 echo '<tr><th>&nbsp;</th><th>Attribute name</th><th>Object type</th><th>Dictionary chapter</th></tr>';
2795 foreach ($attrMap as $attr)
2796 {
2797 if (count ($attr['application']) == 0)
2798 continue;
2799 foreach ($attr['application'] as $app)
2800 {
2801 echo '<tr>';
2802 echo '<td>';
2803 echo "<a href='${root}process.php?page=${pageno}&tab=${tabno}&op=del&";
2804 echo "attr_id=${attr['id']}&objtype_id=${app['objtype_id']}'>";
2805 printImageHREF ('delete', 'Remove mapping');
2806 echo "</a>";
2807 echo '</td>';
2808 echo "<td>${attr['name']}</td>";
2809 echo "<td>${app['objtype_name']}</td>";
2810 echo "<td>";
2811 if ($attr['type'] == 'dict')
2812 echo "${app['chapter_name']}";
2813 else
2814 echo '&nbsp;';
2815 echo "</td></tr>\n";
2816 }
2817 }
2818 echo "<form action='${root}process.php' method=post>";
2819 echo "<input type=hidden name=page value='${pageno}'>";
2820 echo "<input type=hidden name=tab value='${tabno}'>";
2821 echo "<input type=hidden name=op value=add>";
2822 echo '<tr><td>';
a5ae8c2a 2823 printImageHREF ('add', '', TRUE);
e673ee24
DO
2824 echo "</td><td><select name=attr_id>";
2825 $shortType['uint'] = 'U';
2826 $shortType['float'] = 'F';
2827 $shortType['string'] = 'S';
2828 $shortType['dict'] = 'D';
2829 foreach ($attrMap as $attr)
2830 echo "<option value=${attr['id']}>[" . $shortType[$attr['type']] . "] ${attr['name']}</option>";
2831 echo "</select></td>";
2832 echo '<td>';
2833 printSelect (getObjectTypeList(), 'objtype_id');
2834 echo '</td>';
2835 $dict = getDict();
2836 echo '<td><select name=chapter_no>';
2837 foreach ($dict as $chapter)
2838 if (!$chapter['sticky'])
2839 echo "<option value='${chapter['no']}'>${chapter['name']}</option>";
2840 echo '</select></td>';
2841 echo '</tr>';
2842 echo '</form>';
2843 echo "</table>\n";
2844 finishPortlet();
2845}
2846
a5ae8c2a 2847function printImageHREF ($tag, $title = '', $do_input = FALSE, $tabindex = 0)
e673ee24 2848{
a5ae8c2a
DO
2849 global $root;
2850 $image['error']['path'] = 'pix/error.png';
2851 $image['error']['width'] = 76;
2852 $image['error']['height'] = 17;
a5ae8c2a
DO
2853 $image['logo']['path'] = 'pix/defaultlogo.png';
2854 $image['logo']['width'] = 210;
2855 $image['logo']['height'] = 40;
2856 $image['rackspace']['path'] = 'pix/racks.png';
2857 $image['rackspace']['width'] = 218;
2858 $image['rackspace']['height'] = 200;
2859 $image['objects']['path'] = 'pix/server.png';
2860 $image['objects']['width'] = 218;
2861 $image['objects']['height'] = 200;
2862 $image['ipv4space']['path'] = 'pix/addressspace.png';
2863 $image['ipv4space']['width'] = 218;
2864 $image['ipv4space']['height'] = 200;
2865 $image['config']['path'] = 'pix/configuration.png';
2866 $image['config']['width'] = 218;
2867 $image['config']['height'] = 200;
2868 $image['reports']['path'] = 'pix/report.png';
2869 $image['reports']['width'] = 218;
2870 $image['reports']['height'] = 200;
2871 $image['help']['path'] = 'pix/help.png';
2872 $image['help']['width'] = 218;
2873 $image['help']['height'] = 200;
2874 $image['reserve']['path'] = 'pix/stop.png';
2875 $image['reserve']['width'] = 16;
2876 $image['reserve']['height'] = 16;
2877 $image['useup']['path'] = 'pix/go.png';
2878 $image['useup']['width'] = 16;
2879 $image['useup']['height'] = 16;
2880 $image['blockuser'] = $image['reserve'];
2881 $image['unblockuser'] = $image['useup'];
2882 $image['link']['path'] = 'pix/link.png';
2883 $image['link']['width'] = 24;
2884 $image['link']['height'] = 24;
2885 $image['unlink']['path'] = 'pix/unlink.png';
2886 $image['unlink']['width'] = 24;
2887 $image['unlink']['height'] = 24;
2888 $image['add']['path'] = 'pix/greenplus.png';
2889 $image['add']['width'] = 16;
2890 $image['add']['height'] = 16;
2891 $image['delete']['path'] = 'pix/delete_s.gif';
2892 $image['delete']['width'] = 16;
2893 $image['delete']['height'] = 16;
2894 $image['grant'] = $image['add'];
2895 $image['revoke'] = $image['delete'];
2896 $image['helphint']['path'] = 'pix/helphint.png';
2897 $image['helphint']['width'] = 24;
2898 $image['helphint']['height'] = 24;
e673ee24
DO
2899 if (!isset ($image[$tag]))
2900 $tag = 'error';
2901 $img = $image[$tag];
a5ae8c2a
DO
2902 if ($do_input == TRUE)
2903 echo
2904 "<input type=image name=submit " .
2905 "src='${root}${img['path']}' " .
2906 "border=0 " .
2907 ($tabindex ? '' : "tabindex=${tabindex}") .
2908 ">";
2909 else
2910 echo
2911 "<img " .
2912 "src='${root}${img['path']}' " .
2913 "width=${img['width']} " .
2914 "height=${img['height']} " .
2915 "border=0 " .
2916 (empty ($title) ? '' : "title='${title}'") .
2917 ">";
e673ee24
DO
2918}
2919
2920// This function returns URL for favourite icon.
2921function getFaviconURL ()
2922{
46100c70
DO
2923 global $root;
2924 return $root . 'pix/racktables.ico';
e673ee24
DO
2925}
2926
2927function renderReportSummary ()
2928{
da95280e
DO
2929 echo "<table width='100%'>\n";
2930 echo "<tr><td class=pcleft>\n";
08b4cb24 2931 startPortlet ("Dictionary/objects stats");
da95280e
DO
2932 echo "<table>\n";
2933 foreach (getDictStats() as $header => $data)
2934 {
2935 echo "<tr><th>${header}:</th><td>${data}</td></tr>\n";
2936 }
2937 echo "</table>\n";
2938 finishPortlet();
2939
2940 echo "</td><td class=pcright>\n";
2941
c461c579
DO
2942 startPortlet ("Here be dragons");
2943 dragon();
2944 dragon();
2945 dragon();
2946 echo 'ASCII art &copy; Daniel C. Au';
2947 finishPortlet();
da95280e
DO
2948 echo "</td></tr>\n";
2949 echo "</table>\n";
c461c579
DO
2950}
2951
2952function dragon ()
2953{
2954?>
2955<div class=dragon><pre><font color="#00ff33">
2956 \||/
2957 | <font color="#ff0000">@</font>___oo
2958 /\ /\ / (__<font color=yellow>,,,,</font>|
2959 ) /^\) ^\/ _)
2960 ) /^\/ _)
2961 ) _ / / _)
2962 /\ )/\/ || | )_)
2963 &lt; &gt; |(<font color=white>,,</font>) )__)
2964 || / \)___)\
2965 | \____( )___) )___
2966 \______(_______<font color=white>;;;</font> __<font color=white>;;;</font>
2967
2968</font></pre></div>
2969<?php
e673ee24
DO
2970}
2971
2972function renderUIConfig ()
2973{
4fe32e78
DY
2974 global $configCache, $nextorder;
2975 showMessageOrError();
0a1b1268 2976 startPortlet ('Current configuration');
c461c579
DO
2977 echo '<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center width="50%">';
2978 echo '<tr><th class=tdleft>Option</th><th class=tdleft>Value</th></tr>';
4fe32e78 2979 $order = 'odd';
0a1b1268 2980 foreach ($configCache as $v)
4fe32e78 2981 {
c461c579
DO
2982 if ($v['is_hidden'] != 'no')
2983 continue;
2984 echo "<tr class=row_${order}>";
2985 echo "<td class=tdright>${v['description']}</td>\n";
2986 echo "<td class=tdleft>${v['varvalue']}</td></tr>";
2987 $order = $nextorder[$order];
4fe32e78 2988 }
0a1b1268
DO
2989 echo "</table>\n";
2990 finishPortlet();
7865c525
DO
2991}
2992
4fe32e78
DY
2993function renderUIConfigEditForm ()
2994{
c461c579 2995 global $root, $pageno, $tabno, $configCache;
4fe32e78
DY
2996 showMessageOrError();
2997 startPortlet ('Current configuration');
c461c579
DO
2998 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable width='50%'>\n";
2999 echo "<tr><th class=tdleft>Option</th>";
3000 echo "<th class=tdleft>Value</th></tr>";
4fe32e78
DY
3001 echo "<form action='${root}process.php'>";
3002 echo "<input type=hidden name=op value='upd'>";
c461c579
DO
3003 echo "<input type=hidden name=page value='${pageno}'>\n";
3004 echo "<input type=hidden name=tab value='${tabno}'>\n";
4fe32e78
DY
3005
3006 $i = 0;
3007 foreach ($configCache as $v)
3008 {
c461c579
DO
3009 if ($v['is_hidden'] != 'no')
3010 continue;
3011 echo "<input type=hidden name=${i}_varname value='${v['varname']}'>";
3012 echo "<tr><td class=tdright>${v['description']}</td>";
3013 echo "<td class=tdleft><input type=text name=${i}_varvalue value='${v['varvalue']}' size=24></td>";
3014 echo "</tr>\n";
3015 $i++;
4fe32e78
DY
3016 }
3017 echo "<input type=hidden name=num_vars value=${i}>\n";
c461c579 3018 echo "<tr><td colspan=2><input type=submit value='Save changes'></td></tr>";
4fe32e78
DY
3019 echo "</form>";
3020 finishPortlet();
3021}
3022
7865c525
DO
3023// This function queries the gateway about current VLAN configuration and
3024// renders a form suitable for submit. Ah, and it does submit processing as well.
111b4a67
DO
3025function renderVLANMembership ($object_id = 0)
3026{
fc8d0004 3027 global $root, $pageno, $tabno, $remote_username;
111b4a67
DO
3028 if ($object_id <= 0)
3029 {
591ff2c4 3030 showError ('Invalid object_id', __FUNCTION__);
111b4a67
DO
3031 return;
3032 }
7865c525
DO
3033
3034 // Handle probable pending submit.
3035 if (isset ($_REQUEST['portcount']))
111b4a67 3036 {
7865c525
DO
3037 $data = getSwitchVLANs ($object_id);
3038 if ($data === NULL)
2da7c9b0 3039 {
591ff2c4 3040 showError ('getSwitchVLANs() failed during submit processing', __FUNCTION__);
fc8d0004
DO
3041 return;
3042 }
7865c525
DO
3043 list ($vlanlist, $portlist) = $data;
3044 // Here we just build up 1 set command for the gateway with all of the ports
3045 // included. The gateway is expected to filter unnecessary changes silently
3046 // and to provide a list of responses with either error or success message
3047 // for each of the rest.
3048 assertUIntArg ('portcount');
3049 $nports = $_REQUEST['portcount'];
3050 $prefix = 'set ';
3051 $log = array();
3052 $setcmd = '';
3053 for ($i = 0; $i < $nports; $i++)
3054 if
3055 (
3056 !isset ($_REQUEST['portname_' . $i]) ||
3057 !isset ($_REQUEST['vlanid_' . $i]) ||
3058 $_REQUEST['portname_' . $i] != $portlist[$i]['portname']
3059 )
3060 $log[] = array ('code' => 'error', 'message' => "Ignoring mailformed record #${i} in form submit");
3061 elseif
3062 (
3063 $_REQUEST['vlanid_' . $i] == $portlist[$i]['vlanid'] ||
3064 $portlist[$i]['vlaind'] == 'TRUNK'
3065 )
3066 continue;
3067 else
3068 {
3069 $setcmd .= $prefix . $_REQUEST['portname_' . $i] . '=' . $_REQUEST['vlanid_' . $i];
3070 $prefix = ';';
3071 }
3072 printLog ($log);
3073 // Feed the gateway and interpret its (non)response.
3074 if ($setcmd != '')
3075 printLog (setSwitchVLANs ($object_id, $setcmd));
3076 }
3077
3078 // Reload and render.
3079 $data = getSwitchVLANs ($object_id);
3080 if ($data === NULL)
3081 return;
18cb9495 3082 list ($vlanlist, $portlist, $maclist) = $data;
d28ea105 3083
a684aa6f 3084 echo '<table border=0 width="100%"><tr><td colspan=3>';
d28ea105 3085
2b9e0abd 3086 startPortlet ('Current status');
18cb9495 3087 echo "<table class=widetable cellspacing=3 cellpadding=5 align=center width='100%'><tr>";
7865c525
DO
3088 echo "<form method=post>";
3089 echo "<input type=hidden name=page value='${pageno}'>";
3090 echo "<input type=hidden name=tab value='${tabno}'>";
3091 echo "<input type=hidden name=object_id value=${object_id}>";
0d591525
DO
3092 $portcount = count ($portlist);
3093 echo "<input type=hidden name=portcount value=" . $portcount . ">\n";
7865c525 3094 $portno = 0;
9c0b0016 3095 $ports_per_row = getConfigVar ('PORTS_PER_ROW');
7865c525
DO
3096 foreach ($portlist as $port)
3097 {
3098 // Don't let wide forms break our fancy pages.
9c0b0016 3099 if ($portno % $ports_per_row == 0)
fc8d0004 3100 {
7865c525
DO
3101 if ($portno > 0)
3102 echo "</tr>\n";
0d591525 3103 echo "<tr><th>" . ($portno + 1) . "-" . ($portno + $ports_per_row > $portcount ? $portcount : $portno + $ports_per_row) . "</th>";
fc8d0004 3104 }
18cb9495
DO
3105 echo '<td class=port_';
3106 if ($port['status'] == 'notconnect')
3107 echo 'notconnect';
2b9e0abd
DO
3108 elseif ($port['status'] == 'disabled')
3109 echo 'disabled';
18cb9495
DO
3110 elseif ($port['status'] != 'connected')
3111 echo 'unknown';
3112 elseif (!isset ($maclist[$port['portname']]))
3113 echo 'connected_none';
3114 else
3115 {
3116 $maccount = 0;
3117 foreach ($maclist[$port['portname']] as $vlanid => $addrs)
3118 $maccount += count ($addrs);
3119 if ($maccount == 1)
3120 echo 'connected_single';
3121 else
3122 echo 'connected_multi';
3123 }
3124 echo '>' . $port['portname'] . '<br>';
7865c525
DO
3125 echo "<input type=hidden name=portname_${portno} value=" . $port['portname'] . '>';
3126 if ($port['vlanid'] == 'trunk')
fc8d0004 3127 {
7865c525
DO
3128 echo "<input type=hidden name=vlanid_${portno} value='trunk'>";
3129 echo "<select disabled multiple='multiple' size=1><option>TRUNK</option></select>";
fc8d0004 3130 }
7865c525 3131 else
fc8d0004 3132 {
7865c525 3133 echo "<select name=vlanid_${portno}>";
8c7a0e37
DO
3134 // A port may belong to a VLAN, which is absent from the VLAN table, this is normal.
3135 // We must be able to render its SELECT properly at least.
3136 $in_table = FALSE;
d28ea105 3137 foreach ($vlanlist as $v => $d)
fc8d0004 3138 {
7865c525
DO
3139 echo "<option value=${v}";
3140 if ($v == $port['vlanid'])
8c7a0e37 3141 {
7865c525 3142 echo ' selected';
8c7a0e37
DO
3143 $in_table = TRUE;
3144 }
3145 echo ">${v}</option>\n";
fc8d0004 3146 }
8c7a0e37
DO
3147 if (!$in_table)
3148 echo "<option value=${port['vlanid']} selected>${port['vlanid']}</option>\n";
7865c525 3149 echo "</select>";
fc8d0004 3150 }
7865c525
DO
3151 $portno++;
3152 echo "</td>";
111b4a67 3153 }
9c0b0016 3154 echo "</tr><tr><td colspan=" . ($ports_per_row + 1) . "><input type=submit value='Save changes'></form></td></tr></table>";
7865c525 3155 finishPortlet();
d28ea105 3156
a684aa6f
DO
3157 echo '</td></tr><tr><td class=pcleft>';
3158 startPortlet ('VLAN table');
3159 echo '<table class=cooltable cellspacing=0 cellpadding=5 align=center width="100%">';
3160 echo "<tr><th>ID</th><th>Description</th></tr>";
3161 $order = 'even';
3162 global $nextorder;
3163 foreach ($vlanlist as $id => $descr)
3164 {
3165 echo "<tr class=row_${order}><td class=tdright>${id}</td><td class=tdleft>${descr}</td></tr>";
3166 $order = $nextorder[$order];
3167 }
3168 echo '</table>';
3169 finishPortlet();
3170
3171 echo '</td><td class=pcright>';
3172
3173 startPortlet ('Color legend');
3174 echo '<table>';
3175 echo "<tr><th>port state</th><th>color code</th></tr>";
3176 echo "<tr><td>not connected</td><td class=port_notconnect>SAMPLE</td></tr>";
3177 echo "<tr><td>disabled</td><td class=port_disabled>SAMPLE</td></tr>";
3178 echo "<tr><td>unknown</td><td class=port_unknown>SAMPLE</td></tr>";
3179 echo "<tr><td>connected with none MAC addresses active</td><td class=port_connected_none>SAMPLE</td></tr>";
3180 echo "<tr><td>connected with 1 MAC addresses active</td><td class=port_connected_single>SAMPLE</td></tr>";
3181 echo "<tr><td>connected with 1+ MAC addresses active</td><td class=port_connected_multi>SAMPLE</td></tr>";
3182 echo '</table>';
3183 finishPortlet();
3184
3185 echo '</td><td class=pcright>';
3186
18cb9495
DO
3187 if (count ($maclist))
3188 {
3189 startPortlet ('MAC address table');
3190 echo '<table border=0 class=cooltable align=center cellspacing=0 cellpadding=5>';
3191 echo "<tr><th>Port</th><th>VLAN ID</th><th>MAC address</th></tr>\n";
3192 $order = 'even';
3193 foreach ($maclist as $portname => $portdata)
3194 foreach ($portdata as $vlanid => $addrgroup)
3195 foreach ($addrgroup as $addr)
3196 {
3197 echo "<tr class=row_${order}><td>$portname</td><td>$vlanid</td><td>$addr</td></tr>\n";
3198 $order = $nextorder[$order];
3199 }
3200 echo '</table>';
3201 finishPortlet();
3202 }
3203
18cb9495
DO
3204 // End of main table.
3205 echo '</td></tr></table>';
111b4a67
DO
3206}
3207
9c67f713
DO
3208// This snippet either renders a form inviting the user to start SNMP query
3209// on the current device or displays the result of the scan.
3210function renderSNMPPortFinder ($object_id = 0)
3211{
3212 global $root, $pageno, $tabno, $remote_username;
3213 if ($object_id <= 0)
3214 {
591ff2c4 3215 showError ('Invalid object_id', __FUNCTION__);
9c67f713
DO
3216 return;
3217 }
dd9afc41 3218// FIXME: check if SNMP PHP extension is available!
9c67f713
DO
3219 if (isset ($_REQUEST['do_scan']))
3220 {
dd9afc41 3221 $log = array();
1c4d54d4
DO
3222// IDs: http://cisco.com/en/US/products/sw/cscowork/ps2064/products_device_support_table09186a0080803bb4.html
3223// 2960: http://www.cisco.com/en/US/products/ps6406/prod_models_comparison.html
65813f73 3224// 2970: http://cisco.com/en/US/products/hw/switches/ps5206/products_qanda_item09186a00801b1750.shtml
563196e8 3225// 3500XL: http://cisco.com/en/US/products/hw/switches/ps637/products_eol_models.html
1c4d54d4 3226// 3560: http://cisco.com/en/US/products/hw/switches/ps5528/products_data_sheet09186a00801f3d7f.html
563196e8 3227// 3750: http://cisco.com/en/US/products/hw/switches/ps5023/products_data_sheet09186a008016136f.html
137b7a50 3228 $ciscomodel[283] = 'WS-C6509-E (9-slot system)';
818e40c7
DO
3229// FIXME: hwtype hardcoded value will become invalid after the Dictionary table transformation
3230// in 0.14.7 version. Either the values will have to be adjusted as well or we have to switch
3231// to value lookup (not reliable).
64d5f2b4 3232 $hwtype[283] = 148;
dd9afc41
DO
3233# $ciscomodel[694] = 'WS-C2960-24TC-L (24 Ethernet 10/100 ports and 2 dual-purpose uplinks)';
3234# $ciscomodel[695] = 'WS-C2960-48TC-L (48 Ethernet 10/100 ports and 2 dual-purpose uplinks)';
3235 $ciscomodel[696] = 'WS-C2960G-24TC-L (20 Ethernet 10/100/1000 ports and 4 dual-purpose uplinks)';
64d5f2b4 3236 $hwtype[696] = 167;
dd9afc41 3237 $ciscomodel[697] = 'WS-C2960G-48TC-L (44 Ethernet 10/100/1000 ports and 4 dual-purpose uplinks)';
64d5f2b4 3238 $hwtype[697] = 166;
dd9afc41
DO
3239# $ciscomodel[716] = 'WS-C2960-24TT-L (24 Ethernet 10/100 ports and 2 10/100/1000 uplinks)';
3240# $ciscomodel[717] = 'WS-C2960-48TT-L (48 Ethernet 10/100 ports and 2 10/100/1000 uplinks)';
65813f73 3241 $ciscomodel[527] = 'WS-C2970G-24T (24 Ethernet 10/100/1000 ports)';
64d5f2b4 3242 $hwtype[527] = 210;
65813f73
DO
3243 $ciscomodel[561] = 'WS-C2970G-24TS (24 Ethernet 10/100/1000 ports and 4 10/100/1000 SFP uplinks)';
3244 $hwtype[561] = 115;
137b7a50 3245# $ciscomodel[633] = 'WS-C3560-24TS (24 Ethernet 10/100 ports and 2 10/100/1000 SFP uplinks)';
64d5f2b4 3246# $hwtype[633] = 169;
137b7a50 3247 $ciscomodel[634] = 'WS-C3560-48TS (48 Ethernet 10/100 ports and 4 10/100/1000 SFP uplinks)';
64d5f2b4 3248 $hwtype[634] = 170;
137b7a50 3249# $ciscomodel[563] = 'WS-C3560-24PS (24 Ethernet 10/100 POE ports and 2 10/100/1000 SFP uplinks)';
64d5f2b4 3250# $hwtype[563] = 171;
137b7a50 3251 $ciscomodel[564] = 'WS-C3560-48PS (48 Ethernet 10/100 POE ports and 4 10/100/1000 SFP uplinks)';
64d5f2b4 3252 $hwtype[564] = 172;
1c4d54d4 3253 $ciscomodel[614] = 'WS-C3560G-24PS (24 Ethernet 10/100/1000 POE ports and 4 10/100/1000 SFP uplinks)';
64d5f2b4 3254 $hwtype[614] = 175;
1c4d54d4 3255 $ciscomodel[615] = 'WS-C3560G-24TS (24 Ethernet 10/100/1000 ports and 4 10/100/1000 SFP uplinks)';
64d5f2b4 3256 $hwtype[615] = 173;
1c4d54d4 3257 $ciscomodel[616] = 'WS-C3560G-48PS (48 Ethernet 10/100/1000 POE ports and 4 10/100/1000 SFP uplinks)';
64d5f2b4 3258 $hwtype[616] = 176;
1c4d54d4 3259 $ciscomodel[617] = 'WS-C3560G-48TS (48 Ethernet 10/100/1000 ports and 4 10/100/1000 SFP uplinks)';
64d5f2b4 3260 $hwtype[617] = 174;
7a9f3034 3261 $ciscomodel[58] = 'WS-C4503 (3-slot system)';
64d5f2b4 3262 $hwtype[58] = 145;
7a9f3034 3263 $ciscomodel[503] = '4503 (3-slot system)';
64d5f2b4 3264 $hwtype[503] = 145;
7a9f3034 3265 $ciscomodel[59] = 'WS-C4506 (6-slot system)';
64d5f2b4 3266 $hwtype[59] = 156;
7a9f3034 3267 $ciscomodel[502] = '4506 (6-slot system)';
64d5f2b4 3268 $hwtype[502] = 156;
3d61d4ca 3269 $ciscomodel[626] = 'WS-C4948 (48 Ethernet 10/100/1000 ports and 4 10/100/1000 SFP uplinks)';
64d5f2b4 3270 $hwtype[626] = 147;
563196e8 3271 $ciscomodel[659] = 'WS-C4948-10GE (48 Ethernet 10/100/1000 ports and 2 10Gb X2 uplinks)';
64d5f2b4 3272 $hwtype[659] = 377;
dd9afc41
DO
3273 assertStringArg ('community');
3274 $community = $_REQUEST['community'];
3275 $objectInfo = getObjectInfo ($object_id);
3276 $endpoints = findAllEndpoints ($object_id, $objectInfo['name']);
3277 $sysDescr = snmpget ($endpoints[0], $community, 'sysDescr.0');
3278 // Strip the object type, it's always string here.
3279 $sysDescr = substr ($sysDescr, strlen ('STRING: '));
1c4d54d4 3280 if (strpos ($sysDescr, 'Cisco IOS Software') === 0 or strpos ($sysDescr, 'Cisco Internetwork Operating System Software') === 0)
dd9afc41 3281 $log[] = array ('code' => 'success', 'message' => 'Seems to be a Cisco box');
818e40c7
DO
3282 else
3283 {
3284 $log[] = array ('code' => 'error', 'message' => 'No idea how to handle ' . $sysDescr);
3285 printLog ($log);
3286 return;
3287 }
3288
3289 // It's a Cisco. Go on.
3290 $attrs = getAttrValues ($object_id);
3291 // Only fill in attribute values, if they are not set.
3292 // FIXME: this is hardcoded
3293
3294 if (empty ($attrs[5]['value'])) // SW version
3295 {
3296 $IOSversion = ereg_replace ('^.*, Version ([^ ]+), .*$', '\\1', $sysDescr);
3297 $error = commitUpdateAttrValue ($object_id, 5, $IOSversion);
3298 if ($error == TRUE)
3299 $log[] = array ('code' => 'success', 'message' => 'SW version set to ' . $IOSversion);
3300 else
3301 $log[] = array ('code' => 'error', 'message' => 'Failed settig SW version: ' . $error);
3302 }
3303
3304 if (empty ($attrs[4]['value']) and substr ($IOSversion, 0, 4) == '12.2') // switch OS type
3305 {
64d5f2b4 3306 $error = commitUpdateAttrValue ($object_id, 4, 252);
818e40c7
DO
3307 if ($error == TRUE)
3308 $log[] = array ('code' => 'success', 'message' => 'Switch OS type set to Cisco IOS 12.2');
3309 else
3310 $log[] = array ('code' => 'error', 'message' => 'Failed settig Switch OS type: ' . $error);
3311 }
3312
dd9afc41
DO
3313 $sysObjectID = snmpget ($endpoints[0], $community, 'sysObjectID.0');
3314 // Transform OID
3315 $sysObjectID = substr ($sysObjectID, strlen ('OID: SNMPv2-SMI::enterprises.9.1.'));
3316 if (!isset ($ciscomodel[$sysObjectID]))
3317 {
3318 $log[] = array ('code' => 'error', 'message' => 'Could not guess exact HW model!');
3319 printLog ($log);
3320 return;
3321 }
3322 $log[] = array ('code' => 'success', 'message' => 'HW is ' . $ciscomodel[$sysObjectID]);
818e40c7
DO
3323 if (empty ($attrs[2]['value']) and isset ($hwtype[$sysObjectID])) // switch HW type
3324 {
3325 $error = commitUpdateAttrValue ($object_id, 2, $hwtype[$sysObjectID]);
3326 if ($error == TRUE)
3d61d4ca 3327 $log[] = array ('code' => 'success', 'message' => 'HW type updated Ok');
818e40c7
DO
3328 else
3329 $log[] = array ('code' => 'error', 'message' => 'Failed settig HW type: ' . $error);
3330 }
dd9afc41
DO
3331 // Now fetch ifType, ifDescr and ifPhysAddr and let model-specific code sort the data out.
3332 $ifType = snmpwalkoid ($endpoints[0], $community, 'ifType');
3333 $ifDescr = snmpwalkoid ($endpoints[0], $community, 'ifdescr');
3334 $ifPhysAddress = snmpwalkoid ($endpoints[0], $community, 'ifPhysAddress');
3335 // Combine 3 tables into 1...
3336 $ifList1 = array();
3337 foreach ($ifType as $key => $val)
3338 {
3339 list ($dummy, $ifIndex) = explode ('.', $key);
3340 list ($dummy, $type) = explode (' ', $val);
3341 $ifList1[$ifIndex]['type'] = $type;
3342 }
3343 foreach ($ifDescr as $key => $val)
3344 {
3345 list ($dummy, $ifIndex) = explode ('.', $key);
3346 list ($dummy, $descr) = explode (' ', $val);
3347 $ifList1[$ifIndex]['descr'] = trim ($descr, '"');
3348 }
3349 foreach ($ifPhysAddress as $key => $val)
3350 {
3351 list ($dummy, $ifIndex) = explode ('.', $key);
3352 list ($dummy, $addr) = explode (':', $val);
3353 $addr = str_replace (' ', '', $addr);
3354 $ifList1[$ifIndex]['phyad'] = $addr;
3355 }
3356 // ...and then reverse it inside out to make description the key.
3357 $ifList2 = array();
3358 foreach ($ifList1 as $ifIndex => $data)
3359 {
3360 $ifList2[$data['descr']]['type'] = $data['type'];
3361 $ifList2[$data['descr']]['phyad'] = $data['phyad'];
3362 $ifList2[$data['descr']]['idx'] = $ifIndex;
3363 }
dd9afc41
DO
3364 $newports = 0;
3365 // Now we can directly pick necessary ports from the table accordingly
3366 // to our known hardware model.
3367 switch ($sysObjectID)
3368 {
3369 // FIXME: chassis edge switches often share a common naming scheme, so
3370 // the sequences below have to be generalized. Let's have some duplicated
3371 // code for the time being, as this is the first implementation ever.
3372 case '697': // WS-C2960G-48TC-L
3373 // 44 copper ports: 1X, 2X, 3X...
3374 // 4 combo ports: 45, 46, 47, 48. Don't list SFP connectors atm, as it's not
3375 // clear how to fit them into current Ports table structure.
3376 for ($i = 1; $i <= 48; $i++)
3377 {
3378 $label = ($i >= 45) ? "${i}" : "${i}X";
64d5f2b4 3379 $error = commitAddPort ($object_id, 'gi0/' . $i, 24, $label, $ifList2["GigabitEthernet0/${i}"]['phyad']);
dd9afc41
DO
3380 if ($error == '')
3381 $newports++;
3382 else
3383 $log[] = array ('code' => 'error', 'message' => 'Failed to add port ' . $label . ': ' . $error);
3384 }
3385 break;
3386 case '696': // WS-C2960G-24TC-L
3387 // Quite similar to the above.
3388 for ($i = 1; $i <= 24; $i++)
3389 {
3390 $label = ($i >= 21) ? "${i}" : "${i}X";
64d5f2b4 3391 $error = commitAddPort ($object_id, 'gi0/' . $i, 24, $label, $ifList2["GigabitEthernet0/${i}"]['phyad']);
dd9afc41
DO
3392 if ($error == '')
3393 $newports++;
3394 else
3395 $log[] = array ('code' => 'error', 'message' => 'Failed to add port ' . $label . ': ' . $error);
3396 }
3397 break;
137b7a50
DO
3398 case '564': // WS-C3560-48PS
3399 case '634': // WS-C3560-48TS
3400 for ($i = 1; $i <= 48; $i++)
3401 {
3402 $label = "${i}X";
64d5f2b4 3403 $error = commitAddPort ($object_id, 'fa0/' . $i, 19, $label, $ifList2["FastEthernet0/${i}"]['phyad']);
137b7a50
DO
3404 if ($error == '')
3405 $newports++;
3406 else
3407 $log[] = array ('code' => 'error', 'message' => 'Failed to add port ' . $label . ': ' . $error);
3408 }
3409 for ($i = 1; $i <= 4; $i++)
3410 {
3411 $label = "${i}";
64d5f2b4 3412 $error = commitAddPort ($object_id, 'gi0/' . $i, 24, $label, $ifList2["GigabitEthernet0/${i}"]['phyad']);
137b7a50
DO
3413 if ($error == '')
3414 $newports++;
3415 else
3416 $log[] = array ('code' => 'error', 'message' => 'Failed to add port ' . $label . ': ' . $error);
3417 }
3418 break;
1c4d54d4
DO
3419 case '614': // WS-C3560G-24PS
3420 case '615': // WS-C3560G-24TS
65813f73
DO
3421 case '527': // WS-C2970G-24T
3422 case '561': // WS-C2970G-24TS
1c4d54d4
DO
3423 for ($i = 1; $i <= 24; $i++)
3424 {
3425 $label = "${i}X";
64d5f2b4 3426 $error = commitAddPort ($object_id, 'gi0/' . $i, 24, $label, $ifList2["GigabitEthernet0/${i}"]['phyad']);
1c4d54d4
DO
3427 if ($error == '')
3428 $newports++;
3429 else
3430 $log[] = array ('code' => 'error', 'message' => 'Failed to add port ' . $label . ': ' . $error);
3431 }
3432 break;
3433 case '616': // WS-C3560G-48PS
3434 case '617': // WS-C3560G-48TS
cdc8ff71
DO
3435 for ($i = 1; $i <= 48; $i++)
3436 {
3437 $label = "${i}X";
3438 $error = commitAddPort ($object_id, 'gi0/' . $i, 24, $label, $ifList2["GigabitEthernet0/${i}"]['phyad']);
3439 if ($error == '')
3440 $newports++;
3441 else
3442 $log[] = array ('code' => 'error', 'message' => 'Failed to add port ' . $label . ': ' . $error);
3443 }
3444 break;
3d61d4ca
DO
3445 case '626': // WS-C4948
3446 case '659': // WS-C4948-10GE
1c4d54d4
DO
3447 for ($i = 1; $i <= 48; $i++)
3448 {
3449 $label = "${i}X";
cdc8ff71 3450 $error = commitAddPort ($object_id, 'gi1/' . $i, 24, $label, $ifList2["GigabitEthernet1/${i}"]['phyad']);
1c4d54d4
DO
3451 if ($error == '')
3452 $newports++;
3453 else
3454 $log[] = array ('code' => 'error', 'message' => 'Failed to add port ' . $label . ': ' . $error);
3455 }
3456 break;
137b7a50
DO
3457 // For modular devices we don't iterate over all possible port names,
3458 // but use the first list to pick everything that looks legitimate
3459 // for this hardware. It would be correct to fetch the list of modules
3460 // installed to generate lists of ports, but who is going to implement
3461 // this?
7a9f3034
DO
3462 case '503': // 4503
3463 case '58': // WS-C4503
3464 case '502': // 4506
3465 case '59': // WS-C4506
137b7a50
DO
3466 case '283': // WS-C6509-E
3467 foreach ($ifList1 as $port)
3468 {
3469 if ($port['type'] != 'ethernet-csmacd(6)')
3470 continue;
3471 // Copper Fa/Gi harvesting is relatively simple, while 10Gig ports can
3472 // have random samples of transciever units.
3473 if (strpos ($port['descr'], 'FastEthernet') === 0) // Fa
3474 {
3475 $prefix = 'fa';
64d5f2b4 3476 $ptype = 19; // RJ-45/100Base-TX
137b7a50
DO
3477 list ($slotno, $portno) = explode ('/', substr ($port['descr'], strlen ('FastEthernet')));
3478 }
3479 elseif (strpos ($port['descr'], 'GigabitEthernet') === 0) // Gi
3480 {
3481 $prefix = 'gi';
64d5f2b4 3482 $ptype = 24; // RJ-45/1000Base-T
137b7a50
DO
3483 list ($slotno, $portno) = explode ('/', substr ($port['descr'], strlen ('GigabitEthernet')));
3484 }
3485 else continue;
3486 $label = "slot ${slotno} port ${portno}";
3487 $pname = "${prefix}${slotno}/${portno}";
3488 $error = commitAddPort ($object_id, $pname, $ptype, $label, $port['phyad']);
3489 if ($error == '')
3490 $newports++;
3491 else
3492 $log[] = array ('code' => 'error', 'message' => 'Failed to add port ' . $pname . ': ' . $error);
3493 }
3494 break;
dd9afc41 3495 default:
591ff2c4 3496 showError ("Unexpected sysObjectID '${sysObjectID}'", __FUNCTION__);
dd9afc41 3497 }
64d5f2b4 3498 $error = commitAddPort ($object_id, 'con0', 29, 'console', '');
b8f2fed1
DO
3499 if ($error == '')
3500 $newports++;
3501 else
3502 $log[] = array ('code' => 'error', 'message' => 'Failed to add console port : ' . $error);
dd9afc41
DO
3503 if ($newports > 0)
3504 $log[] = array ('code' => 'success', 'message' => "Added ${newports} new ports");
3505 printLog ($log);
9c67f713
DO
3506 return;
3507 }
dd9afc41
DO
3508 echo "<form method=post>\n";
3509 echo "<input type=hidden name=pageno value='${pageno}'>\n";
3510 echo "<input type=hidden name=tabno value='${pageno}'>\n";
3511?>
3512<p align=center>
3513This switch has no ports listed, that's why you see this form. If you supply SNMP community,
3514I can try atomatic data harvesting on the switch. As soon as at least one relevant port is found,
3515this tab will not be seen any more. Good luck.<br>
3516<input type=text name=community value='public'>
3517<input type=submit name='do_scan' value='Go!'>
3518</p>
b325120a 3519<?php
9c67f713
DO
3520}
3521
b07f617c
DO
3522function renderUIResetForm()
3523{
8dedc926 3524 global $root, $pageno, $tabno;
b07f617c
DO
3525 echo "<form method=post action='${root}process.php'>";
3526 echo "<input type=hidden name=page value=${pageno}>";
3527 echo "<input type=hidden name=tab value=${tabno}>";
3528 echo "<input type=hidden name=op value=go>";
3529 echo "This button will reset user interface configuration to its defaults (except organization name): ";
3530 echo "<input type=submit value='proceed'>";
3531 echo "</form>";
3532}
3533
9b0cf84f
DO
3534function renderFirstRowForm ()
3535{
3536 global $root, $pageno, $tabno;
80c37f85
DO
3537 echo "<form action='${root}process.php'>\n";
3538 echo "<input type=hidden name=page value=dict>\n";
3539 echo "<input type=hidden name=tab value=edit>\n";
3540 echo "<input type=hidden name=op value=add>\n";
3541 echo "<input type=hidden name=chapter_no value=3>\n";
9b0cf84f
DO
3542?>
3543<p align=center>
3544Your rackspace seems to be empty, and this form will create your first rack row,
3545just fill in the name. All the subsequent rack rows will have to be added from the
3546Dictionary edit page in Configuration section.
3547<br>
80c37f85
DO
3548<input type=text name=dict_value value='my server room'>
3549<input type=submit value='OK'>
9b0cf84f
DO
3550</p>
3551<?php
3552}
3553
fb355164 3554function renderLVSConfig ($object_id = 0)
3ee1252b 3555{
fb355164
DO
3556 if ($object_id <= 0)
3557 {
591ff2c4 3558 showError ('Invalid object_id', __FUNCTION__);
fb355164
DO
3559 return;
3560 }
3561 $natrules = getObjectForwards ($object_id);
3562 $lvsconfig = array();
3563 foreach ($natrules['out'] as $rule)
3564 {
3565 $lvsconfig [$rule['localip']] ['description'] = $rule['local_addr_name'];
3566 $lvsconfig [$rule['localip']] [$rule['proto']] [$rule['localport']] ['rs'] [] = array
3567 (
3568 'address' => $rule['remoteip'],
3569 'port' => $rule['remoteport'],
3570 'description' => $rule['remote_addr_name']
3571 );
3572 }
3573 echo '<pre>';
3574 foreach ($lvsconfig as $vip => $vipdata)
3575 foreach (readChapter ('Protocols') as $proto)
3576 {
3577 if (!isset ($vipdata[$proto]))
3578 continue;
3579 foreach ($vipdata[$proto] as $vport => $vportdata)
3580 {
5e19e15c 3581 echo '# auto-VIP: ' . (empty ($vipdata['description']) ? 'NO NAME' : $vipdata['description']) . "\n";
fb355164
DO
3582 echo "virtual_server ${vip} ${vport}\n";
3583 foreach ($vportdata['rs'] as $rs)
04d1707b
DO
3584 {
3585 if (!empty ($rs['description']))
3586 echo "\t# " . $rs['description'] . "\n";
fb355164 3587 echo "\treal_server ${rs['address']} ${rs['port']} {\n\t}\n";
04d1707b 3588 }
fb355164
DO
3589 echo "}\n\n";
3590 }
3591 }
3592 echo '</pre>';
3ee1252b
DO
3593}
3594
060ba26e 3595function renderVirtualService ($vsid = 0)
13bffb29 3596{
5cca8baf 3597 global $root;
060ba26e
DO
3598 if ($vsid <= 0)
3599 {
3600 showError ('Invalid vsid', __FUNCTION__);
3601 return;
3602 }
3603 $vsinfo = getVServiceInfo ($vsid);
c85b85b5
DO
3604#echo '<pre>';
3605#print_r ($vsinfo);
3606#echo '</pre>';
3607 echo '<table border=0 class=objectview cellspacing=0 cellpadding=0>';
3608 if (!empty ($vsinfo['name']))
3609 echo "<tr><td colspan=2 align=center><h1>${vsinfo['name']}</h1></td></tr>\n";
3610 echo '<tr>';
3611
3612 echo '<td class=pcleft>';
3613 startPortlet ('Frontend');
3614 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
3615 if (!empty ($vsinfo['name']))
3616 echo "<tr><th width='50%' class=tdright>Name:</th><td class=tdleft>${vsinfo['name']}</td></tr>\n";
3617 echo "<tr><th width='50%' class=tdright>Protocol:</th><td class=tdleft>${vsinfo['proto']}</td></tr>\n";
85f96f3f 3618 echo "<tr><th width='50%' class=tdright>Virtual IP address:</th><td class=tdleft><a href='${root}?page=ipaddress&tab=default&ip=${vsinfo['vip']}'>${vsinfo['vip']}</a></td></tr>\n";
c85b85b5
DO
3619 echo "<tr><th width='50%' class=tdright>Virtual port:</th><td class=tdleft>${vsinfo['vport']}</td></tr>\n";
3620 echo "</table>\n";
3621 finishPortlet ();
3622 echo '</td>';
3623
3624 echo '<td class=pcright rowspan=3>';
3625 startPortlet ('Backend');
3626 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
3627 echo "<tr><th>Real IP address</th><th>Real port</th><th>[LBs]</tr>\n";
3628 foreach ($vsinfo['rslist'] as $rsinfo)
3629 {
9747f8c6 3630 echo "<tr><td><a href='${root}?page=ipaddress&tab=default&ip=${rsinfo['rsip']}'>${rsinfo['rsip']}</a></td>";
c85b85b5
DO
3631 echo "<td>${rsinfo['rsport']}</td>";
3632 echo "<td>[LB config]</td></tr>";
3633 }
3634 echo "</table>\n";
3635 finishPortlet ();
3636 echo '</td>';
3637
3638 echo "</tr>\n<tr>";
3639
3640 echo '<td>';
3641 startPortlet ('Virtual service configuration');
3642 echo "<pre>${vsinfo['vsconfig']}</pre>";
3643 finishPortlet ();
3644 echo '</td>';
3645
3646 echo "</tr>\n<tr>";
3647
3648 echo '<td>';
3649 startPortlet ('Default real server configuration');
3650 echo "<pre>${vsinfo['default_rsconfig']}</pre>";
3651 finishPortlet ();
3652 echo '</td>';
3653
3654 echo '</tr><table>';
13bffb29
DO
3655}
3656
8a1b387d
DO
3657function renderProgressBar ($percentage = 0)
3658{
3659 $done = ((int) ($percentage * 100));
3660 $left = 100 - $done;
3661 echo "<table width=100px height=10px border=0 cellspacing=0 cellpadding=0><tr>";
3662 echo "<td class=state_T width='${done}%'><div title='${done}%'>&nbsp;</div></td>";
3663 echo "<td class=state_F><div title='${left}%'>&nbsp;</div></td>";
3664 echo "</tr></table>";
3665}
3666
e673ee24 3667?>