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