4 * This file contains frontend functions for RackTables.
8 // Interface function's special.
9 $nextorder['odd'] = 'even';
10 $nextorder['even'] = 'odd';
12 // address allocation type
15 'regular' => 'Connected',
16 'virtual' => 'Loopback',
20 // address allocation code, IPv4 addresses and objects view
24 'virtual' => '<strong>L</strong>',
25 'shared' => '<strong>S</strong>',
26 'router' => '<strong>R</strong>',
28 // address allocation code, IPv4 networks view
32 'virtual' => '<strong>L:</strong>',
33 'shared' => '<strong>S:</strong>',
34 'router' => '<strong>R:</strong>',
37 // Let's have it here, so extensions can add their own images.
39 $image['error']['path'] = 'pix/error.png';
40 $image['error']['width'] = 76;
41 $image['error']['height'] = 17;
42 $image['logo']['path'] = 'pix/defaultlogo.png';
43 $image['logo']['width'] = 210;
44 $image['logo']['height'] = 40;
45 $image['rackspace']['path'] = 'pix/racks.png';
46 $image['rackspace']['width'] = 218;
47 $image['rackspace']['height'] = 200;
48 $image['objects']['path'] = 'pix/server.png';
49 $image['objects']['width'] = 218;
50 $image['objects']['height'] = 200;
51 $image['files']['path'] = 'pix/files.png';
52 $image['files']['width'] = 218;
53 $image['files']['height'] = 200;
54 $image['ipv4space']['path'] = 'pix/addressspace.png';
55 $image['ipv4space']['width'] = 218;
56 $image['ipv4space']['height'] = 200;
57 $image['ipv4slb']['path'] = 'pix/slb.png';
58 $image['ipv4slb']['width'] = 218;
59 $image['ipv4slb']['height'] = 200;
60 $image['config']['path'] = 'pix/configuration.png';
61 $image['config']['width'] = 218;
62 $image['config']['height'] = 200;
63 $image['reports']['path'] = 'pix/report.png';
64 $image['reports']['width'] = 218;
65 $image['reports']['height'] = 200;
66 $image['download']['path'] = 'pix/download.png';
67 $image['download']['width'] = 16;
68 $image['download']['height'] = 16;
69 $image['DOWNLOAD']['path'] = 'pix/download-big.png';
70 $image['DOWNLOAD']['width'] = 32;
71 $image['DOWNLOAD']['height'] = 32;
72 $image['plug']['path'] = 'pix/tango-network-wired.png';
73 $image['plug']['width'] = 16;
74 $image['plug']['height'] = 16;
75 $image['cut']['path'] = 'pix/tango-edit-cut-16x16.png';
76 $image['cut']['width'] = 16;
77 $image['cut']['height'] = 16;
78 $image['CUT']['path'] = 'pix/tango-edit-cut-32x32.png';
79 $image['CUT']['width'] = 32;
80 $image['CUT']['height'] = 32;
81 $image['add']['path'] = 'pix/tango-list-add.png';
82 $image['add']['width'] = 16;
83 $image['add']['height'] = 16;
84 $image['ADD']['path'] = 'pix/tango-list-add-big.png';
85 $image['ADD']['width'] = 32;
86 $image['ADD']['height'] = 32;
87 $image['delete']['path'] = 'pix/tango-list-remove.png';
88 $image['delete']['width'] = 16;
89 $image['delete']['height'] = 16;
90 $image['destroy']['path'] = 'pix/tango-user-trash-16x16.png';
91 $image['destroy']['width'] = 16;
92 $image['destroy']['height'] = 16;
93 $image['nodestroy']['path'] = 'pix/tango-user-trash-16x16-gray.png';
94 $image['nodestroy']['width'] = 16;
95 $image['nodestroy']['height'] = 16;
96 $image['DESTROY']['path'] = 'pix/tango-user-trash-32x32.png';
97 $image['DESTROY']['width'] = 32;
98 $image['DESTROY']['height'] = 32;
99 $image['nodelete']['path'] = 'pix/tango-list-remove-shadow.png';
100 $image['nodelete']['width'] = 16;
101 $image['nodelete']['height'] = 16;
102 $image['inservice']['path'] = 'pix/tango-emblem-system.png';
103 $image['inservice']['width'] = 16;
104 $image['inservice']['height'] = 16;
105 $image['notinservice']['path'] = 'pix/tango-dialog-error.png';
106 $image['notinservice']['width'] = 16;
107 $image['notinservice']['height'] = 16;
108 $image['find']['path'] = 'pix/tango-system-search.png';
109 $image['find']['width'] = 16;
110 $image['find']['height'] = 16;
111 $image['next']['path'] = 'pix/tango-go-next.png';
112 $image['next']['width'] = 32;
113 $image['next']['height'] = 32;
114 $image['prev']['path'] = 'pix/tango-go-previous.png';
115 $image['prev']['width'] = 32;
116 $image['prev']['height'] = 32;
117 $image['clear']['path'] = 'pix/tango-edit-clear.png';
118 $image['clear']['width'] = 16;
119 $image['clear']['height'] = 16;
120 $image['CLEAR']['path'] = 'pix/tango-edit-clear-big.png';
121 $image['CLEAR']['width'] = 32;
122 $image['CLEAR']['height'] = 32;
123 $image['CLEAR gray']['path'] = 'pix/tango-edit-clear-gray-32x32.png';
124 $image['CLEAR gray']['width'] = 32;
125 $image['CLEAR gray']['height'] = 32;
126 $image['save']['path'] = 'pix/tango-document-save.png';
127 $image['save']['width'] = 16;
128 $image['save']['height'] = 16;
129 $image['SAVE']['path'] = 'pix/tango-document-save-big.png';
130 $image['SAVE']['width'] = 32;
131 $image['SAVE']['height'] = 32;
132 $image['create']['path'] = 'pix/tango-document-new.png';
133 $image['create']['width'] = 16;
134 $image['create']['height'] = 16;
135 $image['CREATE']['path'] = 'pix/tango-document-new-big.png';
136 $image['CREATE']['width'] = 32;
137 $image['CREATE']['height'] = 32;
138 $image['DENIED']['path'] = 'pix/tango-dialog-error-big.png';
139 $image['DENIED']['width'] = 32;
140 $image['DENIED']['height'] = 32;
141 $image['apply']['path'] = 'pix/tango-emblem-system.png';
142 $image['apply']['width'] = 16;
143 $image['apply']['height'] = 16;
144 $image['node-collapsed']['path'] = 'pix/node-collapsed.png';
145 $image['node-collapsed']['width'] = 16;
146 $image['node-collapsed']['height'] = 16;
147 $image['node-expanded']['path'] = 'pix/node-expanded.png';
148 $image['node-expanded']['width'] = 16;
149 $image['node-expanded']['height'] = 16;
150 $image['node-expanded-static']['path'] = 'pix/node-expanded-static.png';
151 $image['node-expanded-static']['width'] = 16;
152 $image['node-expanded-static']['height'] = 16;
153 $image['dragons']['path'] = 'pix/mitsudragon.png';
154 $image['dragons']['width'] = 125;
155 $image['dragons']['height'] = 21;
156 $image['LB']['path'] = 'pix/loadbalancer.png';
157 $image['LB']['width'] = 32;
158 $image['LB']['height'] = 32;
159 $image['RS pool']['path'] = 'pix/serverpool.png';
160 $image['RS pool']['width'] = 48;
161 $image['RS pool']['height'] = 16;
162 $image['VS']['path'] = 'pix/servicesign.png';
163 $image['VS']['width'] = 39;
164 $image['VS']['height'] = 62;
165 $image['router']['path'] = 'pix/router.png';
166 $image['router']['width'] = 32;
167 $image['router']['height'] = 32;
168 $image['ATTACH']['path'] = 'pix/crystal-attach-32x32.png';
169 $image['ATTACH']['width'] = 32;
170 $image['ATTACH']['height'] = 32;
171 $image['favorite']['path'] = 'pix/tango-emblem-favorite.png';
172 $image['favorite']['width'] = 16;
173 $image['favorite']['height'] = 16;
174 $image['computer']['path'] = 'pix/tango-computer.png';
175 $image['computer']['width'] = 16;
176 $image['computer']['height'] = 16;
177 $image['empty file']['path'] = 'pix/crystal-file-empty-32x32.png';
178 $image['empty file']['width'] = 32;
179 $image['empty file']['height'] = 32;
180 $image['text file']['path'] = 'pix/crystal-file-text-32x32.png';
181 $image['text file']['width'] = 32;
182 $image['text file']['height'] = 32;
183 $image['image file']['path'] = 'pix/crystal-file-image-32x32.png';
184 $image['image file']['width'] = 32;
185 $image['image file']['height'] = 32;
186 $image['NET']['path'] = 'pix/crystal-network-32x32.png';
187 $image['NET']['width'] = 32;
188 $image['NET']['height'] = 32;
189 $image['USER']['path'] = 'pix/crystal-edit-user-32x32.png';
190 $image['USER']['width'] = 32;
191 $image['USER']['height'] = 32;
193 // This may be populated later onsite, report rendering function will use it.
194 // See the $systemreport for structure.
195 $localreports = array();
196 $CodePressMap = array
202 'js' => 'javascript',
207 'uint' => '[U] unsigned integer',
208 'float' => '[F] floating point',
209 'string' => '[S] string',
210 'dict' => '[D] dictionary record'
214 function renderIndex ()
218 <table border
=0 cellpadding
=0 cellspacing
=0 width
='100%'>
221 <div style
='text-align: center; margin: 10px; '>
222 <table width
='100%' cellspacing
=0 cellpadding
=30 class=mainmenu border
=0>
225 <h1
><a href
='<?php echo makeHref(array('page
'=>'rackspace
')) ?>'>Rackspace
<br
>
226 <?php
printImageHREF ('rackspace'); ?
></a
></h1
>
229 <h1
><a href
='<?php echo makeHref(array('page
'=>'objects
')) ?>'>Objects
<br
>
230 <?php
printImageHREF ('objects'); ?
></a
></h1
>
233 <h1
><a href
='<?php echo makeHref(array('page
'=>'ipv4space
')) ?>'>IPv4 space
<br
>
234 <?php
printImageHREF ('ipv4space'); ?
></a
></h1
>
237 <h1
><a href
='<?php echo makeHref(array('page
'=>'files
')) ?>'>Files
<br
>
238 <?php
printImageHREF ('files'); ?
></a
></h1
>
243 <h1
><a href
='<?php echo makeHref(array('page
'=>'config
')) ?>'>Configuration
<br
>
244 <?php
printImageHREF ('config'); ?
></a
></h1
>
247 <h1
><a href
='<?php echo makeHref(array('page
'=>'reports
')) ?>'>Reports
<br
>
248 <?php
printImageHREF ('reports'); ?
></a
></h1
>
251 <h1
><a href
='<?php echo makeHref(array('page
'=>'ipv4slb
')) ?>'>IPv4 SLB
<br
>
252 <?php
printImageHREF ('ipv4slb'); ?
></a
></h1
>
264 function renderRackspace ()
266 $tagfilter = getTagFilter();
267 $tagfilter_str = getTagFilterStr ($tagfilter);
268 showMessageOrError();
269 echo "<table class=objview border=0 width='100%'><tr><td class=pcleft>";
270 renderTagFilterPortlet ($tagfilter, 'rack');
271 echo '</td><td class=pcright>';
272 echo '<table border=0 cellpadding=10 cellpadding=1>';
273 // generate thumb gallery
274 $rackrowList = getRackspace ($tagfilter);
276 $rackwidth = getRackImageWidth();
278 foreach ($rackrowList as $rackrow)
280 echo "<tr class=row_${order}><th class=tdleft>";
281 echo "<a href='".makeHref(array('page'=>'row', 'row_id'=>$rackrow['row_id']))."${tagfilter_str}'>";
282 echo "${rackrow['row_name']}</a></th>";
283 $rackList = getRacksForRow ($rackrow['row_id'], $tagfilter);
284 echo "<td><table border=0 cellspacing=5><tr>";
285 foreach ($rackList as $rack)
287 echo "<td align=center><a href='".makeHref(array('page'=>'rack', 'rack_id'=>$rack['id']))."'>";
288 echo "<img border=0 width=${rackwidth} height=";
289 echo getRackImageHeight ($rack['height']);
290 echo " title='${rack['height']} units'";
291 echo "src='render_image.php?img=minirack&rack_id=${rack['id']}'>";
292 echo "<br>${rack['name']}</a></td>";
294 echo "</tr></table></tr>\n";
295 $order = $nextorder[$order];
298 echo "</td></tr></table>\n";
301 function renderRackspaceRowEditor ()
303 function printNewItemTR ()
305 printOpFormIntro ('addRow');
306 echo "<tr><td><input type=text name=name tabindex=100></td><td>";
307 printImageHREF ('create', 'Add new row', TRUE, 101);
308 echo "</td><td></td></tr></form>";
310 global $pageno, $tabno;
311 startPortlet ('Rows');
312 showMessageOrError();
313 echo "<table border=0 cellspacing=0 cellpadding=5 align=center class=widetable>\n";
314 echo "<tr><th>Name</th></tr>\n";
315 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
317 $rackrowList = getRackspace ();
318 foreach ($rackrowList as $rackrow)
320 printOpFormIntro ('updateRow', array ('row_id' => $rackrow['row_id']));
321 echo "<tr><td><input type=text name=name value='${rackrow['row_name']}'></td><td>";
322 printImageHREF ('save', 'Save changes', TRUE);
323 echo "</td></form><td>";
324 if ($rackrow['count'] == 0)
326 echo "<a href=\"".makeHrefProcess(array('op'=>'delete', 'row_id'=>$rackrow['row_id'], 'name'=>$rackrow['row_name']))."\">";
327 printImageHREF ('delete', 'Delete row');
332 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
334 echo "</table><br>\n";
338 function renderRow ($row_id = 0)
342 showError ('Invalid row_id', __FUNCTION__
);
345 if (($rowInfo = getRackRowInfo ($row_id)) == NULL)
347 showError ('getRackRowInfo() failed', __FUNCTION__
);
350 $tagfilter = getTagFilter();
351 $rackList = getRacksForRow ($row_id, $tagfilter);
352 // Main layout starts.
353 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
355 // Left portlet with row information.
356 echo "<tr><td class=pcleft>";
357 startPortlet ($rowInfo['name']);
358 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
359 echo "<tr><th width='50%' class=tdright>Racks:</th><td class=tdleft>${rowInfo['count']}</td></tr>\n";
360 echo "<tr><th width='50%' class=tdright>Units:</th><td class=tdleft>${rowInfo['sum']}</td></tr>\n";
361 echo "<tr><th width='50%' class=tdright>%% used:</th><td class=tdleft>";
362 renderProgressBar (getRSUforRackRow ($rackList));
364 echo "</table><br>\n";
367 echo "</td><td class=pcright rowspan=2>";
370 $rackwidth = getRackImageWidth() * getConfigVar ('ROW_SCALE');
372 startPortlet ('Racks');
373 echo "<table border=0 cellspacing=5 align='center'><tr>";
374 foreach ($rackList as $rack)
376 echo "<td align=center class=row_${order}><a href='".makeHref(array('page'=>'rack', 'rack_id'=>$rack['id']))."'>";
377 echo "<img border=0 width=${rackwidth} height=" . (getRackImageHeight ($rack['height']) * getConfigVar ('ROW_SCALE'));
378 echo " title='${rack['height']} units'";
379 echo "src='render_image.php?img=minirack&rack_id=${rack['id']}'>";
380 echo "<br>${rack['name']}</a></td>";
381 $order = $nextorder[$order];
383 echo "</tr></table>\n";
387 echo "<tr><td class=pcleft>";
388 renderTagFilterPortlet ($tagfilter, 'rack', 'row_id', $row_id);
389 echo "</td></tr></table>";
392 function showError ($info = '', $location = 'N/A')
394 if (preg_match ('/\.php$/', $location))
395 $location = basename ($location);
396 elseif ($location != 'N/A')
397 $location = $location . '()';
398 echo "<div class=msg_error>An error has occured in [${location}]. ";
400 echo 'No additional information is available.';
402 echo "Additional information:<br><p>\n<pre>\n${info}\n</pre></p>";
403 echo "Go back or try starting from <a href='".makeHref()."'>index page</a>.<br></div>\n";
406 // This function renders rack as HTML table.
407 function renderRack ($rack_id = 0, $hl_obj_id = 0)
411 showError ('Invalid rack_id', __FUNCTION__
);
414 if (($rackData = getRackData ($rack_id)) == NULL)
416 showError ('getRackData() failed', __FUNCTION__
);
419 global $pageno, $tabno;
420 markAllSpans ($rackData);
422 highlightObject ($rackData, $hl_obj_id);
423 markupObjectProblems ($rackData);
424 $prev_id = getPrevIDforRack ($rackData['row_id'], $rack_id);
425 $next_id = getNextIDforRack ($rackData['row_id'], $rack_id);
426 echo "<center><table border=0><tr valign=middle>";
427 echo "<td><h2><a href='".makeHref(array('page'=>'row', 'row_id'=>$rackData['row_id']))."'>${rackData['row_name']}</a> :</h2></td>";
428 // FIXME: use 'bypass'?
429 if ($prev_id != NULL)
431 echo "<td><a href='".makeHref(array('page'=>'rack', 'rack_id'=>$prev_id))."'>";
432 printImageHREF ('prev', 'previous rack');
435 echo "<td><h2><a href='".makeHref(array('page'=>'rack', 'rack_id'=>$rackData['id']))."'>${rackData['name']}</a></h2></td>";
436 if ($next_id != NULL)
438 echo "<td><a href='".makeHref(array('page'=>'rack', 'rack_id'=>$next_id))."'>";
439 printImageHREF ('next', 'next rack');
442 echo "</h2></td></tr></table>\n";
443 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
444 echo "<tr><th width='10%'> </th><th width='20%'>Front</th>";
445 echo "<th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
446 for ($i = $rackData['height']; $i > 0; $i--)
448 echo "<tr><th>${i}</th>";
449 for ($locidx = 0; $locidx < 3; $locidx++
)
451 if (isset ($rackData[$i][$locidx]['skipped']))
453 $state = $rackData[$i][$locidx]['state'];
454 echo "<td class=state_${state}";
455 if (isset ($rackData[$i][$locidx]['hl']))
456 echo $rackData[$i][$locidx]['hl'];
457 if (isset ($rackData[$i][$locidx]['colspan']))
458 echo ' colspan=' . $rackData[$i][$locidx]['colspan'];
459 if (isset ($rackData[$i][$locidx]['rowspan']))
460 echo ' rowspan=' . $rackData[$i][$locidx]['rowspan'];
465 $objectData = getObjectInfo ($rackData[$i][$locidx]['object_id']);
466 if (!empty ($objectData['asset_no']))
467 $prefix = "<div title='${objectData['asset_no']}";
469 $prefix = "<div title='no asset tag";
470 // Don't tell about label, if it matches common name.
471 if ($objectData['name'] != $objectData['label'] and !empty ($objectData['label']))
472 $suffix = ", visible label is \"${objectData['label']}\"'>";
475 echo $prefix . $suffix;
476 echo "<a href='".makeHref(array('page'=>'object', 'object_id'=>$objectData['id']))."'>${objectData['dname']}</a></div>";
479 echo '<div title="This rackspace does not exist"> </div>';
482 echo '<div title="Free rackspace"> </div>';
485 echo '<div title="Problematic rackspace, you CAN\'T mount here"> </div>';
488 echo '<div title="No data"> </div>';
495 echo "</table></center>\n";
498 function renderNewRackForm ($row_id)
500 showMessageOrError();
502 startPortlet ('Add one');
503 printOpFormIntro ('addRack', array ('got_data' => 'TRUE'));
504 echo '<table border=0 align=center>';
505 $defh = getConfigVar ('DEFAULT_RACK_HEIGHT');
508 echo "<tr><th class=tdright>Rack name (*):</th><td class=tdleft><input type=text name=rack_name tabindex=1></td>";
509 echo "<td rowspan=4>Assign tags:<br>";
512 echo "<tr><th class=tdright>Height in units (*):</th><td class=tdleft><input type=text name=rack_height1 tabindex=2 value='${defh}'></td></tr>\n";
513 echo "<tr><th class=tdright>Comment:</th><td class=tdleft><input type=text name=rack_comment tabindex=3></td></tr>\n";
514 echo "<tr><td class=submit colspan=2>";
515 printImageHREF ('CREATE', 'Add', TRUE);
516 echo "</td></tr></table></form>";
519 startPortlet ('Add many');
520 printOpFormIntro ('addRack', array ('got_mdata' => 'TRUE'));
521 echo '<table border=0 align=center>';
522 $defh = getConfigVar ('DEFAULT_RACK_HEIGHT');
525 echo "<tr><th class=tdright>Height in units (*):</th><td class=tdleft><input type=text name=rack_height2 value='${defh}'></td>";
526 echo "<td rowspan=3 valign=top>Assign tags:<br>";
529 echo "<tr><th class=tdright>Rack names (*):</th><td class=tdleft><textarea name=rack_names cols=40 rows=25></textarea></td></tr>\n";
530 echo "<tr><td class=submit colspan=2>";
531 printImageHREF ('CREATE', 'Add', TRUE);
532 echo '</form></table>';
536 function renderEditObjectForm ($object_id)
538 showMessageOrError();
540 global $pageno, $tabno;
541 $object = getObjectInfo ($object_id);
544 showError ('getObjectInfo() failed', __FUNCTION__
);
548 printOpFormIntro ('update');
549 echo '<table border=0 width=100%><tr><td class=pcleft>';
552 echo '<table border=0 align=center>';
553 echo "<tr><th colspan=2><h2>Static attributes</h2></th></tr>";
554 echo "<tr><th class=tdright>Type:</th><td class=tdleft>";
555 printSelect (getObjectTypeList(), 'object_type_id', $object['objtype_id']);
558 echo "<tr><th class=tdright>Common name:</th><td class=tdleft><input type=text name=object_name value='${object['name']}'></td></tr>\n";
559 echo "<tr><th class=tdright>Visible label:</th><td class=tdleft><input type=text name=object_label value='${object['label']}'></td></tr>\n";
560 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";
561 echo "<tr><th class=tdright>Barcode:</th><td class=tdleft><input type=text name=object_barcode value='${object['barcode']}'></td></tr>\n";
562 echo "<tr><th class=tdright>Has problems:</th><td class=tdleft><input type=checkbox name=object_has_problems";
563 if ($object['has_problems'] == 'yes')
565 echo "></td></tr>\n";
566 echo "<tr><th class=tdright>Actions:</th><td class=tdleft><a href='".
567 makeHrefProcess(array('op'=>'deleteObject', 'page'=>'objects', 'tab'=>'default', 'object_id'=>$object_id, 'name'=>$object['name'])).
568 "' onclick=\"javascript:return confirm('Are you sure you want to delete the object?')\">Delete object</a></td></tr>\n";
569 echo "<tr><td colspan=2><b>Comment:</b><br><textarea name=object_comment rows=10 cols=80>${object['comment']}</textarea></td></tr>";
572 echo '</td><td class=pcright>';
574 // optional attributes
575 $values = getAttrValues ($object_id);
576 if (count($values) > 0)
578 echo "<table border=0 cellspacing=0 cellpadding=5 align=center class=widetable>\n";
579 echo "<tr><th colspan=3><h2>Optional attributes</h2></th></tr>";
580 echo "<tr><th> </th><th>Attribute</th><th>Value</th></tr>\n";
581 echo '<input type=hidden name=num_attrs value=' . count($values) . ">\n";
583 foreach ($values as $record)
585 echo "<input type=hidden name=${i}_attr_id value=${record['id']}>";
587 if (!empty ($record['value']))
589 echo "<a href='".makeHrefProcess(array('op'=>'clearSticker', 'object_id'=>$object_id, 'attr_id'=>$record['id']))."'>";
590 printImageHREF ('clear', 'Clear value');
596 echo "<td class=tdright>${record['name']}:</td><td class=tdleft>";
597 switch ($record['type'])
602 echo "<input type=text name=${i}_value value='${record['value']}'>";
605 $chapter = readChapter ($record['chapter_name']);
606 $chapter[0] = '-- NOT SET --';
607 $chapter = cookOptgroups ($chapter, $object['objtype_id'], $record['key']);
608 printNiftySelect ($chapter, "${i}_value", $record['key']);
618 echo "<tr><th class=submit colspan=2>";
619 printImageHREF ('SAVE', 'Save changes', TRUE);
620 echo "</form></th></tr></table>\n";
623 echo '<table border=0 width=100%><tr><td>';
624 startPortlet ('history');
625 renderHistory ($pageno, $object_id);
627 echo '</td></tr></table>';
630 // This is a clone of renderEditObjectForm().
631 function renderEditRackForm ($rack_id)
633 showMessageOrError();
635 $rack = getRackData ($rack_id);
638 showError ('getRackData() failed', __FUNCTION__
);
642 startPortlet ('Rack attributes');
643 printOpFormIntro ('updateRack');
644 echo '<table border=0 align=center>';
645 echo "<tr><th class=tdright>Rack row:</th><td class=tdleft>";
646 printSelect (getRackRows(), 'rack_row_id', $rack['row_id']);
648 echo "<tr><th class=tdright>Name (required):</th><td class=tdleft><input type=text name=rack_name value='${rack['name']}'></td></tr>\n";
649 echo "<tr><th class=tdright>Height (required):</th><td class=tdleft><input type=text name=rack_height value='${rack['height']}'></td></tr>\n";
650 echo "<tr><th class=tdright>Comment:</th><td class=tdleft><input type=text name=rack_comment value='${rack['comment']}'></td></tr>\n";
651 if (count ($rack['mountedObjects']) == 0)
653 echo "<tr><th class=tdright>Actions:</th><td class=tdleft><a href='".
654 makeHrefProcess(array('op'=>'deleteRack', 'rack_id'=>$rack_id)).
655 "' onclick=\"javascript:return confirm('Are you sure you want to delete the rack?')\">Delete rack</a></td></tr>\n";
657 echo "<tr><td class=submit colspan=2>";
658 printImageHREF ('SAVE', 'Save changes', TRUE);
660 echo '</form></table><br>';
663 startPortlet ('History');
664 renderHistory ($pageno, $rack_id);
668 // This is a helper for creators and editors.
669 // Input array keys are OPTION VALUEs and input array values are OPTION text.
670 function printSelect ($optionList, $select_name, $selected_id = NULL, $tabindex = NULL)
672 echo "<select name=${select_name}" . ($tabindex ?
" tabindex=${tabindex}" : '') . '>';
673 foreach ($optionList as $dict_key => $dict_value)
674 echo "<option value=${dict_key}" . ($dict_key == $selected_id ?
' selected' : '') . ">${dict_value}</option>";
678 // Input is a cooked list of OPTGROUPs, each with own sub-list of OPTIONs in the same
679 // format as printSelect() expects.
680 function printNiftySelect ($groupList, $select_name, $selected_id = NULL, $tabindex = NULL)
682 // special treatment for ungrouped data
683 if (count ($groupList) == 1 and isset ($groupList['other']))
685 printSelect ($groupList['other'], $select_name, $selected_id, $tabindex);
688 echo "<select name=${select_name}" . ($tabindex ?
" tabindex=${tabindex}" : '') . '>';
689 foreach ($groupList as $groupname => $groupdata)
691 echo "<optgroup label='${groupname}'>";
692 foreach ($groupdata as $dict_key => $dict_value)
693 echo "<option value=${dict_key}" . ($dict_key == $selected_id ?
' selected' : '') . ">${dict_value}</option>";
694 echo "</optgroup>\n";
699 // used by renderGridForm() and renderRackPage()
700 function renderRackInfoPortlet ($rackData)
702 startPortlet ('summary');
703 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
704 echo "<tr><th width='50%' class=tdright>Rack row:</th><td class=tdleft>${rackData['row_name']}</td></tr>\n";
705 echo "<tr><th width='50%' class=tdright>Name:</th><td class=tdleft>${rackData['name']}</td></tr>\n";
706 echo "<tr><th width='50%' class=tdright>Height:</th><td class=tdleft>${rackData['height']}</td></tr>\n";
707 echo "<tr><th width='50%' class=tdright>%% used:</th><td class=tdleft>";
708 renderProgressBar (getRSUforRack ($rackData));
710 echo "<tr><th width='50%' class=tdright>Objects:</th><td class=tdleft>";
711 echo count (stuffInRackspace ($rackData));
713 printTagTRs (makeHref(array('page'=>'rackspace', 'tab'=>'default'))."&");
714 if (!empty ($rackData['comment']))
715 echo "<tr><th width='50%' class=tdright>Comment:</th><td class=tdleft>${rackData['comment']}</td></tr>\n";
720 // This is a universal editor of rack design/waste.
721 // FIXME: switch to using printOpFormIntro()
722 function renderGridForm ($rack_id = 0, $filter, $header, $submit, $state1, $state2)
726 showError ('Invalid rack_id', __FUNCTION__
);
729 if (($rackData = getRackData ($rack_id)) == NULL)
731 showError ('getRackData() failed', __FUNCTION__
);
734 showMessageOrError();
735 global $pageno, $tabno;
737 markupObjectProblems ($rackData);
739 // Render the result whatever it is.
741 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
742 echo "<tr><td colspan=2 align=center><h1>${rackData['name']}</h1></td></tr>\n";
744 // Left column with information portlet.
745 echo "<tr><td class=pcleft height='1%' width='50%'>";
746 renderRackInfoPortlet ($rackData);
748 echo "<td class=pcright>";
751 startPortlet ($header);
753 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
754 echo "<tr><th width='10%'> </th><th width='20%'>Front</th>";
755 echo "<th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
756 printOpFormIntro ('updateRack');
757 markupAtomGrid ($rackData, $state2);
758 renderAtomGrid ($rackData);
759 echo "</table></center>\n";
760 echo "<br><input type=submit name=do_update value='${submit}'></form><br><br>\n";
762 echo "</td></tr></table>\n";
765 function renderRackDesign ($rack_id)
767 renderGridForm ($rack_id, 'applyRackDesignMask', 'Rack design', 'Set rack design', 'A', 'F');
770 function renderRackProblems ($rack_id = 0)
772 renderGridForm ($rack_id, 'applyRackProblemMask', 'Rack problems', 'Mark unusable atoms', 'F', 'U');
775 function startPortlet ($title = '')
777 echo "<div class=portlet><h2>${title}</h2>";
780 function finishPortlet ()
785 function printRefsOfType ($refs, $type, $eq)
788 foreach ($refs as $ref)
790 if ($eq($ref['type'], $type))
792 if ($gotone) echo ', ';
793 echo "<a href='".makeHref(array('page'=>'object', 'object_id'=>$ref['object_id']))."'>";
794 if (!empty ($ref['name']))
795 echo $ref['name'] . '@';
796 echo "${ref['object_name']}</a>";
802 function renderRackObject ($object_id = 0)
804 global $nextorder, $aac;
807 showError ('Invalid object_id', __FUNCTION__
);
810 $info = getObjectInfo ($object_id);
813 showError ('getObjectInfo() failed', __FUNCTION__
);
816 // Main layout starts.
817 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
818 echo "<tr><td colspan=2 align=center><h1>${info['dname']}</h1></td></tr>\n";
819 // left column with uknown number of portlets
820 echo "<tr><td class=pcleft>";
821 startPortlet ('summary');
822 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
823 if (!empty ($info['name']))
824 echo "<tr><th width='50%' class=tdright>Common name:</th><td class=tdleft>${info['name']}</td></tr>\n";
825 elseif (in_array ($info['objtype_id'], explode (',', getConfigVar ('NAMEFUL_OBJTYPES'))))
826 echo "<tr><td colspan=2 class=msg_error>Common name is missing.</td></tr>\n";
827 echo "<tr><th width='50%' class=tdright>Object type:</th>";
828 echo "<td class=tdleft><a href='".makeHref(array('page'=>'objgroup', 'group_id'=>$info['objtype_id'], 'hl_object_id'=>$object_id))."'>${info['objtype_name']}</a></td></tr>\n";
829 if (!empty ($info['asset_no']))
830 echo "<tr><th width='50%' class=tdright>Asset tag:</th><td class=tdleft>${info['asset_no']}</td></tr>\n";
831 elseif (in_array ($info['objtype_id'], explode (',', getConfigVar ('REQUIRE_ASSET_TAG_FOR'))))
832 echo "<tr><td colspan=2 class=msg_error>Asset tag is missing.</td></tr>\n";
833 if (!empty ($info['label']))
834 echo "<tr><th width='50%' class=tdright>Visible label:</th><td class=tdleft>${info['label']}</td></tr>\n";
835 if (!empty ($info['barcode']))
836 echo "<tr><th width='50%' class=tdright>Barcode:</th><td class=tdleft>${info['barcode']}</td></tr>\n";
837 if ($info['has_problems'] == 'yes')
838 echo "<tr><td colspan=2 class=msg_error>Has problems</td></tr>\n";
839 foreach (getAttrValues ($object_id, TRUE) as $record)
840 if (!empty ($record['value']))
841 echo "<tr><th width='50%' class=tdright><span class=sticker>${record['name']}</span>:</th><td class=tdleft>${record['a_value']}</td></tr>\n";
842 printTagTRs (makeHref(array('page'=>'objgroup', 'tab'=>'default', 'group_id'=>$info['objtype_id']))."&");
843 echo "</table><br>\n";
846 if (!empty ($info['comment']))
848 startPortlet ('Comment');
849 echo '<div class=commentblock>' . string_insert_hrefs ($info['comment']) . '</div>';
853 renderFilesPortlet ('object', $object_id);
855 $ports = getObjectPortsAndLinks ($object_id);
858 startPortlet ('ports and links');
859 usort($ports, 'sortByName');
863 if (isset ($_REQUEST['hl_port_id']))
865 assertUIntArg ('hl_port_id', __FUNCTION__
);
866 $hl_port_id = $_REQUEST['hl_port_id'];
868 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
869 echo "<tr><th>Local name</th><th>Visible label</th><th>Port type</th><th>L2 address</th>";
870 echo "<th>Rem. Object</th><th>Rem. port</th></tr>\n";
871 foreach ($ports as $port)
874 if ($hl_port_id == $port['id'])
875 echo ' class=port_highlight';
876 echo "><td>${port['name']}</td><td>${port['label']}</td><td>${port['type']}</td>";
877 echo "<td>${port['l2address']}</td>";
878 if ($port['remote_object_id'])
880 echo "<td><a href='".makeHref(array('page'=>'object', 'object_id'=>$port['remote_object_id'], 'hl_port_id'=>$port['remote_id']))."'>${port['remote_object_name']}</a></td>";
881 echo "<td>${port['remote_name']}</td>";
883 elseif (!empty ($port['reservation_comment']))
885 echo "<td><b>Reserved;</b></td>";
886 echo "<td>${port['reservation_comment']}</td>";
889 echo '<td> </td><td> </td>';
892 echo "</table><br>\n";
897 $alloclist = getObjectIPv4Allocations ($object_id);
898 if (count ($alloclist))
900 startPortlet ('IPv4 addresses');
901 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
902 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
903 echo "<tr><th>OS interface</th><th>IP address</th><th>network</th><th>routed by</th><th>peers</th></tr>\n";
905 echo "<tr><th>OS interface</th><th>IP address</th><th>peers</th></tr>\n";
907 if (isset ($_REQUEST['hl_ipv4_addr']))
909 assertIPv4Arg ('hl_ipv4_addr', __FUNCTION__
);
910 $hl_ipv4_addr = $_REQUEST['hl_ipv4_addr'];
912 foreach ($alloclist as $dottedquad => $alloc)
914 $address_name = niftyString ($alloc['addrinfo']['name']);
915 $class = $alloc['addrinfo']['class'];
916 $secondclass = ($hl_ipv4_addr == $dottedquad) ?
'tdleft port_highlight' : 'tdleft';
917 $netid = getIPv4AddressNetworkId ($dottedquad);
920 $netinfo = getIPv4NetworkInfo ($netid);
921 loadIPv4AddrList ($netinfo);
923 echo "<tr class='${class}' valign=top><td class=tdleft>${alloc['osif']}</td><td class='${secondclass}'>";
925 echo "<a href='".makeHref(array('page'=>'ipaddress', 'ip'=>$dottedquad, 'hl_object_id'=>$object_id))."'>${dottedquad}</a>";
928 if (getConfigVar ('EXT_IPV4_VIEW') != 'yes')
929 echo '<small>/' . (NULL === $netid ?
'??' : $netinfo['mask']) . '</small>';
930 echo ' ' . $aac[$alloc['type']];
931 if (!empty ($alloc['addrinfo']['name']))
932 echo ' (' . niftyString ($alloc['addrinfo']['name']) . ')';
934 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
937 echo '<td class=sparenetwork>N/A</td><td class=sparenetwork>N/A</td>';
940 echo "<td class='${secondclass}'>";
941 renderIPv4NetCell ($netinfo);
943 // filter out self-allocation
944 $other_routers = array();
945 foreach (findRouters ($netinfo['addrlist']) as $router)
946 if ($router['id'] != $object_id)
947 $other_routers[] = $router;
948 if (count ($other_routers))
949 printRoutersTD ($other_routers);
951 echo "<td class='${secondclass}'> </td>";
955 echo "<td class='${secondclass}'>\n";
957 if ($alloc['addrinfo']['reserved'] == 'yes')
959 echo $prefix . '<strong>RESERVED</strong>';
962 foreach ($alloc['addrinfo']['allocs'] as $allocpeer)
964 if ($allocpeer['object_id'] == $object_id)
966 echo $prefix . "<a href='".makeHref(array('page'=>'object', 'object_id'=>$allocpeer['object_id']))."'>";
967 if (!empty ($allocpeer['osif']))
968 echo $allocpeer['osif'] . '@';
969 echo $allocpeer['object_name'] . '</a>';
974 echo "</table><br>\n";
978 $forwards = getNATv4ForObject ($object_id);
979 if (count($forwards['in']) or count($forwards['out']))
981 startPortlet('NATv4');
983 if (count($forwards['out']))
986 echo "<h3>locally performed NAT</h3>";
988 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
989 echo "<tr><th>Proto</th><th>Match endpoint</th><th>Translate to</th><th>Target object</th><th>Rule comment</th></tr>\n";
991 foreach ($forwards['out'] as $pf)
995 if (isset ($alloclist [$pf['localip']]))
997 $class = $alloclist [$pf['localip']]['addrinfo']['class'];
998 $osif = $alloclist [$pf['localip']]['osif'] . ': ';
1000 echo "<tr class='$class'>";
1001 echo "<td>${pf['proto']}</td><td class=tdleft>${osif}<a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['localip']))."'>${pf['localip']}</a>:${pf['localport']}</td>";
1002 echo "<td class=tdleft><a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['remoteip']))."'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
1003 $address = getIPv4Address ($pf['remoteip']);
1004 echo "<td class='description'>";
1005 if (count ($address['allocs']))
1006 foreach($address['allocs'] as $bond)
1007 echo "<a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$bond['object_id']))."'>${bond['object_name']}(${bond['name']})</a> ";
1008 elseif (!empty ($pf['remote_addr_name']))
1009 echo '(' . $pf['remote_addr_name'] . ')';
1010 echo "</td><td class='description'>${pf['description']}</td></tr>";
1012 echo "</table><br><br>";
1014 if (count($forwards['in']))
1016 echo "<h3>arriving NAT connections</h3>";
1017 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
1018 echo "<tr><th>Matched endpoint</th><th>Source object</th><th>Translated to</th><th>Rule comment</th></tr>\n";
1019 foreach ($forwards['in'] as $pf)
1022 echo "<td>${pf['proto']}/<a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['localip']))."'>${pf['localip']}</a>:${pf['localport']}</td>";
1023 echo "<td class='description'><a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$pf['object_id']))."'>${pf['object_name']}</a>";
1024 echo "</td><td><a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['remoteip']))."'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
1025 echo "<td class='description'>${pf['description']}</td></tr>";
1027 echo "</table><br><br>";
1032 $pools = getRSPoolsForObject ($object_id);
1036 startPortlet ('Real server pools (' . count ($pools) . ')');
1037 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
1038 echo "<tr><th>VS</th><th>RS pool</th><th>RS</th><th>VS config</th><th>RS config</th></tr>\n";
1039 foreach ($pools as $vs_id => $info)
1041 echo "<tr valign=top class=row_${order}><td class=tdleft>";
1042 renderVSCell ($vs_id);
1043 echo "</td><td class=tdleft>";
1044 renderRSPoolCell ($info['pool_id'], $info['pool_name']);
1045 echo '</td><td class=tdleft>' . $info['rscount'] . '</td>';
1046 echo "<td class=slbconf>${info['vsconfig']}</td>";
1047 echo "<td class=slbconf>${info['rsconfig']}</td>";
1049 $order = $nextorder[$order];
1056 // After left column we have (surprise!) right column with rackspace portlet only.
1057 echo "<td class=pcright>";
1058 // rackspace portlet
1059 startPortlet ('rackspace allocation');
1060 // FIXME: now we call getRackData() twice
1061 $racks = getResidentRacksData ($object_id);
1062 foreach ($racks as $rackData)
1063 renderRack ($rackData['id'], $object_id);
1070 function renderRackMultiSelect ($sname, $racks, $selected)
1072 // Transform the given flat list into a list of groups, each representing a rack row.
1074 foreach ($racks as $rack)
1075 if (!isset ($rdata[$rack['row_name']]))
1076 $rdata[$rack['row_name']] = array ($rack['id'] => $rack['name']);
1078 $rdata[$rack['row_name']][$rack['id']] = $rack['name'];
1079 echo "<select name=${sname} multiple size=" . getConfigVar ('MAXSELSIZE') . " onchange='getElementsByName(\"updateObjectAllocation\")[0].submit()'>\n";
1080 foreach ($rdata as $optgroup => $racklist)
1082 echo "<optgroup label='${optgroup}'>";
1083 foreach ($racklist as $rack_id => $rack_name)
1085 echo "<option value=${rack_id}";
1086 if (!(array_search ($rack_id, $selected) === FALSE))
1088 echo">${rack_name}</option>\n";
1094 function showMessageOrError ()
1096 if (isset ($_SESSION['log']))
1098 printLog ($_SESSION['log']);
1099 unset($_SESSION['log']);
1103 // This function renders a form for port edition.
1104 function renderPortsForObject ($object_id = 0)
1106 function printNewItemTR ()
1108 printOpFormIntro ('addPort');
1110 printImageHREF ('add', 'add a port', TRUE);
1111 echo "</td><td><input type=text size=8 name=port_name tabindex=100></td>\n";
1112 echo "<td><input type=text size=24 name=port_label tabindex=101></td><td>";
1113 printSelect (getPortTypes(), 'port_type_id', getConfigVar ('default_port_type'), 102);
1114 echo "<td><input type=text name=port_l2address tabindex=103></td>\n";
1115 echo "<td colspan=3> </td><td>";
1116 printImageHREF ('add', 'add a port', TRUE, 104);
1117 echo "</td></tr></form>";
1119 global $pageno, $tabno;
1120 if ($object_id <= 0)
1122 showError ('Invalid object_id', __FUNCTION__
);
1125 showMessageOrError();
1126 startPortlet ('Ports and interfaces');
1127 $ports = getObjectPortsAndLinks ($object_id);
1128 usort($ports, 'sortByName');
1129 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
1130 echo "<tr><th> </th><th>Local name</th><th>Visible label</th><th>Port type</th><th>L2 address</th>";
1131 echo "<th>Rem. object</th><th>Rem. port</th><th>(Un)link or (un)reserve</th><th> </th></tr>\n";
1132 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
1134 foreach ($ports as $port)
1136 printOpFormIntro ('editPort', array ('port_id' => $port['id']));
1137 echo "<tr><td><a href='".makeHrefProcess(array('op'=>'delPort', 'port_id'=>$port['id'], 'object_id'=>$object_id, 'port_name'=>$port['name']))."'>";
1138 printImageHREF ('delete', 'Unlink and Delete this port');
1140 echo "<td><input type=text name=name value='${port['name']}' size=8></td>";
1141 echo "<td><input type=text name=label value='${port['label']}' size=24></td>";
1142 if (!$port['remote_object_id'])
1145 printSelect (getPortTypes(), 'port_type_id', $port['type_id']);
1150 echo "<input type=hidden name=port_type_id value='${port['type_id']}'>";
1151 echo "<td class=tdleft>${port['type']}</td>\n";
1153 echo "<td><input type=text name=l2address value='${port['l2address']}'></td>\n";
1154 if ($port['remote_object_id'])
1156 echo "<td><a href='".makeHref(array('page'=>'object', 'object_id'=>$port['remote_object_id']))."'>${port['remote_object_name']}</a></td>";
1157 echo "<td>${port['remote_name']}</td>";
1158 echo "<td><a href='".
1159 makeHrefProcess(array(
1161 'port_id'=>$port['id'],
1162 'object_id'=>$object_id,
1163 'port_name'=>$port['name'],
1164 'remote_port_name'=>$port['remote_name'],
1165 'remote_object_name'=>$port['remote_object_name'])).
1167 printImageHREF ('cut', 'Unlink this port');
1170 elseif (!empty ($port['reservation_comment']))
1172 echo "<td><b>Reserved;</b></td>";
1173 echo "<td><input type=text name=reservation_comment value='${port['reservation_comment']}'></td>";
1174 echo "<td><a href='".
1175 makeHrefProcess(array(
1177 'port_id'=>$port['id'],
1178 'object_id'=>$object_id)).
1180 printImageHREF ('clear', 'Use up this port');
1185 echo "<td> </td><td> </td>";
1187 echo "<a href='javascript:;' onclick='window.open(\"".makeHrefForHelper('portlist', array('port'=>$port['id'], 'type'=>$port['type_id'], 'object_id'=>$object_id, 'port_name'=>$port['name']))."\",\"findlink\",\"height=700, width=400, location=no, menubar=no, resizable=yes, scrollbars=no, status=no, titlebar=no, toolbar=no\");'>";
1188 printImageHREF ('plug', 'Link this port');
1189 echo "</a> <input type=text name=reservation_comment>";
1193 printImageHREF ('save', 'Save changes', TRUE);
1194 echo "</td></form></tr>\n";
1196 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
1198 echo "</table><br>\n";
1201 startPortlet ('Add/update multiple ports');
1202 printOpFormIntro ('addMultiPorts');
1203 echo 'Format: <select name=format tabindex=201>';
1204 echo '<option value=c3600asy>Cisco 3600 async: sh line | inc TTY</option>';
1205 echo '<option value=fiwg selected>Foundry ServerIron/FastIron WorkGroup/Edge: sh int br</option>';
1206 echo '<option value=fisxii>Foundry FastIron SuperX/II4000: sh int br</option>';
1207 echo '<option value=ssv1>SSV:<interface name> <MAC address></option>';
1209 echo 'Default port type: ';
1210 printSelect (getPortTypes(), 'port_type', getConfigVar ('default_port_type'), 202);
1211 echo "<input type=submit value='Parse output' tabindex=204><br>\n";
1212 echo "<textarea name=input cols=100 rows=50 tabindex=203></textarea><br>\n";
1217 function renderIPv4ForObject ($object_id = 0)
1219 function printNewItemTR ()
1222 printOpFormIntro ('addIPv4Allocation');
1224 printImageHREF ('add', 'allocate', TRUE);
1226 echo "<td class=tdleft><input type='text' size='10' name='bond_name' tabindex=100></td>\n";
1227 echo "<td class=tdleft><input type=text name='ip' tabindex=101></td>\n";
1228 echo "<td colspan=2> </td><td>";
1229 printSelect ($aat, 'bond_type', NULL, 102);
1230 echo "</td><td> </td><td>";
1231 printImageHREF ('add', 'allocate', TRUE, 103);
1232 echo "</td></tr></form>";
1234 global $pageno, $tabno, $aat;
1235 if ($object_id <= 0)
1237 showError ('Invalid object_id', __FUNCTION__
);
1240 showMessageOrError();
1241 startPortlet ('Allocations');
1242 $alloclist = getObjectIPv4Allocations ($object_id);
1243 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
1244 echo '<tr><th> </th><th>OS interface</th><th>IP address</th>';
1245 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
1246 echo '<th>network</th><th>routed by</th>';
1247 echo '<th>type</th><th>misc</th><th> </th></tr>';
1249 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
1251 foreach ($alloclist as $dottedquad => $alloc)
1253 $class = $alloc['addrinfo']['class'];
1254 $netid = getIPv4AddressNetworkId ($dottedquad);
1255 if (NULL !== $netid)
1257 $netinfo = getIPv4NetworkInfo ($netid);
1258 loadIPv4AddrList ($netinfo);
1260 printOpFormIntro ('updIPv4Allocation', array ('ip' => $dottedquad));
1261 echo "<tr class='$class' valign=top><td><a href='".makeHrefProcess(array('op'=>'delIPv4Allocation', 'ip'=>$dottedquad, 'object_id'=>$object_id))."'>";
1262 printImageHREF ('delete', 'Delete this IPv4 address');
1264 echo "<td class=tdleft><input type='text' name='bond_name' value='${alloc['osif']}' size=10></td><td class=tdleft>";
1265 if (NULL !== $netid)
1266 echo "<a href='".makeHref(array('page'=>'ipaddress', 'ip'=>$dottedquad))."'>${dottedquad}</a>";
1269 if (getConfigVar ('EXT_IPV4_VIEW') != 'yes')
1270 echo '<small>/' . (NULL === $netid ?
'??' : $netinfo['mask']) . '</small>';
1271 if (!empty ($alloc['addrinfo']['name']))
1272 echo ' (' . niftyString ($alloc['addrinfo']['name']) . ')';
1274 // FIXME: this a copy-and-paste from renderRackObject()
1275 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
1277 if (NULL === $netid)
1278 echo '<td class=sparenetwork>N/A</td><td class=sparenetwork>N/A</td>';
1282 renderIPv4NetCell ($netinfo);
1284 // filter out self-allocation
1285 $other_routers = array();
1286 foreach (findRouters ($netinfo['addrlist']) as $router)
1287 if ($router['id'] != $object_id)
1288 $other_routers[] = $router;
1289 if (count ($other_routers))
1290 printRoutersTD ($other_routers);
1292 echo "<td> </td>";
1296 printSelect ($aat, 'bond_type', $alloc['type']);
1299 if ($alloc['addrinfo']['reserved'] == 'yes')
1301 echo $prefix . '<strong>RESERVED</strong>';
1304 foreach ($alloc['addrinfo']['allocs'] as $allocpeer)
1306 if ($allocpeer['object_id'] == $object_id)
1308 echo $prefix . "<a href='".makeHref(array('page'=>'object', 'object_id'=>$allocpeer['object_id']))."'>";
1309 if (!empty ($allocpeer['osif']))
1310 echo $allocpeer['osif'] . '@';
1311 echo $allocpeer['object_name'] . '</a>';
1315 printImageHREF ('save', 'Save changes', TRUE);
1316 echo "</td></form></tr>\n";
1318 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
1321 echo "</table><br>\n";
1326 // Log structure versions:
1327 // 1: the whole structure is a list of code-message pairs
1328 // 2 and later: there's a "v" field set, which indicates the version
1329 // 2: there's a "m" list set to hold message code and optional arguments
1330 function printLog ($log)
1334 case !isset ($log['v']):
1335 case $log['v'] == 1:
1336 foreach ($log as $key => $record)
1338 echo "<div class=msg_${record['code']}>${record['message']}</div>";
1340 case $log['v'] == 2:
1343 // records 0~99 with success messages
1344 0 => array ('code' => 'success', 'format' => 'Success: %s'),
1345 1 => array ('code' => 'success', 'format' => '%u new records done, %u already existed'),
1346 2 => array ('code' => 'success', 'format' => 'NATv4 rule was successfully added.'),
1347 3 => array ('code' => 'success', 'format' => 'NATv4 rule was successfully deleted.'),
1348 4 => array ('code' => 'success', 'format' => 'NATv4 rule was successfully updated'),
1349 5 => array ('code' => 'success', 'format' => 'Port %s was added successfully'),
1350 6 => array ('code' => 'success', 'format' => 'Port %s was updated successfully'),
1351 7 => array ('code' => 'success', 'format' => 'Port %s was deleted successfully'),
1352 8 => array ('code' => 'success', 'format' => 'Port %s successfully linked with port %s at object %s'),
1353 9 => array ('code' => 'success', 'format' => 'Port %s was successfully unlinked from %s@%s'),
1354 10 => array ('code' => 'success', 'format' => 'Added %u ports, updated %u ports, encountered %u errors.'),
1355 11 => array ('code' => 'success', 'format' => 'Reservation removed.'),
1356 12 => array ('code' => 'success', 'format' => 'allocation updated'),
1357 13 => array ('code' => 'success', 'format' => 'allocated'),
1358 14 => array ('code' => 'success', 'format' => 'deallocated'),
1359 15 => array ('code' => 'success', 'format' => 'Reset succeeded.'),
1360 16 => array ('code' => 'success', 'format' => 'Update done'),
1361 17 => array ('code' => 'success', 'format' => 'Update(s) succeeded.'),
1362 18 => array ('code' => 'success', 'format' => 'Load balancer was successfully added'),
1363 19 => array ('code' => 'success', 'format' => 'Load balancer was successfully deleted'),
1364 20 => array ('code' => 'success', 'format' => 'Load balancer info was successfully updated'),
1365 21 => array ('code' => 'success', 'format' => 'Generation complete'),
1366 22 => array ('code' => 'success', 'format' => 'Chained %u tags'),
1367 23 => array ('code' => 'success', 'format' => 'IPv4 prefix successfully added'),
1368 24 => array ('code' => 'success', 'format' => 'IPv4 prefix deleted'),
1369 25 => array ('code' => 'success', 'format' => 'IPv4 prefix updated'),
1370 26 => array ('code' => 'success', 'format' => '%u IP address(es) were successfully updated'),
1371 27 => array ('code' => 'success', 'format' => 'IPv4 address updated'),
1372 28 => array ('code' => 'success', 'format' => 'Virtual service was successfully created'),
1373 29 => array ('code' => 'success', 'format' => 'Virtual service was successfully deleted'),
1374 30 => array ('code' => 'success', 'format' => 'Virtual service was successfully updated'),
1375 31 => array ('code' => 'success', 'format' => 'RS pool was successfully created'),
1376 32 => array ('code' => 'success', 'format' => 'RS pool was successfully deleted'),
1377 33 => array ('code' => 'success', 'format' => 'RS pool was successfully updated'),
1378 34 => array ('code' => 'success', 'format' => 'Real server was successfully added'),
1379 35 => array ('code' => 'success', 'format' => 'Real server was successfully deleted'),
1380 36 => array ('code' => 'success', 'format' => 'Real server was successfully updated'),
1381 37 => array ('code' => 'success', 'format' => 'Successfully added %u real servers'),
1382 38 => array ('code' => 'success', 'format' => '%u real server(s) were successfully (de)activated'),
1383 39 => array ('code' => 'success', 'format' => 'User account %s updated.'),
1384 40 => array ('code' => 'success', 'format' => 'User account %s created.'),
1387 43 => array ('code' => 'success', 'format' => 'Saved successfully.'),
1388 44 => array ('code' => 'success', 'format' => '%s failures and %s successfull changes.'),
1389 45 => array ('code' => 'success', 'format' => "Attribute '%s' created."),
1390 46 => array ('code' => 'success', 'format' => 'Rename successful.'),
1391 47 => array ('code' => 'success', 'format' => 'Attribute was deleted.'),
1392 48 => array ('code' => 'success', 'format' => 'Supplement succeeded.'),
1393 49 => array ('code' => 'success', 'format' => 'Reduction succeeded.'),
1394 50 => array ('code' => 'success', 'format' => 'Reduction succeeded.'),
1395 51 => array ('code' => 'success', 'format' => 'Update succeeded.'),
1396 52 => array ('code' => 'success', 'format' => 'Supplement succeeded.'),
1397 53 => array ('code' => 'success', 'format' => 'Chapter was deleted.'),
1398 54 => array ('code' => 'success', 'format' => 'Chapter was updated.'),
1399 55 => array ('code' => 'success', 'format' => 'Chapter was added.'),
1400 56 => array ('code' => 'success', 'format' => 'Update succeeded.'),
1401 57 => array ('code' => 'success', 'format' => 'Reset complete'),
1402 58 => array ('code' => 'success', 'format' => "Successfully deleted tag ."),
1403 59 => array ('code' => 'success', 'format' => "Created tag '%s'."),
1404 60 => array ('code' => 'success', 'format' => "Updated tag '%s'."),
1405 61 => array ('code' => 'success', 'format' => 'Password changed successfully.'),
1406 62 => array ('code' => 'success', 'format' => 'gw: %s'),
1407 63 => array ('code' => 'success', 'format' => '%u change request(s) have been processed'),
1408 64 => array ('code' => 'success', 'format' => 'Port %s@%s has been assigned to VLAN %u'),
1409 65 => array ('code' => 'success', 'format' => "Added new rack '%s'"),
1410 66 => array ('code' => 'success', 'format' => "File sent Ok via handler '%s'"),
1411 67 => array ('code' => 'success', 'format' => "Tag rolling done, %u objects involved"),
1412 68 => array ('code' => 'success', 'format' => "Updated rack '%s'"),
1413 69 => array ('code' => 'success', 'format' => 'File %s was added successfully'),
1414 70 => array ('code' => 'success', 'format' => 'File %s was updated successfully'),
1415 71 => array ('code' => 'success', 'format' => 'File %s was linked successfully'),
1416 72 => array ('code' => 'success', 'format' => 'File %s was unlinked successfully'),
1417 73 => array ('code' => 'success', 'format' => 'File %s was deleted successfully'),
1418 74 => array ('code' => 'success', 'format' => 'Row %s was added successfully'),
1419 75 => array ('code' => 'success', 'format' => 'Row %s was updated successfully'),
1420 76 => array ('code' => 'success', 'format' => 'Object %s was deleted successfully'),
1421 77 => array ('code' => 'success', 'format' => 'Row %s was deleted successfully'),
1422 78 => array ('code' => 'success', 'format' => 'File %s saved Ok'),
1423 79 => array ('code' => 'success', 'format' => 'Rack %s was deleted successfully'),
1425 // records 100~199 with fatal error messages
1426 100 => array ('code' => 'error', 'format' => 'Generic error: %s'),
1427 101 => array ('code' => 'error', 'format' => 'Port name cannot be empty'),
1428 102 => array ('code' => 'error', 'format' => "Error creating user account '%s'"),
1429 103 => array ('code' => 'error', 'format' => 'getHashByID() failed'),
1430 104 => array ('code' => 'error', 'format' => "Error updating user account '%s'"),
1434 108 => array ('code' => 'error', 'format' => '%u failures and %u successfull changes.'),
1435 109 => array ('code' => 'error', 'format' => 'Update failed!'),
1436 110 => array ('code' => 'error', 'format' => 'Supplement failed!'),
1437 111 => array ('code' => 'error', 'format' => 'Reduction failed!'),
1438 112 => array ('code' => 'error', 'format' => 'Error adding chapter.'),
1439 113 => array ('code' => 'error', 'format' => 'Error updating chapter.'),
1440 114 => array ('code' => 'error', 'format' => 'Error deleting chapter.'),
1441 115 => array ('code' => 'error', 'format' => 'Error renaming attribute.'),
1442 116 => array ('code' => 'error', 'format' => 'Error creating attribute.'),
1443 117 => array ('code' => 'error', 'format' => 'Error deleting attribute.'),
1444 118 => array ('code' => 'error', 'format' => 'Supplement failed!'),
1445 119 => array ('code' => 'error', 'format' => 'Reduction failed!'),
1446 120 => array ('code' => 'error', 'format' => 'Reset failed!'),
1447 121 => array ('code' => 'error', 'format' => 'commitUpdateObject() failed'),
1448 122 => array ('code' => 'error', 'format' => 'One or more update(s) failed!'),
1449 123 => array ('code' => 'error', 'format' => 'Cannot process submitted data: unknown format code.'),
1450 124 => array ('code' => 'error', 'format' => 'Error removing reservation!'),
1451 125 => array ('code' => 'error', 'format' => "Update failed with error: '%s'"),
1452 126 => array ('code' => 'error', 'format' => 'addRStoRSPool() failed'),
1453 127 => array ('code' => 'error', 'format' => 'Added %u real servers and encountered %u errors'),
1454 128 => array ('code' => 'error', 'format' => 'commitDeleteRS() failed'),
1455 129 => array ('code' => 'error', 'format' => 'commitDeleteLB() failed'),
1456 130 => array ('code' => 'error', 'format' => 'commitDeleteVS() failed'),
1457 131 => array ('code' => 'error', 'format' => 'invalid format requested'),
1458 132 => array ('code' => 'error', 'format' => 'invalid protocol'),
1459 133 => array ('code' => 'error', 'format' => 'commitUpdateRS() failed'),
1460 134 => array ('code' => 'error', 'format' => 'commitUpdateLB() failed'),
1461 135 => array ('code' => 'error', 'format' => 'commitUpdateVS() failed'),
1462 136 => array ('code' => 'error', 'format' => 'addLBtoRSPool() failed'),
1463 137 => array ('code' => 'error', 'format' => 'addLBtoRSPool() failed'),
1464 138 => array ('code' => 'error', 'format' => 'commitDeleteRSPool() failed'),
1465 139 => array ('code' => 'error', 'format' => 'commitUpdateRSPool() failed'),
1466 140 => array ('code' => 'error', 'format' => 'Encountered %u errors, (de)activated %u real servers'),
1467 141 => array ('code' => 'error', 'format' => 'Encountered %u errors, updated %u IP address(es)'),
1468 142 => array ('code' => 'error', 'format' => 'executeAutoPorts() failed'),
1469 143 => array ('code' => 'error', 'format' => 'Tried chaining %u tags, but experienced %u errors.'),
1470 144 => array ('code' => 'error', 'format' => "Error deleting tag: '%s'"),
1471 145 => array ('code' => 'error', 'format' => "Invalid tag name '%s'"),
1472 146 => array ('code' => 'error', 'format' => "Tag '%s' (or similar name) already exists"),
1473 147 => array ('code' => 'error', 'format' => "Could not create tag '%s' because of error '%s'"),
1474 148 => array ('code' => 'error', 'format' => "Could not update tag '%s' because of error '%s'"),
1475 149 => array ('code' => 'error', 'format' => 'Turing test failed'),
1476 150 => array ('code' => 'error', 'format' => 'Can only change password under DB authentication.'),
1477 151 => array ('code' => 'error', 'format' => 'Old password doesn\'t match.'),
1478 152 => array ('code' => 'error', 'format' => 'New passwords don\'t match.'),
1479 153 => array ('code' => 'error', 'format' => 'Password change failed.'),
1480 154 => array ('code' => 'error', 'format' => "Verification error: %s"),
1481 155 => array ('code' => 'error', 'format' => 'Save failed.'),
1482 156 => array ('code' => 'error', 'format' => 'getSwitchVLANs() failed'),
1483 157 => array ('code' => 'error', 'format' => 'operation not permitted'),
1484 158 => array ('code' => 'error', 'format' => 'Ignoring malformed record #%u in form submit'),
1485 159 => array ('code' => 'error', 'format' => 'Permission denied moving port %s from VLAN%u to VLAN%u'),
1486 160 => array ('code' => 'error', 'format' => 'Invalid arguments'),
1487 161 => array ('code' => 'error', 'format' => 'Endpoint not found. Please either set FQDN attribute or assign an IP address to the object.'),
1488 162 => array ('code' => 'error', 'format' => 'More than one IP address is assigned to this object, please configure FQDN attribute.'),
1489 163 => array ('code' => 'error', 'format' => 'Failed to get any response from queryGateway() or the gateway died'),
1490 164 => array ('code' => 'error', 'format' => 'Gateway failure: %s.'),
1491 165 => array ('code' => 'error', 'format' => 'Gateway failure: malformed reply.'),
1492 166 => array ('code' => 'error', 'format' => 'gw: %s'),
1493 167 => array ('code' => 'error', 'format' => 'Could not find port %s'),
1494 168 => array ('code' => 'error', 'format' => 'Port %s is a trunk'),
1495 169 => array ('code' => 'error', 'format' => 'Failed to configure %s, connector returned code %u'),
1496 170 => array ('code' => 'error', 'format' => 'There is no network for IP address "%s"'),
1497 171 => array ('code' => 'error', 'format' => "Failed creating rack '%s'. Already exists in this row?"),
1498 172 => array ('code' => 'error', 'format' => 'Malformed request'),
1499 173 => array ('code' => 'error', 'format' => "Invalid IPv4 prefix '%s'"),
1500 174 => array ('code' => 'error', 'format' => 'Bad IPv4 address'),
1501 175 => array ('code' => 'error', 'format' => 'Invalid netmask'),
1502 176 => array ('code' => 'error', 'format' => 'This network already exists'),
1503 177 => array ('code' => 'error', 'format' => 'commitUpdateRack() failed'),
1504 178 => array ('code' => 'error', 'format' => 'file not found'),
1505 179 => array ('code' => 'error', 'format' => 'Declining outdated text. Re-edit the file for consistency.'),
1506 180 => array ('code' => 'error', 'format' => 'Error saving file, all changes lost!'),
1508 // records 200~299 with warnings
1509 200 => array ('code' => 'warning', 'format' => 'generic warning: %s'),
1510 201 => array ('code' => 'warning', 'format' => 'nothing happened...'),
1511 202 => array ('code' => 'warning', 'format' => 'gw: %s'),
1512 203 => array ('code' => 'warning', 'format' => 'Port %s seems to be the first in VLAN %u at this switch.'),
1513 204 => array ('code' => 'warning', 'format' => 'Check uplink/downlink configuration for proper operation.'),
1514 205 => array ('code' => 'warning', 'format' => '%u change request(s) have been ignored'),
1515 206 => array ('code' => 'warning', 'format' => 'Rack is not empty'),
1517 // Handle the arguments. Is there any better way to do it?
1518 foreach ($log['m'] as $record)
1520 if (!isset ($record['c']) or !isset ($msginfo[$record['c']]))
1522 echo '<div class=msg_neutral>(this message was lost)</div>';
1525 if (isset ($record['a']))
1526 switch (count ($record['a']))
1531 $msginfo[$record['c']]['format'],
1538 $msginfo[$record['c']]['format'],
1546 $msginfo[$record['c']]['format'],
1556 $msginfo[$record['c']]['format'],
1565 $msgtext = $msginfo[$record['c']]['format'];
1566 echo '<div class=msg_' . $msginfo[$record['c']]['code'] . ">${msgtext}</div>";
1570 echo '<div class=msg_error>' . __FUNCTION__
. ': internal error</div>';
1576 The following conditions must be followed:
1577 1. We can mount onto free atoms only. This means: if any record for an atom
1578 already exists in RackSpace, it can't be used for mounting.
1579 2. We can't unmount from 'W' atoms. Operator should review appropriate comments
1580 and either delete them before unmounting or refuse to unmount the object.
1583 // We extensively use $_REQUEST in the function.
1584 // FIXME: move related code into ophandler
1585 function renderRackSpaceForObject ($object_id = 0)
1587 if ($object_id <= 0)
1589 showError ('Invalid object_id', __FUNCTION__
);
1592 $is_submit = isset ($_REQUEST['got_atoms']);
1593 $is_update = isset ($_REQUEST['rackmulti'][0]);
1594 $info = getObjectInfo ($object_id);
1597 showError ('getObjectInfo() failed', __FUNCTION__
);
1600 // Always process occupied racks plus racks chosen by user. First get racks with
1601 // already allocated rackspace...
1602 $workingRacksData = getResidentRacksData ($object_id);
1603 if ($workingRacksData === NULL)
1605 print_r ($workingRacksData);
1606 showError ('getResidentRacksData() failed', __FUNCTION__
);
1610 // ...and then add those chosen by user (if any).
1611 if (isset($_REQUEST['rackmulti']))
1612 foreach ($_REQUEST['rackmulti'] as $cand_id)
1614 if (!isset ($workingRacksData[$cand_id]))
1616 $rackData = getRackData ($cand_id);
1617 if ($rackData == NULL)
1619 showError ('getRackData() failed', __FUNCTION__
);
1622 $workingRacksData[$cand_id] = $rackData;
1626 printOpFormIntro ('updateObjectAllocation');
1628 // Do it only once...
1629 foreach ($workingRacksData as $rackId => &$rackData)
1631 applyObjectMountMask ($rackData, $object_id);
1632 echo "<input type=\"hidden\" name=\"rackmulti[]\" value=\"$rackId\">";
1634 // Now we workaround an old caveat: http://bugs.php.net/bug.php?id=37410
1637 // This is the time for rendering.
1638 global $pageno, $tabno;
1640 showMessageOrError();
1643 // Main layout starts.
1644 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0><tr>";
1646 // Left portlet with rack list.
1647 echo "<td class=pcleft height='1%'>";
1648 startPortlet ('Racks');
1649 $allRacksData = getRacksForRow();
1650 if (count ($allRacksData) <= getConfigVar ('RACK_PRESELECT_THRESHOLD'))
1652 foreach (array_keys ($allRacksData) as $rack_id)
1654 $rackData = getRackData ($rack_id);
1655 if ($rackData == NULL)
1657 showError ('getRackData() failed', __FUNCTION__
);
1660 $workingRacksData[$rack_id] = $rackData;
1662 foreach ($workingRacksData as &$rackData)
1663 applyObjectMountMask ($rackData, $object_id);
1666 renderRackMultiSelect ('rackmulti[]', $allRacksData, array_keys ($workingRacksData));
1672 // Middle portlet with comment and submit.
1673 echo "<td class=pcleft>";
1674 startPortlet ('Comment');
1675 echo "<textarea name=comment rows=10 cols=40></textarea><br>\n";
1676 echo "<input type=submit value='Save' name=got_atoms>\n";
1682 // Right portlet with rendered racks. If this form submit is not final, we have to
1683 // reflect the former state of the grid in current form.
1684 echo "<td class=pcright rowspan=2 height='1%'>";
1685 startPortlet ('Working copy');
1686 echo '<table border=0 cellspacing=10 align=center><tr>';
1687 foreach ($workingRacksData as $rack_id => $rackData)
1689 // Order is important here: only original allocation is highlighted.
1690 highlightObject ($rackData, $object_id);
1691 markupAtomGrid ($rackData, 'T');
1692 // If we have a form processed, discard user input and show new database
1694 if (!$is_submit and $is_update)
1695 mergeGridFormToRack ($rackData);
1696 echo "<td valign=top>";
1697 echo "<center>\n<h2>${rackData['name']}</h2>\n";
1698 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
1699 echo "<tr><th width='10%'> </th><th width='20%'>Front</th>";
1700 echo "<th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
1701 renderAtomGrid ($rackData);
1702 echo "<tr><th width='10%'> </th><th width='20%'>Front</th>";
1703 echo "<th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
1704 echo "</table></center>\n";
1707 echo "</tr></table>";
1713 echo "</tr></table>\n";
1716 function renderMolecule ($mdata, $object_id)
1719 $rackpack = array();
1721 foreach ($mdata as $rua)
1723 $rack_id = $rua['rack_id'];
1724 $unit_no = $rua['unit_no'];
1725 $atom = $rua['atom'];
1726 if (!isset ($rackpack[$rack_id]))
1728 $rackData = getRackData ($rack_id);
1729 for ($i = $rackData['height']; $i > 0; $i--)
1730 for ($locidx = 0; $locidx < 3; $locidx++
)
1731 $rackData[$i][$locidx]['state'] = 'F';
1732 $rackpack[$rack_id] = $rackData;
1734 $rackpack[$rack_id][$unit_no][$loclist[$atom]]['state'] = 'T';
1735 $rackpack[$rack_id][$unit_no][$loclist[$atom]]['object_id'] = $object_id;
1737 // now we have some racks to render
1738 foreach ($rackpack as $rackData)
1740 markAllSpans ($rackData);
1741 echo "<table class=molecule cellspacing=0>\n";
1742 echo "<caption>${rackData['name']}</caption>\n";
1743 echo "<tr><th width='10%'> </th><th width='20%'>Front</th><th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
1744 for ($i = $rackData['height']; $i > 0; $i--)
1746 echo "<tr><th>$i</th>";
1747 for ($locidx = 0; $locidx < 3; $locidx++
)
1749 $state = $rackData[$i][$locidx]['state'];
1750 echo "<td class=state_${state}> </td>\n";
1758 function renderUnmountedObjectsPortlet ()
1760 startPortlet ('Unmounted objects');
1761 $objs = getUnmountedObjects();
1764 showError ('getUnmountedObjects() failed', __FUNCTION__
);
1769 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1770 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset number</th><th>Barcode</th></tr>';
1771 foreach ($objs as $obj)
1773 echo "<tr class=row_${order}><td><a href='".makeHref(array('page'=>'object', 'object_id'=>$obj['id']))."'>${obj['dname']}</a></td>";
1774 echo "<td>${obj['label']}</td>";
1775 echo "<td>${obj['asset_no']}</td>";
1776 echo "<td>${obj['barcode']}</td>";
1778 $order = $nextorder[$order];
1780 echo "</table><br>\n";
1784 function renderProblematicObjectsPortlet ()
1786 startPortlet ('Problematic objects');
1787 $objs = getProblematicObjects();
1790 showError ('getProblematicObjects() failed', __FUNCTION__
);
1795 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1796 echo '<tr><th>Type</th><th>Common name</th></tr>';
1797 foreach ($objs as $obj)
1799 echo "<tr class=row_${order}><td>${obj['objtype_name']}</td>";
1800 echo "<td><a href='".makeHref(array('page'=>'object', 'object_id'=>$obj['id']))."'>${obj['dname']}</a></tr>";
1801 $order = $nextorder[$order];
1803 echo "</table><br>\n";
1807 function renderObjectSpace ()
1809 global $taglist, $tagtree;
1810 showMessageOrError();
1811 echo "<table border=0 class=objectview>\n";
1812 echo "<tr><td class=pcleft width='50%'>";
1813 startPortlet ('View all by type');
1814 $groupInfo = getObjectGroupInfo();
1815 if ($groupInfo === NULL)
1817 showError ('getObjectGroupInfo() failed', __FUNCTION__
);
1820 if (count ($groupInfo) == 0)
1821 echo "No objects exist in DB";
1824 echo '<div align=left><ul>';
1825 foreach ($groupInfo as $gi)
1826 echo "<li><a href='".makeHref(array('page'=>'objgroup', 'group_id'=>$gi['id']))."'>${gi['name']}</a> (${gi['count']})</li>";
1831 echo '</td><td class=pcright>';
1833 startPortlet ('View all by tag');
1834 if (count ($taglist) == 0)
1835 echo "No tags exist in DB";
1837 renderTagCloud ('object');
1839 echo "</td></tr></table>\n";
1842 function renderObjectGroup ()
1844 global $pageno, $tabno, $nextorder, $taglist, $tagtree;
1845 showMessageOrError();
1846 assertUIntArg ('group_id', __FUNCTION__
, TRUE);
1847 $group_id = $_REQUEST['group_id'];
1848 $tagfilter = getTagFilter();
1849 $tagfilter_str = getTagFilterStr ($tagfilter);
1850 echo "<table border=0 class=objectview>\n";
1851 echo "<tr><td class=pcleft width='25%'>";
1852 startPortlet ('change type');
1853 $groupInfo = getObjectGroupInfo();
1854 if ($groupInfo === NULL)
1856 showError ('getObjectGroupInfo() failed', __FUNCTION__
);
1859 if (count ($groupInfo) == 0)
1860 echo "No objects exist in DB";
1863 echo '<div align=left><ul>';
1864 foreach ($groupInfo as $gi)
1866 echo "<li><a href='".makeHref(array('page'=>$pageno, 'group_id'=>$gi['id']))."${tagfilter_str}'>";
1867 if ($gi['id'] == $group_id)
1869 echo "${gi['name']}</a>";
1870 if ($gi['id'] == $group_id)
1872 echo " (${gi['count']})";
1873 if ($gi['id'] == $group_id)
1881 echo '</td><td class=pcleft>';
1883 $objects = getObjectList ($group_id, $tagfilter, getTFMode());
1884 startPortlet ('Objects (' . count ($objects) . ')');
1885 if ($objects === NULL)
1887 showError ('getObjectList() failed', __FUNCTION__
);
1890 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1891 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>Barcode</th><th>Row/Rack</th><th></th></tr>';
1893 foreach ($objects as $obj)
1895 if (isset ($_REQUEST['hl_object_id']) and $_REQUEST['hl_object_id'] == $obj['id'])
1896 $secondclass = 'tdleft port_highlight';
1898 $secondclass = 'tdleft';
1899 $tags = loadRackObjectTags ($obj['id']);
1900 echo "<tr class=row_${order} valign=top><td class='${secondclass}'><a href='".makeHref(array('page'=>'object', 'object_id'=>$obj['id']))."'><strong>${obj['dname']}</strong></a>";
1902 echo '<br><small>' . serializeTags ($tags, makeHref(array('page'=>$pageno, 'tab'=>'default', 'group_id'=>$group_id))."&") . '</small>';
1903 echo "</td><td class='${secondclass}'>${obj['label']}</td>";
1904 echo "<td class='${secondclass}'>${obj['asset_no']}</td>";
1905 echo "<td class='${secondclass}'>${obj['barcode']}</td>";
1906 if ($obj['rack_id'])
1907 echo "<td class='${secondclass}'><a href='".makeHref(array('page'=>'row', 'row_id'=>$obj['row_id']))."'>${obj['Row_name']}</a>/<a href='".makeHref(array('page'=>'rack', 'rack_id'=>$obj['rack_id']))."'>${obj['Rack_name']}</a></td>";
1909 echo "<td class='${secondclass}'>Unmounted</td>";
1911 $order = $nextorder[$order];
1916 echo "</td><td class=pcright width='25%'>";
1918 renderTagFilterPortlet ($tagfilter, 'object', 'group_id', $group_id);
1919 echo "</td></tr></table>\n";
1922 function renderEmptyPortsSelect ($port_id, $type_id)
1924 $ports = getEmptyPortsOfType($type_id);
1925 usort($ports, 'sortEmptyPorts');
1926 foreach ($ports as $port)
1928 if ($port_id == $port['Port_id'])
1930 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";
1934 function renderAllIPv4Allocations ()
1936 $addresses = getAllIPv4Allocations();
1937 usort($addresses, 'sortObjectAddressesAndNames');
1938 foreach ($addresses as $address)
1940 echo "<option value='${address['ip']}' onclick='getElementById(\"ip\").value=\"${address['ip']}\";'>${address['object_name']} ${address['name']} ${address['ip']}</option>\n";
1944 // History viewer for history-enabled simple dictionaries.
1945 function renderHistory ($object_type, $object_id)
1947 switch ($object_type)
1950 $query = "select ctime, user_name, name, deleted, comment from RackRowHistory where id = ${object_id} order by ctime";
1951 $header = '<tr><th>change time</th><th>author</th><th>rack row name</th><th>is deleted?</th><th>rack row comment</th></tr>';
1956 "select ctime, user_name, rh.name, rh.deleted, rr.name as name, rh.height, rh.comment " .
1957 "from RackHistory as rh left join RackRow as rr on rh.row_id = rr.id " .
1958 "where rh.id = ${object_id} order by ctime";
1959 $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>';
1964 "select ctime, user_name, RackObjectHistory.name as name, label, barcode, asset_no, deleted, has_problems, dict_value, comment " .
1965 "from RackObjectHistory inner join Dictionary on objtype_id = dict_key join Chapter on Dictionary.chapter_id = Chapter.id " .
1966 "where Chapter.name = 'RackObjectType' and RackObjectHistory.id=${object_id} order by ctime";
1967 $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>';
1971 showError ("Uknown object type '${object_type}'", __FUNCTION__
);
1975 $result = $dbxlink->query ($query);
1976 if ($result == NULL)
1978 showError ('SQL query failed', __FUNCTION__
);
1981 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1985 while ($row = $result->fetch (PDO
::FETCH_NUM
))
1987 echo "<tr class=row_${order}><td>${row[0]}</td>";
1988 for ($i = 1; $i <= $extra; $i++
)
1989 echo "<td>" . $row[$i] . "</td>";
1991 $order = $nextorder[$order];
1993 echo "</table><br>\n";
1996 function renderRackspaceHistory ()
1998 global $nextorder, $pageno, $tabno;
2000 $history = getRackspaceHistory();
2001 // Show the last operation by default.
2002 if (isset ($_REQUEST['op_id']))
2003 $op_id = $_REQUEST['op_id'];
2004 elseif (isset ($history[0]['mo_id']))
2005 $op_id = $history[0]['mo_id'];
2012 list ($omid, $nmid) = getOperationMolecules ($op_id);
2014 // Main layout starts.
2015 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
2017 // Left top portlet with old allocation.
2018 echo "<tr><td class=pcleft>";
2019 startPortlet ('Old allocation');
2022 $oldMolecule = getMolecule ($omid);
2023 renderMolecule ($oldMolecule, $object_id);
2029 echo '</td><td class=pcright>';
2031 // Right top portlet with new allocation
2032 startPortlet ('New allocation');
2035 $newMolecule = getMolecule ($nmid);
2036 renderMolecule ($newMolecule, $object_id);
2042 echo '</td></tr><tr><td colspan=2>';
2044 // Bottom portlet with list
2046 startPortlet ('Rackspace allocation history');
2047 echo "<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>\n";
2048 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";
2049 foreach ($history as $row)
2051 if ($row['mo_id'] == $op_id)
2054 $class = "row_${order}";
2055 echo "<tr class=${class}><td><a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno, 'op_id'=>$row['mo_id']))."'>${row['ctime']}</a></td>";
2056 echo "<td>${row['user_name']}</td>";
2057 echo "<td>${row['ro_id']}</td><td>${row['objtype_name']}</td><td>${row['name']}</td><td>${row['comment']}</td>\n";
2059 $order = $nextorder[$order];
2064 echo '</td></tr></table>';
2067 function renderIPv4SpaceRecords ($tree, &$tagcache, $baseurl, $target = 0, $level = 1)
2069 $self = __FUNCTION__
;
2070 foreach ($tree as $item)
2072 $total = $item['addrt'];
2073 if (getConfigVar ('IPV4_TREE_SHOW_USAGE') == 'yes')
2075 loadIPv4AddrList ($item); // necessary to compute router list and address counter
2076 $used = $item['addrc'];
2080 $item['addrlist'] = array();
2083 if (isset ($item['id']))
2085 if ($item['symbol'] == 'node-collapsed')
2086 $expandurl = "${baseurl}&eid=" . $item['id'] . "#netid" . $item['id'];
2087 elseif ($item['symbol'] == 'node-expanded')
2088 $expandurl = $baseurl . ($item['parent_id'] ?
"&eid=${item['parent_id']}#netid${item['parent_id']}" : '');
2091 echo "<tr valign=top>";
2092 printIPv4NetInfoTDs ($item, 'tdleft', $level, $item['symbol'], $expandurl);
2093 echo "<td class=tdcenter>";
2094 if ($target == $item['id'])
2095 echo "<a name=netid${target}></a>";
2096 if (getConfigVar ('IPV4_TREE_SHOW_USAGE') == 'yes')
2098 renderProgressBar ($total ?
$used/$total : 0);
2099 echo "<br><small>${used}/${total}</small>";
2102 echo "<small>${total}</small>";
2104 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
2105 printRoutersTD (findRouters ($item['addrlist']), $tagcache);
2107 if ($item['symbol'] == 'node-expanded' or $item['symbol'] == 'node-expanded-static')
2108 $self ($item['kids'], $tagcache, $baseurl, $target, $level +
1);
2112 echo "<tr valign=top>";
2113 printIPv4NetInfoTDs ($item, 'tdleft sparenetwork', $level, $item['symbol']);
2114 echo "<td class=tdcenter>";
2115 if (getConfigVar ('IPV4_TREE_SHOW_USAGE') == 'yes')
2117 renderProgressBar ($used/$total, 'sparenetwork');
2118 echo "<br><small>${used}/${total}</small>";
2121 echo "<small>${total}</small>";
2122 echo "</td><td> </td></tr>";
2127 function renderIPv4Space ()
2129 global $pageno, $tabno;
2130 $tagfilter = getTagFilter();
2131 $netlist = getIPv4NetworkList ($tagfilter, getTFMode());
2134 $netcount = count ($netlist);
2135 // expand request can take either natural values or "ALL". Zero means no expanding.
2136 $eid = isset ($_REQUEST['eid']) ?
$_REQUEST['eid'] : 0;
2137 $tree = prepareIPv4Tree ($netlist, $eid);
2139 echo "<table border=0 class=objectview>\n";
2140 echo "<tr><td class=pcleft>";
2141 startPortlet ("networks (${netcount})");
2144 echo 'auto-collapsing at threshold ' . getConfigVar ('TREE_THRESHOLD') . " (<a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno, 'eid'=>'ALL'))."'>expand all</a>)";
2145 elseif ($eid === 'ALL')
2146 echo "expanding all (<a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno))."'>auto-collapse</a>)";
2149 $netinfo = getIPv4NetworkInfo ($eid);
2150 echo "expanding ${netinfo['ip']}/${netinfo['mask']} (<a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno))."'>auto-collapse</a> / <a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno, 'eid'=>'ALL'))."'>expand all</a>)";
2152 echo "</h4><table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
2153 echo "<tr><th>prefix</th><th>name/tags</th><th>capacity</th>";
2154 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
2155 echo "<th>routed by</th>";
2157 $tagcache = array();
2158 $baseurl = makeHref(array('page'=>$pageno, 'tab'=>$tabno)) . getTagFilterStr ($tagfilter);
2159 renderIPv4SpaceRecords ($tree, $tagcache, $baseurl, $eid);
2162 echo '</td><td class=pcright>';
2163 renderTagFilterPortlet ($tagfilter, 'ipv4net');
2164 echo "</td></tr></table>\n";
2167 function renderIPv4SLB ()
2169 global $page, $nextorder;
2171 startPortlet ('SLB configuration');
2172 echo "<table border=0 width='100%'><tr>";
2173 foreach (array ('ipv4vslist', 'ipv4rsplist', 'rservers', 'lbs') as $pno)
2174 echo "<td><h3><a href='".makeHref(array('page'=>$pno))."'>" . $page[$pno]['title'] . "</a></h3></td>";
2175 echo '</tr></table>';
2178 $summary = getSLBSummary();
2179 startPortlet ('SLB tactical overview');
2180 // A single id-keyed array isn't used here to preserve existing
2181 // order of LBs returned by getSLBSummary()
2184 foreach ($summary as $vipdata)
2185 foreach (array_keys ($vipdata['lblist']) as $lb_object_id)
2186 if (!in_array ($lb_object_id, $lblist))
2188 $oi = getObjectInfo ($lb_object_id);
2189 $lbdname[$lb_object_id] = $oi['dname'];
2190 $lblist[] = $lb_object_id;
2192 if (!count ($summary))
2193 echo 'none configured';
2197 echo "<table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
2198 echo "<tr valign=top><td> </td>";
2199 foreach ($lblist as $lb_object_id)
2201 #echo "<th><a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$lb_object_id))."'>" . $lbdname[$lb_object_id] . "</a></th>";
2203 renderLBCell ($lb_object_id);
2207 foreach ($summary as $vsid => $vsdata)
2209 echo "<tr class=row_${order}><td class=tdleft>";
2210 renderVSCell ($vsid);
2212 foreach ($lblist as $lb_object_id)
2214 echo '<td class=tdleft>';
2215 if (!isset ($vsdata['lblist'][$lb_object_id]))
2219 echo $vsdata['lblist'][$lb_object_id]['size'];
2220 // echo " (<a href='".makeHref(array('page'=>'ipv4rspool', 'pool_id'=>$vsdata['lblist'][$lb_object_id]['id'])). "'>";
2221 // echo $vsdata['lblist'][$lb_object_id]['name'] . '</a>)';
2226 $order = $nextorder[$order];
2233 function renderIPv4SpaceEditor ()
2235 global $pageno, $tabno;
2236 showMessageOrError();
2240 <script type
="text/javascript">
2242 document
.add_new_range
.range
.setAttribute('match', "^\\d\\d?\\d?\\.\\d\\d?\\d?\\.\\d\\d?\\d?\\.\\d\\d?\\d?\\/\\d\\d?$");
2250 startPortlet ("Add new");
2251 echo '<table border=0 cellpadding=10 align=center>';
2252 // This form requires a name, so JavaScript validator can find it.
2253 // No printOpFormIntro() hence
2254 echo "<form method=post name='add_new_range' action='".makeHrefProcess()."'>\n";
2255 echo "<input type=hidden name=op value=addIPv4Prefix>\n";
2257 echo '<tr><td rowspan=4><h3>assign tags</h3>';
2261 echo "<th class=tdright>prefix</th><td class=tdleft><input type=text name='range' size=18 class='live-validate' tabindex=1></td>";
2262 echo "<tr><th class=tdright>name</th><td class=tdleft><input type=text name='name' size='20' tabindex=2></td></tr>";
2263 echo "<tr><th class=tdright>connected network</th><td class=tdleft><input type=checkbox name='is_bcast' tabindex=3></td></tr>";
2264 echo "<tr><td colspan=2>";
2265 printImageHREF ('CREATE', 'Add a new network', TRUE, 4);
2267 echo "</form></table><br><br>\n";
2270 $addrspaceList = getIPv4NetworkList();
2271 if (count ($addrspaceList))
2273 startPortlet ('Manage existing (' . count ($addrspaceList) . ')');
2274 echo "<table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
2275 echo "<tr><th> </th><th>prefix</th><th>name</th><th> </th></tr>";
2276 foreach ($addrspaceList as $netinfo)
2278 echo "<form method=post action='".makeHrefProcess(array('op'=>'updIPv4Prefix', 'id'=>$netinfo['id']))."'>";
2279 echo "<tr valign=top><td>";
2280 if (getConfigVar ('IPV4_JAYWALK') == 'yes')
2282 echo "<a href='".makeHrefProcess(array('op'=>'delIPv4Prefix', 'id'=>$netinfo['id']))."'>";
2283 printImageHREF ('destroy', 'Delete this prefix');
2286 else // only render clickable image for empty networks
2288 $netdata = getIPv4NetworkInfo ($netinfo['id']);
2289 loadIPv4AddrList ($netdata);
2290 if (count ($netdata['addrlist']))
2291 printImageHREF ('nodestroy', 'There are ' . count ($netdata['addrlist']) . ' allocations inside');
2294 echo "<a href='".makeHrefProcess(array('op'=>'delIPv4Prefix', 'id'=>$netinfo['id']))."'>";
2295 printImageHREF ('destroy', 'Delete this prefix');
2300 echo "</td>\n<td class=tdleft>${netinfo['ip']}/${netinfo['mask']}</td>";
2301 echo "<td><input type=text name=name size=40 value='${netinfo['name']}'>";
2303 printImageHREF ('save', 'Save changes', TRUE);
2304 echo "</td></tr></form>\n";
2311 function renderIPv4Network ($id)
2313 global $pageno, $tabno, $aac2;
2314 $netmaskbylen = array
2316 32 => '255.255.255.255',
2317 31 => '255.255.255.254',
2318 30 => '255.255.255.252',
2319 29 => '255.255.255.248',
2320 28 => '255.255.255.240',
2321 27 => '255.255.255.224',
2322 26 => '255.255.255.192',
2323 25 => '255.255.255.128',
2324 24 => '255.255.255.0',
2325 23 => '255.255.254.0',
2326 22 => '255.255.252.0',
2327 21 => '255.255.248.0',
2328 20 => '255.255.240.0',
2329 19 => '255.255.224.0',
2330 18 => '255.255.192.0',
2331 17 => '255.255.128.0',
2332 16 => '255.255.0.0',
2333 15 => '255.254.0.0',
2334 14 => '255.252.0.0',
2335 13 => '255.248.0.0',
2336 12 => '255.240.0.0',
2337 11 => '255.224.0.0',
2338 10 => '255.192.0.0',
2349 $wildcardbylen = array
2366 17 => '0.0.127.255',
2368 15 => '0.1.255.255',
2369 14 => '0.3.255.255',
2370 13 => '0.7.255.255',
2371 12 => '0.15.255.255',
2372 11 => '0.31.255.255',
2373 10 => '0.63.255.255',
2374 9 => '0.127.255.255',
2375 8 => '0.255.255.255',
2376 7 => '1.255.255.255',
2377 6 => '3.255.255.255',
2378 5 => '7.255.255.255',
2379 4 => '15.255.255.255',
2380 3 => '31.255.255.255',
2381 2 => '63.255.255.255',
2382 1 => '127.255.255.255'
2384 $maxperpage = getConfigVar ('IPV4_ADDRS_PER_PAGE');
2385 if (isset($_REQUEST['pg']))
2386 $page = $_REQUEST['pg'];
2390 $range = getIPv4NetworkInfo ($id);
2391 loadIPv4AddrList ($range);
2392 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
2393 echo "<tr><td colspan=2 align=center><h1>${range['ip']}/${range['mask']}</h1><h2>${range['name']}</h2></td></tr>\n";
2395 echo "<tr><td class=pcleft width='50%'>";
2396 startPortlet ('summary');
2397 $total = ($range['ip_bin'] |
$range['mask_bin_inv']) - ($range['ip_bin'] & $range['mask_bin']) +
1;
2398 $used = count ($range['addrlist']);
2399 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
2401 echo "<tr><th width='50%' class=tdright>%% used:</th><td class=tdleft>";
2402 renderProgressBar ($used/$total);
2403 echo " ${used}/${total}</td></tr>\n";
2405 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
2407 // Build a backtrace from all parent networks.
2408 $clen = $range['mask'];
2409 $backtrace = array();
2410 while (NULL !== ($upperid = getIPv4AddressNetworkId ($range['ip'], $clen)))
2412 $upperinfo = getIPv4NetworkInfo ($upperid);
2413 $clen = $upperinfo['mask'];
2414 $backtrace[] = $upperid;
2416 $arrows = count ($backtrace);
2417 foreach (array_reverse ($backtrace) as $ancestorid)
2419 $ainfo = getIPv4NetworkInfo ($ancestorid);
2420 echo "<tr><th width='50%' class=tdright>";
2421 for ($i = 0; $i < $arrows; $i++
)
2424 echo "</th><td class=tdleft><a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno, 'id'=>$ainfo['id']))."'>${ainfo['ip']}/${ainfo['mask']}</a></td></tr>";
2426 echo "<tr><th width='50%' class=tdright>→</th>";
2427 echo "<td class=tdleft>${range['ip']}/${range['mask']}</td></tr>";
2428 // FIXME: get and display nested networks
2429 // $theitem = pickLeaf ($ipv4tree, $id);
2432 echo "<tr><th width='50%' class=tdright>Netmask:</th><td class=tdleft>";
2433 echo $netmaskbylen[$range['mask']];
2434 echo "</td></tr>\n";
2436 echo "<tr><th width='50%' class=tdright>Netmask:</th><td class=tdleft>";
2437 printf ('0x%08X', binMaskFromDec ($range['mask']));
2438 echo "</td></tr>\n";
2440 echo "<tr><th width='50%' class=tdright>Wildcard bits:</th><td class=tdleft>";
2441 echo $wildcardbylen[$range['mask']];
2442 echo "</td></tr>\n";
2444 $routers = findRouters ($range['addrlist']);
2445 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes' and count ($routers))
2447 echo "<tr><th width='50%' class=tdright>Routed by:</th>";
2448 printRoutersTD ($routers);
2452 printTagTRs (makeHref(array('page'=>'ipv4space', 'tab'=>'default'))."&");
2453 echo "</table><br>\n";
2456 renderFilesPortlet ('ipv4net', $id);
2459 echo "<td class=pcright>";
2460 startPortlet ('details');
2461 $startip = $range['ip_bin'] & $range['mask_bin'];
2462 $endip = $range['ip_bin'] |
$range['mask_bin_inv'];
2463 $realstartip = $startip;
2464 $realendip = $endip;
2466 if($endip - $startip > $maxperpage)
2468 $numpages = ($endip - $startip)/$maxperpage;
2469 $startip = $startip +
$page * $maxperpage;
2470 $endip = $startip +
$maxperpage-1;
2474 echo '<h3>' . long2ip ($startip) . ' ~ ' . long2ip ($endip) . '</h3>';
2475 for ($i=0; $i<$numpages; $i++
)
2480 echo "<a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno, 'id'=>$id, 'pg'=>$i))."'>$i</a> ";
2484 echo "<table class='widetable' border=0 cellspacing=0 cellpadding=5 align='center' width='100%'>\n";
2485 echo "<tr><th>Address</th><th>Name</th><th>Allocation</th></tr>\n";
2488 for ($ip = $startip; $ip <= $endip; $ip++
) :
2489 if (isset ($_REQUEST['hl_ipv4_addr']) and ip2long ($_REQUEST['hl_ipv4_addr']) == $ip)
2490 $secondstyle = 'tdleft port_highlight';
2492 $secondstyle = 'tdleft';
2493 if (!isset ($range['addrlist'][$ip]))
2495 echo "<tr><td class=tdleft><a href='".makeHref(array('page'=>'ipaddress', 'ip'=>ip_long2quad($ip)))."'>" . ip_long2quad($ip);
2496 echo "</a></td><td class='${secondstyle}'> </td><td class='${secondstyle}'> </td></tr>\n";
2499 $addr = $range['addrlist'][$ip];
2500 echo "<tr class='${addr['class']}'>";
2502 echo "<td class=tdleft><a href='".makeHref(array('page'=>'ipaddress', 'ip'=>$addr['ip']))."'>${addr['ip']}</a></td>";
2503 echo "<td class='${secondstyle}'>${addr['name']}</td><td class='${secondstyle}'>";
2506 if ( $addr['reserved'] == 'yes')
2508 echo "<strong>RESERVED</strong> ";
2511 foreach ($range['addrlist'][$ip]['allocs'] as $ref)
2513 echo $delim . $aac2[$ref['type']];
2514 echo "<a href='".makeHref(array('page'=>'object', 'object_id'=>$ref['object_id'], 'hl_ipv4_addr'=>$addr['ip']))."'>";
2515 echo $ref['name'] . (empty ($ref['name']) ?
'' : '@');
2516 echo "${ref['object_name']}</a>";
2524 foreach ($range['addrlist'][$ip]['lblist'] as $ref)
2528 echo "${delim}<a href='".makeHref(array('page'=>'object', 'object_id'=>$ref['object_id']))."'>";
2529 echo "${ref['object_name']}</a>:<a href='".makeHref(array('page'=>'ipv4vs', 'vs_id'=>$ref['vs_id']))."'>";
2530 echo "${ref['vport']}/${ref['proto']}</a>→";
2538 foreach ($range['addrlist'][$ip]['rslist'] as $ref)
2542 echo "${delim}→${ref['rsport']}@<a href='".makeHref(array('page'=>'ipv4rspool', 'pool_id'=>$ref['rspool_id']))."'>";
2543 echo "${ref['rspool_name']}</a>";
2546 echo "</td></tr>\n";
2552 echo "</td></tr></table>\n";
2555 function renderIPv4NetworkProperties ($id)
2557 showMessageOrError();
2558 $netdata = getIPv4NetworkInfo ($id);
2559 echo "<center><h1>${netdata['ip']}/${netdata['mask']}</h1></center>\n";
2560 echo "<table border=0 cellpadding=10 cellpadding=1 align='center'>\n";
2561 printOpFormIntro ('editRange');
2562 echo "<tr><td class='tdright'>Name:</td><td class='tdleft'><input type=text name=name size=20 value='${netdata['name']}'></tr>";
2563 echo "<tr><td colspan=2 class=tdcenter>";
2564 printImageHREF ('SAVE', 'Save changes', TRUE);
2565 echo "</td></form></tr></table>\n";
2568 function renderIPv4Address ($dottedquad)
2571 $address = getIPv4Address ($dottedquad);
2572 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
2573 echo "<tr><td colspan=2 align=center><h1>${dottedquad}</h1></td></tr>\n";
2574 if (!empty ($address['name']))
2575 echo "<tr><td colspan=2 align=center><h2>${address['name']}</h2></td></tr>\n";
2577 echo "<tr><td class=pcleft>";
2578 startPortlet ('summary');
2579 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
2580 echo "<tr><th width='50%' class=tdright>Allocations:</th><td class=tdleft>" . count ($address['allocs']) . "</td></tr>\n";
2581 echo "<tr><th width='50%' class=tdright>Originated NAT connections:</th><td class=tdleft>" . count ($address['outpf']) . "</td></tr>\n";
2582 echo "<tr><th width='50%' class=tdright>Arriving NAT connections:</th><td class=tdleft>" . count ($address['inpf']) . "</td></tr>\n";
2583 echo "<tr><th width='50%' class=tdright>SLB virtual services:</th><td class=tdleft>" . count ($address['lblist']) . "</td></tr>\n";
2584 echo "<tr><th width='50%' class=tdright>SLB real servers:</th><td class=tdleft>" . count ($address['rslist']) . "</td></tr>\n";
2586 echo "</table><br>\n";
2590 echo "<td class=pcright>";
2592 if (isset ($address['class']))
2594 startPortlet ('allocations');
2595 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
2596 echo "<tr><th>object</th><th>OS interface</th><th>allocation type</th></tr>\n";
2597 $class = $address['class'];
2598 // render all allocation records for this address the same way
2599 if ($address['reserved'] == 'yes')
2600 echo "<tr class='${class}'><td colspan=2> </td><td class=tdleft><strong>RESERVED</strong></td></tr>";
2601 foreach ($address['allocs'] as $bond)
2603 if (isset ($_REQUEST['hl_object_id']) and $_REQUEST['hl_object_id'] == $bond['object_id'])
2604 $secondclass = 'tdleft port_highlight';
2606 $secondclass = 'tdleft';
2607 echo "<tr class='$class'><td class=tdleft><a href='".makeHref(array('page'=>'object', 'object_id'=>$bond['object_id'], 'hl_ipv4_addr'=>$dottedquad))."'>${bond['object_name']}</td><td class='${secondclass}'>${bond['name']}</td><td class='${secondclass}'><strong>";
2608 echo $aat[$bond['type']];
2609 echo "</strong></td></tr>\n";
2611 echo "</table><br><br>";
2615 // FIXME: The returned list is structured differently, than we expect it to be. One of the sides
2617 if (count ($address['lblist']))
2619 startPortlet ('Virtual services (' . count ($address['lblist']) . ')');
2620 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
2621 echo "<tr><th>VS</th><th>name</th></tr>\n";
2622 foreach ($address['lblist'] as $vsinfo)
2624 echo "<tr><td class=tdleft><a href='".makeHref(array('page'=>'ipv4vs', 'vs_id'=>$vsinfo['vs_id']))."'>";
2625 echo buildVServiceName ($vsinfo) . "</a></td><td class=tdleft>";
2626 echo $vsinfo['name'] . "</td></tr>\n";
2628 echo "</table><br><br>";
2632 if (count ($address['rslist']))
2634 startPortlet ('Real servers (' . count ($address['rslist']) . ')');
2635 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
2636 echo "<tr><th> </th><th>port</th><th>RS pool</th></tr>\n";
2637 foreach ($address['rslist'] as $rsinfo)
2640 if ($rsinfo['inservice'] == 'yes')
2641 printImageHREF ('inservice', 'in service');
2643 printImageHREF ('notinservice', 'NOT in service');
2644 echo "</td><td class=tdleft>${rsinfo['rsport']}</td><td class=tdleft><a href='".makeHref(array('page'=>'ipv4rspool', 'pool_id'=>$rsinfo['rspool_id']))."'>";
2645 echo $rsinfo['rspool_name'] . "</a></td></tr>\n";
2647 echo "</table><br><br>";
2651 if (count ($address['outpf']))
2653 startPortlet ('departing NAT rules');
2654 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
2655 echo "<tr><th>proto</th><th>from</th><th>to</th><th>comment</th></tr>\n";
2656 foreach ($address['outpf'] as $rule)
2657 echo "<tr><td>${rule['proto']}</td><td>${rule['localip']}:${rule['localport']}</td><td>${rule['remoteip']}:${rule['remoteport']}</td><td>${rule['description']}</td></tr>";
2662 if (count ($address['inpf']))
2664 startPortlet ('arriving NAT rules');
2665 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
2666 echo "<tr><th>proto</th><th>from</th><th>to</th><th>comment</th></tr>\n";
2667 foreach ($address['inpf'] as $rule)
2668 echo "<tr><td>${rule['proto']}</td><td>${rule['localip']}:${rule['localport']}</td><td>${rule['remoteip']}:${rule['remoteport']}</td><td>${rule['description']}</td></tr>";
2677 function renderIPv4AddressProperties ($dottedquad)
2679 showMessageOrError();
2680 $address = getIPv4Address ($dottedquad);
2681 echo "<center><h1>$dottedquad</h1></center>\n";
2683 startPortlet ('update');
2684 echo "<table border=0 cellpadding=10 cellpadding=1 align='center'>\n";
2685 printOpFormIntro ('editAddress');
2686 echo "<tr><td class='tdright'>Name:</td><td class='tdleft'><input type=text name=name size=20 value='${address['name']}'></tr>";
2687 echo "<td class='tdright'>Reserved:</td><td class='tdleft'><input type=checkbox name=reserved size=20 ";
2688 echo ($address['reserved']=='yes') ?
'checked' : '';
2689 echo "></tr><tr><td class=tdleft>";
2690 printImageHREF ('SAVE', 'Save changes', TRUE);
2691 echo "</td></form><td class=tdright>";
2692 if (empty ($address['name']) and $address['reserved'] == 'no')
2693 printImageHREF ('CLEAR gray');
2696 printOpFormIntro ('editAddress', array ('name' => '', 'reserved' => ''));
2697 printImageHREF ('CLEAR', 'Release', TRUE);
2700 echo "</td></tr></table>\n";
2704 function renderIPv4AddressAllocations ($dottedquad)
2706 showMessageOrError();
2707 function printNewItemTR ()
2710 printOpFormIntro ('addIPv4Allocation');
2712 printImageHREF ('add', 'allocate', TRUE);
2714 printSelect (getNarrowObjectList (explode (',', getConfigVar ('IPV4_PERFORMERS'))), 'object_id', NULL, 100);
2715 echo "</td><td><input type=text tabindex=101 name=bond_name size=10></td><td>";
2716 printSelect ($aat, 'bond_type', NULL, 102);
2718 printImageHREF ('add', 'allocate', TRUE, 103);
2719 echo "</td></form></tr>";
2721 global $pageno, $tabno, $aat;
2723 $address = getIPv4Address ($dottedquad);
2725 echo "<center><h1>${dottedquad}</h1></center>\n";
2726 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
2727 echo "<tr><th> </th><th>object</th><th>OS interface</th><th>allocation type</th><th> </th></tr>\n";
2729 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
2731 if (isset ($address['class']))
2733 $class = $address['class'];
2734 if ($address['reserved'] == 'yes')
2735 echo "<tr class='${class}'><td colspan=3> </td><td class=tdleft><strong>RESERVED</strong></td><td> </td></tr>";
2736 foreach ($address['allocs'] as $bond)
2738 echo "<tr class='$class'>";
2739 printOpFormIntro ('updIPv4Allocation', array ('object_id' => $bond['object_id']));
2740 echo "<td><a href='".makeHrefProcess(array('op'=>'delIPv4Allocation', 'ip'=>$dottedquad, 'object_id'=>$bond['object_id']))."'>";
2741 printImageHREF ('delete', 'Unallocate address');
2743 echo "<td><a href='".makeHref(array('page'=>'object', 'object_id'=>$bond['object_id'], 'hl_ipv4_addr'=>$dottedquad))."'>${bond['object_name']}</td>";
2744 echo "<td><input type='text' name='bond_name' value='${bond['name']}' size=10></td><td>";
2745 printSelect ($aat, 'bond_type', $bond['type']);
2747 printImageHREF ('save', 'Save changes', TRUE);
2748 echo "</td></form></tr>\n";
2751 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
2753 echo "</table><br><br>";
2756 function renderNATv4ForObject ($object_id = 0)
2759 function printNewItemTR ($alloclist)
2762 printOpFormIntro ('addNATv4Rule');
2763 echo "<tr align='center'><td>";
2764 printImageHREF ('add', 'Add new NAT rule', TRUE);
2766 printSelect (array ('TCP' => 'TCP', 'UDP' => 'UDP'), 'proto');
2767 echo "<select name='localip' tabindex=1>";
2769 foreach ($alloclist as $dottedquad => $alloc)
2771 $name = empty ($alloc['addrinfo']['name']) ?
'' : (' (' . niftyString ($alloc['addrinfo']['name']) . ')');
2772 $osif = empty ($alloc['osif']) ?
'' : ($alloc['osif'] . ': ');
2773 echo "<option value='${dottedquad}'>${osif}${dottedquad}${name}</option>";
2776 echo "</select>:<input type='text' name='localport' size='4' tabindex=2></td>";
2777 echo "<td><input type='text' name='remoteip' id='remoteip' size='10' tabindex=3>";
2778 echo "<a href='javascript:;' onclick='window.open(\"" . makeHrefForHelper ('inet4list');
2779 echo "\", \"findobjectip\", \"height=700, width=400, location=no, menubar=no, resizable=yes, scrollbars=no, status=no, titlebar=no, toolbar=no\");'>";
2780 printImageHREF ('find', 'Find object');
2782 echo ":<input type='text' name='remoteport' size='4' tabindex=4></td><td></td>";
2783 echo "<td colspan=1><input type='text' name='description' size='20' tabindex=5></td><td>";
2784 printImageHREF ('add', 'Add new NAT rule', TRUE, 6);
2785 echo "</td></tr></form>";
2787 global $pageno, $tabno;
2789 $info = getObjectInfo ($object_id);
2790 $forwards = getNATv4ForObject ($object_id);
2791 $alloclist = getObjectIPv4Allocations ($object_id);
2792 showMessageOrError();
2793 echo "<center><h2>locally performed NAT</h2></center>";
2795 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
2796 echo "<tr><th></th><th>Match endpoint</th><th>Translate to</th><th>Target object</th><th>Comment</th><th> </th></tr>\n";
2798 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
2799 printNewItemTR ($alloclist);
2800 foreach ($forwards['out'] as $pf)
2804 if (isset ($alloclist [$pf['localip']]))
2806 $class = $alloclist [$pf['localip']]['addrinfo']['class'];
2807 $osif = $alloclist [$pf['localip']]['osif'] . ': ';
2810 echo "<tr class='$class'>";
2811 echo "<td><a href='".
2812 makeHrefProcess(array(
2813 'op'=>'delNATv4Rule',
2814 'localip'=>$pf['localip'],
2815 'localport'=>$pf['localport'],
2816 'remoteip'=>$pf['remoteip'],
2817 'remoteport'=>$pf['remoteport'],
2818 'proto'=>$pf['proto'],
2819 'object_id'=>$object_id)).
2821 printImageHREF ('delete', 'Delete NAT rule');
2823 echo "<td>${pf['proto']}/${osif}<a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['localip']))."'>${pf['localip']}</a>:${pf['localport']}";
2824 if (!empty ($pf['local_addr_name']))
2825 echo ' (' . $pf['local_addr_name'] . ')';
2827 echo "<td><a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['remoteip']))."'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
2829 $address = getIPv4Address ($pf['remoteip']);
2831 echo "<td class='description'>";
2832 if (count ($address['allocs']))
2833 foreach ($address['allocs'] as $bond)
2834 echo "<a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$bond['object_id']))."'>${bond['object_name']}(${bond['name']})</a> ";
2835 elseif (!empty ($pf['remote_addr_name']))
2836 echo '(' . $pf['remote_addr_name'] . ')';
2842 'localip' => $pf['localip'],
2843 'localport' => $pf['localport'],
2844 'remoteip' => $pf['remoteip'],
2845 'remoteport' => $pf['remoteport'],
2846 'proto' => $pf['proto']
2849 echo "</td><td class='description'>";
2850 echo "<input type='text' name='description' value='${pf['description']}'></td><td>";
2851 printImageHREF ('save', 'Save changes', TRUE);
2852 echo "</td></form></tr>";
2854 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
2855 printNewItemTR ($alloclist);
2857 echo "</table><br><br>";
2859 echo "<center><h2>arriving NAT connections</h2></center>";
2860 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
2861 echo "<tr><th></th><th>Source</th><th>Source objects</th><th>Target</th><th>Description</th></tr>\n";
2863 foreach ($forwards['in'] as $pf)
2865 echo "<tr><td><a href='".
2866 makeHrefProcess(array(
2867 'op'=>'delNATv4Rule',
2868 'localip'=>$pf['localip'],
2869 'localport'=>$pf['localport'],
2870 'remoteip'=>$pf['remoteip'],
2871 'remoteport'=>$pf['remoteport'],
2872 'proto'=>$pf['proto'],
2873 'object_id'=>$pf['object_id']
2876 printImageHREF ('delete', 'Delete NAT rule');
2878 echo "<td>${pf['proto']}/<a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['localip']))."'>${pf['localip']}</a>:${pf['localport']}</td>";
2879 echo "<td class='description'><a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$pf['object_id']))."'>${pf['object_name']}</a>";
2880 echo "</td><td><a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['remoteip']))."'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
2881 echo "<td class='description'>${pf['description']}</td></tr>";
2884 echo "</table><br><br>";
2887 // FIXME: move related code away into ophandler(s)
2888 function renderAddMultipleObjectsForm ()
2890 global $root, $pageno, $tabno, $nextorder;
2893 $global_type_id = 0;
2895 $asset_no = array();
2896 $keepvalues1 = $keepvalues2 = FALSE;
2897 showMessageOrError();
2899 // Render a form for the next.
2900 $typelist = getObjectTypeList();