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