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