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