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