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