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