r2674 - bugfix: don't generate warning about {$unmounted} autotag
[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
6ef9683b 1900function renderAllIPv4Allocations ()
e673ee24 1901{
6ef9683b 1902 $addresses = getAllIPv4Allocations();
e673ee24
DO
1903 usort($addresses, 'sortObjectAddressesAndNames');
1904 foreach ($addresses as $address)
1905 {
1906 echo "<option value='${address['ip']}' onclick='getElementById(\"ip\").value=\"${address['ip']}\";'>${address['object_name']} ${address['name']} ${address['ip']}</option>\n";
1907 }
1908}
1909
1910// History viewer for history-enabled simple dictionaries.
1911function renderHistory ($object_type, $object_id)
1912{
1913 switch ($object_type)
1914 {
1915 case 'row':
1916 $query = "select ctime, user_name, name, deleted, comment from RackRowHistory where id = ${object_id} order by ctime";
1917 $header = '<tr><th>change time</th><th>author</th><th>rack row name</th><th>is deleted?</th><th>rack row comment</th></tr>';
1918 $extra = 4;
1919 break;
1920 case 'rack':
1921 $query =
51690ad4
DY
1922 "select ctime, user_name, rh.name, rh.deleted, rr.name as name, rh.height, rh.comment " .
1923 "from RackHistory as rh left join RackRow as rr on rh.row_id = rr.id " .
1924 "where rh.id = ${object_id} order by ctime";
e673ee24
DO
1925 $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>';
1926 $extra = 6;
1927 break;
1928 case 'object':
1929 $query =
f76c4197 1930 "select ctime, user_name, RackObjectHistory.name as name, label, barcode, asset_no, deleted, has_problems, dict_value, comment " .
00f6f1e4
DY
1931 "from RackObjectHistory inner join Dictionary on objtype_id = dict_key join Chapter on Dictionary.chapter_id = Chapter.id " .
1932 "where Chapter.name = 'RackObjectType' and RackObjectHistory.id=${object_id} order by ctime";
f76c4197 1933 $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
1934 $extra = 9;
1935 break;
1936 default:
591ff2c4 1937 showError ("Uknown object type '${object_type}'", __FUNCTION__);
e673ee24
DO
1938 return;
1939 }
1940 global $dbxlink;
1941 $result = $dbxlink->query ($query);
1942 if ($result == NULL)
1943 {
591ff2c4 1944 showError ('SQL query failed', __FUNCTION__);
e673ee24
DO
1945 return;
1946 }
1947 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1948 $order = 'odd';
1949 global $nextorder;
1950 echo $header;
1951 while ($row = $result->fetch (PDO::FETCH_NUM))
1952 {
1953 echo "<tr class=row_${order}><td>${row[0]}</td>";
1954 for ($i = 1; $i <= $extra; $i++)
1955 echo "<td>" . $row[$i] . "</td>";
1956 echo "</tr>\n";
1957 $order = $nextorder[$order];
1958 }
1959 echo "</table><br>\n";
1960}
1961
1962function renderRackspaceHistory ()
1963{
4fbb5a00 1964 global $nextorder, $pageno, $tabno;
e673ee24
DO
1965 $order = 'odd';
1966 $history = getRackspaceHistory();
1967 // Show the last operation by default.
1968 if (isset ($_REQUEST['op_id']))
1969 $op_id = $_REQUEST['op_id'];
1970 elseif (isset ($history[0]['mo_id']))
1971 $op_id = $history[0]['mo_id'];
1972 else $op_id = NULL;
1973
1974 $omid = NULL;
1975 $nmid = NULL;
1976 $object_id = 1;
1977 if ($op_id)
1978 list ($omid, $nmid) = getOperationMolecules ($op_id);
1979
1980 // Main layout starts.
1981 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
1982
1983 // Left top portlet with old allocation.
1984 echo "<tr><td class=pcleft>";
1985 startPortlet ('Old allocation');
1986 if ($omid)
1987 {
1988 $oldMolecule = getMolecule ($omid);
1989 renderMolecule ($oldMolecule, $object_id);
1990 }
1991 else
1992 echo "nothing";
1993 finishPortlet();
1994
1995 echo '</td><td class=pcright>';
1996
1997 // Right top portlet with new allocation
1998 startPortlet ('New allocation');
1999 if ($nmid)
2000 {
2001 $newMolecule = getMolecule ($nmid);
2002 renderMolecule ($newMolecule, $object_id);
2003 }
2004 else
2005 echo "nothing";
2006 finishPortlet();
737a3f72 2007
e673ee24 2008 echo '</td></tr><tr><td colspan=2>';
737a3f72 2009
e673ee24
DO
2010 // Bottom portlet with list
2011
2012 startPortlet ('Rackspace allocation history');
2013 echo "<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>\n";
2014 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";
2015 foreach ($history as $row)
2016 {
2017 if ($row['mo_id'] == $op_id)
2018 $class = 'hl';
2019 else
2020 $class = "row_${order}";
4fbb5a00 2021 echo "<tr class=${class}><td><a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno, 'op_id'=>$row['mo_id']))."'>${row['ctime']}</a></td>";
e673ee24
DO
2022 echo "<td>${row['user_name']}</td>";
2023 echo "<td>${row['ro_id']}</td><td>${row['objtype_name']}</td><td>${row['name']}</td><td>${row['comment']}</td>\n";
2024 echo "</tr>\n";
2025 $order = $nextorder[$order];
2026 }
2027 echo "</table>\n";
2028 finishPortlet();
737a3f72 2029
e673ee24 2030 echo '</td></tr></table>';
e673ee24
DO
2031}
2032
d9f8a37a 2033function renderIPv4SpaceRecords ($tree, &$tagcache, $baseurl, $target = 0, $level = 1)
d65353ad
DO
2034{
2035 $self = __FUNCTION__;
2036 foreach ($tree as $item)
2037 {
737a3f72 2038 $total = $item['addrt'];
64347dcf
DO
2039 if (getConfigVar ('IPV4_TREE_SHOW_USAGE') == 'yes')
2040 {
2041 loadIPv4AddrList ($item); // necessary to compute router list and address counter
2042 $used = $item['addrc'];
2043 }
2044 else
2045 {
2046 $item['addrlist'] = array();
2047 $item['addrc'] = 0;
2048 }
0137d53c
DO
2049 if (isset ($item['id']))
2050 {
fec0c8da 2051 if ($item['symbol'] == 'node-collapsed')
d9f8a37a 2052 $expandurl = "${baseurl}&eid=" . $item['id'] . "#netid" . $item['id'];
fec0c8da 2053 elseif ($item['symbol'] == 'node-expanded')
d9f8a37a 2054 $expandurl = $baseurl . ($item['parent_id'] ? "&eid=${item['parent_id']}#netid${item['parent_id']}" : '');
fec0c8da
DO
2055 else
2056 $expandurl = '';
0137d53c 2057 echo "<tr valign=top>";
fec0c8da 2058 printIPv4NetInfoTDs ($item, 'tdleft', $level, $item['symbol'], $expandurl);
0137d53c 2059 echo "<td class=tdcenter>";
d9f8a37a
DO
2060 if ($target == $item['id'])
2061 echo "<a name=netid${target}></a>";
64347dcf
DO
2062 if (getConfigVar ('IPV4_TREE_SHOW_USAGE') == 'yes')
2063 {
2064 renderProgressBar ($total ? $used/$total : 0);
2065 echo "<br><small>${used}/${total}</small>";
2066 }
2067 else
2068 echo "<small>${total}</small>";
2069 echo "</td>";
0137d53c 2070 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
b6b87070 2071 printRoutersTD (findRouters ($item['addrlist']), $tagcache);
0137d53c 2072 echo "</tr>";
fec0c8da 2073 if ($item['symbol'] == 'node-expanded' or $item['symbol'] == 'node-expanded-static')
d9f8a37a 2074 $self ($item['kids'], $tagcache, $baseurl, $target, $level + 1);
0137d53c
DO
2075 }
2076 else
2077 {
0137d53c 2078 echo "<tr valign=top>";
fec0c8da 2079 printIPv4NetInfoTDs ($item, 'tdleft sparenetwork', $level, $item['symbol']);
0137d53c 2080 echo "<td class=tdcenter>";
64347dcf
DO
2081 if (getConfigVar ('IPV4_TREE_SHOW_USAGE') == 'yes')
2082 {
2083 renderProgressBar ($used/$total, 'sparenetwork');
2084 echo "<br><small>${used}/${total}</small>";
2085 }
2086 else
2087 echo "<small>${total}</small>";
2088 echo "</td><td>&nbsp;</td></tr>";
0137d53c 2089 }
d65353ad
DO
2090 }
2091}
2092
04d619d0 2093function renderIPv4Space ()
e673ee24 2094{
4fbb5a00 2095 global $pageno, $tabno;
31c941ec
DO
2096 $cellfilter = getCellFilter();
2097 $netlist = filterCellList (listCells ('ipv4net'), $cellfilter['expression']);
573214e0 2098 array_walk ($netlist, 'amplifyCell');
4fbb5a00 2099
94a40058 2100 $netcount = count ($netlist);
5388794d
DO
2101 // expand request can take either natural values or "ALL". Zero means no expanding.
2102 $eid = isset ($_REQUEST['eid']) ? $_REQUEST['eid'] : 0;
2103 $tree = prepareIPv4Tree ($netlist, $eid);
3630d1fb
DO
2104
2105 echo "<table border=0 class=objectview>\n";
2106 echo "<tr><td class=pcleft>";
94a40058 2107 startPortlet ("networks (${netcount})");
5388794d
DO
2108 echo '<h4>';
2109 if ($eid === 0)
4fbb5a00 2110 echo 'auto-collapsing at threshold ' . getConfigVar ('TREE_THRESHOLD') . " (<a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno, 'eid'=>'ALL'))."'>expand all</a>)";
5388794d 2111 elseif ($eid === 'ALL')
4fbb5a00 2112 echo "expanding all (<a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno))."'>auto-collapse</a>)";
5388794d
DO
2113 else
2114 {
2115 $netinfo = getIPv4NetworkInfo ($eid);
4fbb5a00 2116 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
2117 }
2118 echo "</h4><table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
64347dcf 2119 echo "<tr><th>prefix</th><th>name/tags</th><th>capacity</th>";
f0ed1181 2120 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
57dece2f
DO
2121 echo "<th>routed by</th>";
2122 echo "</tr>\n";
fec0c8da 2123 $tagcache = array();
3d670bba 2124 $baseurl = makeHref(array('page'=>$pageno, 'tab'=>$tabno)) . getTagFilterStr (getTagFilter());
5388794d 2125 renderIPv4SpaceRecords ($tree, $tagcache, $baseurl, $eid);
e673ee24 2126 echo "</table>\n";
a7fe7729 2127 finishPortlet();
74ccacff 2128 echo '</td><td class=pcright>';
3d670bba 2129 renderCellFilterPortlet ($cellfilter, 'ipv4net');
74ccacff 2130 echo "</td></tr></table>\n";
f973f491 2131}
a7fe7729 2132
f973f491
DO
2133function renderIPv4SLB ()
2134{
4fbb5a00 2135 global $page, $nextorder;
a7fe7729 2136
6fec9f39 2137 startPortlet ('SLB configuration');
b3c50e6c 2138 echo "<table border=0 width='100%'><tr>";
ee437dab 2139 foreach (array ('ipv4vslist', 'ipv4rsplist', 'rservers', 'lbs') as $pno)
4fbb5a00 2140 echo "<td><h3><a href='".makeHref(array('page'=>$pno))."'>" . $page[$pno]['title'] . "</a></h3></td>";
b3c50e6c
DO
2141 echo '</tr></table>';
2142 finishPortlet();
2143
c3bdc503 2144 $summary = getSLBSummary();
6fec9f39 2145 startPortlet ('SLB tactical overview');
4cadac8f
DO
2146 // A single id-keyed array isn't used here to preserve existing
2147 // order of LBs returned by getSLBSummary()
c3bdc503
DO
2148 $lblist = array();
2149 $lbdname = array();
4cadac8f 2150 foreach ($summary as $vipdata)
da04825a 2151 foreach (array_keys ($vipdata['lblist']) as $lb_object_id)
c3bdc503
DO
2152 if (!in_array ($lb_object_id, $lblist))
2153 {
2154 $oi = getObjectInfo ($lb_object_id);
2155 $lbdname[$lb_object_id] = $oi['dname'];
2156 $lblist[] = $lb_object_id;
2157 }
2158 if (!count ($summary))
2159 echo 'none configured';
2160 else
2161 {
80e85ea1 2162 $order = 'odd';
c3bdc503 2163 echo "<table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
b1a970c7 2164 echo "<tr valign=top><td>&nbsp;</td>";
c3bdc503 2165 foreach ($lblist as $lb_object_id)
b1a970c7 2166 {
4fbb5a00 2167 #echo "<th><a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$lb_object_id))."'>" . $lbdname[$lb_object_id] . "</a></th>";
b1a970c7
DO
2168 echo '<td>';
2169 renderLBCell ($lb_object_id);
2170 echo '</td>';
2171 }
c3bdc503 2172 echo "</tr>\n";
4cadac8f
DO
2173 foreach ($summary as $vsid => $vsdata)
2174 {
b1a970c7
DO
2175 echo "<tr class=row_${order}><td class=tdleft>";
2176 renderVSCell ($vsid);
6fec9f39 2177 echo "</td>";
4cadac8f 2178 foreach ($lblist as $lb_object_id)
da04825a 2179 {
60fbcece 2180 echo '<td class=tdleft>';
2b4eee17 2181 if (!isset ($vsdata['lblist'][$lb_object_id]))
da04825a
DO
2182 echo '&nbsp;';
2183 else
6fec9f39
DO
2184 {
2185 echo $vsdata['lblist'][$lb_object_id]['size'];
4fbb5a00 2186// echo " (<a href='".makeHref(array('page'=>'ipv4rspool', 'pool_id'=>$vsdata['lblist'][$lb_object_id]['id'])). "'>";
79a9edb4 2187// echo $vsdata['lblist'][$lb_object_id]['name'] . '</a>)';
6fec9f39 2188 }
da04825a
DO
2189 echo '</td>';
2190 }
2191 echo "</tr>\n";
80e85ea1 2192 $order = $nextorder[$order];
4cadac8f 2193 }
c3bdc503
DO
2194 echo "</table>\n";
2195 }
a7fe7729 2196 finishPortlet ();
e673ee24
DO
2197}
2198
04d619d0 2199function renderIPv4SpaceEditor ()
e673ee24 2200{
e673ee24 2201 showMessageOrError();
2a201216 2202
a262e150
DO
2203 // IPv4 validator
2204?>
2205 <script type="text/javascript">
2206 function init() {
2207 document.add_new_range.range.setAttribute('match', "^\\d\\d?\\d?\\.\\d\\d?\\d?\\.\\d\\d?\\d?\\.\\d\\d?\\d?\\/\\d\\d?$");
2208
2209 Validate.init();
2210 }
2211 window.onload=init;
2212 </script>
2213<?php
2214
4c0653e2 2215 startPortlet ("Add new");
04d619d0 2216 echo '<table border=0 cellpadding=10 align=center>';
7056988c
DO
2217 // This form requires a name, so JavaScript validator can find it.
2218 // No printOpFormIntro() hence
4fbb5a00 2219 echo "<form method=post name='add_new_range' action='".makeHrefProcess()."'>\n";
42023f03 2220 echo "<input type=hidden name=op value=addIPv4Prefix>\n";
04d619d0
DO
2221 // tags column
2222 echo '<tr><td rowspan=4><h3>assign tags</h3>';
25186565 2223 renderNewEntityTags();
04d619d0
DO
2224 echo '</td>';
2225 // inputs column
2226 echo "<th class=tdright>prefix</th><td class=tdleft><input type=text name='range' size=18 class='live-validate' tabindex=1></td>";
2227 echo "<tr><th class=tdright>name</th><td class=tdleft><input type=text name='name' size='20' tabindex=2></td></tr>";
0c16ef0c 2228 echo "<tr><th class=tdright>connected network</th><td class=tdleft><input type=checkbox name='is_bcast' tabindex=3></td></tr>";
04d619d0 2229 echo "<tr><td colspan=2>";
4c0653e2 2230 printImageHREF ('CREATE', 'Add a new network', TRUE, 4);
04d619d0 2231 echo '</td></tr>';
2a201216 2232 echo "</form></table><br><br>\n";
5c0bb421 2233 finishPortlet();
2a201216 2234
573214e0
DO
2235 $addrspaceList = listCells ('ipv4net');
2236 array_walk ($addrspaceList, 'amplifyCell');
e43a2de4 2237 if (count ($addrspaceList))
e673ee24 2238 {
e43a2de4 2239 startPortlet ('Manage existing (' . count ($addrspaceList) . ')');
04d619d0
DO
2240 echo "<table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
2241 echo "<tr><th>&nbsp;</th><th>prefix</th><th>name</th><th>&nbsp;</th></tr>";
0c16ef0c 2242 foreach ($addrspaceList as $netinfo)
e673ee24 2243 {
0b9c98d7 2244 echo "<form method=post action='".makeHrefProcess(array('op'=>'updIPv4Prefix', 'id'=>$netinfo['id']))."'>";
e43a2de4
DO
2245 echo "<tr valign=top><td>";
2246 if (getConfigVar ('IPV4_JAYWALK') == 'yes')
2247 {
2248 echo "<a href='".makeHrefProcess(array('op'=>'delIPv4Prefix', 'id'=>$netinfo['id']))."'>";
2249 printImageHREF ('destroy', 'Delete this prefix');
2250 echo "</a>";
2251 }
2252 else // only render clickable image for empty networks
2253 {
2254 $netdata = getIPv4NetworkInfo ($netinfo['id']);
2255 loadIPv4AddrList ($netdata);
2256 if (count ($netdata['addrlist']))
2257 printImageHREF ('nodestroy', 'There are ' . count ($netdata['addrlist']) . ' allocations inside');
2258 else
2259 {
2260 echo "<a href='".makeHrefProcess(array('op'=>'delIPv4Prefix', 'id'=>$netinfo['id']))."'>";
2261 printImageHREF ('destroy', 'Delete this prefix');
2262 echo "</a>";
2263 }
2264
2265 }
2266 echo "</td>\n<td class=tdleft>${netinfo['ip']}/${netinfo['mask']}</td>";
0c16ef0c 2267 echo "<td><input type=text name=name size=40 value='${netinfo['name']}'>";
04d619d0
DO
2268 echo "</td><td>";
2269 printImageHREF ('save', 'Save changes', TRUE);
2270 echo "</td></tr></form>\n";
e673ee24 2271 }
04d619d0
DO
2272 echo "</table>";
2273 finishPortlet();
e673ee24 2274 }
e673ee24
DO
2275}
2276
beb9e88a 2277function renderIPv4Network ($id)
e673ee24 2278{
4fbb5a00 2279 global $pageno, $tabno, $aac2;
545478d0
DO
2280 $netmaskbylen = array
2281 (
2282 32 => '255.255.255.255',
2283 31 => '255.255.255.254',
2284 30 => '255.255.255.252',
2285 29 => '255.255.255.248',
2286 28 => '255.255.255.240',
2287 27 => '255.255.255.224',
2288 26 => '255.255.255.192',
2289 25 => '255.255.255.128',
2290 24 => '255.255.255.0',
2291 23 => '255.255.254.0',
2292 22 => '255.255.252.0',
2293 21 => '255.255.248.0',
2294 20 => '255.255.240.0',
2295 19 => '255.255.224.0',
2296 18 => '255.255.192.0',
2297 17 => '255.255.128.0',
2298 16 => '255.255.0.0',
2299 15 => '255.254.0.0',
2300 14 => '255.252.0.0',
2301 13 => '255.248.0.0',
2302 12 => '255.240.0.0',
2303 11 => '255.224.0.0',
2304 10 => '255.192.0.0',
2305 9 => '255.128.0.0',
2306 8 => '255.0.0.0',
2307 7 => '254.0.0.0',
2308 6 => '252.0.0.0',
2309 5 => '248.0.0.0',
2310 4 => '240.0.0.0',
2311 3 => '224.0.0.0',
2312 2 => '192.0.0.0',
2313 1 => '128.0.0.0'
2314 );
2315 $wildcardbylen = array
2316 (
2317 32 => '0.0.0.0',
2318 31 => '0.0.0.1',
2319 30 => '0.0.0.3',
2320 29 => '0.0.0.7',
2321 28 => '0.0.0.15',
2322 27 => '0.0.0.31',
2323 26 => '0.0.0.63',
2324 25 => '0.0.0.127',
2325 24 => '0.0.0.255',
2326 23 => '0.0.1.255',
2327 22 => '0.0.3.255',
2328 21 => '0.0.7.255',
2329 20 => '0.0.15.255',
2330 19 => '0.0.31.255',
2331 18 => '0.0.63.255',
2332 17 => '0.0.127.255',
2333 16 => '0.0.255.25',
2334 15 => '0.1.255.255',
2335 14 => '0.3.255.255',
2336 13 => '0.7.255.255',
2337 12 => '0.15.255.255',
2338 11 => '0.31.255.255',
2339 10 => '0.63.255.255',
2340 9 => '0.127.255.255',
2341 8 => '0.255.255.255',
2342 7 => '1.255.255.255',
2343 6 => '3.255.255.255',
2344 5 => '7.255.255.255',
2345 4 => '15.255.255.255',
2346 3 => '31.255.255.255',
2347 2 => '63.255.255.255',
2348 1 => '127.255.255.255'
2349 );
b901bf1f 2350 $maxperpage = getConfigVar ('IPV4_ADDRS_PER_PAGE');
e673ee24
DO
2351 if (isset($_REQUEST['pg']))
2352 $page = $_REQUEST['pg'];
2353 else
2354 $page=0;
2355
b6b87070
DO
2356 $range = getIPv4NetworkInfo ($id);
2357 loadIPv4AddrList ($range);
2034d968
DO
2358 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
2359 echo "<tr><td colspan=2 align=center><h1>${range['ip']}/${range['mask']}</h1><h2>${range['name']}</h2></td></tr>\n";
2360
2361 echo "<tr><td class=pcleft width='50%'>";
2362 startPortlet ('summary');
2363 $total = ($range['ip_bin'] | $range['mask_bin_inv']) - ($range['ip_bin'] & $range['mask_bin']) + 1;
2364 $used = count ($range['addrlist']);
2365 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
04d619d0
DO
2366
2367 echo "<tr><th width='50%' class=tdright>%% used:</th><td class=tdleft>";
2034d968
DO
2368 renderProgressBar ($used/$total);
2369 echo "&nbsp;${used}/${total}</td></tr>\n";
04d619d0 2370
001e61fa
DO
2371 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
2372 {
3444ecf2
DO
2373 // Build a backtrace from all parent networks.
2374 $clen = $range['mask'];
2375 $backtrace = array();
2376 while (NULL !== ($upperid = getIPv4AddressNetworkId ($range['ip'], $clen)))
2377 {
2378 $upperinfo = getIPv4NetworkInfo ($upperid);
2379 $clen = $upperinfo['mask'];
2380 $backtrace[] = $upperid;
2381 }
2382 $arrows = count ($backtrace);
2383 foreach (array_reverse ($backtrace) as $ancestorid)
001e61fa
DO
2384 {
2385 $ainfo = getIPv4NetworkInfo ($ancestorid);
3444ecf2
DO
2386 echo "<tr><th width='50%' class=tdright>";
2387 for ($i = 0; $i < $arrows; $i++)
2388 echo '&uarr;';
2389 $arrows--;
5d3dcb8d
DO
2390 echo "</th><td class=tdleft>";
2391 renderIPv4NetCell ($ainfo);
2392 echo "</td></tr>";
001e61fa 2393 }
3444ecf2 2394 echo "<tr><th width='50%' class=tdright>&rarr;</th>";
5d3dcb8d
DO
2395 echo "<td class=tdleft>";
2396 renderIPv4NetCell ($range);
2397 echo "</td></tr>";
001e61fa
DO
2398 // FIXME: get and display nested networks
2399 // $theitem = pickLeaf ($ipv4tree, $id);
2400 }
2401
545478d0
DO
2402 echo "<tr><th width='50%' class=tdright>Netmask:</th><td class=tdleft>";
2403 echo $netmaskbylen[$range['mask']];
2404 echo "</td></tr>\n";
04d619d0 2405
c607ab55
DO
2406 echo "<tr><th width='50%' class=tdright>Netmask:</th><td class=tdleft>";
2407 printf ('0x%08X', binMaskFromDec ($range['mask']));
2408 echo "</td></tr>\n";
2409
545478d0
DO
2410 echo "<tr><th width='50%' class=tdright>Wildcard bits:</th><td class=tdleft>";
2411 echo $wildcardbylen[$range['mask']];
2412 echo "</td></tr>\n";
04d619d0 2413
f3d0cb20 2414 $routers = findRouters ($range['addrlist']);
f0ed1181 2415 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes' and count ($routers))
04d619d0 2416 {
57dece2f 2417 echo "<tr><th width='50%' class=tdright>Routed by:</th>";
f3d0cb20 2418 printRoutersTD ($routers);
57dece2f 2419 echo "</tr>\n";
04d619d0
DO
2420 }
2421
4fbb5a00 2422 printTagTRs (makeHref(array('page'=>'ipv4space', 'tab'=>'default'))."&");
2034d968
DO
2423 echo "</table><br>\n";
2424 finishPortlet();
e1ae3fb4
AD
2425
2426 renderFilesPortlet ('ipv4net', $id);
2034d968 2427 echo "</td>\n";
e673ee24 2428
2034d968
DO
2429 echo "<td class=pcright>";
2430 startPortlet ('details');
e673ee24
DO
2431 $startip = $range['ip_bin'] & $range['mask_bin'];
2432 $endip = $range['ip_bin'] | $range['mask_bin_inv'];
2433 $realstartip = $startip;
2434 $realendip = $endip;
2435 $numpages = 0;
2436 if($endip - $startip > $maxperpage)
2437 {
e673ee24
DO
2438 $numpages = ($endip - $startip)/$maxperpage;
2439 $startip = $startip + $page * $maxperpage;
2440 $endip = $startip + $maxperpage-1;
2441 }
2442 echo "<center>";
b901bf1f
DO
2443 if ($numpages)
2444 echo '<h3>' . long2ip ($startip) . ' ~ ' . long2ip ($endip) . '</h3>';
e673ee24
DO
2445 for ($i=0; $i<$numpages; $i++)
2446 {
2447 if ($i == $page)
2448 echo "<b>$i</b> ";
2449 else
4fbb5a00 2450 echo "<a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno, 'id'=>$id, 'pg'=>$i))."'>$i</a> ";
e673ee24
DO
2451 }
2452 echo "</center>";
2453
beb9e88a 2454 echo "<table class='widetable' border=0 cellspacing=0 cellpadding=5 align='center' width='100%'>\n";
e673ee24
DO
2455 echo "<tr><th>Address</th><th>Name</th><th>Allocation</th></tr>\n";
2456
2457
b2035dca
DO
2458 for ($ip = $startip; $ip <= $endip; $ip++) :
2459 if (isset ($_REQUEST['hl_ipv4_addr']) and ip2long ($_REQUEST['hl_ipv4_addr']) == $ip)
2460 $secondstyle = 'tdleft port_highlight';
2727c7df 2461 else
b2035dca
DO
2462 $secondstyle = 'tdleft';
2463 if (!isset ($range['addrlist'][$ip]))
e673ee24 2464 {
4fbb5a00 2465 echo "<tr><td class=tdleft><a href='".makeHref(array('page'=>'ipaddress', 'ip'=>ip_long2quad($ip)))."'>" . ip_long2quad($ip);
b2035dca
DO
2466 echo "</a></td><td class='${secondstyle}'>&nbsp;</td><td class='${secondstyle}'>&nbsp;</td></tr>\n";
2467 continue;
2468 }
b2035dca 2469 $addr = $range['addrlist'][$ip];
2d318652 2470 echo "<tr class='${addr['class']}'>";
e673ee24 2471
4fbb5a00 2472 echo "<td class=tdleft><a href='".makeHref(array('page'=>'ipaddress', 'ip'=>$addr['ip']))."'>${addr['ip']}</a></td>";
b2035dca
DO
2473 echo "<td class='${secondstyle}'>${addr['name']}</td><td class='${secondstyle}'>";
2474 $delim = '';
2475 $prologue = '';
2476 if ( $addr['reserved'] == 'yes')
2477 {
2d318652 2478 echo "<strong>RESERVED</strong> ";
b2035dca
DO
2479 $delim = '; ';
2480 }
2d318652 2481 foreach ($range['addrlist'][$ip]['allocs'] as $ref)
b2035dca 2482 {
beb9e88a 2483 echo $delim . $aac2[$ref['type']];
4fbb5a00 2484 echo "<a href='".makeHref(array('page'=>'object', 'object_id'=>$ref['object_id'], 'hl_ipv4_addr'=>$addr['ip']))."'>";
b2035dca
DO
2485 echo $ref['name'] . (empty ($ref['name']) ? '' : '@');
2486 echo "${ref['object_name']}</a>";
2487 $delim = '; ';
2488 }
2489 if ($delim != '')
2490 {
6131056c 2491 $delim = '';
b2035dca
DO
2492 $prologue = '<br>';
2493 }
2d318652 2494 foreach ($range['addrlist'][$ip]['lblist'] as $ref)
b2035dca
DO
2495 {
2496 echo $prologue;
602663f4 2497 $prologue = '';
4fbb5a00
DY
2498 echo "${delim}<a href='".makeHref(array('page'=>'object', 'object_id'=>$ref['object_id']))."'>";
2499 echo "${ref['object_name']}</a>:<a href='".makeHref(array('page'=>'ipv4vs', 'vs_id'=>$ref['vs_id']))."'>";
b2035dca
DO
2500 echo "${ref['vport']}/${ref['proto']}</a>&rarr;";
2501 $delim = '; ';
2502 }
2503 if ($delim != '')
2504 {
2505 $delim = '';
2506 $prologue = '<br>';
e673ee24 2507 }
2d318652 2508 foreach ($range['addrlist'][$ip]['rslist'] as $ref)
b2035dca
DO
2509 {
2510 echo $prologue;
2511 $prologue = '';
4fbb5a00 2512 echo "${delim}&rarr;${ref['rsport']}@<a href='".makeHref(array('page'=>'ipv4rspool', 'pool_id'=>$ref['rspool_id']))."'>";
b2035dca
DO
2513 echo "${ref['rspool_name']}</a>";
2514 $delim = '; ';
2515 }
2516 echo "</td></tr>\n";
2517 endfor;
2727c7df 2518 // end of iteration
e673ee24
DO
2519
2520 echo "</table>";
2034d968
DO
2521 finishPortlet();
2522 echo "</td></tr></table>\n";
e673ee24
DO
2523}
2524
53ef3908 2525function renderIPv4NetworkProperties ($id)
e673ee24 2526{
e673ee24 2527 showMessageOrError();
53ef3908
DO
2528 $netdata = getIPv4NetworkInfo ($id);
2529 echo "<center><h1>${netdata['ip']}/${netdata['mask']}</h1></center>\n";
e673ee24 2530 echo "<table border=0 cellpadding=10 cellpadding=1 align='center'>\n";
7056988c 2531 printOpFormIntro ('editRange');
53ef3908
DO
2532 echo "<tr><td class='tdright'>Name:</td><td class='tdleft'><input type=text name=name size=20 value='${netdata['name']}'></tr>";
2533 echo "<tr><td colspan=2 class=tdcenter>";
2534 printImageHREF ('SAVE', 'Save changes', TRUE);
2535 echo "</td></form></tr></table>\n";
e673ee24
DO
2536}
2537
2d318652 2538function renderIPv4Address ($dottedquad)
e673ee24 2539{
4fbb5a00 2540 global $aat;
2d318652 2541 $address = getIPv4Address ($dottedquad);
68225375 2542 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
2d318652
DO
2543 echo "<tr><td colspan=2 align=center><h1>${dottedquad}</h1></td></tr>\n";
2544 if (!empty ($address['name']))
68225375 2545 echo "<tr><td colspan=2 align=center><h2>${address['name']}</h2></td></tr>\n";
e673ee24 2546
68225375
DO
2547 echo "<tr><td class=pcleft>";
2548 startPortlet ('summary');
2549 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
04d619d0 2550 echo "<tr><th width='50%' class=tdright>Allocations:</th><td class=tdleft>" . count ($address['allocs']) . "</td></tr>\n";
68225375
DO
2551 echo "<tr><th width='50%' class=tdright>Originated NAT connections:</th><td class=tdleft>" . count ($address['outpf']) . "</td></tr>\n";
2552 echo "<tr><th width='50%' class=tdright>Arriving NAT connections:</th><td class=tdleft>" . count ($address['inpf']) . "</td></tr>\n";
04d619d0 2553 echo "<tr><th width='50%' class=tdright>SLB virtual services:</th><td class=tdleft>" . count ($address['lblist']) . "</td></tr>\n";
68225375
DO
2554 echo "<tr><th width='50%' class=tdright>SLB real servers:</th><td class=tdleft>" . count ($address['rslist']) . "</td></tr>\n";
2555 printTagTRs();
2556 echo "</table><br>\n";
2557 finishPortlet();
2558 echo "</td>\n";
e673ee24 2559
68225375 2560 echo "<td class=pcright>";
e673ee24 2561
f74d96c6 2562 if (isset ($address['class']))
59bebe2b 2563 {
8e700dd1 2564 startPortlet ('allocations');
2d318652
DO
2565 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
2566 echo "<tr><th>object</th><th>OS interface</th><th>allocation type</th></tr>\n";
2567 $class = $address['class'];
2568 // render all allocation records for this address the same way
59bebe2b 2569 if ($address['reserved'] == 'yes')
2d318652
DO
2570 echo "<tr class='${class}'><td colspan=2>&nbsp;</td><td class=tdleft><strong>RESERVED</strong></td></tr>";
2571 foreach ($address['allocs'] as $bond)
59bebe2b 2572 {
8e700dd1
DO
2573 if (isset ($_REQUEST['hl_object_id']) and $_REQUEST['hl_object_id'] == $bond['object_id'])
2574 $secondclass = 'tdleft port_highlight';
2575 else
2576 $secondclass = 'tdleft';
4fbb5a00 2577 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
2578 echo $aat[$bond['type']];
2579 echo "</strong></td></tr>\n";
59bebe2b
DO
2580 }
2581 echo "</table><br><br>";
2582 finishPortlet();
2583 }
e673ee24 2584
f3d0cb20
DO
2585 // FIXME: The returned list is structured differently, than we expect it to be. One of the sides
2586 // must be fixed.
2d318652 2587 if (count ($address['lblist']))
e673ee24 2588 {
2d318652
DO
2589 startPortlet ('Virtual services (' . count ($address['lblist']) . ')');
2590 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
59bebe2b 2591 echo "<tr><th>VS</th><th>name</th></tr>\n";
2d318652 2592 foreach ($address['lblist'] as $vsinfo)
e673ee24 2593 {
4fbb5a00 2594 echo "<tr><td class=tdleft><a href='".makeHref(array('page'=>'ipv4vs', 'vs_id'=>$vsinfo['vs_id']))."'>";
59bebe2b 2595 echo buildVServiceName ($vsinfo) . "</a></td><td class=tdleft>";
5fe1ed76 2596 echo $vsinfo['name'] . "</td></tr>\n";
e673ee24 2597 }
59bebe2b
DO
2598 echo "</table><br><br>";
2599 finishPortlet();
e673ee24 2600 }
5fe1ed76
DO
2601
2602 if (count ($address['rslist']))
2603 {
2604 startPortlet ('Real servers (' . count ($address['rslist']) . ')');
2d318652 2605 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
53f4b619 2606 echo "<tr><th>&nbsp;</th><th>port</th><th>RS pool</th></tr>\n";
5fe1ed76
DO
2607 foreach ($address['rslist'] as $rsinfo)
2608 {
2609 echo "<tr><td>";
2610 if ($rsinfo['inservice'] == 'yes')
2611 printImageHREF ('inservice', 'in service');
2612 else
2613 printImageHREF ('notinservice', 'NOT in service');
4fbb5a00 2614 echo "</td><td class=tdleft>${rsinfo['rsport']}</td><td class=tdleft><a href='".makeHref(array('page'=>'ipv4rspool', 'pool_id'=>$rsinfo['rspool_id']))."'>";
2d318652 2615 echo $rsinfo['rspool_name'] . "</a></td></tr>\n";
5fe1ed76
DO
2616 }
2617 echo "</table><br><br>";
2618 finishPortlet();
2619 }
2620
68225375
DO
2621 if (count ($address['outpf']))
2622 {
105a3bc8 2623 startPortlet ('departing NAT rules');
2d318652 2624 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
105a3bc8
DO
2625 echo "<tr><th>proto</th><th>from</th><th>to</th><th>comment</th></tr>\n";
2626 foreach ($address['outpf'] as $rule)
b62ff880 2627 echo "<tr><td>${rule['proto']}</td><td>${rule['localip']}:${rule['localport']}</td><td>${rule['remoteip']}:${rule['remoteport']}</td><td>${rule['description']}</td></tr>";
105a3bc8 2628 echo "</table>";
68225375
DO
2629 finishPortlet();
2630 }
105a3bc8
DO
2631
2632 if (count ($address['inpf']))
2633 {
2634 startPortlet ('arriving NAT rules');
2d318652 2635 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
105a3bc8
DO
2636 echo "<tr><th>proto</th><th>from</th><th>to</th><th>comment</th></tr>\n";
2637 foreach ($address['inpf'] as $rule)
b62ff880 2638 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
2639 echo "</table>";
2640 finishPortlet();
2641 }
2642
68225375
DO
2643 echo "</td></tr>";
2644 echo "</table>\n";
e673ee24
DO
2645}
2646
2d318652 2647function renderIPv4AddressProperties ($dottedquad)
e673ee24 2648{
e673ee24 2649 showMessageOrError();
2d318652
DO
2650 $address = getIPv4Address ($dottedquad);
2651 echo "<center><h1>$dottedquad</h1></center>\n";
7056988c 2652
1fbc9fd6 2653 startPortlet ('update');
e673ee24 2654 echo "<table border=0 cellpadding=10 cellpadding=1 align='center'>\n";
7056988c 2655 printOpFormIntro ('editAddress');
2d318652
DO
2656 echo "<tr><td class='tdright'>Name:</td><td class='tdleft'><input type=text name=name size=20 value='${address['name']}'></tr>";
2657 echo "<td class='tdright'>Reserved:</td><td class='tdleft'><input type=checkbox name=reserved size=20 ";
2658 echo ($address['reserved']=='yes') ? 'checked' : '';
f3d274bf 2659 echo "></tr><tr><td class=tdleft>";
53ef3908 2660 printImageHREF ('SAVE', 'Save changes', TRUE);
f3d274bf 2661 echo "</td></form><td class=tdright>";
1fbc9fd6 2662 if (empty ($address['name']) and $address['reserved'] == 'no')
f3d274bf
DO
2663 printImageHREF ('CLEAR gray');
2664 else
2665 {
2666 printOpFormIntro ('editAddress', array ('name' => '', 'reserved' => ''));
2667 printImageHREF ('CLEAR', 'Release', TRUE);
2668 echo "</form>";
2669 }
2670 echo "</td></tr></table>\n";
1fbc9fd6 2671 finishPortlet();
e673ee24
DO
2672}
2673
2d318652 2674function renderIPv4AddressAllocations ($dottedquad)
e673ee24 2675{
e673ee24 2676 showMessageOrError();
39b4abd0
DO
2677 function printNewItemTR ()
2678 {
2679 global $aat;
2680 printOpFormIntro ('addIPv4Allocation');
2681 echo "<tr><td>";
9318d2ef 2682 printImageHREF ('add', 'allocate', TRUE);
8d4f7d18 2683 echo "</td><td>";
c6bc0ac5 2684 printSelect (getNarrowObjectList ('IPV4OBJ_LISTSRC'), 'object_id', NULL, 100);
8d4f7d18 2685 echo "</td><td><input type=text tabindex=101 name=bond_name size=10></td><td>";
f5ff50f5 2686 printSelect ($aat, 'bond_type', NULL, 102);
9318d2ef 2687 echo "</td><td>";
f5ff50f5 2688 printImageHREF ('add', 'allocate', TRUE, 103);
9318d2ef 2689 echo "</td></form></tr>";
39b4abd0 2690 }
b82cce3f 2691 global $aat;
e673ee24 2692
2d318652 2693 $address = getIPv4Address ($dottedquad);
f74d96c6 2694
2d318652 2695 echo "<center><h1>${dottedquad}</h1></center>\n";
105a3bc8 2696 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
2d318652 2697 echo "<tr><th>&nbsp;</th><th>object</th><th>OS interface</th><th>allocation type</th><th>&nbsp;</th></tr>\n";
e673ee24 2698
39b4abd0
DO
2699 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
2700 printNewItemTR();
f74d96c6 2701 if (isset ($address['class']))
e673ee24 2702 {
f74d96c6
DO
2703 $class = $address['class'];
2704 if ($address['reserved'] == 'yes')
2705 echo "<tr class='${class}'><td colspan=3>&nbsp;</td><td class=tdleft><strong>RESERVED</strong></td><td>&nbsp;</td></tr>";
2706 foreach ($address['allocs'] as $bond)
2707 {
2708 echo "<tr class='$class'>";
2709 printOpFormIntro ('updIPv4Allocation', array ('object_id' => $bond['object_id']));
4fbb5a00 2710 echo "<td><a href='".makeHrefProcess(array('op'=>'delIPv4Allocation', 'ip'=>$dottedquad, 'object_id'=>$bond['object_id']))."'>";
f74d96c6
DO
2711 printImageHREF ('delete', 'Unallocate address');
2712 echo "</a></td>";
4fbb5a00 2713 echo "<td><a href='".makeHref(array('page'=>'object', 'object_id'=>$bond['object_id'], 'hl_ipv4_addr'=>$dottedquad))."'>${bond['object_name']}</td>";
f74d96c6
DO
2714 echo "<td><input type='text' name='bond_name' value='${bond['name']}' size=10></td><td>";
2715 printSelect ($aat, 'bond_type', $bond['type']);
2716 echo "</td><td>";
2717 printImageHREF ('save', 'Save changes', TRUE);
2718 echo "</td></form></tr>\n";
2719 }
e673ee24 2720 }
39b4abd0
DO
2721 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
2722 printNewItemTR();
e673ee24 2723 echo "</table><br><br>";
e673ee24
DO
2724}
2725
eeb4a5d8 2726function renderNATv4ForObject ($object_id = 0)
e673ee24 2727{
9318d2ef
DO
2728 function printNewItemTR ($alloclist)
2729 {
9318d2ef
DO
2730 printOpFormIntro ('addNATv4Rule');
2731 echo "<tr align='center'><td>";
2732 printImageHREF ('add', 'Add new NAT rule', TRUE);
2733 echo '</td><td>';
2734 printSelect (array ('TCP' => 'TCP', 'UDP' => 'UDP'), 'proto');
2735 echo "<select name='localip' tabindex=1>";
2736
2737 foreach ($alloclist as $dottedquad => $alloc)
2738 {
2739 $name = empty ($alloc['addrinfo']['name']) ? '' : (' (' . niftyString ($alloc['addrinfo']['name']) . ')');
2740 $osif = empty ($alloc['osif']) ? '' : ($alloc['osif'] . ': ');
2741 echo "<option value='${dottedquad}'>${osif}${dottedquad}${name}</option>";
2742 }
2743
2744 echo "</select>:<input type='text' name='localport' size='4' tabindex=2></td>";
2745 echo "<td><input type='text' name='remoteip' id='remoteip' size='10' tabindex=3>";
39106006
DO
2746 echo "<a href='javascript:;' onclick='window.open(\"" . makeHrefForHelper ('inet4list');
2747 echo "\", \"findobjectip\", \"height=700, width=400, location=no, menubar=no, resizable=yes, scrollbars=no, status=no, titlebar=no, toolbar=no\");'>";
9318d2ef
DO
2748 printImageHREF ('find', 'Find object');
2749 echo "</a>";
2750 echo ":<input type='text' name='remoteport' size='4' tabindex=4></td><td></td>";
2751 echo "<td colspan=1><input type='text' name='description' size='20' tabindex=5></td><td>";
f5ff50f5 2752 printImageHREF ('add', 'Add new NAT rule', TRUE, 6);
9318d2ef
DO
2753 echo "</td></tr></form>";
2754 }
e673ee24
DO
2755
2756 $info = getObjectInfo ($object_id);
eeb4a5d8 2757 $forwards = getNATv4ForObject ($object_id);
2c817354 2758 $alloclist = getObjectIPv4Allocations ($object_id);
e673ee24 2759 showMessageOrError();
f28fbe8b 2760 echo "<center><h2>locally performed NAT</h2></center>";
e673ee24 2761
105a3bc8 2762 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
d54b9495 2763 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 2764
9318d2ef
DO
2765 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
2766 printNewItemTR ($alloclist);
e673ee24
DO
2767 foreach ($forwards['out'] as $pf)
2768 {
2c817354
DO
2769 $class = 'trerror';
2770 $osif = '';
2771 if (isset ($alloclist [$pf['localip']]))
2772 {
2773 $class = $alloclist [$pf['localip']]['addrinfo']['class'];
2774 $osif = $alloclist [$pf['localip']]['osif'] . ': ';
2775 }
e673ee24
DO
2776
2777 echo "<tr class='$class'>";
4fbb5a00
DY
2778 echo "<td><a href='".
2779 makeHrefProcess(array(
2780 'op'=>'delNATv4Rule',
2781 'localip'=>$pf['localip'],
2782 'localport'=>$pf['localport'],
2783 'remoteip'=>$pf['remoteip'],
2784 'remoteport'=>$pf['remoteport'],
2785 'proto'=>$pf['proto'],
2786 'object_id'=>$object_id)).
2787 "'>";
4de22e7e
DO
2788 printImageHREF ('delete', 'Delete NAT rule');
2789 echo "</a></td>";
4fbb5a00 2790 echo "<td>${pf['proto']}/${osif}<a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['localip']))."'>${pf['localip']}</a>:${pf['localport']}";
f28fbe8b
DO
2791 if (!empty ($pf['local_addr_name']))
2792 echo ' (' . $pf['local_addr_name'] . ')';
2793 echo "</td>";
4fbb5a00 2794 echo "<td><a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['remoteip']))."'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
e673ee24 2795
53ef3908 2796 $address = getIPv4Address ($pf['remoteip']);
e673ee24
DO
2797
2798 echo "<td class='description'>";
53ef3908
DO
2799 if (count ($address['allocs']))
2800 foreach ($address['allocs'] as $bond)
4fbb5a00 2801 echo "<a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$bond['object_id']))."'>${bond['object_name']}(${bond['name']})</a> ";
f28fbe8b
DO
2802 elseif (!empty ($pf['remote_addr_name']))
2803 echo '(' . $pf['remote_addr_name'] . ')';
7056988c
DO
2804 printOpFormIntro
2805 (
2806 'updNATv4Rule',
2807 array
2808 (
2809 'localip' => $pf['localip'],
2810 'localport' => $pf['localport'],
2811 'remoteip' => $pf['remoteip'],
2812 'remoteport' => $pf['remoteport'],
2813 'proto' => $pf['proto']
2814 )
2815 );
2816 echo "</td><td class='description'>";
d54b9495
DO
2817 echo "<input type='text' name='description' value='${pf['description']}'></td><td>";
2818 printImageHREF ('save', 'Save changes', TRUE);
2819 echo "</td></form></tr>";
e673ee24 2820 }
9318d2ef
DO
2821 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
2822 printNewItemTR ($alloclist);
e673ee24
DO
2823
2824 echo "</table><br><br>";
2825
f28fbe8b 2826 echo "<center><h2>arriving NAT connections</h2></center>";
105a3bc8 2827 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
e673ee24
DO
2828 echo "<tr><th></th><th>Source</th><th>Source objects</th><th>Target</th><th>Description</th></tr>\n";
2829
2830 foreach ($forwards['in'] as $pf)
2831 {
4fbb5a00
DY
2832 echo "<tr><td><a href='".
2833 makeHrefProcess(array(
2834 'op'=>'delNATv4Rule',
2835 'localip'=>$pf['localip'],
2836 'localport'=>$pf['localport'],
2837 'remoteip'=>$pf['remoteip'],
2838 'remoteport'=>$pf['remoteport'],
2839 'proto'=>$pf['proto'],
2840 'object_id'=>$pf['object_id']
2841 )).
2842 "'>";
4de22e7e
DO
2843 printImageHREF ('delete', 'Delete NAT rule');
2844 echo "</a></td>";
4fbb5a00
DY
2845 echo "<td>${pf['proto']}/<a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['localip']))."'>${pf['localip']}</a>:${pf['localport']}</td>";
2846 echo "<td class='description'><a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$pf['object_id']))."'>${pf['object_name']}</a>";
2847 echo "</td><td><a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['remoteip']))."'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
e673ee24
DO
2848 echo "<td class='description'>${pf['description']}</td></tr>";
2849 }
2850
e673ee24 2851 echo "</table><br><br>";
e673ee24
DO
2852}
2853
e673ee24
DO
2854function renderAddMultipleObjectsForm ()
2855{
57777e4a 2856 showMessageOrError();
e673ee24 2857 $typelist = getObjectTypeList();
4c330a14 2858 $typelist[0] = 'select type...';
a1886a78
DO
2859 $max = getConfigVar ('MASSCOUNT');
2860 $tabindex = 100;
7f791d1d 2861
f60bb422 2862 startPortlet ('Distinct types, same tags');
42d73cbf 2863 printOpFormIntro ('addObjects');
e673ee24 2864 echo '<table border=0 align=center>';
f60bb422
DO
2865 echo "<tr><th>Object type</th><th>Common name</th><th>Visible label</th>";
2866 echo "<th>Asset tag</th><th>Barcode</th><th>Tags</th></tr>\n";
9c0b0016 2867 for ($i = 0; $i < $max; $i++)
e673ee24 2868 {
7f791d1d 2869 echo '<tr><td>';
e7ade6bf 2870 // Don't employ DEFAULT_OBJECT_TYPE to avoid creating ghost records for pre-selected empty rows.
a1886a78 2871 printSelect ($typelist, "${i}_object_type_id", 0, $tabindex);
e673ee24 2872 echo '</td>';
a1886a78
DO
2873 echo "<td><input type=text size=30 name=${i}_object_name tabindex=${tabindex}></td>";
2874 echo "<td><input type=text size=30 name=${i}_object_label tabindex=${tabindex}></td>";
2875 echo "<td><input type=text size=20 name=${i}_object_asset_no tabindex=${tabindex}></td>";
2876 echo "<td><input type=text size=10 name=${i}_object_barcode tabindex=${tabindex}></td>";
f60bb422
DO
2877 if ($i == 0)
2878 {
2879 echo "<td valign=top rowspan=${max}>";
25186565 2880 renderNewEntityTags();
f60bb422
DO
2881 echo "</td>\n";
2882 }
e673ee24 2883 echo "</tr>\n";
a1886a78 2884 $tabindex++;
e673ee24 2885 }
216c84bb 2886 echo "<tr><td class=submit colspan=5><input type=submit name=got_fast_data value='Go!'></td></tr>\n";
e673ee24
DO
2887 echo "</form></table>\n";
2888 finishPortlet();
7f791d1d 2889
f60bb422 2890 startPortlet ('Same type, same tags');
42d73cbf 2891 printOpFormIntro ('addLotOfObjects');
f60bb422
DO
2892 echo "<table border=0 align=center><tr><th>names</th><th>type</th></tr>";
2893 echo "<tr><td rowspan=3><textarea name=namelist cols=40 rows=25>\n";
f60bb422
DO
2894 echo "</textarea></td><td valign=top>";
2895 printSelect ($typelist, "global_type_id", getConfigVar ('DEFAULT_OBJECT_TYPE'));
2896 echo "</td></tr>";
2897 echo "<tr><th>Tags</th></tr>";
2898 echo "<tr><td valign=top>";
25186565 2899 renderNewEntityTags();
f60bb422
DO
2900 echo "</td></tr>";
2901 echo "<tr><td colspan=2><input type=submit name=got_very_fast_data value='Go!'></td></tr></table>\n";
2902 echo "</form>\n";
7f791d1d 2903 finishPortlet();
e673ee24
DO
2904}
2905
2906function printGreeting ()
2907{
d6d79c36
DO
2908 global $root, $remote_username, $remote_displayname;
2909 echo "Hello, <a href='${root}?page=myaccount&tab=default'>${remote_displayname}</a>. This is RackTables " .
2910 CODE_VERSION .
2911 ". Click <a href='${root}?logout'>here</a> to logout.";
e673ee24
DO
2912}
2913
2914function renderSearchResults ()
2915{
0b9c98d7 2916 global $root;
e673ee24
DO
2917 $terms = trim ($_REQUEST['q']);
2918 if (empty ($terms))
2919 {
591ff2c4 2920 showError ('Search string cannot be empty.', __FUNCTION__);
e673ee24
DO
2921 return;
2922 }
54522168 2923 if (!permitted ('objects', 'default'))
e673ee24 2924 {
591ff2c4 2925 showError ('You are not authorized for viewing information about objects.', __FUNCTION__);
e673ee24
DO
2926 return;
2927 }
ea5fc465 2928 $nhits = 0;
e673ee24
DO
2929 // If we search for L2 address, we can either find one or find none.
2930 if
2931 (
05771508
DO
2932 preg_match (RE_L2_IFCFG, $terms) or
2933 preg_match (RE_L2_SOLID, $terms) or
2934 preg_match (RE_L2_CISCO, $terms) or
1930dc7f 2935 preg_match (RE_L2_IPCFG, $terms) or
05771508
DO
2936 // Foundry STP bridge ID: bridge priotity + port MAC address. Cut off first 4 chars and look for MAC address.
2937 preg_match (RE_L2_FDRYSTP, $terms)
e673ee24
DO
2938 )
2939 // Search for L2 address.
2940 {
3ec29bf4
DO
2941 $terms = str_replace ('.', '', $terms);
2942 $terms = str_replace (':', '', $terms);
1930dc7f 2943 $terms = str_replace ('-', '', $terms);
ea5fc465 2944 $terms = substr ($terms, -12);
e673ee24
DO
2945 $result = searchByl2address ($terms);
2946 if ($result !== NULL)
2947 {
ea5fc465
DO
2948 $nhits++;
2949 $lasthit = 'port';
2950 $summary['port'][] = $result;
e673ee24 2951 }
e673ee24 2952 }
05771508 2953 elseif (preg_match (RE_IP4_ADDR, $terms))
64347dcf 2954 // Search for IPv4 address.
e673ee24 2955 {
bb0a44e9 2956 if (NULL !== getIPv4AddressNetworkId ($terms))
e673ee24 2957 {
ea5fc465 2958 $nhits++;
f3d0cb20
DO
2959 $lasthit = 'ipv4addressbydq';
2960 $summary['ipv4addressbydq'][] = $terms;
e673ee24 2961 }
e673ee24 2962 }
05771508 2963 elseif (preg_match (RE_IP4_NET, $terms))
64347dcf
DO
2964 // Search for IPv4 network
2965 {
2966 list ($base, $len) = explode ('/', $terms);
2967 if (NULL !== ($tmp = getIPv4AddressNetworkId ($base, $len + 1)))
2968 {
2969 $nhits++;
2970 $lasthit = 'ipv4network';
2971 $summary['ipv4network'][] = getIPv4NetworkInfo ($tmp);
2972 }
2973 }
e673ee24 2974 else
ea5fc465 2975 // Search for objects, addresses, networks, virtual services and RS pools by their description.
e673ee24 2976 {
ea5fc465
DO
2977 $tmp = getObjectSearchResults ($terms);
2978 if (count ($tmp))
e673ee24 2979 {
ea5fc465
DO
2980 $nhits += count ($tmp);
2981 $lasthit = 'object';
2982 $summary['object'] = $tmp;
e673ee24 2983 }
ea5fc465
DO
2984 $tmp = getIPv4AddressSearchResult ($terms);
2985 if (count ($tmp))
e673ee24 2986 {
ea5fc465 2987 $nhits += count ($tmp);
f3d0cb20
DO
2988 $lasthit = 'ipv4addressbydescr';
2989 $summary['ipv4addressbydescr'] = $tmp;
ea5fc465
DO
2990 }
2991 $tmp = getIPv4PrefixSearchResult ($terms);
2992 if (count ($tmp))
2993 {
2994 $nhits += count ($tmp);
2995 $lasthit = 'ipv4network';
2996 $summary['ipv4network'] = $tmp;
2997 }
05411ccd
DO
2998 $tmp = getIPv4RSPoolSearchResult ($terms);
2999 if (count ($tmp))
3000 {
3001 $nhits += count ($tmp);
3002 $lasthit = 'ipv4rspool';
3003 $summary['ipv4rspool'] = $tmp;
3004 }
3005 $tmp = getIPv4VServiceSearchResult ($terms);
3006 if (count ($tmp))
3007 {
3008 $nhits += count ($tmp);
3009 $lasthit = 'ipv4vs';
3010 $summary['ipv4vs'] = $tmp;
3011 }
6a88e734
DO
3012 $tmp = getAccountSearchResult ($terms);
3013 if (count ($tmp))
3014 {
3015 $nhits += count ($tmp);
3016 $lasthit = 'user';
3017 $summary['user'] = $tmp;
3018 }
e1ae3fb4
AD
3019 $tmp = getFileSearchResult ($terms);
3020 if (count ($tmp))
3021 {
3022 $nhits += count ($tmp);
3023 $lasthit = 'file';
3024 $summary['file'] = $tmp;
3025 }
ea5fc465
DO
3026 }
3027 if ($nhits == 0)
3028 echo "<center><h2>Nothing found for '${terms}'</h2></center>";
3029 elseif ($nhits == 1)
3030 {
3031 $record = current ($summary[$lasthit]);
3032 switch ($lasthit)
3033 {
3034 case 'port':
3035 echo "<script language='Javascript'>document.location='${root}?page=object";
3036 echo "&hl_port_id=" . $record['port_id'];
3037 echo "&object_id=" . $record['object_id'] . "';//</script>";
3038 break;
f3d0cb20
DO
3039 case 'ipv4addressbydq':
3040 $parentnet = getIPv4AddressNetworkId ($record);
3041 if ($parentnet !== NULL)
e1ae3fb4 3042 echo "<script language='Javascript'>document.location='${root}?page=ipv4net&tab=default&id=${parentnet}&hl_ipv4_addr=${record}';//</script>";
f3d0cb20
DO
3043 else
3044 echo "<script language='Javascript'>document.location='${root}?page=ipaddress&ip=${record}';//</script>";
ea5fc465 3045 break;
f3d0cb20
DO
3046 case 'ipv4addressbydescr':
3047 $parentnet = getIPv4AddressNetworkId ($record['ip']);
3048 if ($parentnet !== NULL)
e1ae3fb4 3049 echo "<script language='Javascript'>document.location='${root}?page=ipv4net&tab=default&id=${parentnet}&hl_ipv4_addr=${record['ip']}';//</script>";
f3d0cb20
DO
3050 else
3051 echo "<script language='Javascript'>document.location='${root}?page=ipaddress&ip=${record['ip']}';//</script>";
ea5fc465
DO
3052 break;
3053 case 'ipv4network':
e1ae3fb4 3054 echo "<script language='Javascript'>document.location='${root}?page=ipv4net";
ea5fc465
DO
3055 echo "&id=${record['id']}";
3056 echo "';//</script>";
3057 break;
3058 case 'object':
3059 echo "<script language='Javascript'>document.location='${root}?page=object&object_id=${record['id']}';//</script>";
3060 break;
05411ccd 3061 case 'ipv4rspool':
e1ae3fb4 3062 echo "<script language='Javascript'>document.location='${root}?page=ipv4rspool&pool_id=${record['pool_id']}';//</script>";
05411ccd
DO
3063 break;
3064 case 'ipv4vs':
49fb2686 3065 echo "<script language='Javascript'>document.location='${root}?page=ipv4vs&vs_id=${record['id']}';//</script>";
05411ccd 3066 break;
6a88e734
DO
3067 case 'user':
3068 echo "<script language='Javascript'>document.location='${root}?page=user&user_id=${record['user_id']}';//</script>";
3069 break;
e1ae3fb4
AD
3070 case 'file':
3071 echo "<script language='Javascript'>document.location='${root}?page=file&file_id=${record['id']}';//</script>";
3072 break;
ea5fc465
DO
3073 }
3074 return;
3075 }
3076 else
3077 {
3078 global $nextorder;
3079 $order = 'odd';
3080 echo "<center><h2>${nhits} result(s) found for '${terms}'</h2></center>";
3081 foreach ($summary as $where => $what)
3082 switch ($where)
e673ee24 3083 {
ea5fc465 3084 case 'object':
06adfe89 3085 startPortlet ("<a href='${root}?page=objects'>Objects</a>");
ea5fc465 3086 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
e1ae3fb4 3087 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>Barcode</th></tr>';
ea5fc465
DO
3088 foreach ($what as $obj)
3089 {
2c21a10c 3090 $tags = loadEntityTags ('object', $obj['id']);
2b3d64c5
DO
3091 echo "<tr class=row_${order} valign=top><td class=tdleft><a href=\"${root}?page=object&object_id=${obj['id']}\">${obj['dname']}</a>";
3092 if (count ($tags))
3093 echo '<br><small>' . serializeTags ($tags) . '</small>';
3094 echo "</td><td>${obj['label']}</td>";
ea5fc465
DO
3095 echo "<td>${obj['asset_no']}</td>";
3096 echo "<td>${obj['barcode']}</td></tr>";
3097 $order = $nextorder[$order];
3098 }
3099 echo '</table>';
3100 finishPortlet();
3101 break;
3102 case 'ipv4network':
06adfe89 3103 startPortlet ("<a href='${root}?page=ipv4space'>IPv4 networks</a>");
ea5fc465 3104 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
71287f1c 3105 foreach ($what as $netinfo)
ea5fc465 3106 {
0b9c98d7
DO
3107 echo "<tr class=row_${order} valign=top><td>";
3108 renderIPv4NetCell ($netinfo);
3109 echo "</td></tr>\n";
ea5fc465
DO
3110 $order = $nextorder[$order];
3111 }
3112 echo '</table>';
3113 finishPortlet();
3114 break;
f3d0cb20 3115 case 'ipv4addressbydescr':
ea5fc465
DO
3116 startPortlet ('IPv4 addresses');
3117 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
f3d0cb20 3118 // FIXME: address, parent network, routers (if extended view is enabled)
e1ae3fb4 3119 echo '<tr><th>Address</th><th>Description</th></tr>';
ea5fc465
DO
3120 foreach ($what as $addr)
3121 {
f3d0cb20
DO
3122 echo "<tr class=row_${order}><td class=tdleft>";
3123 $parentnet = getIPv4AddressNetworkId ($addr['ip']);
3124 if ($parentnet !== NULL)
e1ae3fb4 3125 echo "<a href='${root}?page=ipv4net&tab=default&id=${parentnet}&hl_ipv4_addr=${addr['ip']}'>${addr['ip']}</a></td>";
f3d0cb20
DO
3126 else
3127 echo "<a href='${root}?page=ipaddress&ip=${addr['ip']}'>${addr['ip']}</a></td>";
ea5fc465
DO
3128 echo "<td class=tdleft>${addr['name']}</td></tr>";
3129 $order = $nextorder[$order];
3130 }
3131 echo '</table>';
3132 finishPortlet();
3133 break;
05411ccd 3134 case 'ipv4rspool':
ee437dab 3135 startPortlet ("<a href='${root}?page=ipv4rsplist'>RS pools</a>");
05411ccd
DO
3136 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
3137 foreach ($what as $rspool)
3138 {
216136d2
DO
3139 echo "<tr class=row_${order}><td class=tdleft>";
3140 renderRSPoolCell ($rspool['pool_id'], $rspool['name']);
3141 echo "</td></tr>";
05411ccd
DO
3142 $order = $nextorder[$order];
3143 }
3144 echo '</table>';
3145 finishPortlet();
3146 break;
3147 case 'ipv4vs':
a239e016 3148 startPortlet ("<a href='${root}?page=ipv4vslist'>Virtual services</a>");
05411ccd 3149 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
8128c257 3150 foreach ($what as $vsinfo)
05411ccd 3151 {
8128c257
DO
3152 echo "<tr class=row_${order}><td class=tdleft>";
3153 renderIPv4VSCell ($vsinfo);
3154 echo "</td></tr>";
6a88e734
DO
3155 $order = $nextorder[$order];
3156 }
3157 echo '</table>';
3158 finishPortlet();
3159 break;
3160 case 'user':
3161 startPortlet ("<a href='${root}?page=userlist'>Users</a>");
3162 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
6a88e734
DO
3163 foreach ($what as $item)
3164 {
19dac9c3 3165 echo "<tr class=row_${order}><td class=tdleft>";
573214e0 3166 renderCell ($item);
19dac9c3 3167 echo "</td></tr>";
05411ccd
DO
3168 $order = $nextorder[$order];
3169 }
3170 echo '</table>';
3171 finishPortlet();
3172 break;
e1ae3fb4
AD
3173 case 'file':
3174 startPortlet ("<a href='${root}?page=files'>Files</a>");
3175 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
e1ae3fb4
AD
3176 foreach ($what as $item)
3177 {
35d10b16
DO
3178 echo "<tr class=row_${order}><td class=tdleft>";
3179 renderFileCell ($item);
3180 echo "</td></tr>";
e1ae3fb4
AD
3181 $order = $nextorder[$order];
3182 }
3183 echo '</table>';
3184 finishPortlet();
3185 break;
e673ee24 3186 }
e673ee24
DO
3187 }
3188}
3189
3190// This function prints a table of checkboxes to aid the user in toggling mount atoms
3191// from one state to another. The first argument is rack data as
3192// produced by getRackData(), the second is the value used for the 'unckecked' state
3193// and the third is the value used for 'checked' state.
3194// Usage contexts:
3195// for mounting an object: printAtomGrid ($data, 'F', 'T')
3196// for changing rack design: printAtomGrid ($data, 'A', 'F')
3197// for adding rack problem: printAtomGrid ($data, 'F', 'U')
3198// for adding object problem: printAtomGrid ($data, 'T', 'W')
3199
3200function renderAtomGrid ($data)
3201{
3202 $rack_id = $data['id'];
3203 for ($unit_no = $data['height']; $unit_no > 0; $unit_no--)
3204 {
57c69e9c 3205 echo "<tr><th><a href='javascript:;' onclick=\"toggleRowOfAtoms('${rack_id}','${unit_no}')\">${unit_no}</a></th>";
e673ee24
DO
3206 for ($locidx = 0; $locidx < 3; $locidx++)
3207 {
57c69e9c 3208 $name = "atom_${rack_id}_${unit_no}_${locidx}";
e673ee24
DO
3209 $state = $data[$unit_no][$locidx]['state'];
3210 echo "<td class=state_${state}";
3211 if (isset ($data[$unit_no][$locidx]['hl']))
3212 echo $data[$unit_no][$locidx]['hl'];
3213 echo ">";
3214 if (!($data[$unit_no][$locidx]['enabled'] === TRUE))
57c69e9c 3215 echo "<input type=checkbox id=${name} disabled>";
e673ee24 3216 else
57c69e9c 3217 echo "<input type=checkbox" . $data[$unit_no][$locidx]['checked'] . " name=${name} id=${name}>";
e673ee24
DO
3218 echo '</td>';
3219 }
3220 echo "</tr>\n";
3221 }
3222}
3223
abf18701 3224function renderCellList ($realm = NULL, $title = 'items', $do_amplify = FALSE)
e673ee24 3225{
573214e0
DO
3226 if ($realm === NULL)
3227 {
3228 global $pageno;