r1199 + updated comment on the protocol
[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();
7f791d1d 2015 $global_type_id = 0;
e673ee24
DO
2016 $name = array();
2017 $asset_no = array();
2018 $keepvalues = FALSE;
7f791d1d 2019 $log = array();
e673ee24 2020 // Look for current submit.
7f791d1d 2021 if (isset ($_REQUEST['got_fast_data']))
e673ee24
DO
2022 {
2023 $keepvalues = TRUE;
e673ee24
DO
2024 for ($i=0; $i < MASSCOUNT; $i++)
2025 {
2026 if (!isset ($_REQUEST["${i}_object_type_id"]))
2027 {
2028 $log[] = array ('code' => 'error', 'message' => "Submitted form is invalid at line " . $i + 1);
2029 break;
2030 }
2031 assertUIntArg ("${i}_object_type_id", TRUE);
2032 assertStringArg ("${i}_object_name", TRUE);
2033 assertStringArg ("${i}_object_label", TRUE);
2034 assertStringArg ("${i}_object_asset_no", TRUE);
2035 assertStringArg ("${i}_object_barcode", TRUE);
2036 $type_id[$i] = $_REQUEST["${i}_object_type_id"];
2037 // Save user input for possible rendering.
2038 $name[$i] = $_REQUEST["${i}_object_name"];
2039 $label[$i] = $_REQUEST["${i}_object_label"];
2040 $asset_no[$i] = $_REQUEST["${i}_object_asset_no"];
2041 $barcode[$i] = $_REQUEST["${i}_object_barcode"];
2042
2043 // It's better to skip silently than printing a notice.
2044 if ($type_id[$i] == 0)
2045 continue;
2046 if (commitAddObject ($name[$i], $label[$i], $barcode[$i], $type_id[$i], $asset_no[$i]) === TRUE)
2047 $log[] = array ('code' => 'success', 'message' => "Added new object '${name[$i]}'");
2048 else
2049 $log[] = array ('code' => 'error', 'message' => 'commitAddObject() failed in renderAddMultipleObjectsForm()');
2050 }
e673ee24 2051 }
7f791d1d
DO
2052 elseif (isset ($_REQUEST['got_very_fast_data']))
2053 {
2054 $keepvalues = TRUE;
2055 assertUIntArg ('global_type_id', TRUE);
2056 assertStringArg ('namelist', TRUE);
2057 $global_type_id = $_REQUEST['global_type_id'];
2058 if ($global_type_id == 0)
2059 {
2060 if (!empty ($_REQUEST['namelist']))
2061 $log[] = array ('code' => 'error', 'message' => 'Object type is not selected, check the form below');
2062 else
2063 $log[] = array ('code' => 'error', 'message' => 'Empty form has been ignored. Cheers.');
2064 }
2065 else
2066 {
2067 // The name extractor below was stolen from ophandlers.php:addMultiPorts()
2068 $names1 = explode ('\n', $_REQUEST['namelist']);
2069 $names2 = array();
2070 foreach ($names1 as $line)
2071 {
2072 $parts = explode ('\r', $line);
2073 reset ($parts);
2074 if (empty ($parts[0]))
2075 continue;
2076 else
2077 $names2[] = rtrim ($parts[0]);
2078 }
2079 foreach ($names2 as $cname)
2080 if (commitAddObject ($cname, '', '', $global_type_id, '') === TRUE)
2081 $log[] = array ('code' => 'success', 'message' => "Added new object '${cname}'");
2082 else
2083 $log[] = array ('code' => 'error', 'message' => "Could not add '${cname}'");
2084 }
2085 }
2086 printLog ($log);
e673ee24
DO
2087
2088 // Render a form for the next.
2089 $typelist = getObjectTypeList();
2090 $typelist[0]['dict_key'] = 0;
7f791d1d
DO
2091 $typelist[0]['dict_value'] = 'select type...';
2092
2093 startPortlet ('Fast way');
e673ee24
DO
2094 echo '<form>';
2095 echo "<input type=hidden name=page value=${pageno}>";
2096 echo "<input type=hidden name=tab value=${tabno}>";
2097 echo '<table border=0 align=center>';
2098 echo "<tr><th>Object type</th><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>Barcode</th></tr>\n";
7f791d1d 2099 // If a user forgot to select object type on input, we keep his
e673ee24 2100 // previous input in the form.
e673ee24
DO
2101 for ($i = 0; $i < MASSCOUNT; $i++)
2102 {
7f791d1d 2103 echo '<tr><td>';
e673ee24
DO
2104 printSelect ($typelist, "${i}_object_type_id", 0);
2105 echo '</td>';
2106 echo "<td><input type=text size=30 name=${i}_object_name";
2107 if ($keepvalues and $type_id[$i] == 0)
2108 echo " value='${name[$i]}'";
2109 echo "></td>";
2110 echo "<td><input type=text size=30 name=${i}_object_label";
2111 if ($keepvalues and $type_id[$i] == 0)
2112 echo " value='${label[$i]}'";
2113 echo "></td>";
2114 echo "<td><input type=text size=20 name=${i}_object_asset_no";
2115 if ($keepvalues and $type_id[$i] == 0)
2116 echo " value='${asset_no[$i]}'";
2117 echo "></td>";
2118 echo "<td><input type=text size=10 name=${i}_object_barcode";
2119 if ($keepvalues and $type_id[$i] == 0)
2120 echo " value='${barcode[$i]}'";
2121 echo "></td>";
2122 echo "</tr>\n";
e673ee24 2123 }
7f791d1d 2124 echo "<tr><td class=submit colspan=5><input type=submit name=got_fast_data value='Create'></td></tr>\n";
e673ee24
DO
2125 echo "</form></table>\n";
2126 finishPortlet();
7f791d1d
DO
2127
2128 startPortlet ('Very fast way');
2129 echo '<form>';
2130 echo "<input type=hidden name=page value=${pageno}>";
2131 echo "<input type=hidden name=tab value=${tabno}>";
2132 echo 'For each line shown below create an object of type ';
2133 printSelect ($typelist, "global_type_id", 0);
2134 echo " <input type=submit name=got_very_fast_data value='Go!'><br>\n";
2135 echo "<textarea name=namelist cols=40 rows=25>\n";
2136 if ($keepvalues and $global_type_id == 0)
2137 echo $_REQUEST['namelist'];
2138 echo "</textarea></form>\n";
2139 finishPortlet();
e673ee24
DO
2140}
2141
2142function printGreeting ()
2143{
2144 global $remote_username, $accounts;
2145 $account = $accounts[$remote_username];
37a61537 2146 echo "Hello, ${account['user_realname']}. This is RackTables " . VERSION . ". Click <a href=logout.php>here</a> to logout.";
e673ee24
DO
2147}
2148
2149function renderSearchResults ()
2150{
2151 global $remote_username, $root;
2152 $terms = trim ($_REQUEST['q']);
2153 if (empty ($terms))
2154 {
2155 showError ('Search string cannot be empty.');
2156 return;
2157 }
2158 if (!authorized ($remote_username, 'object', 'default'))
2159 {
2160 showError ('You are not authorized for viewing information about objects.');
2161 return;
2162 }
2163 // If we search for L2 address, we can either find one or find none.
2164 if
2165 (
2166 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
2167 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
2168 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)
2169 )
2170 // Search for L2 address.
2171 {
2172 $result = searchByl2address ($terms);
2173 if ($result !== NULL)
2174 {
2175 echo "<script language='Javascript'>document.location='${root}?page=object";
2176 echo "&hl_port_id=${result['port_id']}";
2177 echo "&object_id=${result['object_id']}';//</script>";
2178 }
2179 else
2180 echo "L2 address '${terms}' not found!";
2181 }
2182 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))
2183 // STP bridge ID: bridge priotity + port MAC address. Cut off first 4 chars and look for MAC address.
2184 {
2185 $terms = substr ($terms, 4);
2186 $result = searchByl2address ($terms);
2187 if ($result !== NULL)
2188 {
2189 echo "<script language='Javascript'>document.location='${root}?page=object";
2190 echo "&hl_port_id=${result['port_id']}";
2191 echo "&object_id=${result['object_id']}';//</script>";
2192 }
2193 else
2194 echo "L2 address '${terms}' not found!";
2195 }
2196 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))
2197 // Search for IP address.
2198 {
2199 $result = getRangeByIp ($terms);
2200 if ($result !== NULL)
2201 {
2202 echo "<script language='Javascript'>document.location='${root}?page=ipaddress";
2203 echo "&ip=${terms}";
2204 echo "';//</script>";
2205 }
2206 else
2207 echo "IP address '${terms}' not found!";
2208 return;
2209 }
2210 else
2211 // Search for objects.
2212 {
2213 $objects = getSearchResults ($terms);
2214 if (count ($objects) == 1)
2215 {
2216 $obj = current ($objects);
2217 echo "<script language='Javascript'>document.location='${root}?page=object&object_id=${obj['id']}';//</script>";
2218 }
2219 elseif (count ($objects) > 1)
2220 {
2221 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
2222 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>barcode</th></tr>';
2223 $order = 'odd';
2224 global $nextorder;
2225 foreach ($objects as $obj)
2226 {
2227 echo "<tr class=row_${order}><td><a href=\"${root}?page=object&object_id=${obj['id']}\">${obj['dname']}</a></td>";
2228 echo "<td>${obj['label']}</td>";
2229 echo "<td>${obj['asset_no']}</td>";
2230 echo "<td>${obj['barcode']}</td></tr>";
2231 $order = $nextorder[$order];
2232 }
2233 echo '</table>';
2234 }
2235 else
2236 echo "Object '${terms}' not found!";
2237 }
2238}
2239
2240// This function prints a table of checkboxes to aid the user in toggling mount atoms
2241// from one state to another. The first argument is rack data as
2242// produced by getRackData(), the second is the value used for the 'unckecked' state
2243// and the third is the value used for 'checked' state.
2244// Usage contexts:
2245// for mounting an object: printAtomGrid ($data, 'F', 'T')
2246// for changing rack design: printAtomGrid ($data, 'A', 'F')
2247// for adding rack problem: printAtomGrid ($data, 'F', 'U')
2248// for adding object problem: printAtomGrid ($data, 'T', 'W')
2249
2250function renderAtomGrid ($data)
2251{
2252 $rack_id = $data['id'];
2253 for ($unit_no = $data['height']; $unit_no > 0; $unit_no--)
2254 {
2255 echo "<tr><th>${unit_no}</th>";
2256 for ($locidx = 0; $locidx < 3; $locidx++)
2257 {
2258 $state = $data[$unit_no][$locidx]['state'];
2259 echo "<td class=state_${state}";
2260 if (isset ($data[$unit_no][$locidx]['hl']))
2261 echo $data[$unit_no][$locidx]['hl'];
2262 echo ">";
2263 if (!($data[$unit_no][$locidx]['enabled'] === TRUE))
2264 echo '<input type=checkbox disabled>';
2265 else
2266 echo "<input type=checkbox" . $data[$unit_no][$locidx]['checked'] . " name=atom_${rack_id}_${unit_no}_${locidx}>";
2267 echo '</td>';
2268 }
2269 echo "</tr>\n";
2270 }
2271}
2272
2273function renderPermissions ()
2274{
2275 startPortlet ('User permissions');
2276 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
2277 echo "<tr><th>Username</th><th>Page</th><th>Tab</th><th>Access</th></tr>";
2278 global $perms, $nextorder;
2279 $order = 'odd';
2280 foreach ($perms as $username => $pages)
2281 foreach ($pages as $page => $tabs)
2282 foreach ($tabs as $tab => $access)
2283 {
2284 echo "<tr class=row_${order}><td class=tdleft>$username</td><td>$page</td><td>$tab</td><td>$access</td></tr>\n";
2285 $order = $nextorder[$order];
2286 }
2287 echo "</table>\n";
2288 finishPortlet();
2289}
2290
2291function renderAccounts ()
2292{
2293 global $nextorder, $accounts;
2294 startPortlet ('User accounts');
2295 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
2296 echo "<tr><th class=tdleft>Username</th><th class=tdleft>Real name</th></tr>";
2297 $order = 'odd';
2298 foreach ($accounts as $user)
2299 {
2300 echo "<tr class=row_${order}><td class=tdleft>${user['user_name']}</td><td class=tdleft>${user['user_realname']}</td></li>";
2301 $order = $nextorder[$order];
2302 }
2303 echo '</table>';
2304 finishPortlet();
2305}
2306
2307function renderAccountsEditForm ()
2308{
2309 global $root, $pageno, $tabno, $accounts;
2310 startPortlet ('User accounts');
2311 showMessageOrError();
2312 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
2313 echo "<tr><th>op</th><th>Username</th><th>Real name</th><th>Password</th><th>&nbsp;</th></tr>\n";
2314 foreach ($accounts as $account)
2315 {
2316 echo "<form action='${root}process.php'>";
2317 echo "<input type=hidden name=op value=updateAccount>";
2318 echo "<input type=hidden name=page value='${pageno}'>\n";
2319 echo "<input type=hidden name=tab value='${tabno}'>\n";
2320 echo "<input type=hidden name=id value='${account['user_id']}'><tr>";
2321 echo "<td>";
2322 if ($account['user_enabled'] == 'yes' && $account['user_id'] != 1)
2323 {
2324 echo "<a href='${root}process.php?op=disableAccount&page=${pageno}&tab=${tabno}&id=${account['user_id']}'>";
2325 printImageHREF ('blockuser', 'disable account');
2326 echo "</a>\n";
2327 }
2328 if ($account['user_enabled'] == 'no' && $account['user_id'] != 1)
2329 {
2330 echo "<a href='${root}process.php?op=enableAccount&page=${pageno}&tab=${tabno}&id=${account['user_id']}'>";
2331 printImageHREF ('unblockuser', 'enable account');
2332 echo "</a>\n";
2333 }
2334 // Otherwise skip icon.
2335 echo "</td>";
2336 echo "<td><input type=text name=username value='${account['user_name']}' size=16></td>";
2337 echo "<td><input type=text name=realname value='${account['user_realname']}' size=24></td>";
2338 echo "<td><input type=password name=password value='${account['user_password_hash']}' size=64></td>";
2339 echo "<td><input type='submit' value='OK'></td>";
2340 echo "</form></tr>\n";
2341 }
2342 echo "<form action='${root}process.php' method=post><tr>";
2343 echo "<input type=hidden name=op value=createAccount>\n";
2344 echo "<input type=hidden name=page value='${pageno}'>\n";
2345 echo "<input type=hidden name=tab value='${tabno}'>\n";
2346 echo "<td colspan=2><input type=text size=16 name=username tabindex=100></td>\n";
2347 echo "<td><input type=text size=24 name=realname tabindex=101></td>";
2348 echo "<td><input type=password size=64 name=password tabindex=102></td>";
2349 echo "<td colspan=4><input type=submit value='Create account' tabindex=103></td></tr></form>";
2350 echo "</table><br>\n";
2351 finishPortlet();
2352}
2353
2354function printChildrenAsOptions ($root, $depth = 0)
2355{
2356 echo "<option value=${root['title']}>";
2357 if ($depth == 0)
2358 echo '* ';
2359 for ($i = 0; $i < $depth; $i++)
2360 echo '-- ';
2361 echo $root['title'];
2362 echo "</option>\n";
2363 foreach ($root['kids'] as $kid)
2364 printChildrenAsOptions ($kid, $depth + 1);
2365}
2366
2367// 1. Find all parentless pages.
2368// 2. For each of them recursively find all children.
2369// 3. Output the tree with recursion tree display.
2370function printPagesTree ()
2371{
2372 global $page;
2373 echo '<pre>';
2374 foreach ($page as $ctitle => $cpage)
2375 if (!isset ($cpage['parent']))
2376 {
2377 $croot['title'] = $ctitle;
2378 $croot['kids'] = getAllChildPages ($ctitle);
2379 printChildrenAsOptions ($croot);
2380 }
2381 echo '</pre>';
2382}
2383
2384function renderPermissionsEditForm ()
2385{
2386 global $root, $pageno, $tabno, $perms, $accounts;
2387 startPortlet ('User permissions');
2388 showMessageOrError();
2389 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
2390 echo "<tr><th>&nbsp;</th><th>Username</th><th>Page</th><th>Tab</th><th>Access</th></tr>\n";
2391 foreach ($perms as $username => $pages)
2392 foreach ($pages as $access_page => $tabs)
2393 foreach ($tabs as $access_tab => $access)
2394 {
2395 echo "<td>";
2396 if ($username != '%')
2397 $userid = $accounts[$username]['user_id'];
2398 else
2399 $userid = 0;
2400 echo "<a href='${root}process.php?op=revoke&page=${pageno}&tab=${tabno}&access_userid=${userid}&access_page=${access_page}&access_tab=${access_tab}'>";
2401 printImageHREF ('revoke', 'Revoke permission');
2402 echo "</a></td>";
2403 echo "<td>${username}</td>";
2404 echo "<td>${access_page}</td>";
2405 echo "<td>${access_tab}</td>";
2406 echo "<td>${access}</td>";
2407 echo "</tr>\n";
2408 }
2409 echo "<form action='${root}process.php' method=post><tr>";
2410 echo "<input type=hidden name=op value=grant>\n";
2411 echo "<input type=hidden name=page value='${pageno}'>\n";
2412 echo "<input type=hidden name=tab value='${tabno}'>\n";
2413 // FIXME: border=0 doesn't work here for unknown reason
2414 echo "<td>";
a5ae8c2a 2415 printImageHREF ('grant', '', TRUE, 103);
e673ee24
DO
2416 echo "</td>";
2417 echo "<td><select name=access_userid>";
2418 echo "<option value=0>ANY</option>";
2419 foreach ($accounts as $account)
2420 echo "<option value=${account['user_id']}>${account['user_name']}</option>";
2421 echo "</select></td>\n";
2422 echo "<td><select name=access_page>";
2423 echo "<option value='%'>ANY</option>";
2424 printPagesTree();
2425 echo "</select></td>";
2426 echo "<td><input type=text size=16 name=access_tab tabindex=102 value=default></td>";
2427 echo "<td><input type=radio name=access_value value=no checked>no <input type=radio name=access_value value=yes>yes</td>";
2428 echo "</tr></form>";
2429 echo "</table><br>\n";
2430 finishPortlet();
2431}
2432
2433function renderReadonlyParameters ()
2434{
2435 global $color, $default_port_type;
2436 startPortlet ('config.php');
2437 echo '<table border=0 align=center>';
2438 echo "<tr><th class=tdright>version:</th><td class=tdleft>" . VERSION . "</td></tr>\n";
2439 echo "<tr><th class=tdright>password hash:</th><td class=tdleft>" . PASSWORD_HASH . "</td></tr>\n";
2440 echo "<tr><th class=tdright>default port type:</th><td class=tdleft>${default_port_type}</td></tr>\n";
2441 foreach ($color as $class => $value)
2442 echo "<tr><th class=tdright bgcolor='#${value}'>color for class ${class}</th><td class=tdleft>${value}</td></tr>\n";
2443 echo "</table>\n";
2444 finishPortlet();
2445}
2446
2447function renderPortMap ($editable = FALSE)
2448{
2449 global $nextorder, $root, $pageno, $tabno;
2450 showMessageOrError();
2451 startPortlet ("Port compatibility map");
2452 $ptlist = getPortTypes();
2453 $pclist = getPortCompat();
2454 $pctable = buildPortCompatMatrixFromList ($ptlist, $pclist);
2455 if ($editable)
2456 {
2457 echo "<form method=post action='${root}process.php'>";
2458 echo "<input type=hidden name=page value='${pageno}'>";
2459 echo "<input type=hidden name=tab value='${tabno}'>";
2460 echo "<input type=hidden name=op value=save>";
2461 }
2462 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
2463 echo "<tr><th class=vert_th>&nbsp;</th>";
2464 foreach ($ptlist as $name2)
2465 echo "<th>to ${name2}</th>";
2466 echo "</tr>";
2467 // Make a copy to have an independent array pointer.
2468 $ptlistY = $ptlist;
2469 $order = 'odd';
2470 foreach ($ptlistY as $type1 => $name1)
2471 {
2472 echo "<tr class=row_${order}><th class=vert_th style='border-bottom: 0px;'>from $name1</th>";
2473 foreach ($ptlist as $type2 => $name2)
2474 {
2475 echo '<td><input type=checkbox' . ($editable ? " name=atom_${type1}_${type2}" : ' disabled');
2476 echo ($pctable[$type1][$type2] ? ' checked' : '') . '></td>';
2477 }
2478 echo "</tr>\n";
2479 $order = $nextorder[$order];
2480 }
2481 echo '</table><br>';
2482 if ($editable)
2483 {
2484 echo "<input type=submit value='Save changes'>";
2485 echo "</form>";
2486 }
2487 finishPortlet();
2488}
2489
2490function renderConfigMainpage ()
2491{
2492 global $pageno, $root;
2493 $children = getDirectChildPages ($pageno);
2494 echo '<ul>';
2495 foreach ($children as $cpageno => $child)
2496 {
2497 $ctitle = $child['title']($cpageno);
2498 echo "<li><a href='${root}?page=${cpageno}'>" . $ctitle['name'] . "</li>\n";
2499 }
2500 echo '';
2501 echo '</ul>';
2502}
2503
2504function renderRackPage ($rack_id)
2505{
2506 if ($rack_id == 0)
2507 {
2508 showError ('Invalid rack_id in renderRack()');
2509 return;
2510 }
2511 if (($rackData = getRackData ($rack_id)) == NULL)
2512 {
2513 showError ('getRackData() failed in renderRack()');
2514 return;
2515 }
2516 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0><tr>";
2517
2518 // Left column with information.
2519 echo "<td class=pcleft>";
2520 startPortlet ('Rack information');
2521 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
2522 echo "<tr><th width='50%' class=tdright>Rack row:</th><td class=tdleft>${rackData['row_name']}</td></tr>\n";
2523 echo "<tr><th width='50%' class=tdright>Name:</th><td class=tdleft>${rackData['name']}</td></tr>\n";
2524 echo "<tr><th width='50%' class=tdright>Height:</th><td class=tdleft>${rackData['height']}</td></tr>\n";
2525 if (!empty ($rackData['comment']))
2526 echo "<tr><th width='50%' class=tdright>Comment:</th><td class=tdleft>${rackData['comment']}</td></tr>\n";
2527 echo '</table>';
2528 finishPortlet();
2529 echo '</td>';
2530
2531 // Right column with rendered rack.
2532 echo '<td>';
2533 startPortlet ('Rack diagram');
2534 renderRack ($rack_id);
2535 finishPortlet();
2536 echo '</td>';
2537
2538 echo '</tr></table>';
2539}
2540
2541function renderDictionary ()
2542{
2543 global $nextorder;
2544 $dict = getDict();
2545 echo "<table border=0><tr>";
2546 foreach ($dict as $chapter)
2547 {
2548 echo "<td class=pcleft>";
2549 startPortlet ($chapter['name'] . ' (' . count ($chapter['word']) . ')');
2550 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
2551 $order = 'odd';
cfadde04 2552 foreach ($chapter['word'] as $key => $value)
e673ee24 2553 {
cfadde04 2554 echo "<tr class=row_${order}><td class=tdleft><div title='key=${key}'>${value}</div></td></tr>";
e673ee24
DO
2555 $order = $nextorder[$order];
2556 }
2557 echo "</table>";
2558 finishPortlet();
2559 echo "</td>";
2560 }
2561 echo "</tr></table>";
2562}
2563
2564function renderDictionaryEditor ()
2565{
2566 global $root, $pageno, $tabno;
2567 showMessageOrError();
2568 $dict = getDict();
2569 echo "<table border=0><tr>";
2570 foreach ($dict as $chapter)
2571 {
2572 echo "<td class=pcleft>";
2573 startPortlet ($chapter['name'] . ' (' . count ($chapter['word']) . ')');
2574 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
2575 foreach ($chapter['word'] as $key => $value)
2576 {
2577 echo "<form action='${root}process.php' method=post>";
2578 echo "<input type=hidden name=page value='${pageno}'>";
2579 echo "<input type=hidden name=tab value='${tabno}'>";
2580 echo "<input type=hidden name=op value='upd'>";
2581 echo "<input type=hidden name=chapter_no value='${chapter['no']}'>";
2582 echo "<input type=hidden name=dict_key value='${key}'>";
2583 echo '<tr>';
2584 echo "<td><a href='${root}process.php?page=${pageno}&tab=${tabno}&op=del&chapter_no=${chapter['no']}&dict_key=${key}'>";
2585 printImageHREF ('delete', 'Delete word');
2586 echo "</a></td>";
2587 echo "<td class=tdright><input type=text name=dict_value size=32 value='${value}'></td>";
2588 echo "<td><input type=submit value=OK></td>";
2589 echo '</tr></form>';
2590 }
2591 echo "<form action='${root}process.php' method=post>";
2592 echo "<input type=hidden name=page value='${pageno}'>";
2593 echo "<input type=hidden name=tab value='${tabno}'>";
2594 echo "<input type=hidden name=op value=add>";
2595 echo "<input type=hidden name=chapter_no value='${chapter['no']}'>";
2596 echo '<tr>';
2597 echo "<td>&nbsp;</td>";
2598 echo "<td class=tdright><input type=text name=dict_value size=32></td>";
2599 echo "<td><input type=submit value=OK></td>";
2600 echo '</tr></form>';
2601 echo "</table>";
2602 finishPortlet();
2603 echo "</td>";
2604 }
2605 echo "</tr></table>";
2606}
2607
2608// We don't allow to rename/delete a sticky chapter and we don't allow
2609// to delete a non-empty chapter.
2610function renderChaptersEditor ()
2611{
2612 global $root, $pageno, $tabno;
2613 showMessageOrError();
2614 $dict = getDict();
2615 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
2616 echo '<tr><th>&nbsp;</th><th>Chapter name</th><th>Words</th><th>&nbsp;</th></tr>';
2617 foreach ($dict as $chapter)
2618 {
2619 $wordcount = count ($chapter['word']);
2620 $sticky = $chapter['sticky'];
2621 echo "<form action='${root}process.php' method=post>";
2622 echo "<input type=hidden name=page value='${pageno}'>";
2623 echo "<input type=hidden name=tab value='${tabno}'>";
2624 echo "<input type=hidden name=op value=upd>";
2625 echo "<input type=hidden name=chapter_no value='${chapter['no']}'>";
2626 echo '<tr>';
2627 echo '<td>';
2628 if ($sticky or $wordcount > 0)
2629 echo '&nbsp;';
2630 else
2631 {
2632 echo "<a href='${root}process.php?page=${pageno}&tab=${tabno}&op=del&chapter_no=${chapter['no']}'>";
2633 printImageHREF ('delete', 'Remove chapter');
2634 echo "</a>";
2635 }
2636 echo '</td>';
2637 echo "<td><input type=text name=chapter_name value='${chapter['name']}'" . ($sticky ? ' disabled' : '') . "></td>";
2638 echo "<td class=tdleft>${wordcount}</td><td>";
2639 if ($sticky)
2640 echo '&nbsp;';
2641 else
2642 echo "<input type=submit value='OK'>";
2643 echo '</td></tr>';
2644 echo '</form>';
2645 }
2646 echo "<form action='${root}process.php' method=post>";
2647 echo "<input type=hidden name=page value='${pageno}'>";
2648 echo "<input type=hidden name=tab value='${tabno}'>";
2649 echo "<input type=hidden name=op value=add>";
2650 echo '<tr><td>';
a5ae8c2a 2651 printImageHREF ('add', '', TRUE);
e673ee24
DO
2652 echo "</td><td colspan=3><input type=text name=chapter_name></td>";
2653 echo '</tr>';
2654 echo '</form>';
2655 echo "</table>\n";
2656}
2657
2658function renderAttributes ()
2659{
2660 global $nextorder;
2661 $attrMap = getAttrMap();
2662 startPortlet ('Optional attributes');
2663 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
2664 echo "<tr><th class=tdleft>Attribute name</th><th class=tdleft>Attribute type</th><th class=tdleft>Applies to</th></tr>";
2665 $order = 'odd';
2666 foreach ($attrMap as $attr)
2667 {
2668 echo "<tr class=row_${order}>";
2669 echo "<td class=tdleft>${attr['name']}</td>";
2670 echo "<td class=tdleft>${attr['type']}</td>";
2671 echo '<td class=tdleft>';
2672 if (count ($attr['application']) == 0)
2673 echo '&nbsp;';
2674 else
2675 foreach ($attr['application'] as $app)
2676 if ($attr['type'] == 'dict')
2677 echo "${app['objtype_name']} (values from '${app['chapter_name']}')<br>";
2678 else
2679 echo "${app['objtype_name']}<br>";
2680 echo '</td>';
2681 echo "</tr>\n";
2682 $order = $nextorder[$order];
2683 }
2684 echo "</table><br>\n";
2685 finishPortlet();
2686}
2687
2688function renderEditAttributesForm ()
2689{
2690 global $root, $pageno, $tabno;
2691 $attrMap = getAttrMap();
2692 showMessageOrError();
2693 startPortlet ('Optional attributes');
2694 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
2695 echo '<tr><th>&nbsp;</th><th>Name</th><th>Type</th><th>&nbsp;</th></tr>';
2696 foreach ($attrMap as $attr)
2697 {
2698 echo "<form action='${root}process.php' method=post>";
2699 echo "<input type=hidden name=page value='${pageno}'>";
2700 echo "<input type=hidden name=tab value='${tabno}'>";
2701 echo "<input type=hidden name=op value=upd>";
2702 echo "<input type=hidden name=attr_id value='${attr['id']}'>";
2703 echo '<tr>';
2704 echo "<td><a href='${root}process.php?page=${pageno}&tab=${tabno}&op=del&attr_id=${attr['id']}'>";
2705 printImageHREF ('delete', 'Remove attribute');
2706 echo '</a></td>';
2707 echo "<td><input type=text name=attr_name value='${attr['name']}'></td>";
2708 echo "<td>${attr['type']}</td>";
2709 echo "<td><input type=submit value='OK'></td>";
2710 echo '</tr>';
2711 echo '</form>';
2712 }
2713 echo "<form action='${root}process.php' method=post>";
2714 echo "<input type=hidden name=page value='${pageno}'>";
2715 echo "<input type=hidden name=tab value='${tabno}'>";
2716 echo "<input type=hidden name=op value=add>";
2717 echo '<tr><td>';
a5ae8c2a 2718 printImageHREF ('add', '', TRUE);
e673ee24
DO
2719 echo "</td><td><input type=text name=attr_name></td>";
2720 echo '<td><select name=attr_type>';
2721 echo '<option value=uint>uint</option>';
2722 echo '<option value=float>float</option>';
2723 echo '<option value=string>string</option>';
2724 echo '<option value=dict>dict</option>';
2725 echo '</select></td>';
2726 echo '</tr>';
2727 echo '</form>';
2728 echo "</table>\n";
2729 finishPortlet();
2730}
2731
2732function renderEditAttrMapForm ()
2733{
2734 global $root, $pageno, $tabno;
2735 $attrMap = getAttrMap();
2736 showMessageOrError();
2737 startPortlet ('Attribute map');
2738 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
2739 echo '<tr><th>&nbsp;</th><th>Attribute name</th><th>Object type</th><th>Dictionary chapter</th></tr>';
2740 foreach ($attrMap as $attr)
2741 {
2742 if (count ($attr['application']) == 0)
2743 continue;
2744 foreach ($attr['application'] as $app)
2745 {
2746 echo '<tr>';
2747 echo '<td>';
2748 echo "<a href='${root}process.php?page=${pageno}&tab=${tabno}&op=del&";
2749 echo "attr_id=${attr['id']}&objtype_id=${app['objtype_id']}'>";
2750 printImageHREF ('delete', 'Remove mapping');
2751 echo "</a>";
2752 echo '</td>';
2753 echo "<td>${attr['name']}</td>";
2754 echo "<td>${app['objtype_name']}</td>";
2755 echo "<td>";
2756 if ($attr['type'] == 'dict')
2757 echo "${app['chapter_name']}";
2758 else
2759 echo '&nbsp;';
2760 echo "</td></tr>\n";
2761 }
2762 }
2763 echo "<form action='${root}process.php' method=post>";
2764 echo "<input type=hidden name=page value='${pageno}'>";
2765 echo "<input type=hidden name=tab value='${tabno}'>";
2766 echo "<input type=hidden name=op value=add>";
2767 echo '<tr><td>';
a5ae8c2a 2768 printImageHREF ('add', '', TRUE);
e673ee24
DO
2769 echo "</td><td><select name=attr_id>";
2770 $shortType['uint'] = 'U';
2771 $shortType['float'] = 'F';
2772 $shortType['string'] = 'S';
2773 $shortType['dict'] = 'D';
2774 foreach ($attrMap as $attr)
2775 echo "<option value=${attr['id']}>[" . $shortType[$attr['type']] . "] ${attr['name']}</option>";
2776 echo "</select></td>";
2777 echo '<td>';
2778 printSelect (getObjectTypeList(), 'objtype_id');
2779 echo '</td>';
2780 $dict = getDict();
2781 echo '<td><select name=chapter_no>';
2782 foreach ($dict as $chapter)
2783 if (!$chapter['sticky'])
2784 echo "<option value='${chapter['no']}'>${chapter['name']}</option>";
2785 echo '</select></td>';
2786 echo '</tr>';
2787 echo '</form>';
2788 echo "</table>\n";
2789 finishPortlet();
2790}
2791
a5ae8c2a 2792function printImageHREF ($tag, $title = '', $do_input = FALSE, $tabindex = 0)
e673ee24 2793{
a5ae8c2a
DO
2794 global $root;
2795 $image['error']['path'] = 'pix/error.png';
2796 $image['error']['width'] = 76;
2797 $image['error']['height'] = 17;
2798 $image['favicon']['path'] = 'pix/racktables.ico';
2799 $image['favicon']['width'] = 16;
2800 $image['favicon']['height'] = 16;
2801 $image['logo']['path'] = 'pix/defaultlogo.png';
2802 $image['logo']['width'] = 210;
2803 $image['logo']['height'] = 40;
2804 $image['rackspace']['path'] = 'pix/racks.png';
2805 $image['rackspace']['width'] = 218;
2806 $image['rackspace']['height'] = 200;
2807 $image['objects']['path'] = 'pix/server.png';
2808 $image['objects']['width'] = 218;
2809 $image['objects']['height'] = 200;
2810 $image['ipv4space']['path'] = 'pix/addressspace.png';
2811 $image['ipv4space']['width'] = 218;
2812 $image['ipv4space']['height'] = 200;
2813 $image['config']['path'] = 'pix/configuration.png';
2814 $image['config']['width'] = 218;
2815 $image['config']['height'] = 200;
2816 $image['reports']['path'] = 'pix/report.png';
2817 $image['reports']['width'] = 218;
2818 $image['reports']['height'] = 200;
2819 $image['help']['path'] = 'pix/help.png';
2820 $image['help']['width'] = 218;
2821 $image['help']['height'] = 200;
2822 $image['reserve']['path'] = 'pix/stop.png';
2823 $image['reserve']['width'] = 16;
2824 $image['reserve']['height'] = 16;
2825 $image['useup']['path'] = 'pix/go.png';
2826 $image['useup']['width'] = 16;
2827 $image['useup']['height'] = 16;
2828 $image['blockuser'] = $image['reserve'];
2829 $image['unblockuser'] = $image['useup'];
2830 $image['link']['path'] = 'pix/link.png';
2831 $image['link']['width'] = 24;
2832 $image['link']['height'] = 24;
2833 $image['unlink']['path'] = 'pix/unlink.png';
2834 $image['unlink']['width'] = 24;
2835 $image['unlink']['height'] = 24;
2836 $image['add']['path'] = 'pix/greenplus.png';
2837 $image['add']['width'] = 16;
2838 $image['add']['height'] = 16;
2839 $image['delete']['path'] = 'pix/delete_s.gif';
2840 $image['delete']['width'] = 16;
2841 $image['delete']['height'] = 16;
2842 $image['grant'] = $image['add'];
2843 $image['revoke'] = $image['delete'];
2844 $image['helphint']['path'] = 'pix/helphint.png';
2845 $image['helphint']['width'] = 24;
2846 $image['helphint']['height'] = 24;
e673ee24
DO
2847 if (!isset ($image[$tag]))
2848 $tag = 'error';
2849 $img = $image[$tag];
a5ae8c2a
DO
2850 if ($do_input == TRUE)
2851 echo
2852 "<input type=image name=submit " .
2853 "src='${root}${img['path']}' " .
2854 "border=0 " .
2855 ($tabindex ? '' : "tabindex=${tabindex}") .
2856 ">";
2857 else
2858 echo
2859 "<img " .
2860 "src='${root}${img['path']}' " .
2861 "width=${img['width']} " .
2862 "height=${img['height']} " .
2863 "border=0 " .
2864 (empty ($title) ? '' : "title='${title}'") .
2865 ">";
e673ee24
DO
2866}
2867
2868// This function returns URL for favourite icon.
2869function getFaviconURL ()
2870{
2871 global $root, $image;
2872 return $root . $image['favicon']['path'];
2873}
2874
2875function renderReportSummary ()
2876{
2877 echo "Here be dragons :-P";
2878}
2879
2880function renderUIConfig ()
2881{
2882 echo "Here be dragons :-P";
2883}
2884
7865c525
DO
2885// This functions returns an array for VLAN list, and an array for port list (both
2886// form another array themselves).
2887// The ports in the latter array are marked with either VLAN ID or 'trunk'.
2888// We don't sort the port list, as the gateway is believed to have done this already
2889// (or at least the underlying switch software ought to). This is important, as the
2890// port info is transferred to/from form not by names, but by numbers.
2891function getSwitchVLANs ($object_id = 0)
2892{
2893 global $remote_username;
2894 if ($object_id <= 0)
2895 {
2896 showError ('Invalid object_id in getSwitchVLANs()');
2897 return;
2898 }
f321b50a
DO
2899 $objectInfo = getObjectInfo ($object_id);
2900 $endpoints = findAllEndpoints ($object_id, $objectInfo['name']);
7865c525
DO
2901 if (count ($endpoints) == 0)
2902 {
2903 showError ('Can\'t find any mean to reach current object. Please either set FQDN attribute or assign an IP address to the object.');
2904 return NULL;
2905 }
2906 if (count ($endpoints) > 1)
2907 {
2908 showError ('More than one IP address is assigned to this object, please configure FQDN attribute.');
2909 return NULL;
2910 }
2911 $hwtype = $swtype = 'unknown';
2912 foreach (getAttrValues ($object_id) as $record)
2913 {
2914 if ($record['name'] == 'SW type' && !empty ($record['value']))
2915 $swtype = str_replace (' ', '+', $record['value']);
2916 if ($record['name'] == 'HW type' && !empty ($record['value']))
2917 $hwtype = str_replace (' ', '+', $record['value']);
2918 }
2919 $data = queryGateway
2920 (
2921 'switchvlans',
2922 array ("connect ${endpoints[0]} $hwtype $swtype ${remote_username}", 'listvlans', 'listports')
2923 );
2924 if ($data == NULL)
2925 {
2926 showError ('Failed to get any response from queryGateway() or the gateway died');
2927 return NULL;
2928 }
2929 if (strpos ($data[0], 'OK!') !== 0)
2930 {
2931 showError ("Gateway failure: returned code ${data[0]}.");
2932 return NULL;
2933 }
2934 if (count ($data) != 3)
2935 {
2936 showError ("Gateway failure: mailformed reply.");
2937 return NULL;
2938 }
2939 // Now we have VLAN list in $data[1] and port list in $data[2]. Let's sort this out.
d28ea105
DO
2940 $tmp = array_unique (explode (';', substr ($data[1], strlen ('OK!'))));
2941 if (count ($tmp) == 0)
7865c525
DO
2942 {
2943 showError ("Gateway succeeded, but returned no VLAN records.");
2944 return NULL;
2945 }
d28ea105
DO
2946 $vlanlist = array();
2947 foreach ($tmp as $record)
2948 {
2949 list ($vlanid, $vlandescr) = explode ('=', $record);
2950 $vlanlist[$vlanid] = $vlandescr;
2951 }
7865c525 2952 $portlist = array();
d28ea105 2953 foreach (explode (';', substr ($data[2], strlen ('OK '))) as $pair)
7865c525
DO
2954 {
2955 list ($portname, $vlanid) = explode ('=', $pair);
2956 $portlist[] = array ('portname' => $portname, 'vlanid' => $vlanid);
2957 }
2958 if (count ($portlist) == 0)
2959 {
2960 showError ("Gateway succeeded, but returned no port records.");
2961 return NULL;
2962 }
2963 return array ($vlanlist, $portlist);
2964}
2965
2966function setSwitchVLANs ($object_id = 0, $setcmd)
2967{
2968 global $remote_username;
2969 $log = array();
2970 if ($object_id <= 0)
2971 return array (array ('code' => 'error', 'message' => 'Invalid object_id in setSwitchVLANs()'));
4b61807c
DO
2972 $objectInfo = getObjectInfo ($object_id);
2973 $endpoints = findAllEndpoints ($object_id, $objectInfo['name']);
7865c525
DO
2974 if (count ($endpoints) == 0)
2975 return array (array ('code' => 'error', 'message' => 'Can\'t find any mean to reach current object. Please either set FQDN attribute or assign an IP address to the object.'));
2976 if (count ($endpoints) > 1)
2977 return array (array ('code' => 'error', 'message' => 'More than one IP address is assigned to this object, please configure FQDN attribute.'));
2978 $hwtype = $swtype = 'unknown';
2979 foreach (getAttrValues ($object_id) as $record)
2980 {
2981 if ($record['name'] == 'SW type' && !empty ($record['value']))
2982 $swtype = strtr ($record['value'], ' ', '+');
2983 if ($record['name'] == 'HW type' && !empty ($record['value']))
2984 $hwtype = strtr ($record['value'], ' ', '+');
2985 }
2986 $data = queryGateway
2987 (
2988 'switchvlans',
2989 array ("connect ${endpoints[0]} $hwtype $swtype ${remote_username}", $setcmd)
2990 );
2991 if ($data == NULL)
2992 return array (array ('code' => 'error', 'message' => 'Failed to get any response from queryGateway() or the gateway died'));
2993 if (strpos ($data[0], 'OK!') !== 0)
2994 return array (array ('code' => 'error', 'message' => "Gateway failure: returned code ${data[0]}."));
2995 if (count ($data) != 2)
2996 return array (array ('code' => 'error', 'message' => 'Gateway failure: mailformed reply.'));
2997 // Finally we can parse the response into message array.
2998 $ret = array();
2999 foreach (split (';', substr ($data[1], strlen ('OK!'))) as $text)
3000 {
3001 if (strpos ($text, 'I!') === 0)
3002 $code = 'success';
3003 elseif (strpos ($text, 'W!') === 0)
3004 $code = 'warning';
3005 else // All improperly formatted messages must be treated as error conditions.
3006 $code = 'error';
3007 $ret[] = array ('code' => $code, 'message' => substr ($text, 2));
3008 }
3009 return $ret;
3010}
3011
3012// This function queries the gateway about current VLAN configuration and
3013// renders a form suitable for submit. Ah, and it does submit processing as well.
111b4a67
DO
3014function renderVLANMembership ($object_id = 0)
3015{
fc8d0004 3016 global $root, $pageno, $tabno, $remote_username;
111b4a67
DO
3017 if ($object_id <= 0)
3018 {
3019 showError ('Invalid object_id in renderVLANMembership()');
3020 return;
3021 }
7865c525
DO
3022
3023 // Handle probable pending submit.
3024 if (isset ($_REQUEST['portcount']))
111b4a67 3025 {
7865c525
DO
3026 $data = getSwitchVLANs ($object_id);
3027 if ($data === NULL)
2da7c9b0 3028 {
7865c525 3029 showError ('getSwitchVLANs() failed in renderVLANMembership() during submit processing');
fc8d0004
DO
3030 return;
3031 }
7865c525
DO
3032 list ($vlanlist, $portlist) = $data;
3033 // Here we just build up 1 set command for the gateway with all of the ports
3034 // included. The gateway is expected to filter unnecessary changes silently
3035 // and to provide a list of responses with either error or success message
3036 // for each of the rest.
3037 assertUIntArg ('portcount');
3038 $nports = $_REQUEST['portcount'];
3039 $prefix = 'set ';
3040 $log = array();
3041 $setcmd = '';
3042 for ($i = 0; $i < $nports; $i++)
3043 if
3044 (
3045 !isset ($_REQUEST['portname_' . $i]) ||
3046 !isset ($_REQUEST['vlanid_' . $i]) ||
3047 $_REQUEST['portname_' . $i] != $portlist[$i]['portname']
3048 )
3049 $log[] = array ('code' => 'error', 'message' => "Ignoring mailformed record #${i} in form submit");
3050 elseif
3051 (
3052 $_REQUEST['vlanid_' . $i] == $portlist[$i]['vlanid'] ||
3053 $portlist[$i]['vlaind'] == 'TRUNK'
3054 )
3055 continue;
3056 else
3057 {
3058 $setcmd .= $prefix . $_REQUEST['portname_' . $i] . '=' . $_REQUEST['vlanid_' . $i];
3059 $prefix = ';';
3060 }
3061 printLog ($log);
3062 // Feed the gateway and interpret its (non)response.
3063 if ($setcmd != '')
3064 printLog (setSwitchVLANs ($object_id, $setcmd));
3065 }
3066
3067 // Reload and render.
3068 $data = getSwitchVLANs ($object_id);
3069 if ($data === NULL)
3070 return;
3071 list ($vlanlist, $portlist) = $data;
d28ea105
DO
3072
3073 echo '<table border=0 width="100%"><tr><td class=pcleft>'; // --------------------------------------------------
3074
3075 startPortlet ('VLAN table');
3076 echo '<table class=cooltable cellspacing=0 cellpadding=5 align=center>';
3077 echo "<tr><th>ID</th><th>Description</th></tr>";
3078 $order = 'even';
3079 global $nextorder;
3080 foreach ($vlanlist as $id => $descr)
3081 {
3082 echo "<tr class=row_${order}><td class=tdright>${id}</td><td class=tdleft>${descr}</td></tr>";
3083 $order = $nextorder[$order];
3084 }
3085 echo '</table>';
3086 finishPortlet();
3087
3088 echo '</td><td class=pcright>'; // ------------------------------------------------------------
3089
3090 startPortlet ('Port configuration');
7865c525
DO
3091 echo "<table class=widetable cellspacing=0 cellpadding='5' align=center><tr>";
3092 echo "<form method=post>";
3093 echo "<input type=hidden name=page value='${pageno}'>";
3094 echo "<input type=hidden name=tab value='${tabno}'>";
3095 echo "<input type=hidden name=object_id value=${object_id}>";
3096 echo "<input type=hidden name=portcount value=" . count ($portlist) . ">\n";
3097 $portno = 0;
3098 foreach ($portlist as $port)
3099 {
3100 // Don't let wide forms break our fancy pages.
3101 if ($portno % PORTS_PER_ROW == 0)
fc8d0004 3102 {
7865c525
DO
3103 if ($portno > 0)
3104 echo "</tr>\n";
3105 echo "<tr><th>" . ($portno + 1) . "-" . ($portno + PORTS_PER_ROW) . "</th>";
fc8d0004 3106 }
7865c525
DO
3107 echo '<td>' . $port['portname'] . '<br>';
3108 echo "<input type=hidden name=portname_${portno} value=" . $port['portname'] . '>';
3109 if ($port['vlanid'] == 'trunk')
fc8d0004 3110 {
7865c525
DO
3111 echo "<input type=hidden name=vlanid_${portno} value='trunk'>";
3112 echo "<select disabled multiple='multiple' size=1><option>TRUNK</option></select>";
fc8d0004 3113 }
7865c525 3114 else
fc8d0004 3115 {
7865c525 3116 echo "<select name=vlanid_${portno}>";
d28ea105 3117 foreach ($vlanlist as $v => $d)
fc8d0004 3118 {
7865c525
DO
3119 echo "<option value=${v}";
3120 if ($v == $port['vlanid'])
3121 echo ' selected';
3122 echo ">${v}</option>";
fc8d0004 3123 }
7865c525 3124 echo "</select>";
fc8d0004 3125 }
7865c525
DO
3126 $portno++;
3127 echo "</td>";
111b4a67 3128 }
7865c525
DO
3129 echo "</tr><tr><td colspan=" . (PORTS_PER_ROW + 1) . "><input type=submit value='Save changes'></form></td></tr></table>";
3130 finishPortlet();
d28ea105
DO
3131
3132 echo '</td></tr></table>'; // -------------------------------------
111b4a67
DO
3133}
3134
e673ee24 3135?>