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