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