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