r2223 - introduce and use ADDNEW_AT_TOP option
[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>";
1039 printImageHREF ('add', '', TRUE, 104);
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";
1055 echo "<td colspan=4>&nbsp;</td></tr></form>";
1056 }
e673ee24
DO
1057 global $root, $pageno, $tabno;
1058 if ($object_id <= 0)
1059 {
591ff2c4 1060 showError ('Invalid object_id', __FUNCTION__);
e673ee24
DO
1061 return;
1062 }
1063 showMessageOrError();
1064 startPortlet ('Ports and interfaces');
1065 $ports = getObjectPortsAndLinks ($object_id);
1066 usort($ports, 'sortByName');
1067 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
1068 echo "<tr><th>&nbsp;</th><th>Local name</th><th>Visible label</th><th>Port type</th><th>L2 address</th>";
1069 echo "<th>Rem. object</th><th>Rem. port</th><th>(Un)link or (un)reserve</th><th>&nbsp;</th></tr>\n";
39b4abd0
DO
1070 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
1071 printNewItemTR();
e673ee24
DO
1072 foreach ($ports as $port)
1073 {
7056988c 1074 printOpFormIntro ('editPort', array ('port_id' => $port['id']));
e673ee24
DO
1075 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']}'>";
1076 printImageHREF ('delete', 'Unlink and Delete this port');
1077 echo "</a></td>\n";
1078 echo "<td><input type=text name=name value='${port['name']}' size=8></td>";
1079 echo "<td><input type=text name=label value='${port['label']}' size=24></td>";
1080 echo "<td>${port['type']}</td>\n";
1081 echo "<td><input type=text name=l2address value='${port['l2address']}'></td>\n";
1082 if ($port['remote_object_id'])
1083 {
1084 echo "<td><a href='${root}?page=object&object_id=${port['remote_object_id']}'>${port['remote_object_name']}</a></td>";
1085 echo "<td>${port['remote_name']}</td>";
1086 echo "<td><a href='${root}process.php?op=unlinkPort&page=${pageno}&tab=${tabno}&port_id=${port['id']}&object_id=$object_id&port_name=";
1087 echo urlencode ($port['name']);
1088 echo "&remote_port_name=${port['remote_name']}&remote_object_name=${port['remote_object_name']}'>";
39be655e 1089 printImageHREF ('clear', 'Unlink this port');
e673ee24
DO
1090 echo "</a></td>";
1091 }
1092 elseif (!empty ($port['reservation_comment']))
1093 {
1094 echo "<td><b>Reserved;</b></td>";
1095 echo "<td><input type=text name=reservation_comment value='${port['reservation_comment']}'></td>";
1096 echo "<td><a href='${root}process.php?op=useup&page=${pageno}&tab=${tabno}&port_id=${port['id']}&object_id=${object_id}'>";
39be655e 1097 printImageHREF ('clear', 'Use up this port');
e673ee24
DO
1098 echo "</a></td>";
1099 }
1100 else
1101 {
1102 echo "<td>&nbsp;</td><td>&nbsp;</td>";
1103 echo "<td>";
1104 echo "<a href='javascript:;' onclick='window.open(\"${root}link_helper.php?port=${port['id']}&type=${port['type_id']}&object_id=$object_id&port_name=";
1105 echo urlencode ($port['name']);
1106 echo "\",\"findlink\",\"height=700, width=400, location=no, menubar=no, resizable=yes, scrollbars=no, status=no, titlebar=no, toolbar=no\");'>";
1107 printImageHREF ('link', 'Link this port');
1108 echo "</a> <input type=text name=reservation_comment>";
1109 echo "</td>\n";
1110 }
5bbbeaa2
DO
1111 echo "<td>";
1112 printImageHREF ('save', 'Save changes', TRUE);
1113 echo "</td></form></tr>\n";
e673ee24 1114 }
39b4abd0
DO
1115 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
1116 printNewItemTR();
e673ee24
DO
1117 echo "</table><br>\n";
1118 finishPortlet();
1119
1120 startPortlet ('Add/update multiple ports');
7056988c 1121 printOpFormIntro ('addMultiPorts');
e673ee24 1122 echo 'Format: <select name=format>';
e673ee24
DO
1123 echo '<option value=c3600asy>Cisco 3600 async: sh line | inc TTY</option>';
1124 echo '<option value=fiwg selected>Foundry ServerIron/FastIron WorkGroup/Edge: sh int br</option>';
e673ee24 1125 echo '<option value=fisxii>Foundry FastIron SuperX/II4000: sh int br</option>';
351d4dbf 1126 echo '<option value=ssv1>SSV:&lt;interface name&gt; &lt;MAC address&gt;</option>';
e673ee24
DO
1127 echo "</select>";
1128 echo 'Default port type: ';
1129 echo "<select name=port_type>\n";
1130 foreach ($types as $typeid => $typename)
1131 {
1132 echo "<option value='${typeid}'";
1133 if ($typeid == $default_port_type)
1134 echo " selected";
1135 echo ">${typename}</option>\n";
1136 }
1137 echo "</select>";
1138 echo "<input type=submit value='Parse output'><br>\n";
1139 echo "<textarea name=input cols=100 rows=50></textarea><br>\n";
1140 echo '</form>';
1141 finishPortlet();
1142}
1143
72d8ced3 1144function renderIPv4ForObject ($object_id = 0)
e673ee24 1145{
39b4abd0
DO
1146 function printNewItemTR ()
1147 {
1148 global $aat;
1149 printOpFormIntro ('addIPv4Allocation');
1150 echo "<tr><td>";
1151 printImageHREF ('add', 'Allocate new address', TRUE, 99);
1152 echo "</td>";
1153 echo "<td class=tdleft><input type='text' size='10' name='bond_name' tabindex=100></td>\n";
1154 echo "<td class=tdleft><input type=text name='ip' tabindex=101></td>\n";
1155 echo "<td colspan=3>&nbsp;</td><td>";
1156 printSelect ($aat, 'bond_type');
1157 echo "</td><td colspan=2>&nbsp;</td></tr></form>";
1158 }
52c836b1 1159 global $root, $pageno, $tabno, $aat;
e673ee24
DO
1160 if ($object_id <= 0)
1161 {
591ff2c4 1162 showError ('Invalid object_id', __FUNCTION__);
e673ee24
DO
1163 return;
1164 }
1165 showMessageOrError();
72d8ced3 1166 startPortlet ('Allocations');
85970da2 1167 $alloclist = getObjectIPv4Allocations ($object_id);
e673ee24 1168 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
79e45b4c
DO
1169 echo '<tr><th>&nbsp;</th><th>OS interface</th><th>IP address</th>';
1170 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
1171 echo '<th colspan=2>network</th><th>routed by</th>';
1172 echo '<th>type</th><th>misc</th><th>&nbsp</th></tr>';
09620506 1173
39b4abd0
DO
1174 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
1175 printNewItemTR();
85970da2 1176 foreach ($alloclist as $dottedquad => $alloc)
e673ee24 1177 {
85970da2 1178 $class = $alloc['addrinfo']['class'];
79e45b4c
DO
1179 $netid = getIPv4AddressNetworkId ($dottedquad);
1180 $netinfo = getIPv4NetworkInfo ($netid);
b6b87070 1181 loadIPv4AddrList ($netinfo);
85970da2 1182 printOpFormIntro ('updIPv4Allocation', array ('ip' => $dottedquad));
79e45b4c 1183 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
1184 printImageHREF ('delete', 'Delete this IPv4 address');
1185 echo "</a></td>";
85970da2 1186 echo "<td class=tdleft><input type='text' name='bond_name' value='${alloc['osif']}' size=10></td>";
79e45b4c
DO
1187 echo "<td class=tdleft><a href='${root}?page=ipaddress&ip=${dottedquad}'>${dottedquad}</a>";
1188 if (getConfigVar ('EXT_IPV4_VIEW') != 'yes')
1189 {
1190 if (NULL === $netid)
1191 $suffix = '/??';
1192 else
1193 echo '<small>/' . $netinfo['mask'] . '</small>';
1194 }
1195 echo '&nbsp;' . $aac[$alloc['type']];
1196 if (!empty ($alloc['addrinfo']['name']))
1197 echo '(' . niftyString ($alloc['addrinfo']['name']) . ')';
1198 echo '</td>';
1199 // FIXME: this a copy-and-paste from renderRackObject()
1200 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
1201 {
1202 if (NULL === $netid)
1203 echo '<td colspan=2>?</td>';
1204 else
1205 printIPv4NetInfoTDs ($netinfo);
1206 echo "<td class='${secondclass}'>";
1207 // FIXME: These cals are really heavy, replace them with a more appropriate dedicated function.
79e45b4c 1208 $newline = '';
b6b87070 1209 foreach (findRouters ($netinfo['addrlist']) as $router)
79e45b4c
DO
1210 {
1211 if ($router['id'] == $object_id)
1212 continue;
1213 echo $newline . $router['addr'] . ", <a href='${root}?page=object&object_id=${router['id']}&hl_ipv4_addr=${router['addr']}'>";
1214 echo (empty ($router['iface']) ? '' : $router['iface'] . '@') . $router['dname'] . '</a>';
1215 $routertags = loadRackObjectTags ($router['id']);
1216 if (count ($routertags))
1217 echo '<br><small>' . serializeTags ($routertags, "${root}?page=objects&tab=default&") . '</small>';
1218 $newline = '<br>';
1219 }
1220 echo '</td>';
1221 }
1222 echo '<td>';
85970da2 1223 printSelect ($aat, 'bond_type', $alloc['type']);
e673ee24 1224 echo "</td><td>";
85970da2 1225 $prefix = '';
4940e4d5 1226 if ($alloc['addrinfo']['reserved'] == 'yes')
e673ee24 1227 {
85970da2
DO
1228 echo $prefix . '<strong>RESERVED</strong>';
1229 $prefix = '; ';
e673ee24 1230 }
85970da2 1231 foreach ($alloc['addrinfo']['allocs'] as $allocpeer)
e673ee24 1232 {
85970da2
DO
1233 if ($allocpeer['object_id'] == $object_id)
1234 continue;
1235 echo $prefix . "<a href='${root}?page=object&object_id=${allocpeer['object_id']}'>";
1236 if (!empty ($allocpeer['osif']))
1237 echo $allocpeer['osif'] . '@';
1238 echo $allocpeer['object_name'] . '</a>';
1239 $prefix = '; ';
e673ee24 1240 }
d54b9495
DO
1241 echo "</td><td>";
1242 printImageHREF ('save', 'Save changes', TRUE);
1243 echo "</td></form></tr>\n";
e673ee24 1244 }
39b4abd0
DO
1245 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
1246 printNewItemTR();
e673ee24 1247
09620506 1248 echo "</table><br>\n";
e673ee24
DO
1249 finishPortlet();
1250
1251}
1252
baf37d01
DO
1253// Log structure versions:
1254// 1: the whole structure is a list of code-message pairs
1255// 2 and later: there's a "v" field set, which indicates the version
1256// 2: there's a "m" list set to hold message code and optional arguments
e673ee24
DO
1257function printLog ($log)
1258{
baf37d01
DO
1259 switch (TRUE)
1260 {
1261 case !isset ($log['v']):
ebb5441d 1262 case $log['v'] == 1:
baf37d01 1263 foreach ($log as $key => $record)
ebb5441d 1264 if ($key !== 'v')
baf37d01
DO
1265 echo "<div class=msg_${record['code']}>${record['message']}</div>";
1266 break;
1267 case $log['v'] == 2:
1268 $msginfo = array
1269 (
ebb5441d 1270 0 => array ('code' => 'success', 'format' => 'Success: %s'),
baf37d01
DO
1271 1 => array ('code' => 'success', 'format' => '%u new records done, %u already existed'),
1272 2 => array ('code' => 'success', 'format' => 'NATv4 rule was successfully added.'),
1273 3 => array ('code' => 'success', 'format' => 'NATv4 rule was successfully deleted.'),
1274 4 => array ('code' => 'success', 'format' => 'NATv4 rule was successfully updated'),
1275 5 => array ('code' => 'success', 'format' => 'Port %s was added successfully'),
1276 6 => array ('code' => 'success', 'format' => 'Port %s was updated successfully'),
1277 7 => array ('code' => 'success', 'format' => 'Port %s was deleted successfully'),
1278 8 => array ('code' => 'success', 'format' => 'Port %s successfully linked with port %s at object %s'),
1279 9 => array ('code' => 'success', 'format' => 'Port %s was successfully unlinked from %s@%s'),
1280 10 => array ('code' => 'success', 'format' => 'Added %u ports, updated %u ports, encountered %u errors.'),
1281 11 => array ('code' => 'success', 'format' => 'Reservation removed.'),
1282 12 => array ('code' => 'success', 'format' => 'allocation updated'),
1283 13 => array ('code' => 'success', 'format' => 'allocated'),
1284 14 => array ('code' => 'success', 'format' => 'deallocated'),
1285 15 => array ('code' => 'success', 'format' => 'Reset succeeded.'),
1286 16 => array ('code' => 'success', 'format' => 'Update done'),
1287 17 => array ('code' => 'success', 'format' => 'Update(s) succeeded.'),
1288 18 => array ('code' => 'success', 'format' => 'Load balancer was successfully added'),
1289 19 => array ('code' => 'success', 'format' => 'Load balancer was successfully deleted'),
1290 20 => array ('code' => 'success', 'format' => 'Load balancer info was successfully updated'),
1291 21 => array ('code' => 'success', 'format' => 'Generation complete'),
1292 22 => array ('code' => 'success', 'format' => 'Chained %u tags'),
1293 23 => array ('code' => 'success', 'format' => 'IPv4 prefix successfully added'),
1294 24 => array ('code' => 'success', 'format' => 'IPv4 prefix deleted'),
1295 25 => array ('code' => 'success', 'format' => 'IPv4 prefix updated'),
1296 26 => array ('code' => 'success', 'format' => '%u IP address(es) were successfully updated'),
1297 27 => array ('code' => 'success', 'format' => 'IPv4 address updated'),
1298 28 => array ('code' => 'success', 'format' => 'Virtual service was successfully created'),
1299 29 => array ('code' => 'success', 'format' => 'Virtual service was successfully deleted'),
1300 30 => array ('code' => 'success', 'format' => 'Virtual service was successfully updated'),
1301 31 => array ('code' => 'success', 'format' => 'RS pool was successfully created'),
1302 32 => array ('code' => 'success', 'format' => 'RS pool was successfully deleted'),
1303 33 => array ('code' => 'success', 'format' => 'RS pool was successfully updated'),
1304 34 => array ('code' => 'success', 'format' => 'Real server was successfully added'),
1305 35 => array ('code' => 'success', 'format' => 'Real server was successfully deleted'),
1306 36 => array ('code' => 'success', 'format' => 'Real server was successfully updated'),
1307 37 => array ('code' => 'success', 'format' => 'Successfully added %u real servers'),
1308 38 => array ('code' => 'success', 'format' => '%u real server(s) were successfully (de)activated'),
1309 39 => array ('code' => 'success', 'format' => 'User account %s updated.'),
1310 40 => array ('code' => 'success', 'format' => 'User account %s created.'),
1311 41 => array ('code' => 'success', 'format' => 'User account disabled.'),
1312 42 => array ('code' => 'success', 'format' => 'User account enabled.'),
1313 43 => array ('code' => 'success', 'format' => 'Saved successfully.'),
1314 44 => array ('code' => 'success', 'format' => '%s failures and %s successfull changes.'),
1315 45 => array ('code' => 'success', 'format' => "Attribute '%s' created."),
1316 46 => array ('code' => 'success', 'format' => 'Rename successful.'),
1317 47 => array ('code' => 'success', 'format' => 'Attribute was deleted.'),
1318 48 => array ('code' => 'success', 'format' => 'Supplement succeeded.'),
1319 49 => array ('code' => 'success', 'format' => 'Reduction succeeded.'),
1320 50 => array ('code' => 'success', 'format' => 'Reduction succeeded.'),
1321 51 => array ('code' => 'success', 'format' => 'Update succeeded.'),
1322 52 => array ('code' => 'success', 'format' => 'Supplement succeeded.'),
1323 53 => array ('code' => 'success', 'format' => 'Chapter was deleted.'),
1324 54 => array ('code' => 'success', 'format' => 'Chapter was updated.'),
1325 55 => array ('code' => 'success', 'format' => 'Chapter was added.'),
1326 56 => array ('code' => 'success', 'format' => 'Update succeeded.'),
1327 57 => array ('code' => 'success', 'format' => 'Reset complete'),
1328 58 => array ('code' => 'success', 'format' => "Successfully deleted tag ."),
1329 59 => array ('code' => 'success', 'format' => "Created tag '%s'."),
1330 60 => array ('code' => 'success', 'format' => "Updated tag '%s'."),
ebb5441d 1331 61 => array ('code' => 'success', 'format' => 'Password changed successfully.'),
24dcb9d8 1332 62 => array ('code' => 'success', 'format' => 'gw: %s'),
f0ff4930
DO
1333 63 => array ('code' => 'success', 'format' => '%u change request(s) have been processed'),
1334 64 => array ('code' => 'success', 'format' => 'Port %s@%s has been assigned to VLAN %u'),
f19c75d6 1335 65 => array ('code' => 'success', 'format' => "Added new rack '%s'"),
03e6ef01 1336 66 => array ('code' => 'success', 'format' => "File sent Ok via handler '%s'"),
abef7149 1337 67 => array ('code' => 'success', 'format' => "Tag rolling done, %u objects involved"),
0c2b7c4a 1338 68 => array ('code' => 'success', 'format' => "Updated rack '%s'"),
f0ff4930 1339
ebb5441d
DO
1340 100 => array ('code' => 'error', 'format' => 'Generic error: %s'),
1341 101 => array ('code' => 'error', 'format' => 'Port name cannot be empty'),
1342 102 => array ('code' => 'error', 'format' => "Error creating user account '%s'"),
1343 103 => array ('code' => 'error', 'format' => 'getHashByID() failed'),
1344 104 => array ('code' => 'error', 'format' => "Error updating user account '%s'"),
1345 105 => array ('code' => 'error', 'format' => 'Error enabling user account.'),
1346 106 => array ('code' => 'error', 'format' => 'Error disabling user account.'),
1347 107 => array ('code' => 'error', 'format' => 'Admin account cannot be disabled'),
1348 108 => array ('code' => 'error', 'format' => '%u failures and %u successfull changes.'),
1349 109 => array ('code' => 'error', 'format' => 'Update failed!'),
1350 110 => array ('code' => 'error', 'format' => 'Supplement failed!'),
1351 111 => array ('code' => 'error', 'format' => 'Reduction failed!'),
1352 112 => array ('code' => 'error', 'format' => 'Error adding chapter.'),
1353 113 => array ('code' => 'error', 'format' => 'Error updating chapter.'),
1354 114 => array ('code' => 'error', 'format' => 'Error deleting chapter.'),
1355 115 => array ('code' => 'error', 'format' => 'Error renaming attribute.'),
1356 116 => array ('code' => 'error', 'format' => 'Error creating attribute.'),
1357 117 => array ('code' => 'error', 'format' => 'Error deleting attribute.'),
1358 118 => array ('code' => 'error', 'format' => 'Supplement failed!'),
1359 119 => array ('code' => 'error', 'format' => 'Reduction failed!'),
1360 120 => array ('code' => 'error', 'format' => 'Reset failed!'),
1361 121 => array ('code' => 'error', 'format' => 'commitUpdateObject() failed'),
1362 122 => array ('code' => 'error', 'format' => 'One or more update(s) failed!'),
1363 123 => array ('code' => 'error', 'format' => 'Cannot process submitted data: unknown format code.'),
1364 124 => array ('code' => 'error', 'format' => 'Error removing reservation!'),
1365 125 => array ('code' => 'error', 'format' => "Update failed with error: '%s'"),
1366 126 => array ('code' => 'error', 'format' => 'addRStoRSPool() failed'),
1367 127 => array ('code' => 'error', 'format' => 'Added %u real servers and encountered %u errors'),
1368 128 => array ('code' => 'error', 'format' => 'commitDeleteRS() failed'),
1369 129 => array ('code' => 'error', 'format' => 'commitDeleteLB() failed'),
1370 130 => array ('code' => 'error', 'format' => 'commitDeleteVS() failed'),
1371 131 => array ('code' => 'error', 'format' => 'invalid format requested'),
1372 132 => array ('code' => 'error', 'format' => 'invalid protocol'),
1373 133 => array ('code' => 'error', 'format' => 'commitUpdateRS() failed'),
1374 134 => array ('code' => 'error', 'format' => 'commitUpdateLB() failed'),
1375 135 => array ('code' => 'error', 'format' => 'commitUpdateVS() failed'),
1376 136 => array ('code' => 'error', 'format' => 'addLBtoRSPool() failed'),
1377 137 => array ('code' => 'error', 'format' => 'addLBtoRSPool() failed'),
1378 138 => array ('code' => 'error', 'format' => 'commitDeleteRSPool() failed'),
1379 139 => array ('code' => 'error', 'format' => 'commitUpdateRSPool() failed'),
1380 140 => array ('code' => 'error', 'format' => 'Encountered %u errors, (de)activated %u real servers'),
1381 141 => array ('code' => 'error', 'format' => 'Encountered %u errors, updated %u IP address(es)'),
1382 142 => array ('code' => 'error', 'format' => 'executeAutoPorts() failed'),
1383 143 => array ('code' => 'error', 'format' => 'Tried chaining %u tags, but experienced %u errors.'),
1384 144 => array ('code' => 'error', 'format' => "Error deleting tag: '%s'"),
1385 145 => array ('code' => 'error', 'format' => "Invalid tag name '%s'"),
1386 146 => array ('code' => 'error', 'format' => "Tag '%s' (or similar name) already exists"),
1387 147 => array ('code' => 'error', 'format' => "Could not create tag '%s' because of error '%s'"),
1388 148 => array ('code' => 'error', 'format' => "Could not update tag '%s' because of error '%s'"),
1389 149 => array ('code' => 'error', 'format' => 'Turing test failed'),
1390 150 => array ('code' => 'error', 'format' => 'Can only change password under DB authentication.'),
1391 151 => array ('code' => 'error', 'format' => 'Old password doesn\'t match.'),
1392 152 => array ('code' => 'error', 'format' => 'New passwords don\'t match.'),
1393 153 => array ('code' => 'error', 'format' => 'Password change failed.'),
1394 154 => array ('code' => 'error', 'format' => "Verification error: %s"),
1395 155 => array ('code' => 'error', 'format' => 'Save failed.'),
1396 156 => array ('code' => 'error', 'format' => 'getSwitchVLANs() failed'),
e81fb764 1397 157 => array ('code' => 'error', 'format' => 'operation not permitted'),
24dcb9d8
DO
1398 158 => array ('code' => 'error', 'format' => 'Ignoring malformed record #%u in form submit'),
1399 159 => array ('code' => 'error', 'format' => 'Permission denied moving port %s from VLAN%u to VLAN%u'),
1400 160 => array ('code' => 'error', 'format' => 'Invalid arguments'),
1401 161 => array ('code' => 'error', 'format' => 'Endpoint not found. Please either set FQDN attribute or assign an IP address to the object.'),
1402 162 => array ('code' => 'error', 'format' => 'More than one IP address is assigned to this object, please configure FQDN attribute.'),
1403 163 => array ('code' => 'error', 'format' => 'Failed to get any response from queryGateway() or the gateway died'),
c030232f 1404 164 => array ('code' => 'error', 'format' => 'Gateway failure: %s.'),
24dcb9d8
DO
1405 165 => array ('code' => 'error', 'format' => 'Gateway failure: malformed reply.'),
1406 166 => array ('code' => 'error', 'format' => 'gw: %s'),
f0ff4930
DO
1407 167 => array ('code' => 'error', 'format' => 'Could not find port %s'),
1408 168 => array ('code' => 'error', 'format' => 'Port %s is a trunk'),
1409 169 => array ('code' => 'error', 'format' => 'Failed to configure %s, connector returned code %u'),
5222f192 1410 170 => array ('code' => 'error', 'format' => 'There is no network for IP address "%s"'),
f19c75d6
DO
1411 171 => array ('code' => 'error', 'format' => "Failed creating rack '%s'. Already exists in this row?"),
1412 172 => array ('code' => 'error', 'format' => 'Malformed request'),
e5c4506d
DO
1413 173 => array ('code' => 'error', 'format' => "Invalid IPv4 prefix '%s'"),
1414 174 => array ('code' => 'error', 'format' => 'Bad IPv4 address'),
1415 175 => array ('code' => 'error', 'format' => 'Invalid netmask'),
1416 176 => array ('code' => 'error', 'format' => 'This network already exists'),
0c2b7c4a 1417 177 => array ('code' => 'error', 'format' => 'commitUpdateRack() failed'),
f0ff4930 1418
24dcb9d8
DO
1419 200 => array ('code' => 'warning', 'format' => 'generic warning: %s'),
1420 201 => array ('code' => 'warning', 'format' => 'nothing happened...'),
1421 202 => array ('code' => 'warning', 'format' => 'gw: %s'),
f0ff4930
DO
1422 203 => array ('code' => 'warning', 'format' => 'Port %s seems to be the first in VLAN %u at this switch.'),
1423 204 => array ('code' => 'warning', 'format' => 'Check uplink/downlink configuration for proper operation.'),
1424 205 => array ('code' => 'warning', 'format' => '%u change request(s) have been ignored'),
baf37d01
DO
1425 );
1426 // Handle the arguments. Is there any better way to do it?
1427 foreach ($log['m'] as $record)
1428 {
5222f192
DO
1429 if (!isset ($record['c']) or !isset ($msginfo[$record['c']]))
1430 {
1431 echo '<div class=msg_neutral>(this message was lost)</div>';
1432 continue;
1433 }
baf37d01
DO
1434 if (isset ($record['a']))
1435 switch (count ($record['a']))
1436 {
1437 case 1:
1438 $msgtext = sprintf
1439 (
1440 $msginfo[$record['c']]['format'],
1441 $record['a'][0]
1442 );
1443 break;
1444 case 2:
1445 $msgtext = sprintf
1446 (
1447 $msginfo[$record['c']]['format'],
1448 $record['a'][0],
1449 $record['a'][1]
1450 );
1451 break;
1452 case 3:
1453 $msgtext = sprintf
1454 (
1455 $msginfo[$record['c']]['format'],
1456 $record['a'][0],
1457 $record['a'][1],
1458 $record['a'][2]
1459 );
1460 break;
1461 case 4:
1462 default:
1463 $msgtext = sprintf
1464 (
1465 $msginfo[$record['c']]['format'],
1466 $record['a'][0],
1467 $record['a'][1],
1468 $record['a'][2],
1469 $record['a'][3]
1470 );
1471 break;
1472 }
1473 else
1474 $msgtext = $msginfo[$record['c']]['format'];
1475 echo '<div class=msg_' . $msginfo[$record['c']]['code'] . ">${msgtext}</div>";
1476 }
1477 break;
1478 default:
1479 echo '<div class=msg_error>' . __FUNCTION__ . ': internal error</div>';
1480 break;
1481 }
e673ee24
DO
1482}
1483
1484/*
1485The following conditions must be followed:
14861. We can mount onto free atoms only. This means: if any record for an atom
1487already exists in RackSpace, it can't be used for mounting.
14882. We can't unmount from 'W' atoms. Operator should review appropriate comments
1489and either delete them before unmounting or refuse to unmount the object.
1490*/
1491
1492// We extensively use $_REQUEST in the function.
7056988c 1493// FIXME: move related code into ophandler
e673ee24
DO
1494function renderRackSpaceForObject ($object_id = 0)
1495{
1496 if ($object_id <= 0)
1497 {
591ff2c4 1498 showError ('Invalid object_id', __FUNCTION__);
e673ee24
DO
1499 return;
1500 }
1501 $is_submit = isset ($_REQUEST['got_atoms']);
1502 $is_update = isset ($_REQUEST['rackmulti'][0]);
1503 $info = getObjectInfo ($object_id);
1504 if ($info == NULL)
1505 {
591ff2c4 1506 showError ('getObjectInfo() failed', __FUNCTION__);
e673ee24
DO
1507 return;
1508 }
1509 // Always process occupied racks plus racks chosen by user. First get racks with
1510 // already allocated rackspace...
1511 $workingRacksData = getResidentRacksData ($object_id);
1512 if ($workingRacksData === NULL)
1513 {
1514 print_r ($workingRacksData);
591ff2c4 1515 showError ('getResidentRacksData() failed', __FUNCTION__);
e673ee24
DO
1516 return;
1517 }
1518
1519 // ...and then add those chosen by user (if any).
1520 if ($is_update)
1521 foreach ($_REQUEST['rackmulti'] as $cand_id)
1522 {
1523 if (!isset ($workingRacksData[$cand_id]))
1524 {
1525 $rackData = getRackData ($cand_id);
1526 if ($rackData == NULL)
1527 {
591ff2c4 1528 showError ('getRackData() failed', __FUNCTION__);
e673ee24
DO
1529 return NULL;
1530 }
1531 $workingRacksData[$cand_id] = $rackData;
1532 }
1533 }
1534
1535 // Do it only once...
1536 foreach ($workingRacksData as &$rackData)
1537 applyObjectMountMask ($rackData, $object_id);
1538 // Now we workaround an old caveat: http://bugs.php.net/bug.php?id=37410
1539 unset ($rackData);
1540
1541 // Here we process form submit by trying to save all submitted info to database.
1542 if ($is_submit)
1543 {
1544 $oldMolecule = getMoleculeForObject ($object_id);
1545 $worldchanged = FALSE;
1546 $log = array();
1547 foreach ($workingRacksData as $rack_id => $rackData)
1548 {
1549 $logrecord = processGridForm ($rackData, 'F', 'T', $object_id);
1550 $log[] = $logrecord;
1551 if ($logrecord['code'] != 300)
1552 {
1553 $worldchanged = TRUE;
1554 // Reload our working copy after form processing.
1555 $rackData = getRackData ($rack_id);
1556 if ($rackData == NULL)
4d2e93f2 1557 $log[] = array ('code' => 500, 'message' => 'Working copy update failed in ', __FUNCTION__);
e673ee24
DO
1558 applyObjectMountMask ($rackData, $object_id);
1559 $workingRacksData[$rack_id] = $rackData;
1560 }
1561 }
1562 if ($worldchanged)
1563 {
1564 // Log a record.
1565 $newMolecule = getMoleculeForObject ($object_id);
1566 $oc = count ($oldMolecule);
1567 $nc = count ($newMolecule);
1568 $omid = $oc ? createMolecule ($oldMolecule) : 'NULL';
1569 $nmid = $nc ? createMolecule ($newMolecule) : 'NULL';
1570 global $remote_username;
1571 $comment = empty ($_REQUEST['comment']) ? 'NULL' : "'${_REQUEST['comment']}'";
1572 $query =
1573 "insert into MountOperation(object_id, old_molecule_id, new_molecule_id, user_name, comment) " .
1574 "values (${object_id}, ${omid}, ${nmid}, '${remote_username}', ${comment})";
1575 global $dbxlink;
1576 $result = $dbxlink->query ($query);
1577 if ($result == NULL)
1578 $log[] = array ('code' => 'error', 'message' => 'SQL query failed during history logging.');
1579 else
1580 $log[] = array ('code' => 'success', 'message' => 'History logged.');
1581 }
1582 printLog ($log);
1583 }
1584
1585 // This is the time for rendering.
1586 global $root, $pageno, $tabno;
1587 echo "<form id='racks' action='${root}'>";
1588 echo "<input type=hidden name=page value='${pageno}'>\n";
1589 echo "<input type=hidden name=tab value='${tabno}'>\n";
1590 echo "<input type=hidden name=object_id value='${object_id}'>\n";
1591 // Main layout starts.
1592 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0><tr>";
1593
1594 // Left portlet with rack list.
1595 echo "<td class=pcleft height='1%'>";
1596 startPortlet ('Racks');
1597 $allRacksData = getRacksForRow();
4b8d413e
DO
1598 if (count ($allRacksData) <= getConfigVar ('RACK_PRESELECT_THRESHOLD'))
1599 {
1600 foreach (array_keys ($allRacksData) as $rack_id)
1601 {
1602 $rackData = getRackData ($rack_id);
1603 if ($rackData == NULL)
1604 {
1605 showError ('getRackData() failed', __FUNCTION__);
1606 return NULL;
1607 }
1608 $workingRacksData[$rack_id] = $rackData;
1609 }
1610 foreach ($workingRacksData as &$rackData)
1611 applyObjectMountMask ($rackData, $object_id);
1612 unset ($rackData);
1613 }
1614 renderRackMultiSelect ('rackmulti[]', $allRacksData, array_keys ($workingRacksData));
e673ee24
DO
1615 echo "<br>";
1616 echo "<br>";
1617 finishPortlet();
1618 echo "</td>";
1619
1620 // Middle portlet with comment and submit.
1621 echo "<td class=pcleft>";
1622 startPortlet ('Comment');
1623 echo "<textarea name=comment rows=10 cols=40></textarea><br>\n";
1624 echo "<input type=submit value='Save' name=got_atoms>\n";
1625 echo "<br>";
1626 echo "<br>";
1627 finishPortlet();
1628 echo "</td>";
1629
1630 // Right portlet with rendered racks. If this form submit is not final, we have to
1631 // reflect the former state of the grid in current form.
1632 echo "<td class=pcright rowspan=2 height='1%'>";
1633 startPortlet ('Working copy');
1634 echo '<table border=0 cellspacing=10 align=center><tr>';
1635 foreach ($workingRacksData as $rack_id => $rackData)
1636 {
1637 // Order is important here: only original allocation is highlighted.
1638 highlightObject ($rackData, $object_id);
1639 markupAtomGrid ($rackData, 'T');
1640 // If we have a form processed, discard user input and show new database
1641 // contents.
1642 if (!$is_submit and $is_update)
1643 mergeGridFormToRack ($rackData);
1644 echo "<td valign=top>";
1645 echo "<center>\n<h2>${rackData['name']}</h2>\n";
1646 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
1647 echo "<tr><th width='10%'>&nbsp;</th><th width='20%'>Front</th>";
1648 echo "<th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
1649 renderAtomGrid ($rackData);
9b7468b7
DO
1650 echo "<tr><th width='10%'>&nbsp;</th><th width='20%'>Front</th>";
1651 echo "<th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
e673ee24
DO
1652 echo "</table></center>\n";
1653 echo '</td>';
1654 }
1655 echo "</tr></table>";
1656 finishPortlet();
1657 echo "</td>\n";
1658
1659 echo "</form>\n";
1660 echo "</tr></table>\n";
1661}
1662
1663function renderMolecule ($mdata, $object_id)
1664{
1665 // sort data out
1666 $rackpack = array();
1667 global $loclist;
64b95774 1668 foreach ($mdata as $rua)
e673ee24
DO
1669 {
1670 $rack_id = $rua['rack_id'];
1671 $unit_no = $rua['unit_no'];
1672 $atom = $rua['atom'];
1673 if (!isset ($rackpack[$rack_id]))
1674 {
1675 $rackData = getRackData ($rack_id);
1676 for ($i = $rackData['height']; $i > 0; $i--)
1677 for ($locidx = 0; $locidx < 3; $locidx++)
1678 $rackData[$i][$locidx]['state'] = 'F';
1679 $rackpack[$rack_id] = $rackData;
1680 }
1681 $rackpack[$rack_id][$unit_no][$loclist[$atom]]['state'] = 'T';
1682 $rackpack[$rack_id][$unit_no][$loclist[$atom]]['object_id'] = $object_id;
1683 }
1684 // now we have some racks to render
64b95774 1685 foreach ($rackpack as $rackData)
e673ee24
DO
1686 {
1687 markAllSpans ($rackData);
1688 echo "<table class=molecule cellspacing=0>\n";
1689 echo "<caption>${rackData['name']}</caption>\n";
1690 echo "<tr><th width='10%'>&nbsp;</th><th width='20%'>Front</th><th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
1691 for ($i = $rackData['height']; $i > 0; $i--)
1692 {
1693 echo "<tr><th>$i</th>";
1694 for ($locidx = 0; $locidx < 3; $locidx++)
1695 {
1696 $state = $rackData[$i][$locidx]['state'];
1697 echo "<td class=state_${state}>&nbsp;</td>\n";
1698 }
1699 echo "</tr>\n";
1700 }
1701 echo "</table>\n";
1702 }
1703}
1704
1705function renderUnmountedObjectsPortlet ()
1706{
1707 startPortlet ('Unmounted objects');
1708 $objs = getUnmountedObjects();
1709 if ($objs === NULL)
1710 {
591ff2c4 1711 showError ('getUnmountedObjects() failed', __FUNCTION__);
e673ee24
DO
1712 return;
1713 }
1714 global $root, $nextorder;
1715 $order = 'odd';
1716 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
18d94c29 1717 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset number</th><th>Barcode</th></tr>';
e673ee24
DO
1718 foreach ($objs as $obj)
1719 {
1720 echo "<tr class=row_${order}><td><a href='${root}?page=object&object_id=${obj['id']}'>${obj['dname']}</a></td>";
1721 echo "<td>${obj['label']}</td>";
18d94c29
DO
1722 echo "<td>${obj['asset_no']}</td>";
1723 echo "<td>${obj['barcode']}</td></tr>";
e673ee24
DO
1724 $order = $nextorder[$order];
1725 }
1726 echo "</table><br>\n";
1727 finishPortlet();
1728}
1729
1730function renderProblematicObjectsPortlet ()
1731{
1732 startPortlet ('Problematic objects');
1733 $objs = getProblematicObjects();
1734 if ($objs === NULL)
1735 {
591ff2c4 1736 showError ('getProblematicObjects() failed', __FUNCTION__);
e673ee24
DO
1737 return;
1738 }
1739 global $root, $nextorder;
1740 $order = 'odd';
1741 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1742 echo '<tr><th>Type</th><th>Common name</th></tr>';
1743 foreach ($objs as $obj)
1744 {
1745 echo "<tr class=row_${order}><td>${obj['objtype_name']}</td>";
1746 echo "<td><a href='${root}?page=object&object_id=${obj['id']}'>${obj['dname']}</a></tr>";
1747 $order = $nextorder[$order];
1748 }
1749 echo "</table><br>\n";
1750 finishPortlet();
1751}
1752
7cc02fc1
DO
1753function renderObjectSpace ()
1754{
105cea6e 1755 global $root, $taglist, $tagtree;
7cc02fc1
DO
1756 echo "<table border=0 class=objectview>\n";
1757 echo "<tr><td class=pcleft width='50%'>";
1758 startPortlet ('View all by type');
1759 $groupInfo = getObjectGroupInfo();
1760 if ($groupInfo === NULL)
1761 {
1762 showError ('getObjectGroupInfo() failed', __FUNCTION__);
1763 return;
1764 }
1765 if (count ($groupInfo) == 0)
1766 echo "No objects exist in DB";
1767 else
1768 {
1769 echo '<div align=left><ul>';
1770 foreach ($groupInfo as $gi)
1771 echo "<li><a href='${root}?page=objgroup&group_id=${gi['id']}'>${gi['name']}</a> (${gi['count']})</li>";
1772 echo '</ul></div>';
1773 }
1774 finishPortlet();
1775
1776 echo '</td><td class=pcright>';
1777
1778 startPortlet ('View all by tag');
1779 if (count ($taglist) == 0)
1780 echo "No tags exist in DB";
1781 else
1782 renderTagCloud ('object');
1783 finishPortlet();
e673ee24
DO
1784 echo "</td></tr></table>\n";
1785}
1786
466dcbe6 1787function renderObjectGroup ()
7cc02fc1
DO
1788{
1789 global $root, $pageno, $tabno, $nextorder, $taglist, $tagtree;
2c6c7645 1790 assertUIntArg ('group_id', __FUNCTION__, TRUE);
7cc02fc1 1791 $group_id = $_REQUEST['group_id'];
a0d54e7e
DO
1792 $tagfilter = getTagFilter();
1793 $tagfilter_str = getTagFilterStr ($tagfilter);
7cc02fc1
DO
1794 echo "<table border=0 class=objectview>\n";
1795 echo "<tr><td class=pcleft width='25%'>";
1796 startPortlet ('change type');
1797 $groupInfo = getObjectGroupInfo();
1798 if ($groupInfo === NULL)
1799 {
1800 showError ('getObjectGroupInfo() failed', __FUNCTION__);
1801 return;
1802 }
1803 if (count ($groupInfo) == 0)
1804 echo "No objects exist in DB";
1805 else
1806 {
1807 echo '<div align=left><ul>';
1808 foreach ($groupInfo as $gi)
1809 {
a0d54e7e 1810 echo "<li><a href='${root}?page=${pageno}&group_id=${gi['id']}${tagfilter_str}'>";
105cea6e
DO
1811 if ($gi['id'] == $group_id)
1812 echo '<strong>';
1813 echo "${gi['name']}</a>";
1814 if ($gi['id'] == $group_id)
1815 echo '</strong>';
1816 echo " (${gi['count']})";
1817 if ($gi['id'] == $group_id)
1818 echo ' &larr;';
1819 echo "</li>";
7cc02fc1
DO
1820 }
1821 echo '</ul></div>';
1822 }
1823 finishPortlet();
1824
1825 echo '</td><td class=pcleft>';
1826
1827 startPortlet ('Objects');
11c8e4be 1828 $objects = getObjectList ($group_id, $tagfilter, getTFMode());
7cc02fc1
DO
1829 if ($objects === NULL)
1830 {
1831 showError ('getObjectList() failed', __FUNCTION__);
1832 return;
1833 }
1834 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1835 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>Barcode</th><th>Rack</th></tr>';
1836 $order = 'odd';
1837 foreach ($objects as $obj)
1838 {
8e700dd1
DO
1839 if (isset ($_REQUEST['hl_object_id']) and $_REQUEST['hl_object_id'] == $obj['id'])
1840 $secondclass = 'tdleft port_highlight';
1841 else
1842 $secondclass = 'tdleft';
1843 echo "<tr class=row_${order}><td class='${secondclass}'><a href='${root}?page=object&object_id=${obj['id']}'>${obj['dname']}</a></td>";
1844 echo "<td class='${secondclass}'>${obj['label']}</td>";
1845 echo "<td class='${secondclass}'>${obj['asset_no']}</td>";
1846 echo "<td class='${secondclass}'>${obj['barcode']}</td>";
7cc02fc1 1847 if ($obj['rack_id'])
8e700dd1 1848 echo "<td class='${secondclass}'><a href='${root}?page=rack&rack_id=${obj['rack_id']}'>${obj['Rack_name']}</a></td>";
7cc02fc1 1849 else
8e700dd1 1850 echo "<td class='${secondclass}'>Unmounted</td>";
7cc02fc1
DO
1851 echo '</tr>';
1852 $order = $nextorder[$order];
1853 }
1854 echo '</table>';
1855 finishPortlet();
1856
1857 echo "</td><td class=pcright width='25%'>";
1858
a0d54e7e 1859 renderTagFilterPortlet ($tagfilter, 'object', 'group_id', $group_id);
7cc02fc1 1860 echo "</td></tr></table>\n";
e673ee24
DO
1861}
1862
1863function renderEmptyPortsSelect ($port_id, $type_id)
1864{
1865 $ports = getEmptyPortsOfType($type_id);
1866 usort($ports, 'sortEmptyPorts');
1867 foreach ($ports as $port)
1868 {
1869 if ($port_id == $port['Port_id'])
1870 continue;
1871 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";
1872 }
1873}
1874
6ef9683b 1875function renderAllIPv4Allocations ()
e673ee24 1876{
6ef9683b 1877 $addresses = getAllIPv4Allocations();
e673ee24
DO
1878 usort($addresses, 'sortObjectAddressesAndNames');
1879 foreach ($addresses as $address)
1880 {
1881 echo "<option value='${address['ip']}' onclick='getElementById(\"ip\").value=\"${address['ip']}\";'>${address['object_name']} ${address['name']} ${address['ip']}</option>\n";
1882 }
1883}
1884
1885// History viewer for history-enabled simple dictionaries.
1886function renderHistory ($object_type, $object_id)
1887{
1888 switch ($object_type)
1889 {
1890 case 'row':
1891 $query = "select ctime, user_name, name, deleted, comment from RackRowHistory where id = ${object_id} order by ctime";
1892 $header = '<tr><th>change time</th><th>author</th><th>rack row name</th><th>is deleted?</th><th>rack row comment</th></tr>';
1893 $extra = 4;
1894 break;
1895 case 'rack':
1896 $query =
1897 "select ctime, user_name, rh.name, rh.deleted, d.dict_value as name, rh.height, rh.comment " .
1898 "from RackHistory as rh left join Dictionary as d on rh.row_id = d.dict_key " .
1899 "natural join Chapter " .
1900 "where chapter_name = 'RackRow' and rh.id = ${object_id} order by ctime";
1901 $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>';
1902 $extra = 6;
1903 break;
1904 case 'object':
1905 $query =
1906 "select ctime, user_name, name, label, barcode, asset_no, deleted, has_problems, dict_value, comment " .
1907 "from RackObjectHistory inner join Dictionary on objtype_id = dict_key natural join Chapter " .
1908 "where chapter_name = 'RackObjectType' and id=${object_id} order by ctime";
1909 $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>';
1910 $extra = 9;
1911 break;
1912 default:
591ff2c4 1913 showError ("Uknown object type '${object_type}'", __FUNCTION__);
e673ee24
DO
1914 return;
1915 }
1916 global $dbxlink;
1917 $result = $dbxlink->query ($query);
1918 if ($result == NULL)
1919 {
591ff2c4 1920 showError ('SQL query failed', __FUNCTION__);
e673ee24
DO
1921 return;
1922 }
1923 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1924 $order = 'odd';
1925 global $nextorder;
1926 echo $header;
1927 while ($row = $result->fetch (PDO::FETCH_NUM))
1928 {
1929 echo "<tr class=row_${order}><td>${row[0]}</td>";
1930 for ($i = 1; $i <= $extra; $i++)
1931 echo "<td>" . $row[$i] . "</td>";
1932 echo "</tr>\n";
1933 $order = $nextorder[$order];
1934 }
1935 echo "</table><br>\n";
1936}
1937
1938function renderRackspaceHistory ()
1939{
1940 global $root, $nextorder, $pageno, $tabno;
1941 $order = 'odd';
1942 $history = getRackspaceHistory();
1943 // Show the last operation by default.
1944 if (isset ($_REQUEST['op_id']))
1945 $op_id = $_REQUEST['op_id'];
1946 elseif (isset ($history[0]['mo_id']))
1947 $op_id = $history[0]['mo_id'];
1948 else $op_id = NULL;
1949
1950 $omid = NULL;
1951 $nmid = NULL;
1952 $object_id = 1;
1953 if ($op_id)
1954 list ($omid, $nmid) = getOperationMolecules ($op_id);
1955
1956 // Main layout starts.
1957 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
1958
1959 // Left top portlet with old allocation.
1960 echo "<tr><td class=pcleft>";
1961 startPortlet ('Old allocation');
1962 if ($omid)
1963 {
1964 $oldMolecule = getMolecule ($omid);
1965 renderMolecule ($oldMolecule, $object_id);
1966 }
1967 else
1968 echo "nothing";
1969 finishPortlet();
1970
1971 echo '</td><td class=pcright>';
1972
1973 // Right top portlet with new allocation
1974 startPortlet ('New allocation');
1975 if ($nmid)
1976 {
1977 $newMolecule = getMolecule ($nmid);
1978 renderMolecule ($newMolecule, $object_id);
1979 }
1980 else
1981 echo "nothing";
1982 finishPortlet();
737a3f72 1983
e673ee24 1984 echo '</td></tr><tr><td colspan=2>';
737a3f72 1985
e673ee24
DO
1986 // Bottom portlet with list
1987
1988 startPortlet ('Rackspace allocation history');
1989 echo "<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>\n";
1990 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";
1991 foreach ($history as $row)
1992 {
1993 if ($row['mo_id'] == $op_id)
1994 $class = 'hl';
1995 else
1996 $class = "row_${order}";
1997 echo "<tr class=${class}><td><a href='${root}?page=${pageno}&tab=${tabno}&op_id=${row['mo_id']}'>${row['ctime']}</a></td>";
1998 echo "<td>${row['user_name']}</td>";
1999 echo "<td>${row['ro_id']}</td><td>${row['objtype_name']}</td><td>${row['name']}</td><td>${row['comment']}</td>\n";
2000 echo "</tr>\n";
2001 $order = $nextorder[$order];
2002 }
2003 echo "</table>\n";
2004 finishPortlet();
737a3f72 2005
e673ee24 2006 echo '</td></tr></table>';
e673ee24
DO
2007}
2008
d9f8a37a 2009function renderIPv4SpaceRecords ($tree, &$tagcache, $baseurl, $target = 0, $level = 1)
d65353ad
DO
2010{
2011 $self = __FUNCTION__;
2012 foreach ($tree as $item)
2013 {
737a3f72 2014 $total = $item['addrt'];
a987ff52
DO
2015 loadIPv4AddrList ($item); // necessary to compute router list and address counter
2016 $used = $item['addrc'];
0137d53c
DO
2017 if (isset ($item['id']))
2018 {
fec0c8da 2019 if ($item['symbol'] == 'node-collapsed')
d9f8a37a 2020 $expandurl = "${baseurl}&eid=" . $item['id'] . "#netid" . $item['id'];
fec0c8da 2021 elseif ($item['symbol'] == 'node-expanded')
d9f8a37a 2022 $expandurl = $baseurl . ($item['parent_id'] ? "&eid=${item['parent_id']}#netid${item['parent_id']}" : '');
fec0c8da
DO
2023 else
2024 $expandurl = '';
0137d53c 2025 echo "<tr valign=top>";
fec0c8da 2026 printIPv4NetInfoTDs ($item, 'tdleft', $level, $item['symbol'], $expandurl);
0137d53c 2027 echo "<td class=tdcenter>";
d9f8a37a
DO
2028 if ($target == $item['id'])
2029 echo "<a name=netid${target}></a>";
737a3f72 2030 renderProgressBar ($total ? $used/$total : 0);
0137d53c
DO
2031 echo "<br><small>${used}/${total}</small></td>";
2032 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
b6b87070 2033 printRoutersTD (findRouters ($item['addrlist']), $tagcache);
0137d53c 2034 echo "</tr>";
fec0c8da 2035 if ($item['symbol'] == 'node-expanded' or $item['symbol'] == 'node-expanded-static')
d9f8a37a 2036 $self ($item['kids'], $tagcache, $baseurl, $target, $level + 1);
0137d53c
DO
2037 }
2038 else
2039 {
0137d53c 2040 echo "<tr valign=top>";
fec0c8da 2041 printIPv4NetInfoTDs ($item, 'tdleft sparenetwork', $level, $item['symbol']);
0137d53c 2042 echo "<td class=tdcenter>";
fec0c8da 2043 renderProgressBar ($used/$total, 'sparenetwork');
0137d53c
DO
2044 echo "<br><small>${used}/${total}</small></td>";
2045 echo "<td>&nbsp;</td></tr>";
2046 }
d65353ad
DO
2047 }
2048}
2049
04d619d0 2050function renderIPv4Space ()
e673ee24 2051{
fec0c8da 2052 global $root, $pageno, $tabno;
932cf41f 2053 $tagfilter = getTagFilter();
94a40058
DO
2054 $netlist = getIPv4NetworkList ($tagfilter, getTFMode());
2055 $netcount = count ($netlist);
fec0c8da 2056 $tree = prepareIPv4Tree ($netlist, isset ($_REQUEST['eid']) ? $_REQUEST['eid'] : 0);
94a40058 2057 unset ($netlist);
3630d1fb
DO
2058
2059 echo "<table border=0 class=objectview>\n";
2060 echo "<tr><td class=pcleft>";
94a40058 2061 startPortlet ("networks (${netcount})");
04d619d0 2062 echo "<table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
57dece2f 2063 echo "<tr><th>prefix</th><th>name/tags</th><th>%% used</th>";
f0ed1181 2064 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
57dece2f
DO
2065 echo "<th>routed by</th>";
2066 echo "</tr>\n";
fec0c8da 2067 $tagcache = array();
0c16ef0c 2068 $baseurl = "${root}?page=${pageno}&tab=${tabno}" . getTagFilterStr ($tagfilter);
d9f8a37a 2069 renderIPv4SpaceRecords ($tree, $tagcache, $baseurl, isset ($_REQUEST['eid']) ? $_REQUEST['eid'] : 0);
e673ee24 2070 echo "</table>\n";
a7fe7729 2071 finishPortlet();
74ccacff 2072 echo '</td><td class=pcright>';
5b7bd02e 2073 renderTagFilterPortlet ($tagfilter, 'ipv4net');
74ccacff 2074 echo "</td></tr></table>\n";
f973f491 2075}
a7fe7729 2076
f973f491
DO
2077function renderIPv4SLB ()
2078{
80e85ea1 2079 global $root, $page, $nextorder;
a7fe7729 2080
6fec9f39 2081 startPortlet ('SLB configuration');
b3c50e6c 2082 echo "<table border=0 width='100%'><tr>";
ee437dab 2083 foreach (array ('ipv4vslist', 'ipv4rsplist', 'rservers', 'lbs') as $pno)
e57dca7f 2084 echo "<td><h3><a href='${root}?page=${pno}'>" . $page[$pno]['title'] . "</a></h3></td>";
b3c50e6c
DO
2085 echo '</tr></table>';
2086 finishPortlet();
2087
c3bdc503 2088 $summary = getSLBSummary();
6fec9f39 2089 startPortlet ('SLB tactical overview');
4cadac8f
DO
2090 // A single id-keyed array isn't used here to preserve existing
2091 // order of LBs returned by getSLBSummary()
c3bdc503
DO
2092 $lblist = array();
2093 $lbdname = array();
4cadac8f 2094 foreach ($summary as $vipdata)
da04825a 2095 foreach (array_keys ($vipdata['lblist']) as $lb_object_id)
c3bdc503
DO
2096 if (!in_array ($lb_object_id, $lblist))
2097 {
2098 $oi = getObjectInfo ($lb_object_id);
2099 $lbdname[$lb_object_id] = $oi['dname'];
2100 $lblist[] = $lb_object_id;
2101 }
2102 if (!count ($summary))
2103 echo 'none configured';
2104 else
2105 {
80e85ea1 2106 $order = 'odd';
c3bdc503 2107 echo "<table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
a7bc13c8 2108 echo "<tr><th>VS&nbsp;&darr; LB&nbsp;&rarr;</th>";
c3bdc503 2109 foreach ($lblist as $lb_object_id)
71b8bda1 2110 echo "<th><a href='${root}?page=object&tab=default&object_id=${lb_object_id}'>" . $lbdname[$lb_object_id] . "</a></th>";
c3bdc503 2111 echo "</tr>\n";
4cadac8f
DO
2112 foreach ($summary as $vsid => $vsdata)
2113 {
49fb2686 2114 echo "<tr class=row_${order}><td class=tdleft><a href='$root?page=ipv4vs&tab=default&vs_id=${vsid}'>";
8d790216 2115 echo buildVServiceName ($vsdata);
6fec9f39
DO
2116 echo '</a>';
2117 if (!empty ($vsdata['name']))
300826cb 2118 echo "<br>${vsdata['name']}";
6fec9f39 2119 echo "</td>";
4cadac8f 2120 foreach ($lblist as $lb_object_id)
da04825a 2121 {
60fbcece 2122 echo '<td class=tdleft>';
2b4eee17 2123 if (!isset ($vsdata['lblist'][$lb_object_id]))
da04825a
DO
2124 echo '&nbsp;';
2125 else
6fec9f39
DO
2126 {
2127 echo $vsdata['lblist'][$lb_object_id]['size'];
79a9edb4
DO
2128// echo " (<a href='${root}?page=ipv4rsp&pool_id=";
2129// echo $vsdata['lblist'][$lb_object_id]['id'] . "'>";
2130// echo $vsdata['lblist'][$lb_object_id]['name'] . '</a>)';
6fec9f39 2131 }
da04825a
DO
2132 echo '</td>';
2133 }
2134 echo "</tr>\n";
80e85ea1 2135 $order = $nextorder[$order];
4cadac8f 2136 }
c3bdc503
DO
2137 echo "</table>\n";
2138 }
a7fe7729 2139 finishPortlet ();
e673ee24
DO
2140}
2141
04d619d0 2142function renderIPv4SpaceEditor ()
e673ee24
DO
2143{
2144 global $root, $pageno, $tabno;
2145 showMessageOrError();
2a201216 2146
a262e150
DO
2147 // IPv4 validator
2148?>
2149 <script type="text/javascript">
2150 function init() {
2151 document.add_new_range.range.setAttribute('match', "^\\d\\d?\\d?\\.\\d\\d?\\d?\\.\\d\\d?\\d?\\.\\d\\d?\\d?\\/\\d\\d?$");
2152
2153 Validate.init();
2154 }
2155 window.onload=init;
2156 </script>
2157<?php
2158
4c0653e2 2159 startPortlet ("Add new");
04d619d0 2160 echo '<table border=0 cellpadding=10 align=center>';
7056988c
DO
2161 // This form requires a name, so JavaScript validator can find it.
2162 // No printOpFormIntro() hence
04d619d0 2163 echo "<form method=post name='add_new_range' action='${root}process.php'>\n";
42023f03 2164 echo "<input type=hidden name=op value=addIPv4Prefix>\n";
2a201216
DY
2165 echo "<input type=hidden name=page value='${pageno}'>\n";
2166 echo "<input type=hidden name=tab value='${tabno}'>\n";
04d619d0
DO
2167 // tags column
2168 echo '<tr><td rowspan=4><h3>assign tags</h3>';
5c0bb421 2169 renderTagSelect();
04d619d0
DO
2170 echo '</td>';
2171 // inputs column
2172 echo "<th class=tdright>prefix</th><td class=tdleft><input type=text name='range' size=18 class='live-validate' tabindex=1></td>";
2173 echo "<tr><th class=tdright>name</th><td class=tdleft><input type=text name='name' size='20' tabindex=2></td></tr>";
0c16ef0c 2174 echo "<tr><th class=tdright>connected network</th><td class=tdleft><input type=checkbox name='is_bcast' tabindex=3></td></tr>";
04d619d0 2175 echo "<tr><td colspan=2>";
4c0653e2 2176 printImageHREF ('CREATE', 'Add a new network', TRUE, 4);
04d619d0 2177 echo '</td></tr>';
2a201216 2178 echo "</form></table><br><br>\n";
5c0bb421 2179 finishPortlet();
2a201216 2180
b18d26dc 2181 $addrspaceList = getIPv4NetworkList();
0c16ef0c
DO
2182 $netcount = count ($addrspaceList);
2183 if ($netcount)
e673ee24 2184 {
0c16ef0c 2185 startPortlet ("Manage existing (${netcount})");
04d619d0
DO
2186 echo "<table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
2187 echo "<tr><th>&nbsp;</th><th>prefix</th><th>name</th><th>&nbsp;</th></tr>";
0c16ef0c 2188 foreach ($addrspaceList as $netinfo)
e673ee24 2189 {
0c16ef0c
DO
2190 echo "<form method=post action='${root}process.php?page=${pageno}&tab=${tabno}&op=updIPv4Prefix&id=${netinfo['id']}'>";
2191 echo "<tr valign=top><td><a href='${root}process.php?op=delIPv4Prefix&page=${pageno}&tab=${tabno}&id=${netinfo['id']}'>";
2192 printImageHREF ('delete', 'Delete this IP range');
2193 echo "</a></td>\n<td class=tdleft>${netinfo['ip']}/${netinfo['mask']}</td>";
2194 echo "<td><input type=text name=name size=40 value='${netinfo['name']}'>";
04d619d0
DO
2195 echo "</td><td>";
2196 printImageHREF ('save', 'Save changes', TRUE);
2197 echo "</td></tr></form>\n";
e673ee24 2198 }
04d619d0
DO
2199 echo "</table>";
2200 finishPortlet();
e673ee24 2201 }
e673ee24
DO
2202}
2203
beb9e88a 2204function renderIPv4Network ($id)
e673ee24 2205{
beb9e88a 2206 global $root, $pageno, $tabno, $aac2;
545478d0
DO
2207 $netmaskbylen = array
2208 (
2209 32 => '255.255.255.255',
2210 31 => '255.255.255.254',
2211 30 => '255.255.255.252',
2212 29 => '255.255.255.248',
2213 28 => '255.255.255.240',
2214 27 => '255.255.255.224',
2215 26 => '255.255.255.192',
2216 25 => '255.255.255.128',
2217 24 => '255.255.255.0',
2218 23 => '255.255.254.0',
2219 22 => '255.255.252.0',
2220 21 => '255.255.248.0',
2221 20 => '255.255.240.0',
2222 19 => '255.255.224.0',
2223 18 => '255.255.192.0',
2224 17 => '255.255.128.0',
2225 16 => '255.255.0.0',
2226 15 => '255.254.0.0',
2227 14 => '255.252.0.0',
2228 13 => '255.248.0.0',
2229 12 => '255.240.0.0',
2230 11 => '255.224.0.0',
2231 10 => '255.192.0.0',
2232 9 => '255.128.0.0',
2233 8 => '255.0.0.0',
2234 7 => '254.0.0.0',
2235 6 => '252.0.0.0',
2236 5 => '248.0.0.0',
2237 4 => '240.0.0.0',
2238 3 => '224.0.0.0',
2239 2 => '192.0.0.0',
2240 1 => '128.0.0.0'
2241 );
2242 $wildcardbylen = array
2243 (
2244 32 => '0.0.0.0',
2245 31 => '0.0.0.1',
2246 30 => '0.0.0.3',
2247 29 => '0.0.0.7',
2248 28 => '0.0.0.15',
2249 27 => '0.0.0.31',
2250 26 => '0.0.0.63',
2251 25 => '0.0.0.127',
2252 24 => '0.0.0.255',
2253 23 => '0.0.1.255',
2254 22 => '0.0.3.255',
2255 21 => '0.0.7.255',
2256 20 => '0.0.15.255',
2257 19 => '0.0.31.255',
2258 18 => '0.0.63.255',
2259 17 => '0.0.127.255',
2260 16 => '0.0.255.25',
2261 15 => '0.1.255.255',
2262 14 => '0.3.255.255',
2263 13 => '0.7.255.255',
2264 12 => '0.15.255.255',
2265 11 => '0.31.255.255',
2266 10 => '0.63.255.255',
2267 9 => '0.127.255.255',
2268 8 => '0.255.255.255',
2269 7 => '1.255.255.255',
2270 6 => '3.255.255.255',
2271 5 => '7.255.255.255',
2272 4 => '15.255.255.255',
2273 3 => '31.255.255.255',
2274 2 => '63.255.255.255',
2275 1 => '127.255.255.255'
2276 );
b901bf1f 2277 $maxperpage = getConfigVar ('IPV4_ADDRS_PER_PAGE');
e673ee24
DO
2278 if (isset($_REQUEST['pg']))
2279 $page = $_REQUEST['pg'];
2280 else
2281 $page=0;
2282
b6b87070
DO
2283 $range = getIPv4NetworkInfo ($id);
2284 loadIPv4AddrList ($range);
2034d968
DO
2285 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
2286 echo "<tr><td colspan=2 align=center><h1>${range['ip']}/${range['mask']}</h1><h2>${range['name']}</h2></td></tr>\n";
2287
2288 echo "<tr><td class=pcleft width='50%'>";
2289 startPortlet ('summary');
2290 $total = ($range['ip_bin'] | $range['mask_bin_inv']) - ($range['ip_bin'] & $range['mask_bin']) + 1;
2291 $used = count ($range['addrlist']);
2292 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
04d619d0
DO
2293
2294 echo "<tr><th width='50%' class=tdright>%% used:</th><td class=tdleft>";
2034d968
DO
2295 renderProgressBar ($used/$total);
2296 echo "&nbsp;${used}/${total}</td></tr>\n";
04d619d0 2297
545478d0
DO
2298 echo "<tr><th width='50%' class=tdright>Netmask:</th><td class=tdleft>";
2299 echo $netmaskbylen[$range['mask']];
2300 echo "</td></tr>\n";
04d619d0 2301
545478d0
DO
2302 echo "<tr><th width='50%' class=tdright>Wildcard bits:</th><td class=tdleft>";
2303 echo $wildcardbylen[$range['mask']];
2304 echo "</td></tr>\n";
04d619d0 2305
f3d0cb20 2306 $routers = findRouters ($range['addrlist']);
f0ed1181 2307 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes' and count ($routers))
04d619d0 2308 {
57dece2f 2309 echo "<tr><th width='50%' class=tdright>Routed by:</th>";
f3d0cb20 2310 printRoutersTD ($routers);
57dece2f 2311 echo "</tr>\n";
04d619d0
DO
2312 }
2313
d9f8a37a 2314 printTagTRs ("${root}?page=ipv4space&tab=default&");
2034d968
DO
2315 echo "</table><br>\n";
2316 finishPortlet();
2317 echo "</td>\n";
e673ee24 2318
2034d968
DO
2319 echo "<td class=pcright>";
2320 startPortlet ('details');
e673ee24
DO
2321 $startip = $range['ip_bin'] & $range['mask_bin'];
2322 $endip = $range['ip_bin'] | $range['mask_bin_inv'];
2323 $realstartip = $startip;
2324 $realendip = $endip;
2325 $numpages = 0;
2326 if($endip - $startip > $maxperpage)
2327 {
e673ee24
DO
2328 $numpages = ($endip - $startip)/$maxperpage;
2329 $startip = $startip + $page * $maxperpage;
2330 $endip = $startip + $maxperpage-1;
2331 }
2332 echo "<center>";
b901bf1f
DO
2333 if ($numpages)
2334 echo '<h3>' . long2ip ($startip) . ' ~ ' . long2ip ($endip) . '</h3>';
e673ee24
DO
2335 for ($i=0; $i<$numpages; $i++)
2336 {
2337 if ($i == $page)
2338 echo "<b>$i</b> ";
2339 else
a60e0851 2340 echo "<a href='${root}?page=${pageno}&tab=${tabno}&id=$id&pg=$i'>$i</a> ";
e673ee24
DO
2341 }
2342 echo "</center>";
2343
beb9e88a 2344 echo "<table class='widetable' border=0 cellspacing=0 cellpadding=5 align='center' width='100%'>\n";
e673ee24
DO
2345 echo "<tr><th>Address</th><th>Name</th><th>Allocation</th></tr>\n";
2346
2347
b2035dca
DO
2348 for ($ip = $startip; $ip <= $endip; $ip++) :
2349 if (isset ($_REQUEST['hl_ipv4_addr']) and ip2long ($_REQUEST['hl_ipv4_addr']) == $ip)
2350 $secondstyle = 'tdleft port_highlight';
2727c7df 2351 else
b2035dca
DO
2352 $secondstyle = 'tdleft';
2353 if (!isset ($range['addrlist'][$ip]))
e673ee24 2354 {
b2035dca
DO
2355 echo "<tr><td class=tdleft><a href='${root}?page=ipaddress&ip=" . long2ip ($ip) . "'>" . long2ip ($ip);
2356 echo "</a></td><td class='${secondstyle}'>&nbsp;</td><td class='${secondstyle}'>&nbsp;</td></tr>\n";
2357 continue;
2358 }
b2035dca 2359 $addr = $range['addrlist'][$ip];
2d318652 2360 echo "<tr class='${addr['class']}'>";
e673ee24 2361
b2035dca
DO
2362 echo "<td class=tdleft><a href='${root}?page=ipaddress&ip=${addr['ip']}'>${addr['ip']}</a></td>";
2363 echo "<td class='${secondstyle}'>${addr['name']}</td><td class='${secondstyle}'>";
2364 $delim = '';
2365 $prologue = '';
2366 if ( $addr['reserved'] == 'yes')
2367 {
2d318652 2368 echo "<strong>RESERVED</strong> ";
b2035dca
DO
2369 $delim = '; ';
2370 }
2d318652 2371 foreach ($range['addrlist'][$ip]['allocs'] as $ref)
b2035dca 2372 {
beb9e88a
DO
2373 echo $delim . $aac2[$ref['type']];
2374 echo "<a href='${root}?page=object&object_id=${ref['object_id']}";
b2035dca
DO
2375 echo "&hl_ipv4_addr=${addr['ip']}'>";
2376 echo $ref['name'] . (empty ($ref['name']) ? '' : '@');
2377 echo "${ref['object_name']}</a>";
2378 $delim = '; ';
2379 }
2380 if ($delim != '')
2381 {
6131056c 2382 $delim = '';
b2035dca
DO
2383 $prologue = '<br>';
2384 }
2d318652 2385 foreach ($range['addrlist'][$ip]['lblist'] as $ref)
b2035dca
DO
2386 {
2387 echo $prologue;
602663f4 2388 $prologue = '';
b2035dca
DO
2389 echo "${delim}<a href='${root}?page=object&object_id=${ref['object_id']}'>";
2390 echo "${ref['object_name']}</a>:<a href='${root}?page=ipv4vs&vs_id=${ref['vs_id']}'>";
2391 echo "${ref['vport']}/${ref['proto']}</a>&rarr;";
2392 $delim = '; ';
2393 }
2394 if ($delim != '')
2395 {
2396 $delim = '';
2397 $prologue = '<br>';
e673ee24 2398 }
2d318652 2399 foreach ($range['addrlist'][$ip]['rslist'] as $ref)
b2035dca
DO
2400 {
2401 echo $prologue;
2402 $prologue = '';
2403 echo "${delim}&rarr;${ref['rsport']}@<a href='${root}?page=ipv4rsp&pool_id=${ref['rspool_id']}'>";
2404 echo "${ref['rspool_name']}</a>";
2405 $delim = '; ';
2406 }
2407 echo "</td></tr>\n";
2408 endfor;
2727c7df 2409 // end of iteration
e673ee24
DO
2410
2411 echo "</table>";
2034d968
DO
2412 finishPortlet();
2413 echo "</td></tr></table>\n";
e673ee24
DO
2414}
2415
53ef3908 2416function renderIPv4NetworkProperties ($id)
e673ee24 2417{
e673ee24 2418 showMessageOrError();
53ef3908
DO
2419 $netdata = getIPv4NetworkInfo ($id);
2420 echo "<center><h1>${netdata['ip']}/${netdata['mask']}</h1></center>\n";
e673ee24 2421 echo "<table border=0 cellpadding=10 cellpadding=1 align='center'>\n";
7056988c 2422 printOpFormIntro ('editRange');
53ef3908
DO
2423 echo "<tr><td class='tdright'>Name:</td><td class='tdleft'><input type=text name=name size=20 value='${netdata['name']}'></tr>";
2424 echo "<tr><td colspan=2 class=tdcenter>";
2425 printImageHREF ('SAVE', 'Save changes', TRUE);
2426 echo "</td></form></tr></table>\n";
e673ee24
DO
2427}
2428
2d318652 2429function renderIPv4Address ($dottedquad)
e673ee24 2430{
52c836b1 2431 global $root, $aat;
2d318652 2432 $address = getIPv4Address ($dottedquad);
68225375 2433 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
2d318652
DO
2434 echo "<tr><td colspan=2 align=center><h1>${dottedquad}</h1></td></tr>\n";
2435 if (!empty ($address['name']))
68225375 2436 echo "<tr><td colspan=2 align=center><h2>${address['name']}</h2></td></tr>\n";
e673ee24 2437
68225375
DO
2438 echo "<tr><td class=pcleft>";
2439 startPortlet ('summary');
2440 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
04d619d0 2441 echo "<tr><th width='50%' class=tdright>Allocations:</th><td class=tdleft>" . count ($address['allocs']) . "</td></tr>\n";
68225375
DO
2442 echo "<tr><th width='50%' class=tdright>Originated NAT connections:</th><td class=tdleft>" . count ($address['outpf']) . "</td></tr>\n";
2443 echo "<tr><th width='50%' class=tdright>Arriving NAT connections:</th><td class=tdleft>" . count ($address['inpf']) . "</td></tr>\n";
04d619d0 2444 echo "<tr><th width='50%' class=tdright>SLB virtual services:</th><td class=tdleft>" . count ($address['lblist']) . "</td></tr>\n";
68225375
DO
2445 echo "<tr><th width='50%' class=tdright>SLB real servers:</th><td class=tdleft>" . count ($address['rslist']) . "</td></tr>\n";
2446 printTagTRs();
2447 echo "</table><br>\n";
2448 finishPortlet();
2449 echo "</td>\n";
e673ee24 2450
68225375 2451 echo "<td class=pcright>";
e673ee24 2452
2d318652 2453 if (!empty ($address['class']))
59bebe2b 2454 {
8e700dd1 2455 startPortlet ('allocations');
2d318652
DO
2456 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
2457 echo "<tr><th>object</th><th>OS interface</th><th>allocation type</th></tr>\n";
2458 $class = $address['class'];
2459 // render all allocation records for this address the same way
59bebe2b 2460 if ($address['reserved'] == 'yes')
2d318652
DO
2461 echo "<tr class='${class}'><td colspan=2>&nbsp;</td><td class=tdleft><strong>RESERVED</strong></td></tr>";
2462 foreach ($address['allocs'] as $bond)
59bebe2b 2463 {
8e700dd1
DO
2464 if (isset ($_REQUEST['hl_object_id']) and $_REQUEST['hl_object_id'] == $bond['object_id'])
2465 $secondclass = 'tdleft port_highlight';
2466 else
2467 $secondclass = 'tdleft';
2468 echo "<tr class='$class'><td class=tdleft><a href='${root}?page=object&object_id=${bond['object_id']}";
2d318652 2469 echo "&hl_ipv4_addr=${dottedquad}'>${bond['object_name']}</td><td class='${secondclass}'>${bond['name']}</td><td class='${secondclass}'><strong>";
52c836b1
DO
2470 echo $aat[$bond['type']];
2471 echo "</strong></td></tr>\n";
59bebe2b
DO
2472 }
2473 echo "</table><br><br>";
2474 finishPortlet();
2475 }
e673ee24 2476
f3d0cb20
DO
2477 // FIXME: The returned list is structured differently, than we expect it to be. One of the sides
2478 // must be fixed.
2d318652 2479 if (count ($address['lblist']))
e673ee24 2480 {
2d318652
DO
2481 startPortlet ('Virtual services (' . count ($address['lblist']) . ')');
2482 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
59bebe2b 2483 echo "<tr><th>VS</th><th>name</th></tr>\n";
2d318652 2484 foreach ($address['lblist'] as $vsinfo)
e673ee24 2485 {
2d318652 2486 echo "<tr><td class=tdleft><a href='${root}?page=ipv4vs&vs_id=${vsinfo['vs_id']}'>";
59bebe2b 2487 echo buildVServiceName ($vsinfo) . "</a></td><td class=tdleft>";
5fe1ed76 2488 echo $vsinfo['name'] . "</td></tr>\n";
e673ee24 2489 }
59bebe2b
DO
2490 echo "</table><br><br>";
2491 finishPortlet();
e673ee24 2492 }
5fe1ed76
DO
2493
2494 if (count ($address['rslist']))
2495 {
2496 startPortlet ('Real servers (' . count ($address['rslist']) . ')');
2d318652 2497 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
53f4b619 2498 echo "<tr><th>&nbsp;</th><th>port</th><th>RS pool</th></tr>\n";
5fe1ed76
DO
2499 foreach ($address['rslist'] as $rsinfo)
2500 {
2501 echo "<tr><td>";
2502 if ($rsinfo['inservice'] == 'yes')
2503 printImageHREF ('inservice', 'in service');
2504 else
2505 printImageHREF ('notinservice', 'NOT in service');
2d318652
DO
2506 echo "</td><td class=tdleft>${rsinfo['rsport']}</td><td class=tdleft><a href='${root}?page=ipv4rsp&pool_id=${rsinfo['rspool_id']}'>";
2507 echo $rsinfo['rspool_name'] . "</a></td></tr>\n";
5fe1ed76
DO
2508 }
2509 echo "</table><br><br>";
2510 finishPortlet();
2511 }
2512
68225375
DO
2513 if (count ($address['outpf']))
2514 {
105a3bc8 2515 startPortlet ('departing NAT rules');
2d318652 2516 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
105a3bc8
DO
2517 echo "<tr><th>proto</th><th>from</th><th>to</th><th>comment</th></tr>\n";
2518 foreach ($address['outpf'] as $rule)
b62ff880 2519 echo "<tr><td>${rule['proto']}</td><td>${rule['localip']}:${rule['localport']}</td><td>${rule['remoteip']}:${rule['remoteport']}</td><td>${rule['description']}</td></tr>";
105a3bc8 2520 echo "</table>";
68225375
DO
2521 finishPortlet();
2522 }
105a3bc8
DO
2523
2524 if (count ($address['inpf']))
2525 {
2526 startPortlet ('arriving NAT rules');
2d318652 2527 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
105a3bc8
DO
2528 echo "<tr><th>proto</th><th>from</th><th>to</th><th>comment</th></tr>\n";
2529 foreach ($address['inpf'] as $rule)
b62ff880 2530 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
2531 echo "</table>";
2532 finishPortlet();
2533 }
2534
68225375
DO
2535 echo "</td></tr>";
2536 echo "</table>\n";
e673ee24
DO
2537}
2538
2d318652 2539function renderIPv4AddressProperties ($dottedquad)
e673ee24 2540{
e673ee24 2541 showMessageOrError();
2d318652
DO
2542 $address = getIPv4Address ($dottedquad);
2543 echo "<center><h1>$dottedquad</h1></center>\n";
7056988c 2544
1fbc9fd6 2545 startPortlet ('update');
e673ee24 2546 echo "<table border=0 cellpadding=10 cellpadding=1 align='center'>\n";
7056988c 2547 printOpFormIntro ('editAddress');
2d318652
DO
2548 echo "<tr><td class='tdright'>Name:</td><td class='tdleft'><input type=text name=name size=20 value='${address['name']}'></tr>";
2549 echo "<td class='tdright'>Reserved:</td><td class='tdleft'><input type=checkbox name=reserved size=20 ";
2550 echo ($address['reserved']=='yes') ? 'checked' : '';
53ef3908
DO
2551 echo "></tr><tr><td colspan=2 class='tdcenter'>";
2552 printImageHREF ('SAVE', 'Save changes', TRUE);
2553 echo "</td></form></tr></table>\n";
1fbc9fd6
DO
2554 finishPortlet();
2555 if (empty ($address['name']) and $address['reserved'] == 'no')
2556 return;
7056988c 2557
1fbc9fd6 2558 startPortlet ('release');
7056988c 2559 printOpFormIntro ('editAddress', array ('name' => '', 'reserved' => ''));
1fbc9fd6
DO
2560 echo "<input type=submit value='release'></form>";
2561 finishPortlet();
e673ee24
DO
2562}
2563
2d318652 2564function renderIPv4AddressAllocations ($dottedquad)
e673ee24 2565{
e673ee24 2566 showMessageOrError();
39b4abd0
DO
2567 function printNewItemTR ()
2568 {
2569 global $aat;
2570 printOpFormIntro ('addIPv4Allocation');
2571 echo "<tr><td>";
2572 printImageHREF ('add', 'new allocation', TRUE);
2573 echo "</td><td><select name='object_id'>";
2574
2575 foreach (explode (',', getConfigVar ('IPV4_PERFORMERS')) as $type)
2576 foreach (getNarrowObjectList ($type) as $object)
2577 echo "<option value='${object['id']}'>${object['dname']}</option>";
2578
2579 echo "</select></td><td><input type='text' name='bond_name' value='' size=10></td><td>";
2580 printSelect ($aat, 'bond_type');
2581 echo "</td><td>&nbsp;</td></form></tr>";
2582 }
2d318652 2583 global $pageno, $tabno, $root, $aat;
e673ee24 2584
2d318652
DO
2585 $address = getIPv4Address ($dottedquad);
2586 $class = $address['class'];
2587 echo "<center><h1>${dottedquad}</h1></center>\n";
105a3bc8 2588 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
2d318652 2589 echo "<tr><th>&nbsp;</th><th>object</th><th>OS interface</th><th>allocation type</th><th>&nbsp;</th></tr>\n";
e673ee24
DO
2590
2591 if ($address['reserved'] == 'yes')
2d318652 2592 echo "<tr class='${class}'><td colspan=3>&nbsp;</td><td class=tdleft><strong>RESERVED</strong></td><td>&nbsp;</td></tr>";
39b4abd0
DO
2593 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
2594 printNewItemTR();
2d318652 2595 foreach ($address['allocs'] as $bond)
e673ee24 2596 {
7056988c
DO
2597 echo "<tr class='$class'>";
2598 printOpFormIntro ('updIPv4Allocation', array ('object_id' => $bond['object_id']));
2d318652 2599 echo "<td><a href='${root}process.php?op=delIPv4Allocation&page=${pageno}&tab=${tabno}&ip=${dottedquad}&object_id=${bond['object_id']}'>";
e673ee24
DO
2600 printImageHREF ('delete', 'Unallocate address');
2601 echo "</a></td>";
2d318652 2602 echo "<td><a href='${root}?page=object&object_id=${bond['object_id']}&hl_ipv4_addr=${dottedquad}'>${bond['object_name']}</td>";
52c836b1
DO
2603 echo "<td><input type='text' name='bond_name' value='${bond['name']}' size=10></td><td>";
2604 printSelect ($aat, 'bond_type', $bond['type']);
2605 echo "</td><td>";
b4c1ef87
DO
2606 printImageHREF ('save', 'Save changes', TRUE);
2607 echo "</td></form></tr>\n";
e673ee24 2608 }
39b4abd0
DO
2609 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
2610 printNewItemTR();
e673ee24
DO
2611 echo "</table><br><br>";
2612
2613}
2614
eeb4a5d8 2615function renderNATv4ForObject ($object_id = 0)
e673ee24
DO
2616{
2617 global $pageno, $tabno, $root;
2618
2619 $info = getObjectInfo ($object_id);
eeb4a5d8 2620 $forwards = getNATv4ForObject ($object_id);
2c817354 2621 $alloclist = getObjectIPv4Allocations ($object_id);
e673ee24 2622 showMessageOrError();
f28fbe8b 2623 echo "<center><h2>locally performed NAT</h2></center>";
e673ee24 2624
105a3bc8 2625 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
d54b9495 2626 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
DO
2627
2628 foreach ($forwards['out'] as $pf)
2629 {
2c817354
DO
2630 $class = 'trerror';
2631 $osif = '';
2632 if (isset ($alloclist [$pf['localip']]))
2633 {
2634 $class = $alloclist [$pf['localip']]['addrinfo']['class'];
2635 $osif = $alloclist [$pf['localip']]['osif'] . ': ';
2636 }
e673ee24
DO
2637
2638 echo "<tr class='$class'>";
72d8ced3 2639 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
2640 printImageHREF ('delete', 'Delete NAT rule');
2641 echo "</a></td>";
2c817354 2642 echo "<td>${pf['proto']}/${osif}<a href='${root}?page=ipaddress&tab=default&ip=${pf['localip']}'>${pf['localip']}</a>:${pf['localport']}";
f28fbe8b
DO
2643 if (!empty ($pf['local_addr_name']))
2644 echo ' (' . $pf['local_addr_name'] . ')';
2645 echo "</td>";
e673ee24
DO
2646 echo "<td><a href='${root}?page=ipaddress&tab=default&ip=${pf['remoteip']}'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
2647
53ef3908 2648 $address = getIPv4Address ($pf['remoteip']);
e673ee24
DO
2649
2650 echo "<td class='description'>";
53ef3908
DO
2651 if (count ($address['allocs']))
2652 foreach ($address['allocs'] as $bond)
f28fbe8b
DO
2653 echo "<a href='${root}?page=object&tab=default&object_id=${bond['object_id']}'>${bond['object_name']}(${bond['name']})</a> ";
2654 elseif (!empty ($pf['remote_addr_name']))
2655 echo '(' . $pf['remote_addr_name'] . ')';
7056988c
DO
2656 printOpFormIntro
2657 (
2658 'updNATv4Rule',
2659 array
2660 (
2661 'localip' => $pf['localip'],
2662 'localport' => $pf['localport'],
2663 'remoteip' => $pf['remoteip'],
2664 'remoteport' => $pf['remoteport'],
2665 'proto' => $pf['proto']
2666 )
2667 );
2668 echo "</td><td class='description'>";
d54b9495
DO
2669 echo "<input type='text' name='description' value='${pf['description']}'></td><td>";
2670 printImageHREF ('save', 'Save changes', TRUE);
2671 echo "</td></form></tr>";
e673ee24 2672 }
7056988c 2673 printOpFormIntro ('addNATv4Rule');
d54b9495
DO
2674 echo "<tr align='center'><td>";
2675 printImageHREF ('add', 'Add new NAT rule', TRUE);
2676 echo '</td><td>';
eeb4a5d8 2677 printSelect (array ('TCP' => 'TCP', 'UDP' => 'UDP'), 'proto');
52c3543f 2678 echo "<select name='localip' tabindex=1>";
e673ee24 2679
2c817354
DO
2680 foreach ($alloclist as $dottedquad => $alloc)
2681 {
2682 $name = empty ($alloc['addrinfo']['name']) ? '' : (' (' . niftyString ($alloc['addrinfo']['name']) . ')');
2683 $osif = empty ($alloc['osif']) ? '' : ($alloc['osif'] . ': ');
2684 echo "<option value='${dottedquad}'>${osif}${dottedquad}${name}</option>";
2685 }
e673ee24 2686
52c3543f
DO
2687 echo "</select>:<input type='text' name='localport' size='4' tabindex=2></td>";
2688 echo "<td><input type='text' name='remoteip' id='remoteip' size='10' tabindex=3>";
4de22e7e
DO
2689 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\");'>";
2690 printImageHREF ('find', 'Find object');
2691 echo "</a>";
52c3543f 2692 echo ":<input type='text' name='remoteport' size='4' tabindex=4></td><td></td>";
d54b9495 2693 echo "<td colspan=1><input type='text' name='description' size='20' tabindex=5></td><td>&nbsp;</td></tr>";
e673ee24
DO
2694 echo "</form>";
2695
2696 echo "</table><br><br>";
2697
f28fbe8b 2698 echo "<center><h2>arriving NAT connections</h2></center>";
105a3bc8 2699 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
e673ee24
DO
2700 echo "<tr><th></th><th>Source</th><th>Source objects</th><th>Target</th><th>Description</th></tr>\n";
2701
2702 foreach ($forwards['in'] as $pf)
2703 {
72d8ced3 2704 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
2705 printImageHREF ('delete', 'Delete NAT rule');
2706 echo "</a></td>";
e673ee24
DO
2707 echo "<td>${pf['proto']}/<a href='${root}?page=ipaddress&tab=default&ip=${pf['localip']}'>${pf['localip']}</a>:${pf['localport']}</td>";
2708 echo "<td class='description'><a href='${root}?page=object&tab=default&object_id=${pf['object_id']}'>${pf['object_name']}</a>";
2709 echo "</td><td><a href='${root}?page=ipaddress&tab=default&ip=${pf['remoteip']}'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
2710 echo "<td class='description'>${pf['description']}</td></tr>";
2711 }
2712
e673ee24 2713 echo "</table><br><br>";
e673ee24
DO
2714}
2715
7056988c 2716// FIXME: move related code away into ophandler(s)
e673ee24
DO
2717function renderAddMultipleObjectsForm ()
2718{
20c901a7 2719 global $root, $pageno, $tabno, $nextorder;
e673ee24
DO
2720
2721 $type_id = array();
7f791d1d 2722 $global_type_id = 0;
e673ee24
DO
2723 $name = array();
2724 $asset_no = array();
ce4d1a79 2725 $keepvalues1 = $keepvalues2 = FALSE;
7f791d1d 2726 $log = array();
e673ee24 2727 // Look for current submit.
7f791d1d 2728 if (isset ($_REQUEST['got_fast_data']))
e673ee24 2729 {
f60bb422 2730 $taglist = isset ($_REQUEST['taglist']) ? $_REQUEST['taglist'] : array();
ce4d1a79 2731 $keepvalues1 = TRUE;
9c0b0016
DO
2732 $max = getConfigVar ('MASSCOUNT');
2733 for ($i = 0; $i < $max; $i++)
e673ee24
DO
2734 {
2735 if (!isset ($_REQUEST["${i}_object_type_id"]))
2736 {
2737 $log[] = array ('code' => 'error', 'message' => "Submitted form is invalid at line " . $i + 1);
2738 break;
2739 }
2c6c7645
DO
2740 assertUIntArg ("${i}_object_type_id", __FUNCTION__, TRUE);
2741 assertStringArg ("${i}_object_name", __FUNCTION__, TRUE);
2742 assertStringArg ("${i}_object_label", __FUNCTION__, TRUE);
2743 assertStringArg ("${i}_object_asset_no", __FUNCTION__, TRUE);
2744 assertStringArg ("${i}_object_barcode", __FUNCTION__, TRUE);
e673ee24
DO
2745 $type_id[$i] = $_REQUEST["${i}_object_type_id"];
2746 // Save user input for possible rendering.
2747 $name[$i] = $_REQUEST["${i}_object_name"];
2748 $label[$i] = $_REQUEST["${i}_object_label"];
2749 $asset_no[$i] = $_REQUEST["${i}_object_asset_no"];
2750 $barcode[$i] = $_REQUEST["${i}_object_barcode"];
2751
f60bb422 2752 // It's better to skip silently, than to print a notice.
e673ee24
DO
2753 if ($type_id[$i] == 0)
2754 continue;
f60bb422 2755 if (commitAddObject ($name[$i], $label[$i], $barcode[$i], $type_id[$i], $asset_no[$i], $taglist) === TRUE)
e673ee24
DO
2756 $log[] = array ('code' => 'success', 'message' => "Added new object '${name[$i]}'");
2757 else
4d2e93f2 2758 $log[] = array ('code' => 'error', 'message' => __FUNCTION__ . ': commitAddObject() failed');
e673ee24 2759 }
e673ee24 2760 }
7f791d1d
DO
2761 elseif (isset ($_REQUEST['got_very_fast_data']))
2762 {
f60bb422 2763 $taglist = isset ($_REQUEST['taglist']) ? $_REQUEST['taglist'] : array();
ce4d1a79 2764 $keepvalues2 = TRUE;
2c6c7645
DO
2765 assertUIntArg ('global_type_id', __FUNCTION__, TRUE);
2766 assertStringArg ('namelist', __FUNCTION__, TRUE);
7f791d1d
DO
2767 $global_type_id = $_REQUEST['global_type_id'];
2768 if ($global_type_id == 0)
2769 {
2770 if (!empty ($_REQUEST['namelist']))
2771 $log[] = array ('code' => 'error', 'message' => 'Object type is not selected, check the form below');
2772 else
2773 $log[] = array ('code' => 'error', 'message' => 'Empty form has been ignored. Cheers.');
2774 }
2775 else
2776 {
2777 // The name extractor below was stolen from ophandlers.php:addMultiPorts()
2778 $names1 = explode ('\n', $_REQUEST['namelist']);
2779 $names2 = array();
2780 foreach ($names1 as $line)
2781 {
2782 $parts = explode ('\r', $line);
2783 reset ($parts);
2784 if (empty ($parts[0]))
2785 continue;
2786 else
2787 $names2[] = rtrim ($parts[0]);
2788 }
2789 foreach ($names2 as $cname)
f60bb422 2790 if (commitAddObject ($cname, '', '', $global_type_id, '', $taglist) === TRUE)
7f791d1d
DO
2791 $log[] = array ('code' => 'success', 'message' => "Added new object '${cname}'");
2792 else
2793 $log[] = array ('code' => 'error', 'message' => "Could not add '${cname}'");
2794 }
2795 }
2796 printLog ($log);
e673ee24
DO
2797
2798 // Render a form for the next.
2799 $typelist = getObjectTypeList();
4c330a14 2800 $typelist[0] = 'select type...';
7f791d1d 2801
f60bb422
DO
2802 startPortlet ('Distinct types, same tags');
2803 $max = getConfigVar ('MASSCOUNT');
20c901a7 2804 echo "<form name=fastform method=post action='${root}?page=${pageno}&tab=${tabno}'>";
e673ee24 2805 echo '<table border=0 align=center>';
f60bb422
DO
2806 echo "<tr><th>Object type</th><th>Common name</th><th>Visible label</th>";
2807 echo "<th>Asset tag</th><th>Barcode</th><th>Tags</th></tr>\n";
7f791d1d 2808 // If a user forgot to select object type on input, we keep his
e673ee24 2809 // previous input in the form.
9c0b0016 2810 for ($i = 0; $i < $max; $i++)
e673ee24 2811 {
7f791d1d 2812 echo '<tr><td>';
e7ade6bf
DO
2813 // Don't employ DEFAULT_OBJECT_TYPE to avoid creating ghost records for pre-selected empty rows.
2814 printSelect ($typelist, "${i}_object_type_id", 0);
e673ee24
DO
2815 echo '</td>';
2816 echo "<td><input type=text size=30 name=${i}_object_name";
ce4d1a79 2817 if ($keepvalues1 and isset ($name[$i]) and (!isset ($type_id[$i]) or $type_id[$i] == 0))
e673ee24
DO
2818 echo " value='${name[$i]}'";
2819 echo "></td>";
2820 echo "<td><input type=text size=30 name=${i}_object_label";
ce4d1a79 2821 if ($keepvalues1 and isset ($label[$i]) and (!isset ($type_id[$i]) or $type_id[$i] == 0))
e673ee24
DO
2822 echo " value='${label[$i]}'";
2823 echo "></td>";
2824 echo "<td><input type=text size=20 name=${i}_object_asset_no";
ce4d1a79 2825 if ($keepvalues1 and isset ($asset_no[$i]) and (!isset ($type_id[$i]) or $type_id[$i] == 0))
e673ee24
DO
2826 echo " value='${asset_no[$i]}'";
2827 echo "></td>";
2828 echo "<td><input type=text size=10 name=${i}_object_barcode";
ce4d1a79 2829 if ($keepvalues1 and isset ($barcode[$i]) and (!isset ($type_id[$i]) or $type_id[$i] == 0))
e673ee24
DO
2830 echo " value='${barcode[$i]}'";
2831 echo "></td>";
f60bb422
DO
2832 if ($i == 0)
2833 {
2834 echo "<td valign=top rowspan=${max}>";
2835 renderTagSelect();
2836 echo "</td>\n";
2837 }
e673ee24 2838 echo "</tr>\n";
e673ee24 2839 }
216c84bb 2840 echo "<tr><td class=submit colspan=5><input type=submit name=got_fast_data value='Go!'></td></tr>\n";
e673ee24
DO
2841 echo "</form></table>\n";
2842 finishPortlet();
7f791d1d 2843
f60bb422 2844 startPortlet ('Same type, same tags');
20c901a7 2845 echo "<form name=veryfastform method=post action='${root}?page=${pageno}&tab=${tabno}'>";
f60bb422
DO
2846 echo "<table border=0 align=center><tr><th>names</th><th>type</th></tr>";
2847 echo "<tr><td rowspan=3><textarea name=namelist cols=40 rows=25>\n";
ce4d1a79 2848 if ($keepvalues2 and $global_type_id == 0)
7f791d1d 2849 echo $_REQUEST['namelist'];
f60bb422
DO
2850 echo "</textarea></td><td valign=top>";
2851 printSelect ($typelist, "global_type_id", getConfigVar ('DEFAULT_OBJECT_TYPE'));
2852 echo "</td></tr>";
2853 echo "<tr><th>Tags</th></tr>";
2854 echo "<tr><td valign=top>";
2855 renderTagSelect();
2856 echo "</td></tr>";
2857 echo "<tr><td colspan=2><input type=submit name=got_very_fast_data value='Go!'></td></tr></table>\n";
2858 echo "</form>\n";
7f791d1d 2859 finishPortlet();
e673ee24
DO
2860}
2861
2862function printGreeting ()
2863{
59cd003e 2864 global $remote_username, $accounts, $root;
e673ee24 2865 $account = $accounts[$remote_username];
7056988c
DO
2866 $person = empty ($account['user_realname']) ? $account['user_name'] : $account['user_realname'];
2867 echo "Hello, ${person}. This is RackTables " . CODE_VERSION . ". Click <a href='${root}?logout'>here</a> to logout.";
e673ee24
DO
2868}
2869
2870function renderSearchResults ()
2871{
2872 global $remote_username, $root;
2873 $terms = trim ($_REQUEST['q']);
2874 if (empty ($terms))
2875 {
591ff2c4 2876 showError ('Search string cannot be empty.', __FUNCTION__);
e673ee24
DO
2877 return;
2878 }
54522168 2879 if (!permitted ('objects', 'default'))
e673ee24 2880 {
591ff2c4 2881 showError ('You are not authorized for viewing information about objects.', __FUNCTION__);
e673ee24
DO
2882 return;
2883 }
ea5fc465 2884 $nhits = 0;
e673ee24
DO
2885 // If we search for L2 address, we can either find one or find none.
2886 if
2887 (
2888 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
2889 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
2890 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
2891 // STP bridge ID: bridge priotity + port MAC address. Cut off first 4 chars and look for MAC address.
2892 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
2893 )
2894 // Search for L2 address.
2895 {
3ec29bf4
DO
2896 $terms = str_replace ('.', '', $terms);
2897 $terms = str_replace (':', '', $terms);
ea5fc465 2898 $terms = substr ($terms, -12);
e673ee24
DO
2899 $result = searchByl2address ($terms);
2900 if ($result !== NULL)
2901 {
ea5fc465
DO
2902 $nhits++;
2903 $lasthit = 'port';
2904 $summary['port'][] = $result;
e673ee24 2905 }
e673ee24
DO
2906 }
2907 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))
2908 // Search for IP address.
2909 {
bb0a44e9 2910 if (NULL !== getIPv4AddressNetworkId ($terms))
e673ee24 2911 {
ea5fc465 2912 $nhits++;
f3d0cb20
DO
2913 $lasthit = 'ipv4addressbydq';
2914 $summary['ipv4addressbydq'][] = $terms;
e673ee24 2915 }
e673ee24
DO
2916 }
2917 else
ea5fc465 2918 // Search for objects, addresses, networks, virtual services and RS pools by their description.
e673ee24 2919 {
ea5fc465
DO
2920 $tmp = getObjectSearchResults ($terms);
2921 if (count ($tmp))
e673ee24 2922 {
ea5fc465
DO
2923 $nhits += count ($tmp);
2924 $lasthit = 'object';
2925 $summary['object'] = $tmp;
e673ee24 2926 }
ea5fc465
DO
2927 $tmp = getIPv4AddressSearchResult ($terms);
2928 if (count ($tmp))
e673ee24 2929 {
ea5fc465 2930 $nhits += count ($tmp);
f3d0cb20
DO
2931 $lasthit = 'ipv4addressbydescr';
2932 $summary['ipv4addressbydescr'] = $tmp;
ea5fc465
DO
2933 }
2934 $tmp = getIPv4PrefixSearchResult ($terms);
2935 if (count ($tmp))
2936 {
2937 $nhits += count ($tmp);
2938 $lasthit = 'ipv4network';
2939 $summary['ipv4network'] = $tmp;
2940 }
05411ccd
DO
2941 $tmp = getIPv4RSPoolSearchResult ($terms);
2942 if (count ($tmp))
2943 {
2944 $nhits += count ($tmp);
2945 $lasthit = 'ipv4rspool';
2946 $summary['ipv4rspool'] = $tmp;
2947 }
2948 $tmp = getIPv4VServiceSearchResult ($terms);
2949 if (count ($tmp))
2950 {
2951 $nhits += count ($tmp);
2952 $lasthit = 'ipv4vs';
2953 $summary['ipv4vs'] = $tmp;
2954 }
6a88e734
DO
2955 $tmp = getAccountSearchResult ($terms);
2956 if (count ($tmp))
2957 {
2958 $nhits += count ($tmp);
2959 $lasthit = 'user';
2960 $summary['user'] = $tmp;
2961 }
ea5fc465
DO
2962 }
2963 if ($nhits == 0)
2964 echo "<center><h2>Nothing found for '${terms}'</h2></center>";
2965 elseif ($nhits == 1)
2966 {
2967 $record = current ($summary[$lasthit]);
2968 switch ($lasthit)
2969 {
2970 case 'port':
2971 echo "<script language='Javascript'>document.location='${root}?page=object";
2972 echo "&hl_port_id=" . $record['port_id'];
2973 echo "&object_id=" . $record['object_id'] . "';//</script>";
2974 break;
f3d0cb20
DO
2975 case 'ipv4addressbydq':
2976 $parentnet = getIPv4AddressNetworkId ($record);
2977 if ($parentnet !== NULL)
79a9edb4 2978 echo "<script language='Javascript'>document.location='${root}?page=iprange&tab=default&id=${parentnet}&hl_ipv4_addr=${record}';//</script>";
f3d0cb20
DO
2979 else
2980 echo "<script language='Javascript'>document.location='${root}?page=ipaddress&ip=${record}';//</script>";
ea5fc465 2981 break;
f3d0cb20
DO
2982 case 'ipv4addressbydescr':
2983 $parentnet = getIPv4AddressNetworkId ($record['ip']);
2984 if ($parentnet !== NULL)
79a9edb4 2985 echo "<script language='Javascript'>document.location='${root}?page=iprange&tab=default&id=${parentnet}&hl_ipv4_addr=${record['ip']}';//</script>";
f3d0cb20
DO
2986 else
2987 echo "<script language='Javascript'>document.location='${root}?page=ipaddress&ip=${record['ip']}';//</script>";
ea5fc465
DO
2988 break;
2989 case 'ipv4network':
2990 echo "<script language='Javascript'>document.location='${root}?page=iprange";
2991 echo "&id=${record['id']}";
2992 echo "';//</script>";
2993 break;
2994 case 'object':
2995 echo "<script language='Javascript'>document.location='${root}?page=object&object_id=${record['id']}';//</script>";
2996 break;
05411ccd 2997 case 'ipv4rspool':
0e692350 2998 echo "<script language='Javascript'>document.location='${root}?page=ipv4rsp&pool_id=${record['pool_id']}';//</script>";
05411ccd
DO
2999 break;
3000 case 'ipv4vs':
49fb2686 3001 echo "<script language='Javascript'>document.location='${root}?page=ipv4vs&vs_id=${record['id']}';//</script>";
05411ccd 3002 break;
6a88e734
DO
3003 case 'user':
3004 echo "<script language='Javascript'>document.location='${root}?page=user&user_id=${record['user_id']}';//</script>";
3005 break;
ea5fc465
DO
3006 }
3007 return;
3008 }
3009 else
3010 {
3011 global $nextorder;
3012 $order = 'odd';
3013 echo "<center><h2>${nhits} result(s) found for '${terms}'</h2></center>";
3014 foreach ($summary as $where => $what)
3015 switch ($where)
e673ee24 3016 {
ea5fc465 3017 case 'object':
06adfe89 3018 startPortlet ("<a href='${root}?page=objects'>Objects</a>");
ea5fc465
DO
3019 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
3020 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>barcode</th></tr>';
3021 foreach ($what as $obj)
3022 {
3023 echo "<tr class=row_${order}><td><a href=\"${root}?page=object&object_id=${obj['id']}\">${obj['dname']}</a></td>";
3024 echo "<td>${obj['label']}</td>";
3025 echo "<td>${obj['asset_no']}</td>";
3026 echo "<td>${obj['barcode']}</td></tr>";
3027 $order = $nextorder[$order];
3028 }
3029 echo '</table>';
3030 finishPortlet();
3031 break;
3032 case 'ipv4network':
06adfe89 3033 startPortlet ("<a href='${root}?page=ipv4space'>IPv4 networks</a>");
ea5fc465 3034 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
3c41194e 3035 echo '<tr><th>network</th><th>name/tags</th></tr>';
71287f1c 3036 foreach ($what as $netinfo)
ea5fc465 3037 {
71287f1c
DO
3038 echo "<tr class=row_${order} valign=top>";
3039 printIPv4NetInfoTDs ($netinfo);
3040 echo "</tr>\n";
ea5fc465
DO
3041 $order = $nextorder[$order];
3042 }
3043 echo '</table>';
3044 finishPortlet();
3045 break;
f3d0cb20 3046 case 'ipv4addressbydescr':
ea5fc465
DO
3047 startPortlet ('IPv4 addresses');
3048 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
f3d0cb20 3049 // FIXME: address, parent network, routers (if extended view is enabled)
ea5fc465
DO
3050 echo '<tr><th>Address</th><th>Descritpion</th></tr>';
3051 foreach ($what as $addr)
3052 {
f3d0cb20
DO
3053 echo "<tr class=row_${order}><td class=tdleft>";
3054 $parentnet = getIPv4AddressNetworkId ($addr['ip']);
3055 if ($parentnet !== NULL)
3056 echo "<a href='${root}?page=iprange&id=${parentnet}&hl_ipv4_addr=${addr['ip']}'>${addr['ip']}</a></td>";
3057 else
3058 echo "<a href='${root}?page=ipaddress&ip=${addr['ip']}'>${addr['ip']}</a></td>";
ea5fc465
DO
3059 echo "<td class=tdleft>${addr['name']}</td></tr>";
3060 $order = $nextorder[$order];
3061 }
3062 echo '</table>';
3063 finishPortlet();
3064 break;
05411ccd 3065 case 'ipv4rspool':
ee437dab 3066 startPortlet ("<a href='${root}?page=ipv4rsplist'>RS pools</a>");
05411ccd
DO
3067 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
3068 foreach ($what as $rspool)
3069 {
0e692350 3070 echo "<tr class=row_${order}><td class=tdleft><a href='${root}?page=ipv4rsp&pool_id=${rspool['pool_id']}'>";
05411ccd
DO
3071 echo buildRSPoolName ($rspool);
3072 echo "</a></td></tr>";
3073 $order = $nextorder[$order];
3074 }
3075 echo '</table>';
3076 finishPortlet();
3077 break;
3078 case 'ipv4vs':
a239e016 3079 startPortlet ("<a href='${root}?page=ipv4vslist'>Virtual services</a>");
05411ccd
DO
3080 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
3081 echo '<tr><th>VS</th><th>Descritpion</th></tr>';
3082 foreach ($what as $vs)
3083 {
49fb2686 3084 echo "<tr class=row_${order}><td class=tdleft><a href='${root}?page=ipv4vs&vs_id=${vs['id']}'>";
05411ccd 3085 echo buildVServiceName ($vs);
6a88e734
DO
3086 echo "</a></td><td class=tdleft>${vs['name']}</td></tr>";
3087 $order = $nextorder[$order];
3088 }
3089 echo '</table>';
3090 finishPortlet();
3091 break;
3092 case 'user':
3093 startPortlet ("<a href='${root}?page=userlist'>Users</a>");
3094 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
3095 echo '<tr><th>username</th><th>realname</th></tr>';
3096 foreach ($what as $item)
3097 {
3098 echo "<tr class=row_${order}><td class=tdleft><a href='${root}?page=user&user_id=${item['user_id']}'>";
3099 echo $item['user_name'];
3100 echo "</a></td><td class=tdleft>${item['user_realname']}</td></tr>";
05411ccd
DO
3101 $order = $nextorder[$order];
3102 }
3103 echo '</table>';
3104 finishPortlet();
3105 break;
e673ee24 3106 }
e673ee24
DO
3107 }
3108}
3109
3110// This function prints a table of checkboxes to aid the user in toggling mount atoms
3111// from one state to another. The first argument is rack data as
3112// produced by getRackData(), the second is the value used for the 'unckecked' state
3113// and the third is the value used for 'checked' state.
3114// Usage contexts:
3115// for mounting an object: printAtomGrid ($data, 'F', 'T')
3116// for changing rack design: printAtomGrid ($data, 'A', 'F')
3117// for adding rack problem: printAtomGrid ($data, 'F', 'U')
3118// for adding object problem: printAtomGrid ($data, 'T', 'W')
3119
3120function renderAtomGrid ($data)
3121{
3122 $rack_id = $data['id'];
3123 for ($unit_no = $data['height']; $unit_no > 0; $unit_no--)
3124 {
3125 echo "<tr><th>${unit_no}</th>";
3126 for ($locidx = 0; $locidx < 3; $locidx++)
3127 {
3128 $state = $data[$unit_no][$locidx]['state'];
3129 echo "<td class=state_${state}";
3130 if (isset ($data[$unit_no][$locidx]['hl']))
3131 echo $data[$unit_no][$locidx]['hl'];
3132 echo ">";
3133 if (!($data[$unit_no][$locidx]['enabled'] === TRUE))
3134 echo '<input type=checkbox disabled>';
3135 else
3136 echo "<input type=checkbox" . $data[$unit_no][$locidx]['checked'] . " name=atom_${rack_id}_${unit_no}_${locidx}>";
3137 echo '</td>';
3138 }
3139 echo "</tr>\n";
3140 }
3141}
3142
59427701 3143function renderUserList ()
e673ee24 3144{
9048d42b 3145 global $nextorder, $accounts, $root, $pageno;
59427701
DO
3146 echo "<table border=0 class=objectview>\n";
3147 echo "<tr><td class=pcleft>";
e673ee24
DO
3148 startPortlet ('User accounts');
3149 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
3150 echo "<tr><th class=tdleft>Username</th><th class=tdleft>Real name</th></tr>";
3151 $order = 'odd';
59427701 3152 $tagfilter = getTagFilter();
11c8e4be 3153 foreach (getUserAccounts ($tagfilter, getTFMode()) as $user)
e673ee24 3154 {
9048d42b
DO
3155 echo "<tr class=row_${order} valign=top><td class=tdleft><a href='${root}?page=user&user_id=${user['user_id']}'>";
3156 echo "${user['user_name']}</a>";
3157 $usertags = loadUserTags ($user['user_id']);
3158 if (count ($usertags))
3159 echo '<br><small>' . serializeTags ($usertags, "${root}?page=${pageno}&tab=default&") . '</small>';
3160 echo "</td><td class=tdleft>${user['user_realname']}</td></li>";
e673ee24
DO
3161 $order = $nextorder[$order];
3162 }
3163 echo '</table>';
3164 finishPortlet();
59427701
DO
3165 echo '</td><td class=pcright>';
3166 renderTagFilterPortlet ($tagfilter, 'user');
3167 echo "</td></tr></table>\n";
e673ee24
DO
3168}
3169
59427701 3170function renderUserListEditor ()
e673ee24 3171{
39b4abd0
DO
3172 function printNewItemTR ()
3173 {
3174 printOpFormIntro ('createUser');
3175 echo "<tr><td>&nbsp;</td><td><input type=text size=16 name=username tabindex=100></td>\n";
3176 echo "<td><input type=text size=24 name=realname tabindex=101></td>";
3177 echo "<td><input type=password size=64 name=password tabindex=102></td><td>";
3178 printImageHREF ('create', 'Add new account', TRUE, 103);
3179 echo "</td></tr></form>";
3180 }
e673ee24
DO
3181 global $root, $pageno, $tabno, $accounts;
3182 startPortlet ('User accounts');
3183 showMessageOrError();
3184 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
623457f8 3185 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
3186 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
3187 printNewItemTR();
e673ee24
DO
3188 foreach ($accounts as $account)
3189 {
7056988c
DO
3190 printOpFormIntro ('updateUser', array ('user_id' => $account['user_id']));
3191 echo "<tr><td>";
e673ee24
DO
3192 if ($account['user_enabled'] == 'yes' && $account['user_id'] != 1)
3193 {
59427701 3194 echo "<a href='${root}process.php?op=disableUser&page=${pageno}&tab=${tabno}&user_id=${account['user_id']}'>";
e673ee24
DO
3195 printImageHREF ('blockuser', 'disable account');
3196 echo "</a>\n";
3197 }
3198 if ($account['user_enabled'] == 'no' && $account['user_id'] != 1)
3199 {
59427701 3200 echo "<a href='${root}process.php?op=enableUser&page=${pageno}&tab=${tabno}&user_id=${account['user_id']}'>";
e673ee24
DO
3201 printImageHREF ('unblockuser', 'enable account');
3202 echo "</a>\n";
3203 }
3204 // Otherwise skip icon.
3205 echo "</td>";
3206 echo "<td><input type=text name=username value='${account['user_name']}' size=16></td>";
3207 echo "<td><input type=text name=realname value='${account['user_realname']}' size=24></td>";
8e5763a7
DO
3208 echo "<td><input type=password name=password value='${account['user_password_hash']}' size=64></td><td>";
3209 printImageHREF ('save', 'Save changes', TRUE);
3210 echo "</td></form></tr>\n";
e673ee24 3211 }
39b4abd0
DO
3212 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
3213 printNewItemTR();
e673ee24
DO
3214 echo "</table><br>\n";
3215 finishPortlet();
3216}
3217
17c32f4c
DO
3218function renderPortMapViewer ()
3219{
3220 renderPortMap (FALSE);
3221}
3222
3223function renderPortMapEditor ()
3224{
3225 renderPortMap (TRUE);
3226}
3227
e673ee24
DO
3228function renderPortMap ($editable = FALSE)
3229{
3230 global $nextorder, $root, $pageno, $tabno;
3231 showMessageOrError();
3232 startPortlet ("Port compatibility map");
3233 $ptlist = getPortTypes();
3234 $pclist = getPortCompat();
3235 $pctable = buildPortCompatMatrixFromList ($ptlist, $pclist);
3236 if ($editable)
7056988c 3237 printOpFormIntro ('save');
e673ee24
DO
3238 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
3239 echo "<tr><th class=vert_th>&nbsp;</th>";
3240 foreach ($ptlist as $name2)
3241 echo "<th>to ${name2}</th>";
3242 echo "</tr>";
3243 // Make a copy to have an independent array pointer.
3244 $ptlistY = $ptlist;
3245 $order = 'odd';
3246 foreach ($ptlistY as $type1 => $name1)
3247 {
3248 echo "<tr class=row_${order}><th class=vert_th style='border-bottom: 0px;'>from $name1</th>";
3249 foreach ($ptlist as $type2 => $name2)
3250 {
92b38217 3251 echo '<td' . ($pctable[$type1][$type2] ? " class=portmap_highlight_$order" : '') . '>';
19acd465 3252 echo '<input type=checkbox' . ($editable ? " name=atom_${type1}_${type2}" : ' disabled');
e673ee24
DO
3253 echo ($pctable[$type1][$type2] ? ' checked' : '') . '></td>';
3254 }
3255 echo "</tr>\n";
3256 $order = $nextorder[$order];
3257 }
3258 echo '</table><br>';
3259 if ($editable)
3260 {
7056988c 3261 printImageHREF ('SAVE', 'Save changes', TRUE);
e673ee24
DO
3262 echo "</form>";
3263 }
3264 finishPortlet();
3265}
3266
3267function renderConfigMainpage ()
3268{
3269 global $pageno, $root;
3270 $children = getDirectChildPages ($pageno);
3271 echo '<ul>';
27ef67da
DO
3272 // FIXME: assume all config kids to have static titles at the moment,
3273 // but use some proper abstract function later.
e673ee24 3274 foreach ($children as $cpageno => $child)
27ef67da 3275 echo "<li><a href='${root}?page=${cpageno}'>" . $child['title'] . "</li>\n";
e673ee24
DO
3276 echo '';
3277 echo '</ul>';
3278}
3279
3280function renderRackPage ($rack_id)
3281{
3282 if ($rack_id == 0)
3283 {
7056988c 3284 showError ('Invalid argument', __FUNCTION__);
e673ee24
DO
3285 return;
3286 }
3287 if (($rackData = getRackData ($rack_id)) == NULL)
3288 {
591ff2c4 3289 showError ('getRackData() failed', __FUNCTION__);
e673ee24
DO
3290 return;
3291 }
3292 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0><tr>";
3293
3294 // Left column with information.
3295 echo "<td class=pcleft>";
254673dd 3296 renderRackInfoPortlet ($rackData);
e673ee24
DO
3297 echo '</td>';
3298
3299 // Right column with rendered rack.
3300 echo '<td>';
3301 startPortlet ('Rack diagram');
3302 renderRack ($rack_id);
3303 finishPortlet();
3304 echo '</td>';
3305
3306 echo '</tr></table>';
3307}
3308
3309function renderDictionary ()
3310{
3311 global $nextorder;
2dd59b15 3312 $dict = getDict (TRUE);
aa28ebdf 3313 echo "<br><table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
aa28ebdf
DO
3314 foreach ($dict as $chapter_no => $chapter)
3315 {
a22ec5b4 3316 $order = 'odd';
83d2fcca 3317 echo "<tr><th>Chapter</th><th>refs</th><th>Word</th></tr>\n";
aa28ebdf
DO
3318 $wc = count ($chapter['word']);
3319 echo "<tr class=row_${order}><td class=tdleft" . ($wc ? " rowspan = ${wc}" : '');
3320 echo "><div title='number=${chapter_no}'>${chapter['name']} (${wc} records)</div></td>";
3321 if (!$wc)
3322 echo "<td colspan=2>none</td>";
3323 else
e673ee24 3324 {
aa28ebdf
DO
3325 $chap_start = TRUE;
3326 foreach ($chapter['word'] as $key => $value)
3327 {
3328 if (!$chap_start)
3329 echo "<tr class=row_${order}>";
3330 else
3331 $chap_start = FALSE;
6bb8e41d
DO
3332 echo '<td>' . ($chapter['refcnt'][$key] ? $chapter['refcnt'][$key] : '&nbsp;') . '</td>';
3333 echo "<td><div title='key=${key}'>${value}</div></td></tr>\n";
aa28ebdf
DO
3334 $order = $nextorder[$order];
3335 }
e673ee24 3336 }
e673ee24 3337 }
2dd59b15 3338 echo "</table>\n<br>";
e673ee24
DO
3339}
3340
3341function renderDictionaryEditor ()
3342{
f632bd28 3343 global $root, $pageno, $tabno, $nextorder;
e673ee24 3344 $dict = getDict();
95d80773 3345 showMessageOrError();
f632bd28
DO
3346 echo "<br><table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
3347 foreach ($dict as $chapter_no => $chapter)
e673ee24 3348 {
f632bd28 3349 $order = 'odd';
b2f9fa84 3350 echo "<tr><th>Chapter</th><th>&nbsp;</th><th>Word</th><th>&nbsp;</th></tr>\n";
f632bd28
DO
3351 $wc = count ($chapter['word']);