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