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