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