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