r2293 - renderTagStats(): fixed sums calculation
[racktables] / inc / interface.php
CommitLineData
b325120a 1<?php
e673ee24
DO
2/*
3*
4* This file contains frontend functions for RackTables.
5*
6*/
7
9c0b0016
DO
8// Interface function's special.
9$nextorder['odd'] = 'even';
10$nextorder['even'] = 'odd';
11
52c836b1
DO
12// address allocation type
13$aat = array
14(
15 'regular' => 'Connected',
16 'virtual' => 'Loopback',
17 'shared' => 'Shared',
18 'router' => 'Router',
19);
beb9e88a 20// address allocation code, IPv4 addresses and objects view
52c836b1
DO
21$aac = array
22(
23 'regular' => '',
24 'virtual' => '<strong>L</strong>',
25 'shared' => '<strong>S</strong>',
26 'router' => '<strong>R</strong>',
27);
beb9e88a
DO
28// address allocation code, IPv4 networks view
29$aac2 = array
30(
31 'regular' => '',
32 'virtual' => '<strong>L:</strong>',
33 'router' => '<strong>R:</strong>',
34);
52c836b1 35
7056988c
DO
36// Let's have it here, so extensions can add their own images.
37$image = array();
38$image['error']['path'] = 'pix/error.png';
39$image['error']['width'] = 76;
40$image['error']['height'] = 17;
41$image['logo']['path'] = 'pix/defaultlogo.png';
42$image['logo']['width'] = 210;
43$image['logo']['height'] = 40;
44$image['rackspace']['path'] = 'pix/racks.png';
45$image['rackspace']['width'] = 218;
46$image['rackspace']['height'] = 200;
47$image['objects']['path'] = 'pix/server.png';
48$image['objects']['width'] = 218;
49$image['objects']['height'] = 200;
e1ae3fb4
AD
50$image['files']['path'] = 'pix/files.png';
51$image['files']['width'] = 218;
52$image['files']['height'] = 200;
7056988c
DO
53$image['ipv4space']['path'] = 'pix/addressspace.png';
54$image['ipv4space']['width'] = 218;
55$image['ipv4space']['height'] = 200;
56$image['ipv4slb']['path'] = 'pix/slb.png';
57$image['ipv4slb']['width'] = 218;
58$image['ipv4slb']['height'] = 200;
59$image['config']['path'] = 'pix/configuration.png';
60$image['config']['width'] = 218;
61$image['config']['height'] = 200;
62$image['reports']['path'] = 'pix/report.png';
63$image['reports']['width'] = 218;
64$image['reports']['height'] = 200;
e1ae3fb4
AD
65$image['download']['path'] = 'pix/download.png';
66$image['download']['width'] = 16;
67$image['download']['height'] = 16;
7056988c
DO
68$image['link']['path'] = 'pix/tango-network-wired.png';
69$image['link']['width'] = 16;
70$image['link']['height'] = 16;
7056988c
DO
71$image['add']['path'] = 'pix/tango-list-add.png';
72$image['add']['width'] = 16;
73$image['add']['height'] = 16;
74$image['delete']['path'] = 'pix/tango-list-remove.png';
75$image['delete']['width'] = 16;
76$image['delete']['height'] = 16;
77$image['nodelete']['path'] = 'pix/tango-list-remove-shadow.png';
78$image['nodelete']['width'] = 16;
79$image['nodelete']['height'] = 16;
7056988c
DO
80$image['inservice']['path'] = 'pix/tango-emblem-system.png';
81$image['inservice']['width'] = 16;
82$image['inservice']['height'] = 16;
83$image['notinservice']['path'] = 'pix/tango-dialog-error.png';
84$image['notinservice']['width'] = 16;
85$image['notinservice']['height'] = 16;
86$image['blockuser'] = $image['inservice'];
87$image['unblockuser'] = $image['notinservice'];
88$image['find']['path'] = 'pix/tango-system-search.png';
89$image['find']['width'] = 16;
90$image['find']['height'] = 16;
7056988c
DO
91$image['next']['path'] = 'pix/tango-go-next.png';
92$image['next']['width'] = 32;
93$image['next']['height'] = 32;
94$image['prev']['path'] = 'pix/tango-go-previous.png';
95$image['prev']['width'] = 32;
96$image['prev']['height'] = 32;
97$image['clear']['path'] = 'pix/tango-edit-clear.png';
98$image['clear']['width'] = 16;
99$image['clear']['height'] = 16;
61a61189
DO
100$image['CLEAR']['path'] = 'pix/tango-edit-clear-big.png';
101$image['CLEAR']['width'] = 32;
102$image['CLEAR']['height'] = 32;
7056988c
DO
103$image['save']['path'] = 'pix/tango-document-save.png';
104$image['save']['width'] = 16;
105$image['save']['height'] = 16;
106$image['SAVE']['path'] = 'pix/tango-document-save-big.png';
107$image['SAVE']['width'] = 32;
108$image['SAVE']['height'] = 32;
109$image['create']['path'] = 'pix/tango-document-new.png';
110$image['create']['width'] = 16;
111$image['create']['height'] = 16;
112$image['CREATE']['path'] = 'pix/tango-document-new-big.png';
113$image['CREATE']['width'] = 32;
114$image['CREATE']['height'] = 32;
115$image['DENIED']['path'] = 'pix/tango-dialog-error-big.png';
116$image['DENIED']['width'] = 32;
117$image['DENIED']['height'] = 32;
d28d7f4d
DO
118$image['apply']['path'] = 'pix/tango-emblem-system.png';
119$image['apply']['width'] = 16;
120$image['apply']['height'] = 16;
737a3f72
DO
121$image['node-collapsed']['path'] = 'pix/node-collapsed.png';
122$image['node-collapsed']['width'] = 16;
123$image['node-collapsed']['height'] = 16;
124$image['node-expanded']['path'] = 'pix/node-expanded.png';
125$image['node-expanded']['width'] = 16;
126$image['node-expanded']['height'] = 16;
fec0c8da
DO
127$image['node-expanded-static']['path'] = 'pix/node-expanded-static.png';
128$image['node-expanded-static']['width'] = 16;
129$image['node-expanded-static']['height'] = 16;
09620506
DO
130$image['dragons']['path'] = 'pix/mitsudragon.png';
131$image['dragons']['width'] = 125;
132$image['dragons']['height'] = 21;
7056988c 133
e5c4506d
DO
134// This may be populated later onsite, report rendering function will use it.
135// See the $systemreport for structure.
136$localreports = array();
137
e673ee24
DO
138// Main menu.
139function renderIndex ()
140{
141 global $root;
142?>
143<table border=0 cellpadding=0 cellspacing=0 width='100%'>
144 <tr>
145 <td>
146 <div style='text-align: center; margin: 10px; '>
147 <table width='100%' cellspacing=0 cellpadding=30 class=mainmenu border=0>
148 <tr>
149 <td>
b325120a
DO
150 <h1><a href='<?php echo $root; ?>?page=rackspace'>Rackspace<br>
151 <?php printImageHREF ('rackspace'); ?></a></h1>
e673ee24
DO
152 </td>
153 <td>
b325120a
DO
154 <h1><a href='<?php echo $root; ?>?page=objects'>Objects<br>
155 <?php printImageHREF ('objects'); ?></a></h1>
e673ee24 156 </td>
e673ee24 157 <td>
e1ae3fb4
AD
158 <h1><a href='<?php echo $root; ?>?page=ipv4space'>IPv4 space<br>
159 <?php printImageHREF ('ipv4space'); ?></a></h1>
e673ee24
DO
160 </td>
161 <td>
e1ae3fb4
AD
162 <h1><a href='<?php echo $root; ?>?page=files'>Files<br>
163 <?php printImageHREF ('files'); ?></a></h1>
e673ee24 164 </td>
e1ae3fb4 165 </tr>
e1ae3fb4 166 <tr>
ae545907 167 <td>
f4d879a9
DO
168 <h1><a href='<?php echo $root; ?>?page=config'>Configuration<br>
169 <?php printImageHREF ('config'); ?></a></h1>
ae545907 170 </td>
e1ae3fb4 171 <td>
f4d879a9
DO
172 <h1><a href='<?php echo $root; ?>?page=reports'>Reports<br>
173 <?php printImageHREF ('reports'); ?></a></h1>
e1ae3fb4
AD
174 </td>
175 <td>
f4d879a9
DO
176 <h1><a href='<?php echo $root; ?>?page=ipv4slb'>IPv4 SLB<br>
177 <?php printImageHREF ('ipv4slb'); ?></a></h1>
e1ae3fb4 178 </td>
f4d879a9 179 <td>&nbsp;</td>
e673ee24
DO
180 </tr>
181 </table>
182 </div>
183 </td>
184 </tr>
185</table>
b325120a 186<?php
e673ee24
DO
187}
188
189function renderRackspace ()
190{
932cf41f 191 $tagfilter = getTagFilter();
094a8e6e 192 $tagfilter_str = getTagFilterStr ($tagfilter);
489a7502
DO
193 echo "<table class=objview border=0 width='100%'><tr><td class=pcleft>";
194 renderTagFilterPortlet ($tagfilter, 'rack');
195 echo '</td><td class=pcright>';
196 echo '<table border=0 cellpadding=10 cellpadding=1>';
e673ee24 197 // generate thumb gallery
489a7502 198 $rackrowList = getRackspace ($tagfilter);
9c0b0016 199 global $root, $nextorder;
d5157018 200 $rackwidth = getRackImageWidth();
e673ee24
DO
201 $order = 'odd';
202 foreach ($rackrowList as $rackrow)
203 {
84466afa 204 echo "<tr class=row_${order}><th class=tdleft>";
a0d54e7e
DO
205 echo "<a href='${root}?page=row&row_id=${rackrow['row_id']}${tagfilter_str}'>";
206 echo "${rackrow['row_name']}</a></th>";
207 $rackList = getRacksForRow ($rackrow['row_id'], $tagfilter);
e673ee24 208 echo "<td><table border=0 cellspacing=5><tr>";
64b95774 209 foreach ($rackList as $rack)
e673ee24
DO
210 {
211 echo "<td align=center><a href='${root}?page=rack&rack_id=${rack['id']}'>";
212 echo "<img border=0 width=${rackwidth} height=";
d5157018 213 echo getRackImageHeight ($rack['height']);
e673ee24 214 echo " title='${rack['height']} units'";
d2ec5490 215 echo "src='render_image.php?img=minirack&rack_id=${rack['id']}'>";
e673ee24
DO
216 echo "<br>${rack['name']}</a></td>";
217 }
218 echo "</tr></table></tr>\n";
219 $order = $nextorder[$order];
220 }
221 echo "</table>\n";
489a7502 222 echo "</td></tr></table>\n";
e673ee24
DO
223}
224
345fd640
AD
225function renderRackspaceRowEditor ()
226{
227 function printNewItemTR ()
228 {
229 printOpFormIntro ('addRow');
230 echo "<tr><td><input type=text name=name tabindex=100></td><td>";
231 printImageHREF ('create', 'Add new row', TRUE, 101);
232 echo "</td></tr></form>";
233 }
234 global $root, $pageno, $tabno;
235 startPortlet ('Rows');
236 showMessageOrError();
237 echo "<table border=0 cellspacing=0 cellpadding=5 align=center class=widetable>\n";
238 echo "<tr><th>Name</th></tr>\n";
239 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
240 printNewItemTR();
241 $rackrowList = getRackspace ();
242 foreach ($rackrowList as $rackrow)
243 {
244 printOpFormIntro ('updateRow', array ('row_id' => $rackrow['row_id']));
245 echo "<tr><td><input type=text name=name value='${rackrow['row_name']}'></td><td>";
246 printImageHREF ('save', 'Save changes', TRUE);
247 echo "</td></form></tr>\n";
248 }
249 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
250 printNewItemTR();
251 echo "</table><br>\n";
252 finishPortlet();
253}
254
d5157018 255function renderRow ($row_id = 0)
e673ee24
DO
256{
257 if ($row_id == 0)
258 {
39a6338a 259 showError ('Invalid row_id', __FUNCTION__);
e673ee24
DO
260 return;
261 }
262 if (($rowInfo = getRackRowInfo ($row_id)) == NULL)
263 {
39a6338a 264 showError ('getRackRowInfo() failed', __FUNCTION__);
e673ee24
DO
265 return;
266 }
a0d54e7e
DO
267 $tagfilter = getTagFilter();
268 $rackList = getRacksForRow ($row_id, $tagfilter);
e673ee24
DO
269 // Main layout starts.
270 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
271
272 // Left portlet with row information.
273 echo "<tr><td class=pcleft>";
a8ce7234 274 startPortlet ($rowInfo['name']);
e673ee24 275 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
e673ee24
DO
276 echo "<tr><th width='50%' class=tdright>Racks:</th><td class=tdleft>${rowInfo['count']}</td></tr>\n";
277 echo "<tr><th width='50%' class=tdright>Units:</th><td class=tdleft>${rowInfo['sum']}</td></tr>\n";
04d619d0 278 echo "<tr><th width='50%' class=tdright>%% used:</th><td class=tdleft>";
114e50af
DO
279 renderProgressBar (getRSUforRackRow ($rackList));
280 echo "</td></tr>\n";
e673ee24
DO
281 echo "</table><br>\n";
282 finishPortlet();
283
a0d54e7e 284 echo "</td><td class=pcright rowspan=2>";
e673ee24 285
9c0b0016 286 global $root, $nextorder;
d5157018 287 $rackwidth = getRackImageWidth() * getConfigVar ('ROW_SCALE');
e673ee24
DO
288 $order = 'odd';
289 startPortlet ('Racks');
290 echo "<table border=0 cellspacing=5 align='center'><tr>";
64b95774 291 foreach ($rackList as $rack)
e673ee24
DO
292 {
293 echo "<td align=center class=row_${order}><a href='${root}?page=rack&rack_id=${rack['id']}'>";
d5157018 294 echo "<img border=0 width=${rackwidth} height=" . (getRackImageHeight ($rack['height']) * getConfigVar ('ROW_SCALE'));
e673ee24 295 echo " title='${rack['height']} units'";
d2ec5490 296 echo "src='render_image.php?img=minirack&rack_id=${rack['id']}'>";
e673ee24
DO
297 echo "<br>${rack['name']}</a></td>";
298 $order = $nextorder[$order];
299 }
300 echo "</tr></table>\n";
301 finishPortlet();
a0d54e7e 302 echo "</td></tr>";
e673ee24 303
a0d54e7e
DO
304 echo "<tr><td class=pcleft>";
305 renderTagFilterPortlet ($tagfilter, 'rack', 'row_id', $row_id);
e673ee24
DO
306 echo "</td></tr></table>";
307}
308
04f110a0 309function showError ($info = '', $location = 'N/A')
e673ee24
DO
310{
311 global $root;
04f110a0
DO
312 if (preg_match ('/\.php$/', $location))
313 $location = basename ($location);
314 elseif ($location != 'N/A')
315 $location = $location . '()';
316 echo "<div class=msg_error>An error has occured in [${location}]. ";
e673ee24
DO
317 if (empty ($info))
318 echo 'No additional information is available.';
319 else
320 echo "Additional information:<br><p>\n<pre>\n${info}\n</pre></p>";
321 echo "Go back or try starting from <a href='${root}'>index page</a>.<br></div>\n";
322}
323
324// This function renders rack as HTML table.
325function renderRack ($rack_id = 0, $hl_obj_id = 0)
326{
327 if ($rack_id == 0)
328 {
39a6338a 329 showError ('Invalid rack_id', __FUNCTION__);
e673ee24
DO
330 return;
331 }
332 if (($rackData = getRackData ($rack_id)) == NULL)
333 {
39a6338a 334 showError ('getRackData() failed', __FUNCTION__);
e673ee24
DO
335 return;
336 }
337 global $root, $pageno, $tabno;
338 markAllSpans ($rackData);
339 if ($hl_obj_id > 0)
340 highlightObject ($rackData, $hl_obj_id);
341 markupObjectProblems ($rackData);
342 $prev_id = getPrevIDforRack ($rackData['row_id'], $rack_id);
343 $next_id = getNextIDforRack ($rackData['row_id'], $rack_id);
d48d8820
DO
344 echo "<center><table border=0><tr valign=middle>";
345 echo "<td><h2><a href='${root}?page=row&row_id=${rackData['row_id']}'>${rackData['row_name']}</a> :</h2></td>";
e673ee24
DO
346 // FIXME: use 'bypass'?
347 if ($prev_id != NULL)
9803c56c 348 {
d48d8820 349 echo "<td><a href='${root}?page=rack&rack_id=${prev_id}'>";
9803c56c 350 printImageHREF ('prev', 'previous rack');
d48d8820 351 echo "</a></td>";
9803c56c 352 }
d48d8820 353 echo "<td><h2><a href='${root}?page=rack&rack_id=${rackData['id']}'>${rackData['name']}</a></h2></td>";
e673ee24 354 if ($next_id != NULL)
9803c56c 355 {
d48d8820 356 echo "<td><a href='${root}?page=rack&rack_id=${next_id}'>";
f444c095 357 printImageHREF ('next', 'next rack');
d48d8820 358 echo "</a></td>";
9803c56c 359 }
d48d8820 360 echo "</h2></td></tr></table>\n";
1c81a02c
DO
361 if ($rackData['left_is_front'] == 'yes')
362 $markup = array ('left' => 'Front', 'right' => 'Back');
363 else
364 $markup = array ('left' => 'Back', 'right' => 'Front');
e673ee24 365 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
9ddfe309
DO
366 echo "<tr><th width='10%'>&nbsp;</th><th width='20%'>${markup['left']}</th>";
367 echo "<th width='50%'>Interior</th><th width='20%'>${markup['right']}</th></tr>\n";
e673ee24
DO
368 for ($i = $rackData['height']; $i > 0; $i--)
369 {
9ddfe309 370 echo '<tr><th>' . ($rackData['bottom_is_unit1'] == 'yes' ? $i : $rackData['height'] - $i + 1) . '</th>';
e673ee24
DO
371 for ($locidx = 0; $locidx < 3; $locidx++)
372 {
373 if (isset ($rackData[$i][$locidx]['skipped']))
374 continue;
375 $state = $rackData[$i][$locidx]['state'];
376 echo "<td class=state_${state}";
377 if (isset ($rackData[$i][$locidx]['hl']))
378 echo $rackData[$i][$locidx]['hl'];
379 if (isset ($rackData[$i][$locidx]['colspan']))
380 echo ' colspan=' . $rackData[$i][$locidx]['colspan'];
381 if (isset ($rackData[$i][$locidx]['rowspan']))
382 echo ' rowspan=' . $rackData[$i][$locidx]['rowspan'];
383 echo ">";
384 switch ($state)
385 {
386 case 'T':
387 $objectData = getObjectInfo ($rackData[$i][$locidx]['object_id']);
388 if (!empty ($objectData['asset_no']))
389 $prefix = "<div title='${objectData['asset_no']}";
390 else
391 $prefix = "<div title='no asset tag";
392 // Don't tell about label, if it matches common name.
393 if ($objectData['name'] != $objectData['label'] and !empty ($objectData['label']))
394 $suffix = ", visible label is \"${objectData['label']}\"'>";
395 else
396 $suffix = "'>";
397 echo $prefix . $suffix;
398 echo "<a href='${root}?page=object&object_id=${objectData['id']}'>${objectData['dname']}</a></div>";
399 break;
400 case 'A':
401 echo '<div title="This rackspace does not exist">&nbsp;</div>';
402 break;
403 case 'F':
404 echo '<div title="Free rackspace">&nbsp;</div>';
405 break;
406 case 'U':
407 echo '<div title="Problematic rackspace, you CAN\'T mount here">&nbsp;</div>';
408 break;
409 default:
410 echo '<div title="No data">&nbsp;</div>';
411 break;
412 }
413 echo '</td>';
414 }
415 echo "</tr>\n";
416 }
417 echo "</table></center>\n";
418}
419
e673ee24
DO
420function renderNewRackForm ($row_id)
421{
f19c75d6 422 showMessageOrError();
f19c75d6 423
50b4ba85 424 startPortlet ('Add one');
f19c75d6 425 printOpFormIntro ('addRack', array ('got_data' => 'TRUE'));
e673ee24 426 echo '<table border=0 align=center>';
b901bf1f
DO
427 $defh = getConfigVar ('DEFAULT_RACK_HEIGHT');
428 if ($defh == 0)
429 $defh = '';
72d52730
DO
430 echo "<tr><th class=tdright>Rack name (*):</th><td class=tdleft><input type=text name=rack_name tabindex=1></td>";
431 echo "<td rowspan=4>Assign tags:<br>";
432 renderTagSelect();
433 echo "</td></tr>\n";
b8094ae4 434 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";
4134b5c0 435 echo "<tr><th class=tdright>Comment:</th><td class=tdleft><input type=text name=rack_comment tabindex=3></td></tr>\n";
f19c75d6
DO
436 echo "<tr><td class=submit colspan=2>";
437 printImageHREF ('CREATE', 'Add', TRUE);
438 echo "</td></tr></table></form>";
406b54bd 439 finishPortlet();
406b54bd 440
50b4ba85 441 startPortlet ('Add many');
f19c75d6 442 printOpFormIntro ('addRack', array ('got_mdata' => 'TRUE'));
50b4ba85
DO
443 echo '<table border=0 align=center>';
444 $defh = getConfigVar ('DEFAULT_RACK_HEIGHT');
445 if ($defh == 0)
446 $defh = '';
72d52730
DO
447 echo "<tr><th class=tdright>Height in units (*):</th><td class=tdleft><input type=text name=rack_height2 value='${defh}'></td>";
448 echo "<td rowspan=3 valign=top>Assign tags:<br>";
449 renderTagSelect();
450 echo "</td></tr>\n";
50b4ba85 451 echo "<tr><th class=tdright>Rack names (*):</th><td class=tdleft><textarea name=rack_names cols=40 rows=25></textarea></td></tr>\n";
f19c75d6
DO
452 echo "<tr><td class=submit colspan=2>";
453 printImageHREF ('CREATE', 'Add', TRUE);
e673ee24
DO
454 echo '</form></table>';
455 finishPortlet();
456}
457
458function renderEditObjectForm ($object_id)
459{
460 showMessageOrError();
e673ee24 461
22bb04da 462 global $pageno, $tabno, $root;
e673ee24
DO
463 $object = getObjectInfo ($object_id);
464 if ($object == NULL)
465 {
39a6338a 466 showError ('getObjectInfo() failed', __FUNCTION__);
e673ee24
DO
467 return;
468 }
cdd3efe9 469 startPortlet ();
43fb6eaf 470 printOpFormIntro ('update');
cdd3efe9
AD
471 echo '<table border=0 width=100%><tr><td class=pcleft>';
472
473 // static attributes
e673ee24 474 echo '<table border=0 align=center>';
cdd3efe9 475 echo "<tr><th colspan=2><h2>Static attributes</h2></th></tr>";
e673ee24
DO
476 echo "<tr><th class=tdright>Type:</th><td class=tdleft>";
477 printSelect (getObjectTypeList(), 'object_type_id', $object['objtype_id']);
478 echo "</td></tr>\n";
22bb04da 479 // baseline info
e673ee24
DO
480 echo "<tr><th class=tdright>Common name:</th><td class=tdleft><input type=text name=object_name value='${object['name']}'></td></tr>\n";
481 echo "<tr><th class=tdright>Visible label:</th><td class=tdleft><input type=text name=object_label value='${object['label']}'></td></tr>\n";
482 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";
483 echo "<tr><th class=tdright>Barcode:</th><td class=tdleft><input type=text name=object_barcode value='${object['barcode']}'></td></tr>\n";
484 echo "<tr><th class=tdright>Has problems:</th><td class=tdleft><input type=checkbox name=object_has_problems";
485 if ($object['has_problems'] == 'yes')
486 echo ' checked';
487 echo "></td></tr>\n";
488 echo "<tr><td colspan=2><b>Comment:</b><br><textarea name=object_comment rows=10 cols=80>${object['comment']}</textarea></td></tr>";
cdd3efe9
AD
489 echo '</table>';
490
491 echo '</td><td class=pcright>';
e673ee24 492
cdd3efe9 493 // optional attributes
e673ee24 494 $values = getAttrValues ($object_id);
2b98d5a2 495 if (count($values) > 0)
e673ee24 496 {
2b98d5a2
AD
497 echo "<table border=0 cellspacing=0 cellpadding=5 align=center class=widetable>\n";
498 echo "<tr><th colspan=3><h2>Optional attributes</h2></th></tr>";
499 echo "<tr><th>&nbsp;</th><th>Attribute</th><th>Value</th></tr>\n";
500 echo '<input type=hidden name=num_attrs value=' . count($values) . ">\n";
501 $i = 0;
502 foreach ($values as $record)
e673ee24 503 {
2b98d5a2
AD
504 echo "<input type=hidden name=${i}_attr_id value=${record['id']}>";
505 echo '<tr><td>';
506 if (!empty ($record['value']))
507 {
508 echo "<a href='${root}process.php?page=${pageno}&tab=${tabno}&op=clearSticker&object_id=${object_id}&attr_id=${record['id']}'>";
509 printImageHREF ('clear', 'Clear value');
510 echo '</a>';
511 }
512 else
513 echo '&nbsp;';
514 echo '</td>';
515 echo "<td class=tdright>${record['name']}:</td><td class=tdleft>";
516 switch ($record['type'])
517 {
518 case 'uint':
519 case 'float':
520 case 'string':
521 echo "<input type=text name=${i}_value value='${record['value']}'>";
522 break;
523 case 'dict':
524 $chapter = readChapter ($record['chapter_name']);
525 $chapter[0] = '-- NOT SET --';
526 printSelect ($chapter, "${i}_value", $record['key']);
527 break;
528 }
529 echo "</td></tr>\n";
530 $i++;
e673ee24 531 }
2b98d5a2 532 echo "</table>";
e673ee24 533 }
2b98d5a2 534 echo "</td></tr>\n";
cdd3efe9
AD
535
536 echo "<tr><th class=submit colspan=2>";
5bbbeaa2 537 printImageHREF ('SAVE', 'Save changes', TRUE);
cdd3efe9 538 echo "</form></th></tr></table>\n";
e673ee24 539 finishPortlet();
e673ee24 540
cdd3efe9 541 echo '<table border=0 width=100%><tr><td>';
e673ee24
DO
542 startPortlet ('history');
543 renderHistory ($pageno, $object_id);
544 finishPortlet();
cdd3efe9 545 echo '</td></tr></table>';
e673ee24
DO
546}
547
548// This is a clone of renderEditObjectForm().
549function renderEditRackForm ($rack_id)
550{
0c2b7c4a
DO
551 showMessageOrError();
552 global $pageno;
e673ee24
DO
553 $rack = getRackData ($rack_id);
554 if ($rack == NULL)
555 {
39a6338a 556 showError ('getRackData() failed', __FUNCTION__);
e673ee24
DO
557 return;
558 }
559
e673ee24 560 startPortlet ('Rack attributes');
7056988c 561 printOpFormIntro ('updateRack');
e673ee24
DO
562 echo '<table border=0 align=center>';
563 echo "<tr><th class=tdright>Rack row:</th><td class=tdleft>";
4c330a14 564 printSelect (readChapter ('RackRow'), 'rack_row_id', $rack['row_id']);
e673ee24
DO
565 echo "</td></tr>\n";
566 echo "<tr><th class=tdright>Name (required):</th><td class=tdleft><input type=text name=rack_name value='${rack['name']}'></td></tr>\n";
567 echo "<tr><th class=tdright>Height (required):</th><td class=tdleft><input type=text name=rack_height value='${rack['height']}'></td></tr>\n";
568 echo "<tr><th class=tdright>Comment:</th><td class=tdleft><input type=text name=rack_comment value='${rack['comment']}'></td></tr>\n";
7056988c
DO
569 echo "<tr><td class=submit colspan=2>";
570 printImageHREF ('SAVE', 'Save changes', TRUE);
571 echo "</td></tr>\n";
e673ee24
DO
572 echo '</form></table><br>';
573 finishPortlet();
574
575 startPortlet ('History');
576 renderHistory ($pageno, $rack_id);
577 finishPortlet();
578}
579
580// This is a helper for creators and editors.
a65f9f54 581function printSelect ($rowList, $select_name, $selected_id = NULL, $tabindex = NULL)
e673ee24 582{
9e7f32a7
DO
583 // First collect all data for OPTGROUPs, then ouput it and dump
584 // the rest of records as is.
585 $optgroup = array();
586 $other = array();
4c330a14 587 foreach ($rowList as $dict_key => $dict_value)
e673ee24 588 {
f0b540a3 589 if (strpos ($dict_value, '%GSKIP%') !== FALSE)
9e7f32a7 590 {
f0b540a3 591 $tmp = explode ('%GSKIP%', $dict_value, 2);
9e7f32a7
DO
592 $optgroup[$tmp[0]][$dict_key] = $tmp[1];
593 }
f0b540a3 594 elseif (strpos ($dict_value, '%GPASS%') !== FALSE)
2613bc1c 595 {
f0b540a3 596 $tmp = explode ('%GPASS%', $dict_value, 2);
2613bc1c
DO
597 $optgroup[$tmp[0]][$dict_key] = $tmp[1];
598 }
9e7f32a7
DO
599 else
600 $other[$dict_key] = $dict_value;
601 }
a65f9f54 602 echo "<select name=${select_name}" . ($tabindex ? " tabindex=${tabindex}" : '') . '>';
9e7f32a7
DO
603 if (!count ($optgroup))
604 {
605 foreach ($other as $dict_key => $dict_value)
606 {
607 echo "<option value=${dict_key}";
0b9b1063 608 if ($dict_key == $selected_id)
9e7f32a7
DO
609 echo ' selected';
610 echo ">${dict_value}</option>";
611 }
612 }
613 else
614 {
615 foreach ($optgroup as $groupname => $groupdata)
616 {
617 echo "<optgroup label='${groupname}'>";
618 foreach ($groupdata as $dict_key => $dict_value)
619 {
620 echo "<option value=${dict_key}";
0b9b1063 621 if ($dict_key == $selected_id)
9e7f32a7
DO
622 echo ' selected';
623 echo ">${dict_value}</option>";
624 }
625 echo "</optgroup>\n";
626 }
627 if (count ($other))
628 {
629 echo "<optgroup label='other'>\n";
630 foreach ($other as $dict_key => $dict_value)
631 {
632 echo "<option value=${dict_key}";
0b9b1063 633 if ($dict_key == $selected_id)
9e7f32a7
DO
634 echo ' selected';
635 echo ">${dict_value}</option>";
636 }
637 echo "</optgroup>\n";
638 }
e673ee24
DO
639 }
640 echo "</select>";
641}
642
254673dd
DO
643// used by renderGridForm() and renderRackPage()
644function renderRackInfoPortlet ($rackData)
645{
d9c609c4 646 global $root;
254673dd
DO
647 startPortlet ('summary');
648 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
649 echo "<tr><th width='50%' class=tdright>Rack row:</th><td class=tdleft>${rackData['row_name']}</td></tr>\n";
650 echo "<tr><th width='50%' class=tdright>Name:</th><td class=tdleft>${rackData['name']}</td></tr>\n";
651 echo "<tr><th width='50%' class=tdright>Height:</th><td class=tdleft>${rackData['height']}</td></tr>\n";
04d619d0 652 echo "<tr><th width='50%' class=tdright>%% used:</th><td class=tdleft>";
254673dd
DO
653 renderProgressBar (getRSUforRack ($rackData));
654 echo "</td></tr>\n";
655 echo "<tr><th width='50%' class=tdright>Objects:</th><td class=tdleft>";
abef7149 656 echo count (stuffInRackspace ($rackData));
254673dd 657 echo "</td></tr>\n";
d9f8a37a 658 printTagTRs ("${root}?page=rackspace&tab=default&");
254673dd
DO
659 if (!empty ($rackData['comment']))
660 echo "<tr><th width='50%' class=tdright>Comment:</th><td class=tdleft>${rackData['comment']}</td></tr>\n";
661 echo '</table>';
662 finishPortlet();
663}
664
e673ee24 665// This is a universal editor of rack design/waste.
7056988c 666// FIXME: switch to using printOpFormIntro()
bb09cca0 667function renderGridForm ($rack_id = 0, $filter, $header, $submit, $state1, $state2)
e673ee24
DO
668{
669 if ($rack_id == 0)
670 {
591ff2c4 671 showError ('Invalid rack_id', __FUNCTION__);
e673ee24
DO
672 return;
673 }
674 if (($rackData = getRackData ($rack_id)) == NULL)
675 {
591ff2c4 676 showError ('getRackData() failed', __FUNCTION__);
e673ee24
DO
677 return;
678 }
679
680 global $root, $pageno, $tabno;
254673dd 681 $filter ($rackData);
e673ee24
DO
682 markupObjectProblems ($rackData);
683
684 // Process form submit.
685 if (isset ($_REQUEST['do_update']))
686 {
687 $log[] = processGridForm ($rackData, $state1, $state2);
254673dd
DO
688 printLog ($log);
689 $rackData = getRackData ($rack_id);
690 $filter ($rackData);
691 markupObjectProblems ($rackData);
e673ee24
DO
692 }
693
694 // Render the result whatever it is.
695 // Main layout.
696 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
697 echo "<tr><td colspan=2 align=center><h1>${rackData['name']}</h1></td></tr>\n";
698
699 // Left column with information portlet.
700 echo "<tr><td class=pcleft height='1%' width='50%'>";
254673dd 701 renderRackInfoPortlet ($rackData);
e673ee24 702 echo "</td>\n";
bb09cca0 703 echo "<td class=pcright>";
e673ee24
DO
704
705 // Grid form.
706 startPortlet ($header);
707 echo "<center>\n";
708 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
709 echo "<tr><th width='10%'>&nbsp;</th><th width='20%'>Front</th>";
710 echo "<th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
9d479d56 711 echo "<form method=post action='${root}?'>\n";
e673ee24
DO
712 echo "<input type=hidden name=page value=${pageno}>\n";
713 echo "<input type=hidden name=tab value=${tabno}>\n";
714 echo "<input type=hidden name=rack_id value=${rack_id}>\n";
715 markupAtomGrid ($rackData, $state2);
716 renderAtomGrid ($rackData);
717 echo "</table></center>\n";
718 echo "<br><input type=submit name=do_update value='${submit}'></form><br><br>\n";
719 finishPortlet();
bb09cca0 720 echo "</td></tr></table>\n";
e673ee24
DO
721}
722
723function renderRackDesign ($rack_id)
724{
bb09cca0 725 renderGridForm ($rack_id, 'applyRackDesignMask', 'Rack design', 'Set rack design', 'A', 'F');
e673ee24
DO
726}
727
728function renderRackProblems ($rack_id = 0)
729{
bb09cca0 730 renderGridForm ($rack_id, 'applyRackProblemMask', 'Rack problems', 'Mark unusable atoms', 'F', 'U');
e673ee24
DO
731}
732
733function startPortlet ($title = '')
734{
735 echo "<div class=portlet><h2>${title}</h2>";
736}
737
738function finishPortlet ()
739{
740 echo "</div>\n";
741}
742
743function printRefsOfType ($refs, $type, $eq)
744{
745 global $root;
746 $gotone=0;
747 foreach ($refs as $ref)
748 {
749 if ($eq($ref['type'], $type))
750 {
751 if ($gotone) echo ', ';
4b2bf583
DO
752 echo "<a href='${root}?page=object&object_id=${ref['object_id']}'>";
753 if (!empty ($ref['name']))
754 echo $ref['name'] . '@';
755 echo "${ref['object_name']}</a>";
e673ee24
DO
756 $gotone=1;
757 }
758 }
759}
760
761function renderRackObject ($object_id = 0)
762{
52c836b1 763 global $root, $nextorder, $aac;
e673ee24
DO
764 if ($object_id <= 0)
765 {
591ff2c4 766 showError ('Invalid object_id', __FUNCTION__);
e673ee24
DO
767 return;
768 }
769 $info = getObjectInfo ($object_id);
770 if ($info == NULL)
771 {
591ff2c4 772 showError ('getObjectInfo() failed', __FUNCTION__);
e673ee24
DO
773 return;
774 }
775 // Main layout starts.
776 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
777 echo "<tr><td colspan=2 align=center><h1>${info['dname']}</h1></td></tr>\n";
778 // left column with uknown number of portlets
779 echo "<tr><td class=pcleft>";
0ab782bc 780 startPortlet ('summary');
e673ee24
DO
781 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
782 if (!empty ($info['name']))
783 echo "<tr><th width='50%' class=tdright>Common name:</th><td class=tdleft>${info['name']}</td></tr>\n";
9c0b0016 784 elseif (in_array ($info['objtype_id'], explode (',', getConfigVar ('NAMEFUL_OBJTYPES'))))
a0ec6295 785 echo "<tr><td colspan=2 class=msg_error>Common name is missing.</td></tr>\n";
e2ac59cf 786 echo "<tr><th width='50%' class=tdright>Object type:</th>";
8e700dd1 787 echo "<td class=tdleft><a href='${root}?page=objgroup&group_id=${info['objtype_id']}&hl_object_id=${object_id}'>${info['objtype_name']}</a></td></tr>\n";
e673ee24
DO
788 if (!empty ($info['asset_no']))
789 echo "<tr><th width='50%' class=tdright>Asset tag:</th><td class=tdleft>${info['asset_no']}</td></tr>\n";
a6305acc 790 elseif (in_array ($info['objtype_id'], explode (',', getConfigVar ('REQUIRE_ASSET_TAG_FOR'))))
a0ec6295 791 echo "<tr><td colspan=2 class=msg_error>Asset tag is missing.</td></tr>\n";
e673ee24
DO
792 if (!empty ($info['label']))
793 echo "<tr><th width='50%' class=tdright>Visible label:</th><td class=tdleft>${info['label']}</td></tr>\n";
794 if (!empty ($info['barcode']))
795 echo "<tr><th width='50%' class=tdright>Barcode:</th><td class=tdleft>${info['barcode']}</td></tr>\n";
796 if ($info['has_problems'] == 'yes')
797 echo "<tr><td colspan=2 class=msg_error>Has problems</td></tr>\n";
24cbe8af 798 foreach (getAttrValues ($object_id, TRUE) as $record)
e673ee24 799 if (!empty ($record['value']))
50a954f6 800 echo "<tr><th width='50%' class=opt_attr_th>${record['name']}:</th><td class=tdleft>${record['a_value']}</td></tr>\n";
d9f8a37a 801 printTagTRs ("${root}?page=objgroup&tab=default&group_id=${info['objtype_id']}&");
e673ee24
DO
802 echo "</table><br>\n";
803 finishPortlet();
804
805 if (!empty ($info['comment']))
806 {
807 startPortlet ('Comment');
6cc5d6cd 808 echo '<div class=commentblock>' . string_insert_hrefs ($info['comment']) . '</div>';
e673ee24
DO
809 finishPortlet ();
810 }
811
e1ae3fb4
AD
812 renderFilesPortlet ('object', $object_id);
813
e673ee24
DO
814 $ports = getObjectPortsAndLinks ($object_id);
815 if (count ($ports))
816 {
0ab782bc 817 startPortlet ('ports and links');
e673ee24
DO
818 usort($ports, 'sortByName');
819 if ($ports)
820 {
821 $hl_port_id = 0;
822 if (isset ($_REQUEST['hl_port_id']))
823 {
2c6c7645 824 assertUIntArg ('hl_port_id', __FUNCTION__);
e673ee24
DO
825 $hl_port_id = $_REQUEST['hl_port_id'];
826 }
827 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
828 echo "<tr><th>Local name</th><th>Visible label</th><th>Port type</th><th>L2 address</th>";
829 echo "<th>Rem. Object</th><th>Rem. port</th></tr>\n";
830 foreach ($ports as $port)
831 {
832 echo '<tr';
833 if ($hl_port_id == $port['id'])
834 echo ' class=port_highlight';
835 echo "><td>${port['name']}</td><td>${port['label']}</td><td>${port['type']}</td>";
836 echo "<td>${port['l2address']}</td>";
837 if ($port['remote_object_id'])
838 {
8e700dd1 839 echo "<td><a href='${root}?page=object&object_id=${port['remote_object_id']}&hl_port_id=${port['remote_id']}'>${port['remote_object_name']}</a></td>";
e673ee24
DO
840 echo "<td>${port['remote_name']}</td>";
841 }
842 elseif (!empty ($port['reservation_comment']))
843 {
844 echo "<td><b>Reserved;</b></td>";
845 echo "<td>${port['reservation_comment']}</td>";
846 }
847 else
848 echo '<td>&nbsp;</td><td>&nbsp;</td>';
849 echo "</tr>\n";
850 }
851 echo "</table><br>\n";
852 }
853 finishPortlet();
854 }
85970da2 855
0ab782bc
DO
856 $alloclist = getObjectIPv4Allocations ($object_id);
857 if (count ($alloclist))
e673ee24 858 {
f28fbe8b 859 startPortlet ('IPv4 addresses');
e673ee24 860 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
f0ed1181 861 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
71287f1c 862 echo "<tr><th>OS interface</th><th>IP address</th><th colspan=2>network</th><th>routed by</th><th>peers</th></tr>\n";
83fdf85f
DO
863 else
864 echo "<tr><th>OS interface</th><th>IP address</th><th>peers</th></tr>\n";
fc0e3978
DO
865 $hl_ipv4_addr = '';
866 if (isset ($_REQUEST['hl_ipv4_addr']))
867 {
868 assertIPv4Arg ('hl_ipv4_addr', __FUNCTION__);
869 $hl_ipv4_addr = $_REQUEST['hl_ipv4_addr'];
870 }
85970da2 871 foreach ($alloclist as $dottedquad => $alloc)
e673ee24 872 {
0ab782bc
DO
873 $address_name = niftyString ($alloc['addrinfo']['name']);
874 $class = $alloc['addrinfo']['class'];
85970da2 875 $secondclass = ($hl_ipv4_addr == $dottedquad) ? 'tdleft port_highlight' : 'tdleft';
83fdf85f 876 $netid = getIPv4AddressNetworkId ($dottedquad);
d7a8186d 877 if (NULL !== $netid)
83fdf85f 878 {
d7a8186d
DO
879 $netinfo = getIPv4NetworkInfo ($netid);
880 loadIPv4AddrList ($netinfo);
83fdf85f 881 }
d7a8186d
DO
882 echo "<tr class='${class}' valign=top><td class=tdleft>${alloc['osif']}</td><td class='${secondclass}'>";
883 if (NULL !== $netid)
884 echo "<a href='${root}?page=ipaddress&ip=" . $dottedquad . "&hl_object_id=${object_id}'>${dottedquad}</a>";
885 else
886 echo $dottedquad;
887 if (getConfigVar ('EXT_IPV4_VIEW') != 'yes')
888 echo '<small>/' . (NULL === $netid ? '??' : $netinfo['mask']) . '</small>';
351b1f45 889 echo '&nbsp;' . $aac[$alloc['type']];
83fdf85f 890 if (!empty ($alloc['addrinfo']['name']))
28a664e7 891 echo ' (' . niftyString ($alloc['addrinfo']['name']) . ')';
83fdf85f 892 echo '</td>';
f0ed1181 893 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
b90c3907 894 {
83fdf85f 895 if (NULL === $netid)
d7a8186d 896 echo '<td colspan=2>N/A</td><td>&nbsp;</td>';
83fdf85f 897 else
83fdf85f 898 {
d7a8186d
DO
899 printIPv4NetInfoTDs ($netinfo, $secondclass);
900 echo "<td class='${secondclass}'>";
901 // FIXME: These calls are really heavy, replace them with a more appropriate dedicated function.
902 $newline = '';
903 foreach (findRouters ($netinfo['addrlist']) as $router)
904 {
905 if ($router['id'] == $object_id)
906 continue;
907 echo $newline . $router['addr'] . ", <a href='${root}?page=object&object_id=${router['id']}&hl_ipv4_addr=${router['addr']}'>";
908 echo (empty ($router['iface']) ? '' : $router['iface'] . '@') . $router['dname'] . '</a>';
909 $routertags = loadRackObjectTags ($router['id']);
910 if (count ($routertags))
911 echo '<br><small>' . serializeTags ($routertags, "${root}?page=objects&tab=default&") . '</small>';
912 $newline = '<br>';
913 }
914 echo '</td>';
83fdf85f 915 }
b90c3907 916 }
83fdf85f 917 // peers
0ab782bc 918 echo "<td class='${secondclass}'>\n";
0ab782bc 919 $prefix = '';
2c817354 920 if ($alloc['addrinfo']['reserved'] == 'yes')
e673ee24 921 {
85970da2 922 echo $prefix . '<strong>RESERVED</strong>';
0ab782bc
DO
923 $prefix = '; ';
924 }
925 foreach ($alloc['addrinfo']['allocs'] as $allocpeer)
926 {
927 if ($allocpeer['object_id'] == $object_id)
928 continue;
929 echo $prefix . "<a href='${root}?page=object&object_id=${allocpeer['object_id']}'>";
930 if (!empty ($allocpeer['osif']))
931 echo $allocpeer['osif'] . '@';
932 echo $allocpeer['object_name'] . '</a>';
0ab782bc 933 $prefix = '; ';
e673ee24 934 }
e673ee24
DO
935 echo "</td></tr>\n";
936 }
937 echo "</table><br>\n";
938 finishPortlet();
939 }
940
eeb4a5d8 941 $forwards = getNATv4ForObject ($object_id);
e673ee24
DO
942 if (count($forwards['in']) or count($forwards['out']))
943 {
f28fbe8b 944 startPortlet('NATv4');
e673ee24
DO
945
946 if (count($forwards['out']))
947 {
948
f28fbe8b 949 echo "<h3>locally performed NAT</h3>";
e673ee24 950
105a3bc8 951 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
f28fbe8b 952 echo "<tr><th>Proto</th><th>Match endpoint</th><th>Translate to</th><th>Target object</th><th>Rule comment</th></tr>\n";
e673ee24
DO
953
954 foreach ($forwards['out'] as $pf)
955 {
2c817354
DO
956 $class = 'trerror';
957 $osif = '';
958 if (isset ($alloclist [$pf['localip']]))
959 {
960 $class = $alloclist [$pf['localip']]['addrinfo']['class'];
961 $osif = $alloclist [$pf['localip']]['osif'] . ': ';
962 }
e673ee24 963 echo "<tr class='$class'>";
2c817354 964 echo "<td>${pf['proto']}</td><td class=tdleft>${osif}<a href='${root}?page=ipaddress&tab=default&ip=${pf['localip']}'>${pf['localip']}</a>:${pf['localport']}</td>";
f28fbe8b 965 echo "<td class=tdleft><a href='${root}?page=ipaddress&tab=default&ip=${pf['remoteip']}'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
53ef3908 966 $address = getIPv4Address ($pf['remoteip']);
e673ee24 967 echo "<td class='description'>";
53ef3908
DO
968 if (count ($address['allocs']))
969 foreach($address['allocs'] as $bond)
f28fbe8b
DO
970 echo "<a href='${root}?page=object&tab=default&object_id=${bond['object_id']}'>${bond['object_name']}(${bond['name']})</a> ";
971 elseif (!empty ($pf['remote_addr_name']))
972 echo '(' . $pf['remote_addr_name'] . ')';
53ef3908 973 echo "</td><td class='description'>${pf['description']}</td></tr>";
e673ee24
DO
974 }
975 echo "</table><br><br>";
976 }
977 if (count($forwards['in']))
978 {
f28fbe8b 979 echo "<h3>arriving NAT connections</h3>";
105a3bc8 980 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
f28fbe8b 981 echo "<tr><th>Matched endpoint</th><th>Source object</th><th>Translated to</th><th>Rule comment</th></tr>\n";
e673ee24
DO
982 foreach ($forwards['in'] as $pf)
983 {
984 echo "<tr>";
985 echo "<td>${pf['proto']}/<a href='${root}?page=ipaddress&tab=default&ip=${pf['localip']}'>${pf['localip']}</a>:${pf['localport']}</td>";
e673ee24 986 echo "<td class='description'><a href='${root}?page=object&tab=default&object_id=${pf['object_id']}'>${pf['object_name']}</a>";
e673ee24
DO
987 echo "</td><td><a href='${root}?page=ipaddress&tab=default&ip=${pf['remoteip']}'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
988 echo "<td class='description'>${pf['description']}</td></tr>";
989 }
e673ee24
DO
990 echo "</table><br><br>";
991 }
992 finishPortlet();
993 }
994
78e7b769
DO
995 $pools = getRSPoolsForObject ($object_id);
996 if (count ($pools))
997 {
300826cb 998 $order = 'odd';
78e7b769
DO
999 startPortlet ('Real server pools');
1000 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
732e4578 1001 echo "<tr><th>VS</th><th>RS pool</th><th>RS</th><th>VS config</th><th>RS config</th></tr>\n";
748805bf 1002 foreach ($pools as $vs_id => $info)
78e7b769 1003 {
300826cb 1004 echo "<tr valign=top class=row_${order}><td class=tdleft><a href='${root}?page=ipv4vs&vs_id=${vs_id}'>";
748805bf
DO
1005 echo buildVServiceName ($info);
1006 echo '</a>';
1007 if (!empty ($info['name']))
300826cb 1008 echo "<br>${info['name']}";
e1ae3fb4 1009 echo "</td><td class=tdleft><a href='${root}?page=ipv4rspool&pool_id=${info['pool_id']}'>";
748805bf 1010 echo (empty ($info['pool_name']) ? 'ANONYMOUS' : $info['pool_name']);
732e4578
DO
1011 echo '</a></td><td class=tdleft>' . $info['rscount'] . '</td>';
1012 echo "<td class=tdleft><pre>${info['vsconfig']}</pre></td>";
1013 echo "<td class=tdleft><pre>${info['rsconfig']}</pre></td>";
78e7b769 1014 echo "</tr>\n";
300826cb 1015 $order = $nextorder[$order];
78e7b769
DO
1016 }
1017 echo "</table>\n";
1018 finishPortlet();
1019 }
e673ee24
DO
1020 echo "</td>\n";
1021
7056988c 1022 // After left column we have (surprise!) right column with rackspace portlet only.
e673ee24
DO
1023 echo "<td class=pcright>";
1024 // rackspace portlet
0ab782bc 1025 startPortlet ('rackspace allocation');
e673ee24
DO
1026 // FIXME: now we call getRackData() twice
1027 $racks = getResidentRacksData ($object_id);
1028 foreach ($racks as $rackData)
1029 renderRack ($rackData['id'], $object_id);
1030 echo '<br>';
1031 finishPortlet();
1032 echo "</td></tr>";
1033 echo "</table>\n";
1034}
1035
1036function renderRackMultiSelect ($sname, $racks, $selected)
1037{
04571888
DO
1038 // Transform the given flat list into a list of groups, each representing a rack row.
1039 $rdata = array();
e673ee24 1040 foreach ($racks as $rack)
04571888
DO
1041 if (!isset ($rdata[$rack['row_name']]))
1042 $rdata[$rack['row_name']] = array ($rack['id'] => $rack['name']);
1043 else
1044 $rdata[$rack['row_name']][$rack['id']] = $rack['name'];
1045 echo "<select name=${sname} multiple size=" . getConfigVar ('MAXSELSIZE') . " onchange='getElementById(\"racks\").submit()'>\n";
1046 foreach ($rdata as $optgroup => $racklist)
e673ee24 1047 {
04571888
DO
1048 echo "<optgroup label='${optgroup}'>";
1049 foreach ($racklist as $rack_id => $rack_name)
1050 {
1051 echo "<option value=${rack_id}";
1052 if (!(array_search ($rack_id, $selected) === FALSE))
1053 echo ' selected';
1054 echo">${rack_name}</option>\n";
1055 }
e673ee24
DO
1056 }
1057 echo "</select>\n";
1058}
1059
1060function showMessageOrError ()
1061{
46f92ff7 1062 if (isset ($_REQUEST['message']))
e673ee24 1063 echo "<div class=msg_success>${_REQUEST['message']}</div>";
46f92ff7 1064 elseif (isset ($_REQUEST['error']))
e673ee24 1065 echo "<div class=msg_error>${_REQUEST['error']}</div>";
46f92ff7
DO
1066 elseif (isset ($_REQUEST['log']))
1067 printLog (unserialize (base64_decode ($_REQUEST['log'])));
e673ee24
DO
1068}
1069
1070// This function renders a form for port edition.
1071function renderPortsForObject ($object_id = 0)
1072{
39b4abd0
DO
1073 function printNewItemTR ()
1074 {
1075 printOpFormIntro ('addPort');
1076 echo "<tr><td>";
f5ff50f5 1077 printImageHREF ('add', 'add a port', TRUE);
39b4abd0 1078 echo "</td><td><input type=text size=8 name=port_name tabindex=100></td>\n";
3decd141
DO
1079 echo "<td><input type=text size=24 name=port_label tabindex=101></td><td>";
1080 printSelect (getPortTypes(), 'port_type_id', getConfigVar ('default_port_type'), 102);
39b4abd0 1081 echo "<td><input type=text name=port_l2address tabindex=103></td>\n";
9318d2ef
DO
1082 echo "<td colspan=3>&nbsp;</td><td>";
1083 printImageHREF ('add', 'add a port', TRUE, 104);
1084 echo "</td></tr></form>";
39b4abd0 1085 }
e673ee24
DO
1086 global $root, $pageno, $tabno;
1087 if ($object_id <= 0)
1088 {
591ff2c4 1089 showError ('Invalid object_id', __FUNCTION__);
e673ee24
DO
1090 return;
1091 }
1092 showMessageOrError();
1093 startPortlet ('Ports and interfaces');
1094 $ports = getObjectPortsAndLinks ($object_id);
1095 usort($ports, 'sortByName');
1096 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
1097 echo "<tr><th>&nbsp;</th><th>Local name</th><th>Visible label</th><th>Port type</th><th>L2 address</th>";
1098 echo "<th>Rem. object</th><th>Rem. port</th><th>(Un)link or (un)reserve</th><th>&nbsp;</th></tr>\n";
39b4abd0
DO
1099 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
1100 printNewItemTR();
e673ee24
DO
1101 foreach ($ports as $port)
1102 {
7056988c 1103 printOpFormIntro ('editPort', array ('port_id' => $port['id']));
e673ee24
DO
1104 echo "<tr><td><a href='${root}process.php?op=delPort&page=${pageno}&tab=${tabno}&port_id=${port['id']}&object_id=$object_id&port_name=${port['name']}'>";
1105 printImageHREF ('delete', 'Unlink and Delete this port');
1106 echo "</a></td>\n";
1107 echo "<td><input type=text name=name value='${port['name']}' size=8></td>";
1108 echo "<td><input type=text name=label value='${port['label']}' size=24></td>";
611170af
AD
1109 if (!$port['remote_object_id'])
1110 {
1111 echo "<td>";
1112 printSelect (getPortTypes(), 'port_type_id', $port['type_id']);
1113 echo "</td>";
1114 }
1115 else
1116 {
1117 echo "<input type=hidden name=port_type_id value='${port['type_id']}'>";
1118 echo "<td>${port['type']}</td>\n";
1119 }
e673ee24
DO
1120 echo "<td><input type=text name=l2address value='${port['l2address']}'></td>\n";
1121 if ($port['remote_object_id'])
1122 {
1123 echo "<td><a href='${root}?page=object&object_id=${port['remote_object_id']}'>${port['remote_object_name']}</a></td>";
1124 echo "<td>${port['remote_name']}</td>";
1125 echo "<td><a href='${root}process.php?op=unlinkPort&page=${pageno}&tab=${tabno}&port_id=${port['id']}&object_id=$object_id&port_name=";
1126 echo urlencode ($port['name']);
1127 echo "&remote_port_name=${port['remote_name']}&remote_object_name=${port['remote_object_name']}'>";
39be655e 1128 printImageHREF ('clear', 'Unlink this port');
e673ee24
DO
1129 echo "</a></td>";
1130 }
1131 elseif (!empty ($port['reservation_comment']))
1132 {
1133 echo "<td><b>Reserved;</b></td>";
1134 echo "<td><input type=text name=reservation_comment value='${port['reservation_comment']}'></td>";
1135 echo "<td><a href='${root}process.php?op=useup&page=${pageno}&tab=${tabno}&port_id=${port['id']}&object_id=${object_id}'>";
39be655e 1136 printImageHREF ('clear', 'Use up this port');
e673ee24
DO
1137 echo "</a></td>";
1138 }
1139 else
1140 {
1141 echo "<td>&nbsp;</td><td>&nbsp;</td>";
1142 echo "<td>";
e1ae3fb4 1143 echo "<a href='javascript:;' onclick='window.open(\"${root}port_link_helper.php?port=${port['id']}&type=${port['type_id']}&object_id=$object_id&port_name=";
e673ee24
DO
1144 echo urlencode ($port['name']);
1145 echo "\",\"findlink\",\"height=700, width=400, location=no, menubar=no, resizable=yes, scrollbars=no, status=no, titlebar=no, toolbar=no\");'>";
1146 printImageHREF ('link', 'Link this port');
1147 echo "</a> <input type=text name=reservation_comment>";
1148 echo "</td>\n";
1149 }
5bbbeaa2
DO
1150 echo "<td>";
1151 printImageHREF ('save', 'Save changes', TRUE);
1152 echo "</td></form></tr>\n";
e673ee24 1153 }
39b4abd0
DO
1154 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
1155 printNewItemTR();
e673ee24
DO
1156 echo "</table><br>\n";
1157 finishPortlet();
1158
1159 startPortlet ('Add/update multiple ports');
7056988c 1160 printOpFormIntro ('addMultiPorts');
e673ee24 1161 echo 'Format: <select name=format>';
e673ee24
DO
1162 echo '<option value=c3600asy>Cisco 3600 async: sh line | inc TTY</option>';
1163 echo '<option value=fiwg selected>Foundry ServerIron/FastIron WorkGroup/Edge: sh int br</option>';
e673ee24 1164 echo '<option value=fisxii>Foundry FastIron SuperX/II4000: sh int br</option>';
351d4dbf 1165 echo '<option value=ssv1>SSV:&lt;interface name&gt; &lt;MAC address&gt;</option>';
e673ee24
DO
1166 echo "</select>";
1167 echo 'Default port type: ';
3decd141 1168 printSelect (getPortTypes(), 'port_type', getConfigVar ('default_port_type'), 102);
e673ee24
DO
1169 echo "<input type=submit value='Parse output'><br>\n";
1170 echo "<textarea name=input cols=100 rows=50></textarea><br>\n";
1171 echo '</form>';
1172 finishPortlet();
1173}
1174
72d8ced3 1175function renderIPv4ForObject ($object_id = 0)
e673ee24 1176{
39b4abd0
DO
1177 function printNewItemTR ()
1178 {
1179 global $aat;
1180 printOpFormIntro ('addIPv4Allocation');
1181 echo "<tr><td>";
f5ff50f5 1182 printImageHREF ('add', 'allocate', TRUE);
39b4abd0
DO
1183 echo "</td>";
1184 echo "<td class=tdleft><input type='text' size='10' name='bond_name' tabindex=100></td>\n";
1185 echo "<td class=tdleft><input type=text name='ip' tabindex=101></td>\n";
1186 echo "<td colspan=3>&nbsp;</td><td>";
f5ff50f5 1187 printSelect ($aat, 'bond_type', NULL, 102);
9318d2ef 1188 echo "</td><td>&nbsp;</td><td>";
f5ff50f5 1189 printImageHREF ('add', 'allocate', TRUE, 103);
9318d2ef 1190 echo "</td></tr></form>";
39b4abd0 1191 }
52c836b1 1192 global $root, $pageno, $tabno, $aat;
e673ee24
DO
1193 if ($object_id <= 0)
1194 {
591ff2c4 1195 showError ('Invalid object_id', __FUNCTION__);
e673ee24
DO
1196 return;
1197 }
1198 showMessageOrError();
72d8ced3 1199 startPortlet ('Allocations');
85970da2 1200 $alloclist = getObjectIPv4Allocations ($object_id);
e673ee24 1201 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
79e45b4c
DO
1202 echo '<tr><th>&nbsp;</th><th>OS interface</th><th>IP address</th>';
1203 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
1204 echo '<th colspan=2>network</th><th>routed by</th>';
1205 echo '<th>type</th><th>misc</th><th>&nbsp</th></tr>';
09620506 1206
39b4abd0
DO
1207 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
1208 printNewItemTR();
85970da2 1209 foreach ($alloclist as $dottedquad => $alloc)
e673ee24 1210 {
85970da2 1211 $class = $alloc['addrinfo']['class'];
79e45b4c 1212 $netid = getIPv4AddressNetworkId ($dottedquad);
d7a8186d
DO
1213 if (NULL !== $netid)
1214 {
1215 $netinfo = getIPv4NetworkInfo ($netid);
1216 loadIPv4AddrList ($netinfo);
1217 }
85970da2 1218 printOpFormIntro ('updIPv4Allocation', array ('ip' => $dottedquad));
79e45b4c 1219 echo "<tr class='$class' valign=top><td><a href='${root}process.php?op=delIPv4Allocation&page=${pageno}&tab=${tabno}&ip=${dottedquad}&object_id=$object_id'>";
e673ee24
DO
1220 printImageHREF ('delete', 'Delete this IPv4 address');
1221 echo "</a></td>";
d7a8186d
DO
1222 echo "<td class=tdleft><input type='text' name='bond_name' value='${alloc['osif']}' size=10></td><td class=tdleft>";
1223 if (NULL !== $netid)
1224 echo "<a href='${root}?page=ipaddress&ip=${dottedquad}'>${dottedquad}</a>";
1225 else
1226 echo $dottedquad;
79e45b4c 1227 if (getConfigVar ('EXT_IPV4_VIEW') != 'yes')
d7a8186d 1228 echo '<small>/' . (NULL === $netid ? '??' : $netinfo['mask']) . '</small>';
79e45b4c 1229 if (!empty ($alloc['addrinfo']['name']))
28a664e7 1230 echo ' (' . niftyString ($alloc['addrinfo']['name']) . ')';
79e45b4c
DO
1231 echo '</td>';
1232 // FIXME: this a copy-and-paste from renderRackObject()
1233 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
1234 {
1235 if (NULL === $netid)
d7a8186d 1236 echo '<td colspan=2>N/A</td><td>&nbsp;</td>';
79e45b4c 1237 else
79e45b4c 1238 {
d7a8186d
DO
1239 printIPv4NetInfoTDs ($netinfo);
1240 echo "<td class=tdleft>";
1241 // FIXME: These calls are really heavy, replace them with a more appropriate dedicated function.
1242 $newline = '';
1243 foreach (findRouters ($netinfo['addrlist']) as $router)
1244 {
1245 if ($router['id'] == $object_id)
1246 continue;
1247 echo $newline . $router['addr'] . ", <a href='${root}?page=object&object_id=${router['id']}&hl_ipv4_addr=${router['addr']}'>";
1248 echo (empty ($router['iface']) ? '' : $router['iface'] . '@') . $router['dname'] . '</a>';
1249 $routertags = loadRackObjectTags ($router['id']);
1250 if (count ($routertags))
1251 echo '<br><small>' . serializeTags ($routertags, "${root}?page=objects&tab=default&") . '</small>';
1252 $newline = '<br>';
1253 }
1254 echo '</td>';
79e45b4c 1255 }
79e45b4c
DO
1256 }
1257 echo '<td>';
85970da2 1258 printSelect ($aat, 'bond_type', $alloc['type']);
e673ee24 1259 echo "</td><td>";
85970da2 1260 $prefix = '';
4940e4d5 1261 if ($alloc['addrinfo']['reserved'] == 'yes')
e673ee24 1262 {
85970da2
DO
1263 echo $prefix . '<strong>RESERVED</strong>';
1264 $prefix = '; ';
e673ee24 1265 }
85970da2 1266 foreach ($alloc['addrinfo']['allocs'] as $allocpeer)
e673ee24 1267 {
85970da2
DO
1268 if ($allocpeer['object_id'] == $object_id)
1269 continue;
1270 echo $prefix . "<a href='${root}?page=object&object_id=${allocpeer['object_id']}'>";
1271 if (!empty ($allocpeer['osif']))
1272 echo $allocpeer['osif'] . '@';
1273 echo $allocpeer['object_name'] . '</a>';
1274 $prefix = '; ';
e673ee24 1275 }
d54b9495
DO
1276 echo "</td><td>";
1277 printImageHREF ('save', 'Save changes', TRUE);
1278 echo "</td></form></tr>\n";
e673ee24 1279 }
39b4abd0
DO
1280 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
1281 printNewItemTR();
e673ee24 1282
09620506 1283 echo "</table><br>\n";
e673ee24
DO
1284 finishPortlet();
1285
1286}
1287
baf37d01
DO
1288// Log structure versions:
1289// 1: the whole structure is a list of code-message pairs
1290// 2 and later: there's a "v" field set, which indicates the version
1291// 2: there's a "m" list set to hold message code and optional arguments
e673ee24
DO
1292function printLog ($log)
1293{
baf37d01
DO
1294 switch (TRUE)
1295 {
1296 case !isset ($log['v']):
ebb5441d 1297 case $log['v'] == 1:
baf37d01 1298 foreach ($log as $key => $record)
ebb5441d 1299 if ($key !== 'v')
baf37d01
DO
1300 echo "<div class=msg_${record['code']}>${record['message']}</div>";
1301 break;
1302 case $log['v'] == 2:
1303 $msginfo = array
1304 (
ebb5441d 1305 0 => array ('code' => 'success', 'format' => 'Success: %s'),
baf37d01
DO
1306 1 => array ('code' => 'success', 'format' => '%u new records done, %u already existed'),
1307 2 => array ('code' => 'success', 'format' => 'NATv4 rule was successfully added.'),
1308 3 => array ('code' => 'success', 'format' => 'NATv4 rule was successfully deleted.'),
1309 4 => array ('code' => 'success', 'format' => 'NATv4 rule was successfully updated'),
1310 5 => array ('code' => 'success', 'format' => 'Port %s was added successfully'),
1311 6 => array ('code' => 'success', 'format' => 'Port %s was updated successfully'),
1312 7 => array ('code' => 'success', 'format' => 'Port %s was deleted successfully'),
1313 8 => array ('code' => 'success', 'format' => 'Port %s successfully linked with port %s at object %s'),
1314 9 => array ('code' => 'success', 'format' => 'Port %s was successfully unlinked from %s@%s'),
1315 10 => array ('code' => 'success', 'format' => 'Added %u ports, updated %u ports, encountered %u errors.'),
1316 11 => array ('code' => 'success', 'format' => 'Reservation removed.'),
1317 12 => array ('code' => 'success', 'format' => 'allocation updated'),
1318 13 => array ('code' => 'success', 'format' => 'allocated'),
1319 14 => array ('code' => 'success', 'format' => 'deallocated'),
1320 15 => array ('code' => 'success', 'format' => 'Reset succeeded.'),
1321 16 => array ('code' => 'success', 'format' => 'Update done'),
1322 17 => array ('code' => 'success', 'format' => 'Update(s) succeeded.'),
1323 18 => array ('code' => 'success', 'format' => 'Load balancer was successfully added'),
1324 19 => array ('code' => 'success', 'format' => 'Load balancer was successfully deleted'),
1325 20 => array ('code' => 'success', 'format' => 'Load balancer info was successfully updated'),
1326 21 => array ('code' => 'success', 'format' => 'Generation complete'),
1327 22 => array ('code' => 'success', 'format' => 'Chained %u tags'),
1328 23 => array ('code' => 'success', 'format' => 'IPv4 prefix successfully added'),
1329 24 => array ('code' => 'success', 'format' => 'IPv4 prefix deleted'),
1330 25 => array ('code' => 'success', 'format' => 'IPv4 prefix updated'),
1331 26 => array ('code' => 'success', 'format' => '%u IP address(es) were successfully updated'),
1332 27 => array ('code' => 'success', 'format' => 'IPv4 address updated'),
1333 28 => array ('code' => 'success', 'format' => 'Virtual service was successfully created'),
1334 29 => array ('code' => 'success', 'format' => 'Virtual service was successfully deleted'),
1335 30 => array ('code' => 'success', 'format' => 'Virtual service was successfully updated'),
1336 31 => array ('code' => 'success', 'format' => 'RS pool was successfully created'),
1337 32 => array ('code' => 'success', 'format' => 'RS pool was successfully deleted'),
1338 33 => array ('code' => 'success', 'format' => 'RS pool was successfully updated'),
1339 34 => array ('code' => 'success', 'format' => 'Real server was successfully added'),
1340 35 => array ('code' => 'success', 'format' => 'Real server was successfully deleted'),
1341 36 => array ('code' => 'success', 'format' => 'Real server was successfully updated'),
1342 37 => array ('code' => 'success', 'format' => 'Successfully added %u real servers'),
1343 38 => array ('code' => 'success', 'format' => '%u real server(s) were successfully (de)activated'),
1344 39 => array ('code' => 'success', 'format' => 'User account %s updated.'),
1345 40 => array ('code' => 'success', 'format' => 'User account %s created.'),
1346 41 => array ('code' => 'success', 'format' => 'User account disabled.'),
1347 42 => array ('code' => 'success', 'format' => 'User account enabled.'),
1348 43 => array ('code' => 'success', 'format' => 'Saved successfully.'),
1349 44 => array ('code' => 'success', 'format' => '%s failures and %s successfull changes.'),
1350 45 => array ('code' => 'success', 'format' => "Attribute '%s' created."),
1351 46 => array ('code' => 'success', 'format' => 'Rename successful.'),
1352 47 => array ('code' => 'success', 'format' => 'Attribute was deleted.'),
1353 48 => array ('code' => 'success', 'format' => 'Supplement succeeded.'),
1354 49 => array ('code' => 'success', 'format' => 'Reduction succeeded.'),
1355 50 => array ('code' => 'success', 'format' => 'Reduction succeeded.'),
1356 51 => array ('code' => 'success', 'format' => 'Update succeeded.'),
1357 52 => array ('code' => 'success', 'format' => 'Supplement succeeded.'),
1358 53 => array ('code' => 'success', 'format' => 'Chapter was deleted.'),
1359 54 => array ('code' => 'success', 'format' => 'Chapter was updated.'),
1360 55 => array ('code' => 'success', 'format' => 'Chapter was added.'),
1361 56 => array ('code' => 'success', 'format' => 'Update succeeded.'),
1362 57 => array ('code' => 'success', 'format' => 'Reset complete'),
1363 58 => array ('code' => 'success', 'format' => "Successfully deleted tag ."),
1364 59 => array ('code' => 'success', 'format' => "Created tag '%s'."),
1365 60 => array ('code' => 'success', 'format' => "Updated tag '%s'."),
ebb5441d 1366 61 => array ('code' => 'success', 'format' => 'Password changed successfully.'),
24dcb9d8 1367 62 => array ('code' => 'success', 'format' => 'gw: %s'),
f0ff4930
DO
1368 63 => array ('code' => 'success', 'format' => '%u change request(s) have been processed'),
1369 64 => array ('code' => 'success', 'format' => 'Port %s@%s has been assigned to VLAN %u'),
f19c75d6 1370 65 => array ('code' => 'success', 'format' => "Added new rack '%s'"),
03e6ef01 1371 66 => array ('code' => 'success', 'format' => "File sent Ok via handler '%s'"),
abef7149 1372 67 => array ('code' => 'success', 'format' => "Tag rolling done, %u objects involved"),
0c2b7c4a 1373 68 => array ('code' => 'success', 'format' => "Updated rack '%s'"),
e1ae3fb4
AD
1374 69 => array ('code' => 'success', 'format' => 'File %s was added successfully'),
1375 70 => array ('code' => 'success', 'format' => 'File %s was updated successfully'),
1376 71 => array ('code' => 'success', 'format' => 'File %s was linked successfully'),
1377 72 => array ('code' => 'success', 'format' => 'File %s was unlinked successfully'),
1378 73 => array ('code' => 'success', 'format' => 'File %s was deleted successfully'),
345fd640
AD
1379 74 => array ('code' => 'success', 'format' => 'Row %s was added successfully'),
1380 75 => array ('code' => 'success', 'format' => 'Row %s was updated successfully'),
f0ff4930 1381
ebb5441d
DO
1382 100 => array ('code' => 'error', 'format' => 'Generic error: %s'),
1383 101 => array ('code' => 'error', 'format' => 'Port name cannot be empty'),
1384 102 => array ('code' => 'error', 'format' => "Error creating user account '%s'"),
1385 103 => array ('code' => 'error', 'format' => 'getHashByID() failed'),
1386 104 => array ('code' => 'error', 'format' => "Error updating user account '%s'"),
1387 105 => array ('code' => 'error', 'format' => 'Error enabling user account.'),
1388 106 => array ('code' => 'error', 'format' => 'Error disabling user account.'),
1389 107 => array ('code' => 'error', 'format' => 'Admin account cannot be disabled'),
1390 108 => array ('code' => 'error', 'format' => '%u failures and %u successfull changes.'),
1391 109 => array ('code' => 'error', 'format' => 'Update failed!'),
1392 110 => array ('code' => 'error', 'format' => 'Supplement failed!'),
1393 111 => array ('code' => 'error', 'format' => 'Reduction failed!'),
1394 112 => array ('code' => 'error', 'format' => 'Error adding chapter.'),
1395 113 => array ('code' => 'error', 'format' => 'Error updating chapter.'),
1396 114 => array ('code' => 'error', 'format' => 'Error deleting chapter.'),
1397 115 => array ('code' => 'error', 'format' => 'Error renaming attribute.'),
1398 116 => array ('code' => 'error', 'format' => 'Error creating attribute.'),
1399 117 => array ('code' => 'error', 'format' => 'Error deleting attribute.'),
1400 118 => array ('code' => 'error', 'format' => 'Supplement failed!'),
1401 119 => array ('code' => 'error', 'format' => 'Reduction failed!'),
1402 120 => array ('code' => 'error', 'format' => 'Reset failed!'),
1403 121 => array ('code' => 'error', 'format' => 'commitUpdateObject() failed'),
1404 122 => array ('code' => 'error', 'format' => 'One or more update(s) failed!'),
1405 123 => array ('code' => 'error', 'format' => 'Cannot process submitted data: unknown format code.'),
1406 124 => array ('code' => 'error', 'format' => 'Error removing reservation!'),
1407 125 => array ('code' => 'error', 'format' => "Update failed with error: '%s'"),
1408 126 => array ('code' => 'error', 'format' => 'addRStoRSPool() failed'),
1409 127 => array ('code' => 'error', 'format' => 'Added %u real servers and encountered %u errors'),
1410 128 => array ('code' => 'error', 'format' => 'commitDeleteRS() failed'),
1411 129 => array ('code' => 'error', 'format' => 'commitDeleteLB() failed'),
1412 130 => array ('code' => 'error', 'format' => 'commitDeleteVS() failed'),
1413 131 => array ('code' => 'error', 'format' => 'invalid format requested'),
1414 132 => array ('code' => 'error', 'format' => 'invalid protocol'),
1415 133 => array ('code' => 'error', 'format' => 'commitUpdateRS() failed'),
1416 134 => array ('code' => 'error', 'format' => 'commitUpdateLB() failed'),
1417 135 => array ('code' => 'error', 'format' => 'commitUpdateVS() failed'),
1418 136 => array ('code' => 'error', 'format' => 'addLBtoRSPool() failed'),
1419 137 => array ('code' => 'error', 'format' => 'addLBtoRSPool() failed'),
1420 138 => array ('code' => 'error', 'format' => 'commitDeleteRSPool() failed'),
1421 139 => array ('code' => 'error', 'format' => 'commitUpdateRSPool() failed'),
1422 140 => array ('code' => 'error', 'format' => 'Encountered %u errors, (de)activated %u real servers'),
1423 141 => array ('code' => 'error', 'format' => 'Encountered %u errors, updated %u IP address(es)'),
1424 142 => array ('code' => 'error', 'format' => 'executeAutoPorts() failed'),
1425 143 => array ('code' => 'error', 'format' => 'Tried chaining %u tags, but experienced %u errors.'),
1426 144 => array ('code' => 'error', 'format' => "Error deleting tag: '%s'"),
1427 145 => array ('code' => 'error', 'format' => "Invalid tag name '%s'"),
1428 146 => array ('code' => 'error', 'format' => "Tag '%s' (or similar name) already exists"),
1429 147 => array ('code' => 'error', 'format' => "Could not create tag '%s' because of error '%s'"),
1430 148 => array ('code' => 'error', 'format' => "Could not update tag '%s' because of error '%s'"),
1431 149 => array ('code' => 'error', 'format' => 'Turing test failed'),
1432 150 => array ('code' => 'error', 'format' => 'Can only change password under DB authentication.'),
1433 151 => array ('code' => 'error', 'format' => 'Old password doesn\'t match.'),
1434 152 => array ('code' => 'error', 'format' => 'New passwords don\'t match.'),
1435 153 => array ('code' => 'error', 'format' => 'Password change failed.'),
1436 154 => array ('code' => 'error', 'format' => "Verification error: %s"),
1437 155 => array ('code' => 'error', 'format' => 'Save failed.'),
1438 156 => array ('code' => 'error', 'format' => 'getSwitchVLANs() failed'),
e81fb764 1439 157 => array ('code' => 'error', 'format' => 'operation not permitted'),
24dcb9d8
DO
1440 158 => array ('code' => 'error', 'format' => 'Ignoring malformed record #%u in form submit'),
1441 159 => array ('code' => 'error', 'format' => 'Permission denied moving port %s from VLAN%u to VLAN%u'),
1442 160 => array ('code' => 'error', 'format' => 'Invalid arguments'),
1443 161 => array ('code' => 'error', 'format' => 'Endpoint not found. Please either set FQDN attribute or assign an IP address to the object.'),
1444 162 => array ('code' => 'error', 'format' => 'More than one IP address is assigned to this object, please configure FQDN attribute.'),
1445 163 => array ('code' => 'error', 'format' => 'Failed to get any response from queryGateway() or the gateway died'),
c030232f 1446 164 => array ('code' => 'error', 'format' => 'Gateway failure: %s.'),
24dcb9d8
DO
1447 165 => array ('code' => 'error', 'format' => 'Gateway failure: malformed reply.'),
1448 166 => array ('code' => 'error', 'format' => 'gw: %s'),
f0ff4930
DO
1449 167 => array ('code' => 'error', 'format' => 'Could not find port %s'),
1450 168 => array ('code' => 'error', 'format' => 'Port %s is a trunk'),
1451 169 => array ('code' => 'error', 'format' => 'Failed to configure %s, connector returned code %u'),
5222f192 1452 170 => array ('code' => 'error', 'format' => 'There is no network for IP address "%s"'),
f19c75d6
DO
1453 171 => array ('code' => 'error', 'format' => "Failed creating rack '%s'. Already exists in this row?"),
1454 172 => array ('code' => 'error', 'format' => 'Malformed request'),
e5c4506d
DO
1455 173 => array ('code' => 'error', 'format' => "Invalid IPv4 prefix '%s'"),
1456 174 => array ('code' => 'error', 'format' => 'Bad IPv4 address'),
1457 175 => array ('code' => 'error', 'format' => 'Invalid netmask'),
1458 176 => array ('code' => 'error', 'format' => 'This network already exists'),
0c2b7c4a 1459 177 => array ('code' => 'error', 'format' => 'commitUpdateRack() failed'),
f0ff4930 1460
24dcb9d8
DO
1461 200 => array ('code' => 'warning', 'format' => 'generic warning: %s'),
1462 201 => array ('code' => 'warning', 'format' => 'nothing happened...'),
1463 202 => array ('code' => 'warning', 'format' => 'gw: %s'),
f0ff4930
DO
1464 203 => array ('code' => 'warning', 'format' => 'Port %s seems to be the first in VLAN %u at this switch.'),
1465 204 => array ('code' => 'warning', 'format' => 'Check uplink/downlink configuration for proper operation.'),
1466 205 => array ('code' => 'warning', 'format' => '%u change request(s) have been ignored'),
baf37d01
DO
1467 );
1468 // Handle the arguments. Is there any better way to do it?
1469 foreach ($log['m'] as $record)
1470 {
5222f192
DO
1471 if (!isset ($record['c']) or !isset ($msginfo[$record['c']]))
1472 {
1473 echo '<div class=msg_neutral>(this message was lost)</div>';
1474 continue;
1475 }
baf37d01
DO
1476 if (isset ($record['a']))
1477 switch (count ($record['a']))
1478 {
1479 case 1:
1480 $msgtext = sprintf
1481 (
1482 $msginfo[$record['c']]['format'],
1483 $record['a'][0]
1484 );
1485 break;
1486 case 2:
1487 $msgtext = sprintf
1488 (
1489 $msginfo[$record['c']]['format'],
1490 $record['a'][0],
1491 $record['a'][1]
1492 );
1493 break;
1494 case 3:
1495 $msgtext = sprintf
1496 (
1497 $msginfo[$record['c']]['format'],
1498 $record['a'][0],
1499 $record['a'][1],
1500 $record['a'][2]
1501 );
1502 break;
1503 case 4:
1504 default:
1505 $msgtext = sprintf
1506 (
1507 $msginfo[$record['c']]['format'],
1508 $record['a'][0],
1509 $record['a'][1],
1510 $record['a'][2],
1511 $record['a'][3]
1512 );
1513 break;
1514 }
1515 else
1516 $msgtext = $msginfo[$record['c']]['format'];
1517 echo '<div class=msg_' . $msginfo[$record['c']]['code'] . ">${msgtext}</div>";
1518 }
1519 break;
1520 default:
1521 echo '<div class=msg_error>' . __FUNCTION__ . ': internal error</div>';
1522 break;
1523 }
e673ee24
DO
1524}
1525
1526/*
1527The following conditions must be followed:
15281. We can mount onto free atoms only. This means: if any record for an atom
1529already exists in RackSpace, it can't be used for mounting.
15302. We can't unmount from 'W' atoms. Operator should review appropriate comments
1531and either delete them before unmounting or refuse to unmount the object.
1532*/
1533
1534// We extensively use $_REQUEST in the function.
7056988c 1535// FIXME: move related code into ophandler
e673ee24
DO
1536function renderRackSpaceForObject ($object_id = 0)
1537{
1538 if ($object_id <= 0)
1539 {
591ff2c4 1540 showError ('Invalid object_id', __FUNCTION__);
e673ee24
DO
1541 return;
1542 }
1543 $is_submit = isset ($_REQUEST['got_atoms']);
1544 $is_update = isset ($_REQUEST['rackmulti'][0]);
1545 $info = getObjectInfo ($object_id);
1546 if ($info == NULL)
1547 {
591ff2c4 1548 showError ('getObjectInfo() failed', __FUNCTION__);
e673ee24
DO
1549 return;
1550 }
1551 // Always process occupied racks plus racks chosen by user. First get racks with
1552 // already allocated rackspace...
1553 $workingRacksData = getResidentRacksData ($object_id);
1554 if ($workingRacksData === NULL)
1555 {
1556 print_r ($workingRacksData);
591ff2c4 1557 showError ('getResidentRacksData() failed', __FUNCTION__);
e673ee24
DO
1558 return;
1559 }
1560
1561 // ...and then add those chosen by user (if any).
1562 if ($is_update)
1563 foreach ($_REQUEST['rackmulti'] as $cand_id)
1564 {
1565 if (!isset ($workingRacksData[$cand_id]))
1566 {
1567 $rackData = getRackData ($cand_id);
1568 if ($rackData == NULL)
1569 {
591ff2c4 1570 showError ('getRackData() failed', __FUNCTION__);
e673ee24
DO
1571 return NULL;
1572 }
1573 $workingRacksData[$cand_id] = $rackData;
1574 }
1575 }
1576
1577 // Do it only once...
1578 foreach ($workingRacksData as &$rackData)
1579 applyObjectMountMask ($rackData, $object_id);
1580 // Now we workaround an old caveat: http://bugs.php.net/bug.php?id=37410
1581 unset ($rackData);
1582
1583 // Here we process form submit by trying to save all submitted info to database.
1584 if ($is_submit)
1585 {
1586 $oldMolecule = getMoleculeForObject ($object_id);
1587 $worldchanged = FALSE;
1588 $log = array();
1589 foreach ($workingRacksData as $rack_id => $rackData)
1590 {
1591 $logrecord = processGridForm ($rackData, 'F', 'T', $object_id);
1592 $log[] = $logrecord;
1593 if ($logrecord['code'] != 300)
1594 {
1595 $worldchanged = TRUE;
1596 // Reload our working copy after form processing.
1597 $rackData = getRackData ($rack_id);
1598 if ($rackData == NULL)
4d2e93f2 1599 $log[] = array ('code' => 500, 'message' => 'Working copy update failed in ', __FUNCTION__);
e673ee24
DO
1600 applyObjectMountMask ($rackData, $object_id);
1601 $workingRacksData[$rack_id] = $rackData;
1602 }
1603 }
1604 if ($worldchanged)
1605 {
1606 // Log a record.
1607 $newMolecule = getMoleculeForObject ($object_id);
1608 $oc = count ($oldMolecule);
1609 $nc = count ($newMolecule);
1610 $omid = $oc ? createMolecule ($oldMolecule) : 'NULL';
1611 $nmid = $nc ? createMolecule ($newMolecule) : 'NULL';
1612 global $remote_username;
1613 $comment = empty ($_REQUEST['comment']) ? 'NULL' : "'${_REQUEST['comment']}'";
1614 $query =
1615 "insert into MountOperation(object_id, old_molecule_id, new_molecule_id, user_name, comment) " .
1616 "values (${object_id}, ${omid}, ${nmid}, '${remote_username}', ${comment})";
1617 global $dbxlink;
1618 $result = $dbxlink->query ($query);
1619 if ($result == NULL)
1620 $log[] = array ('code' => 'error', 'message' => 'SQL query failed during history logging.');
1621 else
1622 $log[] = array ('code' => 'success', 'message' => 'History logged.');
1623 }
1624 printLog ($log);
1625 }
1626
1627 // This is the time for rendering.
1628 global $root, $pageno, $tabno;
1629 echo "<form id='racks' action='${root}'>";
1630 echo "<input type=hidden name=page value='${pageno}'>\n";
1631 echo "<input type=hidden name=tab value='${tabno}'>\n";
1632 echo "<input type=hidden name=object_id value='${object_id}'>\n";
1633 // Main layout starts.
1634 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0><tr>";
1635
1636 // Left portlet with rack list.
1637 echo "<td class=pcleft height='1%'>";
1638 startPortlet ('Racks');
1639 $allRacksData = getRacksForRow();
4b8d413e
DO
1640 if (count ($allRacksData) <= getConfigVar ('RACK_PRESELECT_THRESHOLD'))
1641 {
1642 foreach (array_keys ($allRacksData) as $rack_id)
1643 {
1644 $rackData = getRackData ($rack_id);
1645 if ($rackData == NULL)
1646 {
1647 showError ('getRackData() failed', __FUNCTION__);
1648 return NULL;
1649 }
1650 $workingRacksData[$rack_id] = $rackData;
1651 }
1652 foreach ($workingRacksData as &$rackData)
1653 applyObjectMountMask ($rackData, $object_id);
1654 unset ($rackData);
1655 }
1656 renderRackMultiSelect ('rackmulti[]', $allRacksData, array_keys ($workingRacksData));
e673ee24
DO
1657 echo "<br>";
1658 echo "<br>";
1659 finishPortlet();
1660 echo "</td>";
1661
1662 // Middle portlet with comment and submit.
1663 echo "<td class=pcleft>";
1664 startPortlet ('Comment');
1665 echo "<textarea name=comment rows=10 cols=40></textarea><br>\n";
1666 echo "<input type=submit value='Save' name=got_atoms>\n";
1667 echo "<br>";
1668 echo "<br>";
1669 finishPortlet();
1670 echo "</td>";
1671
1672 // Right portlet with rendered racks. If this form submit is not final, we have to
1673 // reflect the former state of the grid in current form.
1674 echo "<td class=pcright rowspan=2 height='1%'>";
1675 startPortlet ('Working copy');
1676 echo '<table border=0 cellspacing=10 align=center><tr>';
1677 foreach ($workingRacksData as $rack_id => $rackData)
1678 {
1679 // Order is important here: only original allocation is highlighted.
1680 highlightObject ($rackData, $object_id);
1681 markupAtomGrid ($rackData, 'T');
1682 // If we have a form processed, discard user input and show new database
1683 // contents.
1684 if (!$is_submit and $is_update)
1685 mergeGridFormToRack ($rackData);
1686 echo "<td valign=top>";
1687 echo "<center>\n<h2>${rackData['name']}</h2>\n";
1688 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
1689 echo "<tr><th width='10%'>&nbsp;</th><th width='20%'>Front</th>";
1690 echo "<th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
1691 renderAtomGrid ($rackData);
9b7468b7
DO
1692 echo "<tr><th width='10%'>&nbsp;</th><th width='20%'>Front</th>";
1693 echo "<th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
e673ee24
DO
1694 echo "</table></center>\n";
1695 echo '</td>';
1696 }
1697 echo "</tr></table>";
1698 finishPortlet();
1699 echo "</td>\n";
1700
1701 echo "</form>\n";
1702 echo "</tr></table>\n";
1703}
1704
1705function renderMolecule ($mdata, $object_id)
1706{
1707 // sort data out
1708 $rackpack = array();
1709 global $loclist;
64b95774 1710 foreach ($mdata as $rua)
e673ee24
DO
1711 {
1712 $rack_id = $rua['rack_id'];
1713 $unit_no = $rua['unit_no'];
1714 $atom = $rua['atom'];
1715 if (!isset ($rackpack[$rack_id]))
1716 {
1717 $rackData = getRackData ($rack_id);
1718 for ($i = $rackData['height']; $i > 0; $i--)
1719 for ($locidx = 0; $locidx < 3; $locidx++)
1720 $rackData[$i][$locidx]['state'] = 'F';
1721 $rackpack[$rack_id] = $rackData;
1722 }
1723 $rackpack[$rack_id][$unit_no][$loclist[$atom]]['state'] = 'T';
1724 $rackpack[$rack_id][$unit_no][$loclist[$atom]]['object_id'] = $object_id;
1725 }
1726 // now we have some racks to render
64b95774 1727 foreach ($rackpack as $rackData)
e673ee24
DO
1728 {
1729 markAllSpans ($rackData);
1730 echo "<table class=molecule cellspacing=0>\n";
1731 echo "<caption>${rackData['name']}</caption>\n";
1732 echo "<tr><th width='10%'>&nbsp;</th><th width='20%'>Front</th><th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
1733 for ($i = $rackData['height']; $i > 0; $i--)
1734 {
1735 echo "<tr><th>$i</th>";
1736 for ($locidx = 0; $locidx < 3; $locidx++)
1737 {
1738 $state = $rackData[$i][$locidx]['state'];
1739 echo "<td class=state_${state}>&nbsp;</td>\n";
1740 }
1741 echo "</tr>\n";
1742 }
1743 echo "</table>\n";
1744 }
1745}
1746
1747function renderUnmountedObjectsPortlet ()
1748{
1749 startPortlet ('Unmounted objects');
1750 $objs = getUnmountedObjects();
1751 if ($objs === NULL)
1752 {
591ff2c4 1753 showError ('getUnmountedObjects() failed', __FUNCTION__);
e673ee24
DO
1754 return;
1755 }
1756 global $root, $nextorder;
1757 $order = 'odd';
1758 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
18d94c29 1759 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset number</th><th>Barcode</th></tr>';
e673ee24
DO
1760 foreach ($objs as $obj)
1761 {
1762 echo "<tr class=row_${order}><td><a href='${root}?page=object&object_id=${obj['id']}'>${obj['dname']}</a></td>";
1763 echo "<td>${obj['label']}</td>";
18d94c29
DO
1764 echo "<td>${obj['asset_no']}</td>";
1765 echo "<td>${obj['barcode']}</td></tr>";
e673ee24
DO
1766 $order = $nextorder[$order];
1767 }
1768 echo "</table><br>\n";
1769 finishPortlet();
1770}
1771
1772function renderProblematicObjectsPortlet ()
1773{
1774 startPortlet ('Problematic objects');
1775 $objs = getProblematicObjects();
1776 if ($objs === NULL)
1777 {
591ff2c4 1778 showError ('getProblematicObjects() failed', __FUNCTION__);
e673ee24
DO
1779 return;
1780 }
1781 global $root, $nextorder;
1782 $order = 'odd';
1783 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1784 echo '<tr><th>Type</th><th>Common name</th></tr>';
1785 foreach ($objs as $obj)
1786 {
1787 echo "<tr class=row_${order}><td>${obj['objtype_name']}</td>";
1788 echo "<td><a href='${root}?page=object&object_id=${obj['id']}'>${obj['dname']}</a></tr>";
1789 $order = $nextorder[$order];
1790 }
1791 echo "</table><br>\n";
1792 finishPortlet();
1793}
1794
7cc02fc1
DO
1795function renderObjectSpace ()
1796{
105cea6e 1797 global $root, $taglist, $tagtree;
7cc02fc1
DO
1798 echo "<table border=0 class=objectview>\n";
1799 echo "<tr><td class=pcleft width='50%'>";
1800 startPortlet ('View all by type');
1801 $groupInfo = getObjectGroupInfo();
1802 if ($groupInfo === NULL)
1803 {
1804 showError ('getObjectGroupInfo() failed', __FUNCTION__);
1805 return;
1806 }
1807 if (count ($groupInfo) == 0)
1808 echo "No objects exist in DB";
1809 else
1810 {
1811 echo '<div align=left><ul>';
1812 foreach ($groupInfo as $gi)
1813 echo "<li><a href='${root}?page=objgroup&group_id=${gi['id']}'>${gi['name']}</a> (${gi['count']})</li>";
1814 echo '</ul></div>';
1815 }
1816 finishPortlet();
1817
1818 echo '</td><td class=pcright>';
1819
1820 startPortlet ('View all by tag');
1821 if (count ($taglist) == 0)
1822 echo "No tags exist in DB";
1823 else
1824 renderTagCloud ('object');
1825 finishPortlet();
e673ee24
DO
1826 echo "</td></tr></table>\n";
1827}
1828
466dcbe6 1829function renderObjectGroup ()
7cc02fc1
DO
1830{
1831 global $root, $pageno, $tabno, $nextorder, $taglist, $tagtree;
2c6c7645 1832 assertUIntArg ('group_id', __FUNCTION__, TRUE);
7cc02fc1 1833 $group_id = $_REQUEST['group_id'];
a0d54e7e
DO
1834 $tagfilter = getTagFilter();
1835 $tagfilter_str = getTagFilterStr ($tagfilter);
7cc02fc1
DO
1836 echo "<table border=0 class=objectview>\n";
1837 echo "<tr><td class=pcleft width='25%'>";
1838 startPortlet ('change type');
1839 $groupInfo = getObjectGroupInfo();
1840 if ($groupInfo === NULL)
1841 {
1842 showError ('getObjectGroupInfo() failed', __FUNCTION__);
1843 return;
1844 }
1845 if (count ($groupInfo) == 0)
1846 echo "No objects exist in DB";
1847 else
1848 {
1849 echo '<div align=left><ul>';
1850 foreach ($groupInfo as $gi)
1851 {
a0d54e7e 1852 echo "<li><a href='${root}?page=${pageno}&group_id=${gi['id']}${tagfilter_str}'>";
105cea6e
DO
1853 if ($gi['id'] == $group_id)
1854 echo '<strong>';
1855 echo "${gi['name']}</a>";
1856 if ($gi['id'] == $group_id)
1857 echo '</strong>';
1858 echo " (${gi['count']})";
1859 if ($gi['id'] == $group_id)
1860 echo ' &larr;';
1861 echo "</li>";
7cc02fc1
DO
1862 }
1863 echo '</ul></div>';
1864 }
1865 finishPortlet();
1866
1867 echo '</td><td class=pcleft>';
1868
11c8e4be 1869 $objects = getObjectList ($group_id, $tagfilter, getTFMode());
922b8da6 1870 startPortlet ('Objects (' . count ($objects) . ')');
7cc02fc1
DO
1871 if ($objects === NULL)
1872 {
1873 showError ('getObjectList() failed', __FUNCTION__);
1874 return;
1875 }
1876 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
c21e3cd5 1877 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>Barcode</th><th>Row/Rack</th></tr>';
7cc02fc1
DO
1878 $order = 'odd';
1879 foreach ($objects as $obj)
1880 {
8e700dd1
DO
1881 if (isset ($_REQUEST['hl_object_id']) and $_REQUEST['hl_object_id'] == $obj['id'])
1882 $secondclass = 'tdleft port_highlight';
1883 else
1884 $secondclass = 'tdleft';
2b3d64c5
DO
1885 $tags = loadRackObjectTags ($obj['id']);
1886 echo "<tr class=row_${order} valign=top><td class='${secondclass}'><a href='${root}?page=object&object_id=${obj['id']}'><strong>${obj['dname']}</strong></a>";
1887 if (count ($tags))
1888 echo '<br><small>' . serializeTags ($tags, "${root}?page=${pageno}&tab=default&group_id=${group_id}&") . '</small>';
1889 echo "</td><td class='${secondclass}'>${obj['label']}</td>";
8e700dd1
DO
1890 echo "<td class='${secondclass}'>${obj['asset_no']}</td>";
1891 echo "<td class='${secondclass}'>${obj['barcode']}</td>";
7cc02fc1 1892 if ($obj['rack_id'])
c21e3cd5 1893 echo "<td class='${secondclass}'><a href='${root}?page=row&row_id=${obj['row_id']}'>${obj['Row_name']}</a>/<a href='${root}?page=rack&rack_id=${obj['rack_id']}'>${obj['Rack_name']}</a></td>";
7cc02fc1 1894 else
8e700dd1 1895 echo "<td class='${secondclass}'>Unmounted</td>";
7cc02fc1
DO
1896 echo '</tr>';
1897 $order = $nextorder[$order];
1898 }
1899 echo '</table>';
1900 finishPortlet();
1901
1902 echo "</td><td class=pcright width='25%'>";
1903
a0d54e7e 1904 renderTagFilterPortlet ($tagfilter, 'object', 'group_id', $group_id);
7cc02fc1 1905 echo "</td></tr></table>\n";
e673ee24
DO
1906}
1907
1908function renderEmptyPortsSelect ($port_id, $type_id)
1909{
1910 $ports = getEmptyPortsOfType($type_id);
1911 usort($ports, 'sortEmptyPorts');
1912 foreach ($ports as $port)
1913 {
1914 if ($port_id == $port['Port_id'])
1915 continue;
1916 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";
1917 }
1918}
1919
6ef9683b 1920function renderAllIPv4Allocations ()
e673ee24 1921{
6ef9683b 1922 $addresses = getAllIPv4Allocations();
e673ee24
DO
1923 usort($addresses, 'sortObjectAddressesAndNames');
1924 foreach ($addresses as $address)
1925 {
1926 echo "<option value='${address['ip']}' onclick='getElementById(\"ip\").value=\"${address['ip']}\";'>${address['object_name']} ${address['name']} ${address['ip']}</option>\n";
1927 }
1928}
1929
1930// History viewer for history-enabled simple dictionaries.
1931function renderHistory ($object_type, $object_id)
1932{
1933 switch ($object_type)
1934 {
1935 case 'row':
1936 $query = "select ctime, user_name, name, deleted, comment from RackRowHistory where id = ${object_id} order by ctime";
1937 $header = '<tr><th>change time</th><th>author</th><th>rack row name</th><th>is deleted?</th><th>rack row comment</th></tr>';
1938 $extra = 4;
1939 break;
1940 case 'rack':
1941 $query =
1942 "select ctime, user_name, rh.name, rh.deleted, d.dict_value as name, rh.height, rh.comment " .
1943 "from RackHistory as rh left join Dictionary as d on rh.row_id = d.dict_key " .
1944 "natural join Chapter " .
1945 "where chapter_name = 'RackRow' and rh.id = ${object_id} order by ctime";
1946 $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>';
1947 $extra = 6;
1948 break;
1949 case 'object':
1950 $query =
1951 "select ctime, user_name, name, label, barcode, asset_no, deleted, has_problems, dict_value, comment " .
1952 "from RackObjectHistory inner join Dictionary on objtype_id = dict_key natural join Chapter " .
1953 "where chapter_name = 'RackObjectType' and id=${object_id} order by ctime";
1954 $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>';
1955 $extra = 9;
1956 break;
1957 default:
591ff2c4 1958 showError ("Uknown object type '${object_type}'", __FUNCTION__);
e673ee24
DO
1959 return;
1960 }
1961 global $dbxlink;
1962 $result = $dbxlink->query ($query);
1963 if ($result == NULL)
1964 {
591ff2c4 1965 showError ('SQL query failed', __FUNCTION__);
e673ee24
DO
1966 return;
1967 }
1968 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1969 $order = 'odd';
1970 global $nextorder;
1971 echo $header;
1972 while ($row = $result->fetch (PDO::FETCH_NUM))
1973 {
1974 echo "<tr class=row_${order}><td>${row[0]}</td>";
1975 for ($i = 1; $i <= $extra; $i++)
1976 echo "<td>" . $row[$i] . "</td>";
1977 echo "</tr>\n";
1978 $order = $nextorder[$order];
1979 }
1980 echo "</table><br>\n";
1981}
1982
1983function renderRackspaceHistory ()
1984{
1985 global $root, $nextorder, $pageno, $tabno;
1986 $order = 'odd';
1987 $history = getRackspaceHistory();
1988 // Show the last operation by default.
1989 if (isset ($_REQUEST['op_id']))
1990 $op_id = $_REQUEST['op_id'];
1991 elseif (isset ($history[0]['mo_id']))
1992 $op_id = $history[0]['mo_id'];
1993 else $op_id = NULL;
1994
1995 $omid = NULL;
1996 $nmid = NULL;
1997 $object_id = 1;
1998 if ($op_id)
1999 list ($omid, $nmid) = getOperationMolecules ($op_id);
2000
2001 // Main layout starts.
2002 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
2003
2004 // Left top portlet with old allocation.
2005 echo "<tr><td class=pcleft>";
2006 startPortlet ('Old allocation');
2007 if ($omid)
2008 {
2009 $oldMolecule = getMolecule ($omid);
2010 renderMolecule ($oldMolecule, $object_id);
2011 }
2012 else
2013 echo "nothing";
2014 finishPortlet();
2015
2016 echo '</td><td class=pcright>';
2017
2018 // Right top portlet with new allocation
2019 startPortlet ('New allocation');
2020 if ($nmid)
2021 {
2022 $newMolecule = getMolecule ($nmid);
2023 renderMolecule ($newMolecule, $object_id);
2024 }
2025 else
2026 echo "nothing";
2027 finishPortlet();
737a3f72 2028
e673ee24 2029 echo '</td></tr><tr><td colspan=2>';
737a3f72 2030
e673ee24
DO
2031 // Bottom portlet with list
2032
2033 startPortlet ('Rackspace allocation history');
2034 echo "<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>\n";
2035 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";
2036 foreach ($history as $row)
2037 {
2038 if ($row['mo_id'] == $op_id)
2039 $class = 'hl';
2040 else
2041 $class = "row_${order}";
2042 echo "<tr class=${class}><td><a href='${root}?page=${pageno}&tab=${tabno}&op_id=${row['mo_id']}'>${row['ctime']}</a></td>";
2043 echo "<td>${row['user_name']}</td>";
2044 echo "<td>${row['ro_id']}</td><td>${row['objtype_name']}</td><td>${row['name']}</td><td>${row['comment']}</td>\n";
2045 echo "</tr>\n";
2046 $order = $nextorder[$order];
2047 }
2048 echo "</table>\n";
2049 finishPortlet();
737a3f72 2050
e673ee24 2051 echo '</td></tr></table>';
e673ee24
DO
2052}
2053
d9f8a37a 2054function renderIPv4SpaceRecords ($tree, &$tagcache, $baseurl, $target = 0, $level = 1)
d65353ad
DO
2055{
2056 $self = __FUNCTION__;
2057 foreach ($tree as $item)
2058 {
737a3f72 2059 $total = $item['addrt'];
a987ff52
DO
2060 loadIPv4AddrList ($item); // necessary to compute router list and address counter
2061 $used = $item['addrc'];
0137d53c
DO
2062 if (isset ($item['id']))
2063 {
fec0c8da 2064 if ($item['symbol'] == 'node-collapsed')
d9f8a37a 2065 $expandurl = "${baseurl}&eid=" . $item['id'] . "#netid" . $item['id'];
fec0c8da 2066 elseif ($item['symbol'] == 'node-expanded')
d9f8a37a 2067 $expandurl = $baseurl . ($item['parent_id'] ? "&eid=${item['parent_id']}#netid${item['parent_id']}" : '');
fec0c8da
DO
2068 else
2069 $expandurl = '';
0137d53c 2070 echo "<tr valign=top>";
fec0c8da 2071 printIPv4NetInfoTDs ($item, 'tdleft', $level, $item['symbol'], $expandurl);
0137d53c 2072 echo "<td class=tdcenter>";
d9f8a37a
DO
2073 if ($target == $item['id'])
2074 echo "<a name=netid${target}></a>";
737a3f72 2075 renderProgressBar ($total ? $used/$total : 0);
0137d53c
DO
2076 echo "<br><small>${used}/${total}</small></td>";
2077 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
b6b87070 2078 printRoutersTD (findRouters ($item['addrlist']), $tagcache);
0137d53c 2079 echo "</tr>";
fec0c8da 2080 if ($item['symbol'] == 'node-expanded' or $item['symbol'] == 'node-expanded-static')
d9f8a37a 2081 $self ($item['kids'], $tagcache, $baseurl, $target, $level + 1);
0137d53c
DO
2082 }
2083 else
2084 {
0137d53c 2085 echo "<tr valign=top>";
fec0c8da 2086 printIPv4NetInfoTDs ($item, 'tdleft sparenetwork', $level, $item['symbol']);
0137d53c 2087 echo "<td class=tdcenter>";
fec0c8da 2088 renderProgressBar ($used/$total, 'sparenetwork');
0137d53c
DO
2089 echo "<br><small>${used}/${total}</small></td>";
2090 echo "<td>&nbsp;</td></tr>";
2091 }
d65353ad
DO
2092 }
2093}
2094
04d619d0 2095function renderIPv4Space ()
e673ee24 2096{
fec0c8da 2097 global $root, $pageno, $tabno;
932cf41f 2098 $tagfilter = getTagFilter();
94a40058
DO
2099 $netlist = getIPv4NetworkList ($tagfilter, getTFMode());
2100 $netcount = count ($netlist);
fec0c8da 2101 $tree = prepareIPv4Tree ($netlist, isset ($_REQUEST['eid']) ? $_REQUEST['eid'] : 0);
3630d1fb
DO
2102
2103 echo "<table border=0 class=objectview>\n";
2104 echo "<tr><td class=pcleft>";
94a40058 2105 startPortlet ("networks (${netcount})");
04d619d0 2106 echo "<table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
57dece2f 2107 echo "<tr><th>prefix</th><th>name/tags</th><th>%% used</th>";
f0ed1181 2108 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
57dece2f
DO
2109 echo "<th>routed by</th>";
2110 echo "</tr>\n";
fec0c8da 2111 $tagcache = array();
0c16ef0c 2112 $baseurl = "${root}?page=${pageno}&tab=${tabno}" . getTagFilterStr ($tagfilter);
d9f8a37a 2113 renderIPv4SpaceRecords ($tree, $tagcache, $baseurl, isset ($_REQUEST['eid']) ? $_REQUEST['eid'] : 0);
e673ee24 2114 echo "</table>\n";
a7fe7729 2115 finishPortlet();
74ccacff 2116 echo '</td><td class=pcright>';
5b7bd02e 2117 renderTagFilterPortlet ($tagfilter, 'ipv4net');
74ccacff 2118 echo "</td></tr></table>\n";
f973f491 2119}
a7fe7729 2120
f973f491
DO
2121function renderIPv4SLB ()
2122{
80e85ea1 2123 global $root, $page, $nextorder;
a7fe7729 2124
6fec9f39 2125 startPortlet ('SLB configuration');
b3c50e6c 2126 echo "<table border=0 width='100%'><tr>";
ee437dab 2127 foreach (array ('ipv4vslist', 'ipv4rsplist', 'rservers', 'lbs') as $pno)
e57dca7f 2128 echo "<td><h3><a href='${root}?page=${pno}'>" . $page[$pno]['title'] . "</a></h3></td>";
b3c50e6c
DO
2129 echo '</tr></table>';
2130 finishPortlet();
2131
c3bdc503 2132 $summary = getSLBSummary();
6fec9f39 2133 startPortlet ('SLB tactical overview');
4cadac8f
DO
2134 // A single id-keyed array isn't used here to preserve existing
2135 // order of LBs returned by getSLBSummary()
c3bdc503
DO
2136 $lblist = array();
2137 $lbdname = array();
4cadac8f 2138 foreach ($summary as $vipdata)
da04825a 2139 foreach (array_keys ($vipdata['lblist']) as $lb_object_id)
c3bdc503
DO
2140 if (!in_array ($lb_object_id, $lblist))
2141 {
2142 $oi = getObjectInfo ($lb_object_id);
2143 $lbdname[$lb_object_id] = $oi['dname'];
2144 $lblist[] = $lb_object_id;
2145 }
2146 if (!count ($summary))
2147 echo 'none configured';
2148 else
2149 {
80e85ea1 2150 $order = 'odd';
c3bdc503 2151 echo "<table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
a7bc13c8 2152 echo "<tr><th>VS&nbsp;&darr; LB&nbsp;&rarr;</th>";
c3bdc503 2153 foreach ($lblist as $lb_object_id)
71b8bda1 2154 echo "<th><a href='${root}?page=object&tab=default&object_id=${lb_object_id}'>" . $lbdname[$lb_object_id] . "</a></th>";
c3bdc503 2155 echo "</tr>\n";
4cadac8f
DO
2156 foreach ($summary as $vsid => $vsdata)
2157 {
49fb2686 2158 echo "<tr class=row_${order}><td class=tdleft><a href='$root?page=ipv4vs&tab=default&vs_id=${vsid}'>";
8d790216 2159 echo buildVServiceName ($vsdata);
6fec9f39
DO
2160 echo '</a>';
2161 if (!empty ($vsdata['name']))
300826cb 2162 echo "<br>${vsdata['name']}";
6fec9f39 2163 echo "</td>";
4cadac8f 2164 foreach ($lblist as $lb_object_id)
da04825a 2165 {
60fbcece 2166 echo '<td class=tdleft>';
2b4eee17 2167 if (!isset ($vsdata['lblist'][$lb_object_id]))
da04825a
DO
2168 echo '&nbsp;';
2169 else
6fec9f39
DO
2170 {
2171 echo $vsdata['lblist'][$lb_object_id]['size'];
e1ae3fb4 2172// echo " (<a href='${root}?page=ipv4rspool&pool_id=";
79a9edb4
DO
2173// echo $vsdata['lblist'][$lb_object_id]['id'] . "'>";
2174// echo $vsdata['lblist'][$lb_object_id]['name'] . '</a>)';
6fec9f39 2175 }
da04825a
DO
2176 echo '</td>';
2177 }
2178 echo "</tr>\n";
80e85ea1 2179 $order = $nextorder[$order];
4cadac8f 2180 }
c3bdc503
DO
2181 echo "</table>\n";
2182 }
a7fe7729 2183 finishPortlet ();
e673ee24
DO
2184}
2185
04d619d0 2186function renderIPv4SpaceEditor ()
e673ee24
DO
2187{
2188 global $root, $pageno, $tabno;
2189 showMessageOrError();
2a201216 2190
a262e150
DO
2191 // IPv4 validator
2192?>
2193 <script type="text/javascript">
2194 function init() {
2195 document.add_new_range.range.setAttribute('match', "^\\d\\d?\\d?\\.\\d\\d?\\d?\\.\\d\\d?\\d?\\.\\d\\d?\\d?\\/\\d\\d?$");
2196
2197 Validate.init();
2198 }
2199 window.onload=init;
2200 </script>
2201<?php
2202
4c0653e2 2203 startPortlet ("Add new");
04d619d0 2204 echo '<table border=0 cellpadding=10 align=center>';
7056988c
DO
2205 // This form requires a name, so JavaScript validator can find it.
2206 // No printOpFormIntro() hence
04d619d0 2207 echo "<form method=post name='add_new_range' action='${root}process.php'>\n";
42023f03 2208 echo "<input type=hidden name=op value=addIPv4Prefix>\n";
2a201216
DY
2209 echo "<input type=hidden name=page value='${pageno}'>\n";
2210 echo "<input type=hidden name=tab value='${tabno}'>\n";
04d619d0
DO
2211 // tags column
2212 echo '<tr><td rowspan=4><h3>assign tags</h3>';
5c0bb421 2213 renderTagSelect();
04d619d0
DO
2214 echo '</td>';
2215 // inputs column
2216 echo "<th class=tdright>prefix</th><td class=tdleft><input type=text name='range' size=18 class='live-validate' tabindex=1></td>";
2217 echo "<tr><th class=tdright>name</th><td class=tdleft><input type=text name='name' size='20' tabindex=2></td></tr>";
0c16ef0c 2218 echo "<tr><th class=tdright>connected network</th><td class=tdleft><input type=checkbox name='is_bcast' tabindex=3></td></tr>";
04d619d0 2219 echo "<tr><td colspan=2>";
4c0653e2 2220 printImageHREF ('CREATE', 'Add a new network', TRUE, 4);
04d619d0 2221 echo '</td></tr>';
2a201216 2222 echo "</form></table><br><br>\n";
5c0bb421 2223 finishPortlet();
2a201216 2224
b18d26dc 2225 $addrspaceList = getIPv4NetworkList();
0c16ef0c
DO
2226 $netcount = count ($addrspaceList);
2227 if ($netcount)
e673ee24 2228 {
0c16ef0c 2229 startPortlet ("Manage existing (${netcount})");
04d619d0
DO
2230 echo "<table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
2231 echo "<tr><th>&nbsp;</th><th>prefix</th><th>name</th><th>&nbsp;</th></tr>";
0c16ef0c 2232 foreach ($addrspaceList as $netinfo)
e673ee24 2233 {
0c16ef0c
DO
2234 echo "<form method=post action='${root}process.php?page=${pageno}&tab=${tabno}&op=updIPv4Prefix&id=${netinfo['id']}'>";
2235 echo "<tr valign=top><td><a href='${root}process.php?op=delIPv4Prefix&page=${pageno}&tab=${tabno}&id=${netinfo['id']}'>";
2236 printImageHREF ('delete', 'Delete this IP range');
2237 echo "</a></td>\n<td class=tdleft>${netinfo['ip']}/${netinfo['mask']}</td>";
2238 echo "<td><input type=text name=name size=40 value='${netinfo['name']}'>";
04d619d0
DO
2239 echo "</td><td>";
2240 printImageHREF ('save', 'Save changes', TRUE);
2241 echo "</td></tr></form>\n";
e673ee24 2242 }
04d619d0
DO
2243 echo "</table>";
2244 finishPortlet();
e673ee24 2245 }
e673ee24
DO
2246}
2247
beb9e88a 2248function renderIPv4Network ($id)
e673ee24 2249{
beb9e88a 2250 global $root, $pageno, $tabno, $aac2;
545478d0
DO
2251 $netmaskbylen = array
2252 (
2253 32 => '255.255.255.255',
2254 31 => '255.255.255.254',
2255 30 => '255.255.255.252',
2256 29 => '255.255.255.248',
2257 28 => '255.255.255.240',
2258 27 => '255.255.255.224',
2259 26 => '255.255.255.192',
2260 25 => '255.255.255.128',
2261 24 => '255.255.255.0',
2262 23 => '255.255.254.0',
2263 22 => '255.255.252.0',
2264 21 => '255.255.248.0',
2265 20 => '255.255.240.0',
2266 19 => '255.255.224.0',
2267 18 => '255.255.192.0',
2268 17 => '255.255.128.0',
2269 16 => '255.255.0.0',
2270 15 => '255.254.0.0',
2271 14 => '255.252.0.0',
2272 13 => '255.248.0.0',
2273 12 => '255.240.0.0',
2274 11 => '255.224.0.0',
2275 10 => '255.192.0.0',
2276 9 => '255.128.0.0',
2277 8 => '255.0.0.0',
2278 7 => '254.0.0.0',
2279 6 => '252.0.0.0',
2280 5 => '248.0.0.0',
2281 4 => '240.0.0.0',
2282 3 => '224.0.0.0',
2283 2 => '192.0.0.0',
2284 1 => '128.0.0.0'
2285 );
2286 $wildcardbylen = array
2287 (
2288 32 => '0.0.0.0',
2289 31 => '0.0.0.1',
2290 30 => '0.0.0.3',
2291 29 => '0.0.0.7',
2292 28 => '0.0.0.15',
2293 27 => '0.0.0.31',
2294 26 => '0.0.0.63',
2295 25 => '0.0.0.127',
2296 24 => '0.0.0.255',
2297 23 => '0.0.1.255',
2298 22 => '0.0.3.255',
2299 21 => '0.0.7.255',
2300 20 => '0.0.15.255',
2301 19 => '0.0.31.255',
2302 18 => '0.0.63.255',
2303 17 => '0.0.127.255',
2304 16 => '0.0.255.25',
2305 15 => '0.1.255.255',
2306 14 => '0.3.255.255',
2307 13 => '0.7.255.255',
2308 12 => '0.15.255.255',
2309 11 => '0.31.255.255',
2310 10 => '0.63.255.255',
2311 9 => '0.127.255.255',
2312 8 => '0.255.255.255',
2313 7 => '1.255.255.255',
2314 6 => '3.255.255.255',
2315 5 => '7.255.255.255',
2316 4 => '15.255.255.255',
2317 3 => '31.255.255.255',
2318 2 => '63.255.255.255',
2319 1 => '127.255.255.255'
2320 );
b901bf1f 2321 $maxperpage = getConfigVar ('IPV4_ADDRS_PER_PAGE');
e673ee24
DO
2322 if (isset($_REQUEST['pg']))
2323 $page = $_REQUEST['pg'];
2324 else
2325 $page=0;
2326
b6b87070
DO
2327 $range = getIPv4NetworkInfo ($id);
2328 loadIPv4AddrList ($range);
2034d968
DO
2329 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
2330 echo "<tr><td colspan=2 align=center><h1>${range['ip']}/${range['mask']}</h1><h2>${range['name']}</h2></td></tr>\n";
2331
2332 echo "<tr><td class=pcleft width='50%'>";
2333 startPortlet ('summary');
2334 $total = ($range['ip_bin'] | $range['mask_bin_inv']) - ($range['ip_bin'] & $range['mask_bin']) + 1;
2335 $used = count ($range['addrlist']);
2336 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
04d619d0
DO
2337
2338 echo "<tr><th width='50%' class=tdright>%% used:</th><td class=tdleft>";
2034d968
DO
2339 renderProgressBar ($used/$total);
2340 echo "&nbsp;${used}/${total}</td></tr>\n";
04d619d0 2341
001e61fa
DO
2342 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
2343 {
3444ecf2
DO
2344 // Build a backtrace from all parent networks.
2345 $clen = $range['mask'];
2346 $backtrace = array();
2347 while (NULL !== ($upperid = getIPv4AddressNetworkId ($range['ip'], $clen)))
2348 {
2349 $upperinfo = getIPv4NetworkInfo ($upperid);
2350 $clen = $upperinfo['mask'];
2351 $backtrace[] = $upperid;
2352 }
2353 $arrows = count ($backtrace);
2354 foreach (array_reverse ($backtrace) as $ancestorid)
001e61fa
DO
2355 {
2356 $ainfo = getIPv4NetworkInfo ($ancestorid);
3444ecf2
DO
2357 echo "<tr><th width='50%' class=tdright>";
2358 for ($i = 0; $i < $arrows; $i++)
2359 echo '&uarr;';
2360 $arrows--;
2361 echo "</th><td class=tdleft><a href='${root}?page=${pageno}&tab=${tabno}&id=${ainfo['id']}'>${ainfo['ip']}/${ainfo['mask']}</a></td></tr>";
001e61fa 2362 }
3444ecf2
DO
2363 echo "<tr><th width='50%' class=tdright>&rarr;</th>";
2364 echo "<td class=tdleft>${range['ip']}/${range['mask']}</td></tr>";
001e61fa
DO
2365 // FIXME: get and display nested networks
2366 // $theitem = pickLeaf ($ipv4tree, $id);
2367 }
2368
545478d0
DO
2369 echo "<tr><th width='50%' class=tdright>Netmask:</th><td class=tdleft>";
2370 echo $netmaskbylen[$range['mask']];
2371 echo "</td></tr>\n";
04d619d0 2372
c607ab55
DO
2373 echo "<tr><th width='50%' class=tdright>Netmask:</th><td class=tdleft>";
2374 printf ('0x%08X', binMaskFromDec ($range['mask']));
2375 echo "</td></tr>\n";
2376
545478d0
DO
2377 echo "<tr><th width='50%' class=tdright>Wildcard bits:</th><td class=tdleft>";
2378 echo $wildcardbylen[$range['mask']];
2379 echo "</td></tr>\n";
04d619d0 2380
f3d0cb20 2381 $routers = findRouters ($range['addrlist']);
f0ed1181 2382 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes' and count ($routers))
04d619d0 2383 {
57dece2f 2384 echo "<tr><th width='50%' class=tdright>Routed by:</th>";
f3d0cb20 2385 printRoutersTD ($routers);
57dece2f 2386 echo "</tr>\n";
04d619d0
DO
2387 }
2388
d9f8a37a 2389 printTagTRs ("${root}?page=ipv4space&tab=default&");
2034d968
DO
2390 echo "</table><br>\n";
2391 finishPortlet();
e1ae3fb4
AD
2392
2393 renderFilesPortlet ('ipv4net', $id);
2034d968 2394 echo "</td>\n";
e673ee24 2395
2034d968
DO
2396 echo "<td class=pcright>";
2397 startPortlet ('details');
e673ee24
DO
2398 $startip = $range['ip_bin'] & $range['mask_bin'];
2399 $endip = $range['ip_bin'] | $range['mask_bin_inv'];
2400 $realstartip = $startip;
2401 $realendip = $endip;
2402 $numpages = 0;
2403 if($endip - $startip > $maxperpage)
2404 {
e673ee24
DO
2405 $numpages = ($endip - $startip)/$maxperpage;
2406 $startip = $startip + $page * $maxperpage;
2407 $endip = $startip + $maxperpage-1;
2408 }
2409 echo "<center>";
b901bf1f
DO
2410 if ($numpages)
2411 echo '<h3>' . long2ip ($startip) . ' ~ ' . long2ip ($endip) . '</h3>';
e673ee24
DO
2412 for ($i=0; $i<$numpages; $i++)
2413 {
2414 if ($i == $page)
2415 echo "<b>$i</b> ";
2416 else
a60e0851 2417 echo "<a href='${root}?page=${pageno}&tab=${tabno}&id=$id&pg=$i'>$i</a> ";
e673ee24
DO
2418 }
2419 echo "</center>";
2420
beb9e88a 2421 echo "<table class='widetable' border=0 cellspacing=0 cellpadding=5 align='center' width='100%'>\n";
e673ee24
DO
2422 echo "<tr><th>Address</th><th>Name</th><th>Allocation</th></tr>\n";
2423
2424
b2035dca
DO
2425 for ($ip = $startip; $ip <= $endip; $ip++) :
2426 if (isset ($_REQUEST['hl_ipv4_addr']) and ip2long ($_REQUEST['hl_ipv4_addr']) == $ip)
2427 $secondstyle = 'tdleft port_highlight';
2727c7df 2428 else
b2035dca
DO
2429 $secondstyle = 'tdleft';
2430 if (!isset ($range['addrlist'][$ip]))
e673ee24 2431 {
b2035dca
DO
2432 echo "<tr><td class=tdleft><a href='${root}?page=ipaddress&ip=" . long2ip ($ip) . "'>" . long2ip ($ip);
2433 echo "</a></td><td class='${secondstyle}'>&nbsp;</td><td class='${secondstyle}'>&nbsp;</td></tr>\n";
2434 continue;
2435 }
b2035dca 2436 $addr = $range['addrlist'][$ip];
2d318652 2437 echo "<tr class='${addr['class']}'>";
e673ee24 2438
b2035dca
DO
2439 echo "<td class=tdleft><a href='${root}?page=ipaddress&ip=${addr['ip']}'>${addr['ip']}</a></td>";
2440 echo "<td class='${secondstyle}'>${addr['name']}</td><td class='${secondstyle}'>";
2441 $delim = '';
2442 $prologue = '';
2443 if ( $addr['reserved'] == 'yes')
2444 {
2d318652 2445 echo "<strong>RESERVED</strong> ";
b2035dca
DO
2446 $delim = '; ';
2447 }
2d318652 2448 foreach ($range['addrlist'][$ip]['allocs'] as $ref)
b2035dca 2449 {
beb9e88a
DO
2450 echo $delim . $aac2[$ref['type']];
2451 echo "<a href='${root}?page=object&object_id=${ref['object_id']}";
b2035dca
DO
2452 echo "&hl_ipv4_addr=${addr['ip']}'>";
2453 echo $ref['name'] . (empty ($ref['name']) ? '' : '@');
2454 echo "${ref['object_name']}</a>";
2455 $delim = '; ';
2456 }
2457 if ($delim != '')
2458 {
6131056c 2459 $delim = '';
b2035dca
DO
2460 $prologue = '<br>';
2461 }
2d318652 2462 foreach ($range['addrlist'][$ip]['lblist'] as $ref)
b2035dca
DO
2463 {
2464 echo $prologue;
602663f4 2465 $prologue = '';
b2035dca
DO
2466 echo "${delim}<a href='${root}?page=object&object_id=${ref['object_id']}'>";
2467 echo "${ref['object_name']}</a>:<a href='${root}?page=ipv4vs&vs_id=${ref['vs_id']}'>";
2468 echo "${ref['vport']}/${ref['proto']}</a>&rarr;";
2469 $delim = '; ';
2470 }
2471 if ($delim != '')
2472 {
2473 $delim = '';
2474 $prologue = '<br>';
e673ee24 2475 }
2d318652 2476 foreach ($range['addrlist'][$ip]['rslist'] as $ref)
b2035dca
DO
2477 {
2478 echo $prologue;
2479 $prologue = '';
e1ae3fb4 2480 echo "${delim}&rarr;${ref['rsport']}@<a href='${root}?page=ipv4rspool&pool_id=${ref['rspool_id']}'>";
b2035dca
DO
2481 echo "${ref['rspool_name']}</a>";
2482 $delim = '; ';
2483 }
2484 echo "</td></tr>\n";
2485 endfor;
2727c7df 2486 // end of iteration
e673ee24
DO
2487
2488 echo "</table>";
2034d968
DO
2489 finishPortlet();
2490 echo "</td></tr></table>\n";
e673ee24
DO
2491}
2492
53ef3908 2493function renderIPv4NetworkProperties ($id)
e673ee24 2494{
e673ee24 2495 showMessageOrError();
53ef3908
DO
2496 $netdata = getIPv4NetworkInfo ($id);
2497 echo "<center><h1>${netdata['ip']}/${netdata['mask']}</h1></center>\n";
e673ee24 2498 echo "<table border=0 cellpadding=10 cellpadding=1 align='center'>\n";
7056988c 2499 printOpFormIntro ('editRange');
53ef3908
DO
2500 echo "<tr><td class='tdright'>Name:</td><td class='tdleft'><input type=text name=name size=20 value='${netdata['name']}'></tr>";
2501 echo "<tr><td colspan=2 class=tdcenter>";
2502 printImageHREF ('SAVE', 'Save changes', TRUE);
2503 echo "</td></form></tr></table>\n";
e673ee24
DO
2504}
2505
2d318652 2506function renderIPv4Address ($dottedquad)
e673ee24 2507{
52c836b1 2508 global $root, $aat;
2d318652 2509 $address = getIPv4Address ($dottedquad);
68225375 2510 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
2d318652
DO
2511 echo "<tr><td colspan=2 align=center><h1>${dottedquad}</h1></td></tr>\n";
2512 if (!empty ($address['name']))
68225375 2513 echo "<tr><td colspan=2 align=center><h2>${address['name']}</h2></td></tr>\n";
e673ee24 2514
68225375
DO
2515 echo "<tr><td class=pcleft>";
2516 startPortlet ('summary');
2517 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
04d619d0 2518 echo "<tr><th width='50%' class=tdright>Allocations:</th><td class=tdleft>" . count ($address['allocs']) . "</td></tr>\n";
68225375
DO
2519 echo "<tr><th width='50%' class=tdright>Originated NAT connections:</th><td class=tdleft>" . count ($address['outpf']) . "</td></tr>\n";
2520 echo "<tr><th width='50%' class=tdright>Arriving NAT connections:</th><td class=tdleft>" . count ($address['inpf']) . "</td></tr>\n";
04d619d0 2521 echo "<tr><th width='50%' class=tdright>SLB virtual services:</th><td class=tdleft>" . count ($address['lblist']) . "</td></tr>\n";
68225375
DO
2522 echo "<tr><th width='50%' class=tdright>SLB real servers:</th><td class=tdleft>" . count ($address['rslist']) . "</td></tr>\n";
2523 printTagTRs();
2524 echo "</table><br>\n";
2525 finishPortlet();
2526 echo "</td>\n";
e673ee24 2527
68225375 2528 echo "<td class=pcright>";
e673ee24 2529
f74d96c6 2530 if (isset ($address['class']))
59bebe2b 2531 {
8e700dd1 2532 startPortlet ('allocations');
2d318652
DO
2533 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
2534 echo "<tr><th>object</th><th>OS interface</th><th>allocation type</th></tr>\n";
2535 $class = $address['class'];
2536 // render all allocation records for this address the same way
59bebe2b 2537 if ($address['reserved'] == 'yes')
2d318652
DO
2538 echo "<tr class='${class}'><td colspan=2>&nbsp;</td><td class=tdleft><strong>RESERVED</strong></td></tr>";
2539 foreach ($address['allocs'] as $bond)
59bebe2b 2540 {
8e700dd1
DO
2541 if (isset ($_REQUEST['hl_object_id']) and $_REQUEST['hl_object_id'] == $bond['object_id'])
2542 $secondclass = 'tdleft port_highlight';
2543 else
2544 $secondclass = 'tdleft';
2545 echo "<tr class='$class'><td class=tdleft><a href='${root}?page=object&object_id=${bond['object_id']}";
2d318652 2546 echo "&hl_ipv4_addr=${dottedquad}'>${bond['object_name']}</td><td class='${secondclass}'>${bond['name']}</td><td class='${secondclass}'><strong>";
52c836b1
DO
2547 echo $aat[$bond['type']];
2548 echo "</strong></td></tr>\n";
59bebe2b
DO
2549 }
2550 echo "</table><br><br>";
2551 finishPortlet();
2552 }
e673ee24 2553
f3d0cb20
DO
2554 // FIXME: The returned list is structured differently, than we expect it to be. One of the sides
2555 // must be fixed.
2d318652 2556 if (count ($address['lblist']))
e673ee24 2557 {
2d318652
DO
2558 startPortlet ('Virtual services (' . count ($address['lblist']) . ')');
2559 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
59bebe2b 2560 echo "<tr><th>VS</th><th>name</th></tr>\n";
2d318652 2561 foreach ($address['lblist'] as $vsinfo)
e673ee24 2562 {
2d318652 2563 echo "<tr><td class=tdleft><a href='${root}?page=ipv4vs&vs_id=${vsinfo['vs_id']}'>";
59bebe2b 2564 echo buildVServiceName ($vsinfo) . "</a></td><td class=tdleft>";
5fe1ed76 2565 echo $vsinfo['name'] . "</td></tr>\n";
e673ee24 2566 }
59bebe2b
DO
2567 echo "</table><br><br>";
2568 finishPortlet();
e673ee24 2569 }
5fe1ed76
DO
2570
2571 if (count ($address['rslist']))
2572 {
2573 startPortlet ('Real servers (' . count ($address['rslist']) . ')');
2d318652 2574 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
53f4b619 2575 echo "<tr><th>&nbsp;</th><th>port</th><th>RS pool</th></tr>\n";
5fe1ed76
DO
2576 foreach ($address['rslist'] as $rsinfo)
2577 {
2578 echo "<tr><td>";
2579 if ($rsinfo['inservice'] == 'yes')
2580 printImageHREF ('inservice', 'in service');
2581 else
2582 printImageHREF ('notinservice', 'NOT in service');
e1ae3fb4 2583 echo "</td><td class=tdleft>${rsinfo['rsport']}</td><td class=tdleft><a href='${root}?page=ipv4rspool&pool_id=${rsinfo['rspool_id']}'>";
2d318652 2584 echo $rsinfo['rspool_name'] . "</a></td></tr>\n";
5fe1ed76
DO
2585 }
2586 echo "</table><br><br>";
2587 finishPortlet();
2588 }
2589
68225375
DO
2590 if (count ($address['outpf']))
2591 {
105a3bc8 2592 startPortlet ('departing NAT rules');
2d318652 2593 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
105a3bc8
DO
2594 echo "<tr><th>proto</th><th>from</th><th>to</th><th>comment</th></tr>\n";
2595 foreach ($address['outpf'] as $rule)
b62ff880 2596 echo "<tr><td>${rule['proto']}</td><td>${rule['localip']}:${rule['localport']}</td><td>${rule['remoteip']}:${rule['remoteport']}</td><td>${rule['description']}</td></tr>";
105a3bc8 2597 echo "</table>";
68225375
DO
2598 finishPortlet();
2599 }
105a3bc8
DO
2600
2601 if (count ($address['inpf']))
2602 {
2603 startPortlet ('arriving NAT rules');
2d318652 2604 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
105a3bc8
DO
2605 echo "<tr><th>proto</th><th>from</th><th>to</th><th>comment</th></tr>\n";
2606 foreach ($address['inpf'] as $rule)
b62ff880 2607 echo "<tr><td>${rule['proto']}</td><td>${rule['localip']}:${rule['localport']}</td><td>${rule['remoteip']}:${rule['remoteport']}</td><td>${rule['description']}</td></tr>";
105a3bc8
DO
2608 echo "</table>";
2609 finishPortlet();
2610 }
2611
68225375
DO
2612 echo "</td></tr>";
2613 echo "</table>\n";
e673ee24
DO
2614}
2615
2d318652 2616function renderIPv4AddressProperties ($dottedquad)
e673ee24 2617{
e673ee24 2618 showMessageOrError();
2d318652
DO
2619 $address = getIPv4Address ($dottedquad);
2620 echo "<center><h1>$dottedquad</h1></center>\n";
7056988c 2621
1fbc9fd6 2622 startPortlet ('update');
e673ee24 2623 echo "<table border=0 cellpadding=10 cellpadding=1 align='center'>\n";
7056988c 2624 printOpFormIntro ('editAddress');
2d318652
DO
2625 echo "<tr><td class='tdright'>Name:</td><td class='tdleft'><input type=text name=name size=20 value='${address['name']}'></tr>";
2626 echo "<td class='tdright'>Reserved:</td><td class='tdleft'><input type=checkbox name=reserved size=20 ";
2627 echo ($address['reserved']=='yes') ? 'checked' : '';
53ef3908
DO
2628 echo "></tr><tr><td colspan=2 class='tdcenter'>";
2629 printImageHREF ('SAVE', 'Save changes', TRUE);
2630 echo "</td></form></tr></table>\n";
1fbc9fd6
DO
2631 finishPortlet();
2632 if (empty ($address['name']) and $address['reserved'] == 'no')
2633 return;
7056988c 2634
1fbc9fd6 2635 startPortlet ('release');
7056988c 2636 printOpFormIntro ('editAddress', array ('name' => '', 'reserved' => ''));
1fbc9fd6
DO
2637 echo "<input type=submit value='release'></form>";
2638 finishPortlet();
e673ee24
DO
2639}
2640
2d318652 2641function renderIPv4AddressAllocations ($dottedquad)
e673ee24 2642{
e673ee24 2643 showMessageOrError();
39b4abd0
DO
2644 function printNewItemTR ()
2645 {
2646 global $aat;
2647 printOpFormIntro ('addIPv4Allocation');
2648 echo "<tr><td>";
9318d2ef 2649 printImageHREF ('add', 'allocate', TRUE);
f5ff50f5 2650 echo "</td><td><select name='object_id' tabindex=100>";
39b4abd0
DO
2651
2652 foreach (explode (',', getConfigVar ('IPV4_PERFORMERS')) as $type)
2653 foreach (getNarrowObjectList ($type) as $object)
2654 echo "<option value='${object['id']}'>${object['dname']}</option>";
2655
f5ff50f5
DO
2656 echo "</select></td><td><input type=text tabindex=101 name=bond_name size=10></td><td>";
2657 printSelect ($aat, 'bond_type', NULL, 102);
9318d2ef 2658 echo "</td><td>";
f5ff50f5 2659 printImageHREF ('add', 'allocate', TRUE, 103);
9318d2ef 2660 echo "</td></form></tr>";
39b4abd0 2661 }
2d318652 2662 global $pageno, $tabno, $root, $aat;
e673ee24 2663
2d318652 2664 $address = getIPv4Address ($dottedquad);
f74d96c6 2665
2d318652 2666 echo "<center><h1>${dottedquad}</h1></center>\n";
105a3bc8 2667 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
2d318652 2668 echo "<tr><th>&nbsp;</th><th>object</th><th>OS interface</th><th>allocation type</th><th>&nbsp;</th></tr>\n";
e673ee24 2669
39b4abd0
DO
2670 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
2671 printNewItemTR();
f74d96c6 2672 if (isset ($address['class']))
e673ee24 2673 {
f74d96c6
DO
2674 $class = $address['class'];
2675 if ($address['reserved'] == 'yes')
2676 echo "<tr class='${class}'><td colspan=3>&nbsp;</td><td class=tdleft><strong>RESERVED</strong></td><td>&nbsp;</td></tr>";
2677 foreach ($address['allocs'] as $bond)
2678 {
2679 echo "<tr class='$class'>";
2680 printOpFormIntro ('updIPv4Allocation', array ('object_id' => $bond['object_id']));
2681 echo "<td><a href='${root}process.php?op=delIPv4Allocation&page=${pageno}&tab=${tabno}&ip=${dottedquad}&object_id=${bond['object_id']}'>";
2682 printImageHREF ('delete', 'Unallocate address');
2683 echo "</a></td>";
2684 echo "<td><a href='${root}?page=object&object_id=${bond['object_id']}&hl_ipv4_addr=${dottedquad}'>${bond['object_name']}</td>";
2685 echo "<td><input type='text' name='bond_name' value='${bond['name']}' size=10></td><td>";
2686 printSelect ($aat, 'bond_type', $bond['type']);
2687 echo "</td><td>";
2688 printImageHREF ('save', 'Save changes', TRUE);
2689 echo "</td></form></tr>\n";
2690 }
e673ee24 2691 }
39b4abd0
DO
2692 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
2693 printNewItemTR();
e673ee24 2694 echo "</table><br><br>";
e673ee24
DO
2695}
2696
eeb4a5d8 2697function renderNATv4ForObject ($object_id = 0)
e673ee24 2698{
9318d2ef
DO
2699 function printNewItemTR ($alloclist)
2700 {
2701 global $root;
2702 printOpFormIntro ('addNATv4Rule');
2703 echo "<tr align='center'><td>";
2704 printImageHREF ('add', 'Add new NAT rule', TRUE);
2705 echo '</td><td>';
2706 printSelect (array ('TCP' => 'TCP', 'UDP' => 'UDP'), 'proto');
2707 echo "<select name='localip' tabindex=1>";
2708
2709 foreach ($alloclist as $dottedquad => $alloc)
2710 {
2711 $name = empty ($alloc['addrinfo']['name']) ? '' : (' (' . niftyString ($alloc['addrinfo']['name']) . ')');
2712 $osif = empty ($alloc['osif']) ? '' : ($alloc['osif'] . ': ');
2713 echo "<option value='${dottedquad}'>${osif}${dottedquad}${name}</option>";
2714 }
2715
2716 echo "</select>:<input type='text' name='localport' size='4' tabindex=2></td>";
2717 echo "<td><input type='text' name='remoteip' id='remoteip' size='10' tabindex=3>";
2718 echo "<a href='javascript:;' onclick='window.open(\"${root}/find_object_ip_helper.php\", \"findobjectip\", \"height=700, width=400, location=no, menubar=no, resizable=yes, scrollbars=no, status=no, titlebar=no, toolbar=no\");'>";
2719 printImageHREF ('find', 'Find object');
2720 echo "</a>";
2721 echo ":<input type='text' name='remoteport' size='4' tabindex=4></td><td></td>";
2722 echo "<td colspan=1><input type='text' name='description' size='20' tabindex=5></td><td>";
f5ff50f5 2723 printImageHREF ('add', 'Add new NAT rule', TRUE, 6);
9318d2ef
DO
2724 echo "</td></tr></form>";
2725 }
e673ee24
DO
2726 global $pageno, $tabno, $root;
2727
2728 $info = getObjectInfo ($object_id);
eeb4a5d8 2729 $forwards = getNATv4ForObject ($object_id);
2c817354 2730 $alloclist = getObjectIPv4Allocations ($object_id);
e673ee24 2731 showMessageOrError();
f28fbe8b 2732 echo "<center><h2>locally performed NAT</h2></center>";
e673ee24 2733
105a3bc8 2734 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
d54b9495 2735 echo "<tr><th></th><th>Match endpoint</th><th>Translate to</th><th>Target object</th><th>Comment</th><th>&nbsp;</th></tr>\n";
e673ee24 2736
9318d2ef
DO
2737 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
2738 printNewItemTR ($alloclist);
e673ee24
DO
2739 foreach ($forwards['out'] as $pf)
2740 {
2c817354
DO
2741 $class = 'trerror';
2742 $osif = '';
2743 if (isset ($alloclist [$pf['localip']]))
2744 {
2745 $class = $alloclist [$pf['localip']]['addrinfo']['class'];
2746 $osif = $alloclist [$pf['localip']]['osif'] . ': ';
2747 }
e673ee24
DO
2748
2749 echo "<tr class='$class'>";
72d8ced3 2750 echo "<td><a href='${root}process.php?op=delNATv4Rule&localip=${pf['localip']}&localport=${pf['localport']}&remoteip=${pf['remoteip']}&remoteport=${pf['remoteport']}&proto=${pf['proto']}&object_id=$object_id&page=${pageno}&tab=${tabno}'>";
4de22e7e
DO
2751 printImageHREF ('delete', 'Delete NAT rule');
2752 echo "</a></td>";
2c817354 2753 echo "<td>${pf['proto']}/${osif}<a href='${root}?page=ipaddress&tab=default&ip=${pf['localip']}'>${pf['localip']}</a>:${pf['localport']}";
f28fbe8b
DO
2754 if (!empty ($pf['local_addr_name']))
2755 echo ' (' . $pf['local_addr_name'] . ')';
2756 echo "</td>";
e673ee24
DO
2757 echo "<td><a href='${root}?page=ipaddress&tab=default&ip=${pf['remoteip']}'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
2758
53ef3908 2759 $address = getIPv4Address ($pf['remoteip']);
e673ee24
DO
2760
2761 echo "<td class='description'>";
53ef3908
DO
2762 if (count ($address['allocs']))
2763 foreach ($address['allocs'] as $bond)
f28fbe8b
DO
2764 echo "<a href='${root}?page=object&tab=default&object_id=${bond['object_id']}'>${bond['object_name']}(${bond['name']})</a> ";
2765 elseif (!empty ($pf['remote_addr_name']))
2766 echo '(' . $pf['remote_addr_name'] . ')';
7056988c
DO
2767 printOpFormIntro
2768 (
2769 'updNATv4Rule',
2770 array
2771 (
2772 'localip' => $pf['localip'],
2773 'localport' => $pf['localport'],
2774 'remoteip' => $pf['remoteip'],
2775 'remoteport' => $pf['remoteport'],
2776 'proto' => $pf['proto']
2777 )
2778 );
2779 echo "</td><td class='description'>";
d54b9495
DO
2780 echo "<input type='text' name='description' value='${pf['description']}'></td><td>";
2781 printImageHREF ('save', 'Save changes', TRUE);
2782 echo "</td></form></tr>";
e673ee24 2783 }
9318d2ef
DO
2784 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
2785 printNewItemTR ($alloclist);
e673ee24
DO
2786
2787 echo "</table><br><br>";
2788
f28fbe8b 2789 echo "<center><h2>arriving NAT connections</h2></center>";
105a3bc8 2790 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
e673ee24
DO
2791 echo "<tr><th></th><th>Source</th><th>Source objects</th><th>Target</th><th>Description</th></tr>\n";
2792
2793 foreach ($forwards['in'] as $pf)
2794 {
72d8ced3 2795 echo "<tr><td><a href='${root}process.php?op=delNATv4Rule&localip=${pf['localip']}&localport=${pf['localport']}&remoteip=${pf['remoteip']}&remoteport=${pf['remoteport']}&proto=${pf['proto']}&object_id=${pf['object_id']}&page=${pageno}&tab=${tabno}'>";
4de22e7e
DO
2796 printImageHREF ('delete', 'Delete NAT rule');
2797 echo "</a></td>";
e673ee24
DO
2798 echo "<td>${pf['proto']}/<a href='${root}?page=ipaddress&tab=default&ip=${pf['localip']}'>${pf['localip']}</a>:${pf['localport']}</td>";
2799 echo "<td class='description'><a href='${root}?page=object&tab=default&object_id=${pf['object_id']}'>${pf['object_name']}</a>";
2800 echo "</td><td><a href='${root}?page=ipaddress&tab=default&ip=${pf['remoteip']}'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
2801 echo "<td class='description'>${pf['description']}</td></tr>";
2802 }
2803
e673ee24 2804 echo "</table><br><br>";
e673ee24
DO
2805}
2806
7056988c 2807// FIXME: move related code away into ophandler(s)
e673ee24
DO
2808function renderAddMultipleObjectsForm ()
2809{
20c901a7 2810 global $root, $pageno, $tabno, $nextorder;
e673ee24
DO
2811
2812 $type_id = array();
7f791d1d 2813 $global_type_id = 0;
e673ee24
DO
2814 $name = array();
2815 $asset_no = array();
ce4d1a79 2816 $keepvalues1 = $keepvalues2 = FALSE;
7f791d1d 2817 $log = array();
e673ee24 2818 // Look for current submit.
7f791d1d 2819 if (isset ($_REQUEST['got_fast_data']))
e673ee24 2820 {
f60bb422 2821 $taglist = isset ($_REQUEST['taglist']) ? $_REQUEST['taglist'] : array();
ce4d1a79 2822 $keepvalues1 = TRUE;
9c0b0016
DO
2823 $max = getConfigVar ('MASSCOUNT');
2824 for ($i = 0; $i < $max; $i++)
e673ee24
DO
2825 {
2826 if (!isset ($_REQUEST["${i}_object_type_id"]))
2827 {
2828 $log[] = array ('code' => 'error', 'message' => "Submitted form is invalid at line " . $i + 1);
2829 break;
2830 }
2c6c7645
DO
2831 assertUIntArg ("${i}_object_type_id", __FUNCTION__, TRUE);
2832 assertStringArg ("${i}_object_name", __FUNCTION__, TRUE);
2833 assertStringArg ("${i}_object_label", __FUNCTION__, TRUE);
2834 assertStringArg ("${i}_object_asset_no", __FUNCTION__, TRUE);
2835 assertStringArg ("${i}_object_barcode", __FUNCTION__, TRUE);
e673ee24
DO
2836 $type_id[$i] = $_REQUEST["${i}_object_type_id"];
2837 // Save user input for possible rendering.
2838 $name[$i] = $_REQUEST["${i}_object_name"];
2839 $label[$i] = $_REQUEST["${i}_object_label"];
2840 $asset_no[$i] = $_REQUEST["${i}_object_asset_no"];
2841 $barcode[$i] = $_REQUEST["${i}_object_barcode"];
2842
f60bb422 2843 // It's better to skip silently, than to print a notice.
e673ee24
DO
2844 if ($type_id[$i] == 0)
2845 continue;
f60bb422 2846 if (commitAddObject ($name[$i], $label[$i], $barcode[$i], $type_id[$i], $asset_no[$i], $taglist) === TRUE)
e673ee24
DO
2847 $log[] = array ('code' => 'success', 'message' => "Added new object '${name[$i]}'");
2848 else
4d2e93f2 2849 $log[] = array ('code' => 'error', 'message' => __FUNCTION__ . ': commitAddObject() failed');
e673ee24 2850 }
e673ee24 2851 }
7f791d1d
DO
2852 elseif (isset ($_REQUEST['got_very_fast_data']))
2853 {
f60bb422 2854 $taglist = isset ($_REQUEST['taglist']) ? $_REQUEST['taglist'] : array();
ce4d1a79 2855 $keepvalues2 = TRUE;
2c6c7645
DO
2856 assertUIntArg ('global_type_id', __FUNCTION__, TRUE);
2857 assertStringArg ('namelist', __FUNCTION__, TRUE);
7f791d1d
DO
2858 $global_type_id = $_REQUEST['global_type_id'];
2859 if ($global_type_id == 0)
2860 {
2861 if (!empty ($_REQUEST['namelist']))
2862 $log[] = array ('code' => 'error', 'message' => 'Object type is not selected, check the form below');
2863 else
2864 $log[] = array ('code' => 'error', 'message' => 'Empty form has been ignored. Cheers.');
2865 }
2866 else
2867 {
2868 // The name extractor below was stolen from ophandlers.php:addMultiPorts()
2869 $names1 = explode ('\n', $_REQUEST['namelist']);
2870 $names2 = array();
2871 foreach ($names1 as $line)
2872 {
2873 $parts = explode ('\r', $line);
2874 reset ($parts);
2875 if (empty ($parts[0]))
2876 continue;
2877 else
2878 $names2[] = rtrim ($parts[0]);
2879 }
2880 foreach ($names2 as $cname)
f60bb422 2881 if (commitAddObject ($cname, '', '', $global_type_id, '', $taglist) === TRUE)
7f791d1d
DO
2882 $log[] = array ('code' => 'success', 'message' => "Added new object '${cname}'");
2883 else
2884 $log[] = array ('code' => 'error', 'message' => "Could not add '${cname}'");
2885 }
2886 }
2887 printLog ($log);
e673ee24
DO
2888
2889 // Render a form for the next.
2890 $typelist = getObjectTypeList();
4c330a14 2891 $typelist[0] = 'select type...';
7f791d1d 2892
f60bb422
DO
2893 startPortlet ('Distinct types, same tags');
2894 $max = getConfigVar ('MASSCOUNT');
20c901a7 2895 echo "<form name=fastform method=post action='${root}?page=${pageno}&tab=${tabno}'>";
e673ee24 2896 echo '<table border=0 align=center>';
f60bb422
DO
2897 echo "<tr><th>Object type</th><th>Common name</th><th>Visible label</th>";
2898 echo "<th>Asset tag</th><th>Barcode</th><th>Tags</th></tr>\n";
7f791d1d 2899 // If a user forgot to select object type on input, we keep his
e673ee24 2900 // previous input in the form.
9c0b0016 2901 for ($i = 0; $i < $max; $i++)
e673ee24 2902 {
7f791d1d 2903 echo '<tr><td>';
e7ade6bf
DO
2904 // Don't employ DEFAULT_OBJECT_TYPE to avoid creating ghost records for pre-selected empty rows.
2905 printSelect ($typelist, "${i}_object_type_id", 0);
e673ee24
DO
2906 echo '</td>';
2907 echo "<td><input type=text size=30 name=${i}_object_name";
ce4d1a79 2908 if ($keepvalues1 and isset ($name[$i]) and (!isset ($type_id[$i]) or $type_id[$i] == 0))
e673ee24
DO
2909 echo " value='${name[$i]}'";
2910 echo "></td>";
2911 echo "<td><input type=text size=30 name=${i}_object_label";
ce4d1a79 2912 if ($keepvalues1 and isset ($label[$i]) and (!isset ($type_id[$i]) or $type_id[$i] == 0))
e673ee24
DO
2913 echo " value='${label[$i]}'";
2914 echo "></td>";
2915 echo "<td><input type=text size=20 name=${i}_object_asset_no";
ce4d1a79 2916 if ($keepvalues1 and isset ($asset_no[$i]) and (!isset ($type_id[$i]) or $type_id[$i] == 0))
e673ee24
DO
2917 echo " value='${asset_no[$i]}'";
2918 echo "></td>";
2919 echo "<td><input type=text size=10 name=${i}_object_barcode";
ce4d1a79 2920 if ($keepvalues1 and isset ($barcode[$i]) and (!isset ($type_id[$i]) or $type_id[$i] == 0))
e673ee24
DO
2921 echo " value='${barcode[$i]}'";
2922 echo "></td>";
f60bb422
DO
2923 if ($i == 0)
2924 {
2925 echo "<td valign=top rowspan=${max}>";
2926 renderTagSelect();
2927 echo "</td>\n";
2928 }
e673ee24 2929 echo "</tr>\n";
e673ee24 2930 }
216c84bb 2931 echo "<tr><td class=submit colspan=5><input type=submit name=got_fast_data value='Go!'></td></tr>\n";
e673ee24
DO
2932 echo "</form></table>\n";
2933 finishPortlet();
7f791d1d 2934
f60bb422 2935 startPortlet ('Same type, same tags');
20c901a7 2936 echo "<form name=veryfastform method=post action='${root}?page=${pageno}&tab=${tabno}'>";
f60bb422
DO
2937 echo "<table border=0 align=center><tr><th>names</th><th>type</th></tr>";
2938 echo "<tr><td rowspan=3><textarea name=namelist cols=40 rows=25>\n";
ce4d1a79 2939 if ($keepvalues2 and $global_type_id == 0)
7f791d1d 2940 echo $_REQUEST['namelist'];
f60bb422
DO
2941 echo "</textarea></td><td valign=top>";
2942 printSelect ($typelist, "global_type_id", getConfigVar ('DEFAULT_OBJECT_TYPE'));
2943 echo "</td></tr>";
2944 echo "<tr><th>Tags</th></tr>";
2945 echo "<tr><td valign=top>";
2946 renderTagSelect();
2947 echo "</td></tr>";
2948 echo "<tr><td colspan=2><input type=submit name=got_very_fast_data value='Go!'></td></tr></table>\n";
2949 echo "</form>\n";
7f791d1d 2950 finishPortlet();
e673ee24
DO
2951}
2952
2953function printGreeting ()
2954{
9318d2ef 2955 global $root, $remote_username, $accounts, $root;
e673ee24 2956 $account = $accounts[$remote_username];
9318d2ef
DO
2957 $person = "<a href='${root}?page=myaccount&tab=default'>";
2958 $person .= empty ($account['user_realname']) ? $account['user_name'] : $account['user_realname'];
2959 $person .= '</a>';
7056988c 2960 echo "Hello, ${person}. This is RackTables " . CODE_VERSION . ". Click <a href='${root}?logout'>here</a> to logout.";
e673ee24
DO
2961}
2962
2963function renderSearchResults ()
2964{
2965 global $remote_username, $root;
2966 $terms = trim ($_REQUEST['q']);
2967 if (empty ($terms))
2968 {
591ff2c4 2969 showError ('Search string cannot be empty.', __FUNCTION__);
e673ee24
DO
2970 return;
2971 }
54522168 2972 if (!permitted ('objects', 'default'))
e673ee24 2973 {
591ff2c4 2974 showError ('You are not authorized for viewing information about objects.', __FUNCTION__);
e673ee24
DO
2975 return;
2976 }
ea5fc465 2977 $nhits = 0;
e673ee24
DO
2978 // If we search for L2 address, we can either find one or find none.
2979 if
2980 (
2981 preg_match ('/^[0-9a-f][0-9a-f]?:[0-9a-f][0-9a-f]?:[0-9a-f][0-9a-f]?:[0-9a-f][0-9a-f]?:[0-9a-f][0-9a-f]?:[0-9a-f][0-9a-f]?$/i', $terms) or
2982 preg_match ('/^[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]$/i', $terms) or
ea5fc465
DO
2983 preg_match ('/^[0-9a-f][0-9a-f][0-9a-f][0-9a-f].[0-9a-f][0-9a-f][0-9a-f][0-9a-f].[0-9a-f][0-9a-f][0-9a-f][0-9a-f]$/i', $terms) or
2984 // STP bridge ID: bridge priotity + port MAC address. Cut off first 4 chars and look for MAC address.
2985 preg_match ('/^[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]$/i', $terms)
e673ee24
DO
2986 )
2987 // Search for L2 address.
2988 {
3ec29bf4
DO
2989 $terms = str_replace ('.', '', $terms);
2990 $terms = str_replace (':', '', $terms);
ea5fc465 2991 $terms = substr ($terms, -12);
e673ee24
DO
2992 $result = searchByl2address ($terms);
2993 if ($result !== NULL)
2994 {
ea5fc465
DO
2995 $nhits++;
2996 $lasthit = 'port';
2997 $summary['port'][] = $result;
e673ee24 2998 }
e673ee24
DO
2999 }
3000 elseif (preg_match ('/^[0-9][0-9]?[0-9]?\.[0-9]?[0-9]?[0-9]?\.[0-9][0-9]?[0-9]?\.[0-9]?[0-9]?[0-9]?$/i', $terms))
3001 // Search for IP address.
3002 {
bb0a44e9 3003 if (NULL !== getIPv4AddressNetworkId ($terms))
e673ee24 3004 {
ea5fc465 3005 $nhits++;
f3d0cb20
DO
3006 $lasthit = 'ipv4addressbydq';
3007 $summary['ipv4addressbydq'][] = $terms;
e673ee24 3008 }
e673ee24
DO
3009 }
3010 else
ea5fc465 3011 // Search for objects, addresses, networks, virtual services and RS pools by their description.
e673ee24 3012 {
ea5fc465
DO
3013 $tmp = getObjectSearchResults ($terms);
3014 if (count ($tmp))
e673ee24 3015 {
ea5fc465
DO
3016 $nhits += count ($tmp);
3017 $lasthit = 'object';
3018 $summary['object'] = $tmp;
e673ee24 3019 }
ea5fc465
DO
3020 $tmp = getIPv4AddressSearchResult ($terms);
3021 if (count ($tmp))
e673ee24 3022 {
ea5fc465 3023 $nhits += count ($tmp);
f3d0cb20
DO
3024 $lasthit = 'ipv4addressbydescr';
3025 $summary['ipv4addressbydescr'] = $tmp;
ea5fc465
DO
3026 }
3027 $tmp = getIPv4PrefixSearchResult ($terms);
3028 if (count ($tmp))
3029 {
3030 $nhits += count ($tmp);
3031 $lasthit = 'ipv4network';
3032 $summary['ipv4network'] = $tmp;
3033 }
05411ccd
DO
3034 $tmp = getIPv4RSPoolSearchResult ($terms);
3035 if (count ($tmp))
3036 {
3037 $nhits += count ($tmp);
3038 $lasthit = 'ipv4rspool';
3039 $summary['ipv4rspool'] = $tmp;
3040 }
3041 $tmp = getIPv4VServiceSearchResult ($terms);
3042 if (count ($tmp))
3043 {
3044 $nhits += count ($tmp);
3045 $lasthit = 'ipv4vs';
3046 $summary['ipv4vs'] = $tmp;
3047 }
6a88e734
DO
3048 $tmp = getAccountSearchResult ($terms);
3049 if (count ($tmp))
3050 {
3051 $nhits += count ($tmp);
3052 $lasthit = 'user';
3053 $summary['user'] = $tmp;
3054 }
e1ae3fb4
AD
3055 $tmp = getFileSearchResult ($terms);
3056 if (count ($tmp))
3057 {
3058 $nhits += count ($tmp);
3059 $lasthit = 'file';
3060 $summary['file'] = $tmp;
3061 }
ea5fc465
DO
3062 }
3063 if ($nhits == 0)
3064 echo "<center><h2>Nothing found for '${terms}'</h2></center>";
3065 elseif ($nhits == 1)
3066 {
3067 $record = current ($summary[$lasthit]);
3068 switch ($lasthit)
3069 {
3070 case 'port':
3071 echo "<script language='Javascript'>document.location='${root}?page=object";
3072 echo "&hl_port_id=" . $record['port_id'];
3073 echo "&object_id=" . $record['object_id'] . "';//</script>";
3074 break;
f3d0cb20
DO
3075 case 'ipv4addressbydq':
3076 $parentnet = getIPv4AddressNetworkId ($record);
3077 if ($parentnet !== NULL)
e1ae3fb4 3078 echo "<script language='Javascript'>document.location='${root}?page=ipv4net&tab=default&id=${parentnet}&hl_ipv4_addr=${record}';//</script>";
f3d0cb20
DO
3079 else
3080 echo "<script language='Javascript'>document.location='${root}?page=ipaddress&ip=${record}';//</script>";
ea5fc465 3081 break;
f3d0cb20
DO
3082 case 'ipv4addressbydescr':
3083 $parentnet = getIPv4AddressNetworkId ($record['ip']);
3084 if ($parentnet !== NULL)
e1ae3fb4 3085 echo "<script language='Javascript'>document.location='${root}?page=ipv4net&tab=default&id=${parentnet}&hl_ipv4_addr=${record['ip']}';//</script>";
f3d0cb20
DO
3086 else
3087 echo "<script language='Javascript'>document.location='${root}?page=ipaddress&ip=${record['ip']}';//</script>";
ea5fc465
DO
3088 break;
3089 case 'ipv4network':
e1ae3fb4 3090 echo "<script language='Javascript'>document.location='${root}?page=ipv4net";
ea5fc465
DO
3091 echo "&id=${record['id']}";
3092 echo "';//</script>";
3093 break;
3094 case 'object':
3095 echo "<script language='Javascript'>document.location='${root}?page=object&object_id=${record['id']}';//</script>";
3096 break;
05411ccd 3097 case 'ipv4rspool':
e1ae3fb4 3098 echo "<script language='Javascript'>document.location='${root}?page=ipv4rspool&pool_id=${record['pool_id']}';//</script>";
05411ccd
DO
3099 break;
3100 case 'ipv4vs':
49fb2686 3101 echo "<script language='Javascript'>document.location='${root}?page=ipv4vs&vs_id=${record['id']}';//</script>";
05411ccd 3102 break;
6a88e734
DO
3103 case 'user':
3104 echo "<script language='Javascript'>document.location='${root}?page=user&user_id=${record['user_id']}';//</script>";
3105 break;
e1ae3fb4
AD
3106 case 'file':
3107 echo "<script language='Javascript'>document.location='${root}?page=file&file_id=${record['id']}';//</script>";
3108 break;
ea5fc465
DO
3109 }
3110 return;
3111 }
3112 else
3113 {
3114 global $nextorder;
3115 $order = 'odd';
3116 echo "<center><h2>${nhits} result(s) found for '${terms}'</h2></center>";
3117 foreach ($summary as $where => $what)
3118 switch ($where)
e673ee24 3119 {
ea5fc465 3120 case 'object':
06adfe89 3121 startPortlet ("<a href='${root}?page=objects'>Objects</a>");
ea5fc465 3122 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
e1ae3fb4 3123 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>Barcode</th></tr>';
ea5fc465
DO
3124 foreach ($what as $obj)
3125 {
2b3d64c5
DO
3126 $tags = loadRackObjectTags ($obj['id']);
3127 echo "<tr class=row_${order} valign=top><td class=tdleft><a href=\"${root}?page=object&object_id=${obj['id']}\">${obj['dname']}</a>";
3128 if (count ($tags))
3129 echo '<br><small>' . serializeTags ($tags) . '</small>';
3130 echo "</td><td>${obj['label']}</td>";
ea5fc465
DO
3131 echo "<td>${obj['asset_no']}</td>";
3132 echo "<td>${obj['barcode']}</td></tr>";
3133 $order = $nextorder[$order];
3134 }
3135 echo '</table>';
3136 finishPortlet();
3137 break;
3138 case 'ipv4network':
06adfe89 3139 startPortlet ("<a href='${root}?page=ipv4space'>IPv4 networks</a>");
ea5fc465 3140 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
e1ae3fb4 3141 echo '<tr><th>Network</th><th>Name/tags</th></tr>';
71287f1c 3142 foreach ($what as $netinfo)
ea5fc465 3143 {
71287f1c
DO
3144 echo "<tr class=row_${order} valign=top>";
3145 printIPv4NetInfoTDs ($netinfo);
3146 echo "</tr>\n";
ea5fc465
DO
3147 $order = $nextorder[$order];
3148 }
3149 echo '</table>';
3150 finishPortlet();
3151 break;
f3d0cb20 3152 case 'ipv4addressbydescr':
ea5fc465
DO
3153 startPortlet ('IPv4 addresses');
3154 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
f3d0cb20 3155 // FIXME: address, parent network, routers (if extended view is enabled)
e1ae3fb4 3156 echo '<tr><th>Address</th><th>Description</th></tr>';
ea5fc465
DO
3157 foreach ($what as $addr)
3158 {
f3d0cb20
DO
3159 echo "<tr class=row_${order}><td class=tdleft>";
3160 $parentnet = getIPv4AddressNetworkId ($addr['ip']);
3161 if ($parentnet !== NULL)
e1ae3fb4 3162 echo "<a href='${root}?page=ipv4net&tab=default&id=${parentnet}&hl_ipv4_addr=${addr['ip']}'>${addr['ip']}</a></td>";
f3d0cb20
DO
3163 else
3164 echo "<a href='${root}?page=ipaddress&ip=${addr['ip']}'>${addr['ip']}</a></td>";
ea5fc465
DO
3165 echo "<td class=tdleft>${addr['name']}</td></tr>";
3166 $order = $nextorder[$order];
3167 }
3168 echo '</table>';
3169 finishPortlet();
3170 break;
05411ccd 3171 case 'ipv4rspool':
ee437dab 3172 startPortlet ("<a href='${root}?page=ipv4rsplist'>RS pools</a>");
05411ccd
DO
3173 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
3174 foreach ($what as $rspool)
3175 {
e1ae3fb4 3176 echo "<tr class=row_${order}><td class=tdleft><a href='${root}?page=ipv4rspool&pool_id=${rspool['pool_id']}'>";
05411ccd
DO
3177 echo buildRSPoolName ($rspool);
3178 echo "</a></td></tr>";
3179 $order = $nextorder[$order];
3180 }
3181 echo '</table>';
3182 finishPortlet();
3183 break;
3184 case 'ipv4vs':
a239e016 3185 startPortlet ("<a href='${root}?page=ipv4vslist'>Virtual services</a>");
05411ccd 3186 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
e1ae3fb4 3187 echo '<tr><th>VS</th><th>Description</th></tr>';
05411ccd
DO
3188 foreach ($what as $vs)
3189 {
49fb2686 3190 echo "<tr class=row_${order}><td class=tdleft><a href='${root}?page=ipv4vs&vs_id=${vs['id']}'>";
05411ccd 3191 echo buildVServiceName ($vs);
6a88e734
DO
3192 echo "</a></td><td class=tdleft>${vs['name']}</td></tr>";
3193 $order = $nextorder[$order];
3194 }
3195 echo '</table>';
3196 finishPortlet();
3197 break;
3198 case 'user':
3199 startPortlet ("<a href='${root}?page=userlist'>Users</a>");
3200 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
e1ae3fb4 3201 echo '<tr><th>Username</th><th>Real Name</th></tr>';
6a88e734
DO
3202 foreach ($what as $item)
3203 {
3204 echo "<tr class=row_${order}><td class=tdleft><a href='${root}?page=user&user_id=${item['user_id']}'>";
3205 echo $item['user_name'];
3206 echo "</a></td><td class=tdleft>${item['user_realname']}</td></tr>";
05411ccd
DO
3207 $order = $nextorder[$order];
3208 }
3209 echo '</table>';
3210 finishPortlet();
3211 break;
e1ae3fb4
AD
3212 case 'file':
3213 startPortlet ("<a href='${root}?page=files'>Files</a>");
3214 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
3215 echo '<tr><th>Name</th><th>Comment</th></tr>';
3216 foreach ($what as $item)
3217 {
3218 echo "<tr class=row_${order}><td class=tdleft><a href='${root}?page=file&file_id=${item['id']}'>";
3219 echo $item['name'];
3220 echo "</a></td><td class=tdleft>${item['comment']}</td></tr>";
3221 $order = $nextorder[$order];
3222 }
3223 echo '</table>';
3224 finishPortlet();
3225 break;
e673ee24 3226 }
e673ee24
DO
3227 }
3228}
3229
3230// This function prints a table of checkboxes to aid the user in toggling mount atoms
3231// from one state to another. The first argument is rack data as
3232// produced by getRackData(), the second is the value used for the 'unckecked' state
3233// and the third is the value used for 'checked' state.
3234// Usage contexts:
3235// for mounting an object: printAtomGrid ($data, 'F', 'T')
3236// for changing rack design: printAtomGrid ($data, 'A', 'F')
3237// for adding rack problem: printAtomGrid ($data, 'F', 'U')
3238// for adding object problem: printAtomGrid ($data, 'T', 'W')
3239
3240function renderAtomGrid ($data)
3241{
3242 $rack_id = $data['id'];
3243 for ($unit_no = $data['height']; $unit_no > 0; $unit_no--)
3244 {
3245 echo "<tr><th>${unit_no}</th>";
3246 for ($locidx = 0; $locidx < 3; $locidx++)
3247 {
3248 $state = $data[$unit_no][$locidx]['state'];
3249 echo "<td class=state_${state}";
3250 if (isset ($data[$unit_no][$locidx]['hl']))
3251 echo $data[$unit_no][$locidx]['hl'];
3252 echo ">";
3253 if (!($data[$unit_no][$locidx]['enabled'] === TRUE))
3254 echo '<input type=checkbox disabled>';
3255 else
3256 echo "<input type=checkbox" . $data[$unit_no][$locidx]['checked'] . " name=atom_${rack_id}_${unit_no}_${locidx}>";
3257 echo '</td>';
3258 }
3259 echo "</tr>\n";
3260 }
3261}
3262
59427701 3263function renderUserList ()
e673ee24 3264{
9048d42b 3265 global $nextorder, $accounts, $root, $pageno;
59427701
DO
3266 echo "<table border=0 class=objectview>\n";
3267 echo "<tr><td class=pcleft>";
e673ee24
DO
3268 startPortlet ('User accounts');
3269 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
3270 echo "<tr><th class=tdleft>Username</th><th class=tdleft>Real name</th></tr>";
3271 $order = 'odd';
59427701 3272 $tagfilter = getTagFilter();
11c8e4be 3273 foreach (getUserAccounts ($tagfilter, getTFMode()) as $user)
e673ee24 3274 {
9048d42b
DO
3275 echo "<tr class=row_${order} valign=top><td class=tdleft><a href='${root}?page=user&user_id=${user['user_id']}'>";
3276 echo "${user['user_name']}</a>";
3277 $usertags = loadUserTags ($user['user_id']);
3278 if (count ($usertags))
3279 echo '<br><small>' . serializeTags ($usertags, "${root}?page=${pageno}&tab=default&") . '</small>';
3280 echo "</td><td class=tdleft>${user['user_realname']}</td></li>";
e673ee24
DO
3281 $order = $nextorder[$order];
3282 }
3283 echo '</table>';
3284 finishPortlet();
59427701
DO
3285 echo '</td><td class=pcright>';
3286 renderTagFilterPortlet ($tagfilter, 'user');
3287 echo "</td></tr></table>\n";
e673ee24
DO
3288}
3289
59427701 3290function renderUserListEditor ()
e673ee24 3291{
39b4abd0
DO
3292 function printNewItemTR ()
3293 {
3294 printOpFormIntro ('createUser');
3295 echo "<tr><td>&nbsp;</td><td><input type=text size=16 name=username tabindex=100></td>\n";
3296 echo "<td><input type=text size=24 name=realname tabindex=101></td>";
3297 echo "<td><input type=password size=64 name=password tabindex=102></td><td>";
3298 printImageHREF ('create', 'Add new account', TRUE, 103);
3299 echo "</td></tr></form>";
3300 }
e673ee24
DO
3301 global $root, $pageno, $tabno, $accounts;
3302 startPortlet ('User accounts');
3303 showMessageOrError();
3304 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
623457f8 3305 echo "<tr><th>status (click to change)</th><th>Username</th><th>Real name</th><th>Password</th><th>&nbsp;</th></tr>\n";
39b4abd0
DO
3306 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
3307 printNewItemTR();
e673ee24
DO
3308 foreach ($accounts as $account)
3309 {
7056988c
DO
3310 printOpFormIntro ('updateUser', array ('user_id' => $account['user_id']));
3311 echo "<tr><td>";
e673ee24
DO
3312 if ($account['user_enabled'] == 'yes' && $account['user_id'] != 1)
3313 {
59427701 3314 echo "<a href='${root}process.php?op=disableUser&page=${pageno}&tab=${tabno}&user_id=${account['user_id']}'>";
e673ee24
DO
3315 printImageHREF ('blockuser', 'disable account');
3316 echo "</a>\n";
3317 }
3318 if ($account['user_enabled'] == 'no' && $account['user_id'] != 1)
3319 {
59427701 3320 echo "<a href='${root}process.php?op=enableUser&page=${pageno}&tab=${tabno}&user_id=${account['user_id']}'>";
e673ee24
DO
3321 printImageHREF ('unblockuser', 'enable account');
3322 echo "</a>\n";
3323 }
3324 // Otherwise skip icon.