r1885 + implement tag filtering for IPv4 RS pools
[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
eeb4a5d8 859 $forwards = getNATv4ForObject ($object_id);
e673ee24
DO
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
eeb4a5d8 2410function renderNATv4ForObject ($object_id = 0)
e673ee24
DO
2411{
2412 global $pageno, $tabno, $root;
2413
2414 $info = getObjectInfo ($object_id);
eeb4a5d8 2415 $forwards = getNATv4ForObject ($object_id);
e673ee24
DO
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'>";
eeb4a5d8 2436 echo "<td><a href='process.php?op=delPortForwarding&localip=${pf['localip']}&localport=${pf['localport']}&remoteip=${pf['remoteip']}&remoteport=${pf['remoteport']}&proto=${pf['proto']}&object_id=$object_id&page=${pageno}&tab=${tabno}'>";
4de22e7e
DO
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'] . ')';
eeb4a5d8
DO
2453 echo "</td><form action='process.php'><input type='hidden' name='op' value='updPortForwarding'><input type=hidden name=page value='${pageno}'>";
2454 echo "<input type=hidden name=tab value='${tabno}'><input type='hidden' name='object_id' value='$object_id'>";
2455 echo "<input type='hidden' name='localip' value='${pf['localip']}'><input type='hidden' name='localport' value='${pf['localport']}'>";
2456 echo "<input type='hidden' name='remoteip' value='${pf['remoteip']}'><input type='hidden' name='remoteport' value='${pf['remoteport']}'>";
2457 echo "<input type='hidden' name='proto' value='${pf['proto']}'><td class='description'>";
2458 echo "<input type='text' name='description' value='${pf['description']}'> <input type='submit' value='OK'></td></form>";
e673ee24
DO
2459 echo "</tr>";
2460 }
2461 echo "<form action='process.php'><input type='hidden' name='op' value='forwardPorts'>";
2462 echo "<input type='hidden' name='object_id' value='$object_id'>";
2463 echo "<input type=hidden name=page value='${pageno}'>\n";
2464 echo "<input type=hidden name=tab value='${tabno}'>\n";
436605a7 2465 echo "<tr align='center'><td colspan=2>";
eeb4a5d8 2466 printSelect (array ('TCP' => 'TCP', 'UDP' => 'UDP'), 'proto');
52c3543f 2467 echo "<select name='localip' tabindex=1>";
e673ee24
DO
2468
2469 foreach ($addresses as $addr)
09992c16
DO
2470 echo "<option value='${addr['ip']}'>" . (empty ($addr['name']) ? '' : "${addr['name']}: ") .
2471 "${addr['ip']}" . (empty ($addr['address_name']) ? '' : " (${addr['address_name']})") . "</option>";
e673ee24 2472
52c3543f
DO
2473 echo "</select>:<input type='text' name='localport' size='4' tabindex=2></td>";
2474 echo "<td><input type='text' name='remoteip' id='remoteip' size='10' tabindex=3>";
4de22e7e
DO
2475 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\");'>";
2476 printImageHREF ('find', 'Find object');
2477 echo "</a>";
52c3543f
DO
2478 echo ":<input type='text' name='remoteport' size='4' tabindex=4></td><td></td>";
2479 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
2480 echo "</form>";
2481
2482 echo "</table><br><br>";
2483
f28fbe8b 2484 echo "<center><h2>arriving NAT connections</h2></center>";
e673ee24
DO
2485 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
2486 echo "<tr><th></th><th>Source</th><th>Source objects</th><th>Target</th><th>Description</th></tr>\n";
2487
2488 foreach ($forwards['in'] as $pf)
2489 {
eeb4a5d8 2490 echo "<tr><td><a href='process.php?op=delPortForwarding&localip=${pf['localip']}&localport=${pf['localport']}&remoteip=${pf['remoteip']}&remoteport=${pf['remoteport']}&proto=${pf['proto']}&object_id=${pf['object_id']}&page=${pageno}&tab=${tabno}'>";
4de22e7e
DO
2491 printImageHREF ('delete', 'Delete NAT rule');
2492 echo "</a></td>";
e673ee24
DO
2493 echo "<td>${pf['proto']}/<a href='${root}?page=ipaddress&tab=default&ip=${pf['localip']}'>${pf['localip']}</a>:${pf['localport']}</td>";
2494 echo "<td class='description'><a href='${root}?page=object&tab=default&object_id=${pf['object_id']}'>${pf['object_name']}</a>";
2495 echo "</td><td><a href='${root}?page=ipaddress&tab=default&ip=${pf['remoteip']}'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
2496 echo "<td class='description'>${pf['description']}</td></tr>";
2497 }
2498
e673ee24 2499 echo "</table><br><br>";
e673ee24
DO
2500}
2501
2502
2503function renderAddMultipleObjectsForm ()
2504{
20c901a7 2505 global $root, $pageno, $tabno, $nextorder;
e673ee24
DO
2506
2507 $type_id = array();
7f791d1d 2508 $global_type_id = 0;
e673ee24
DO
2509 $name = array();
2510 $asset_no = array();
2511 $keepvalues = FALSE;
7f791d1d 2512 $log = array();
e673ee24 2513 // Look for current submit.
7f791d1d 2514 if (isset ($_REQUEST['got_fast_data']))
e673ee24
DO
2515 {
2516 $keepvalues = TRUE;
9c0b0016
DO
2517 $max = getConfigVar ('MASSCOUNT');
2518 for ($i = 0; $i < $max; $i++)
e673ee24
DO
2519 {
2520 if (!isset ($_REQUEST["${i}_object_type_id"]))
2521 {
2522 $log[] = array ('code' => 'error', 'message' => "Submitted form is invalid at line " . $i + 1);
2523 break;
2524 }
2c6c7645
DO
2525 assertUIntArg ("${i}_object_type_id", __FUNCTION__, TRUE);
2526 assertStringArg ("${i}_object_name", __FUNCTION__, TRUE);
2527 assertStringArg ("${i}_object_label", __FUNCTION__, TRUE);
2528 assertStringArg ("${i}_object_asset_no", __FUNCTION__, TRUE);
2529 assertStringArg ("${i}_object_barcode", __FUNCTION__, TRUE);
e673ee24
DO
2530 $type_id[$i] = $_REQUEST["${i}_object_type_id"];
2531 // Save user input for possible rendering.
2532 $name[$i] = $_REQUEST["${i}_object_name"];
2533 $label[$i] = $_REQUEST["${i}_object_label"];
2534 $asset_no[$i] = $_REQUEST["${i}_object_asset_no"];
2535 $barcode[$i] = $_REQUEST["${i}_object_barcode"];
2536
2537 // It's better to skip silently than printing a notice.
2538 if ($type_id[$i] == 0)
2539 continue;
2540 if (commitAddObject ($name[$i], $label[$i], $barcode[$i], $type_id[$i], $asset_no[$i]) === TRUE)
2541 $log[] = array ('code' => 'success', 'message' => "Added new object '${name[$i]}'");
2542 else
4d2e93f2 2543 $log[] = array ('code' => 'error', 'message' => __FUNCTION__ . ': commitAddObject() failed');
e673ee24 2544 }
e673ee24 2545 }
7f791d1d
DO
2546 elseif (isset ($_REQUEST['got_very_fast_data']))
2547 {
2548 $keepvalues = TRUE;
2c6c7645
DO
2549 assertUIntArg ('global_type_id', __FUNCTION__, TRUE);
2550 assertStringArg ('namelist', __FUNCTION__, TRUE);
7f791d1d
DO
2551 $global_type_id = $_REQUEST['global_type_id'];
2552 if ($global_type_id == 0)
2553 {
2554 if (!empty ($_REQUEST['namelist']))
2555 $log[] = array ('code' => 'error', 'message' => 'Object type is not selected, check the form below');
2556 else
2557 $log[] = array ('code' => 'error', 'message' => 'Empty form has been ignored. Cheers.');
2558 }
2559 else
2560 {
2561 // The name extractor below was stolen from ophandlers.php:addMultiPorts()
2562 $names1 = explode ('\n', $_REQUEST['namelist']);
2563 $names2 = array();
2564 foreach ($names1 as $line)
2565 {
2566 $parts = explode ('\r', $line);
2567 reset ($parts);
2568 if (empty ($parts[0]))
2569 continue;
2570 else
2571 $names2[] = rtrim ($parts[0]);
2572 }
2573 foreach ($names2 as $cname)
2574 if (commitAddObject ($cname, '', '', $global_type_id, '') === TRUE)
2575 $log[] = array ('code' => 'success', 'message' => "Added new object '${cname}'");
2576 else
2577 $log[] = array ('code' => 'error', 'message' => "Could not add '${cname}'");
2578 }
2579 }
2580 printLog ($log);
e673ee24
DO
2581
2582 // Render a form for the next.
2583 $typelist = getObjectTypeList();
4c330a14 2584 $typelist[0] = 'select type...';
7f791d1d
DO
2585
2586 startPortlet ('Fast way');
20c901a7 2587 echo "<form name=fastform method=post action='${root}?page=${pageno}&tab=${tabno}'>";
e673ee24
DO
2588 echo '<table border=0 align=center>';
2589 echo "<tr><th>Object type</th><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>Barcode</th></tr>\n";
7f791d1d 2590 // If a user forgot to select object type on input, we keep his
e673ee24 2591 // previous input in the form.
9c0b0016
DO
2592 $max = getConfigVar ('MASSCOUNT');
2593 for ($i = 0; $i < $max; $i++)
e673ee24 2594 {
7f791d1d 2595 echo '<tr><td>';
e7ade6bf
DO
2596 // Don't employ DEFAULT_OBJECT_TYPE to avoid creating ghost records for pre-selected empty rows.
2597 printSelect ($typelist, "${i}_object_type_id", 0);
e673ee24
DO
2598 echo '</td>';
2599 echo "<td><input type=text size=30 name=${i}_object_name";
2600 if ($keepvalues and $type_id[$i] == 0)
2601 echo " value='${name[$i]}'";
2602 echo "></td>";
2603 echo "<td><input type=text size=30 name=${i}_object_label";
2604 if ($keepvalues and $type_id[$i] == 0)
2605 echo " value='${label[$i]}'";
2606 echo "></td>";
2607 echo "<td><input type=text size=20 name=${i}_object_asset_no";
2608 if ($keepvalues and $type_id[$i] == 0)
2609 echo " value='${asset_no[$i]}'";
2610 echo "></td>";
2611 echo "<td><input type=text size=10 name=${i}_object_barcode";
2612 if ($keepvalues and $type_id[$i] == 0)
2613 echo " value='${barcode[$i]}'";
2614 echo "></td>";
2615 echo "</tr>\n";
e673ee24 2616 }
7f791d1d 2617 echo "<tr><td class=submit colspan=5><input type=submit name=got_fast_data value='Create'></td></tr>\n";
e673ee24
DO
2618 echo "</form></table>\n";
2619 finishPortlet();
7f791d1d
DO
2620
2621 startPortlet ('Very fast way');
20c901a7 2622 echo "<form name=veryfastform method=post action='${root}?page=${pageno}&tab=${tabno}'>";
7f791d1d 2623 echo 'For each line shown below create an object of type ';
a477e405 2624 printSelect ($typelist, "global_type_id", getConfigVar ('DEFAULT_OBJECT_TYPE'));
7f791d1d
DO
2625 echo " <input type=submit name=got_very_fast_data value='Go!'><br>\n";
2626 echo "<textarea name=namelist cols=40 rows=25>\n";
2627 if ($keepvalues and $global_type_id == 0)
2628 echo $_REQUEST['namelist'];
2629 echo "</textarea></form>\n";
2630 finishPortlet();
e673ee24
DO
2631}
2632
2633function printGreeting ()
2634{
59cd003e 2635 global $remote_username, $accounts, $root;
e673ee24 2636 $account = $accounts[$remote_username];
4eb5efb7 2637 echo "Hello, ${account['user_realname']}. This is RackTables " . CODE_VERSION . ". Click <a href='${root}?logout'>here</a> to logout.";
e673ee24
DO
2638}
2639
2640function renderSearchResults ()
2641{
2642 global $remote_username, $root;
2643 $terms = trim ($_REQUEST['q']);
2644 if (empty ($terms))
2645 {
591ff2c4 2646 showError ('Search string cannot be empty.', __FUNCTION__);
e673ee24
DO
2647 return;
2648 }
2649 if (!authorized ($remote_username, 'object', 'default'))
2650 {
591ff2c4 2651 showError ('You are not authorized for viewing information about objects.', __FUNCTION__);
e673ee24
DO
2652 return;
2653 }
ea5fc465 2654 $nhits = 0;
e673ee24
DO
2655 // If we search for L2 address, we can either find one or find none.
2656 if
2657 (
2658 preg_match ('/^[0-9a-f][0-9a-f]?:[0-9a-f][0-9a-f]?:[0-9a-f][0-9a-f]?:[0-9a-f][0-9a-f]?:[0-9a-f][0-9a-f]?:[0-9a-f][0-9a-f]?$/i', $terms) or
2659 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
2660 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
2661 // STP bridge ID: bridge priotity + port MAC address. Cut off first 4 chars and look for MAC address.
2662 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
2663 )
2664 // Search for L2 address.
2665 {
ea5fc465 2666 $terms = substr ($terms, -12);
e673ee24
DO
2667 $result = searchByl2address ($terms);
2668 if ($result !== NULL)
2669 {
ea5fc465
DO
2670 $nhits++;
2671 $lasthit = 'port';
2672 $summary['port'][] = $result;
e673ee24 2673 }
e673ee24
DO
2674 }
2675 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))
2676 // Search for IP address.
2677 {
2678 $result = getRangeByIp ($terms);
2679 if ($result !== NULL)
2680 {
ea5fc465 2681 $nhits++;
bc3ab23e 2682 $lasthit = 'ipv4address1';
ea5fc465 2683 $summary['ipv4address1'][] = $terms;
e673ee24 2684 }
e673ee24
DO
2685 }
2686 else
ea5fc465 2687 // Search for objects, addresses, networks, virtual services and RS pools by their description.
e673ee24 2688 {
ea5fc465
DO
2689 $tmp = getObjectSearchResults ($terms);
2690 if (count ($tmp))
e673ee24 2691 {
ea5fc465
DO
2692 $nhits += count ($tmp);
2693 $lasthit = 'object';
2694 $summary['object'] = $tmp;
e673ee24 2695 }
ea5fc465
DO
2696 $tmp = getIPv4AddressSearchResult ($terms);
2697 if (count ($tmp))
e673ee24 2698 {
ea5fc465
DO
2699 $nhits += count ($tmp);
2700 $lasthit = 'ipv4address2';
2701 $summary['ipv4address2'] = $tmp;
2702 }
2703 $tmp = getIPv4PrefixSearchResult ($terms);
2704 if (count ($tmp))
2705 {
2706 $nhits += count ($tmp);
2707 $lasthit = 'ipv4network';
2708 $summary['ipv4network'] = $tmp;
2709 }
2710 }
2711 if ($nhits == 0)
2712 echo "<center><h2>Nothing found for '${terms}'</h2></center>";
2713 elseif ($nhits == 1)
2714 {
2715 $record = current ($summary[$lasthit]);
2716 switch ($lasthit)
2717 {
2718 case 'port':
2719 echo "<script language='Javascript'>document.location='${root}?page=object";
2720 echo "&hl_port_id=" . $record['port_id'];
2721 echo "&object_id=" . $record['object_id'] . "';//</script>";
2722 break;
2723 case 'ipv4address1':
2724 echo "<script language='Javascript'>document.location='${root}?page=ipaddress";
2725 echo "&ip=${record}";
2726 echo "';//</script>";
2727 break;
2728 case 'ipv4address2':
2729 echo "<script language='Javascript'>document.location='${root}?page=ipaddress";
2730 echo "&ip=${record}";
2731 echo "';//</script>";
2732 break;
2733 case 'ipv4network':
2734 echo "<script language='Javascript'>document.location='${root}?page=iprange";
2735 echo "&id=${record['id']}";
2736 echo "';//</script>";
2737 break;
2738 case 'object':
2739 echo "<script language='Javascript'>document.location='${root}?page=object&object_id=${record['id']}';//</script>";
2740 break;
2741 }
2742 return;
2743 }
2744 else
2745 {
2746 global $nextorder;
2747 $order = 'odd';
2748 echo "<center><h2>${nhits} result(s) found for '${terms}'</h2></center>";
2749 foreach ($summary as $where => $what)
2750 switch ($where)
e673ee24 2751 {
ea5fc465
DO
2752 case 'object':
2753 startPortlet ('Objects');
2754 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
2755 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>barcode</th></tr>';
2756 foreach ($what as $obj)
2757 {
2758 echo "<tr class=row_${order}><td><a href=\"${root}?page=object&object_id=${obj['id']}\">${obj['dname']}</a></td>";
2759 echo "<td>${obj['label']}</td>";
2760 echo "<td>${obj['asset_no']}</td>";
2761 echo "<td>${obj['barcode']}</td></tr>";
2762 $order = $nextorder[$order];
2763 }
2764 echo '</table>';
2765 finishPortlet();
2766 break;
2767 case 'ipv4network':
2768 startPortlet ('IPv4 networks');
2769 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
2770 echo '<tr><th>Network</th><th>Descritpion</th></tr>';
2771 foreach ($what as $net)
2772 {
2773 echo "<tr class=row_${order}><td class=tdleft><a href='${root}?page=iprange&id=${net['id']}'>${net['ip']}";
2774 echo '/' . $net['mask'] . '</a></td>';
2775 echo "<td class=tdleft>${net['name']}</td></tr>";
2776 $order = $nextorder[$order];
2777 }
2778 echo '</table>';
2779 finishPortlet();
2780 break;
2781 case 'ipv4address2':
2782 startPortlet ('IPv4 addresses');
2783 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
2784 echo '<tr><th>Address</th><th>Descritpion</th></tr>';
2785 foreach ($what as $addr)
2786 {
fd190b0a 2787 echo "<tr class=row_${order}><td class=tdleft><a href='${root}?page=ipaddress&ip=${addr['ip']}'>";
ea5fc465
DO
2788 echo "${addr['ip']}</a></td>";
2789 echo "<td class=tdleft>${addr['name']}</td></tr>";
2790 $order = $nextorder[$order];
2791 }
2792 echo '</table>';
2793 finishPortlet();
2794 break;
e673ee24 2795 }
e673ee24
DO
2796 }
2797}
2798
2799// This function prints a table of checkboxes to aid the user in toggling mount atoms
2800// from one state to another. The first argument is rack data as
2801// produced by getRackData(), the second is the value used for the 'unckecked' state
2802// and the third is the value used for 'checked' state.
2803// Usage contexts:
2804// for mounting an object: printAtomGrid ($data, 'F', 'T')
2805// for changing rack design: printAtomGrid ($data, 'A', 'F')
2806// for adding rack problem: printAtomGrid ($data, 'F', 'U')
2807// for adding object problem: printAtomGrid ($data, 'T', 'W')
2808
2809function renderAtomGrid ($data)
2810{
2811 $rack_id = $data['id'];
2812 for ($unit_no = $data['height']; $unit_no > 0; $unit_no--)
2813 {
2814 echo "<tr><th>${unit_no}</th>";
2815 for ($locidx = 0; $locidx < 3; $locidx++)
2816 {
2817 $state = $data[$unit_no][$locidx]['state'];
2818 echo "<td class=state_${state}";
2819 if (isset ($data[$unit_no][$locidx]['hl']))
2820 echo $data[$unit_no][$locidx]['hl'];
2821 echo ">";
2822 if (!($data[$unit_no][$locidx]['enabled'] === TRUE))
2823 echo '<input type=checkbox disabled>';
2824 else
2825 echo "<input type=checkbox" . $data[$unit_no][$locidx]['checked'] . " name=atom_${rack_id}_${unit_no}_${locidx}>";
2826 echo '</td>';
2827 }
2828 echo "</tr>\n";
2829 }
2830}
2831
2832function renderPermissions ()
2833{
2834 startPortlet ('User permissions');
2835 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
2836 echo "<tr><th>Username</th><th>Page</th><th>Tab</th><th>Access</th></tr>";
2837 global $perms, $nextorder;
2838 $order = 'odd';
2839 foreach ($perms as $username => $pages)
2840 foreach ($pages as $page => $tabs)
2841 foreach ($tabs as $tab => $access)
2842 {
2843 echo "<tr class=row_${order}><td class=tdleft>$username</td><td>$page</td><td>$tab</td><td>$access</td></tr>\n";
2844 $order = $nextorder[$order];
2845 }
2846 echo "</table>\n";
2847 finishPortlet();
2848}
2849
2850function renderAccounts ()
2851{
2852 global $nextorder, $accounts;
2853 startPortlet ('User accounts');
2854 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
2855 echo "<tr><th class=tdleft>Username</th><th class=tdleft>Real name</th></tr>";
2856 $order = 'odd';
2857 foreach ($accounts as $user)
2858 {
20c901a7
DO
2859 echo "<tr class=row_${order}><td class=tdleft><div title='\$userid_${user['user_id']}'>";
2860 echo "${user['user_name']}</div></td>";
2861 echo "<td class=tdleft>${user['user_realname']}</td></li>";
e673ee24
DO
2862 $order = $nextorder[$order];
2863 }
2864 echo '</table>';
2865 finishPortlet();
2866}
2867
2868function renderAccountsEditForm ()
2869{
2870 global $root, $pageno, $tabno, $accounts;
2871 startPortlet ('User accounts');
2872 showMessageOrError();
2873 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
2874 echo "<tr><th>op</th><th>Username</th><th>Real name</th><th>Password</th><th>&nbsp;</th></tr>\n";
2875 foreach ($accounts as $account)
2876 {
2877 echo "<form action='${root}process.php'>";
2878 echo "<input type=hidden name=op value=updateAccount>";
2879 echo "<input type=hidden name=page value='${pageno}'>\n";
2880 echo "<input type=hidden name=tab value='${tabno}'>\n";
2881 echo "<input type=hidden name=id value='${account['user_id']}'><tr>";
2882 echo "<td>";
2883 if ($account['user_enabled'] == 'yes' && $account['user_id'] != 1)
2884 {
2885 echo "<a href='${root}process.php?op=disableAccount&page=${pageno}&tab=${tabno}&id=${account['user_id']}'>";
2886 printImageHREF ('blockuser', 'disable account');
2887 echo "</a>\n";
2888 }
2889 if ($account['user_enabled'] == 'no' && $account['user_id'] != 1)
2890 {
2891 echo "<a href='${root}process.php?op=enableAccount&page=${pageno}&tab=${tabno}&id=${account['user_id']}'>";
2892 printImageHREF ('unblockuser', 'enable account');
2893 echo "</a>\n";
2894 }
2895 // Otherwise skip icon.
2896 echo "</td>";
2897 echo "<td><input type=text name=username value='${account['user_name']}' size=16></td>";
2898 echo "<td><input type=text name=realname value='${account['user_realname']}' size=24></td>";
2899 echo "<td><input type=password name=password value='${account['user_password_hash']}' size=64></td>";
2900 echo "<td><input type='submit' value='OK'></td>";
2901 echo "</form></tr>\n";
2902 }
2903 echo "<form action='${root}process.php' method=post><tr>";
2904 echo "<input type=hidden name=op value=createAccount>\n";
2905 echo "<input type=hidden name=page value='${pageno}'>\n";
2906 echo "<input type=hidden name=tab value='${tabno}'>\n";
2907 echo "<td colspan=2><input type=text size=16 name=username tabindex=100></td>\n";
2908 echo "<td><input type=text size=24 name=realname tabindex=101></td>";
2909 echo "<td><input type=password size=64 name=password tabindex=102></td>";
2910 echo "<td colspan=4><input type=submit value='Create account' tabindex=103></td></tr></form>";
2911 echo "</table><br>\n";
2912 finishPortlet();
2913}
2914
2915function printChildrenAsOptions ($root, $depth = 0)
2916{
2917 echo "<option value=${root['title']}>";
2918 if ($depth == 0)
2919 echo '* ';
2920 for ($i = 0; $i < $depth; $i++)
2921 echo '-- ';
2922 echo $root['title'];
2923 echo "</option>\n";
2924 foreach ($root['kids'] as $kid)
2925 printChildrenAsOptions ($kid, $depth + 1);
2926}
2927
2928// 1. Find all parentless pages.
2929// 2. For each of them recursively find all children.
2930// 3. Output the tree with recursion tree display.
2931function printPagesTree ()
2932{
2933 global $page;
2934 echo '<pre>';
2935 foreach ($page as $ctitle => $cpage)
2936 if (!isset ($cpage['parent']))
2937 {
2938 $croot['title'] = $ctitle;
2939 $croot['kids'] = getAllChildPages ($ctitle);
2940 printChildrenAsOptions ($croot);
2941 }
2942 echo '</pre>';
2943}
2944
2945function renderPermissionsEditForm ()
2946{
2947 global $root, $pageno, $tabno, $perms, $accounts;
2948 startPortlet ('User permissions');
2949 showMessageOrError();
2950 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
2951 echo "<tr><th>&nbsp;</th><th>Username</th><th>Page</th><th>Tab</th><th>Access</th></tr>\n";
2952 foreach ($perms as $username => $pages)
2953 foreach ($pages as $access_page => $tabs)
2954 foreach ($tabs as $access_tab => $access)
2955 {
2956 echo "<td>";
2957 if ($username != '%')
2958 $userid = $accounts[$username]['user_id'];
2959 else
2960 $userid = 0;
2961 echo "<a href='${root}process.php?op=revoke&page=${pageno}&tab=${tabno}&access_userid=${userid}&access_page=${access_page}&access_tab=${access_tab}'>";
2962 printImageHREF ('revoke', 'Revoke permission');
2963 echo "</a></td>";
2964 echo "<td>${username}</td>";
2965 echo "<td>${access_page}</td>";
2966 echo "<td>${access_tab}</td>";
2967 echo "<td>${access}</td>";
2968 echo "</tr>\n";
2969 }
2970 echo "<form action='${root}process.php' method=post><tr>";
2971 echo "<input type=hidden name=op value=grant>\n";
2972 echo "<input type=hidden name=page value='${pageno}'>\n";
2973 echo "<input type=hidden name=tab value='${tabno}'>\n";
2974 // FIXME: border=0 doesn't work here for unknown reason
2975 echo "<td>";
a5ae8c2a 2976 printImageHREF ('grant', '', TRUE, 103);
e673ee24
DO
2977 echo "</td>";
2978 echo "<td><select name=access_userid>";
2979 echo "<option value=0>ANY</option>";
2980 foreach ($accounts as $account)
2981 echo "<option value=${account['user_id']}>${account['user_name']}</option>";
2982 echo "</select></td>\n";
2983 echo "<td><select name=access_page>";
2984 echo "<option value='%'>ANY</option>";
2985 printPagesTree();
2986 echo "</select></td>";
2987 echo "<td><input type=text size=16 name=access_tab tabindex=102 value=default></td>";
2988 echo "<td><input type=radio name=access_value value=no checked>no <input type=radio name=access_value value=yes>yes</td>";
2989 echo "</tr></form>";
2990 echo "</table><br>\n";
2991 finishPortlet();
2992}
2993
17c32f4c
DO
2994function renderPortMapViewer ()
2995{
2996 renderPortMap (FALSE);
2997}
2998
2999function renderPortMapEditor ()
3000{
3001 renderPortMap (TRUE);
3002}
3003
e673ee24
DO
3004function renderPortMap ($editable = FALSE)
3005{
3006 global $nextorder, $root, $pageno, $tabno;
3007 showMessageOrError();
3008 startPortlet ("Port compatibility map");
3009 $ptlist = getPortTypes();
3010 $pclist = getPortCompat();
3011 $pctable = buildPortCompatMatrixFromList ($ptlist, $pclist);
3012 if ($editable)
3013 {
3014 echo "<form method=post action='${root}process.php'>";
3015 echo "<input type=hidden name=page value='${pageno}'>";
3016 echo "<input type=hidden name=tab value='${tabno}'>";
3017 echo "<input type=hidden name=op value=save>";
3018 }
3019 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
3020 echo "<tr><th class=vert_th>&nbsp;</th>";
3021 foreach ($ptlist as $name2)
3022 echo "<th>to ${name2}</th>";
3023 echo "</tr>";
3024 // Make a copy to have an independent array pointer.
3025 $ptlistY = $ptlist;
3026 $order = 'odd';
3027 foreach ($ptlistY as $type1 => $name1)
3028 {
3029 echo "<tr class=row_${order}><th class=vert_th style='border-bottom: 0px;'>from $name1</th>";
3030 foreach ($ptlist as $type2 => $name2)
3031 {
3032 echo '<td><input type=checkbox' . ($editable ? " name=atom_${type1}_${type2}" : ' disabled');
3033 echo ($pctable[$type1][$type2] ? ' checked' : '') . '></td>';
3034 }
3035 echo "</tr>\n";
3036 $order = $nextorder[$order];
3037 }
3038 echo '</table><br>';
3039 if ($editable)
3040 {
3041 echo "<input type=submit value='Save changes'>";
3042 echo "</form>";
3043 }
3044 finishPortlet();
3045}
3046
3047function renderConfigMainpage ()
3048{
3049 global $pageno, $root;
3050 $children = getDirectChildPages ($pageno);
3051 echo '<ul>';
27ef67da
DO
3052 // FIXME: assume all config kids to have static titles at the moment,
3053 // but use some proper abstract function later.
e673ee24 3054 foreach ($children as $cpageno => $child)
27ef67da 3055 echo "<li><a href='${root}?page=${cpageno}'>" . $child['title'] . "</li>\n";
e673ee24
DO
3056 echo '';
3057 echo '</ul>';
3058}
3059
3060function renderRackPage ($rack_id)
3061{
3062 if ($rack_id == 0)
3063 {
591ff2c4 3064 showError ('Invalid rack_id', __FUNCTION__);
e673ee24
DO
3065 return;
3066 }
3067 if (($rackData = getRackData ($rack_id)) == NULL)
3068 {
591ff2c4 3069 showError ('getRackData() failed', __FUNCTION__);
e673ee24
DO
3070 return;
3071 }
3072 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0><tr>";
3073
3074 // Left column with information.
3075 echo "<td class=pcleft>";
3076 startPortlet ('Rack information');
3077 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
3078 echo "<tr><th width='50%' class=tdright>Rack row:</th><td class=tdleft>${rackData['row_name']}</td></tr>\n";
3079 echo "<tr><th width='50%' class=tdright>Name:</th><td class=tdleft>${rackData['name']}</td></tr>\n";
3080 echo "<tr><th width='50%' class=tdright>Height:</th><td class=tdleft>${rackData['height']}</td></tr>\n";
8a1b387d 3081 echo "<tr><th width='50%' class=tdright>Utilization:</th><td class=tdleft>";
11df133a 3082 renderProgressBar (getRSUforRack ($rackData));
8a1b387d 3083 echo "</td></tr>\n";
f1a0477d
DO
3084 echo "<tr><th width='50%' class=tdright>Objects:</th><td class=tdleft>";
3085 echo getObjectCount ($rackData);
3086 echo "</td></tr>\n";
41bd8c87 3087 printTagTRs();
e673ee24
DO
3088 if (!empty ($rackData['comment']))
3089 echo "<tr><th width='50%' class=tdright>Comment:</th><td class=tdleft>${rackData['comment']}</td></tr>\n";
3090 echo '</table>';
3091 finishPortlet();
3092 echo '</td>';
3093
3094 // Right column with rendered rack.
3095 echo '<td>';
3096 startPortlet ('Rack diagram');
3097 renderRack ($rack_id);
3098 finishPortlet();
3099 echo '</td>';
3100
3101 echo '</tr></table>';
3102}
3103
3104function renderDictionary ()
3105{
3106 global $nextorder;
2dd59b15 3107 $dict = getDict (TRUE);
aa28ebdf 3108 echo "<br><table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
aa28ebdf
DO
3109 foreach ($dict as $chapter_no => $chapter)
3110 {
a22ec5b4 3111 $order = 'odd';
83d2fcca 3112 echo "<tr><th>Chapter</th><th>refs</th><th>Word</th></tr>\n";
aa28ebdf
DO
3113 $wc = count ($chapter['word']);
3114 echo "<tr class=row_${order}><td class=tdleft" . ($wc ? " rowspan = ${wc}" : '');
3115 echo "><div title='number=${chapter_no}'>${chapter['name']} (${wc} records)</div></td>";
3116 if (!$wc)
3117 echo "<td colspan=2>none</td>";
3118 else
e673ee24 3119 {
aa28ebdf
DO
3120 $chap_start = TRUE;
3121 foreach ($chapter['word'] as $key => $value)
3122 {
3123 if (!$chap_start)
3124 echo "<tr class=row_${order}>";
3125 else
3126 $chap_start = FALSE;
6bb8e41d
DO
3127 echo '<td>' . ($chapter['refcnt'][$key] ? $chapter['refcnt'][$key] : '&nbsp;') . '</td>';
3128 echo "<td><div title='key=${key}'>${value}</div></td></tr>\n";
aa28ebdf
DO
3129 $order = $nextorder[$order];
3130 }
e673ee24 3131 }
e673ee24 3132 }
2dd59b15 3133 echo "</table>\n<br>";
e673ee24
DO
3134}
3135
3136function renderDictionaryEditor ()
3137{
f632bd28 3138 global $root, $pageno, $tabno, $nextorder;
e673ee24 3139 $dict = getDict();
95d80773 3140 showMessageOrError();
f632bd28
DO
3141 echo "<br><table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
3142 foreach ($dict as $chapter_no => $chapter)
e673ee24 3143 {
f632bd28 3144 $order = 'odd';
b2f9fa84 3145 echo "<tr><th>Chapter</th><th>&nbsp;</th><th>Word</th><th>&nbsp;</th></tr>\n";
f632bd28
DO
3146 $wc = count ($chapter['word']);
3147 // One extra span for the new record per each chapter block.
3148 echo "<tr class=row_${order}><td class=tdleft" . ($wc ? ' rowspan = ' . ($wc + 1) : '');
3149 echo "><div title='number=${chapter_no}'>${chapter['name']} (${wc} records)</div></td>";
3150 echo "<form action='${root}process.php' method=post>";
3151 echo "<input type=hidden name=page value='${pageno}'>";
3152 echo "<input type=hidden name=tab value='${tabno}'>";
3153 echo "<input type=hidden name=op value=add>";
3154 echo "<input type=hidden name=chapter_no value='${chapter['no']}'>";
3155 echo "<td>&nbsp;</td>";
3156 echo "<td class=tdright><input type=text name=dict_value size=32></td>";
95d80773 3157 echo "<td><input type=submit value='Add new'></td>";
f632bd28 3158 echo '</tr></form>';
b2f9fa84 3159 $order = $nextorder[$order];
e673ee24
DO
3160 foreach ($chapter['word'] as $key => $value)
3161 {
3162 echo "<form action='${root}process.php' method=post>";
3163 echo "<input type=hidden name=page value='${pageno}'>";
3164 echo "<input type=hidden name=tab value='${tabno}'>";
3165 echo "<input type=hidden name=op value='upd'>";
3166 echo "<input type=hidden name=chapter_no value='${chapter['no']}'>";
3167 echo "<input type=hidden name=dict_key value='${key}'>";
95d80773 3168 echo "<tr class=row_${order}><td>";
f632bd28
DO
3169 // Prevent deleting words currently used somewhere.
3170 if ($chapter['refcnt'][$key])
b2f9fa84 3171 printImageHREF ('nodelete', 'referenced ' . $chapter['refcnt'][$key] . ' time(s)');
f632bd28
DO
3172 else
3173 {
3174 echo "<a href='${root}process.php?page=${pageno}&tab=${tabno}&op=del&chapter_no=${chapter['no']}&dict_key=${key}'>";
3175 printImageHREF ('delete', 'Delete word');
3176 echo "</a>";
3177 }
3178 echo '</td>';
e673ee24
DO
3179 echo "<td class=tdright><input type=text name=dict_value size=32 value='${value}'></td>";
3180 echo "<td><input type=submit value=OK></td>";
f632bd28
DO
3181 echo "</tr></form>\n";
3182 $order = $nextorder[$order];
3183 } // foreach ($chapter['word']
3184 } // foreach ($dict
3185 echo "</table>\n";
e673ee24
DO
3186}
3187
3188// We don't allow to rename/delete a sticky chapter and we don't allow
3189// to delete a non-empty chapter.
3190function renderChaptersEditor ()
3191{
3192 global $root, $pageno, $tabno;
3193 showMessageOrError();
3194 $dict = getDict();
3195 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
3196 echo '<tr><th>&nbsp;</th><th>Chapter name</th><th>Words</th><th>&nbsp;</th></tr>';
3197 foreach ($dict as $chapter)
3198 {
3199 $wordcount = count ($chapter['word']);
3200 $sticky = $chapter['sticky'];
3201 echo "<form action='${root}process.php' method=post>";
3202 echo "<input type=hidden name=page value='${pageno}'>";
3203 echo "<input type=hidden name=tab value='${tabno}'>";
3204 echo "<input type=hidden name=op value=upd>";
3205 echo "<input type=hidden name=chapter_no value='${chapter['no']}'>";
3206 echo '<tr>';
3207 echo '<td>';
0c4605ab
DO
3208 if ($sticky)
3209 printImageHREF ('nodelete', 'system chapter');
3210 elseif ($wordcount > 0)
3211 printImageHREF ('nodelete', 'contains ' . $wordcount . ' word(s)');
e673ee24
DO
3212 else
3213 {
3214 echo "<a href='${root}process.php?page=${pageno}&tab=${tabno}&op=del&chapter_no=${chapter['no']}'>";
3215 printImageHREF ('delete', 'Remove chapter');
3216 echo "</a>";
3217 }
3218 echo '</td>';
3219 echo "<td><input type=text name=chapter_name value='${chapter['name']}'" . ($sticky ? ' disabled' : '') . "></td>";
3220 echo "<td class=tdleft>${wordcount}</td><td>";
3221 if ($sticky)
3222 echo '&nbsp;';
3223 else
3224 echo "<input type=submit value='OK'>";
3225 echo '</td></tr>';
3226 echo '</form>';
3227 }
3228 echo "<form action='${root}process.php' method=post>";
3229 echo "<input type=hidden name=page value='${pageno}'>";
3230 echo "<input type=hidden name=tab value='${tabno}'>";
3231 echo "<input type=hidden name=op value=add>";
3232 echo '<tr><td>';
a5ae8c2a 3233 printImageHREF ('add', '', TRUE);
e673ee24
DO
3234 echo "</td><td colspan=3><input type=text name=chapter_name></td>";
3235 echo '</tr>';
3236 echo '</form>';
3237 echo "</table>\n";
3238}
3239
3240function renderAttributes ()
3241{
3242 global $nextorder;
3243 $attrMap = getAttrMap();
3244 startPortlet ('Optional attributes');
3245 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
3246 echo "<tr><th class=tdleft>Attribute name</th><th class=tdleft>Attribute type</th><th class=tdleft>Applies to</th></tr>";
3247 $order = 'odd';
3248 foreach ($attrMap as $attr)
3249 {
3250 echo "<tr class=row_${order}>";
3251 echo "<td class=tdleft>${attr['name']}</td>";
3252 echo "<td class=tdleft>${attr['type']}</td>";
3253 echo '<td class=tdleft>';
3254 if (count ($attr['application']) == 0)
3255 echo '&nbsp;';
3256 else
3257 foreach ($attr['application'] as $app)
3258 if ($attr['type'] == 'dict')
3259 echo "${app['objtype_name']} (values from '${app['chapter_name']}')<br>";
3260 else
3261 echo "${app['objtype_name']}<br>";
3262 echo '</td>';
3263 echo "</tr>\n";
3264 $order = $nextorder[$order];
3265 }
3266 echo "</table><br>\n";
3267 finishPortlet();
3268}
3269
3270function renderEditAttributesForm ()
3271{
3272 global $root, $pageno, $tabno;
3273 $attrMap = getAttrMap();
3274 showMessageOrError();
3275 startPortlet ('Optional attributes');
3276 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
3277 echo '<tr><th>&nbsp;</th><th>Name</th><th>Type</th><th>&nbsp;</th></tr>';
3278 foreach ($attrMap as $attr)
3279 {
3280 echo "<form action='${root}process.php' method=post>";
3281 echo "<input type=hidden name=page value='${pageno}'>";
3282 echo "<input type=hidden name=tab value='${tabno}'>";
3283 echo "<input type=hidden name=op value=upd>";
3284 echo "<input type=hidden name=attr_id value='${attr['id']}'>";
3285 echo '<tr>';
3286 echo "<td><a href='${root}process.php?page=${pageno}&tab=${tabno}&op=del&attr_id=${attr['id']}'>";
3287 printImageHREF ('delete', 'Remove attribute');
3288 echo '</a></td>';
3289 echo "<td><input type=text name=attr_name value='${attr['name']}'></td>";
3290 echo "<td>${attr['type']}</td>";
3291 echo "<td><input type=submit value='OK'></td>";
3292 echo '</tr>';
3293 echo '</form>';
3294 }
3295 echo "<form action='${root}process.php' method=post>";
3296 echo "<input type=hidden name=page value='${pageno}'>";
3297 echo "<input type=hidden name=tab value='${tabno}'>";
3298 echo "<input type=hidden name=op value=add>";
3299 echo '<tr><td>';
a5ae8c2a 3300 printImageHREF ('add', '', TRUE);
e673ee24
DO
3301 echo "</td><td><input type=text name=attr_name></td>";
3302 echo '<td><select name=attr_type>';
3303 echo '<option value=uint>uint</option>';
3304 echo '<option value=float>float</option>';
3305 echo '<option value=string>string</option>';
3306 echo '<option value=dict>dict</option>';
3307 echo '</select></td>';
3308 echo '</tr>';
3309 echo '</form>';
3310 echo "</table>\n";
3311 finishPortlet();
3312}
3313
3314function renderEditAttrMapForm ()
3315{
3316 global $root, $pageno, $tabno;
3317 $attrMap = getAttrMap();
3318 showMessageOrError();
3319 startPortlet ('Attribute map');
3320 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
3321 echo '<tr><th>&nbsp;</th><th>Attribute name</th><th>Object type</th><th>Dictionary chapter</th></tr>';
3322 foreach ($attrMap as $attr)
3323 {
3324 if (count ($attr['application']) == 0)
3325 continue;
3326 foreach ($attr['application'] as $app)
3327 {
3328 echo '<tr>';
3329 echo '<td>';
3330 echo "<a href='${root}process.php?page=${pageno}&tab=${tabno}&op=del&";
3331 echo "attr_id=${attr['id']}&objtype_id=${app['objtype_id']}'>";
3332 printImageHREF ('delete', 'Remove mapping');
3333 echo "</a>";
3334 echo '</td>';
3335 echo "<td>${attr['name']}</td>";
3336 echo "<td>${app['objtype_name']}</td>";
3337 echo "<td>";
3338 if ($attr['type'] == 'dict')
3339 echo "${app['chapter_name']}";
3340 else
3341 echo '&nbsp;';
3342 echo "</td></tr>\n";
3343 }
3344 }
3345 echo "<form action='${root}process.php' method=post>";
3346 echo "<input type=hidden name=page value='${pageno}'>";
3347 echo "<input type=hidden name=tab value='${tabno}'>";
3348 echo "<input type=hidden name=op value=add>";
3349 echo '<tr><td>';
a5ae8c2a 3350 printImageHREF ('add', '', TRUE);
e673ee24
DO
3351 echo "</td><td><select name=attr_id>";
3352 $shortType['uint'] = 'U';
3353 $shortType['float'] = 'F';
3354 $shortType['string'] = 'S';
3355 $shortType['dict'] = 'D';
3356 foreach ($attrMap as $attr)
3357 echo "<option value=${attr['id']}>[" . $shortType[$attr['type']] . "] ${attr['name']}</option>";
3358 echo "</select></td>";
3359 echo '<td>';
3360 printSelect (getObjectTypeList(), 'objtype_id');
3361 echo '</td>';
3362 $dict = getDict();
3363 echo '<td><select name=chapter_no>';
3364 foreach ($dict as $chapter)
3365 if (!$chapter['sticky'])
3366 echo "<option value='${chapter['no']}'>${chapter['name']}</option>";
3367 echo '</select></td>';
3368 echo '</tr>';
3369 echo '</form>';
3370 echo "</table>\n";
3371 finishPortlet();
3372}
3373
a5ae8c2a 3374function printImageHREF ($tag, $title = '', $do_input = FALSE, $tabindex = 0)
e673ee24 3375{
a5ae8c2a
DO
3376 global $root;
3377 $image['error']['path'] = 'pix/error.png';
3378 $image['error']['width'] = 76;
3379 $image['error']['height'] = 17;
a5ae8c2a
DO
3380 $image['logo']['path'] = 'pix/defaultlogo.png';
3381 $image['logo']['width'] = 210;
3382 $image['logo']['height'] = 40;
3383 $image['rackspace']['path'] = 'pix/racks.png';
3384 $image['rackspace']['width'] = 218;
3385 $image['rackspace']['height'] = 200;
3386 $image['objects']['path'] = 'pix/server.png';
3387 $image['objects']['width'] = 218;
3388 $image['objects']['height'] = 200;
3389 $image['ipv4space']['path'] = 'pix/addressspace.png';
3390 $image['ipv4space']['width'] = 218;
3391 $image['ipv4space']['height'] = 200;
f973f491
DO
3392 $image['ipv4slb']['path'] = 'pix/slb.png';
3393 $image['ipv4slb']['width'] = 218;
3394 $image['ipv4slb']['height'] = 200;
a5ae8c2a
DO
3395 $image['config']['path'] = 'pix/configuration.png';
3396 $image['config']['width'] = 218;
3397 $image['config']['height'] = 200;
3398 $image['reports']['path'] = 'pix/report.png';
3399 $image['reports']['width'] = 218;
3400 $image['reports']['height'] = 200;
a5ae8c2a
DO
3401 $image['reserve']['path'] = 'pix/stop.png';
3402 $image['reserve']['width'] = 16;
3403 $image['reserve']['height'] = 16;
3404 $image['useup']['path'] = 'pix/go.png';
3405 $image['useup']['width'] = 16;
3406 $image['useup']['height'] = 16;
3407 $image['blockuser'] = $image['reserve'];
3408 $image['unblockuser'] = $image['useup'];
d48d8820
DO
3409 $image['link']['path'] = 'pix/tango-network-wired.png';
3410 $image['link']['width'] = 16;
3411 $image['link']['height'] = 16;
3412 $image['unlink']['path'] = 'pix/tango-edit-clear.png';
3413 $image['unlink']['width'] = 16;
3414 $image['unlink']['height'] = 16;
77811274 3415 $image['add']['path'] = 'pix/tango-list-add.png';
a5ae8c2a
DO
3416 $image['add']['width'] = 16;
3417 $image['add']['height'] = 16;
d48d8820 3418 $image['delete']['path'] = 'pix/tango-list-remove.png';
a5ae8c2a
DO
3419 $image['delete']['width'] = 16;
3420 $image['delete']['height'] = 16;
0c4605ab
DO
3421 $image['nodelete']['path'] = 'pix/delete_g.png';
3422 $image['nodelete']['width'] = 16;
3423 $image['nodelete']['height'] = 16;
a5ae8c2a
DO
3424 $image['grant'] = $image['add'];
3425 $image['revoke'] = $image['delete'];
d48d8820 3426 $image['inservice']['path'] = 'pix/tango-emblem-system.png';
1f7d18fa
DO
3427 $image['inservice']['width'] = 16;
3428 $image['inservice']['height'] = 16;
d48d8820 3429 $image['notinservice']['path'] = 'pix/tango-dialog-error.png';
1f7d18fa
DO
3430 $image['notinservice']['width'] = 16;
3431 $image['notinservice']['height'] = 16;
77811274 3432 $image['find']['path'] = 'pix/tango-system-search.png';
4de22e7e
DO
3433 $image['find']['width'] = 16;
3434 $image['find']['height'] = 16;
b39e7545
DO
3435 $image['spacer']['path'] = 'pix/pixel.png';
3436 $image['spacer']['width'] = 16;
3437 $image['spacer']['height'] = 16;
9803c56c
DO
3438 $image['next']['path'] = 'pix/tango-go-next.png';
3439 $image['next']['width'] = 32;
3440 $image['next']['height'] = 32;
3441 $image['prev']['path'] = 'pix/tango-go-previous.png';
3442 $image['prev']['width'] = 32;
3443 $image['prev']['height'] = 32;
d48d8820
DO
3444 $image['clear']['path'] = 'pix/tango-edit-clear.png';
3445 $image['clear']['width'] = 16;
3446 $image['clear']['height'] = 16;
e673ee24
DO
3447 if (!isset ($image[$tag]))
3448 $tag = 'error';
3449 $img = $image[$tag];
a5ae8c2a
DO
3450 if ($do_input == TRUE)
3451 echo
3452 "<input type=image name=submit " .
3453 "src='${root}${img['path']}' " .
3454 "border=0 " .
3455 ($tabindex ? '' : "tabindex=${tabindex}") .
3456 ">";
3457 else
3458 echo
3459 "<img " .
3460 "src='${root}${img['path']}' " .
3461 "width=${img['width']} " .
3462 "height=${img['height']} " .
3463 "border=0 " .
3464 (empty ($title) ? '' : "title='${title}'") .
3465 ">";
e673ee24
DO
3466}
3467
3468// This function returns URL for favourite icon.
3469function getFaviconURL ()
3470{
46100c70
DO
3471 global $root;
3472 return $root . 'pix/racktables.ico';
e673ee24
DO
3473}
3474
3475function renderReportSummary ()
3476{
da95280e
DO
3477 echo "<table width='100%'>\n";
3478 echo "<tr><td class=pcleft>\n";
08b4cb24 3479 startPortlet ("Dictionary/objects stats");
da95280e
DO
3480 echo "<table>\n";
3481 foreach (getDictStats() as $header => $data)
7e233246 3482 echo "<tr><th class=tdright>${header}:</th><td class=tdleft>${data}</td></tr>\n";
8948cd63
DO
3483 echo "</table>\n";
3484 finishPortlet();
3485 startPortlet ('IPv4 stats');
3486 echo "<table>\n";
3487 foreach (getIPv4Stats() as $header => $data)
3488 echo "<tr><th class=tdright>${header}:</th><td class=tdleft>${data}</td></tr>\n";
3489 echo "</table>\n";
3490 finishPortlet();
3491 startPortlet ('Rackspace stats');
3492 echo "<table>\n";
3493 foreach (getRackspaceStats() as $header => $data)
3494 echo "<tr><th class=tdright>${header}:</th><td class=tdleft>${data}</td></tr>\n";
da95280e
DO
3495 echo "</table>\n";
3496 finishPortlet();
3497
3498 echo "</td><td class=pcright>\n";
3499
c461c579
DO
3500 startPortlet ("Here be dragons");
3501 dragon();
3502 dragon();
3503 dragon();
3504 echo 'ASCII art &copy; Daniel C. Au';
3505 finishPortlet();
da95280e
DO
3506 echo "</td></tr>\n";
3507 echo "</table>\n";
c461c579
DO
3508}
3509
3510function dragon ()
3511{
3512?>
3513<div class=dragon><pre><font color="#00ff33">
3514 \||/
3515 | <font color="#ff0000">@</font>___oo
3516 /\ /\ / (__<font color=yellow>,,,,</font>|
3517 ) /^\) ^\/ _)
3518 ) /^\/ _)
3519 ) _ / / _)
3520 /\ )/\/ || | )_)
3521 &lt; &gt; |(<font color=white>,,</font>) )__)
3522 || / \)___)\
3523 | \____( )___) )___
3524 \______(_______<font color=white>;;;</font> __<font color=white>;;;</font>
3525
3526</font></pre></div>
3527<?php
e673ee24
DO
3528}
3529
3530function renderUIConfig ()
3531{
4fe32e78
DY
3532 global $configCache, $nextorder;
3533 showMessageOrError();
0a1b1268 3534 startPortlet ('Current configuration');
c461c579
DO
3535 echo '<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center width="50%">';
3536 echo '<tr><th class=tdleft>Option</th><th class=tdleft>Value</th></tr>';
4fe32e78 3537 $order = 'odd';
0a1b1268 3538 foreach ($configCache as $v)
4fe32e78 3539 {
c461c579
DO
3540 if ($v['is_hidden'] != 'no')
3541 continue;
3542 echo "<tr class=row_${order}>";
3543 echo "<td class=tdright>${v['description']}</td>\n";
3544 echo "<td class=tdleft>${v['varvalue']}</td></tr>";
3545 $order = $nextorder[$order];
4fe32e78 3546 }
0a1b1268
DO
3547 echo "</table>\n";
3548 finishPortlet();
7865c525
DO
3549}
3550
4fe32e78
DY
3551function renderUIConfigEditForm ()
3552{
c461c579 3553 global $root, $pageno, $tabno, $configCache;
4fe32e78
DY
3554 showMessageOrError();
3555 startPortlet ('Current configuration');
c461c579
DO
3556 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable width='50%'>\n";
3557 echo "<tr><th class=tdleft>Option</th>";
3558 echo "<th class=tdleft>Value</th></tr>";
4fe32e78
DY
3559 echo "<form action='${root}process.php'>";
3560 echo "<input type=hidden name=op value='upd'>";
c461c579
DO
3561 echo "<input type=hidden name=page value='${pageno}'>\n";
3562 echo "<input type=hidden name=tab value='${tabno}'>\n";
4fe32e78
DY
3563
3564 $i = 0;
3565 foreach ($configCache as $v)
3566 {
c461c579
DO
3567 if ($v['is_hidden'] != 'no')
3568 continue;
3569 echo "<input type=hidden name=${i}_varname value='${v['varname']}'>";
3570 echo "<tr><td class=tdright>${v['description']}</td>";
3571 echo "<td class=tdleft><input type=text name=${i}_varvalue value='${v['varvalue']}' size=24></td>";
3572 echo "</tr>\n";
3573 $i++;
4fe32e78
DY
3574 }
3575 echo "<input type=hidden name=num_vars value=${i}>\n";
c461c579 3576 echo "<tr><td colspan=2><input type=submit value='Save changes'></td></tr>";
4fe32e78
DY
3577 echo "</form>";
3578 finishPortlet();
3579}
3580
7865c525
DO
3581// This function queries the gateway about current VLAN configuration and
3582// renders a form suitable for submit. Ah, and it does submit processing as well.
111b4a67
DO
3583function renderVLANMembership ($object_id = 0)
3584{
fc8d0004 3585 global $root, $pageno, $tabno, $remote_username;
111b4a67
DO
3586 if ($object_id <= 0)
3587 {
591ff2c4 3588 showError ('Invalid object_id', __FUNCTION__);
111b4a67
DO
3589 return;
3590 }
7865c525
DO
3591
3592 // Handle probable pending submit.
3593 if (isset ($_REQUEST['portcount']))
111b4a67 3594 {
7865c525
DO
3595 $data = getSwitchVLANs ($object_id);
3596 if ($data === NULL)
2da7c9b0 3597 {
591ff2c4 3598 showError ('getSwitchVLANs() failed during submit processing', __FUNCTION__);
fc8d0004
DO
3599 return;
3600 }
7865c525
DO
3601 list ($vlanlist, $portlist) = $data;
3602 // Here we just build up 1 set command for the gateway with all of the ports
3603 // included. The gateway is expected to filter unnecessary changes silently
3604 // and to provide a list of responses with either error or success message
3605 // for each of the rest.
2c6c7645 3606 assertUIntArg ('portcount', __FUNCTION__);
7865c525
DO
3607 $nports = $_REQUEST['portcount'];
3608 $prefix = 'set ';
3609 $log = array();
3610 $setcmd = '';
3611 for ($i = 0; $i < $nports; $i++)
3612 if
3613 (
3614 !isset ($_REQUEST['portname_' . $i]) ||
3615 !isset ($_REQUEST['vlanid_' . $i]) ||
3616 $_REQUEST['portname_' . $i] != $portlist[$i]['portname']
3617 )
cd40a2a0 3618 $log[] = array ('code' => 'error', 'message' => "Ignoring malformed record #${i} in form submit");
7865c525
DO
3619 elseif
3620 (
3621 $_REQUEST['vlanid_' . $i] == $portlist[$i]['vlanid'] ||
3622 $portlist[$i]['vlaind'] == 'TRUNK'
3623 )
3624 continue;
3625 else
3626 {
3627 $setcmd .= $prefix . $_REQUEST['portname_' . $i] . '=' . $_REQUEST['vlanid_' . $i];
3628 $prefix = ';';
3629 }
3630 printLog ($log);
3631 // Feed the gateway and interpret its (non)response.
3632 if ($setcmd != '')
3633 printLog (setSwitchVLANs ($object_id, $setcmd));
3634 }
3635
3636 // Reload and render.
3637 $data = getSwitchVLANs ($object_id);
3638 if ($data === NULL)
3639 return;
18cb9495 3640 list ($vlanlist, $portlist, $maclist) = $data;
d28ea105 3641
a684aa6f 3642 echo '<table border=0 width="100%"><tr><td colspan