4 * This file contains frontend functions for RackTables.
8 // Interface function's special.
9 $nextorder['odd'] = 'even';
10 $nextorder['even'] = 'odd';
12 // address allocation type
15 'regular' => 'Connected',
16 'virtual' => 'Loopback',
20 // address allocation code, IPv4 addresses and objects view
24 'virtual' => '<strong>L</strong>',
25 'shared' => '<strong>S</strong>',
26 'router' => '<strong>R</strong>',
28 // address allocation code, IPv4 networks view
32 'virtual' => '<strong>L:</strong>',
33 'shared' => '<strong>S:</strong>',
34 'router' => '<strong>R:</strong>',
47 'compulsory' => 'permanent',
48 # 'alien' => 'never touch',
51 // 802.1Q deploy queue titles
54 'sync_aging' => 'Normal, aging',
55 'resync_aging' => 'Version conflict, aging',
56 'sync_ready' => 'Normal, ready for sync',
57 'resync_ready' => 'Version conflict, ready for retry',
59 'disabled' => 'Sync disabled',
60 'done' => 'Up to date',
64 $port_role_options = array
67 'access' => 'user: access only',
68 'trunk' => 'user: trunk only',
69 'anymode' => 'user: any mode',
70 'uplink' => 'system: uplink trunk',
71 'downlink' => 'system: downlink trunk',
74 // Let's have it here, so extensions can add their own images.
76 $image['error']['path'] = 'pix/error.png';
77 $image['error']['width'] = 76;
78 $image['error']['height'] = 17;
79 $image['logo']['path'] = 'pix/defaultlogo.png';
80 $image['logo']['width'] = 210;
81 $image['logo']['height'] = 40;
82 $image['rackspace']['path'] = 'pix/racks.png';
83 $image['rackspace']['width'] = 218;
84 $image['rackspace']['height'] = 200;
85 $image['objects']['path'] = 'pix/server.png';
86 $image['objects']['width'] = 218;
87 $image['objects']['height'] = 200;
88 $image['depot']['path'] = 'pix/server.png';
89 $image['depot']['width'] = 218;
90 $image['depot']['height'] = 200;
91 $image['files']['path'] = 'pix/files.png';
92 $image['files']['width'] = 218;
93 $image['files']['height'] = 200;
94 $image['ipv4space']['path'] = 'pix/addressspace.png';
95 $image['ipv4space']['width'] = 218;
96 $image['ipv4space']['height'] = 200;
97 $image['ipv6space']['path'] = 'pix/addressspacev6.png';
98 $image['ipv6space']['width'] = 218;
99 $image['ipv6space']['height'] = 200;
100 $image['ipv4slb']['path'] = 'pix/slb.png';
101 $image['ipv4slb']['width'] = 218;
102 $image['ipv4slb']['height'] = 200;
103 $image['config']['path'] = 'pix/configuration.png';
104 $image['config']['width'] = 218;
105 $image['config']['height'] = 200;
106 $image['reports']['path'] = 'pix/report.png';
107 $image['reports']['width'] = 218;
108 $image['reports']['height'] = 200;
109 $image['8021q']['path'] = 'pix/8021q.png';
110 $image['8021q']['width'] = 218;
111 $image['8021q']['height'] = 200;
112 $image['download']['path'] = 'pix/download.png';
113 $image['download']['width'] = 16;
114 $image['download']['height'] = 16;
115 $image['DOWNLOAD']['path'] = 'pix/download-big.png';
116 $image['DOWNLOAD']['width'] = 32;
117 $image['DOWNLOAD']['height'] = 32;
118 $image['plug']['path'] = 'pix/tango-network-wired.png';
119 $image['plug']['width'] = 16;
120 $image['plug']['height'] = 16;
121 $image['cut']['path'] = 'pix/tango-edit-cut-16x16.png';
122 $image['cut']['width'] = 16;
123 $image['cut']['height'] = 16;
124 $image['Cut']['path'] = 'pix/tango-edit-cut-22x22.png';
125 $image['Cut']['width'] = 22;
126 $image['Cut']['height'] = 22;
127 $image['CUT']['path'] = 'pix/tango-edit-cut-32x32.png';
128 $image['CUT']['width'] = 32;
129 $image['CUT']['height'] = 32;
130 $image['add']['path'] = 'pix/tango-list-add.png';
131 $image['add']['width'] = 16;
132 $image['add']['height'] = 16;
133 $image['ADD']['path'] = 'pix/tango-list-add-big.png';
134 $image['ADD']['width'] = 32;
135 $image['ADD']['height'] = 32;
136 $image['delete']['path'] = 'pix/tango-list-remove.png';
137 $image['delete']['width'] = 16;
138 $image['delete']['height'] = 16;
139 $image['DELETE']['path'] = 'pix/tango-list-remove-32x32.png';
140 $image['DELETE']['width'] = 32;
141 $image['DELETE']['height'] = 32;
142 $image['destroy']['path'] = 'pix/tango-user-trash-16x16.png';
143 $image['destroy']['width'] = 16;
144 $image['destroy']['height'] = 16;
145 $image['nodestroy']['path'] = 'pix/tango-user-trash-16x16-gray.png';
146 $image['nodestroy']['width'] = 16;
147 $image['nodestroy']['height'] = 16;
148 $image['NODESTROY']['path'] = 'pix/tango-user-trash-32x32-gray.png';
149 $image['NODESTROY']['width'] = 32;
150 $image['NODESTROY']['height'] = 32;
151 $image['DESTROY']['path'] = 'pix/tango-user-trash-32x32.png';
152 $image['DESTROY']['width'] = 32;
153 $image['DESTROY']['height'] = 32;
154 $image['nodelete']['path'] = 'pix/tango-list-remove-shadow.png';
155 $image['nodelete']['width'] = 16;
156 $image['nodelete']['height'] = 16;
157 $image['inservice']['path'] = 'pix/tango-emblem-system.png';
158 $image['inservice']['width'] = 16;
159 $image['inservice']['height'] = 16;
160 $image['notinservice']['path'] = 'pix/tango-dialog-error.png';
161 $image['notinservice']['width'] = 16;
162 $image['notinservice']['height'] = 16;
163 $image['find']['path'] = 'pix/tango-system-search.png';
164 $image['find']['width'] = 16;
165 $image['find']['height'] = 16;
166 $image['next']['path'] = 'pix/tango-go-next.png';
167 $image['next']['width'] = 32;
168 $image['next']['height'] = 32;
169 $image['prev']['path'] = 'pix/tango-go-previous.png';
170 $image['prev']['width'] = 32;
171 $image['prev']['height'] = 32;
172 $image['COMMIT']['path'] = 'pix/tango-go-prev-next-32x32.png';
173 $image['COMMIT']['width'] = 32;
174 $image['COMMIT']['height'] = 32;
175 $image['COMMIT gray']['path'] = 'pix/tango-go-prev-next-gray-32x32.png';
176 $image['COMMIT gray']['width'] = 32;
177 $image['COMMIT gray']['height'] = 32;
178 $image['RECALC']['path'] = 'pix/tango-view-refresh-32x32.png';
179 $image['RECALC']['width'] = 32;
180 $image['RECALC']['height'] = 32;
181 $image['clear']['path'] = 'pix/tango-edit-clear.png';
182 $image['clear']['width'] = 16;
183 $image['clear']['height'] = 16;
184 $image['CLEAR']['path'] = 'pix/tango-edit-clear-big.png';
185 $image['CLEAR']['width'] = 32;
186 $image['CLEAR']['height'] = 32;
187 $image['CLEAR gray']['path'] = 'pix/tango-edit-clear-gray-32x32.png';
188 $image['CLEAR gray']['width'] = 32;
189 $image['CLEAR gray']['height'] = 32;
190 $image['save']['path'] = 'pix/tango-document-save-16x16.png';
191 $image['save']['width'] = 16;
192 $image['save']['height'] = 16;
193 $image['SAVE']['path'] = 'pix/tango-document-save-32x32.png';
194 $image['SAVE']['width'] = 32;
195 $image['SAVE']['height'] = 32;
196 $image['NOSAVE']['path'] = 'pix/tango-document-save-32x32-gray.png';
197 $image['NOSAVE']['width'] = 32;
198 $image['NOSAVE']['height'] = 32;
199 $image['create']['path'] = 'pix/tango-document-new.png';
200 $image['create']['width'] = 16;
201 $image['create']['height'] = 16;
202 $image['CREATE']['path'] = 'pix/tango-document-new-big.png';
203 $image['CREATE']['width'] = 32;
204 $image['CREATE']['height'] = 32;
205 $image['DENIED']['path'] = 'pix/tango-dialog-error-big.png';
206 $image['DENIED']['width'] = 32;
207 $image['DENIED']['height'] = 32;
208 $image['node-collapsed']['path'] = 'pix/node-collapsed.png';
209 $image['node-collapsed']['width'] = 16;
210 $image['node-collapsed']['height'] = 16;
211 $image['node-expanded']['path'] = 'pix/node-expanded.png';
212 $image['node-expanded']['width'] = 16;
213 $image['node-expanded']['height'] = 16;
214 $image['node-expanded-static']['path'] = 'pix/node-expanded-static.png';
215 $image['node-expanded-static']['width'] = 16;
216 $image['node-expanded-static']['height'] = 16;
217 $image['dragons']['path'] = 'pix/mitsudragon.png';
218 $image['dragons']['width'] = 195;
219 $image['dragons']['height'] = 33;
220 $image['LB']['path'] = 'pix/loadbalancer.png';
221 $image['LB']['width'] = 32;
222 $image['LB']['height'] = 32;
223 $image['RS pool']['path'] = 'pix/serverpool.png';
224 $image['RS pool']['width'] = 48;
225 $image['RS pool']['height'] = 16;
226 $image['VS']['path'] = 'pix/servicesign.png';
227 $image['VS']['width'] = 39;
228 $image['VS']['height'] = 62;
229 $image['router']['path'] = 'pix/router.png';
230 $image['router']['width'] = 32;
231 $image['router']['height'] = 32;
232 $image['object']['path'] = 'pix/bracket-16x16.png';
233 $image['object']['width'] = 16;
234 $image['object']['height'] = 16;
235 $image['OBJECT']['path'] = 'pix/bracket-32x32.png';
236 $image['OBJECT']['width'] = 32;
237 $image['OBJECT']['height'] = 32;
238 $image['ATTACH']['path'] = 'pix/tango-mail-attachment-32x32.png';
239 $image['ATTACH']['width'] = 32;
240 $image['ATTACH']['height'] = 32;
241 $image['Attach']['path'] = 'pix/tango-mail-attachment-22x22.png';
242 $image['Attach']['width'] = 22;
243 $image['Attach']['height'] = 22;
244 $image['favorite']['path'] = 'pix/tango-emblem-favorite.png';
245 $image['favorite']['width'] = 16;
246 $image['favorite']['height'] = 16;
247 $image['computer']['path'] = 'pix/tango-computer.png';
248 $image['computer']['width'] = 16;
249 $image['computer']['height'] = 16;
250 $image['empty file']['path'] = 'pix/crystal-file-empty-32x32.png';
251 $image['empty file']['width'] = 32;
252 $image['empty file']['height'] = 32;
253 $image['text file']['path'] = 'pix/crystal-file-text-32x32.png';
254 $image['text file']['width'] = 32;
255 $image['text file']['height'] = 32;
256 $image['image file']['path'] = 'pix/crystal-file-image-32x32.png';
257 $image['image file']['width'] = 32;
258 $image['image file']['height'] = 32;
259 $image['text']['path'] = 'pix/tango-text-x-generic-16x16.png';
260 $image['text']['width'] = 16;
261 $image['text']['height'] = 16;
262 $image['NET']['path'] = 'pix/crystal-network_local-32x32.png';
263 $image['NET']['width'] = 32;
264 $image['NET']['height'] = 32;
265 $image['net']['path'] = 'pix/crystal-network_local-16x16.png';
266 $image['net']['width'] = 16;
267 $image['net']['height'] = 16;
268 $image['USER']['path'] = 'pix/crystal-edit-user-32x32.png';
269 $image['USER']['width'] = 32;
270 $image['USER']['height'] = 32;
271 $image['setfilter']['path'] = 'pix/pgadmin3-viewfiltereddata.png';
272 $image['setfilter']['width'] = 32;
273 $image['setfilter']['height'] = 32;
274 $image['setfilter gray']['path'] = 'pix/pgadmin3-viewfiltereddata-grayscale.png';
275 $image['setfilter gray']['width'] = 32;
276 $image['setfilter gray']['height'] = 32;
277 $image['resetfilter']['path'] = 'pix/pgadmin3-viewdata.png';
278 $image['resetfilter']['width'] = 32;
279 $image['resetfilter']['height'] = 32;
280 $image['resetfilter gray']['path'] = 'pix/pgadmin3-viewdata-grayscale.png';
281 $image['resetfilter gray']['width'] = 32;
282 $image['resetfilter gray']['height'] = 32;
283 $image['knight']['path'] = 'pix/smiley_knight.png';
284 $image['knight']['width'] = 72;
285 $image['knight']['height'] = 33;
286 $image['Zoom']['path'] = 'pix/tango-system-search-22x22.png';
287 $image['Zoom']['width'] = 22;
288 $image['Zoom']['height'] = 22;
289 $image['Zooming']['path'] = 'pix/tango-view-fullscreen-22x22.png';
290 $image['Zooming']['width'] = 22;
291 $image['Zooming']['height'] = 22;
292 $image['UNLOCK']['path'] = 'pix/crystal-actions-unlock-32x32.png';
293 $image['UNLOCK']['width'] = 32;
294 $image['UNLOCK']['height'] = 32;
295 $image['CLOCK']['path'] = 'pix/tango-appointment-32x32.png';
296 $image['CLOCK']['width'] = 32;
297 $image['CLOCK']['height'] = 32;
298 $image['DQUEUE done']['path'] = 'pix/crystal-ok-32x32.png';
299 $image['DQUEUE done']['width'] = 32;
300 $image['DQUEUE done']['height'] = 32;
301 $image['DQUEUE sync_aging']['path'] = 'pix/tango-appointment-32x32.png';
302 $image['DQUEUE sync_aging']['width'] = 32;
303 $image['DQUEUE sync_aging']['height'] = 32;
304 $image['DQUEUE resync_aging']['path'] = 'pix/tango-appointment-32x32.png';
305 $image['DQUEUE resync_aging']['width'] = 32;
306 $image['DQUEUE resync_aging']['height'] = 32;
307 $image['DQUEUE sync_ready']['path'] = 'pix/tango-emblem-system-32x32.png';
308 $image['DQUEUE sync_ready']['width'] = 32;
309 $image['DQUEUE sync_ready']['height'] = 32;
310 $image['DQUEUE resync_ready']['path'] = 'pix/tango-emblem-important-32x32.png';
311 $image['DQUEUE resync_ready']['width'] = 32;
312 $image['DQUEUE resync_ready']['height'] = 32;
313 $image['DQUEUE failed']['path'] = 'pix/tango-emblem-unreadable-32x32.png';
314 $image['DQUEUE failed']['width'] = 32;
315 $image['DQUEUE failed']['height'] = 32;
316 $image['DQUEUE disabled']['path'] = 'pix/tango-emblem-readonly-32x32.png';
317 $image['DQUEUE disabled']['width'] = 32;
318 $image['DQUEUE disabled']['height'] = 32;
319 $image['COPY']['path'] = 'pix/tango-edit-copy-32x32.png';
320 $image['COPY']['width'] = 32;
321 $image['COPY']['height'] = 32;
323 // This may be populated later onsite, report rendering function will use it.
324 // See the $systemreport for structure.
325 $localreports = array();
327 $CodePressMap = array
333 'js' => 'javascript',
338 'uint' => '[U] unsigned integer',
339 'float' => '[F] floating point',
340 'string' => '[S] string',
341 'dict' => '[D] dictionary record'
345 function renderIndexItem ($ypageno) {
347 if (permitted($ypageno)) {
348 $title = isset ($page[$ypageno]['title']) ?
$page[$ypageno]['title'] : dynamic_title_decoder ($ypageno);
349 if (is_array ($title))
350 $title = $title['name'];
352 print " <h1><a href='".makeHref(array('page'=>$ypageno))."'>".$title."<br>\n";
353 printImageHREF ($ypageno);
357 print " <td> </td>\n";
361 function renderIndex ()
365 <table border
=0 cellpadding
=0 cellspacing
=0 width
='100%'>
368 <div style
='text-align: center; margin: 10px; '>
369 <table width
='100%' cellspacing
=0 cellpadding
=20 class=mainmenu border
=0>
371 foreach ($indexlayout as $row)
374 foreach ($row as $column)
375 if ($column === NULL)
376 echo '<td> </td>';
378 renderIndexItem ($column);
390 function renderRackspace ()
392 $found_racks = array();
394 $cellfilter = getCellFilter();
396 foreach (getRackRows() as $row_id => $row_name) {
397 $rackList = filterCellList (listCells ('rack', $row_id), $cellfilter['expression']);
398 $found_racks = array_merge($found_racks, $rackList);
401 'row_name' => $row_name,
404 $rackCount +
= count($rackList);
407 echo "<table class=objview border=0 width='100%'><tr><td class=pcleft>";
408 renderCellFilterPortlet ($cellfilter, 'rack', $found_racks);
409 echo '</td><td class=pcright>';
411 if (! renderEmptyResults($cellfilter, 'racks', $rackCount))
413 echo '<table border=0 cellpadding=10 cellpadding=1>';
414 // generate thumb gallery
416 $rackwidth = getRackImageWidth();
417 // Zero value effectively disables the limit.
418 $maxPerRow = getConfigVar ('RACKS_PER_ROW');
420 foreach ($rows as $row)
422 $row_id = $row['row_id'];
423 $row_name = $row['row_name'];
424 $rackList = $row['racks'];
426 if (!count ($rackList) and count ($cellfilter['expression']))
429 echo "<tr class=row_${order}><th class=tdleft>";
430 echo "<a href='".makeHref(array('page'=>'row', 'row_id'=>$row_id))."${cellfilter['urlextra']}'>";
431 echo "${row_name}</a></th><td><table border=0 cellspacing=5><tr>";
432 if (!count ($rackList))
433 echo "<td>(empty row)</td>";
435 foreach ($rackList as $rack)
437 if ($rackListIdx > 0 and $maxPerRow > 0 and $rackListIdx %
$maxPerRow == 0)
439 echo '</tr></table></tr>';
440 echo "<tr class=row_${order}><th class=tdleft>${row_name} (continued)";
441 echo "</th><td><table border=0 cellspacing=5><tr>";
443 echo "<td align=center><a href='".makeHref(array('page'=>'rack', 'rack_id'=>$rack['id']))."'>";
444 echo "<img border=0 width=${rackwidth} height=";
445 echo getRackImageHeight ($rack['height']);
446 echo " title='${rack['height']} units'";
447 echo "src='render_image.php?img=minirack&rack_id=${rack['id']}'>";
448 echo "<br>${rack['name']}</a></td>";
451 $order = $nextorder[$order];
452 echo "</tr></table></tr>\n";
456 echo "</td></tr></table>\n";
459 function renderRackspaceRowEditor ()
461 function printNewItemTR ()
463 printOpFormIntro ('addRow');
465 printImageHREF ('create', 'Add new row', TRUE);
466 echo "</td><td><input type=text name=name tabindex=100></td><td>";
467 printImageHREF ('create', 'Add new row', TRUE, 101);
468 echo "</td></tr></form>";
470 startPortlet ('Rows');
471 echo "<table border=0 cellspacing=0 cellpadding=5 align=center class=widetable>\n";
472 echo "<tr><th> </th><th>Name</th><th> </th></tr>\n";
473 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
475 foreach (getRackRows() as $row_id => $row_name)
478 if ($rc = count (listCells ('rack', $row_id)))
479 printImageHREF ('nodestroy', "${rc} rack(s) here");
482 echo "<a href=\"".makeHrefProcess(array('op'=>'delete', 'row_id'=>$row_id))."\">";
483 printImageHREF ('destroy', 'Delete row');
486 printOpFormIntro ('updateRow', array ('row_id' => $row_id));
487 echo "</td><td><input type=text name=name value='${row_name}'></td><td>";
488 printImageHREF ('save', 'Save changes', TRUE);
489 echo "</form></td></tr>\n";
491 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
493 echo "</table><br>\n";
497 function renderRow ($row_id)
499 $rowInfo = getRackRowInfo ($row_id);
500 $cellfilter = getCellFilter();
501 $rackList = filterCellList (listCells ('rack', $row_id), $cellfilter['expression']);
502 // Main layout starts.
503 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
505 // Left portlet with row information.
506 echo "<tr><td class=pcleft>";
507 startPortlet ($rowInfo['name']);
508 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
509 echo "<tr><th width='50%' class=tdright>Racks:</th><td class=tdleft>${rowInfo['count']}</td></tr>\n";
510 echo "<tr><th width='50%' class=tdright>Units:</th><td class=tdleft>${rowInfo['sum']}</td></tr>\n";
511 echo "<tr><th width='50%' class=tdright>%% used:</th><td class=tdleft>";
512 renderProgressBar (getRSUforRackRow ($rackList));
514 echo "</table><br>\n";
516 renderCellFilterPortlet ($cellfilter, 'rack', $rackList, 'row_id', $row_id);
518 echo "</td><td class=pcright>";
521 $rackwidth = getRackImageWidth() * getConfigVar ('ROW_SCALE');
522 // Maximum number of racks per row is proportionally less, but at least 1.
523 $maxPerRow = max (floor (getConfigVar ('RACKS_PER_ROW') / getConfigVar ('ROW_SCALE')), 1);
526 startPortlet ('Racks');
527 echo "<table border=0 cellspacing=5 align='center'><tr>";
528 foreach ($rackList as $rack)
530 if ($rackListIdx %
$maxPerRow == 0)
532 if ($rackListIdx > 0)
536 echo "<td align=center class=row_${order}><a href='".makeHref(array('page'=>'rack', 'rack_id'=>$rack['id']))."'>";
537 echo "<img border=0 width=${rackwidth} height=" . (getRackImageHeight ($rack['height']) * getConfigVar ('ROW_SCALE'));
538 echo " title='${rack['height']} units'";
539 echo "src='render_image.php?img=minirack&rack_id=${rack['id']}'>";
540 echo "<br>${rack['name']}</a></td>";
541 $order = $nextorder[$order];
544 echo "</tr></table>\n";
546 echo "</td></tr></table>";
549 // This function renders rack as HTML table.
550 function renderRack ($rack_id, $hl_obj_id = 0)
552 $rackData = spotEntity ('rack', $rack_id);
553 amplifyCell ($rackData);
554 markAllSpans ($rackData);
556 highlightObject ($rackData, $hl_obj_id);
557 markupObjectProblems ($rackData);
558 $prev_id = getPrevIDforRack ($rackData['row_id'], $rack_id);
559 $next_id = getNextIDforRack ($rackData['row_id'], $rack_id);
560 echo "<center><table border=0><tr valign=middle>";
561 echo "<td><h2><a href='".makeHref(array('page'=>'row', 'row_id'=>$rackData['row_id']))."'>${rackData['row_name']}</a> :</h2></td>";
562 // FIXME: use 'bypass'?
563 if ($prev_id != NULL)
565 echo "<td><a href='".makeHref(array('page'=>'rack', 'rack_id'=>$prev_id))."'>";
566 printImageHREF ('prev', 'previous rack');
569 echo "<td><h2><a href='".makeHref(array('page'=>'rack', 'rack_id'=>$rackData['id']))."'>${rackData['name']}</a></h2></td>";
570 if ($next_id != NULL)
572 echo "<td><a href='".makeHref(array('page'=>'rack', 'rack_id'=>$next_id))."'>";
573 printImageHREF ('next', 'next rack');
576 echo "</h2></td></tr></table>\n";
577 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
578 echo "<tr><th width='10%'> </th><th width='20%'>Front</th>";
579 echo "<th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
580 for ($i = $rackData['height']; $i > 0; $i--)
582 echo "<tr><th>${i}</th>";
583 for ($locidx = 0; $locidx < 3; $locidx++
)
585 if (isset ($rackData[$i][$locidx]['skipped']))
587 $state = $rackData[$i][$locidx]['state'];
588 echo "<td class=state_${state}";
589 if (isset ($rackData[$i][$locidx]['hl']))
590 echo $rackData[$i][$locidx]['hl'];
591 if (isset ($rackData[$i][$locidx]['colspan']))
592 echo ' colspan=' . $rackData[$i][$locidx]['colspan'];
593 if (isset ($rackData[$i][$locidx]['rowspan']))
594 echo ' rowspan=' . $rackData[$i][$locidx]['rowspan'];
599 $objectData = spotEntity ('object', $rackData[$i][$locidx]['object_id']);
600 if (strlen ($objectData['asset_no']))
601 $prefix = "<div title='${objectData['asset_no']}";
603 $prefix = "<div title='no asset tag";
604 // Don't tell about label, if it matches common name.
605 if ($objectData['name'] != $objectData['label'] and strlen ($objectData['label']))
606 $suffix = ", visible label is \"${objectData['label']}\"'>";
609 echo $prefix . $suffix;
610 echo "<a href='".makeHref(array('page'=>'object', 'object_id'=>$objectData['id']))."'>${objectData['dname']}</a></div>";
613 echo '<div title="This rackspace does not exist"> </div>';
616 echo '<div title="Free rackspace"> </div>';
619 echo '<div title="Problematic rackspace, you CAN\'T mount here"> </div>';
622 echo '<div title="No data"> </div>';
629 echo "</table></center>\n";
632 function renderNewRackForm ($row_id)
634 startPortlet ('Add one');
635 printOpFormIntro ('addRack', array ('got_data' => 'TRUE'));
636 echo '<table border=0 align=center>';
637 $defh = getConfigVar ('DEFAULT_RACK_HEIGHT');
640 echo "<tr><th class=tdright>Rack name (*):</th><td class=tdleft><input type=text name=rack_name tabindex=1></td>";
641 echo "<td rowspan=4>Assign tags:<br>";
642 renderNewEntityTags ('rack');
644 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";
645 echo "<tr><th class=tdright>Comment:</th><td class=tdleft><input type=text name=rack_comment tabindex=3></td></tr>\n";
646 echo "<tr><td class=submit colspan=2>";
647 printImageHREF ('CREATE', 'Add', TRUE);
648 echo "</td></tr></table></form>";
651 startPortlet ('Add many');
652 printOpFormIntro ('addRack', array ('got_mdata' => 'TRUE'));
653 echo '<table border=0 align=center>';
654 $defh = getConfigVar ('DEFAULT_RACK_HEIGHT');
657 echo "<tr><th class=tdright>Height in units (*):</th><td class=tdleft><input type=text name=rack_height2 value='${defh}'></td>";
658 echo "<td rowspan=3 valign=top>Assign tags:<br>";
659 renderNewEntityTags ('rack');
661 echo "<tr><th class=tdright>Rack names (*):</th><td class=tdleft><textarea name=rack_names cols=40 rows=25></textarea></td></tr>\n";
662 echo "<tr><td class=submit colspan=2>";
663 printImageHREF ('CREATE', 'Add', TRUE);
664 echo '</form></table>';
668 function renderEditObjectForm ($object_id)
671 $object = spotEntity ('object', $object_id);
673 printOpFormIntro ('update');
676 echo '<table border=0 cellspacing=0 cellpadding=3 align=center>';
677 echo "<tr><td> </td><th colspan=2><h2>Attributes</h2></th></tr>";
678 echo "<tr><td> </td><th class=tdright>Type:</th><td class=tdleft>";
679 printNiftySelect (cookOptgroups (readChapter (CHAP_OBJTYPE
, 'o')), array ('name' => 'object_type_id'), $object['objtype_id']);
682 echo "<tr><td> </td><th class=tdright>Common name:</th><td class=tdleft><input type=text name=object_name value='${object['name']}'></td></tr>\n";
683 echo "<tr><td> </td><th class=tdright>Visible label:</th><td class=tdleft><input type=text name=object_label value='${object['label']}'></td></tr>\n";
684 echo "<tr><td> </td><th class=tdright>Asset tag:</th><td class=tdleft><input type=text name=object_asset_no value='${object['asset_no']}'></td></tr>\n";
685 echo "<tr><td> </td><th class=tdright>Barcode:</th><td class=tdleft><input type=text name=object_barcode value='${object['barcode']}'></td></tr>\n";
686 // optional attributes
687 $values = getAttrValues ($object_id);
688 echo '<input type=hidden name=num_attrs value=' . count($values) . ">\n";
689 if (count($values) > 0)
692 foreach ($values as $record)
694 echo "<input type=hidden name=${i}_attr_id value=${record['id']}>";
696 if (strlen ($record['value']))
698 echo "<a href='".makeHrefProcess(array('op'=>'clearSticker', 'object_id'=>$object_id, 'attr_id'=>$record['id']))."'>";
699 printImageHREF ('clear', 'Clear value');
705 echo "<th class=sticker>${record['name']}:</th><td class=tdleft>";
706 switch ($record['type'])
711 echo "<input type=text name=${i}_value value='${record['value']}'>";
714 $chapter = readChapter ($record['chapter_id'], 'o');
715 $chapter[0] = '-- NOT SET --';
716 $chapter = cookOptgroups ($chapter, $object['objtype_id'], $record['key']);
717 printNiftySelect ($chapter, array ('name' => "${i}_value"), $record['key']);
724 echo "<tr><td> </td><th class=tdright>Has problems:</th><td class=tdleft><input type=checkbox name=object_has_problems";
725 if ($object['has_problems'] == 'yes')
727 echo "></td></tr>\n";
728 echo "<tr><td> </td><th class=tdright>Actions:</th><td class=tdleft>";
730 makeHrefProcess(array('op'=>'deleteObject', 'page'=>'depot', 'tab'=>'addmore', 'object_id'=>$object_id)).
731 "' onclick=\"javascript:return confirm('Are you sure you want to delete the object?')\">" . getImageHREF ('destroy', 'Delete object') . "</a>";
734 makeHrefProcess(array ('op'=>'resetObject', 'page' => 'object', 'tab' => 'edit', 'object_id' => $object_id)).
735 "' onclick=\"javascript:return confirm('Are you sure you want to reset most of object properties?')\">" . getImageHREF ('clear', 'Reset (cleanup) object') . "</a>";
737 echo "<tr><td colspan=3><b>Comment:</b><br><textarea name=object_comment rows=10 cols=80>${object['comment']}</textarea></td></tr>";
739 echo "<tr><th class=submit colspan=3>";
740 printImageHREF ('SAVE', 'Save changes', TRUE);
741 echo "</form></th></tr></table>\n";
744 echo '<table border=0 width=100%><tr><td>';
745 startPortlet ('history');
746 renderHistory ($pageno, $object_id);
748 echo '</td></tr></table>';
751 // This is a clone of renderEditObjectForm().
752 function renderEditRackForm ($rack_id)
755 $rack = spotEntity ('rack', $rack_id);
758 startPortlet ('Rack attributes');
759 printOpFormIntro ('updateRack');
760 echo '<table border=0 align=center>';
761 echo "<tr><th class=tdright>Rack row:</th><td class=tdleft>";
762 printSelect (getRackRows(), array ('name' => 'rack_row_id'), $rack['row_id']);
764 echo "<tr><th class=tdright>Name (required):</th><td class=tdleft><input type=text name=rack_name value='${rack['name']}'></td></tr>\n";
765 echo "<tr><th class=tdright>Height (required):</th><td class=tdleft><input type=text name=rack_height value='${rack['height']}'></td></tr>\n";
766 echo "<tr><th class=tdright>Comment:</th><td class=tdleft><input type=text name=rack_comment value='${rack['comment']}'></td></tr>\n";
767 if (count ($rack['mountedObjects']) == 0)
769 echo "<tr><th class=tdright>Actions:</th><td class=tdleft><a href='".
770 makeHrefProcess(array('op'=>'deleteRack', 'rack_id'=>$rack_id)).
771 "' onclick=\"javascript:return confirm('Are you sure you want to delete the rack?')\">Delete rack</a></td></tr>\n";
773 echo "<tr><td class=submit colspan=2>";
774 printImageHREF ('SAVE', 'Save changes', TRUE);
776 echo '</form></table><br>';
779 startPortlet ('History');
780 renderHistory ($pageno, $rack_id);
784 function printSelect ($optionList, $select_attrs = array(), $selected_id = NULL, $autocomplete = false)
786 echo getSelect ($optionList, $select_attrs, $selected_id);
789 // Input array keys are OPTION VALUEs and input array values are OPTION text.
790 function getSelect ($optionList, $select_attrs = array(), $selected_id = NULL)
793 if (!array_key_exists ('name', $select_attrs))
795 // handle two corner cases in a specific way
796 if (count ($optionList) == 0)
798 if (count ($optionList) == 1)
800 $value = current (array_keys ($optionList));
801 return "<input type=hidden name=${select_attrs['name']} id=${select_attrs['name']} value=${value}>" . current ($optionList);
803 if (!array_key_exists ('id', $select_attrs))
804 $select_attrs['id'] = $select_attrs['name'];
806 foreach ($select_attrs as $attr_name => $attr_value)
807 $ret .= " ${attr_name}=${attr_value}";
809 foreach ($optionList as $dict_key => $dict_value)
810 $ret .= "<option value='${dict_key}'" . ($dict_key == $selected_id ?
' selected' : '') . ">${dict_value}</option>";
815 function printNiftySelect ($groupList, $select_attrs = array(), $selected_id = NULL, $autocomplete = false)
817 echo getNiftySelect ($groupList, $select_attrs, $selected_id);
820 // Input is a cooked list of OPTGROUPs, each with own sub-list of OPTIONs in the same
821 // format as printSelect() expects.
822 function getNiftySelect ($groupList, $select_attrs, $selected_id = NULL)
824 // special treatment for ungrouped data
825 if (count ($groupList) == 1 and isset ($groupList['other']))
826 return getSelect ($groupList['other'], $select_attrs, $selected_id);
827 if (!array_key_exists ('name', $select_attrs))
829 if (!array_key_exists ('id', $select_attrs))
830 $select_attrs['id'] = $select_attrs['name'];
832 foreach ($select_attrs as $attr_name => $attr_value)
833 $ret .= " ${attr_name}=${attr_value}";
835 foreach ($groupList as $groupname => $groupdata)
837 $ret .= "<optgroup label='${groupname}'>";
838 foreach ($groupdata as $dict_key => $dict_value)
839 $ret .= "<option value='${dict_key}'" . ($dict_key == $selected_id ?
' selected' : '') . ">${dict_value}</option>";
840 $ret .= '</optgroup>';
846 // used by renderGridForm() and renderRackPage()
847 function renderRackInfoPortlet ($rackData)
849 startPortlet ('summary');
850 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
851 echo "<tr><th width='50%' class=tdright>Rack row:</th><td class=tdleft>${rackData['row_name']}</td></tr>\n";
852 echo "<tr><th width='50%' class=tdright>Name:</th><td class=tdleft>${rackData['name']}</td></tr>\n";
853 echo "<tr><th width='50%' class=tdright>Height:</th><td class=tdleft>${rackData['height']}</td></tr>\n";
854 echo "<tr><th width='50%' class=tdright>%% used:</th><td class=tdleft>";
855 renderProgressBar (getRSUforRack ($rackData));
857 echo "<tr><th width='50%' class=tdright>Objects:</th><td class=tdleft>";
858 echo count ($rackData['mountedObjects']);
860 printTagTRs ($rackData, makeHref(array('page'=>'rackspace', 'tab'=>'default'))."&");
861 if (strlen ($rackData['comment']))
862 echo "<tr><th width='50%' class=tdright>Comment:</th><td class=tdleft>${rackData['comment']}</td></tr>\n";
867 // This is a universal editor of rack design/waste.
868 // FIXME: switch to using printOpFormIntro()
869 function renderGridForm ($rack_id, $filter, $header, $submit, $state1, $state2)
871 $rackData = spotEntity ('rack', $rack_id);
872 amplifyCell ($rackData);
874 markupObjectProblems ($rackData);
876 // Render the result whatever it is.
878 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
879 echo "<tr><td colspan=2 align=center><h1>${rackData['name']}</h1></td></tr>\n";
881 // Left column with information portlet.
882 echo "<tr><td class=pcleft height='1%' width='50%'>";
883 renderRackInfoPortlet ($rackData);
885 echo "<td class=pcright>";
888 startPortlet ($header);
890 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
891 echo "<tr><th width='10%'> </th>";
892 echo "<th width='20%'><a href='javascript:;' oncontextmenu=\"blockToggleColumnOfAtoms('${rack_id}', '0', ${rackData['height']}); return false;\" onclick=\"toggleColumnOfAtoms('${rack_id}', '0', ${rackData['height']})\">Front</a></th>";
893 echo "<th width='50%'><a href='javascript:;' oncontextmenu=\"blockToggleColumnOfAtoms('${rack_id}', '1', ${rackData['height']}); return false;\" onclick=\"toggleColumnOfAtoms('${rack_id}', '1', ${rackData['height']})\">Interior</a></th>";
894 echo "<th width='20%'><a href='javascript:;' oncontextmenu=\"blockToggleColumnOfAtoms('${rack_id}', '2', ${rackData['height']}); return false;\" onclick=\"toggleColumnOfAtoms('${rack_id}', '2', ${rackData['height']})\">Back</a></th></tr>\n";
895 printOpFormIntro ('updateRack');
896 markupAtomGrid ($rackData, $state2);
897 renderAtomGrid ($rackData);
898 echo "</table></center>\n";
899 echo "<br><input type=submit name=do_update value='${submit}'></form><br><br>\n";
901 echo "</td></tr></table>\n";
904 function renderRackDesign ($rack_id)
906 renderGridForm ($rack_id, 'applyRackDesignMask', 'Rack design', 'Set rack design', 'A', 'F');
909 function renderRackProblems ($rack_id)
911 renderGridForm ($rack_id, 'applyRackProblemMask', 'Rack problems', 'Mark unusable atoms', 'F', 'U');
914 function startPortlet ($title = '')
916 echo "<div class=portlet><h2>${title}</h2>";
919 function finishPortlet ()
924 function renderRackObject ($object_id)
926 global $nextorder, $aac;
927 $info = spotEntity ('object', $object_id);
928 // FIXME: employ amplifyCell() instead of calling loader functions directly
930 // Main layout starts.
931 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
932 echo "<tr><td colspan=2 align=center><h1>${info['dname']}</h1></td></tr>\n";
933 // left column with uknown number of portlets
934 echo "<tr><td class=pcleft>";
935 startPortlet ('summary');
936 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
937 if (strlen ($info['name']))
938 echo "<tr><th width='50%' class=tdright>Common name:</th><td class=tdleft>${info['name']}</td></tr>\n";
939 // FIXME: don't call spotEntity() each time, do it once in the beginning.
940 elseif (considerConfiguredConstraint ($info, 'NAMEWARN_LISTSRC'))
941 echo "<tr><td colspan=2 class=msg_error>Common name is missing.</td></tr>\n";
942 echo "<tr><th width='50%' class=tdright>Object type:</th><td class=tdleft><a href='";
943 echo makeHref (array (
946 'cfe' => '{$typeid_' . $info['objtype_id'] . '}'
948 echo "'>" . decodeObjectType ($info['objtype_id'], 'o') . '</a></td></tr>';
949 if (strlen ($info['asset_no']))
950 echo "<tr><th width='50%' class=tdright>Asset tag:</th><td class=tdleft>${info['asset_no']}</td></tr>\n";
952 elseif (considerConfiguredConstraint ($info, 'ASSETWARN_LISTSRC'))
953 echo "<tr><td colspan=2 class=msg_error>Asset tag is missing.</td></tr>\n";
954 if (strlen ($info['label']))
955 echo "<tr><th width='50%' class=tdright>Visible label:</th><td class=tdleft>${info['label']}</td></tr>\n";
956 if (strlen ($info['barcode']))
957 echo "<tr><th width='50%' class=tdright>Barcode:</th><td class=tdleft>${info['barcode']}</td></tr>\n";
958 if ($info['has_problems'] == 'yes')
959 echo "<tr><td colspan=2 class=msg_error>Has problems</td></tr>\n";
960 foreach (getAttrValues ($object_id) as $attr_id => $record)
961 if (strlen ($record['value']))
963 echo "<tr><th width='50%' class=sticker>${record['name']}:</th><td class=sticker>" .
964 formatAttributeValue($attr_id, $record) .
977 'cfe' => '{$typeid_' . $info['objtype_id'] . '}',
981 echo "</table><br>\n";
984 if (strlen ($info['comment']))
986 startPortlet ('Comment');
987 echo '<div class=commentblock>' . string_insert_hrefs ($info['comment']) . '</div>';
991 renderFilesPortlet ('object', $object_id);
993 if (count ($info['ports']))
995 startPortlet ('ports and links');
997 if (isset ($_REQUEST['hl_port_id']))
999 assertUIntArg ('hl_port_id');
1000 $hl_port_id = $_REQUEST['hl_port_id'];
1002 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>";
1003 echo '<tr><th class=tdleft>Local name</th><th class=tdleft>Visible label</th>';
1004 echo '<th class=tdleft>Interface</th><th class=tdleft>L2 address</th>';
1005 echo '<th class=tdcenter colspan=2>Remote object and port</th>';
1006 echo '<th class=tdleft>Cable ID</th></tr>';
1007 foreach ($info['ports'] as $port)
1010 if ($hl_port_id == $port['id'])
1011 echo ' class=port_highlight';
1012 echo "><td class=tdleft>${port['name']}</td><td class=tdleft>${port['label']}</td><td class=tdleft>";
1013 echo formatPortIIFOIF ($port) . "</td><td class=tdleft><tt>${port['l2address']}</tt></td>";
1014 if ($port['remote_object_id'])
1016 $remote_object = spotEntity ('object', $port['remote_object_id']);
1017 echo "<td class=tdleft><a href='".makeHref(array('page'=>'object', 'object_id'=>$port['remote_object_id'], 'hl_port_id'=>$port['remote_id']))."'>${remote_object['dname']}</a></td>";
1018 echo "<td class=tdleft>${port['remote_name']}</td>";
1019 echo "<td class='tdleft rsvtext'>${port['cableid']}</td>";
1021 elseif (strlen ($port['reservation_comment']))
1023 echo "<td class=tdleft><b>Reserved:</b></td>";
1024 echo "<td class='tdleft rsvtext'>${port['reservation_comment']}</td><td> </td>";
1027 echo '<td> </td><td> </td><td> </td>';
1030 echo "</table><br>";
1034 if (count ($info['ipv4']) +
count ($info['ipv6']))
1036 startPortlet ('IP addresses');
1037 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
1038 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
1039 echo "<tr><th>OS interface</th><th>IP address</th><th>network</th><th>routed by</th><th>peers</th></tr>\n";
1041 echo "<tr><th>OS interface</th><th>IP address</th><th>peers</th></tr>\n";
1043 if (isset ($_REQUEST['hl_ipv6_addr']))
1045 if ($hl_ipv6 = assertIPv6Arg ('hl_ipv6_addr'))
1046 $hl_ip_addr = $hl_ipv6->format();
1048 elseif (isset ($_REQUEST['hl_ipv4_addr']))
1049 $hl_ip_addr = $_REQUEST['hl_ipv4_addr'];
1051 // group IP allocations by interface name instead of address family
1052 $allocs_by_iface = array();
1053 foreach (array ('ipv4', 'ipv6') as $ip_v)
1054 foreach ($info[$ip_v] as $dottedquad => $alloc)
1055 $allocs_by_iface[$alloc['osif']][$dottedquad] = $alloc;
1057 // sort allocs array by portnames
1058 foreach (sortPortList ($allocs_by_iface) as $iface_name => $alloclist)
1060 $is_first_row = TRUE;
1061 foreach ($alloclist as $dottedquad => $alloc)
1063 if ($alloc['addrinfo']['version'] == 6)
1065 $addr_page_name = 'ipv6address';
1066 $ipv6_address = new IPv6Address ($dottedquad);
1067 $dottedquad = $ipv6_address->format();
1068 if ($netid = getIPv6AddressNetworkId ($ipv6_address))
1070 $netinfo = spotEntity ('ipv6net', $netid);
1071 loadIPv6AddrList ($netinfo);
1076 $addr_page_name = 'ipaddress';
1077 if ($netid = getIPv4AddressNetworkId ($dottedquad))
1079 $netinfo = spotEntity ('ipv4net', $netid);
1080 loadIPv4AddrList ($netinfo);
1083 $address_name = niftyString ($alloc['addrinfo']['name']);
1084 $class = $alloc['addrinfo']['class'];
1085 $secondclass = ($hl_ip_addr == $dottedquad) ?
'tdleft port_highlight' : 'tdleft';
1086 echo "<tr class='${class}' valign=top>";
1088 // display iface name (common cell for both address families)
1091 $rowspan = count ($alloclist) > 1 ?
'rowspan="' . count ($alloclist) . '"' : '';
1092 echo "<td class=tdleft $rowspan>$iface_name</td>";
1093 $is_first_row = FALSE;
1095 echo "<td class='${secondclass}'>";
1096 if (NULL !== $netid)
1097 echo "<a href='index.php?page=$addr_page_name&hl_object_id=$object_id&ip=$dottedquad'>${dottedquad}</a>";
1100 if (getConfigVar ('EXT_IPV4_VIEW') != 'yes')
1101 echo '<small>/' . (NULL === $netid ?
'??' : $netinfo['mask']) . '</small>';
1102 echo ' ' . $aac[$alloc['type']];
1103 if (strlen ($alloc['addrinfo']['name']))
1104 echo ' (' . niftyString ($alloc['addrinfo']['name']) . ')';
1106 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
1108 if (NULL === $netid)
1109 echo '<td class=sparenetwork>N/A</td><td class=sparenetwork>N/A</td>';
1112 echo "<td class='${secondclass}'>";
1113 renderCell ($netinfo);
1115 // filter out self-allocation
1116 $other_routers = array();
1117 foreach (findRouters ($netinfo['addrlist']) as $router)
1118 if ($router['id'] != $object_id)
1119 $other_routers[] = $router;
1120 if (count ($other_routers))
1121 printRoutersTD ($other_routers);
1123 echo "<td class='${secondclass}'> </td>";
1127 echo "<td class='${secondclass}'>\n";
1129 if ($alloc['addrinfo']['reserved'] == 'yes')
1131 echo $prefix . '<strong>RESERVED</strong>';
1134 foreach ($alloc['addrinfo']['allocs'] as $allocpeer)
1136 if ($allocpeer['object_id'] == $object_id)
1138 echo $prefix . "<a href='" . makeHref (array ('page' => 'object', 'object_id' => $allocpeer['object_id'])) . "'>";
1139 if (isset ($allocpeer['osif']) and strlen ($allocpeer['osif']))
1140 echo $allocpeer['osif'] . '@';
1141 echo $allocpeer['object_name'] . '</a>';
1144 echo "</td></tr>\n";
1147 echo "</table><br>\n";
1151 $forwards = $info['nat4'];
1152 if (count($forwards['in']) or count($forwards['out']))
1154 startPortlet('NATv4');
1156 if (count($forwards['out']))
1159 echo "<h3>locally performed NAT</h3>";
1161 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
1162 echo "<tr><th>Proto</th><th>Match endpoint</th><th>Translate to</th><th>Target object</th><th>Rule comment</th></tr>\n";
1164 foreach ($forwards['out'] as $pf)
1168 if (isset ($alloclist [$pf['localip']]))
1170 $class = $alloclist [$pf['localip']]['addrinfo']['class'];
1171 $osif = $alloclist [$pf['localip']]['osif'] . ': ';
1173 echo "<tr class='$class'>";
1174 echo "<td>${pf['proto']}</td><td class=tdleft>${osif}<a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['localip']))."'>${pf['localip']}</a>:${pf['localport']}</td>";
1175 echo "<td class=tdleft><a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['remoteip']))."'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
1176 $address = getIPv4Address ($pf['remoteip']);
1177 echo "<td class='description'>";
1178 if (count ($address['allocs']))
1179 foreach($address['allocs'] as $bond)
1180 echo "<a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$bond['object_id']))."'>${bond['object_name']}(${bond['name']})</a> ";
1181 elseif (strlen ($pf['remote_addr_name']))
1182 echo '(' . $pf['remote_addr_name'] . ')';
1183 echo "</td><td class='description'>${pf['description']}</td></tr>";
1185 echo "</table><br><br>";
1187 if (count($forwards['in']))
1189 echo "<h3>arriving NAT connections</h3>";
1190 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
1191 echo "<tr><th>Matched endpoint</th><th>Source object</th><th>Translated to</th><th>Rule comment</th></tr>\n";
1192 foreach ($forwards['in'] as $pf)
1195 echo "<td>${pf['proto']}/<a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['localip']))."'>${pf['localip']}</a>:${pf['localport']}</td>";
1196 echo "<td class='description'><a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$pf['object_id']))."'>${pf['object_name']}</a>";
1197 echo "</td><td><a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['remoteip']))."'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
1198 echo "<td class='description'>${pf['description']}</td></tr>";
1200 echo "</table><br><br>";
1205 $pools = $info['ipv4rspools'];
1209 startPortlet ('Real server pools (' . count ($pools) . ')');
1210 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
1211 echo "<tr><th>VS</th><th>RS pool</th><th>RS</th><th>VS config</th><th>RS config</th><th>Prio</th></tr>\n";
1212 foreach ($pools as $vs_id => $info)
1214 echo "<tr valign=top class=row_${order}><td class=tdleft>";
1215 renderCell (spotEntity ('ipv4vs', $vs_id));
1216 echo "</td><td class=tdleft>";
1217 renderCell (spotEntity ('ipv4rspool', $info['pool_id']));
1218 echo '</td><td class=tdleft>' . $info['rscount'] . '</td>';
1219 echo "<td class=slbconf>${info['vsconfig']}</td>";
1220 echo "<td class=slbconf>${info['rsconfig']}</td>";
1221 echo "<td class=slbconf>${info['prio']}</td>";
1223 $order = $nextorder[$order];
1230 // After left column we have (surprise!) right column with rackspace portlet only.
1231 echo "<td class=pcright>";
1232 // rackspace portlet
1233 startPortlet ('rackspace allocation');
1234 foreach (getResidentRacksData ($object_id, FALSE) as $rack_id)
1235 renderRack ($rack_id, $object_id);
1242 function renderRackMultiSelect ($sname, $racks, $selected)
1244 // Transform the given flat list into a list of groups, each representing a rack row.
1246 foreach ($racks as $rack)
1247 if (!isset ($rdata[$rack['row_name']]))
1248 $rdata[$rack['row_name']] = array ($rack['id'] => $rack['name']);
1250 $rdata[$rack['row_name']][$rack['id']] = $rack['name'];
1251 echo "<select name=${sname} multiple size=" . getConfigVar ('MAXSELSIZE') . " onchange='getElementsByName(\"updateObjectAllocation\")[0].submit()'>\n";
1252 foreach ($rdata as $optgroup => $racklist)
1254 echo "<optgroup label='${optgroup}'>";
1255 foreach ($racklist as $rack_id => $rack_name)
1257 echo "<option value=${rack_id}";
1258 if (!(array_search ($rack_id, $selected) === FALSE))
1260 echo">${rack_name}</option>\n";
1266 // This function renders a form for port edition.
1267 function renderPortsForObject ($object_id)
1269 $prefs = getPortListPrefs();
1270 function printNewItemTR ($prefs)
1272 printOpFormIntro ('addPort');
1274 printImageHREF ('add', 'add a port', TRUE);
1275 echo "</td><td><input type=text size=8 name=port_name tabindex=100></td>\n";
1276 echo "<td><input type=text name=port_label tabindex=101></td><td>";
1277 printNiftySelect (getNewPortTypeOptions(), array ('name' => 'port_type_id', 'tabindex' => 102), $prefs['selected']);
1278 echo "<td><input type=text name=port_l2address tabindex=103 size=18 maxlength=24></td>\n";
1279 echo "<td colspan=3> </td><td>";
1280 printImageHREF ('add', 'add a port', TRUE, 104);
1281 echo "</td></tr></form>";
1283 if (getConfigVar('ENABLE_MULTIPORT_FORM') == 'yes' ||
getConfigVar('ENABLE_BULKPORT_FORM') == 'yes' )
1284 startPortlet ('Ports and interfaces');
1287 $object = spotEntity ('object', $object_id);
1288 amplifyCell ($object);
1289 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes' && getConfigVar('ENABLE_BULKPORT_FORM') == 'yes'){
1290 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
1291 echo "<tr><th> </th><th class=tdleft>Local name</th><th class=tdleft>Visible label</th><th class=tdleft>Interface</th><th class=tdleft>Start Number</th>";
1292 echo "<th class=tdleft>Count</th><th> </th></tr>\n";
1293 printOpFormIntro ('addBulkPorts');
1295 printImageHREF ('add', 'add ports', TRUE);
1296 echo "</td><td><input type=text size=8 name=port_name tabindex=105></td>\n";
1297 echo "<td><input type=text name=port_label tabindex=106></td><td>";
1298 printNiftySelect (getNewPortTypeOptions(), array ('name' => 'port_type_id', 'tabindex' => 107), $prefs['selected']);
1299 echo "<td><input type=text name=port_numbering_start tabindex=108 size=3 maxlength=3></td>\n";
1300 echo "<td><input type=text name=port_numbering_count tabindex=109 size=3 maxlength=3></td>\n";
1301 echo "<td> </td><td>";
1302 printImageHREF ('add', 'add ports', TRUE, 110);
1303 echo "</td></tr></form>";
1304 echo "</table><br>\n";
1307 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
1308 echo "<tr><th> </th><th class=tdleft>Local name</th><th class=tdleft>Visible label</th><th class=tdleft>Interface</th><th class=tdleft>L2 address</th>";
1309 echo "<th class=tdcenter colspan=2>Cable, Remote object and port</th><th class=tdcenter>(Un)link or (un)reserve</th><th> </th></tr>\n";
1310 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
1311 printNewItemTR ($prefs);
1312 foreach ($object['ports'] as $port)
1314 printOpFormIntro ('editPort', array ('port_id' => $port['id']));
1315 echo "<tr><td><a href='".makeHrefProcess(array('op'=>'delPort', 'port_id'=>$port['id'], 'object_id'=>$object_id, 'port_name'=>$port['name']))."'>";
1316 printImageHREF ('delete', 'Unlink and Delete this port');
1318 echo "<td><input type=text name=name value='${port['name']}' size=8></td>";
1319 echo "<td><input type=text name=label value='${port['label']}'></td>";
1320 if (!$port['remote_object_id'])
1323 if ($port['iif_id'] != 1)
1324 echo '<label>' . $port['iif_name'] . ' ';
1325 printSelect (getExistingPortTypeOptions ($port['id']), array ('name' => 'port_type_id'), $port['oif_id']);
1326 if ($port['iif_id'] != 1)
1332 echo "<input type=hidden name=port_type_id value='${port['oif_id']}'><td class=tdleft>";
1333 echo formatPortIIFOIF ($port) . '</td>';
1335 // 18 is enough to fit 6-byte MAC address in its longest form,
1336 // while 24 should be Ok for WWN
1337 echo "<td><input type=text name=l2address value='${port['l2address']}' size=18 maxlength=24></td>\n";
1338 if ($port['remote_object_id'])
1340 $remote_object = spotEntity ('object', $port['remote_object_id']);
1341 echo "<td>${port['cableid']} <a href='".makeHref(array('page'=>'object', 'object_id'=>$port['remote_object_id']))."'>${remote_object['dname']}</a></td>";
1342 echo "<td>${port['remote_name']}<input type=hidden name=reservation_comment value=''></td>";
1343 echo "<td class=tdcenter><a href='".
1344 makeHrefProcess(array(
1346 'port_id'=>$port['id'],
1347 'remote_port_id' => $port['remote_id'],
1348 'object_id'=>$object_id)).
1350 printImageHREF ('cut', 'Unlink this port');
1353 elseif (strlen ($port['reservation_comment']))
1355 echo "<td><b>Reserved:</b></td>";
1356 echo "<td><input type=text name=reservation_comment value='${port['reservation_comment']}'></td>";
1357 echo "<td class=tdcenter><a href='".
1358 makeHrefProcess(array(
1360 'port_id'=>$port['id'],
1361 'object_id'=>$object_id)).
1363 printImageHREF ('clear', 'Use up this port');
1368 //echo "<td> </td><td> </td><td class=tdcenter><a href='javascript:;'";
1369 echo "<td> </td><td> </td><td class=tdcenter><span";
1370 $helper_args = array
1372 'port' => $port['id'],
1375 $popup_args = 'height=700, width=400, location=no, menubar=no, '.
1376 'resizable=yes, scrollbars=yes, status=no, titlebar=no, toolbar=no';
1377 echo " ondblclick='window.open(\"" . makeHrefForHelper ('portlist', $helper_args);
1378 echo "\",\"findlink\",\"${popup_args}\");'";
1380 $helper_args['in_rack'] = 'y';
1381 echo " onclick='window.open(\"" . makeHrefForHelper ('portlist', $helper_args);
1382 echo "\",\"findlink\",\"${popup_args}\");'";
1386 printImageHREF ('plug', 'Link this port');
1388 echo " <input type=text name=reservation_comment></td>\n";
1391 printImageHREF ('save', 'Save changes', TRUE);
1392 echo "</td></form></tr>\n";
1394 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
1395 printNewItemTR ($prefs);
1396 echo "</table><br>\n";
1397 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes' && getConfigVar('ENABLE_BULKPORT_FORM') == 'yes'){
1398 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
1399 echo "<tr><th> </th><th class=tdleft>Local name</th><th class=tdleft>Visible label</th><th class=tdleft>Interface</th><th class=tdleft>Start Number</th>";
1400 echo "<th class=tdleft>Count</th><th> </th></tr>\n";
1401 printOpFormIntro ('addBulkPorts');
1403 printImageHREF ('add', 'add ports', TRUE);
1404 echo "</td><td><input type=text size=8 name=port_name tabindex=105></td>\n";
1405 echo "<td><input type=text name=port_label tabindex=106></td><td>";
1406 printNiftySelect (getNewPortTypeOptions(), array ('name' => 'port_type_id', 'tabindex' => 107), $prefs['selected']);
1407 echo "<td><input type=text name=port_numbering_start tabindex=108 size=3 maxlength=3></td>\n";
1408 echo "<td><input type=text name=port_numbering_count tabindex=109 size=3 maxlength=3></td>\n";
1409 echo "<td> </td><td>";
1410 printImageHREF ('add', 'add ports', TRUE, 110);
1411 echo "</td></tr></form>";
1412 echo "</table><br>\n";
1414 if (getConfigVar('ENABLE_MULTIPORT_FORM') == 'yes')
1416 if (getConfigVar('ENABLE_MULTIPORT_FORM') != 'yes')
1419 startPortlet ('Add/update multiple ports');
1420 printOpFormIntro ('addMultiPorts');
1421 echo 'Format: <select name=format tabindex=201>';
1422 echo '<option value=c3600asy>Cisco 3600 async: sh line | inc TTY</option>';
1423 echo '<option value=fiwg selected>Foundry ServerIron/FastIron WorkGroup/Edge: sh int br</option>';
1424 echo '<option value=fisxii>Foundry FastIron SuperX/II4000: sh int br</option>';
1425 echo '<option value=ssv1>SSV:<interface name> <MAC address></option>';
1427 echo 'Default port type: ';
1428 printNiftySelect (getNewPortTypeOptions(), array ('name' => 'port_type', 'tabindex' => 202), $prefs['selected']);
1429 echo "<input type=submit value='Parse output' tabindex=204><br>\n";
1430 echo "<textarea name=input cols=100 rows=50 tabindex=203></textarea><br>\n";
1435 function renderIPv4ForObject ($object_id)
1437 function printNewItemTR ()
1440 printOpFormIntro ('addIPv4Allocation');
1442 printImageHREF ('add', 'allocate', TRUE);
1444 echo "<td class=tdleft><input type='text' size='10' name='bond_name' tabindex=100></td>\n";
1445 echo "<td class=tdleft><input type=text name='ip' tabindex=101></td>\n";
1446 echo "<td colspan=2> </td><td>";
1447 printSelect ($aat, array ('name' => 'bond_type', 'tabindex' => 102), 'regular');
1448 echo "</td><td> </td><td>";
1449 printImageHREF ('add', 'allocate', TRUE, 103);
1450 echo "</td></tr></form>";
1452 $focus = spotEntity ('object', $object_id);
1453 amplifyCell ($focus);
1455 startPortlet ('Allocations');
1456 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
1457 echo '<tr><th> </th><th>OS interface</th><th>IP address</th>';
1458 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
1459 echo '<th>network</th><th>routed by</th>';
1460 echo '<th>type</th><th>misc</th><th> </th></tr>';
1462 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
1464 foreach ($focus['ipv4'] as $dottedquad => $alloc)
1466 $class = $alloc['addrinfo']['class'];
1467 $netid = getIPv4AddressNetworkId ($dottedquad);
1468 if (NULL !== $netid)
1470 $netinfo = spotEntity ('ipv4net', $netid);
1471 loadIPv4AddrList ($netinfo);
1473 printOpFormIntro ('updIPv4Allocation', array ('ip' => $dottedquad));
1474 echo "<tr class='$class' valign=top><td><a href='".makeHrefProcess(array('op'=>'delIPv4Allocation', 'ip'=>$dottedquad, 'object_id'=>$object_id))."'>";
1475 printImageHREF ('delete', 'Delete this IPv4 address');
1477 echo "<td class=tdleft><input type='text' name='bond_name' value='${alloc['osif']}' size=10></td><td class=tdleft>";
1478 if (NULL !== $netid)
1479 echo "<a href='".makeHref(array('page'=>'ipaddress', 'ip'=>$dottedquad))."'>${dottedquad}</a>";
1482 if (getConfigVar ('EXT_IPV4_VIEW') != 'yes')
1483 echo '<small>/' . (NULL === $netid ?
'??' : $netinfo['mask']) . '</small>';
1484 if (strlen ($alloc['addrinfo']['name']))
1485 echo ' (' . niftyString ($alloc['addrinfo']['name']) . ')';
1487 // FIXME: this a copy-and-paste from renderRackObject()
1488 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
1490 if (NULL === $netid)
1491 echo '<td class=sparenetwork>N/A</td><td class=sparenetwork>N/A</td>';
1495 renderCell ($netinfo);
1497 // filter out self-allocation
1498 $other_routers = array();
1499 foreach (findRouters ($netinfo['addrlist']) as $router)
1500 if ($router['id'] != $object_id)
1501 $other_routers[] = $router;
1502 if (count ($other_routers))
1503 printRoutersTD ($other_routers);
1505 echo "<td> </td>";
1509 printSelect ($aat, array ('name' => 'bond_type'), $alloc['type']);
1512 if ($alloc['addrinfo']['reserved'] == 'yes')
1514 echo $prefix . '<strong>RESERVED</strong>';
1517 foreach ($alloc['addrinfo']['allocs'] as $allocpeer)
1519 if ($allocpeer['object_id'] == $object_id)
1521 echo $prefix . "<a href='".makeHref(array('page'=>'object', 'object_id'=>$allocpeer['object_id']))."'>";
1522 if (isset ($allocpeer['osif']) and strlen ($allocpeer['osif']))
1523 echo $allocpeer['osif'] . '@';
1524 echo $allocpeer['object_name'] . '</a>';
1528 printImageHREF ('save', 'Save changes', TRUE);
1529 echo "</td></form></tr>\n";
1531 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
1534 echo "</table><br>\n";
1539 function renderIPv6ForObject ($object_id)
1541 function printNewItemTR ()
1544 printOpFormIntro ('addIPv6Allocation');
1546 printImageHREF ('add', 'allocate', TRUE);
1548 echo "<td class=tdleft><input type='text' size='10' name='bond_name' tabindex=100></td>\n";
1549 echo "<td class=tdleft><input type=text name='ip' tabindex=101></td>\n";
1550 echo "<td colspan=2> </td><td>";
1551 printSelect ($aat, array ('name' => 'bond_type', 'tabindex' => 102), 'regular');
1552 echo "</td><td> </td><td>";
1553 printImageHREF ('add', 'allocate', TRUE, 103);
1554 echo "</td></tr></form>";
1556 $focus = spotEntity ('object', $object_id);
1557 amplifyCell ($focus);
1559 startPortlet ('Allocations');
1560 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
1561 echo '<tr><th> </th><th>OS interface</th><th>IP address</th>';
1562 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
1563 echo '<th>network</th><th>routed by</th>';
1564 echo '<th>type</th><th>misc</th><th> </th></tr>';
1566 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
1568 foreach ($focus['ipv6'] as $bin_str => $alloc)
1570 $ipv6 = new IPv6Address ($bin_str);
1571 $dottedquad = $ipv6->format();
1572 $class = $alloc['addrinfo']['class'];
1573 $netid = getIPv6AddressNetworkId ($ipv6);
1574 if (NULL !== $netid)
1576 $netinfo = spotEntity ('ipv6net', $netid);
1577 loadIPv6AddrList ($netinfo);
1579 printOpFormIntro ('updIPv6Allocation', array ('ip' => $dottedquad));
1580 echo "<tr class='$class' valign=top><td><a href='".makeHrefProcess(array('op'=>'delIPv6Allocation', 'ip'=>$dottedquad, 'object_id'=>$object_id))."'>";
1581 printImageHREF ('delete', 'Delete this IPv6 address');
1583 echo "<td class=tdleft><input type='text' name='bond_name' value='${alloc['osif']}' size=10></td><td class=tdleft>";
1584 if (NULL !== $netid)
1585 echo "<a href='index.php?page=ipv6address&ip=$dottedquad'>$dottedquad</a>";
1588 if (getConfigVar ('EXT_IPV4_VIEW') != 'yes')
1589 echo '<small>/' . (NULL === $netid ?
'??' : $netinfo['mask']) . '</small>';
1590 if (strlen ($alloc['addrinfo']['name']))
1591 echo ' (' . niftyString ($alloc['addrinfo']['name']) . ')';
1593 // FIXME: this a copy-and-paste from renderRackObject()
1594 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
1596 if (NULL === $netid)
1597 echo '<td class=sparenetwork>N/A</td><td class=sparenetwork>N/A</td>';
1601 renderCell ($netinfo);
1603 // filter out self-allocation
1604 $other_routers = array();
1605 foreach (findRouters ($netinfo['addrlist']) as $router)
1606 if ($router['id'] != $object_id)
1607 $other_routers[] = $router;
1608 if (count ($other_routers))
1609 printRoutersTD ($other_routers);
1611 echo "<td> </td>";
1615 printSelect ($aat, array ('name' => 'bond_type'), $alloc['type']);
1618 if ($alloc['addrinfo']['reserved'] == 'yes')
1620 echo $prefix . '<strong>RESERVED</strong>';
1623 foreach ($alloc['addrinfo']['allocs'] as $allocpeer)
1625 if ($allocpeer['object_id'] == $object_id)
1627 echo $prefix . "<a href='".makeHref(array('page'=>'object', 'object_id'=>$allocpeer['object_id']))."'>";
1628 if (isset ($allocpeer['osif']) and strlen ($allocpeer['osif']))
1629 echo $allocpeer['osif'] . '@';
1630 echo $allocpeer['object_name'] . '</a>';
1634 printImageHREF ('save', 'Save changes', TRUE);
1635 echo "</td></form></tr>\n";
1637 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
1640 echo "</table><br>\n";
1645 // Log structure versions:
1646 // 1: the whole structure is a list of code-message pairs
1647 // 2 and later: there's a "v" field set, which indicates the version
1648 // 2: there's a "m" list set to hold message code and optional arguments
1649 function showMessageOrError ()
1651 if (!isset ($_SESSION['log']))
1653 $log = $_SESSION['log'];
1656 case !isset ($log['v']):
1657 case $log['v'] == 1:
1658 foreach ($log as $key => $record)
1660 echo "<div class=msg_${record['code']}>${record['message']}</div>";
1662 case $log['v'] == 2:
1665 // records 0~99 with success messages
1666 0 => array ('code' => 'success', 'format' => '%s'),
1667 1 => array ('code' => 'success', 'format' => '%u new records done, %u already existed'),
1668 2 => array ('code' => 'success', 'format' => 'NATv4 rule was successfully added.'),
1669 3 => array ('code' => 'success', 'format' => 'NATv4 rule was successfully deleted.'),
1670 4 => array ('code' => 'success', 'format' => 'NATv4 rule was successfully updated'),
1671 5 => array ('code' => 'success', 'format' => 'Port %s was added successfully'),
1672 6 => array ('code' => 'success', 'format' => 'Port %s was updated successfully'),
1673 7 => array ('code' => 'success', 'format' => 'Port %s was deleted successfully'),
1674 8 => array ('code' => 'success', 'format' => 'Port %s successfully linked with port %s at object %s'),
1675 9 => array ('code' => 'success', 'format' => 'Port %s was successfully unlinked from %s@%s'),
1676 10 => array ('code' => 'success', 'format' => 'Added %u ports, updated %u ports, encountered %u errors.'),
1677 11 => array ('code' => 'success', 'format' => 'Reservation removed.'),
1678 12 => array ('code' => 'success', 'format' => 'allocation updated'),
1679 13 => array ('code' => 'success', 'format' => 'allocated'),
1680 14 => array ('code' => 'success', 'format' => 'deallocated'),
1681 15 => array ('code' => 'success', 'format' => 'Reset succeeded.'),
1682 16 => array ('code' => 'success', 'format' => 'Update done'),
1683 17 => array ('code' => 'success', 'format' => 'Update(s) succeeded.'),
1684 18 => array ('code' => 'success', 'format' => 'Load balancer was successfully added'),
1685 19 => array ('code' => 'success', 'format' => 'Load balancer was successfully deleted'),
1686 20 => array ('code' => 'success', 'format' => 'Load balancer info was successfully updated'),
1687 21 => array ('code' => 'success', 'format' => 'Generation complete'),
1688 22 => array ('code' => 'success', 'format' => 'Chained %u tags'),
1689 23 => array ('code' => 'success', 'format' => 'IPv4 prefix successfully added'),
1690 24 => array ('code' => 'success', 'format' => 'IPv4 prefix deleted'),
1691 25 => array ('code' => 'success', 'format' => 'IPv4 prefix updated'),
1692 26 => array ('code' => 'success', 'format' => '%u IP address(es) were successfully updated'),
1693 27 => array ('code' => 'success', 'format' => 'IPv4 address updated'),
1694 28 => array ('code' => 'success', 'format' => 'Virtual service was successfully created'),
1695 29 => array ('code' => 'success', 'format' => 'Virtual service was successfully deleted'),
1696 30 => array ('code' => 'success', 'format' => 'Virtual service was successfully updated'),
1697 31 => array ('code' => 'success', 'format' => 'RS pool was successfully created'),
1698 32 => array ('code' => 'success', 'format' => 'RS pool was successfully deleted'),
1699 33 => array ('code' => 'success', 'format' => 'RS pool was successfully updated'),
1700 34 => array ('code' => 'success', 'format' => 'Real server was successfully added'),
1701 35 => array ('code' => 'success', 'format' => 'Real server was successfully deleted'),
1702 36 => array ('code' => 'success', 'format' => 'Real server was successfully updated'),
1703 37 => array ('code' => 'success', 'format' => 'Successfully added %u real servers'),
1704 38 => array ('code' => 'success', 'format' => '%u real server(s) were successfully (de)activated'),
1705 39 => array ('code' => 'success', 'format' => 'User account %s updated.'),
1706 40 => array ('code' => 'success', 'format' => 'User account %s created.'),
1707 41 => array ('code' => 'success', 'format' => 'uplink ports reverb queued'),
1709 43 => array ('code' => 'success', 'format' => 'Saved successfully.'),
1710 44 => array ('code' => 'success', 'format' => '%s failures and %s successfull changes.'),
1711 45 => array ('code' => 'success', 'format' => "Attribute '%s' created."),
1712 46 => array ('code' => 'success', 'format' => 'Rename successful.'),
1713 47 => array ('code' => 'success', 'format' => 'Attribute was deleted.'),
1714 48 => array ('code' => 'success', 'format' => 'Supplement succeeded.'),
1715 49 => array ('code' => 'success', 'format' => 'Reduction succeeded.'),
1716 50 => array ('code' => 'success', 'format' => 'Reduction succeeded.'),
1717 51 => array ('code' => 'success', 'format' => 'Update succeeded.'),
1718 52 => array ('code' => 'success', 'format' => 'Supplement succeeded.'),
1719 53 => array ('code' => 'success', 'format' => 'Chapter was deleted.'),
1720 54 => array ('code' => 'success', 'format' => 'Chapter was updated.'),
1721 55 => array ('code' => 'success', 'format' => 'Chapter was added.'),
1722 56 => array ('code' => 'success', 'format' => 'Update succeeded.'),
1723 57 => array ('code' => 'success', 'format' => 'Reset complete'),
1724 58 => array ('code' => 'success', 'format' => "Deleted tag '%s'."),
1725 59 => array ('code' => 'success', 'format' => "Created tag '%s'."),
1726 60 => array ('code' => 'success', 'format' => "Updated tag '%s'."),
1727 61 => array ('code' => 'success', 'format' => 'Password changed successfully.'),
1728 62 => array ('code' => 'success', 'format' => 'gw: %s'),
1729 63 => array ('code' => 'success', 'format' => '%u change request(s) have been processed'),
1730 64 => array ('code' => 'success', 'format' => 'Port %s@%s has been assigned to VLAN %u'),
1731 65 => array ('code' => 'success', 'format' => "Added new rack '%s'"),
1732 66 => array ('code' => 'success', 'format' => "File sent Ok via handler '%s'"),
1733 67 => array ('code' => 'success', 'format' => "Tag rolling done, %u objects involved"),
1734 68 => array ('code' => 'success', 'format' => "Updated rack '%s'"),
1735 69 => array ('code' => 'success', 'format' => 'File "%s" was added successfully'),
1736 70 => array ('code' => 'success', 'format' => 'File "%s" was updated successfully'),
1737 71 => array ('code' => 'success', 'format' => 'File "%s" was linked successfully'),
1738 72 => array ('code' => 'success', 'format' => 'File was unlinked successfully'),
1739 73 => array ('code' => 'success', 'format' => 'File "%s" was deleted successfully'),
1740 74 => array ('code' => 'success', 'format' => 'Record "%s" was added successfully'),
1741 75 => array ('code' => 'success', 'format' => 'Row "%s" was updated successfully'),
1742 76 => array ('code' => 'success', 'format' => 'Object "%s" was deleted successfully'),
1743 77 => array ('code' => 'success', 'format' => 'Record "%s" was deleted successfully'),
1744 78 => array ('code' => 'success', 'format' => 'File "%s" saved Ok'),
1745 79 => array ('code' => 'success', 'format' => 'Rack "%s" was deleted successfully'),
1746 80 => array ('code' => 'success', 'format' => "Added new object '%s'"),
1747 81 => array ('code' => 'success', 'format' => "SNMP: completed '%s' work"),
1748 82 => array ('code' => 'success', 'format' => "Bulk port creation was successful. %u ports created, %u failed"),
1749 83 => array ('code' => 'success', 'format' => 'Object "%s" was reset successfully'),
1750 84 => array ('code' => 'success', 'format' => 'IPv6 prefix successfully added'),
1751 85 => array ('code' => 'success', 'format' => 'IPv6 prefix deleted'),
1752 86 => array ('code' => 'success', 'format' => 'IPv6 prefix updated'),
1753 87 => array ('code' => 'success', 'format' => '802.1Q recalculate: %d ports changed on %d switches'),
1754 // records 100~199 with fatal error messages
1755 100 => array ('code' => 'error', 'format' => '%s'),
1756 101 => array ('code' => 'error', 'format' => 'Port name cannot be empty'),
1757 102 => array ('code' => 'error', 'format' => "Error creating user account '%s'"),
1758 103 => array ('code' => 'error', 'format' => 'User not found!'),
1759 104 => array ('code' => 'error', 'format' => "Error updating user account '%s'"),
1760 105 => array ('code' => 'error', 'format' => 'default VLAN cannot be changed'),
1762 107 => array ('code' => 'error', 'format' => 'Assertion failed: %s'),
1763 108 => array ('code' => 'error', 'format' => 'Database error: %s'),
1764 109 => array ('code' => 'error', 'format' => 'Update failed!'),
1765 110 => array ('code' => 'error', 'format' => 'Supplement failed!'),
1766 111 => array ('code' => 'error', 'format' => 'Reduction failed!'),
1767 112 => array ('code' => 'error', 'format' => 'Error adding chapter.'),
1768 113 => array ('code' => 'error', 'format' => 'Error updating chapter.'),
1769 114 => array ('code' => 'error', 'format' => 'Error deleting chapter.'),
1770 115 => array ('code' => 'error', 'format' => 'Error renaming attribute.'),
1771 116 => array ('code' => 'error', 'format' => 'Error creating attribute.'),
1772 117 => array ('code' => 'error', 'format' => 'Error deleting attribute.'),
1773 118 => array ('code' => 'error', 'format' => 'Supplement failed!'),
1774 119 => array ('code' => 'error', 'format' => 'Reduction failed!'),
1775 120 => array ('code' => 'error', 'format' => 'Reset failed!'),
1776 121 => array ('code' => 'error', 'format' => 'commitUpdateObject() failed'),
1777 122 => array ('code' => 'error', 'format' => 'One or more update(s) failed!'),
1778 123 => array ('code' => 'error', 'format' => 'Cannot process submitted data: unknown format code.'),
1779 124 => array ('code' => 'error', 'format' => 'Error removing reservation!'),
1780 125 => array ('code' => 'error', 'format' => "Update failed with error: '%s'"),
1781 126 => array ('code' => 'error', 'format' => 'addRStoRSPool() failed'),
1782 127 => array ('code' => 'error', 'format' => 'Added %u real servers and encountered %u errors'),
1783 128 => array ('code' => 'error', 'format' => 'commitDeleteRS() failed'),
1784 129 => array ('code' => 'error', 'format' => 'commitDeleteLB() failed'),
1785 130 => array ('code' => 'error', 'format' => 'commitDeleteVS() failed'),
1786 131 => array ('code' => 'error', 'format' => 'invalid format requested'),
1787 132 => array ('code' => 'error', 'format' => 'invalid protocol'),
1788 133 => array ('code' => 'error', 'format' => 'commitUpdateRS() failed'),
1789 134 => array ('code' => 'error', 'format' => 'commitUpdateLB() failed'),
1790 135 => array ('code' => 'error', 'format' => 'commitUpdateVS() failed'),
1791 136 => array ('code' => 'error', 'format' => 'addLBtoRSPool() failed'),
1792 137 => array ('code' => 'error', 'format' => 'addLBtoRSPool() failed'),
1793 138 => array ('code' => 'error', 'format' => 'commitDeleteRSPool() failed'),
1794 139 => array ('code' => 'error', 'format' => 'commitUpdateRSPool() failed'),
1795 140 => array ('code' => 'error', 'format' => 'Encountered %u errors, (de)activated %u real servers'),
1796 141 => array ('code' => 'error', 'format' => 'Encountered %u errors, updated %u record(s)'),
1797 142 => array ('code' => 'error', 'format' => 'executeAutoPorts() failed'),
1798 143 => array ('code' => 'error', 'format' => 'Tried chaining %u tags, but experienced %u errors.'),
1799 144 => array ('code' => 'error', 'format' => "Error deleting tag: '%s'"),
1800 145 => array ('code' => 'error', 'format' => "Invalid tag name '%s'"),
1801 146 => array ('code' => 'error', 'format' => 'Error deleting record "%s"'),
1802 147 => array ('code' => 'error', 'format' => "Could not create tag '%s'"),
1803 148 => array ('code' => 'error', 'format' => "Could not update tag '%s'"),
1804 149 => array ('code' => 'error', 'format' => 'Turing test failed'),
1805 150 => array ('code' => 'error', 'format' => 'Can only change password under DB authentication.'),
1806 151 => array ('code' => 'error', 'format' => 'Old password doesn\'t match.'),
1807 152 => array ('code' => 'error', 'format' => 'New passwords don\'t match.'),
1808 153 => array ('code' => 'error', 'format' => 'Password change failed.'),
1809 154 => array ('code' => 'error', 'format' => "Verification error: %s"),
1810 155 => array ('code' => 'error', 'format' => 'Save failed.'),
1811 156 => array ('code' => 'error', 'format' => 'getSwitchVLANs() failed'),
1812 157 => array ('code' => 'error', 'format' => 'operation not permitted'),
1813 158 => array ('code' => 'error', 'format' => 'Ignoring malformed record #%u in form submit'),
1814 159 => array ('code' => 'error', 'format' => 'Permission denied moving port %s from VLAN%u to VLAN%u'),
1815 160 => array ('code' => 'error', 'format' => 'Invalid arguments'),
1816 161 => array ('code' => 'error', 'format' => 'Endpoint not found. Please either set FQDN attribute or assign an IP address to the object.'),
1817 162 => array ('code' => 'error', 'format' => 'More than one IP address is assigned to this object, please configure FQDN attribute.'),
1818 163 => array ('code' => 'error', 'format' => 'Failed to get any response from queryGateway() or the gateway died'),
1819 164 => array ('code' => 'error', 'format' => 'Gateway failure: %s.'),
1820 165 => array ('code' => 'error', 'format' => 'Gateway failure: malformed reply.'),
1821 166 => array ('code' => 'error', 'format' => 'gw: %s'),
1822 167 => array ('code' => 'error', 'format' => 'Could not find port %s'),
1823 168 => array ('code' => 'error', 'format' => 'Port %s is a trunk'),
1824 169 => array ('code' => 'error', 'format' => 'Failed to configure %s, connector returned code %u'),
1825 170 => array ('code' => 'error', 'format' => 'There is no network for IP address "%s"'),
1826 171 => array ('code' => 'error', 'format' => "Failed creating rack '%s'. Already exists in this row?"),
1827 172 => array ('code' => 'error', 'format' => 'Malformed request'),
1828 173 => array ('code' => 'error', 'format' => "Invalid IPv4 prefix '%s'"),
1829 174 => array ('code' => 'error', 'format' => 'Bad IPv4 address'),
1830 175 => array ('code' => 'error', 'format' => 'Invalid netmask'),
1831 176 => array ('code' => 'error', 'format' => 'This network already exists'),
1832 177 => array ('code' => 'error', 'format' => 'commitUpdateRack() failed'),
1833 178 => array ('code' => 'error', 'format' => 'file not found'),
1834 179 => array ('code' => 'error', 'format' => 'Expired form has been declined.'),
1835 180 => array ('code' => 'error', 'format' => 'Error saving file, all changes lost!'),
1836 181 => array ('code' => 'error', 'format' => "file uploads not allowed, change 'file_uploads' parameter in php.ini"),
1837 182 => array ('code' => 'error', 'format' => 'SQL query failed: %s'),
1838 183 => array ('code' => 'error', 'format' => "Tag id '%s' does not exist."),
1839 184 => array ('code' => 'error', 'format' => 'Submitted form is invalid at line %u'),
1840 185 => array ('code' => 'error', 'format' => "Failed to add object '%s'"),
1841 186 => array ('code' => 'error', 'format' => 'Incomplete form has been ignored. Cheers.'),
1842 187 => array ('code' => 'error', 'format' => "Internal error in function '%s'"),
1843 188 => array ('code' => 'error', 'format' => "Fatal SNMP failure"),
1844 189 => array ('code' => 'error', 'format' => "Unknown OID '%s'"),
1845 190 => array ('code' => 'error', 'format' => "Invalid VLAN ID '%s'"),
1846 191 => array ('code' => 'error', 'format' => "deploy was blocked due to conflicting configuration versions"),
1847 192 => array ('code' => 'error', 'format' => "Permission denied"),
1849 // records 200~299 with warnings
1850 200 => array ('code' => 'warning', 'format' => '%s'),
1851 201 => array ('code' => 'warning', 'format' => 'nothing happened...'),
1852 202 => array ('code' => 'warning', 'format' => 'gw: %s'),
1853 203 => array ('code' => 'warning', 'format' => 'Port %s seems to be the first in VLAN %u at this switch.'),
1854 204 => array ('code' => 'warning', 'format' => 'Check uplink/downlink configuration for proper operation.'),
1855 205 => array ('code' => 'warning', 'format' => '%u change request(s) have been ignored'),
1856 206 => array ('code' => 'warning', 'format' => 'Rack is not empty'),
1857 207 => array ('code' => 'warning', 'format' => 'Ignored empty request'),
1859 // records 300~399 with notices
1860 300 => array ('code' => 'neutral', 'format' => '%s'),
1863 // Handle the arguments. Is there any better way to do it?
1864 foreach ($log['m'] as $record)
1866 if (!isset ($record['c']) or !isset ($msginfo[$record['c']]))
1868 echo '<div class=msg_neutral>(this message was lost)</div>';
1871 if (isset ($record['a']))
1872 switch (count ($record['a']))
1877 $msginfo[$record['c']]['format'],
1884 $msginfo[$record['c']]['format'],
1892 $msginfo[$record['c']]['format'],
1902 $msginfo[$record['c']]['format'],
1911 $msgtext = $msginfo[$record['c']]['format'];
1912 echo '<div class=msg_' . $msginfo[$record['c']]['code'] . ">${msgtext}</div>";
1916 echo '<div class=msg_error>' . __FUNCTION__
. ': internal error</div>';
1919 unset($_SESSION['log']);
1923 The following conditions must be met:
1924 1. We can mount onto free atoms only. This means: if any record for an atom
1925 already exists in RackSpace, it can't be used for mounting.
1926 2. We can't unmount from 'W' atoms. Operator should review appropriate comments
1927 and either delete them before unmounting or refuse to unmount the object.
1929 function renderRackSpaceForObject ($object_id)
1931 // Always process occupied racks plus racks chosen by user. First get racks with
1932 // already allocated rackspace...
1933 $workingRacksData = getResidentRacksData ($object_id);
1934 // ...and then add those chosen by user (if any).
1935 if (isset($_REQUEST['rackmulti']))
1936 foreach ($_REQUEST['rackmulti'] as $cand_id)
1937 if (!isset ($workingRacksData[$cand_id]))
1939 $rackData = spotEntity ('rack', $cand_id);
1940 amplifyCell ($rackData);
1941 $workingRacksData[$cand_id] = $rackData;
1944 // Main layout starts.
1945 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0><tr>";
1947 // Left portlet with rack list.
1948 echo "<td class=pcleft height='1%'>";
1949 startPortlet ('Racks');
1950 $allRacksData = listCells ('rack');
1951 if (count ($allRacksData) <= getConfigVar ('RACK_PRESELECT_THRESHOLD'))
1952 foreach ($allRacksData as $rack)
1953 if (!array_key_exists ($rack['id'], $workingRacksData))
1955 amplifyCell ($rack);
1956 $workingRacksData[$rack['id']] = $rack;
1958 foreach (array_keys ($workingRacksData) as $rackId)
1959 applyObjectMountMask ($workingRacksData[$rackId], $object_id);
1960 printOpFormIntro ('updateObjectAllocation');
1961 renderRackMultiSelect ('rackmulti[]', $allRacksData, array_keys ($workingRacksData));
1966 // Middle portlet with comment and submit.
1967 echo "<td class=pcleft>";
1968 startPortlet ('Comment');
1969 echo "<textarea name=comment rows=10 cols=40></textarea><br>\n";
1970 echo "<input type=submit value='Save' name=got_atoms>\n";
1975 // Right portlet with rendered racks. If this form submit is not final, we have to
1976 // reflect the former state of the grid in current form.
1977 echo "<td class=pcright rowspan=2 height='1%'>";
1978 startPortlet ('Working copy');
1979 echo '<table border=0 cellspacing=10 align=center><tr>';
1980 foreach ($workingRacksData as $rack_id => $rackData)
1982 // Order is important here: only original allocation is highlighted.
1983 highlightObject ($rackData, $object_id);
1984 markupAtomGrid ($rackData, 'T');
1985 // If we have a form processed, discard user input and show new database
1987 if (isset ($_REQUEST['rackmulti'][0])) // is an update
1988 mergeGridFormToRack ($rackData);
1989 echo "<td valign=top>";
1990 echo "<center>\n<h2>${rackData['name']}</h2>\n";
1991 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
1992 echo "<tr><th width='10%'> </th>";
1993 echo "<th width='20%'><a href='javascript:;' oncontextmenu=\"blockToggleColumnOfAtoms('${rack_id}', '0', ${rackData['height']}); return false;\" onclick=\"toggleColumnOfAtoms('${rack_id}', '0', ${rackData['height']})\">Front</a></th>";
1994 echo "<th width='50%'><a href='javascript:;' oncontextmenu=\"blockToggleColumnOfAtoms('${rack_id}', '1', ${rackData['height']}); return false;\" onclick=\"toggleColumnOfAtoms('${rack_id}', '1', ${rackData['height']})\">Interior</a></th>";
1995 echo "<th width='20%'><a href='javascript:;' oncontextmenu=\"blockToggleColumnOfAtoms('${rack_id}', '2', ${rackData['height']}); return false;\" onclick=\"toggleColumnOfAtoms('${rack_id}', '2', ${rackData['height']})\">Back</a></th></tr>\n";
1996 renderAtomGrid ($rackData);
1997 echo "<tr><th width='10%'> </th>";
1998 echo "<th width='20%'><a href='javascript:;' oncontextmenu=\"blockToggleColumnOfAtoms('${rack_id}', '0', ${rackData['height']}); return false;\" onclick=\"toggleColumnOfAtoms('${rack_id}', '0', ${rackData['height']})\">Front</a></th>";
1999 echo "<th width='50%'><a href='javascript:;' oncontextmenu=\"blockToggleColumnOfAtoms('${rack_id}', '1', ${rackData['height']}); return false;\" onclick=\"toggleColumnOfAtoms('${rack_id}', '1', ${rackData['height']})\">Interior</a></th>";
2000 echo "<th width='20%'><a href='javascript:;' oncontextmenu=\"blockToggleColumnOfAtoms('${rack_id}', '2', ${rackData['height']}); return false;\" onclick=\"toggleColumnOfAtoms('${rack_id}', '2', ${rackData['height']})\">Back</a></th></tr>\n";
2001 echo "</table></center>\n";
2004 echo "</tr></table>";
2009 echo "</tr></table>\n";
2012 function renderMolecule ($mdata, $object_id)
2015 $rackpack = array();
2017 foreach ($mdata as $rua)
2019 $rack_id = $rua['rack_id'];
2020 $unit_no = $rua['unit_no'];
2021 $atom = $rua['atom'];
2022 if (!isset ($rackpack[$rack_id]))
2024 $rackData = spotEntity ('rack', $rack_id);
2025 amplifyCell ($rackData);
2026 for ($i = $rackData['height']; $i > 0; $i--)
2027 for ($locidx = 0; $locidx < 3; $locidx++
)
2028 $rackData[$i][$locidx]['state'] = 'F';
2029 $rackpack[$rack_id] = $rackData;
2031 $rackpack[$rack_id][$unit_no][$loclist[$atom]]['state'] = 'T';
2032 $rackpack[$rack_id][$unit_no][$loclist[$atom]]['object_id'] = $object_id;
2034 // now we have some racks to render
2035 foreach ($rackpack as $rackData)
2037 markAllSpans ($rackData);
2038 echo "<table class=molecule cellspacing=0>\n";
2039 echo "<caption>${rackData['name']}</caption>\n";
2040 echo "<tr><th width='10%'> </th><th width='20%'>Front</th><th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
2041 for ($i = $rackData['height']; $i > 0; $i--)
2043 echo "<tr><th>$i</th>";
2044 for ($locidx = 0; $locidx < 3; $locidx++
)
2046 $state = $rackData[$i][$locidx]['state'];
2047 echo "<td class=state_${state}> </td>\n";
2055 function renderDepot ()
2057 global $pageno, $nextorder;
2058 $cellfilter = getCellFilter();
2059 $objects = filterCellList (listCells ('object'), $cellfilter['expression']);
2061 echo "<table border=0 class=objectview>\n";
2062 echo "<tr><td class=pcleft>";
2064 if (! renderEmptyResults ($cellfilter, 'objects', count($objects)))
2066 startPortlet ('Objects (' . count ($objects) . ')');
2067 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
2068 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>Barcode</th><th>Row/Rack</th></tr>';
2070 foreach ($objects as $obj)
2072 if (isset ($_REQUEST['hl_object_id']) and $_REQUEST['hl_object_id'] == $obj['id'])
2073 $secondclass = 'tdleft port_highlight';
2075 $secondclass = 'tdleft';
2076 echo "<tr class=row_${order} valign=top><td class='${secondclass}'><a href='".makeHref(array('page'=>'object', 'object_id'=>$obj['id']))."'><strong>${obj['dname']}</strong></a>";
2077 if (count ($obj['etags']))
2078 echo '<br><small>' . serializeTags ($obj['etags'], makeHref(array('page'=>$pageno, 'tab'=>'default')) . '&') . '</small>';
2079 echo "</td><td class='${secondclass}'>${obj['label']}</td>";
2080 echo "<td class='${secondclass}'>${obj['asset_no']}</td>";
2081 echo "<td class='${secondclass}'>${obj['barcode']}</td>";
2082 if ($obj['rack_id'])
2083 echo "<td class='${secondclass}'><a href='".makeHref(array('page'=>'row', 'row_id'=>$obj['row_id']))."'>${obj['Row_name']}</a>/<a href='".makeHref(array('page'=>'rack', 'rack_id'=>$obj['rack_id']))."'>${obj['Rack_name']}</a></td>";
2085 echo "<td class='${secondclass}'>Unmounted</td>";
2087 $order = $nextorder[$order];
2093 echo "</td><td class=pcright width='25%'>";
2095 renderCellFilterPortlet ($cellfilter, 'object', $objects);
2096 echo "</td></tr></table>\n";
2099 // This function returns TRUE if the result set is too big to be rendered, and no filter is set.
2100 // In this case it renders the describing message instead.
2101 function renderEmptyResults($cellfilter, $entities_name, $count = NULL)
2103 if (!$cellfilter['is_empty'])
2105 if (isset ($_REQUEST['show_all_objects']))
2107 $max = intval(getConfigVar('MAX_UNFILTERED_ENTITIES'));
2108 if (0 == $max ||
$count <= $max)
2111 $href_show_all = trim($_SERVER['REQUEST_URI'], '&');
2112 $href_show_all .= htmlspecialchars('&show_all_objects=1');
2113 $suffix = isset ($count) ?
" ($count)" : '';
2115 <p>Please set a filter to display the corresponging $entities_name.
2116 <br><a href="$href_show_all">Show all $entities_name$suffix</a>
2121 // History viewer for history-enabled simple dictionaries.
2122 function renderHistory ($object_type, $object_id)
2124 switch ($object_type)
2127 $query = "select ctime, user_name, name, comment from RackRowHistory where id = ? order by ctime";
2128 $header = '<tr><th>change time</th><th>author</th><th>rack row name</th><th>rack row comment</th></tr>';
2133 "select ctime, user_name, rh.name, rr.name as name, rh.height, rh.comment " .
2134 "from RackHistory as rh left join RackRow as rr on rh.row_id = rr.id " .
2135 "where rh.id = ? order by ctime";
2136 $header = '<tr><th>change time</th><th>author</th><th>rack name</th><th>rack row name</th><th>rack height</th><th>rack comment</th></tr>';
2141 "select ctime, user_name, RackObjectHistory.name as name, label, barcode, asset_no, has_problems, dict_value, comment " .
2142 "from RackObjectHistory inner join Dictionary on objtype_id = dict_key join Chapter on Dictionary.chapter_id = Chapter.id " .
2143 "where Chapter.name = 'RackObjectType' and RackObjectHistory.id=? order by ctime";
2144 $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>has problems?</th><th>object type</th><th>comment</th></tr>';
2148 throw new InvalidArgException ('object_type', $object_type);
2150 $result = usePreparedSelectBlade ($query, array ($object_id));
2151 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
2155 while ($row = $result->fetch (PDO
::FETCH_NUM
))
2157 echo "<tr class=row_${order}><td>${row[0]}</td>";
2158 for ($i = 1; $i <= $extra; $i++
)
2159 echo "<td>" . $row[$i] . "</td>";
2161 $order = $nextorder[$order];
2163 echo "</table><br>\n";
2166 function renderRackspaceHistory ()
2168 global $nextorder, $pageno, $tabno;
2170 $history = getRackspaceHistory();
2171 // Show the last operation by default.
2172 if (isset ($_REQUEST['op_id']))
2173 $op_id = $_REQUEST['op_id'];
2174 elseif (isset ($history[0]['mo_id']))
2175 $op_id = $history[0]['mo_id'];
2182 list ($omid, $nmid) = getOperationMolecules ($op_id);
2184 // Main layout starts.
2185 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
2187 // Left top portlet with old allocation.
2188 echo "<tr><td class=pcleft>";
2189 startPortlet ('Old allocation');
2192 $oldMolecule = getMolecule ($omid);
2193 renderMolecule ($oldMolecule, $object_id);
2199 echo '</td><td class=pcright>';
2201 // Right top portlet with new allocation
2202 startPortlet ('New allocation');
2205 $newMolecule = getMolecule ($nmid);
2206 renderMolecule ($newMolecule, $object_id);
2212 echo '</td></tr><tr><td colspan=2>';
2214 // Bottom portlet with list
2216 startPortlet ('Rackspace allocation history');
2217 echo "<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>\n";
2218 echo "<tr><th>timestamp</th><th>author</th><th>object</th><th>comment</th></tr>\n";
2219 foreach ($history as $row)
2221 if ($row['mo_id'] == $op_id)
2224 $class = "row_${order}";
2225 echo "<tr class=${class}><td><a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno, 'op_id'=>$row['mo_id']))."'>${row['ctime']}</a></td>";
2226 echo "<td>${row['user_name']}</td><td>";
2227 renderCell (spotEntity ('object', $row['ro_id']));
2228 echo "</td><td>${row['comment']}</td>\n";
2230 $order = $nextorder[$order];
2235 echo '</td></tr></table>';
2238 function renderIPv4SpaceRecords ($tree, $baseurl, $target = 0, $knight, $level = 1)
2240 $self = __FUNCTION__
;
2241 static $vdomlist = NULL;
2242 if ($vdomlist == NULL and getConfigVar ('IPV4_TREE_SHOW_VLAN') == 'yes')
2243 $vdomlist = getVLANDomainOptions();
2244 foreach ($tree as $item)
2246 if (getConfigVar ('IPV4_TREE_SHOW_USAGE') == 'yes')
2247 loadIPv4AddrList ($item); // necessary to compute router list and address counter
2250 $item['addrlist'] = array();
2253 $used = $item['addrc'];
2254 $maxdirect = $item['addrt'];
2255 $maxtotal = binInvMaskFromDec ($item['mask']) +
1;
2256 if (isset ($item['id']))
2258 $decor = array ('indent' => $level);
2259 if ($item['symbol'] == 'node-collapsed')
2260 $decor['symbolurl'] = "${baseurl}&eid=" . $item['id'] . "#netid" . $item['id'];
2261 elseif ($item['symbol'] == 'node-expanded')
2262 $decor['symbolurl'] = $baseurl . ($item['parent_id'] ?
"&eid=${item['parent_id']}#netid${item['parent_id']}" : '');
2263 echo "<tr valign=top>";
2264 if ($target == $item['id'] && isset ($_REQUEST['hl_net']))
2265 $decor['tdclass'] .= ' port_highlight';
2266 printIPNetInfoTDs ($item, $decor);
2267 echo "<td class=tdcenter>";
2268 if ($target == $item['id'])
2269 echo "<a name=netid${target}></a>";
2270 if (getConfigVar ('IPV4_TREE_SHOW_USAGE') == 'yes')
2272 renderProgressBar ($maxdirect ?
$used/$maxdirect : 0);
2273 echo "<br><small>${used}/${maxdirect}" . ($maxdirect == $maxtotal ?
'' : "/${maxtotal}") . '</small>';
2276 echo "<small>${maxdirect}</small>";
2278 if (getConfigVar ('IPV4_TREE_SHOW_VLAN') == 'yes')
2280 echo '<td class=tdleft>';
2281 if (count ($item['8021q']))
2284 foreach ($item['8021q'] as $binding)
2286 echo '<li><a href="' . makeHref (array ('page' => 'vlan', 'vlan_ck' => $binding['domain_id'] . '-' . $binding['vlan_id'])) . '">';
2287 // FIXME: would formatVLANName() do this?
2288 echo $binding['vlan_id'] . '@' . niftyString ($vdomlist[$binding['domain_id']], 15) . '</a></li>';
2294 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
2295 printRoutersTD (findRouters ($item['addrlist']), getConfigVar ('IPV4_TREE_RTR_AS_CELL'));
2297 if ($item['symbol'] == 'node-expanded' or $item['symbol'] == 'node-expanded-static')
2298 $self ($item['kids'], $baseurl, $target, $knight, $level +
1);
2302 echo "<tr valign=top>";
2303 printIPNetInfoTDs ($item, array ('indent' => $level, 'knight' => $knight, 'tdclass' => 'sparenetwork'));
2304 echo "<td class=tdcenter>";
2305 if (getConfigVar ('IPV4_TREE_SHOW_USAGE') == 'yes')
2307 renderProgressBar ($used/$maxtotal, 'sparenetwork');
2308 echo "<br><small>${used}/${maxtotal}</small>";
2311 echo "<small>${maxtotal}</small>";
2312 if (getConfigVar ('IPV4_TREE_SHOW_VLAN') == 'yes')
2313 echo '</td><td> </td>';
2314 echo "</td><td> </td></tr>";
2319 function renderIPv6SpaceRecords ($tree, $baseurl, $target = 0, $knight, $level = 1)
2321 $self = __FUNCTION__
;
2322 static $vdomlist = NULL;
2323 if ($vdomlist == NULL and getConfigVar ('IPV4_TREE_SHOW_VLAN') == 'yes')
2324 $vdomlist = getVLANDomainOptions();
2325 foreach ($tree as $item)
2327 if (getConfigVar ('IPV4_TREE_SHOW_USAGE') == 'yes')
2328 loadIPv6AddrList ($item); // necessary to compute router list and address counter
2331 $item['addrlist'] = array();
2334 if (isset ($item['id']))
2336 $decor = array ('indent' => $level);
2337 if ($item['symbol'] == 'node-collapsed')
2338 $decor['symbolurl'] = "${baseurl}&eid=" . $item['id'] . "#netid" . $item['id'];
2339 elseif ($item['symbol'] == 'node-expanded')
2340 $decor['symbolurl'] = $baseurl . ($item['parent_id'] ?
"&eid=${item['parent_id']}#net6id${item['parent_id']}" : '');
2341 echo "<tr valign=top>";
2342 if ($target == $item['id'] && isset ($_REQUEST['hl_net']))
2343 $decor['tdclass'] .= ' port_highlight';
2344 printIPNetInfoTDs ($item, $decor);
2345 echo "<td class=tdcenter>";
2346 if ($target == $item['id'])
2347 echo "<a name=netid${target}></a>";
2349 echo formatIPv6NetUsage ($item['addrc'], $item['mask']);
2351 if (getConfigVar ('IPV4_TREE_SHOW_VLAN') == 'yes')
2353 echo '<td class=tdleft>';
2354 if (count ($item['8021q']))
2357 foreach ($item['8021q'] as $binding)
2359 echo '<li><a href="' . makeHref (array ('page' => 'vlan', 'vlan_ck' => $binding['domain_id'] . '-' . $binding['vlan_id'])) . '">';
2360 // FIXME: would formatVLANName() do this?
2361 echo $binding['vlan_id'] . '@' . niftyString ($vdomlist[$binding['domain_id']], 15) . '</a></li>';
2367 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
2368 printRoutersTD (findRouters ($item['addrlist']), getConfigVar ('IPV4_TREE_RTR_AS_CELL'));
2370 if ($item['symbol'] == 'node-expanded' or $item['symbol'] == 'node-expanded-static')
2371 $self ($item['kids'], $baseurl, $target, $knight, $level +
1);
2373 /* do not display spare networks
2375 { // display spare networks
2376 echo "<tr valign=top>";
2377 printIPNetInfoTDs ($item, array ('indent' => $level, 'knight' => $knight, 'tdclass' => 'sparenetwork'));
2378 echo "<td class=tdcenter>";
2379 echo formatIPv6NetUsage ($item['addrc'], $item['mask']);
2380 if (getConfigVar ('IPV4_TREE_SHOW_VLAN') == 'yes')
2381 echo '</td><td> </td>';
2382 echo "</td><td> </td></tr>";
2387 // if $used is NULL, returns only human-formatted mask.
2388 // Otherwise returns "$used in/of " . human-formatted-mask
2389 function formatIPv6NetUsage ($used, $mask)
2407 $preposition = 'in';
2413 $preposition = 'of';
2415 $what .= (0 == $mask %
64 ?
'' : 's');
2416 $addrc = isset ($used) ?
"$used $preposition " : '';
2418 $dec_order = intval ((128 - $mask) / 10) * 3;
2419 $mult = isset ($prefixes[$dec_order]) ?
$prefixes[$dec_order] : '??';
2421 $cnt = 1 << ((128 - $mask) %
10);
2422 if ($cnt == 1 && $mult == '')
2425 return "<small>${addrc}${cnt}${mult} ${what}</small>";
2428 function renderIPv4Space ()
2430 global $pageno, $tabno;
2431 $cellfilter = getCellFilter();
2432 $netlist = listCells ('ipv4net');
2433 $allcount = count ($netlist);
2434 $netlist = filterCellList ($netlist, $cellfilter['expression']);
2435 array_walk ($netlist, 'amplifyCell');
2437 $netcount = count ($netlist);
2438 // expand request can take either natural values or "ALL". Zero means no expanding.
2439 $eid = isset ($_REQUEST['eid']) ?
$_REQUEST['eid'] : 0;
2440 $tree = prepareIPv4Tree ($netlist, $eid);
2442 echo "<table border=0 class=objectview>\n";
2443 echo "<tr><td class=pcleft>";
2444 if (! renderEmptyResults($cellfilter, 'IPv4 nets', count($tree)))
2446 startPortlet ("networks (${netcount})");
2449 echo 'auto-collapsing at threshold ' . getConfigVar ('TREE_THRESHOLD') .
2450 " (<a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno, 'eid'=>'ALL')) .
2451 $cellfilter['urlextra'] . "'>expand all</a>)";
2452 elseif ($eid === 'ALL')
2453 echo "expanding all (<a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno)) .
2454 $cellfilter['urlextra'] . "'>auto-collapse</a>)";
2457 $netinfo = spotEntity ('ipv4net', $eid);
2458 echo "expanding ${netinfo['ip']}/${netinfo['mask']} (<a href='" .
2459 makeHref (array ('page' => $pageno, 'tab' => $tabno)) .
2460 $cellfilter['urlextra'] . "'>auto-collapse</a> / <a href='" .
2461 makeHref (array ('page' => $pageno, 'tab' => $tabno, 'eid' => 'ALL')) .
2462 $cellfilter['urlextra'] . "'>expand all</a>)";
2464 echo "</h4><table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
2465 echo "<tr><th>prefix</th><th>name/tags</th><th>capacity</th>";
2466 if (getConfigVar ('IPV4_TREE_SHOW_VLAN') == 'yes')
2467 echo '<th>VLAN</th>';
2468 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
2469 echo "<th>routed by</th>";
2471 $baseurl = makeHref(array('page'=>$pageno, 'tab'=>$tabno)) . $cellfilter['urlextra'];
2472 renderIPv4SpaceRecords ($tree, $baseurl, $eid, $netcount == $allcount and getConfigVar ('IPV4_ENABLE_KNIGHT') == 'yes');
2477 echo '</td><td class=pcright>';
2478 renderCellFilterPortlet ($cellfilter, 'ipv4net', $netlist);
2479 echo "</td></tr></table>\n";
2482 function renderIPv6Space ()
2484 global $pageno, $tabno;
2485 $cellfilter = getCellFilter();
2486 $netlist = listCells ('ipv6net');
2487 $allcount = count ($netlist);
2488 $netlist = filterCellList ($netlist, $cellfilter['expression']);
2489 array_walk ($netlist, 'amplifyCell');
2491 $netcount = count ($netlist);
2492 // expand request can take either natural values or "ALL". Zero means no expanding.
2493 $eid = isset ($_REQUEST['eid']) ?
$_REQUEST['eid'] : 0;
2494 $tree = prepareIPv6Tree ($netlist, $eid);
2496 echo "<table border=0 class=objectview>\n";
2497 echo "<tr><td class=pcleft>";
2498 if (! renderEmptyResults($cellfilter, 'IPv6 nets', count($tree)))
2500 startPortlet ("networks (${netcount})");
2503 echo 'auto-collapsing at threshold ' . getConfigVar ('TREE_THRESHOLD') .
2504 " (<a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno, 'eid'=>'ALL')) .
2505 $cellfilter['urlextra'] . "'>expand all</a>)";
2506 elseif ($eid === 'ALL')
2507 echo "expanding all (<a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno)) .
2508 $cellfilter['urlextra'] . "'>auto-collapse</a>)";
2511 $netinfo = spotEntity ('ipv6net', $eid);
2512 echo "expanding ${netinfo['ip']}/${netinfo['mask']} (<a href='" .
2513 makeHref (array ('page' => $pageno, 'tab' => $tabno)) .
2514 $cellfilter['urlextra'] . "'>auto-collapse</a> / <a href='" .
2515 makeHref (array ('page' => $pageno, 'tab' => $tabno, 'eid' => 'ALL')) .
2516 $cellfilter['urlextra'] . "'>expand all</a>)";
2518 echo "</h4><table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
2519 echo "<tr><th>prefix</th><th>name/tags</th><th>capacity</th>";
2520 if (getConfigVar ('IPV4_TREE_SHOW_VLAN') == 'yes')
2521 echo '<th>VLAN</th>';
2522 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
2523 echo "<th>routed by</th>";
2525 $baseurl = makeHref(array('page'=>$pageno, 'tab'=>$tabno)) . $cellfilter['urlextra'];
2526 renderIPv6SpaceRecords ($tree, $baseurl, $eid, $netcount == $allcount and getConfigVar ('IPV4_ENABLE_KNIGHT') == 'yes');
2531 echo '</td><td class=pcright>';
2532 renderCellFilterPortlet ($cellfilter, 'ipv6net', $netlist);
2533 echo "</td></tr></table>\n";
2536 function renderSLBDefConfig()
2538 $defaults = getSLBDefaults ();
2539 startPortlet ('SLB default configs');
2540 echo '<table cellspacing=0 cellpadding=5 align=center>';
2541 printOpFormIntro ('save');
2542 echo '<tr><th class=tdright>VS config</th><td colspan=2><textarea tabindex=103 name=vsconfig rows=10 cols=80>' . htmlspecialchars($defaults['vs']) . '</textarea></td>';
2543 echo '<td rowspan=2>';
2544 printImageHREF ('SAVE', 'Save changes', TRUE);
2546 echo '<tr><th class=tdright>RS config</th><td colspan=2><textarea tabindex=104 name=rsconfig rows=10 cols=80>' . htmlspecialchars($defaults['rs']) . '</textarea></td></tr>';
2547 echo '</form></table>';
2551 function renderIPv4SLB ()
2553 global $page, $nextorder;
2555 startPortlet ('SLB configuration');
2556 echo "<table border=0 width='100%'><tr>";
2557 foreach (array ('ipv4vslist', 'ipv4rsplist', 'rservers', 'lbs') as $pno)
2558 echo "<td><h3><a href='".makeHref(array('page'=>$pno))."'>" . $page[$pno]['title'] . "</a></h3></td>";
2559 echo '</tr></table>';
2562 $summary = getSLBSummary();
2563 startPortlet ('SLB tactical overview');
2564 // A single id-keyed array isn't used here to preserve existing
2565 // order of LBs returned by getSLBSummary()
2568 foreach ($summary as $vipdata)
2569 foreach (array_keys ($vipdata['lblist']) as $lb_object_id)
2570 if (!in_array ($lb_object_id, $lblist))
2572 $oi = spotEntity ('object', $lb_object_id);
2573 $lbdname[$lb_object_id] = $oi['dname'];
2574 $lblist[] = $lb_object_id;
2576 if (!count ($summary))
2577 echo 'none configured';
2581 echo "<table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
2582 echo "<tr valign=top><td> </td>";
2583 foreach ($lblist as $lb_object_id)
2585 #echo "<th><a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$lb_object_id))."'>" . $lbdname[$lb_object_id] . "</a></th>";
2587 renderLBCell ($lb_object_id);
2591 foreach ($summary as $vsid => $vsdata)
2593 echo "<tr class=row_${order}><td class=tdleft>";
2594 renderCell (spotEntity ('ipv4vs', $vsid));
2596 foreach ($lblist as $lb_object_id)
2598 echo '<td class=tdleft>';
2599 if (!isset ($vsdata['lblist'][$lb_object_id]))
2603 echo $vsdata['lblist'][$lb_object_id]['size'];
2604 // echo " (<a href='".makeHref(array('page'=>'ipv4rspool', 'pool_id'=>$vsdata['lblist'][$lb_object_id]['id'])). "'>";
2605 // echo $vsdata['lblist'][$lb_object_id]['name'] . '</a>)';
2610 $order = $nextorder[$order];
2617 function renderIPv4SpaceEditor ()
2621 <script type
="text/javascript">
2623 document
.add_new_range
.range
.setAttribute('match', "^\\d\\d?\\d?\\.\\d\\d?\\d?\\.\\d\\d?\\d?\\.\\d\\d?\\d?\\/\\d\\d?$");
2631 function printNewItemTR ()
2633 startPortlet ('Add new');
2634 echo '<table border=0 cellpadding=10 align=center>';
2635 // This form requires a name, so JavaScript validator can find it.
2636 // No printOpFormIntro() hence
2637 echo "<form method=post name='add_new_range' action='".makeHrefProcess()."'>\n";
2638 echo "<input type=hidden name=op value=addIPv4Prefix>\n";
2640 echo '<tr><td rowspan=4><h3>assign tags</h3>';
2641 renderNewEntityTags ('ipv4net');
2644 $prefix_value = empty ($_REQUEST['set-prefix']) ?
'' : $_REQUEST['set-prefix'];
2645 echo "<th class=tdright>prefix</th><td class=tdleft><input type=text name='range' size=18 class='live-validate' tabindex=1 value='${prefix_value}'></td>";
2646 echo "<tr><th class=tdright>name</th><td class=tdleft><input type=text name='name' size='20' tabindex=2></td></tr>";
2647 echo "<tr><th class=tdright>connected network</th><td class=tdleft><input type=checkbox name='is_bcast' tabindex=3></td></tr>";
2648 echo "<tr><td colspan=2>";
2649 printImageHREF ('CREATE', 'Add a new network', TRUE, 4);
2651 echo "</form></table><br><br>\n";
2655 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
2657 if (count ($addrspaceList = listCells ('ipv4net')))
2659 startPortlet ('Manage existing (' . count ($addrspaceList) . ')');
2660 echo "<table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
2661 echo "<tr><th> </th><th>prefix</th><th>name</th><th>capacity</th></tr>";
2662 array_walk ($addrspaceList, 'amplifyCell');
2663 $tree = prepareIPv4Tree ($addrspaceList, 'ALL');
2664 // this is only called for having "trace" set
2665 treeFromList ($addrspaceList);
2666 foreach ($addrspaceList as $netinfo)
2668 $netinfo = peekNode ($tree, $netinfo['trace'], $netinfo['id']);
2669 // now we have all subnets listed in netinfo
2670 loadIPv4AddrList ($netinfo);
2671 $used = $netinfo['addrc'];
2672 $maxdirect = $netinfo['addrt'];
2673 $maxtotal = binInvMaskFromDec ($netinfo['mask']) +
1;
2674 echo "<tr valign=top><td>";
2675 if (count ($netinfo['addrlist']) && getConfigVar ('IPV4_JAYWALK') == 'no')
2676 printImageHREF ('nodestroy', 'There are ' . count ($netinfo['addrlist']) . ' allocations inside');
2679 echo "<a href='".makeHrefProcess(array('op'=>'delIPv4Prefix', 'id'=>$netinfo['id']))."'>";
2680 printImageHREF ('destroy', 'Delete this prefix');
2683 echo '</td><td class=tdleft><a href="' . makeHref (array ('page' => 'ipv4net', 'id' => $netinfo['id'])) . '">';
2684 echo "${netinfo['ip']}/${netinfo['mask']}</a></td>";
2685 echo '<td class=tdleft>' . niftyString ($netinfo['name']);
2686 if (count ($netinfo['etags']))
2687 echo '<br><small>' . serializeTags ($netinfo['etags']) . '</small>';
2689 renderProgressBar ($maxdirect ?
$used/$maxdirect : 0);
2690 echo "<br><small>${used}/${maxdirect}" . ($maxdirect == $maxtotal ?
'' : "/${maxtotal}") . '</small></td>';
2696 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
2700 function renderIPv6SpaceEditor ()
2704 <script type
="text/javascript">
2706 document
.add_new_range
.range
.setAttribute ('match', '^[a-fA-F0-9:]*:[a-fA-F0-9:\\.]*\/\\d{1,3}$');
2714 function printNewItemTR ()
2716 startPortlet ('Add new');
2717 echo '<table border=0 cellpadding=10 align=center>';
2718 // This form requires a name, so JavaScript validator can find it.
2719 // No printOpFormIntro() hence
2720 echo "<form method=post name='add_new_range' action='".makeHrefProcess()."'>\n";
2721 echo "<input type=hidden name=op value=addIPv6Prefix>\n";
2723 echo '<tr><td rowspan=4><h3>assign tags</h3>';
2724 renderNewEntityTags ('ipv4net');
2727 $prefix_value = empty ($_REQUEST['set-prefix']) ?
'' : $_REQUEST['set-prefix'];
2728 echo "<th class=tdright>prefix</th><td class=tdleft><input type=text name='range' size=36 class='live-validate' tabindex=1 value='${prefix_value}'></td>";
2729 echo "<tr><th class=tdright>name</th><td class=tdleft><input type=text name='name' size='20' tabindex=2></td></tr>";
2730 echo "<tr><td colspan=2>";
2731 printImageHREF ('CREATE', 'Add a new network', TRUE, 4);
2733 echo "</form></table><br><br>\n";
2737 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
2739 if (count ($addrspaceList = listCells ('ipv6net')))
2741 startPortlet ('Manage existing (' . count ($addrspaceList) . ')');
2742 echo "<table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
2743 echo "<tr><th> </th><th>prefix</th><th>name</th><th>capacity</th></tr>";
2744 array_walk ($addrspaceList, 'amplifyCell');
2745 $tree = prepareIPv6Tree ($addrspaceList, 'ALL');
2746 // this is only called for having "trace" set
2747 treeFromList ($addrspaceList);
2748 foreach ($addrspaceList as $netinfo)
2750 $netinfo = peekNode ($tree, $netinfo['trace'], $netinfo['id']);
2751 // now we have all subnets listed in netinfo
2752 loadIPv6AddrList ($netinfo);
2753 echo "<tr valign=top><td>";
2754 if (count ($netinfo['addrlist']) && getConfigVar ('IPV4_JAYWALK') == 'no')
2755 printImageHREF ('nodestroy', 'There are ' . count ($netinfo['addrlist']) . ' allocations inside');
2758 echo "<a href='".makeHrefProcess (array ('op' => 'delIPv6Prefix', 'id' => $netinfo['id'])) . "'>";
2759 printImageHREF ('destroy', 'Delete this prefix');
2762 echo '</td><td class=tdleft><a href="' . makeHref (array ('page' => 'ipv6net', 'id' => $netinfo['id'])) . '">';
2763 echo "${netinfo['ip']}/${netinfo['mask']}</a></td>";
2764 echo '<td class=tdleft>' . niftyString ($netinfo['name']);
2765 if (count ($netinfo['etags']))
2766 echo '<br><small>' . serializeTags ($netinfo['etags']) . '</small>';
2768 echo formatIPv6NetUsage ($netinfo['addrc'], $netinfo['mask']);
2774 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
2778 function renderIPv4Network ($id)
2780 global $pageno, $tabno, $aac2, $netmaskbylen, $wildcardbylen;
2781 $maxperpage = getConfigVar ('IPV4_ADDRS_PER_PAGE');
2782 if (isset($_REQUEST['pg']))
2783 $page = $_REQUEST['pg'];