r2312 - forward-porting to trunk
[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'];
a987ff52
DO
2060 loadIPv4AddrList ($item); // necessary to compute router list and address counter
2061 $used = $item['addrc'];
0137d53c
DO
2062 if (isset ($item['id']))
2063 {
fec0c8da 2064 if ($item['symbol'] == 'node-collapsed')
d9f8a37a 2065 $expandurl = "${baseurl}&eid=" . $item['id'] . "#netid" . $item['id'];
fec0c8da 2066 elseif ($item['symbol'] == 'node-expanded')
d9f8a37a 2067 $expandurl = $baseurl . ($item['parent_id'] ? "&eid=${item['parent_id']}#netid${item['parent_id']}" : '');
fec0c8da
DO
2068 else
2069 $expandurl = '';
0137d53c 2070 echo "<tr valign=top>";
fec0c8da 2071 printIPv4NetInfoTDs ($item, 'tdleft', $level, $item['symbol'], $expandurl);
0137d53c 2072 echo "<td class=tdcenter>";
d9f8a37a
DO
2073 if ($target == $item['id'])
2074 echo "<a name=netid${target}></a>";
737a3f72 2075 renderProgressBar ($total ? $used/$total : 0);
0137d53c
DO
2076 echo "<br><small>${used}/${total}</small></td>";
2077 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
b6b87070 2078 printRoutersTD (findRouters ($item['addrlist']), $tagcache);
0137d53c 2079 echo "</tr>";
fec0c8da 2080 if ($item['symbol'] == 'node-expanded' or $item['symbol'] == 'node-expanded-static')
d9f8a37a 2081 $self ($item['kids'], $tagcache, $baseurl, $target, $level + 1);
0137d53c
DO
2082 }
2083 else
2084 {
0137d53c 2085 echo "<tr valign=top>";
fec0c8da 2086 printIPv4NetInfoTDs ($item, 'tdleft sparenetwork', $level, $item['symbol']);
0137d53c 2087 echo "<td class=tdcenter>";
fec0c8da 2088 renderProgressBar ($used/$total, 'sparenetwork');
0137d53c
DO
2089 echo "<br><small>${used}/${total}</small></td>";
2090 echo "<td>&nbsp;</td></tr>";
2091 }
d65353ad
DO
2092 }
2093}
2094
04d619d0 2095function renderIPv4Space ()
e673ee24 2096{
fec0c8da 2097 global $root, $pageno, $tabno;
932cf41f 2098 $tagfilter = getTagFilter();
94a40058
DO
2099 $netlist = getIPv4NetworkList ($tagfilter, getTFMode());
2100 $netcount = count ($netlist);
5388794d
DO
2101 // expand request can take either natural values or "ALL". Zero means no expanding.
2102 $eid = isset ($_REQUEST['eid']) ? $_REQUEST['eid'] : 0;
2103 $tree = prepareIPv4Tree ($netlist, $eid);
3630d1fb
DO
2104
2105 echo "<table border=0 class=objectview>\n";
2106 echo "<tr><td class=pcleft>";
94a40058 2107 startPortlet ("networks (${netcount})");
5388794d
DO
2108 echo '<h4>';
2109 if ($eid === 0)
2110 echo 'auto-collapsing at threshold ' . getConfigVar ('TREE_THRESHOLD') . " (<a href='${root}?page=${pageno}&tab=${tabno}&eid=ALL'>expand all</a>)";
2111 elseif ($eid === 'ALL')
2112 echo "expanding all (<a href='${root}?page=${pageno}&tab=${tabno}'>auto-collapse</a>)";
2113 else
2114 {
2115 $netinfo = getIPv4NetworkInfo ($eid);
2116 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>)";
2117 }
2118 echo "</h4><table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
57dece2f 2119 echo "<tr><th>prefix</th><th>name/tags</th><th>%% used</th>";
f0ed1181 2120 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
57dece2f
DO
2121 echo "<th>routed by</th>";
2122 echo "</tr>\n";
fec0c8da 2123 $tagcache = array();
0c16ef0c 2124 $baseurl = "${root}?page=${pageno}&tab=${tabno}" . getTagFilterStr ($tagfilter);
5388794d 2125 renderIPv4SpaceRecords ($tree, $tagcache, $baseurl, $eid);
e673ee24 2126 echo "</table>\n";
a7fe7729 2127 finishPortlet();
74ccacff 2128 echo '</td><td class=pcright>';
5b7bd02e 2129 renderTagFilterPortlet ($tagfilter, 'ipv4net');
74ccacff 2130 echo "</td></tr></table>\n";
f973f491 2131}
a7fe7729 2132
f973f491
DO
2133function renderIPv4SLB ()
2134{
80e85ea1 2135 global $root, $page, $nextorder;
a7fe7729 2136
6fec9f39 2137 startPortlet ('SLB configuration');
b3c50e6c 2138 echo "<table border=0 width='100%'><tr>";
ee437dab 2139 foreach (array ('ipv4vslist', 'ipv4rsplist', 'rservers', 'lbs') as $pno)
e57dca7f 2140 echo "<td><h3><a href='${root}?page=${pno}'>" . $page[$pno]['title'] . "</a></h3></td>";
b3c50e6c
DO
2141 echo '</tr></table>';
2142 finishPortlet();
2143
c3bdc503 2144 $summary = getSLBSummary();
6fec9f39 2145 startPortlet ('SLB tactical overview');
4cadac8f
DO
2146 // A single id-keyed array isn't used here to preserve existing
2147 // order of LBs returned by getSLBSummary()
c3bdc503
DO
2148 $lblist = array();
2149 $lbdname = array();
4cadac8f 2150 foreach ($summary as $vipdata)
da04825a 2151 foreach (array_keys ($vipdata['lblist']) as $lb_object_id)
c3bdc503
DO
2152 if (!in_array ($lb_object_id, $lblist))
2153 {
2154 $oi = getObjectInfo ($lb_object_id);
2155 $lbdname[$lb_object_id] = $oi['dname'];
2156 $lblist[] = $lb_object_id;
2157 }
2158 if (!count ($summary))
2159 echo 'none configured';
2160 else
2161 {
80e85ea1 2162 $order = 'odd';
c3bdc503 2163 echo "<table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
b1a970c7 2164 echo "<tr valign=top><td>&nbsp;</td>";
c3bdc503 2165 foreach ($lblist as $lb_object_id)
b1a970c7
DO
2166 {
2167 #echo "<th><a href='${root}?page=object&tab=default&object_id=${lb_object_id}'>" . $lbdname[$lb_object_id] . "</a></th>";
2168 echo '<td>';
2169 renderLBCell ($lb_object_id);
2170 echo '</td>';
2171 }
c3bdc503 2172 echo "</tr>\n";
4cadac8f
DO
2173 foreach ($summary as $vsid => $vsdata)
2174 {
b1a970c7
DO
2175 echo "<tr class=row_${order}><td class=tdleft>";
2176 renderVSCell ($vsid);
6fec9f39 2177 echo "</td>";
4cadac8f 2178 foreach ($lblist as $lb_object_id)
da04825a 2179 {
60fbcece 2180 echo '<td class=tdleft>';
2b4eee17 2181 if (!isset ($vsdata['lblist'][$lb_object_id]))
da04825a
DO
2182 echo '&nbsp;';
2183 else
6fec9f39
DO
2184 {
2185 echo $vsdata['lblist'][$lb_object_id]['size'];
e1ae3fb4 2186// echo " (<a href='${root}?page=ipv4rspool&pool_id=";
79a9edb4
DO
2187// echo $vsdata['lblist'][$lb_object_id]['id'] . "'>";
2188// echo $vsdata['lblist'][$lb_object_id]['name'] . '</a>)';
6fec9f39 2189 }
da04825a
DO
2190 echo '</td>';
2191 }
2192 echo "</tr>\n";
80e85ea1 2193 $order = $nextorder[$order];
4cadac8f 2194 }
c3bdc503
DO
2195 echo "</table>\n";
2196 }
a7fe7729 2197 finishPortlet ();
e673ee24
DO
2198}
2199
04d619d0 2200function renderIPv4SpaceEditor ()
e673ee24
DO
2201{
2202 global $root, $pageno, $tabno;
2203 showMessageOrError();
2a201216 2204
a262e150
DO
2205 // IPv4 validator
2206?>
2207 <script type="text/javascript">
2208 function init() {
2209 document.add_new_range.range.setAttribute('match', "^\\d\\d?\\d?\\.\\d\\d?\\d?\\.\\d\\d?\\d?\\.\\d\\d?\\d?\\/\\d\\d?$");
2210
2211 Validate.init();
2212 }
2213 window.onload=init;
2214 </script>
2215<?php
2216
4c0653e2 2217 startPortlet ("Add new");
04d619d0 2218 echo '<table border=0 cellpadding=10 align=center>';
7056988c
DO
2219 // This form requires a name, so JavaScript validator can find it.
2220 // No printOpFormIntro() hence
04d619d0 2221 echo "<form method=post name='add_new_range' action='${root}process.php'>\n";
42023f03 2222 echo "<input type=hidden name=op value=addIPv4Prefix>\n";
2a201216
DY
2223 echo "<input type=hidden name=page value='${pageno}'>\n";
2224 echo "<input type=hidden name=tab value='${tabno}'>\n";
04d619d0
DO
2225 // tags column
2226 echo '<tr><td rowspan=4><h3>assign tags</h3>';
5c0bb421 2227 renderTagSelect();
04d619d0
DO
2228 echo '</td>';
2229 // inputs column
2230 echo "<th class=tdright>prefix</th><td class=tdleft><input type=text name='range' size=18 class='live-validate' tabindex=1></td>";
2231 echo "<tr><th class=tdright>name</th><td class=tdleft><input type=text name='name' size='20' tabindex=2></td></tr>";
0c16ef0c 2232 echo "<tr><th class=tdright>connected network</th><td class=tdleft><input type=checkbox name='is_bcast' tabindex=3></td></tr>";
04d619d0 2233 echo "<tr><td colspan=2>";
4c0653e2 2234 printImageHREF ('CREATE', 'Add a new network', TRUE, 4);
04d619d0 2235 echo '</td></tr>';
2a201216 2236 echo "</form></table><br><br>\n";
5c0bb421 2237 finishPortlet();
2a201216 2238
b18d26dc 2239 $addrspaceList = getIPv4NetworkList();
0c16ef0c
DO
2240 $netcount = count ($addrspaceList);
2241 if ($netcount)
e673ee24 2242 {
0c16ef0c 2243 startPortlet ("Manage existing (${netcount})");
04d619d0
DO
2244 echo "<table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
2245 echo "<tr><th>&nbsp;</th><th>prefix</th><th>name</th><th>&nbsp;</th></tr>";
0c16ef0c 2246 foreach ($addrspaceList as $netinfo)
e673ee24 2247 {
0c16ef0c
DO
2248 echo "<form method=post action='${root}process.php?page=${pageno}&tab=${tabno}&op=updIPv4Prefix&id=${netinfo['id']}'>";
2249 echo "<tr valign=top><td><a href='${root}process.php?op=delIPv4Prefix&page=${pageno}&tab=${tabno}&id=${netinfo['id']}'>";
2250 printImageHREF ('delete', 'Delete this IP range');
2251 echo "</a></td>\n<td class=tdleft>${netinfo['ip']}/${netinfo['mask']}</td>";
2252 echo "<td><input type=text name=name size=40 value='${netinfo['name']}'>";
04d619d0
DO
2253 echo "</td><td>";
2254 printImageHREF ('save', 'Save changes', TRUE);
2255 echo "</td></tr></form>\n";
e673ee24 2256 }
04d619d0
DO
2257 echo "</table>";
2258 finishPortlet();
e673ee24 2259 }
e673ee24
DO
2260}
2261
beb9e88a 2262function renderIPv4Network ($id)
e673ee24 2263{
beb9e88a 2264 global $root, $pageno, $tabno, $aac2;
545478d0
DO
2265 $netmaskbylen = array
2266 (
2267 32 => '255.255.255.255',
2268 31 => '255.255.255.254',
2269 30 => '255.255.255.252',
2270 29 => '255.255.255.248',
2271 28 => '255.255.255.240',
2272 27 => '255.255.255.224',
2273 26 => '255.255.255.192',
2274 25 => '255.255.255.128',
2275 24 => '255.255.255.0',
2276 23 => '255.255.254.0',
2277 22 => '255.255.252.0',
2278 21 => '255.255.248.0',
2279 20 => '255.255.240.0',
2280 19 => '255.255.224.0',
2281 18 => '255.255.192.0',
2282 17 => '255.255.128.0',
2283 16 => '255.255.0.0',
2284 15 => '255.254.0.0',
2285 14 => '255.252.0.0',
2286 13 => '255.248.0.0',
2287 12 => '255.240.0.0',
2288 11 => '255.224.0.0',
2289 10 => '255.192.0.0',
2290 9 => '255.128.0.0',
2291 8 => '255.0.0.0',
2292 7 => '254.0.0.0',
2293 6 => '252.0.0.0',
2294 5 => '248.0.0.0',
2295 4 => '240.0.0.0',
2296 3 => '224.0.0.0',
2297 2 => '192.0.0.0',
2298 1 => '128.0.0.0'
2299 );
2300 $wildcardbylen = array
2301 (
2302 32 => '0.0.0.0',
2303 31 => '0.0.0.1',
2304 30 => '0.0.0.3',
2305 29 => '0.0.0.7',
2306 28 => '0.0.0.15',
2307 27 => '0.0.0.31',
2308 26 => '0.0.0.63',
2309 25 => '0.0.0.127',
2310 24 => '0.0.0.255',
2311 23 => '0.0.1.255',
2312 22 => '0.0.3.255',
2313 21 => '0.0.7.255',
2314 20 => '0.0.15.255',
2315 19 => '0.0.31.255',
2316 18 => '0.0.63.255',
2317 17 => '0.0.127.255',
2318 16 => '0.0.255.25',
2319 15 => '0.1.255.255',
2320 14 => '0.3.255.255',
2321 13 => '0.7.255.255',
2322 12 => '0.15.255.255',
2323 11 => '0.31.255.255',
2324 10 => '0.63.255.255',
2325 9 => '0.127.255.255',
2326 8 => '0.255.255.255',
2327 7 => '1.255.255.255',
2328 6 => '3.255.255.255',
2329 5 => '7.255.255.255',
2330 4 => '15.255.255.255',
2331 3 => '31.255.255.255',
2332 2 => '63.255.255.255',
2333 1 => '127.255.255.255'
2334 );
b901bf1f 2335 $maxperpage = getConfigVar ('IPV4_ADDRS_PER_PAGE');
e673ee24
DO
2336 if (isset($_REQUEST['pg']))
2337 $page = $_REQUEST['pg'];
2338 else
2339 $page=0;
2340
b6b87070
DO
2341 $range = getIPv4NetworkInfo ($id);
2342 loadIPv4AddrList ($range);
2034d968
DO
2343 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
2344 echo "<tr><td colspan=2 align=center><h1>${range['ip']}/${range['mask']}</h1><h2>${range['name']}</h2></td></tr>\n";
2345
2346 echo "<tr><td class=pcleft width='50%'>";
2347 startPortlet ('summary');
2348 $total = ($range['ip_bin'] | $range['mask_bin_inv']) - ($range['ip_bin'] & $range['mask_bin']) + 1;
2349 $used = count ($range['addrlist']);
2350 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
04d619d0
DO
2351
2352 echo "<tr><th width='50%' class=tdright>%% used:</th><td class=tdleft>";
2034d968
DO
2353 renderProgressBar ($used/$total);
2354 echo "&nbsp;${used}/${total}</td></tr>\n";
04d619d0 2355
001e61fa
DO
2356 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
2357 {
3444ecf2
DO
2358 // Build a backtrace from all parent networks.
2359 $clen = $range['mask'];
2360 $backtrace = array();
2361 while (NULL !== ($upperid = getIPv4AddressNetworkId ($range['ip'], $clen)))
2362 {
2363 $upperinfo = getIPv4NetworkInfo ($upperid);
2364 $clen = $upperinfo['mask'];
2365 $backtrace[] = $upperid;
2366 }
2367 $arrows = count ($backtrace);
2368 foreach (array_reverse ($backtrace) as $ancestorid)
001e61fa
DO
2369 {
2370 $ainfo = getIPv4NetworkInfo ($ancestorid);
3444ecf2
DO
2371 echo "<tr><th width='50%' class=tdright>";
2372 for ($i = 0; $i < $arrows; $i++)
2373 echo '&uarr;';
2374 $arrows--;
2375 echo "</th><td class=tdleft><a href='${root}?page=${pageno}&tab=${tabno}&id=${ainfo['id']}'>${ainfo['ip']}/${ainfo['mask']}</a></td></tr>";
001e61fa 2376 }
3444ecf2
DO
2377 echo "<tr><th width='50%' class=tdright>&rarr;</th>";
2378 echo "<td class=tdleft>${range['ip']}/${range['mask']}</td></tr>";
001e61fa
DO
2379 // FIXME: get and display nested networks
2380 // $theitem = pickLeaf ($ipv4tree, $id);
2381 }
2382
545478d0
DO
2383 echo "<tr><th width='50%' class=tdright>Netmask:</th><td class=tdleft>";
2384 echo $netmaskbylen[$range['mask']];
2385 echo "</td></tr>\n";
04d619d0 2386
c607ab55
DO
2387 echo "<tr><th width='50%' class=tdright>Netmask:</th><td class=tdleft>";
2388 printf ('0x%08X', binMaskFromDec ($range['mask']));
2389 echo "</td></tr>\n";
2390
545478d0
DO
2391 echo "<tr><th width='50%' class=tdright>Wildcard bits:</th><td class=tdleft>";
2392 echo $wildcardbylen[$range['mask']];
2393 echo "</td></tr>\n";
04d619d0 2394
f3d0cb20 2395 $routers = findRouters ($range['addrlist']);
f0ed1181 2396 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes' and count ($routers))
04d619d0 2397 {
57dece2f 2398 echo "<tr><th width='50%' class=tdright>Routed by:</th>";
f3d0cb20 2399 printRoutersTD ($routers);
57dece2f 2400 echo "</tr>\n";
04d619d0
DO
2401 }
2402
d9f8a37a 2403 printTagTRs ("${root}?page=ipv4space&tab=default&");
2034d968
DO
2404 echo "</table><br>\n";
2405 finishPortlet();
e1ae3fb4
AD
2406
2407 renderFilesPortlet ('ipv4net', $id);
2034d968 2408 echo "</td>\n";
e673ee24 2409
2034d968
DO
2410 echo "<td class=pcright>";
2411 startPortlet ('details');
e673ee24
DO
2412 $startip = $range['ip_bin'] & $range['mask_bin'];
2413 $endip = $range['ip_bin'] | $range['mask_bin_inv'];
2414 $realstartip = $startip;
2415 $realendip = $endip;
2416 $numpages = 0;
2417 if($endip - $startip > $maxperpage)
2418 {
e673ee24
DO
2419 $numpages = ($endip - $startip)/$maxperpage;
2420 $startip = $startip + $page * $maxperpage;
2421 $endip = $startip + $maxperpage-1;
2422 }
2423 echo "<center>";
b901bf1f
DO
2424 if ($numpages)
2425 echo '<h3>' . long2ip ($startip) . ' ~ ' . long2ip ($endip) . '</h3>';
e673ee24
DO
2426 for ($i=0; $i<$numpages; $i++)
2427 {
2428 if ($i == $page)
2429 echo "<b>$i</b> ";
2430 else
a60e0851 2431 echo "<a href='${root}?page=${pageno}&tab=${tabno}&id=$id&pg=$i'>$i</a> ";
e673ee24
DO
2432 }
2433 echo "</center>";
2434
beb9e88a 2435 echo "<table class='widetable' border=0 cellspacing=0 cellpadding=5 align='center' width='100%'>\n";
e673ee24
DO
2436 echo "<tr><th>Address</th><th>Name</th><th>Allocation</th></tr>\n";
2437
2438
b2035dca
DO
2439 for ($ip = $startip; $ip <= $endip; $ip++) :
2440 if (isset ($_REQUEST['hl_ipv4_addr']) and ip2long ($_REQUEST['hl_ipv4_addr']) == $ip)
2441 $secondstyle = 'tdleft port_highlight';
2727c7df 2442 else
b2035dca
DO
2443 $secondstyle = 'tdleft';
2444 if (!isset ($range['addrlist'][$ip]))
e673ee24 2445 {
b2035dca
DO
2446 echo "<tr><td class=tdleft><a href='${root}?page=ipaddress&ip=" . long2ip ($ip) . "'>" . long2ip ($ip);
2447 echo "</a></td><td class='${secondstyle}'>&nbsp;</td><td class='${secondstyle}'>&nbsp;</td></tr>\n";
2448 continue;
2449 }
b2035dca 2450 $addr = $range['addrlist'][$ip];
2d318652 2451 echo "<tr class='${addr['class']}'>";
e673ee24 2452
b2035dca
DO
2453 echo "<td class=tdleft><a href='${root}?page=ipaddress&ip=${addr['ip']}'>${addr['ip']}</a></td>";
2454 echo "<td class='${secondstyle}'>${addr['name']}</td><td class='${secondstyle}'>";
2455 $delim = '';
2456 $prologue = '';
2457 if ( $addr['reserved'] == 'yes')
2458 {
2d318652 2459 echo "<strong>RESERVED</strong> ";
b2035dca
DO
2460 $delim = '; ';
2461 }
2d318652 2462 foreach ($range['addrlist'][$ip]['allocs'] as $ref)
b2035dca 2463 {
beb9e88a
DO
2464 echo $delim . $aac2[$ref['type']];
2465 echo "<a href='${root}?page=object&object_id=${ref['object_id']}";
b2035dca
DO
2466 echo "&hl_ipv4_addr=${addr['ip']}'>";
2467 echo $ref['name'] . (empty ($ref['name']) ? '' : '@');
2468 echo "${ref['object_name']}</a>";
2469 $delim = '; ';
2470 }
2471 if ($delim != '')
2472 {
6131056c 2473 $delim = '';
b2035dca
DO
2474 $prologue = '<br>';
2475 }
2d318652 2476 foreach ($range['addrlist'][$ip]['lblist'] as $ref)
b2035dca
DO
2477 {
2478 echo $prologue;
602663f4 2479 $prologue = '';
b2035dca
DO
2480 echo "${delim}<a href='${root}?page=object&object_id=${ref['object_id']}'>";
2481 echo "${ref['object_name']}</a>:<a href='${root}?page=ipv4vs&vs_id=${ref['vs_id']}'>";
2482 echo "${ref['vport']}/${ref['proto']}</a>&rarr;";
2483 $delim = '; ';
2484 }
2485 if ($delim != '')
2486 {
2487 $delim = '';
2488 $prologue = '<br>';
e673ee24 2489 }
2d318652 2490 foreach ($range['addrlist'][$ip]['rslist'] as $ref)
b2035dca
DO
2491 {
2492 echo $prologue;
2493 $prologue = '';
e1ae3fb4 2494 echo "${delim}&rarr;${ref['rsport']}@<a href='${root}?page=ipv4rspool&pool_id=${ref['rspool_id']}'>";
b2035dca
DO
2495 echo "${ref['rspool_name']}</a>";
2496 $delim = '; ';
2497 }
2498 echo "</td></tr>\n";
2499 endfor;
2727c7df 2500 // end of iteration
e673ee24
DO
2501
2502 echo "</table>";
2034d968
DO
2503 finishPortlet();
2504 echo "</td></tr></table>\n";
e673ee24
DO
2505}
2506
53ef3908 2507function renderIPv4NetworkProperties ($id)
e673ee24 2508{
e673ee24 2509 showMessageOrError();
53ef3908
DO
2510 $netdata = getIPv4NetworkInfo ($id);
2511 echo "<center><h1>${netdata['ip']}/${netdata['mask']}</h1></center>\n";
e673ee24 2512 echo "<table border=0 cellpadding=10 cellpadding=1 align='center'>\n";
7056988c 2513 printOpFormIntro ('editRange');
53ef3908
DO
2514 echo "<tr><td class='tdright'>Name:</td><td class='tdleft'><input type=text name=name size=20 value='${netdata['name']}'></tr>";
2515 echo "<tr><td colspan=2 class=tdcenter>";
2516 printImageHREF ('SAVE', 'Save changes', TRUE);
2517 echo "</td></form></tr></table>\n";
e673ee24
DO
2518}
2519
2d318652 2520function renderIPv4Address ($dottedquad)
e673ee24 2521{
52c836b1 2522 global $root, $aat;
2d318652 2523 $address = getIPv4Address ($dottedquad);
68225375 2524 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
2d318652
DO
2525 echo "<tr><td colspan=2 align=center><h1>${dottedquad}</h1></td></tr>\n";
2526 if (!empty ($address['name']))
68225375 2527 echo "<tr><td colspan=2 align=center><h2>${address['name']}</h2></td></tr>\n";
e673ee24 2528
68225375
DO
2529 echo "<tr><td class=pcleft>";
2530 startPortlet ('summary');
2531 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
04d619d0 2532 echo "<tr><th width='50%' class=tdright>Allocations:</th><td class=tdleft>" . count ($address['allocs']) . "</td></tr>\n";
68225375
DO
2533 echo "<tr><th width='50%' class=tdright>Originated NAT connections:</th><td class=tdleft>" . count ($address['outpf']) . "</td></tr>\n";
2534 echo "<tr><th width='50%' class=tdright>Arriving NAT connections:</th><td class=tdleft>" . count ($address['inpf']) . "</td></tr>\n";
04d619d0 2535 echo "<tr><th width='50%' class=tdright>SLB virtual services:</th><td class=tdleft>" . count ($address['lblist']) . "</td></tr>\n";
68225375
DO
2536 echo "<tr><th width='50%' class=tdright>SLB real servers:</th><td class=tdleft>" . count ($address['rslist']) . "</td></tr>\n";
2537 printTagTRs();
2538 echo "</table><br>\n";
2539 finishPortlet();
2540 echo "</td>\n";
e673ee24 2541
68225375 2542 echo "<td class=pcright>";
e673ee24 2543
f74d96c6 2544 if (isset ($address['class']))
59bebe2b 2545 {
8e700dd1 2546 startPortlet ('allocations');
2d318652
DO
2547 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
2548 echo "<tr><th>object</th><th>OS interface</th><th>allocation type</th></tr>\n";
2549 $class = $address['class'];
2550 // render all allocation records for this address the same way
59bebe2b 2551 if ($address['reserved'] == 'yes')
2d318652
DO
2552 echo "<tr class='${class}'><td colspan=2>&nbsp;</td><td class=tdleft><strong>RESERVED</strong></td></tr>";
2553 foreach ($address['allocs'] as $bond)
59bebe2b 2554 {
8e700dd1
DO
2555 if (isset ($_REQUEST['hl_object_id']) and $_REQUEST['hl_object_id'] == $bond['object_id'])
2556 $secondclass = 'tdleft port_highlight';
2557 else
2558 $secondclass = 'tdleft';
2559 echo "<tr class='$class'><td class=tdleft><a href='${root}?page=object&object_id=${bond['object_id']}";
2d318652 2560 echo "&hl_ipv4_addr=${dottedquad}'>${bond['object_name']}</td><td class='${secondclass}'>${bond['name']}</td><td class='${secondclass}'><strong>";
52c836b1
DO
2561 echo $aat[$bond['type']];
2562 echo "</strong></td></tr>\n";
59bebe2b
DO
2563 }
2564 echo "</table><br><br>";
2565 finishPortlet();
2566 }
e673ee24 2567
f3d0cb20
DO
2568 // FIXME: The returned list is structured differently, than we expect it to be. One of the sides
2569 // must be fixed.
2d318652 2570 if (count ($address['lblist']))
e673ee24 2571 {
2d318652
DO
2572 startPortlet ('Virtual services (' . count ($address['lblist']) . ')');
2573 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
59bebe2b 2574 echo "<tr><th>VS</th><th>name</th></tr>\n";
2d318652 2575 foreach ($address['lblist'] as $vsinfo)
e673ee24 2576 {
2d318652 2577 echo "<tr><td class=tdleft><a href='${root}?page=ipv4vs&vs_id=${vsinfo['vs_id']}'>";
59bebe2b 2578 echo buildVServiceName ($vsinfo) . "</a></td><td class=tdleft>";
5fe1ed76 2579 echo $vsinfo['name'] . "</td></tr>\n";
e673ee24 2580 }
59bebe2b
DO
2581 echo "</table><br><br>";
2582 finishPortlet();
e673ee24 2583 }
5fe1ed76
DO
2584
2585 if (count ($address['rslist']))
2586 {
2587 startPortlet ('Real servers (' . count ($address['rslist']) . ')');
2d318652 2588 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
53f4b619 2589 echo "<tr><th>&nbsp;</th><th>port</th><th>RS pool</th></tr>\n";
5fe1ed76
DO
2590 foreach ($address['rslist'] as $rsinfo)
2591 {
2592 echo "<tr><td>";
2593 if ($rsinfo['inservice'] == 'yes')
2594 printImageHREF ('inservice', 'in service');
2595 else
2596 printImageHREF ('notinservice', 'NOT in service');
e1ae3fb4 2597 echo "</td><td class=tdleft>${rsinfo['rsport']}</td><td class=tdleft><a href='${root}?page=ipv4rspool&pool_id=${rsinfo['rspool_id']}'>";
2d318652 2598 echo $rsinfo['rspool_name'] . "</a></td></tr>\n";
5fe1ed76
DO
2599 }
2600 echo "</table><br><br>";
2601 finishPortlet();
2602 }
2603
68225375
DO
2604 if (count ($address['outpf']))
2605 {
105a3bc8 2606 startPortlet ('departing NAT rules');
2d318652 2607 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
105a3bc8
DO
2608 echo "<tr><th>proto</th><th>from</th><th>to</th><th>comment</th></tr>\n";
2609 foreach ($address['outpf'] as $rule)
b62ff880 2610 echo "<tr><td>${rule['proto']}</td><td>${rule['localip']}:${rule['localport']}</td><td>${rule['remoteip']}:${rule['remoteport']}</td><td>${rule['description']}</td></tr>";
105a3bc8 2611 echo "</table>";
68225375
DO
2612 finishPortlet();
2613 }
105a3bc8
DO
2614
2615 if (count ($address['inpf']))
2616 {
2617 startPortlet ('arriving NAT rules');
2d318652 2618 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
105a3bc8
DO
2619 echo "<tr><th>proto</th><th>from</th><th>to</th><th>comment</th></tr>\n";
2620 foreach ($address['inpf'] as $rule)
b62ff880 2621 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
2622 echo "</table>";
2623 finishPortlet();
2624 }
2625
68225375
DO
2626 echo "</td></tr>";
2627 echo "</table>\n";
e673ee24
DO
2628}
2629
2d318652 2630function renderIPv4AddressProperties ($dottedquad)
e673ee24 2631{
e673ee24 2632 showMessageOrError();
2d318652
DO
2633 $address = getIPv4Address ($dottedquad);
2634 echo "<center><h1>$dottedquad</h1></center>\n";
7056988c 2635
1fbc9fd6 2636 startPortlet ('update');
e673ee24 2637 echo "<table border=0 cellpadding=10 cellpadding=1 align='center'>\n";
7056988c 2638 printOpFormIntro ('editAddress');
2d318652
DO
2639 echo "<tr><td class='tdright'>Name:</td><td class='tdleft'><input type=text name=name size=20 value='${address['name']}'></tr>";
2640 echo "<td class='tdright'>Reserved:</td><td class='tdleft'><input type=checkbox name=reserved size=20 ";
2641 echo ($address['reserved']=='yes') ? 'checked' : '';
53ef3908
DO
2642 echo "></tr><tr><td colspan=2 class='tdcenter'>";
2643 printImageHREF ('SAVE', 'Save changes', TRUE);
2644 echo "</td></form></tr></table>\n";
1fbc9fd6
DO
2645 finishPortlet();
2646 if (empty ($address['name']) and $address['reserved'] == 'no')
2647 return;
7056988c 2648
1fbc9fd6 2649 startPortlet ('release');
7056988c 2650 printOpFormIntro ('editAddress', array ('name' => '', 'reserved' => ''));
1fbc9fd6
DO
2651 echo "<input type=submit value='release'></form>";
2652 finishPortlet();
e673ee24
DO
2653}
2654
2d318652 2655function renderIPv4AddressAllocations ($dottedquad)
e673ee24 2656{
e673ee24 2657 showMessageOrError();
39b4abd0
DO
2658 function printNewItemTR ()
2659 {
2660 global $aat;
2661 printOpFormIntro ('addIPv4Allocation');
2662 echo "<tr><td>";
9318d2ef 2663 printImageHREF ('add', 'allocate', TRUE);
f5ff50f5 2664 echo "</td><td><select name='object_id' tabindex=100>";
39b4abd0
DO
2665
2666 foreach (explode (',', getConfigVar ('IPV4_PERFORMERS')) as $type)
2667 foreach (getNarrowObjectList ($type) as $object)
2668 echo "<option value='${object['id']}'>${object['dname']}</option>";
2669
f5ff50f5
DO
2670 echo "</select></td><td><input type=text tabindex=101 name=bond_name size=10></td><td>";
2671 printSelect ($aat, 'bond_type', NULL, 102);
9318d2ef 2672 echo "</td><td>";
f5ff50f5 2673 printImageHREF ('add', 'allocate', TRUE, 103);
9318d2ef 2674 echo "</td></form></tr>";
39b4abd0 2675 }
2d318652 2676 global $pageno, $tabno, $root, $aat;
e673ee24 2677
2d318652 2678 $address = getIPv4Address ($dottedquad);
f74d96c6 2679
2d318652 2680 echo "<center><h1>${dottedquad}</h1></center>\n";
105a3bc8 2681 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
2d318652 2682 echo "<tr><th>&nbsp;</th><th>object</th><th>OS interface</th><th>allocation type</th><th>&nbsp;</th></tr>\n";
e673ee24 2683
39b4abd0
DO
2684 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
2685 printNewItemTR();
f74d96c6 2686 if (isset ($address['class']))
e673ee24 2687 {
f74d96c6
DO
2688 $class = $address['class'];
2689 if ($address['reserved'] == 'yes')
2690 echo "<tr class='${class}'><td colspan=3>&nbsp;</td><td class=tdleft><strong>RESERVED</strong></td><td>&nbsp;</td></tr>";
2691 foreach ($address['allocs'] as $bond)
2692 {
2693 echo "<tr class='$class'>";
2694 printOpFormIntro ('updIPv4Allocation', array ('object_id' => $bond['object_id']));
2695 echo "<td><a href='${root}process.php?op=delIPv4Allocation&page=${pageno}&tab=${tabno}&ip=${dottedquad}&object_id=${bond['object_id']}'>";
2696 printImageHREF ('delete', 'Unallocate address');
2697 echo "</a></td>";
2698 echo "<td><a href='${root}?page=object&object_id=${bond['object_id']}&hl_ipv4_addr=${dottedquad}'>${bond['object_name']}</td>";
2699 echo "<td><input type='text' name='bond_name' value='${bond['name']}' size=10></td><td>";
2700 printSelect ($aat, 'bond_type', $bond['type']);
2701 echo "</td><td>";
2702 printImageHREF ('save', 'Save changes', TRUE);
2703 echo "</td></form></tr>\n";
2704 }
e673ee24 2705 }
39b4abd0
DO
2706 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
2707 printNewItemTR();
e673ee24 2708 echo "</table><br><br>";
e673ee24
DO
2709}
2710
eeb4a5d8 2711function renderNATv4ForObject ($object_id = 0)
e673ee24 2712{
9318d2ef
DO
2713 function printNewItemTR ($alloclist)
2714 {
2715 global $root;
2716 printOpFormIntro ('addNATv4Rule');
2717 echo "<tr align='center'><td>";
2718 printImageHREF ('add', 'Add new NAT rule', TRUE);
2719 echo '</td><td>';
2720 printSelect (array ('TCP' => 'TCP', 'UDP' => 'UDP'), 'proto');
2721 echo "<select name='localip' tabindex=1>";
2722
2723 foreach ($alloclist as $dottedquad => $alloc)
2724 {
2725 $name = empty ($alloc['addrinfo']['name']) ? '' : (' (' . niftyString ($alloc['addrinfo']['name']) . ')');
2726 $osif = empty ($alloc['osif']) ? '' : ($alloc['osif'] . ': ');
2727 echo "<option value='${dottedquad}'>${osif}${dottedquad}${name}</option>";
2728 }
2729
2730 echo "</select>:<input type='text' name='localport' size='4' tabindex=2></td>";
2731 echo "<td><input type='text' name='remoteip' id='remoteip' size='10' tabindex=3>";
2732 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\");'>";
2733 printImageHREF ('find', 'Find object');
2734 echo "</a>";
2735 echo ":<input type='text' name='remoteport' size='4' tabindex=4></td><td></td>";
2736 echo "<td colspan=1><input type='text' name='description' size='20' tabindex=5></td><td>";
f5ff50f5 2737 printImageHREF ('add', 'Add new NAT rule', TRUE, 6);
9318d2ef
DO
2738 echo "</td></tr></form>";
2739 }
e673ee24
DO
2740 global $pageno, $tabno, $root;
2741
2742 $info = getObjectInfo ($object_id);
eeb4a5d8 2743 $forwards = getNATv4ForObject ($object_id);
2c817354 2744 $alloclist = getObjectIPv4Allocations ($object_id);
e673ee24 2745 showMessageOrError();
f28fbe8b 2746 echo "<center><h2>locally performed NAT</h2></center>";
e673ee24 2747
105a3bc8 2748 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
d54b9495 2749 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 2750
9318d2ef
DO
2751 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
2752 printNewItemTR ($alloclist);
e673ee24
DO
2753 foreach ($forwards['out'] as $pf)
2754 {
2c817354
DO
2755 $class = 'trerror';
2756 $osif = '';
2757 if (isset ($alloclist [$pf['localip']]))
2758 {
2759 $class = $alloclist [$pf['localip']]['addrinfo']['class'];
2760 $osif = $alloclist [$pf['localip']]['osif'] . ': ';
2761 }
e673ee24
DO
2762
2763 echo "<tr class='$class'>";
72d8ced3 2764 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
2765 printImageHREF ('delete', 'Delete NAT rule');
2766 echo "</a></td>";
2c817354 2767 echo "<td>${pf['proto']}/${osif}<a href='${root}?page=ipaddress&tab=default&ip=${pf['localip']}'>${pf['localip']}</a>:${pf['localport']}";
f28fbe8b
DO
2768 if (!empty ($pf['local_addr_name']))
2769 echo ' (' . $pf['local_addr_name'] . ')';
2770 echo "</td>";
e673ee24
DO
2771 echo "<td><a href='${root}?page=ipaddress&tab=default&ip=${pf['remoteip']}'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
2772
53ef3908 2773 $address = getIPv4Address ($pf['remoteip']);
e673ee24
DO
2774
2775 echo "<td class='description'>";
53ef3908
DO
2776 if (count ($address['allocs']))
2777 foreach ($address['allocs'] as $bond)
f28fbe8b
DO
2778 echo "<a href='${root}?page=object&tab=default&object_id=${bond['object_id']}'>${bond['object_name']}(${bond['name']})</a> ";
2779 elseif (!empty ($pf['remote_addr_name']))
2780 echo '(' . $pf['remote_addr_name'] . ')';
7056988c
DO
2781 printOpFormIntro
2782 (
2783 'updNATv4Rule',
2784 array
2785 (
2786 'localip' => $pf['localip'],
2787 'localport' => $pf['localport'],
2788 'remoteip' => $pf['remoteip'],
2789 'remoteport' => $pf['remoteport'],
2790 'proto' => $pf['proto']
2791 )
2792 );
2793 echo "</td><td class='description'>";
d54b9495
DO
2794 echo "<input type='text' name='description' value='${pf['description']}'></td><td>";
2795 printImageHREF ('save', 'Save changes', TRUE);
2796 echo "</td></form></tr>";
e673ee24 2797 }
9318d2ef
DO
2798 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
2799 printNewItemTR ($alloclist);
e673ee24
DO
2800
2801 echo "</table><br><br>";
2802
f28fbe8b 2803 echo "<center><h2>arriving NAT connections</h2></center>";
105a3bc8 2804 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
e673ee24
DO
2805 echo "<tr><th></th><th>Source</th><th>Source objects</th><th>Target</th><th>Description</th></tr>\n";
2806
2807 foreach ($forwards['in'] as $pf)
2808 {
72d8ced3 2809 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
2810 printImageHREF ('delete', 'Delete NAT rule');
2811 echo "</a></td>";
e673ee24
DO
2812 echo "<td>${pf['proto']}/<a href='${root}?page=ipaddress&tab=default&ip=${pf['localip']}'>${pf['localip']}</a>:${pf['localport']}</td>";
2813 echo "<td class='description'><a href='${root}?page=object&tab=default&object_id=${pf['object_id']}'>${pf['object_name']}</a>";
2814 echo "</td><td><a href='${root}?page=ipaddress&tab=default&ip=${pf['remoteip']}'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
2815 echo "<td class='description'>${pf['description']}</td></tr>";
2816 }
2817
e673ee24 2818 echo "</table><br><br>";
e673ee24
DO
2819}
2820
7056988c 2821// FIXME: move related code away into ophandler(s)
e673ee24
DO
2822function renderAddMultipleObjectsForm ()
2823{
20c901a7 2824 global $root, $pageno, $tabno, $nextorder;
e673ee24
DO
2825
2826 $type_id = array();
7f791d1d 2827 $global_type_id = 0;
e673ee24
DO
2828 $name = array();
2829 $asset_no = array();
ce4d1a79 2830 $keepvalues1 = $keepvalues2 = FALSE;
7f791d1d 2831 $log = array();
e673ee24 2832 // Look for current submit.
7f791d1d 2833 if (isset ($_REQUEST['got_fast_data']))
e673ee24 2834 {
f60bb422 2835 $taglist = isset ($_REQUEST['taglist']) ? $_REQUEST['taglist'] : array();
ce4d1a79 2836 $keepvalues1 = TRUE;
9c0b0016
DO
2837 $max = getConfigVar ('MASSCOUNT');
2838 for ($i = 0; $i < $max; $i++)
e673ee24
DO
2839 {
2840 if (!isset ($_REQUEST["${i}_object_type_id"]))
2841 {
2842 $log[] = array ('code' => 'error', 'message' => "Submitted form is invalid at line " . $i + 1);
2843 break;
2844 }
2c6c7645
DO
2845 assertUIntArg ("${i}_object_type_id", __FUNCTION__, TRUE);
2846 assertStringArg ("${i}_object_name", __FUNCTION__, TRUE);
2847 assertStringArg ("${i}_object_label", __FUNCTION__, TRUE);
2848 assertStringArg ("${i}_object_asset_no", __FUNCTION__, TRUE);
2849 assertStringArg ("${i}_object_barcode", __FUNCTION__, TRUE);
e673ee24
DO
2850 $type_id[$i] = $_REQUEST["${i}_object_type_id"];
2851 // Save user input for possible rendering.
2852 $name[$i] = $_REQUEST["${i}_object_name"];
2853 $label[$i] = $_REQUEST["${i}_object_label"];
2854 $asset_no[$i] = $_REQUEST["${i}_object_asset_no"];
2855 $barcode[$i] = $_REQUEST["${i}_object_barcode"];
2856
f60bb422 2857 // It's better to skip silently, than to print a notice.
e673ee24
DO
2858 if ($type_id[$i] == 0)
2859 continue;
f60bb422 2860 if (commitAddObject ($name[$i], $label[$i], $barcode[$i], $type_id[$i], $asset_no[$i], $taglist) === TRUE)
e673ee24
DO
2861 $log[] = array ('code' => 'success', 'message' => "Added new object '${name[$i]}'");
2862 else
4d2e93f2 2863 $log[] = array ('code' => 'error', 'message' => __FUNCTION__ . ': commitAddObject() failed');
e673ee24 2864 }
e673ee24 2865 }
7f791d1d
DO
2866 elseif (isset ($_REQUEST['got_very_fast_data']))
2867 {
f60bb422 2868 $taglist = isset ($_REQUEST['taglist']) ? $_REQUEST['taglist'] : array();
ce4d1a79 2869 $keepvalues2 = TRUE;
2c6c7645
DO
2870 assertUIntArg ('global_type_id', __FUNCTION__, TRUE);
2871 assertStringArg ('namelist', __FUNCTION__, TRUE);
7f791d1d
DO
2872 $global_type_id = $_REQUEST['global_type_id'];
2873 if ($global_type_id == 0)
2874 {
2875 if (!empty ($_REQUEST['namelist']))
2876 $log[] = array ('code' => 'error', 'message' => 'Object type is not selected, check the form below');
2877 else
2878 $log[] = array ('code' => 'error', 'message' => 'Empty form has been ignored. Cheers.');
2879 }
2880 else
2881 {
2882 // The name extractor below was stolen from ophandlers.php:addMultiPorts()
2883 $names1 = explode ('\n', $_REQUEST['namelist']);
2884 $names2 = array();
2885 foreach ($names1 as $line)
2886 {
2887 $parts = explode ('\r', $line);
2888 reset ($parts);
2889 if (empty ($parts[0]))
2890 continue;
2891 else
2892 $names2[] = rtrim ($parts[0]);
2893 }
2894 foreach ($names2 as $cname)
f60bb422 2895 if (commitAddObject ($cname, '', '', $global_type_id, '', $taglist) === TRUE)
7f791d1d
DO
2896 $log[] = array ('code' => 'success', 'message' => "Added new object '${cname}'");
2897 else
2898 $log[] = array ('code' => 'error', 'message' => "Could not add '${cname}'");
2899 }
2900 }
2901 printLog ($log);
e673ee24
DO
2902
2903 // Render a form for the next.
2904 $typelist = getObjectTypeList();
4c330a14 2905 $typelist[0] = 'select type...';
7f791d1d 2906
f60bb422
DO
2907 startPortlet ('Distinct types, same tags');
2908 $max = getConfigVar ('MASSCOUNT');
20c901a7 2909 echo "<form name=fastform method=post action='${root}?page=${pageno}&tab=${tabno}'>";
e673ee24 2910 echo '<table border=0 align=center>';
f60bb422
DO
2911 echo "<tr><th>Object type</th><th>Common name</th><th>Visible label</th>";
2912 echo "<th>Asset tag</th><th>Barcode</th><th>Tags</th></tr>\n";
7f791d1d 2913 // If a user forgot to select object type on input, we keep his
e673ee24 2914 // previous input in the form.
9c0b0016 2915 for ($i = 0; $i < $max; $i++)
e673ee24 2916 {
7f791d1d 2917 echo '<tr><td>';
e7ade6bf
DO
2918 // Don't employ DEFAULT_OBJECT_TYPE to avoid creating ghost records for pre-selected empty rows.
2919 printSelect ($typelist, "${i}_object_type_id", 0);
e673ee24
DO
2920 echo '</td>';
2921 echo "<td><input type=text size=30 name=${i}_object_name";
ce4d1a79 2922 if ($keepvalues1 and isset ($name[$i]) and (!isset ($type_id[$i]) or $type_id[$i] == 0))
e673ee24
DO
2923 echo " value='${name[$i]}'";
2924 echo "></td>";
2925 echo "<td><input type=text size=30 name=${i}_object_label";
ce4d1a79 2926 if ($keepvalues1 and isset ($label[$i]) and (!isset ($type_id[$i]) or $type_id[$i] == 0))
e673ee24
DO
2927 echo " value='${label[$i]}'";
2928 echo "></td>";
2929 echo "<td><input type=text size=20 name=${i}_object_asset_no";
ce4d1a79 2930 if ($keepvalues1 and isset ($asset_no[$i]) and (!isset ($type_id[$i]) or $type_id[$i] == 0))
e673ee24
DO
2931 echo " value='${asset_no[$i]}'";
2932 echo "></td>";
2933 echo "<td><input type=text size=10 name=${i}_object_barcode";
ce4d1a79 2934 if ($keepvalues1 and isset ($barcode[$i]) and (!isset ($type_id[$i]) or $type_id[$i] == 0))
e673ee24
DO
2935 echo " value='${barcode[$i]}'";
2936 echo "></td>";
f60bb422
DO
2937 if ($i == 0)
2938 {
2939 echo "<td valign=top rowspan=${max}>";
2940 renderTagSelect();
2941 echo "</td>\n";
2942 }
e673ee24 2943 echo "</tr>\n";
e673ee24 2944 }
216c84bb 2945 echo "<tr><td class=submit colspan=5><input type=submit name=got_fast_data value='Go!'></td></tr>\n";
e673ee24
DO
2946 echo "</form></table>\n";
2947 finishPortlet();
7f791d1d 2948
f60bb422 2949 startPortlet ('Same type, same tags');
20c901a7 2950 echo "<form name=veryfastform method=post action='${root}?page=${pageno}&tab=${tabno}'>";
f60bb422
DO
2951 echo "<table border=0 align=center><tr><th>names</th><th>type</th></tr>";
2952 echo "<tr><td rowspan=3><textarea name=namelist cols=40 rows=25>\n";
ce4d1a79 2953 if ($keepvalues2 and $global_type_id == 0)
7f791d1d 2954 echo $_REQUEST['namelist'];
f60bb422
DO
2955 echo "</textarea></td><td valign=top>";
2956 printSelect ($typelist, "global_type_id", getConfigVar ('DEFAULT_OBJECT_TYPE'));
2957 echo "</td></tr>";
2958 echo "<tr><th>Tags</th></tr>";
2959 echo "<tr><td valign=top>";
2960 renderTagSelect();
2961 echo "</td></tr>";
2962 echo "<tr><td colspan=2><input type=submit name=got_very_fast_data value='Go!'></td></tr></table>\n";
2963 echo "</form>\n";
7f791d1d 2964 finishPortlet();
e673ee24
DO
2965}
2966
2967function printGreeting ()
2968{
9318d2ef 2969 global $root, $remote_username, $accounts, $root;
e673ee24 2970 $account = $accounts[$remote_username];
9318d2ef
DO
2971 $person = "<a href='${root}?page=myaccount&tab=default'>";
2972 $person .= empty ($account['user_realname']) ? $account['user_name'] : $account['user_realname'];
2973 $person .= '</a>';
7056988c 2974 echo "Hello, ${person}. This is RackTables " . CODE_VERSION . ". Click <a href='${root}?logout'>here</a> to logout.";
e673ee24
DO
2975}
2976
2977function renderSearchResults ()
2978{
2979 global $remote_username, $root;
2980 $terms = trim ($_REQUEST['q']);
2981 if (empty ($terms))
2982 {
591ff2c4 2983 showError ('Search string cannot be empty.', __FUNCTION__);
e673ee24
DO
2984 return;
2985 }
54522168 2986 if (!permitted ('objects', 'default'))
e673ee24 2987 {
591ff2c4 2988 showError ('You are not authorized for viewing information about objects.', __FUNCTION__);
e673ee24
DO
2989 return;
2990 }
ea5fc465 2991 $nhits = 0;
e673ee24
DO
2992 // If we search for L2 address, we can either find one or find none.
2993 if
2994 (
2995 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
2996 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
2997 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
2998 // STP bridge ID: bridge priotity + port MAC address. Cut off first 4 chars and look for MAC address.
2999 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
3000 )
3001 // Search for L2 address.
3002 {
3ec29bf4
DO
3003 $terms = str_replace ('.', '', $terms);
3004 $terms = str_replace (':', '', $terms);
ea5fc465 3005 $terms = substr ($terms, -12);
e673ee24
DO
3006 $result = searchByl2address ($terms);
3007 if ($result !== NULL)
3008 {
ea5fc465
DO
3009 $nhits++;
3010 $lasthit = 'port';
3011 $summary['port'][] = $result;
e673ee24 3012 }
e673ee24
DO
3013 }
3014 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))
3015 // Search for IP address.
3016 {
bb0a44e9 3017 if (NULL !== getIPv4AddressNetworkId ($terms))
e673ee24 3018 {
ea5fc465 3019 $nhits++;
f3d0cb20
DO
3020 $lasthit = 'ipv4addressbydq';
3021 $summary['ipv4addressbydq'][] = $terms;
e673ee24 3022 }
e673ee24
DO
3023 }
3024 else
ea5fc465 3025 // Search for objects, addresses, networks, virtual services and RS pools by their description.
e673ee24 3026 {
ea5fc465
DO
3027 $tmp = getObjectSearchResults ($terms);
3028 if (count ($tmp))
e673ee24 3029 {
ea5fc465
DO
3030 $nhits += count ($tmp);
3031 $lasthit = 'object';
3032 $summary['object'] = $tmp;
e673ee24 3033 }
ea5fc465
DO
3034 $tmp = getIPv4AddressSearchResult ($terms);
3035 if (count ($tmp))
e673ee24 3036 {
ea5fc465 3037 $nhits += count ($tmp);
f3d0cb20
DO
3038 $lasthit = 'ipv4addressbydescr';
3039 $summary['ipv4addressbydescr'] = $tmp;
ea5fc465
DO
3040 }
3041 $tmp = getIPv4PrefixSearchResult ($terms);
3042 if (count ($tmp))
3043 {
3044 $nhits += count ($tmp);
3045 $lasthit = 'ipv4network';
3046 $summary['ipv4network'] = $tmp;
3047 }
05411ccd
DO
3048 $tmp = getIPv4RSPoolSearchResult ($terms);
3049 if (count ($tmp))
3050 {
3051 $nhits += count ($tmp);
3052 $lasthit = 'ipv4rspool';
3053 $summary['ipv4rspool'] = $tmp;
3054 }
3055 $tmp = getIPv4VServiceSearchResult ($terms);
3056 if (count ($tmp))
3057 {
3058 $nhits += count ($tmp);
3059 $lasthit = 'ipv4vs';
3060 $summary['ipv4vs'] = $tmp;
3061 }
6a88e734
DO
3062 $tmp = getAccountSearchResult ($terms);
3063 if (count ($tmp))
3064 {
3065 $nhits += count ($tmp);
3066 $lasthit = 'user';
3067 $summary['user'] = $tmp;
3068 }
e1ae3fb4
AD
3069 $tmp = getFileSearchResult ($terms);
3070 if (count ($tmp))
3071 {
3072 $nhits += count ($tmp);
3073 $lasthit = 'file';
3074 $summary['file'] = $tmp;
3075 }
ea5fc465
DO
3076 }
3077 if ($nhits == 0)
3078 echo "<center><h2>Nothing found for '${terms}'</h2></center>";
3079 elseif ($nhits == 1)
3080 {
3081 $record = current ($summary[$lasthit]);
3082 switch ($lasthit)
3083 {
3084 case 'port':
3085 echo "<script language='Javascript'>document.location='${root}?page=object";
3086 echo "&hl_port_id=" . $record['port_id'];
3087 echo "&object_id=" . $record['object_id'] . "';//</script>";
3088 break;
f3d0cb20
DO
3089 case 'ipv4addressbydq':
3090 $parentnet = getIPv4AddressNetworkId ($record);
3091 if ($parentnet !== NULL)
e1ae3fb4 3092 echo "<script language='Javascript'>document.location='${root}?page=ipv4net&tab=default&id=${parentnet}&hl_ipv4_addr=${record}';//</script>";
f3d0cb20
DO
3093 else
3094 echo "<script language='Javascript'>document.location='${root}?page=ipaddress&ip=${record}';//</script>";
ea5fc465 3095 break;
f3d0cb20
DO
3096 case 'ipv4addressbydescr':
3097 $parentnet = getIPv4AddressNetworkId ($record['ip']);
3098 if ($parentnet !== NULL)
e1ae3fb4 3099 echo "<script language='Javascript'>document.location='${root}?page=ipv4net&tab=default&id=${parentnet}&hl_ipv4_addr=${record['ip']}';//</script>";
f3d0cb20
DO
3100 else
3101 echo "<script language='Javascript'>document.location='${root}?page=ipaddress&ip=${record['ip']}';//</script>";
ea5fc465
DO
3102 break;
3103 case 'ipv4network':
e1ae3fb4 3104 echo "<script language='Javascript'>document.location='${root}?page=ipv4net";
ea5fc465
DO
3105 echo "&id=${record['id']}";
3106 echo "';//</script>";
3107 break;
3108 case 'object':
3109 echo "<script language='Javascript'>document.location='${root}?page=object&object_id=${record['id']}';//</script>";
3110 break;
05411ccd 3111 case 'ipv4rspool':
e1ae3fb4 3112 echo "<script language='Javascript'>document.location='${root}?page=ipv4rspool&pool_id=${record['pool_id']}';//</script>";
05411ccd
DO
3113 break;
3114 case 'ipv4vs':
49fb2686 3115 echo "<script language='Javascript'>document.location='${root}?page=ipv4vs&vs_id=${record['id']}';//</script>";
05411ccd 3116 break;
6a88e734
DO
3117 case 'user':
3118 echo "<script language='Javascript'>document.location='${root}?page=user&user_id=${record['user_id']}';//</script>";
3119 break;
e1ae3fb4
AD
3120 case 'file':
3121 echo "<script language='Javascript'>document.location='${root}?page=file&file_id=${record['id']}';//</script>";
3122 break;
ea5fc465
DO
3123 }
3124 return;
3125 }
3126 else
3127 {
3128 global $nextorder;
3129 $order = 'odd';
3130 echo "<center><h2>${nhits} result(s) found for '${terms}'</h2></center>";
3131 foreach ($summary as $where => $what)
3132 switch ($where)
e673ee24 3133 {
ea5fc465 3134 case 'object':
06adfe89 3135 startPortlet ("<a href='${root}?page=objects'>Objects</a>");
ea5fc465 3136 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
e1ae3fb4 3137 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>Barcode</th></tr>';
ea5fc465
DO
3138 foreach ($what as $obj)
3139 {
2b3d64c5
DO
3140 $tags = loadRackObjectTags ($obj['id']);
3141 echo "<tr class=row_${order} valign=top><td class=tdleft><a href=\"${root}?page=object&object_id=${obj['id']}\">${obj['dname']}</a>";
3142 if (count ($tags))
3143 echo '<br><small>' . serializeTags ($tags) . '</small>';
3144 echo "</td><td>${obj['label']}</td>";
ea5fc465
DO
3145 echo "<td>${obj['asset_no']}</td>";
3146 echo "<td>${obj['barcode']}</td></tr>";
3147 $order = $nextorder[$order];
3148 }
3149 echo '</table>';
3150 finishPortlet();
3151 break;
3152 case 'ipv4network':
06adfe89 3153 startPortlet ("<a href='${root}?page=ipv4space'>IPv4 networks</a>");
ea5fc465 3154 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
e1ae3fb4 3155 echo '<tr><th>Network</th><th>Name/tags</th></tr>';
71287f1c 3156 foreach ($what as $netinfo)
ea5fc465 3157 {
71287f1c
DO
3158 echo "<tr class=row_${order} valign=top>";
3159 printIPv4NetInfoTDs ($netinfo);
3160 echo "</tr>\n";
ea5fc465
DO
3161 $order = $nextorder[$order];
3162 }
3163 echo '</table>';
3164 finishPortlet();
3165 break;
f3d0cb20 3166 case 'ipv4addressbydescr':
ea5fc465
DO
3167 startPortlet ('IPv4 addresses');
3168 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
f3d0cb20 3169 // FIXME: address, parent network, routers (if extended view is enabled)
e1ae3fb4 3170 echo '<tr><th>Address</th><th>Description</th></tr>';
ea5fc465
DO
3171 foreach ($what as $addr)
3172 {
f3d0cb20
DO
3173 echo "<tr class=row_${order}><td class=tdleft>";
3174 $parentnet = getIPv4AddressNetworkId ($addr['ip']);
3175 if ($parentnet !== NULL)
e1ae3fb4 3176 echo "<a href='${root}?page=ipv4net&tab=default&id=${parentnet}&hl_ipv4_addr=${addr['ip']}'>${addr['ip']}</a></td>";
f3d0cb20
DO
3177 else
3178 echo "<a href='${root}?page=ipaddress&ip=${addr['ip']}'>${addr['ip']}</a></td>";
ea5fc465
DO
3179 echo "<td class=tdleft>${addr['name']}</td></tr>";
3180 $order = $nextorder[$order];
3181 }
3182 echo '</table>';
3183 finishPortlet();
3184 break;
05411ccd 3185 case 'ipv4rspool':
ee437dab 3186 startPortlet ("<a href='${root}?page=ipv4rsplist'>RS pools</a>");
05411ccd
DO
3187 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
3188 foreach ($what as $rspool)
3189 {
e1ae3fb4 3190 echo "<tr class=row_${order}><td class=tdleft><a href='${root}?page=ipv4rspool&pool_id=${rspool['pool_id']}'>";
05411ccd
DO
3191 echo buildRSPoolName ($rspool);
3192 echo "</a></td></tr>";
3193 $order = $nextorder[$order];
3194 }
3195 echo '</table>';
3196 finishPortlet();
3197 break;
3198 case 'ipv4vs':
a239e016 3199 startPortlet ("<a href='${root}?page=ipv4vslist'>Virtual services</a>");
05411ccd 3200 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
e1ae3fb4 3201 echo '<tr><th>VS</th><th>Description</th></tr>';
05411ccd
DO
3202 foreach ($what as $vs)
3203 {
49fb2686 3204 echo "<tr class=row_${order}><td class=tdleft><a href='${root}?page=ipv4vs&vs_id=${vs['id']}'>";
05411ccd 3205 echo buildVServiceName ($vs);
6a88e734
DO
3206 echo "</a></td><td class=tdleft>${vs['name']}</td></tr>";
3207 $order = $nextorder[$order];
3208 }
3209 echo '</table>';
3210 finishPortlet();
3211 break;
3212 case 'user':
3213 startPortlet ("<a href='${root}?page=userlist'>Users</a>");
3214 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
e1ae3fb4 3215 echo '<tr><th>Username</th><th>Real Name</th></tr>';
6a88e734
DO
3216 foreach ($what as $item)
3217 {
3218 echo "<tr class=row_${order}><td class=tdleft><a href='${root}?page=user&user_id=${item['user_id']}'>";
3219 echo $item['user_name'];
3220 echo "</a></td><td class=tdleft>${item['user_realname']}</td></tr>";
05411ccd
DO
3221 $order = $nextorder[$order];
3222 }
3223 echo '</table>';
3224 finishPortlet();
3225 break;
e1ae3fb4
AD
3226 case 'file':
3227 startPortlet ("<a href='${root}?page=files'>Files</a>");
3228 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
3229 echo '<tr><th>Name</th><th>Comment</th></tr>';
3230 foreach ($what as $item)
3231 {
3232 echo "<tr class=row_${order}><td class=tdleft><a href='${root}?page=file&file_id=${item['id']}'>";
3233 echo $item['name'];
3234 echo "</a></td><td class=tdleft>${item['comment']}</td></tr>";
3235 $order = $nextorder[$order];
3236 }
3237 echo '</table>';
3238 finishPortlet();
3239 break;
e673ee24 3240 }
e673ee24
DO
3241 }
3242}
3243
3244// This function prints a table of checkboxes to aid the user in toggling mount atoms
3245// from one state to another. The first argument is rack data as
3246// produced by getRackData(), the second is the value used for the 'unckecked' state
3247// and the third is the value used for 'checked' state.
3248// Usage contexts:
3249// for mounting an object: printAtomGrid ($data, 'F', 'T')
3250// for changing rack design: printAtomGrid ($data, 'A', 'F')
3251// for adding rack problem: printAtomGrid ($data, 'F', 'U')
3252// for adding object problem: printAtomGrid ($data, 'T', 'W')
3253
3254function renderAtomGrid ($data)
3255{
3256 $rack_id = $data['id'];
3257 for ($unit_no = $data['height']; $unit_no > 0; $unit_no--)
3258 {
3259 echo "<tr><th>${unit_no}</th>";
3260 for ($locidx = 0; $locidx < 3; $locidx++)
3261 {
3262 $state = $data[$unit_no][$locidx]['state'];
3263 echo "<td class=state_${state}";
3264 if (isset ($data[$unit_no][$locidx]['hl']))
3265 echo $data[$unit_no][$locidx]['hl'];
3266 echo ">";
3267 if (!($data[$unit_no][$locidx]['enabled'] === TRUE))
3268 echo '<input type=checkbox disabled>';
3269 else
3270 echo "<input type=checkbox" . $data[$unit_no][$locidx]['checked'] . " name=atom_${rack_id}_${unit_no}_${locidx}>";
3271 echo '</td>';
3272 }
3273 echo "</tr>\n";
3274 }
3275}
3276
59427701 3277function renderUserList ()
e673ee24 3278{
9048d42b 3279 global $nextorder, $accounts, $root, $pageno;
59427701
DO
3280 echo "<table border=0 class=objectview>\n";
3281 echo "<tr><td class=pcleft>";
e673ee24
DO
3282 startPortlet ('User accounts');
3283 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
3284 echo "<tr><th class=tdleft>Username</th><th class=tdleft>Real name</th></tr>";
3285 $order = 'odd';
59427701 3286 $tagfilter = getTagFilter();
11c8e4be 3287 foreach (getUserAccounts ($tagfilter, getTFMode()) as $user)
e673ee24 3288 {
9048d42b
DO
3289 echo "<tr class=row_${order} valign=top><td class=tdleft><a href='${root}?page=user&user_id=${user['user_id']}'>";
3290 echo "${user['user_name']}</a>";
3291 $usertags = loadUserTags ($user['user_id']);
3292 if (count ($usertags))
3293 echo '<br><small>' . serializeTags ($usertags, "${root}?page=${pageno}&tab=default&") . '</small>';
3294 echo "</td><td class=tdleft>${user['user_realname']}</td></li>";
e673ee24
DO
3295 $order = $nextorder[$order];
3296 }
3297 echo '</table>';
3298 finishPortlet();
59427701
DO
3299 echo '</td><td class=pcright>';
3300 renderTagFilterPortlet ($tagfilter, 'user');
3301 echo "</td></tr></table>\n";
e673ee24
DO
3302}
3303
59427701 3304function renderUserListEditor ()
e673ee24 3305{
39b4abd0
DO
3306 function printNewItemTR ()
3307 {
3308 printOpFormIntro ('createUser');
3309 echo "<tr><td>&nbsp;</td><td><input type=text size=16 name=username tabindex=100></td>\n";
3310 echo "<td><input type=text size=24 name=realname tabindex=101></td>";
3311 echo "<td><input type=password size=64 name=password tabindex=102></td><td>";
3312 printImageHREF ('create', 'Add new account', TRUE, 103);
3313 echo "</td></tr></form>";
3314 }
e673ee24
DO
3315 global $root, $pageno, $tabno, $accounts;
3316 startPortlet ('User accounts');
3317 showMessageOrError();
3318 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
623457f8 3319 echo "<tr><th>status (click to change)</th><th>Username</th><th>Real name</th><th>Password</th><th>&nbsp;</th></tr>\n";
39b4abd0
DO
3320 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
3321 printNewItemTR();
e673ee24
DO
3322 foreach ($accounts as $account)
3323 {
7056988c
DO
3324 printOpFormIntro ('updateUser', array ('user_id' => $account['user_id']));
3325 echo "<tr><td>";
e673ee24
DO
3326 if ($account['user_enabled'] == 'yes' && $account['user_id'] != 1)
3327 {
59427701 3328 echo "<a href='${root}process.php?op=disableUser&page=${pageno}&tab=${tabno}&user_id=${account['user_id']}'>";
e673ee24
DO
3329 printImageHREF ('blockuser', 'disable account');
3330