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