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