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