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