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