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