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