r4910 APCPowerSwitch::getPorts () - change snmpwalk call to snmpwalkoid, fixes #504
[racktables] / wwwroot / inc / popup.php
CommitLineData
38ee0db8 1<?php
cd3775e9
DO
2
3// Return a list of rack IDs, which are P or less positions
4// far from the given rack in its row.
5function getProximateRacks ($rack_id, $proximity = 0)
6{
cd3775e9 7 $ret = array ($rack_id);
76a7ec36 8 if ($proximity > 0)
cd3775e9 9 {
76a7ec36
AA
10 $rack = spotEntity ('rack', $rack_id);
11 $rackList = listCells ('rack', $rack['row_id']);
12 doubleLink ($rackList);
13 $todo = $proximity;
14 $cur_item = $rackList[$rack_id];
15 while ($todo and array_key_exists ('prev_key', $cur_item))
16 {
17 $cur_item = $rackList[$cur_item['prev_key']];
18 $ret[] = $cur_item['id'];
19 $todo--;
20 }
21 $todo = $proximity;
22 $cur_item = $rackList[$rack_id];
23 while ($todo and array_key_exists ('next_key', $cur_item))
24 {
25 $cur_item = $rackList[$cur_item['next_key']];
26 $ret[] = $cur_item['id'];
27 $todo--;
28 }
cd3775e9
DO
29 }
30 return $ret;
31}
32
2030a7f2 33function findSparePorts ($port_info, $filter)
cd3775e9 34{
2030a7f2 35 $qparams = array ();
0037d053
AA
36 $query = "
37SELECT
38 p.id,
39 p.name,
40 p.reservation_comment,
41 p.iif_id,
42 p.type as oif_id,
43 pii.iif_name,
44 d.dict_value as oif_name,
45 p.object_id,
46 o.name as object_name
47FROM Port p
48INNER JOIN Object o ON o.id = p.object_id
49INNER JOIN PortInnerInterface pii ON p.iif_id = pii.id
50INNER JOIN Dictionary d ON d.dict_key = p.type
51";
2030a7f2 52 // porttype filter (non-strict match)
9e5dc00a
AA
53 $query .= "
54INNER JOIN (
55 SELECT Port.id FROM Port
56 INNER JOIN
57 (
58 SELECT DISTINCT pic2.iif_id
59 FROM PortInterfaceCompat pic2
60 INNER JOIN PortCompat pc ON pc.type2 = pic2.oif_id
61";
62 if ($port_info['iif_id'] != 1)
63 {
7df4dcad 64 $query .= " INNER JOIN PortInterfaceCompat pic ON pic.oif_id = pc.type1 WHERE pic.iif_id = ? AND ";
9e5dc00a
AA
65 $qparams[] = $port_info['iif_id'];
66 }
67 else
68 {
69 $query .= " WHERE pc.type1 = ? AND ";
70 $qparams[] = $port_info['oif_id'];
71 }
72 $query .= "
73 pic2.iif_id <> 1
74 ) AS sub1 USING (iif_id)
75 UNION
76 SELECT Port.id
77 FROM Port
78 INNER JOIN PortCompat ON type1 = type
79 WHERE
80 iif_id = 1 and type2 = ?
81) AS sub2 ON sub2.id = p.id
82";
2030a7f2 83 $qparams[] = $port_info['oif_id'];
9e5dc00a 84
2030a7f2 85 // self and linked ports filter
9e5dc00a 86 $query .= " WHERE p.id <> ? " .
2030a7f2
AA
87 "AND p.id NOT IN (SELECT porta FROM Link) " .
88 "AND p.id NOT IN (SELECT portb FROM Link) ";
89 $qparams[] = $port_info['id'];
90 // rack filter
91 if (! empty ($filter['racks']))
92 {
93 $query .= 'AND p.object_id IN (SELECT DISTINCT object_id FROM RackSpace WHERE rack_id IN (' .
94 questionMarks (count ($filter['racks'])) . ')) ';
95 $qparams = array_merge ($qparams, $filter['racks']);
96 }
97 // objectname filter
98 if (! empty ($filter['objects']))
cd3775e9 99 {
2030a7f2
AA
100 $query .= 'AND o.name like ? ';
101 $qparams[] = '%' . $filter['objects'] . '%';
cd3775e9 102 }
2030a7f2
AA
103 // portname filter
104 if (! empty ($filter['ports']))
105 {
106 $query .= 'AND p.name LIKE ? ';
107 $qparams[] = '%' . $filter['ports'] . '%';
108 }
109 // ordering
0037d053 110 $query .= ' ORDER BY o.name';
a8838b74 111
2030a7f2
AA
112 $ret = array();
113 $result = usePreparedSelectBlade ($query, $qparams);
0037d053
AA
114
115 $rows_by_pn = array();
116 $prev_object_id = NULL;
117
118 // fetch port rows from the DB
119 while (TRUE)
120 {
121 $row = $result->fetch (PDO::FETCH_ASSOC);
122 if (isset ($prev_object_id) and (! $row or $row['object_id'] != $prev_object_id))
123 {
124 // handle sorted object's portlist
125 foreach (sortPortList ($rows_by_pn) as $ports_subarray)
126 foreach ($ports_subarray as $port_row)
127 {
128 $port_description = $port_row['object_name'] . ' -- ' . $port_row['name'];
129 if (count ($ports_subarray) > 1)
130 {
131 $if_type = $port_row['iif_id'] == 1 ? $port_row['oif_name'] : $port_row['iif_name'];
132 $port_description .= " ($if_type)";
133 }
134 if (! empty ($port_row['reservation_comment']))
135 $port_description .= ' -- ' . $port_row['reservation_comment'];
136 $ret[$port_row['id']] = $port_description;
137 }
138 $rows_by_pn = array();
139 }
140 $prev_object_id = $row['object_id'];
141 if ($row)
142 $rows_by_pn[$row['name']][] = $row;
143 else
144 break;
145 }
2030a7f2 146
cd3775e9
DO
147 return $ret;
148}
149
0682218d
AD
150// Return a list of all objects which are possible parents
151// Special case for VMs and VM Virtual Switches
152// - only select Servers with the Hypervisor attribute set to Yes
9b8174d7 153function findObjectParentCandidates ($object_id)
0682218d
AD
154{
155 $object = spotEntity ('object', $object_id);
156 $args = array ($object['objtype_id'], $object_id, $object_id);
157
9b8174d7
AD
158 $query = "SELECT O.id, O.name FROM Object O ";
159 $query .= "LEFT JOIN ObjectParentCompat OPC ON O.objtype_id = OPC.parent_objtype_id ";
0682218d 160 $query .= "WHERE OPC.child_objtype_id = ? ";
9b8174d7 161 $query .= "AND O.id != ? ";
0682218d 162 // exclude existing parents
9b8174d7 163 $query .= "AND O.id NOT IN (SELECT parent_entity_id FROM EntityLink WHERE parent_entity_type = 'object' AND child_entity_type = 'object' AND child_entity_id = ?) ";
0682218d
AD
164 if ($object['objtype_id'] == 1504 || $object['objtype_id'] == 1507)
165 {
166 array_push($args, $object['objtype_id'], $object_id, $object_id);
167 $query .= "AND OPC.parent_objtype_id != 4 ";
168 $query .= "UNION ";
9b8174d7
AD
169 $query .= "SELECT O.id, O.name FROM Object O ";
170 $query .= "LEFT JOIN ObjectParentCompat OPC ON O.objtype_id = OPC.parent_objtype_id ";
171 $query .= "LEFT JOIN AttributeValue AV ON O.id = AV.object_id ";
0682218d 172 $query .= "WHERE OPC.child_objtype_id = ? ";
9b8174d7
AD
173 $query .= "AND (O.objtype_id = 4 AND AV.attr_id = 26 AND AV.uint_value = 1501) ";
174 $query .= "AND O.id != ? ";
0682218d 175 // exclude existing parents
9b8174d7 176 $query .= "AND O.id NOT IN (SELECT parent_entity_id FROM EntityLink WHERE parent_entity_type = 'object' AND child_entity_type = 'object' AND child_entity_id = ?) ";
0682218d
AD
177 }
178 $query .= "ORDER BY 2";
179
180 $result = usePreparedSelectBlade ($query, $args);
181 $ret = array();
182 while ($row = $result->fetch (PDO::FETCH_ASSOC))
183 $ret[$row['id']] = $row['name'];
184 return $ret;
185}
186
9a15394d
DO
187function sortObjectAddressesAndNames ($a, $b)
188{
189 $objname_cmp = sortTokenize($a['object_name'], $b['object_name']);
190 if ($objname_cmp == 0)
191 {
192 $name_a = (isset ($a['port_name'])) ? $a['port_name'] : '';
193 $name_b = (isset ($b['port_name'])) ? $b['port_name'] : '';
194 $objname_cmp = sortTokenize($name_a, $name_b);
195 if ($objname_cmp == 0)
196 sortTokenize($a['ip'], $b['ip']);
197 return $objname_cmp;
198 }
199 return $objname_cmp;
200}
201
2030a7f2
AA
202function renderPopupObjectSelector()
203{
204 $object_id = getBypassValue();
205 echo '<div style="background-color: #f0f0f0; border: 1px solid #3c78b5; padding: 10px; height: 100%; text-align: center; margin: 5px;">';
206 echo '<h2>Choose a container:</h2>';
207 echo '<form action="javascript:;">';
208 $parents = findObjectParentCandidates($object_id);
209 printSelect ($parents, array ('name' => 'parents', 'size' => getConfigVar ('MAXSELSIZE')));
210 echo '<br>';
211 echo "<input type=submit value='Proceed' onclick='".
212 "if (getElementById(\"parents\").value != \"\") {".
213 " opener.location=\"?module=redirect&page=object&tab=edit&op=linkEntities&object_id=${object_id}&child_entity_type=object&child_entity_id=${object_id}&parent_entity_type=object&parent_entity_id=\"+getElementById(\"parents\").value; ".
214 " window.close();}'>";
215 echo '</form></div>';
216}
217
218function handlePopupPortLink()
219{
220 assertUIntArg ('port');
221 assertUIntArg ('remote_port');
222 assertStringArg ('cable', TRUE);
223 $port_info = getPortInfo ($_REQUEST['port']);
224 $remote_port_info = getPortInfo ($_REQUEST['remote_port']);
225 $POIFC = getPortOIFCompat();
226 if (isset ($_REQUEST['port_type']) and isset ($_REQUEST['remote_port_type']))
227 {
228 $type_local = $_REQUEST['port_type'];
229 $type_remote = $_REQUEST['remote_port_type'];
230 }
231 else
232 {
233 $type_local = $port_info['oif_id'];
234 $type_remote = $remote_port_info['oif_id'];
235 }
236 $matches = FALSE;
237 $js_table = '';
238 foreach ($POIFC as $pair)
239 if ($pair['type1'] == $type_local && $pair['type2'] == $type_remote)
240 {
241 $matches = TRUE;
242 break;
243 }
244 else
245 $js_table .= "POIFC['${pair['type1']}-${pair['type2']}'] = 1;\n";
246
247 if ($matches)
248 {
249 if ($port_info['oif_id'] != $type_local)
250 commitUpdatePortOIF ($port_info['id'], $type_local);
251 if ($remote_port_info['oif_id'] != $type_remote)
252 commitUpdatePortOIF ($remote_port_info['id'], $type_remote);
253 linkPorts ($port_info['id'], $remote_port_info['id'], $_REQUEST['cable']);
254 showOneLiner
255 (
256 8,
257 array
258 (
259 formatPortLink ($port_info['id'], $port_info['name'], NULL, NULL),
260 formatPort ($remote_port_info),
261 )
262 );
263 addJS (<<<END
264window.opener.location.reload(true);
265window.close();
266END
267 , TRUE);
268 }
269 else
270 {
271 // JS code to display port compatibility hint
272 addJS (<<<END
273POIFC = {};
274$js_table
275$(document).ready(function () {
276 $('select.porttype').change(onPortTypeChange);
277 onPortTypeChange();
278});
279function onPortTypeChange() {
280 var key = $('*[name=port_type]')[0].value + '-' + $('*[name=remote_port_type]')[0].value;
281 if (POIFC[key] == 1)
282 {
283 $('#hint-not-compat').hide();
284 $('#hint-compat').show();
285 }
286 else
287 {
288 $('#hint-compat').hide();
289 $('#hint-not-compat').show();
290 }
291}
292END
293 , TRUE);
294 addCSS (<<<END
295.compat-hint {
296 display: none;
297 font-size: 125%;
298}
299.compat-hint#hint-compat {
300 color: green;
301}
302.compat-hint#hint-not-compat {
303 color: #804040;
304}
305END
306 , TRUE);
307 // render port type editor form
308 echo '<form method=GET>';
309 echo '<input type=hidden name="module" value="popup">';
310 echo '<input type=hidden name="helper" value="portlist">';
311 echo '<input type=hidden name="port" value="' . $port_info['id'] . '">';
312 echo '<input type=hidden name="remote_port" value="' . $remote_port_info['id'] . '">';
313 echo '<input type=hidden name="cable" value="' . htmlspecialchars ($_REQUEST['cable'], ENT_QUOTES) . '">';
314 echo '<p>The ports you have selected are not compatible. Please select a compatible transceiver pair.';
315 echo '<p>';
316 echo formatPort ($port_info) . ' ';
317 if ($port_info['iif_id'] == 1)
318 {
319 echo formatPortIIFOIF ($port_info);
320 echo '<input type=hidden name="port_type" value="' . $port_info['oif_id'] . '">';
321 }
322 else
323 {
324 echo '<label>' . $port_info['iif_name'] . ' ';
325 printSelect (getExistingPortTypeOptions ($port_info['id']), array ('class' => 'porttype', 'name' => 'port_type'), $type_local);
326 echo '</label>';
327 }
328 echo ' &mdash; ';
329 if ($remote_port_info['iif_id'] == 1)
330 {
331 echo formatPortIIFOIF ($remote_port_info);
332 echo '<input type=hidden name="remote_port_type" value="' . $remote_port_info['oif_id'] . '">';
333 }
334 else
335 {
336 echo '<label>' . $remote_port_info['iif_name'] . ' ';
337 printSelect (getExistingPortTypeOptions ($remote_port_info['id']), array ('class' => 'porttype', 'name' => 'remote_port_type'), $type_remote);
338 echo '</label>';
339 }
340 echo ' ' . formatPort ($remote_port_info);
341 echo '<p class="compat-hint" id="hint-not-compat">&#10005; Not compatible port types</p>';
342 echo '<p class="compat-hint" id="hint-compat">&#10004; Compatible port types</p>';
343 echo '<p><input type=submit name="do_link" value="Link">';
344 }
345}
346
347function renderPopupPortSelector()
348{
349 assertUIntArg ('port');
350 $port_id = $_REQUEST['port'];
351 $port_info = getPortInfo ($port_id);
352 $in_rack = isset ($_REQUEST['in_rack']);
353
354 // fill port filter structure
355 $filter = array
356 (
357 'racks' => array(),
358 'objects' => '',
359 'ports' => '',
360 );
361 if (isset ($_REQUEST['filter-obj']))
362 $filter['objects'] = $_REQUEST['filter-obj'];
363 if (isset ($_REQUEST['filter-port']))
364 $filter['ports'] = $_REQUEST['filter-port'];
365 if ($in_rack)
366 {
367 $object = spotEntity ('object', $port_info['object_id']);
368 if ($object['rack_id'])
369 $filter['racks'] = getProximateRacks ($object['rack_id'], getConfigVar ('PROXIMITY_RANGE'));
370 }
9e5dc00a
AA
371 $spare_ports = array();
372 if
373 (
374 $in_rack ||
375 ! empty ($filter['objects']) ||
376 ! empty ($filter['ports'])
377 )
378 $spare_ports = findSparePorts ($port_info, $filter);
2030a7f2
AA
379
380 // display search form
381 echo 'Link ' . formatPort ($port_info) . ' to...';
382 echo '<form method=GET>';
383 startPortlet ('Port list filter');
384 echo '<input type=hidden name="module" value="popup">';
385 echo '<input type=hidden name="helper" value="portlist">';
386 echo '<input type=hidden name="port" value="' . $port_id . '">';
387 echo '<table align="center" valign="bottom"><tr>';
388 echo '<td class="tdleft"><label>Object name:<br><input type=text size=8 name="filter-obj" value="' . htmlspecialchars ($filter['objects'], ENT_QUOTES) . '"></label></td>';
389 echo '<td class="tdleft"><label>Port name:<br><input type=text size=6 name="filter-port" value="' . htmlspecialchars ($filter['ports'], ENT_QUOTES) . '"></label></td>';
76a7ec36 390 echo '<td class="tdleft" valign="bottom"><label><input type=checkbox name="in_rack"' . ($in_rack ? ' checked' : '') . '>Nearest racks</label></td>';
2030a7f2
AA
391 echo '<td valign="bottom"><input type=submit value="show ports"></td>';
392 echo '</tr></table>';
393 finishPortlet();
394
395 // display results
396 startPortlet ('Compatible spare ports');
397 if (empty ($spare_ports))
398 echo '(nothing found)';
399 else
400 {
401 echo getSelect ($spare_ports, array ('name' => 'remote_port', 'size' => getConfigVar ('MAXSELSIZE')), NULL, FALSE);
402 echo "<p>Cable ID: <input type=text id=cable name=cable>";
403 echo "<p><input type='submit' value='Link' name='do_link'>";
404 }
405 finishPortlet();
406 echo '</form>';
407}
408
409function renderPopupIPv4Selector()
410{
411 echo '<div style="background-color: #f0f0f0; border: 1px solid #3c78b5; padding: 10px; height: 100%; text-align: center; margin: 5px;">';
412 echo '<h2>Choose a port:</h2><br><br>';
413 echo '<form action="javascript:;">';
414 echo '<input type=hidden id=ip>';
415 echo '<select size=' . getConfigVar ('MAXSELSIZE') . ' id=addresses>';
416 $addresses = getAllIPv4Allocations();
417 usort ($addresses, 'sortObjectAddressesAndNames');
418 foreach ($addresses as $address)
419 echo "<option value='${address['ip']}' onclick='getElementById(\"ip\").value=\"${address['ip']}\";'>" .
420 "${address['object_name']} ${address['name']} ${address['ip']}</option>\n";
421 echo '</select><br><br>';
422 echo "<input type=submit value='Proceed' onclick='".
423 "if (getElementById(\"ip\")!=\"\") {".
424 " opener.document.getElementById(\"remoteip\").value=getElementById(\"ip\").value;".
425 " window.close();}'>";
426 echo '</form></div>';
427}
428
e0ce8064
DO
429function renderPopupHTML()
430{
431 global $pageno, $tabno;
878512c6 432header ('Content-Type: text/html; charset=UTF-8');
e0ce8064 433?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
39106006 434<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" style="height: 100%;">
b325120a 435<?php
0cc24e9a 436 assertStringArg ('helper');
2030a7f2 437 $text = '';
39106006
DO
438 switch ($_REQUEST['helper'])
439 {
0682218d
AD
440 case 'objlist':
441 $pageno = 'object';
442 $tabno = 'default';
443 fixContext();
3ec33017 444 assertPermission();
2030a7f2 445 $text .= getOutputOf ('renderPopupObjectSelector');
0682218d 446 break;
39106006 447 case 'portlist':
026a79ee
DO
448 $pageno = 'depot';
449 $tabno = 'default';
4dc8e857 450 fixContext();
3ec33017 451 assertPermission();
2030a7f2
AA
452 $text .= '<div style="background-color: #f0f0f0; border: 1px solid #3c78b5; padding: 10px; height: 100%; text-align: center; margin: 5px;">';
453 if (isset ($_REQUEST['do_link']))
454 $text .= getOutputOf ('handlePopupPortLink');
455 else
456 $text .= getOutputOf ('renderPopupPortSelector');
457 $text .= '</div>';
39106006
DO
458 break;
459 case 'inet4list':
4dc8e857
DO
460 $pageno = 'ipv4space';
461 $tabno = 'default';
462 fixContext();
3ec33017 463 assertPermission();
2030a7f2 464 $text .= getOutputOf ('renderPopupIPv4Selector');
39106006
DO
465 break;
466 default:
d6b0c986 467 throw new InvalidRequestArgException ('helper', $_REQUEST['helper']);
39106006 468 }
2030a7f2
AA
469 echo '<head><title>RackTables pop-up</title>';
470 printPageHeaders();
471 echo '</head>';
472 echo '<body style="height: 100%;">' . $text . '</body>';
e673ee24 473?>
e673ee24 474</html>
0cc24e9a 475<?php
0cc24e9a
DY
476}
477?>