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