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