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