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