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