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