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