Commit | Line | Data |
---|---|---|
b325120a | 1 | <?php |
e673ee24 DO |
2 | /* |
3 | * | |
4 | * This file is a library of computational functions for RackTables. | |
5 | * | |
6 | */ | |
7 | ||
8 | $loclist[0] = 'front'; | |
9 | $loclist[1] = 'interior'; | |
10 | $loclist[2] = 'rear'; | |
11 | $loclist['front'] = 0; | |
12 | $loclist['interior'] = 1; | |
13 | $loclist['rear'] = 2; | |
14 | $template[0] = array (TRUE, TRUE, TRUE); | |
15 | $template[1] = array (TRUE, TRUE, FALSE); | |
16 | $template[2] = array (FALSE, TRUE, TRUE); | |
17 | $template[3] = array (TRUE, FALSE, FALSE); | |
18 | $template[4] = array (FALSE, TRUE, FALSE); | |
19 | $template[5] = array (FALSE, FALSE, TRUE); | |
20 | $templateWidth[0] = 3; | |
21 | $templateWidth[1] = 2; | |
22 | $templateWidth[2] = 2; | |
23 | $templateWidth[3] = 1; | |
24 | $templateWidth[4] = 1; | |
25 | $templateWidth[5] = 1; | |
26 | ||
27 | // Objects of some types should be explicitly shown as | |
28 | // anonymous (labelless). This function is a single place where the | |
29 | // decision about displayed name is made. | |
30 | function displayedName ($objectData) | |
31 | { | |
32 | if ($objectData['name'] != '') | |
33 | return $objectData['name']; | |
9c0b0016 | 34 | elseif (in_array ($objectData['objtype_id'], explode (',', getConfigVar ('NAMEFUL_OBJTYPES')))) |
a0ec6295 | 35 | return "ANONYMOUS " . $objectData['objtype_name']; |
e673ee24 | 36 | else |
a0ec6295 | 37 | return "[${objectData['objtype_name']}]"; |
e673ee24 DO |
38 | } |
39 | ||
40 | // This function finds height of solid rectangle of atoms, which are all | |
41 | // assigned to the same object. Rectangle base is defined by specified | |
42 | // template. | |
43 | function rectHeight ($rackData, $startRow, $template_idx) | |
44 | { | |
45 | $height = 0; | |
46 | // The first met object_id is used to match all the folowing IDs. | |
47 | $object_id = 0; | |
48 | global $template; | |
49 | do | |
50 | { | |
51 | for ($locidx = 0; $locidx < 3; $locidx++) | |
52 | { | |
53 | // At least one value in template is TRUE, but the following block | |
54 | // can meet 'skipped' atoms. Let's ensure we have something after processing | |
55 | // the first row. | |
56 | if ($template[$template_idx][$locidx]) | |
57 | { | |
58 | if (isset ($rackData[$startRow - $height][$locidx]['skipped'])) | |
59 | break 2; | |
93e02204 DO |
60 | if (isset ($rackData[$startRow - $height][$locidx]['rowspan'])) |
61 | break 2; | |
62 | if (isset ($rackData[$startRow - $height][$locidx]['colspan'])) | |
63 | break 2; | |
e673ee24 DO |
64 | if ($rackData[$startRow - $height][$locidx]['state'] != 'T') |
65 | break 2; | |
66 | if ($object_id == 0) | |
67 | $object_id = $rackData[$startRow - $height][$locidx]['object_id']; | |
68 | if ($object_id != $rackData[$startRow - $height][$locidx]['object_id']) | |
69 | break 2; | |
70 | } | |
71 | } | |
72 | // If the first row can't offer anything, bail out. | |
73 | if ($height == 0 and $object_id == 0) | |
74 | break; | |
75 | $height++; | |
76 | } | |
77 | while ($startRow - $height > 0); | |
93e02204 DO |
78 | # echo "for startRow==${startRow} and template==(" . ($template[$template_idx][0] ? 'T' : 'F'); |
79 | # echo ', ' . ($template[$template_idx][1] ? 'T' : 'F') . ', ' . ($template[$template_idx][2] ? 'T' : 'F'); | |
80 | # echo ") height==${height}<br>\n"; | |
e673ee24 DO |
81 | return $height; |
82 | } | |
83 | ||
84 | // This function marks atoms to be avoided by rectHeight() and assigns rowspan/colspan | |
85 | // attributes. | |
86 | function markSpan (&$rackData, $startRow, $maxheight, $template_idx) | |
87 | { | |
88 | global $template, $templateWidth; | |
89 | $colspan = 0; | |
90 | for ($height = 0; $height < $maxheight; $height++) | |
91 | { | |
92 | for ($locidx = 0; $locidx < 3; $locidx++) | |
93 | { | |
94 | if ($template[$template_idx][$locidx]) | |
95 | { | |
96 | // Add colspan/rowspan to the first row met and mark the following ones to skip. | |
93e02204 DO |
97 | // Explicitly show even single-cell spanned atoms, because rectHeight() |
98 | // is expeciting this data for correct calculation. | |
e673ee24 DO |
99 | if ($colspan != 0) |
100 | $rackData[$startRow - $height][$locidx]['skipped'] = TRUE; | |
101 | else | |
102 | { | |
103 | $colspan = $templateWidth[$template_idx]; | |
93e02204 | 104 | if ($colspan >= 1) |
e673ee24 | 105 | $rackData[$startRow - $height][$locidx]['colspan'] = $colspan; |
93e02204 | 106 | if ($maxheight >= 1) |
e673ee24 DO |
107 | $rackData[$startRow - $height][$locidx]['rowspan'] = $maxheight; |
108 | } | |
109 | } | |
110 | } | |
111 | } | |
112 | return; | |
113 | } | |
114 | ||
93e02204 DO |
115 | // This function sets rowspan/solspan/skipped atom attributes for renderRack() |
116 | // What we actually have to do is to find _all_ possible rectangles for each unit | |
117 | // and then select the widest of those with the maximal square. | |
e673ee24 DO |
118 | function markAllSpans (&$rackData = NULL) |
119 | { | |
120 | if ($rackData == NULL) | |
121 | { | |
61e269b5 | 122 | showError ('Invalid rackData', __FUNCTION__); |
e673ee24 DO |
123 | return; |
124 | } | |
125 | for ($i = $rackData['height']; $i > 0; $i--) | |
93e02204 DO |
126 | while (markBestSpan ($rackData, $i)); |
127 | } | |
128 | ||
129 | // Calculate height of 6 possible span templates (array is presorted by width | |
130 | // descending) and mark the best (if any). | |
131 | function markBestSpan (&$rackData, $i) | |
132 | { | |
133 | global $template, $templateWidth; | |
134 | for ($j = 0; $j < 6; $j++) | |
e673ee24 | 135 | { |
93e02204 DO |
136 | $height[$j] = rectHeight ($rackData, $i, $j); |
137 | $square[$j] = $height[$j] * $templateWidth[$j]; | |
138 | } | |
139 | // find the widest rectangle of those with maximal height | |
140 | $maxsquare = max ($square); | |
141 | if (!$maxsquare) | |
142 | return FALSE; | |
143 | $best_template_index = 0; | |
144 | for ($j = 0; $j < 6; $j++) | |
145 | if ($square[$j] == $maxsquare) | |
e673ee24 | 146 | { |
93e02204 DO |
147 | $best_template_index = $j; |
148 | $bestheight = $height[$j]; | |
149 | break; | |
e673ee24 | 150 | } |
93e02204 DO |
151 | // distribute span marks |
152 | markSpan ($rackData, $i, $bestheight, $best_template_index); | |
153 | return TRUE; | |
e673ee24 DO |
154 | } |
155 | ||
156 | function delRow ($row_id = 0) | |
157 | { | |
158 | if ($row_id == 0) | |
159 | { | |
61e269b5 | 160 | showError ('Not all required args are present.', __FUNCTION__); |
e673ee24 DO |
161 | return; |
162 | } | |
163 | if (!isset ($_REQUEST['confirmed']) || $_REQUEST['confirmed'] != 'true') | |
164 | { | |
165 | echo "Press <a href='?op=del_row&row_id=${row_id}&confirmed=true'>here</a> to confirm rack row deletion."; | |
166 | return; | |
167 | } | |
168 | global $dbxlink; | |
169 | echo 'Deleting rack row information: '; | |
170 | $result = $dbxlink->query ("update RackRow set deleted = 'yes' where id=${row_id} limit 1"); | |
171 | if ($result->rowCount() != 1) | |
172 | { | |
61e269b5 | 173 | showError ('Marked ' . $result.rowCount() . ' rows as deleted, but expected 1', __FUNCTION__); |
e673ee24 DO |
174 | return; |
175 | } | |
176 | echo 'OK<br>'; | |
177 | recordHistory ('RackRow', "id = ${row_id}"); | |
178 | echo "Information was deleted. You may return to <a href='?op=list_rows&editmode=on'>rack row list</a>."; | |
179 | } | |
180 | ||
181 | function delRack ($rack_id = 0) | |
182 | { | |
183 | if ($rack_id == 0) | |
184 | { | |
61e269b5 | 185 | showError ('Not all required args are present.', __FUNCTION__); |
e673ee24 DO |
186 | return; |
187 | } | |
188 | if (!isset ($_REQUEST['confirmed']) || $_REQUEST['confirmed'] != 'true') | |
189 | { | |
190 | echo "Press <a href='?op=del_rack&rack_id=${rack_id}&confirmed=true'>here</a> to confirm rack deletion."; | |
191 | return; | |
192 | } | |
193 | global $dbxlink; | |
194 | echo 'Deleting rack information: '; | |
195 | $result = $dbxlink->query ("update Rack set deleted = 'yes' where id=${rack_id} limit 1"); | |
196 | if ($result->rowCount() != 1) | |
197 | { | |
61e269b5 | 198 | showError ('Marked ' . $result.rowCount() . ' rows as deleted, but expected 1', __FUNCTION__); |
e673ee24 DO |
199 | return; |
200 | } | |
201 | echo 'OK<br>'; | |
202 | recordHistory ('Rack', "id = ${rack_id}"); | |
203 | echo "Information was deleted. You may return to <a href='?op=list_racks&editmode=on'>rack list</a>."; | |
204 | } | |
205 | ||
206 | function delObject ($object_id = 0) | |
207 | { | |
208 | if ($object_id == 0) | |
209 | { | |
61e269b5 | 210 | showError ('Not all required args are present.', __FUNCTION__); |
e673ee24 DO |
211 | return; |
212 | } | |
213 | if (!isset ($_REQUEST['confirmed']) || $_REQUEST['confirmed'] != 'true') | |
214 | { | |
215 | echo "Press <a href='?op=del_object&object_id=${object_id}&confirmed=true'>here</a> to confirm object deletion."; | |
216 | return; | |
217 | } | |
218 | global $dbxlink; | |
219 | echo 'Deleting object information: '; | |
220 | $result = $dbxlink->query ("update RackObject set deleted = 'yes' where id=${object_id} limit 1"); | |
221 | if ($result->rowCount() != 1) | |
222 | { | |
61e269b5 | 223 | showError ('Marked ' . $result.rowCount() . ' rows as deleted, but expected 1', __FUNCTION__); |
e673ee24 DO |
224 | return; |
225 | } | |
226 | echo 'OK<br>'; | |
227 | recordHistory ('RackObject', "id = ${object_id}"); | |
228 | echo "Information was deleted. You may return to <a href='?op=list_objects&editmode=on'>object list</a>."; | |
229 | } | |
230 | ||
231 | // We can mount 'F' atoms and unmount our own 'T' atoms. | |
232 | function applyObjectMountMask (&$rackData, $object_id) | |
233 | { | |
234 | for ($unit_no = $rackData['height']; $unit_no > 0; $unit_no--) | |
235 | for ($locidx = 0; $locidx < 3; $locidx++) | |
236 | switch ($rackData[$unit_no][$locidx]['state']) | |
237 | { | |
238 | case 'F': | |
239 | $rackData[$unit_no][$locidx]['enabled'] = TRUE; | |
240 | break; | |
241 | case 'T': | |
242 | $rackData[$unit_no][$locidx]['enabled'] = ($rackData[$unit_no][$locidx]['object_id'] == $object_id); | |
243 | break; | |
244 | default: | |
245 | $rackData[$unit_no][$locidx]['enabled'] = FALSE; | |
246 | } | |
247 | } | |
248 | ||
249 | // Design change means transition between 'F' and 'A' and back. | |
250 | function applyRackDesignMask (&$rackData) | |
251 | { | |
252 | for ($unit_no = $rackData['height']; $unit_no > 0; $unit_no--) | |
253 | for ($locidx = 0; $locidx < 3; $locidx++) | |
254 | switch ($rackData[$unit_no][$locidx]['state']) | |
255 | { | |
256 | case 'F': | |
257 | case 'A': | |
258 | $rackData[$unit_no][$locidx]['enabled'] = TRUE; | |
259 | break; | |
260 | default: | |
261 | $rackData[$unit_no][$locidx]['enabled'] = FALSE; | |
262 | } | |
263 | } | |
264 | ||
265 | // The same for 'F' and 'U'. | |
266 | function applyRackProblemMask (&$rackData) | |
267 | { | |
268 | for ($unit_no = $rackData['height']; $unit_no > 0; $unit_no--) | |
269 | for ($locidx = 0; $locidx < 3; $locidx++) | |
270 | switch ($rackData[$unit_no][$locidx]['state']) | |
271 | { | |
272 | case 'F': | |
273 | case 'U': | |
274 | $rackData[$unit_no][$locidx]['enabled'] = TRUE; | |
275 | break; | |
276 | default: | |
277 | $rackData[$unit_no][$locidx]['enabled'] = FALSE; | |
278 | } | |
279 | } | |
280 | ||
281 | // This mask should allow toggling 'T' and 'W' on object's rackspace. | |
282 | function applyObjectProblemMask (&$rackData) | |
283 | { | |
284 | for ($unit_no = $rackData['height']; $unit_no > 0; $unit_no--) | |
285 | for ($locidx = 0; $locidx < 3; $locidx++) | |
286 | switch ($rackData[$unit_no][$locidx]['state']) | |
287 | { | |
288 | case 'T': | |
289 | case 'W': | |
290 | $rackData[$unit_no][$locidx]['enabled'] = ($rackData[$unit_no][$locidx]['object_id'] == $object_id); | |
291 | break; | |
292 | default: | |
293 | $rackData[$unit_no][$locidx]['enabled'] = FALSE; | |
294 | } | |
295 | } | |
296 | ||
297 | // This function highlights specified object (and removes previous highlight). | |
298 | function highlightObject (&$rackData, $object_id) | |
299 | { | |
300 | for ($unit_no = $rackData['height']; $unit_no > 0; $unit_no--) | |
301 | for ($locidx = 0; $locidx < 3; $locidx++) | |
302 | if | |
303 | ( | |
304 | $rackData[$unit_no][$locidx]['state'] == 'T' and | |
305 | $rackData[$unit_no][$locidx]['object_id'] == $object_id | |
306 | ) | |
307 | $rackData[$unit_no][$locidx]['hl'] = 'h'; | |
308 | else | |
309 | unset ($rackData[$unit_no][$locidx]['hl']); | |
310 | } | |
311 | ||
312 | // This function marks atoms to selected or not depending on their current state. | |
313 | function markupAtomGrid (&$data, $checked_state) | |
314 | { | |
315 | for ($unit_no = $data['height']; $unit_no > 0; $unit_no--) | |
316 | for ($locidx = 0; $locidx < 3; $locidx++) | |
317 | { | |
318 | if (!($data[$unit_no][$locidx]['enabled'] === TRUE)) | |
319 | continue; | |
320 | if ($data[$unit_no][$locidx]['state'] == $checked_state) | |
321 | $data[$unit_no][$locidx]['checked'] = ' checked'; | |
322 | else | |
323 | $data[$unit_no][$locidx]['checked'] = ''; | |
324 | } | |
325 | } | |
326 | ||
327 | // This function is almost a clone of processGridForm(), but doesn't save anything to database | |
328 | // Return value is the changed rack data. | |
329 | // Here we assume that correct filter has already been applied, so we just | |
330 | // set or unset checkbox inputs w/o changing atom state. | |
331 | function mergeGridFormToRack (&$rackData) | |
332 | { | |
333 | $rack_id = $rackData['id']; | |
334 | for ($unit_no = $rackData['height']; $unit_no > 0; $unit_no--) | |
335 | for ($locidx = 0; $locidx < 3; $locidx++) | |
336 | { | |
337 | if ($rackData[$unit_no][$locidx]['enabled'] != TRUE) | |
338 | continue; | |
339 | $inputname = "atom_${rack_id}_${unit_no}_${locidx}"; | |
340 | if (isset ($_REQUEST[$inputname]) and $_REQUEST[$inputname] == 'on') | |
341 | $rackData[$unit_no][$locidx]['checked'] = ' checked'; | |
342 | else | |
343 | $rackData[$unit_no][$locidx]['checked'] = ''; | |
344 | } | |
345 | } | |
346 | ||
347 | function binMaskFromDec ($maskL) | |
348 | { | |
349 | $binmask=0; | |
350 | for ($i=0; $i<$maskL; $i++) | |
351 | { | |
352 | $binmask*=2; | |
353 | $binmask+=1; | |
354 | } | |
355 | for ($i=$maskL; $i<32; $i++) | |
356 | { | |
357 | $binmask*=2; | |
358 | } | |
359 | return $binmask; | |
360 | } | |
361 | ||
362 | function binInvMaskFromDec ($maskL) | |
363 | { | |
364 | $binmask=0; | |
365 | for ($i=0; $i<$maskL; $i++) | |
366 | { | |
367 | $binmask*=2; | |
368 | } | |
369 | for ($i=$maskL; $i<32; $i++) | |
370 | { | |
371 | $binmask*=2; | |
372 | $binmask+=1; | |
373 | } | |
374 | return $binmask; | |
375 | } | |
376 | ||
fa05e3de | 377 | function addRange ($range='', $name='', $is_bcast = FALSE, $taglist = array()) |
e673ee24 | 378 | { |
2a201216 DY |
379 | // $range is in x.x.x.x/x format, split into ip/mask vars |
380 | $rangeArray = explode('/', $range); | |
6e8868cc DO |
381 | if (count ($rangeArray) != 2) |
382 | return "Invalid IP subnet '${range}'"; | |
2a201216 DY |
383 | $ip = $rangeArray[0]; |
384 | $mask = $rangeArray[1]; | |
385 | ||
c87fd3fe DO |
386 | if (empty ($ip) or empty ($mask)) |
387 | return "Invalid IP subnet '${range}'"; | |
e673ee24 DO |
388 | $ipL = ip2long($ip); |
389 | $maskL = ip2long($mask); | |
390 | if ($ipL == -1 || $ipL === FALSE) | |
391 | return 'Bad ip address'; | |
392 | if ($mask < 32 && $mask > 0) | |
393 | $maskL = $mask; | |
394 | else | |
395 | { | |
396 | $maskB = decbin($maskL); | |
397 | if (strlen($maskB)!=32) | |
398 | return 'Bad mask'; | |
399 | $ones=0; | |
400 | $zeroes=FALSE; | |
401 | foreach( str_split ($maskB) as $digit) | |
402 | { | |
403 | if ($digit == '0') | |
404 | $zeroes = TRUE; | |
405 | if ($digit == '1') | |
406 | { | |
407 | $ones++; | |
408 | if ($zeroes == TRUE) | |
409 | return 'Bad mask'; | |
410 | } | |
411 | } | |
412 | $maskL = $ones; | |
413 | } | |
414 | $binmask = binMaskFromDec($maskL); | |
415 | $ipL = $ipL & $binmask; | |
416 | ||
417 | $query = | |
418 | "select ". | |
419 | "id, ip, mask, name ". | |
420 | "from IPRanges "; | |
421 | ||
422 | ||
fa05e3de | 423 | $result = useSelectBlade ($query); |
e673ee24 DO |
424 | |
425 | while ($row = $result->fetch (PDO::FETCH_ASSOC)) | |
426 | { | |
427 | $otherip = $row['ip']; | |
428 | $othermask = binMaskFromDec($row['mask']); | |
429 | // echo "checking $otherip & $othermask ".($otherip & $othermask)." == $ipL & $othermask ".($ipL & $othermask)." ".decbin($otherip)." ".decbin($othermask)." ".decbin($otherip & $othermask)." ".decbin($ipL)." ".decbin($othermask)." ".decbin($ipL & $othermask)."\n"; | |
430 | // echo "checking $otherip & $binmask ".($otherip & $binmask)." == $ipL & $binmask ".($ipL & $binmask)." ".decbin($otherip)." ".decbin($binmask)." ".decbin($otherip & $binmask)." ".decbin($ipL)." ".decbin($binmask)." ".decbin($ipL & $binmask)."\n"; | |
431 | // echo "\n"; | |
432 | // flush(); | |
433 | if (($otherip & $othermask) == ($ipL & $othermask)) | |
434 | return "This subnet intersects with ".long2ip($row['ip'])."/${row['mask']}"; | |
435 | if (($otherip & $binmask) == ($ipL & $binmask)) | |
436 | return "This subnet intersects with ".long2ip($row['ip'])."/${row['mask']}"; | |
437 | } | |
438 | $result->closeCursor(); | |
fa05e3de DO |
439 | unset ($result); |
440 | $result = useInsertBlade | |
441 | ( | |
442 | 'IPRanges', | |
443 | array | |
444 | ( | |
445 | 'ip' => sprintf ('%u', $ipL), | |
446 | 'mask' => "'${maskL}'", | |
447 | 'name' => "'${name}'" | |
448 | ) | |
449 | ); | |
2dee289e DO |
450 | |
451 | if ($is_bcast and $maskL < 31) | |
452 | { | |
453 | $network_addr = long2ip ($ipL); | |
454 | $broadcast_addr = long2ip ($ipL | binInvMaskFromDec ($maskL)); | |
455 | updateAddress ($network_addr, 'network', 'yes'); | |
456 | updateAddress ($broadcast_addr, 'broadcast', 'yes'); | |
457 | } | |
fa05e3de DO |
458 | if (!count ($taglist)) |
459 | return ''; | |
460 | if (($result = useSelectBlade ('select last_insert_id()')) == NULL) | |
461 | return 'Query #3 failed in ' . __FUNCTION__; | |
462 | $row = $result->fetch (PDO::FETCH_NUM); | |
463 | $netid = $row[0]; | |
464 | $errcount = 0; | |
465 | foreach ($taglist as $tag_id) | |
466 | if (useInsertBlade | |
467 | ( | |
468 | 'TagStorage', | |
469 | array | |
470 | ( | |
471 | 'target_realm' => "'ipv4net'", | |
472 | 'target_id' => $netid, | |
473 | 'tag_id' => $tag_id | |
474 | ) | |
475 | ) == FALSE) | |
476 | $errcount++; | |
477 | if (!$errcount) | |
478 | return ''; | |
479 | else | |
480 | return "Experienced ${errcount} errors adding tags for the network"; | |
e673ee24 DO |
481 | } |
482 | ||
483 | function getIPRange ($id = 0) | |
484 | { | |
485 | global $dbxlink; | |
486 | $query = | |
487 | "select ". | |
488 | "id as IPRanges_id, ". | |
489 | "INET_NTOA(ip) as IPRanges_ip, ". | |
e673ee24 DO |
490 | "mask as IPRanges_mask, ". |
491 | "name as IPRanges_name ". | |
492 | "from IPRanges ". | |
493 | "where id = '$id'"; | |
602663f4 | 494 | $result = useSelectBlade ($query); |
5c43a978 | 495 | $ret = array(); |
55cc3e4e DO |
496 | $row = $result->fetch (PDO::FETCH_ASSOC); |
497 | if ($row == NULL) | |
498 | return $ret; | |
499 | $ret['id'] = $row['IPRanges_id']; | |
500 | $ret['ip'] = $row['IPRanges_ip']; | |
7e039e88 | 501 | $ret['ip_bin'] = ip2long ($row['IPRanges_ip']); |
55cc3e4e DO |
502 | $ret['mask_bin'] = binMaskFromDec($row['IPRanges_mask']); |
503 | $ret['mask_bin_inv'] = binInvMaskFromDec($row['IPRanges_mask']); | |
504 | $ret['name'] = $row['IPRanges_name']; | |
505 | $ret['mask'] = $row['IPRanges_mask']; | |
506 | $ret['addrlist'] = array(); | |
55cc3e4e | 507 | $result->closeCursor(); |
602663f4 | 508 | unset ($result); |
7e039e88 DO |
509 | // We risk losing some significant bits in an unsigned 32bit integer, |
510 | // unless it is converted to a string. | |
511 | $db_first = "'" . sprintf ('%u', 0x00000000 + $ret['ip_bin'] & $ret['mask_bin']) . "'"; | |
512 | $db_last = "'" . sprintf ('%u', 0x00000000 + $ret['ip_bin'] | ($ret['mask_bin_inv'])) . "'"; | |
5c43a978 DO |
513 | |
514 | // Don't try to build up the whole structure in a single pass. Request | |
515 | // the list of user comments and reservations and merge allocations in | |
516 | // at a latter point. | |
55cc3e4e | 517 | $query = |
7e039e88 DO |
518 | "select INET_NTOA(ip) as ip, name, reserved from IPAddress " . |
519 | "where ip between ${db_first} and ${db_last} " . | |
5c43a978 | 520 | "and (reserved = 'yes' or name != '')"; |
602663f4 DO |
521 | $result = $dbxlink->query ($query); |
522 | while ($row = $result->fetch (PDO::FETCH_ASSOC)) | |
55cc3e4e | 523 | { |
7e039e88 DO |
524 | $ip_bin = ip2long ($row['ip']); |
525 | $ret['addrlist'][$ip_bin] = $row; | |
5c43a978 DO |
526 | $tmp = array(); |
527 | foreach (array ('ip', 'name', 'reserved') as $cname) | |
528 | $tmp[$cname] = $row[$cname]; | |
529 | $tmp['references'] = array(); | |
602663f4 DO |
530 | $tmp['lbrefs'] = array(); |
531 | $tmp['rsrefs'] = array(); | |
7e039e88 | 532 | $ret['addrlist'][$ip_bin] = $tmp; |
5c43a978 | 533 | } |
602663f4 DO |
534 | $result->closeCursor(); |
535 | unset ($result); | |
e673ee24 | 536 | |
5c43a978 | 537 | $query = |
dda31a62 DO |
538 | "select INET_NTOA(ipb.ip) as ip, ro.id as object_id, " . |
539 | "ro.name as object_name, ipb.name, ipb.type, objtype_id, " . | |
540 | "dict_value as objtype_name from " . | |
5c43a978 | 541 | "IPBonds as ipb inner join RackObject as ro on ipb.object_id = ro.id " . |
dda31a62 | 542 | "left join Dictionary on objtype_id=dict_key natural join Chapter " . |
7e039e88 | 543 | "where ip between ${db_first} and ${db_last} " . |
dda31a62 | 544 | "and chapter_name = 'RackObjectType'" . |
5c43a978 | 545 | "order by ipb.type, object_name"; |
602663f4 DO |
546 | $result = useSelectBlade ($query); |
547 | while ($row = $result->fetch (PDO::FETCH_ASSOC)) | |
5c43a978 | 548 | { |
7e039e88 DO |
549 | $ip_bin = ip2long ($row['ip']); |
550 | if (!isset ($ret['addrlist'][$ip_bin])) | |
55cc3e4e | 551 | { |
7e039e88 DO |
552 | $ret['addrlist'][$ip_bin] = array(); |
553 | $ret['addrlist'][$ip_bin]['ip'] = $row['ip']; | |
554 | $ret['addrlist'][$ip_bin]['name'] = ''; | |
555 | $ret['addrlist'][$ip_bin]['reserved'] = 'no'; | |
556 | $ret['addrlist'][$ip_bin]['references'] = array(); | |
602663f4 DO |
557 | $ret['addrlist'][$ip_bin]['lbrefs'] = array(); |
558 | $ret['addrlist'][$ip_bin]['rsrefs'] = array(); | |
e673ee24 | 559 | } |
5c43a978 | 560 | $tmp = array(); |
dda31a62 | 561 | foreach (array ('object_id', 'type', 'name') as $cname) |
5c43a978 | 562 | $tmp[$cname] = $row[$cname]; |
dda31a62 DO |
563 | $quasiobject['name'] = $row['object_name']; |
564 | $quasiobject['objtype_id'] = $row['objtype_id']; | |
565 | $quasiobject['objtype_name'] = $row['objtype_name']; | |
566 | $tmp['object_name'] = displayedName ($quasiobject); | |
7e039e88 | 567 | $ret['addrlist'][$ip_bin]['references'][] = $tmp; |
e673ee24 | 568 | } |
602663f4 DO |
569 | $result->closeCursor(); |
570 | unset ($result); | |
571 | ||
572 | $query = "select vs_id, inet_ntoa(vip) as ip, vport, proto, " . | |
573 | "object_id, objtype_id, ro.name, dict_value as objtype_name from " . | |
574 | "IPVirtualService as vs inner join IPLoadBalancer as lb on vs.id = lb.vs_id " . | |
575 | "inner join RackObject as ro on lb.object_id = ro.id " . | |
576 | "left join Dictionary on objtype_id=dict_key " . | |
577 | "natural join Chapter " . | |
578 | "where vip between ${db_first} and ${db_last} " . | |
579 | "and chapter_name = 'RackObjectType'" . | |
580 | "order by vport, proto, ro.name, object_id"; | |
581 | $result = useSelectBlade ($query); | |
582 | while ($row = $result->fetch (PDO::FETCH_ASSOC)) | |
583 | { | |
584 | $ip_bin = ip2long ($row['ip']); | |
585 | if (!isset ($ret['addrlist'][$ip_bin])) | |
586 | { | |
587 | $ret['addrlist'][$ip_bin] = array(); | |
588 | $ret['addrlist'][$ip_bin]['ip'] = $row['ip']; | |
589 | $ret['addrlist'][$ip_bin]['name'] = ''; | |
590 | $ret['addrlist'][$ip_bin]['reserved'] = 'no'; | |
591 | $ret['addrlist'][$ip_bin]['references'] = array(); | |
592 | $ret['addrlist'][$ip_bin]['lbrefs'] = array(); | |
593 | $ret['addrlist'][$ip_bin]['rsrefs'] = array(); | |
594 | } | |
595 | $tmp = $qbject = array(); | |
596 | foreach (array ('object_id', 'vport', 'proto', 'vs_id') as $cname) | |
597 | $tmp[$cname] = $row[$cname]; | |
598 | foreach (array ('name', 'objtype_id', 'objtype_name') as $cname) | |
599 | $qobject[$cname] = $row[$cname]; | |
600 | $tmp['object_name'] = displayedName ($qobject); | |
601 | $ret['addrlist'][$ip_bin]['lbrefs'][] = $tmp; | |
602 | } | |
603 | $result->closeCursor(); | |
604 | unset ($result); | |
605 | ||
606 | $query = "select inet_ntoa(rsip) as ip, rsport, rspool_id, rsp.name as rspool_name from " . | |
607 | "IPRealServer as rs inner join IPRSPool as rsp on rs.rspool_id = rsp.id " . | |
608 | "where rsip between ${db_first} and ${db_last} " . | |
609 | "order by ip, rsport, rspool_id"; | |
610 | $result = useSelectBlade ($query); | |
611 | while ($row = $result->fetch (PDO::FETCH_ASSOC)) | |
612 | { | |
613 | $ip_bin = ip2long ($row['ip']); | |
614 | if (!isset ($ret['addrlist'][$ip_bin])) | |
615 | { | |
616 | $ret['addrlist'][$ip_bin] = array(); | |
617 | $ret['addrlist'][$ip_bin]['ip'] = $row['ip']; | |
618 | $ret['addrlist'][$ip_bin]['name'] = ''; | |
619 | $ret['addrlist'][$ip_bin]['reserved'] = 'no'; | |
620 | $ret['addrlist'][$ip_bin]['references'] = array(); | |
621 | $ret['addrlist'][$ip_bin]['lbrefs'] = array(); | |
622 | $ret['addrlist'][$ip_bin]['rsrefs'] = array(); | |
623 | } | |
624 | $tmp = array(); | |
625 | foreach (array ('rspool_id', 'rsport', 'rspool_name') as $cname) | |
626 | $tmp[$cname] = $row[$cname]; | |
627 | $ret['addrlist'][$ip_bin]['rsrefs'][] = $tmp; | |
628 | } | |
5c43a978 | 629 | |
e673ee24 DO |
630 | return $ret; |
631 | } | |
632 | ||
dda31a62 DO |
633 | // Don't require any records in IPAddress, but if there is one, |
634 | // merge the data between getting allocation list. Collect enough data | |
635 | // to call displayedName() ourselves. | |
e673ee24 DO |
636 | function getIPAddress ($ip=0) |
637 | { | |
638 | $ret = array(); | |
e673ee24 | 639 | $ret['bonds'] = array(); |
59bebe2b | 640 | // FIXME: below two aren't neither filled in with data nor rendered (ticket:23) |
e673ee24 DO |
641 | $ret['outpf'] = array(); |
642 | $ret['inpf'] = array(); | |
59bebe2b DO |
643 | $ret['vslist'] = array(); |
644 | $ret['rslist'] = array(); | |
e673ee24 | 645 | $ret['exists'] = 0; |
dda31a62 | 646 | $ret['name'] = ''; |
e673ee24 DO |
647 | $ret['reserved'] = 'no'; |
648 | global $dbxlink; | |
59bebe2b | 649 | $query = |
e673ee24 | 650 | "select ". |
dda31a62 | 651 | "name, reserved ". |
e673ee24 | 652 | "from IPAddress ". |
dda31a62 | 653 | "where ip = INET_ATON('$ip') and (reserved = 'yes' or name != '')"; |
59bebe2b DO |
654 | $result = $dbxlink->query ($query); |
655 | if ($result == NULL) | |
656 | { | |
657 | showError ('Query #1 failed', __FUNCTION__); | |
e673ee24 | 658 | return NULL; |
59bebe2b DO |
659 | } |
660 | if ($row = $result->fetch (PDO::FETCH_ASSOC)) | |
e673ee24 | 661 | { |
959c4f4c | 662 | $ret['exists'] = 1; |
959c4f4c DO |
663 | $ret['name'] = $row['name']; |
664 | $ret['reserved'] = $row['reserved']; | |
e673ee24 | 665 | } |
59bebe2b DO |
666 | $result->closeCursor(); |
667 | unset ($result); | |
e673ee24 | 668 | |
59bebe2b | 669 | $query = |
dda31a62 DO |
670 | "select ". |
671 | "IPBonds.object_id as object_id, ". | |
672 | "IPBonds.name as name, ". | |
673 | "IPBonds.type as type, ". | |
674 | "objtype_id, dict_value as objtype_name, " . | |
675 | "RackObject.name as object_name ". | |
676 | "from IPBonds join RackObject on IPBonds.object_id=RackObject.id ". | |
677 | "left join Dictionary on objtype_id=dict_key natural join Chapter " . | |
678 | "where IPBonds.ip=INET_ATON('$ip') ". | |
679 | "and chapter_name = 'RackObjectType' " . | |
680 | "order by RackObject.id, IPBonds.name"; | |
59bebe2b | 681 | $result = $dbxlink->query ($query); |
dda31a62 | 682 | $count=0; |
59bebe2b | 683 | while ($row = $result->fetch (PDO::FETCH_ASSOC)) |
e673ee24 | 684 | { |
dda31a62 DO |
685 | $ret['bonds'][$count]['object_id'] = $row['object_id']; |
686 | $ret['bonds'][$count]['name'] = $row['name']; | |
687 | $ret['bonds'][$count]['type'] = $row['type']; | |
688 | $qo = array(); | |
689 | $qo['name'] = $row['object_name']; | |
690 | $qo['objtype_id'] = $row['objtype_id']; | |
691 | $qo['objtype_name'] = $row['objtype_name']; | |
692 | $ret['bonds'][$count]['object_name'] = displayedName ($qo); | |
693 | $count++; | |
694 | $ret['exists'] = 1; | |
e673ee24 | 695 | } |
59bebe2b DO |
696 | $result->closeCursor(); |
697 | unset ($result); | |
698 | ||
5fe1ed76 | 699 | $query = "select id, vport, proto, name from IPVirtualService where vip = inet_aton('${ip}')"; |
59bebe2b DO |
700 | $result = $dbxlink->query ($query); |
701 | while ($row = $result->fetch (PDO::FETCH_ASSOC)) | |
5fe1ed76 DO |
702 | { |
703 | $new = $row; | |
704 | $new['vip'] = $ip; | |
705 | $ret['vslist'][] = $new; | |
706 | } | |
707 | $result->closeCursor(); | |
708 | unset ($result); | |
709 | ||
710 | $query = "select inservice, rsport, IPRSPool.id as pool_id, IPRSPool.name as poolname from " . | |
711 | "IPRealServer inner join IPRSPool on rspool_id = IPRSPool.id " . | |
712 | "where rsip = inet_aton('${ip}')"; | |
713 | $result = $dbxlink->query ($query); | |
714 | while ($row = $result->fetch (PDO::FETCH_ASSOC)) | |
715 | { | |
716 | $new = $row; | |
717 | $new['rsip'] = $ip; | |
718 | $ret['rslist'][] = $new; | |
719 | } | |
59bebe2b DO |
720 | $result->closeCursor(); |
721 | unset ($result); | |
e673ee24 DO |
722 | |
723 | return $ret; | |
724 | } | |
725 | ||
726 | function bindIpToObject ($ip='', $object_id=0, $name='', $type='') | |
727 | { | |
728 | global $dbxlink; | |
729 | ||
730 | $range = getRangeByIp($ip); | |
e673ee24 DO |
731 | if (!$range) |
732 | return 'Non-existant ip address. Try adding IP range first'; | |
733 | ||
20a92aa2 DO |
734 | $result = useInsertBlade |
735 | ( | |
736 | 'IPBonds', | |
737 | array | |
738 | ( | |
dda31a62 | 739 | 'ip' => "INET_ATON('$ip')", |
20a92aa2 DO |
740 | 'object_id' => "'${object_id}'", |
741 | 'name' => "'${name}'", | |
742 | 'type' => "'${type}'" | |
743 | ) | |
744 | ); | |
745 | return $result ? '' : 'useInsertBlade() failed in bindIpToObject()'; | |
e673ee24 DO |
746 | } |
747 | ||
748 | // This function looks up 'has_problems' flag for 'T' atoms | |
749 | // and modifies 'hl' key. May be, this should be better done | |
750 | // in getRackData(). We don't honour 'skipped' key, because | |
751 | // the function is also used for thumb creation. | |
752 | function markupObjectProblems (&$rackData) | |
753 | { | |
754 | for ($i = $rackData['height']; $i > 0; $i--) | |
755 | for ($locidx = 0; $locidx < 3; $locidx++) | |
756 | if ($rackData[$i][$locidx]['state'] == 'T') | |
757 | { | |
758 | $object = getObjectInfo ($rackData[$i][$locidx]['object_id']); | |
759 | if ($object['has_problems'] == 'yes') | |
760 | { | |
761 | // Object can be already highlighted. | |
762 | if (isset ($rackData[$i][$locidx]['hl'])) | |
763 | $rackData[$i][$locidx]['hl'] = $rackData[$i][$locidx]['hl'] . 'w'; | |
764 | else | |
765 | $rackData[$i][$locidx]['hl'] = 'w'; | |
766 | } | |
767 | } | |
768 | } | |
769 | ||
770 | function search_cmpObj ($a, $b) | |
771 | { | |
772 | return ($a['score'] > $b['score'] ? -1 : 1); | |
773 | } | |
774 | ||
775 | // This function performs search and then calculates score for each result. | |
776 | // Given previous search results in $objects argument, it adds new results | |
777 | // to the array and updates score for existing results, if it is greater than | |
778 | // existing score. | |
779 | function mergeSearchResults (&$objects, $terms, $fieldname) | |
780 | { | |
781 | global $dbxlink; | |
782 | $query = | |
783 | "select name, label, asset_no, barcode, ro.id, dict_key as objtype_id, " . | |
784 | "dict_value as objtype_name, asset_no from RackObject as ro inner join Dictionary " . | |
785 | "on objtype_id = dict_key natural join Chapter where chapter_name = 'RackObjectType' and "; | |
786 | $count = 0; | |
787 | foreach (explode (' ', $terms) as $term) | |
788 | { | |
789 | if ($count) $query .= ' or '; | |
790 | $query .= "${fieldname} like '%$term%'"; | |
791 | $count++; | |
792 | } | |
ea5fc465 | 793 | $result = useSelectBlade ($query); |
e673ee24 DO |
794 | // FIXME: this dead call was executed 4 times per 1 object search! |
795 | // $typeList = getObjectTypeList(); | |
796 | $clist = array ('id', 'name', 'label', 'asset_no', 'barcode', 'objtype_id', 'objtype_name'); | |
797 | while ($row = $result->fetch(PDO::FETCH_ASSOC)) | |
798 | { | |
799 | foreach ($clist as $cname) | |
800 | $object[$cname] = $row[$cname]; | |
801 | $object['score'] = 0; | |
802 | $object['dname'] = displayedName ($object); | |
803 | unset ($object['objtype_id']); | |
804 | foreach (explode (' ', $terms) as $term) | |
805 | if (strstr ($object['name'], $term)) | |
806 | $object['score'] += 1; | |
807 | unset ($object['name']); | |
808 | if (!isset ($objects[$row['id']])) | |
809 | $objects[$row['id']] = $object; | |
810 | elseif ($objects[$row['id']]['score'] < $object['score']) | |
811 | $objects[$row['id']]['score'] = $object['score']; | |
812 | } | |
813 | return $objects; | |
814 | } | |
815 | ||
ea5fc465 | 816 | function getObjectSearchResults ($terms) |
e673ee24 DO |
817 | { |
818 | $objects = array(); | |
819 | mergeSearchResults ($objects, $terms, 'name'); | |
820 | mergeSearchResults ($objects, $terms, 'label'); | |
821 | mergeSearchResults ($objects, $terms, 'asset_no'); | |
822 | mergeSearchResults ($objects, $terms, 'barcode'); | |
823 | if (count ($objects) == 1) | |
824 | usort ($objects, 'search_cmpObj'); | |
825 | return $objects; | |
826 | } | |
827 | ||
828 | // This function removes all colons and dots from a string. | |
829 | function l2addressForDatabase ($string) | |
830 | { | |
831 | if (empty ($string)) | |
832 | return 'NULL'; | |
833 | $pieces = explode (':', $string); | |
834 | // This workaround is for SunOS ifconfig. | |
835 | foreach ($pieces as &$byte) | |
836 | if (strlen ($byte) == 1) | |
837 | $byte = '0' . $byte; | |
838 | // And this workaround is for PHP. | |
839 | unset ($byte); | |
840 | $string = implode ('', $pieces); | |
841 | $pieces = explode ('.', $string); | |
842 | $string = implode ('', $pieces); | |
843 | $string = strtoupper ($string); | |
844 | return "'$string'"; | |
845 | } | |
846 | ||
847 | function l2addressFromDatabase ($string) | |
848 | { | |
849 | switch (strlen ($string)) | |
850 | { | |
851 | case 12: // Ethernet | |
852 | case 16: // FireWire | |
853 | $ret = implode (':', str_split ($string, 2)); | |
854 | break; | |
855 | default: | |
856 | $ret = $string; | |
857 | break; | |
858 | } | |
859 | return $ret; | |
860 | } | |
861 | ||
862 | // The following 2 functions return previous and next rack IDs for | |
863 | // a given rack ID. The order of racks is the same as in renderRackspace() | |
864 | // or renderRow(). | |
865 | function getPrevIDforRack ($row_id = 0, $rack_id = 0) | |
866 | { | |
867 | if ($row_id <= 0 or $rack_id <= 0) | |
868 | { | |
61e269b5 | 869 | showError ('Invalid arguments passed', __FUNCTION__); |
e673ee24 DO |
870 | return NULL; |
871 | } | |
872 | $rackList = getRacksForRow ($row_id); | |
873 | doubleLink ($rackList); | |
874 | if (isset ($rackList[$rack_id]['prev_key'])) | |
875 | return $rackList[$rack_id]['prev_key']; | |
876 | return NULL; | |
877 | } | |
878 | ||
879 | function getNextIDforRack ($row_id = 0, $rack_id = 0) | |
880 | { | |
881 | if ($row_id <= 0 or $rack_id <= 0) | |
882 | { | |
61e269b5 | 883 | showError ('Invalid arguments passed', __FUNCTION__); |
e673ee24 DO |
884 | return NULL; |
885 | } | |
886 | $rackList = getRacksForRow ($row_id); | |
887 | doubleLink ($rackList); | |
888 | if (isset ($rackList[$rack_id]['next_key'])) | |
889 | return $rackList[$rack_id]['next_key']; | |
890 | return NULL; | |
891 | } | |
892 | ||
893 | // This function finds previous and next array keys for each array key and | |
894 | // modifies its argument accordingly. | |
895 | function doubleLink (&$array) | |
896 | { | |
897 | $prev_key = NULL; | |
898 | foreach (array_keys ($array) as $key) | |
899 | { | |
900 | if ($prev_key) | |
901 | { | |
902 | $array[$key]['prev_key'] = $prev_key; | |
903 | $array[$prev_key]['next_key'] = $key; | |
904 | } | |
905 | $prev_key = $key; | |
906 | } | |
907 | } | |
908 | ||
909 | // After applying usort() to a rack list we will lose original array keys. | |
910 | // This function restores the keys so they are equal to rack IDs. | |
911 | function restoreRackIDs ($racks) | |
912 | { | |
913 | $ret = array(); | |
914 | foreach ($racks as $rack) | |
915 | $ret[$rack['id']] = $rack; | |
916 | return $ret; | |
917 | } | |
918 | ||
919 | function sortTokenize ($a, $b) | |
920 | { | |
921 | $aold=''; | |
922 | while ($a != $aold) | |
923 | { | |
924 | $aold=$a; | |
925 | $a = ereg_replace('[^a-zA-Z0-9]',' ',$a); | |
926 | $a = ereg_replace('([0-9])([a-zA-Z])','\\1 \\2',$a); | |
927 | $a = ereg_replace('([a-zA-Z])([0-9])','\\1 \\2',$a); | |
928 | } | |
929 | ||
930 | $bold=''; | |
931 | while ($b != $bold) | |
932 | { | |
933 | $bold=$b; | |
934 | $b = ereg_replace('[^a-zA-Z0-9]',' ',$b); | |
935 | $b = ereg_replace('([0-9])([a-zA-Z])','\\1 \\2',$b); | |
936 | $b = ereg_replace('([a-zA-Z])([0-9])','\\1 \\2',$b); | |
937 | } | |
938 | ||
939 | ||
940 | ||
941 | $ar = explode(' ', $a); | |
942 | $br = explode(' ', $b); | |
943 | for ($i=0; $i<count($ar) && $i<count($br); $i++) | |
944 | { | |
945 | $ret = 0; | |
946 | if (is_numeric($ar[$i]) and is_numeric($br[$i])) | |
947 | $ret = ($ar[$i]==$br[$i])?0:($ar[$i]<$br[$i]?-1:1); | |
948 | else | |
949 | $ret = strcasecmp($ar[$i], $br[$i]); | |
950 | if ($ret != 0) | |
951 | return $ret; | |
952 | } | |
953 | if ($i<count($ar)) | |
954 | return 1; | |
955 | if ($i<count($br)) | |
956 | return -1; | |
957 | return 0; | |
958 | } | |
959 | ||
960 | function sortByName ($a, $b) | |
961 | { | |
962 | return sortTokenize($a['name'], $b['name']); | |
963 | } | |
964 | ||
6a3a37b2 DO |
965 | function sortRacks ($a, $b) |
966 | { | |
967 | return sortTokenize($a['row_name'] . ': ' . $a['name'], $b['row_name'] . ': ' . $b['name']); | |
968 | } | |
969 | ||
e673ee24 DO |
970 | function eq ($a, $b) |
971 | { | |
972 | return $a==$b; | |
973 | } | |
974 | ||
975 | function neq ($a, $b) | |
976 | { | |
977 | return $a!=$b; | |
978 | } | |
979 | ||
980 | function countRefsOfType ($refs, $type, $eq) | |
981 | { | |
982 | $count=0; | |
983 | foreach ($refs as $ref) | |
984 | { | |
985 | if ($eq($ref['type'], $type)) | |
986 | $count++; | |
987 | } | |
988 | return $count; | |
989 | } | |
990 | ||
991 | function sortEmptyPorts ($a, $b) | |
992 | { | |
993 | $objname_cmp = sortTokenize($a['Object_name'], $b['Object_name']); | |
994 | if ($objname_cmp == 0) | |
995 | { | |
996 | return sortTokenize($a['Port_name'], $b['Port_name']); | |
997 | } | |
998 | return $objname_cmp; | |
999 | } | |
1000 | ||
1001 | function sortObjectAddressesAndNames ($a, $b) | |
1002 | { | |
1003 | $objname_cmp = sortTokenize($a['object_name'], $b['object_name']); | |
1004 | if ($objname_cmp == 0) | |
1005 | { | |
79f22c3d DO |
1006 | $name_a = (isset ($a['port_name'])) ? $a['port_name'] : ''; |
1007 | $name_b = (isset ($b['port_name'])) ? $b['port_name'] : ''; | |
1008 | $objname_cmp = sortTokenize($name_a, $name_b); | |
e673ee24 | 1009 | if ($objname_cmp == 0) |
e673ee24 | 1010 | sortTokenize($a['ip'], $b['ip']); |
e673ee24 DO |
1011 | return $objname_cmp; |
1012 | } | |
1013 | return $objname_cmp; | |
1014 | } | |
1015 | ||
1016 | ||
1017 | ||
1018 | function sortAddresses ($a, $b) | |
1019 | { | |
1020 | $name_cmp = sortTokenize($a['name'], $b['name']); | |
1021 | if ($name_cmp == 0) | |
1022 | { | |
1023 | return sortTokenize($a['ip'], $b['ip']); | |
1024 | } | |
1025 | return $name_cmp; | |
1026 | } | |
1027 | ||
1028 | // This function expands port compat list into a matrix. | |
1029 | function buildPortCompatMatrixFromList ($portTypeList, $portCompatList) | |
1030 | { | |
1031 | $matrix = array(); | |
1032 | // Create type matrix and markup compatible types. | |
1033 | foreach (array_keys ($portTypeList) as $type1) | |
1034 | foreach (array_keys ($portTypeList) as $type2) | |
1035 | $matrix[$type1][$type2] = FALSE; | |
1036 | foreach ($portCompatList as $pair) | |
1037 | $matrix[$pair['type1']][$pair['type2']] = TRUE; | |
1038 | return $matrix; | |
1039 | } | |
1040 | ||
1041 | function newPortForwarding($object_id, $localip, $localport, $remoteip, $remoteport, $proto, $description) | |
1042 | { | |
1043 | global $dbxlink; | |
1044 | ||
1045 | $range = getRangeByIp($localip); | |
1046 | if (!$range) | |
1047 | return "$localip: Non existant ip"; | |
1048 | ||
1049 | $range = getRangeByIp($remoteip); | |
1050 | if (!$range) | |
1051 | return "$remoteip: Non existant ip"; | |
1052 | ||
1053 | if ( ($localport <= 0) or ($localport >= 65536) ) | |
1054 | return "$localport: invaild port"; | |
1055 | ||
1056 | if ( ($remoteport <= 0) or ($remoteport >= 65536) ) | |
1057 | return "$remoteport: invaild port"; | |
1058 | ||
1059 | $query = | |
1060 | "insert into PortForwarding set object_id='$object_id', localip=INET_ATON('$localip'), remoteip=INET_ATON('$remoteip'), localport='$localport', remoteport='$remoteport', proto='$proto', description='$description'"; | |
1061 | $result = $dbxlink->exec ($query); | |
1062 | ||
1063 | return ''; | |
1064 | } | |
1065 | ||
1066 | function deletePortForwarding($object_id, $localip, $localport, $remoteip, $remoteport, $proto) | |
1067 | { | |
1068 | global $dbxlink; | |
1069 | ||
1070 | $query = | |
1071 | "delete from PortForwarding where object_id='$object_id' and localip=INET_ATON('$localip') and remoteip=INET_ATON('$remoteip') and localport='$localport' and remoteport='$remoteport' and proto='$proto'"; | |
1072 | $result = $dbxlink->exec ($query); | |
1073 | return ''; | |
1074 | } | |
1075 | ||
1076 | function updatePortForwarding($object_id, $localip, $localport, $remoteip, $remoteport, $proto, $description) | |
1077 | { | |
1078 | global $dbxlink; | |
1079 | ||
1080 | $query = | |
1081 | "update PortForwarding set description='$description' where object_id='$object_id' and localip=INET_ATON('$localip') and remoteip=INET_ATON('$remoteip') and localport='$localport' and remoteport='$remoteport' and proto='$proto'"; | |
1082 | $result = $dbxlink->exec ($query); | |
1083 | return ''; | |
1084 | } | |
1085 | ||
1086 | function getObjectForwards($object_id) | |
1087 | { | |
1088 | global $dbxlink; | |
1089 | ||
1090 | $ret = array(); | |
1091 | $ret['out'] = array(); | |
1092 | $ret['in'] = array(); | |
1093 | $query = | |
1094 | "select ". | |
1095 | "dict_value as proto, ". | |
1096 | "proto as proto_bin, ". | |
1097 | "INET_NTOA(localip) as localip, ". | |
1098 | "localport, ". | |
1099 | "INET_NTOA(remoteip) as remoteip, ". | |
1100 | "remoteport, ". | |
f28fbe8b DO |
1101 | "ipa1.name as local_addr_name, " . |
1102 | "ipa2.name as remote_addr_name, " . | |
e673ee24 DO |
1103 | "description ". |
1104 | "from PortForwarding inner join Dictionary on proto = dict_key natural join Chapter ". | |
f28fbe8b DO |
1105 | "left join IPAddress as ipa1 on PortForwarding.localip = ipa1.ip " . |
1106 | "left join IPAddress as ipa2 on PortForwarding.remoteip = ipa2.ip " . | |
e673ee24 DO |
1107 | "where object_id='$object_id' and chapter_name = 'Protocols' ". |
1108 | "order by localip, localport, proto, remoteip, remoteport"; | |
1109 | $result2 = $dbxlink->query ($query); | |
1110 | $count=0; | |
1111 | while ($row = $result2->fetch (PDO::FETCH_ASSOC)) | |
1112 | { | |
f28fbe8b DO |
1113 | foreach (array ('proto', 'proto_bin', 'localport', 'localip', 'remoteport', 'remoteip', 'description', 'local_addr_name', 'remote_addr_name') as $cname) |
1114 | $ret['out'][$count][$cname] = $row[$cname]; | |
e673ee24 DO |
1115 | $count++; |
1116 | } | |
1117 | $result2->closeCursor(); | |
1118 | ||
1119 | $query = | |
1120 | "select ". | |
1121 | "dict_value as proto, ". | |
1122 | "proto as proto_bin, ". | |
1123 | "INET_NTOA(localip) as localip, ". | |
1124 | "localport, ". | |
1125 | "INET_NTOA(remoteip) as remoteip, ". | |
1126 | "remoteport, ". | |
1127 | "PortForwarding.object_id as object_id, ". | |
1128 | "RackObject.name as object_name, ". | |
1129 | "description ". | |
f28fbe8b | 1130 | "from ((PortForwarding join IPBonds on remoteip=IPBonds.ip) join RackObject on PortForwarding.object_id=RackObject.id) inner join Dictionary on proto = dict_key natural join Chapter ". |
e673ee24 DO |
1131 | "where IPBonds.object_id='$object_id' and chapter_name = 'Protocols' ". |
1132 | "order by remoteip, remoteport, proto, localip, localport"; | |
1133 | $result3 = $dbxlink->query ($query); | |
1134 | $count=0; | |
1135 | while ($row = $result3->fetch (PDO::FETCH_ASSOC)) | |
1136 | { | |
603ad85f | 1137 | foreach (array ('proto', 'proto_bin', 'localport', 'localip', 'remoteport', 'remoteip', 'object_id', 'object_name', 'description') as $cname) |
f28fbe8b | 1138 | $ret['in'][$count][$cname] = $row[$cname]; |
e673ee24 DO |
1139 | $count++; |
1140 | } | |
1141 | $result3->closeCursor(); | |
1142 | ||
1143 | return $ret; | |
1144 | } | |
1145 | ||
c31cd72c | 1146 | // This function returns an array of single element of object's FQDN attribute, |
f321b50a DO |
1147 | // if FQDN is set. The next choice is object's common name, if it looks like a |
1148 | // hostname. Otherwise an array of all 'regular' IP addresses of the | |
c31cd72c | 1149 | // object is returned (which may appear 0 and more elements long). |
f321b50a | 1150 | function findAllEndpoints ($object_id, $fallback = '') |
c31cd72c DO |
1151 | { |
1152 | $values = getAttrValues ($object_id); | |
1153 | foreach ($values as $record) | |
f321b50a | 1154 | if ($record['name'] == 'FQDN' && !empty ($record['value'])) |
c31cd72c DO |
1155 | return array ($record['value']); |
1156 | $addresses = getObjectAddresses ($object_id); | |
1157 | $regular = array(); | |
1158 | foreach ($addresses as $idx => $address) | |
1159 | if ($address['type'] == 'regular') | |
fa8112d1 | 1160 | $regular[] = $address['ip']; |
f321b50a DO |
1161 | if (!count ($regular) && !empty ($fallback)) |
1162 | return array ($fallback); | |
c31cd72c DO |
1163 | return $regular; |
1164 | } | |
1165 | ||
83ba6670 DO |
1166 | // Some records in the dictionary may be written as plain text or as Wiki |
1167 | // link in the following syntax: | |
1168 | // 1. word | |
1169 | // 2. [[word URL]] // FIXME: this isn't working | |
1170 | // 3. [[word word word | URL]] | |
1171 | // This function parses the line and returns text suitable for either A | |
1172 | // (rendering <A HREF>) or O (for <OPTION>). | |
24cbe8af | 1173 | function parseWikiLink ($line, $which, $strip_optgroup = FALSE) |
83ba6670 | 1174 | { |
010231c2 | 1175 | if (preg_match ('/^\[\[.+\]\]$/', $line) == 0) |
24cbe8af DO |
1176 | { |
1177 | if ($strip_optgroup) | |
1178 | return ereg_replace ('^.+\^', '', $line); | |
1179 | else | |
1180 | return $line; | |
1181 | } | |
010231c2 DO |
1182 | $line = preg_replace ('/^\[\[(.+)\]\]$/', '$1', $line); |
1183 | $s = explode ('|', $line); | |
83ba6670 | 1184 | $o_value = trim ($s[0]); |
24cbe8af DO |
1185 | if ($strip_optgroup) |
1186 | $o_value = ereg_replace ('^.+\^', '', $o_value); | |
83ba6670 DO |
1187 | $a_value = trim ($s[1]); |
1188 | if ($which == 'a') | |
010231c2 | 1189 | return "<a href='${a_value}'>${o_value}</a>"; |
83ba6670 DO |
1190 | if ($which == 'o') |
1191 | return $o_value; | |
1192 | } | |
1193 | ||
2de490b7 DO |
1194 | function buildVServiceName ($vsinfo = NULL) |
1195 | { | |
1196 | if ($vsinfo == NULL) | |
1197 | { | |
1198 | showError ('NULL argument', __FUNCTION__); | |
1199 | return NULL; | |
1200 | } | |
8d790216 | 1201 | return $vsinfo['vip'] . ':' . $vsinfo['vport'] . '/' . $vsinfo['proto']; |
2de490b7 DO |
1202 | } |
1203 | ||
177b1e9b DO |
1204 | // rackspace usage for a single rack |
1205 | // (T + W + U) / (height * 3 - A) | |
11df133a | 1206 | function getRSUforRack ($data = NULL) |
177b1e9b | 1207 | { |
11df133a | 1208 | if ($data == NULL) |
177b1e9b DO |
1209 | { |
1210 | showError ('Invalid argument', __FUNCTION__); | |
1211 | return NULL; | |
1212 | } | |
6ffba290 | 1213 | $counter = array ('A' => 0, 'U' => 0, 'T' => 0, 'W' => 0, 'F' => 0); |
9e60f7df DO |
1214 | for ($unit_no = $data['height']; $unit_no > 0; $unit_no--) |
1215 | for ($locidx = 0; $locidx < 3; $locidx++) | |
1216 | $counter[$data[$unit_no][$locidx]['state']]++; | |
dfa3c075 | 1217 | return ($counter['T'] + $counter['W'] + $counter['U']) / ($counter['T'] + $counter['W'] + $counter['U'] + $counter['F']); |
177b1e9b DO |
1218 | } |
1219 | ||
11df133a DO |
1220 | // Same for row. |
1221 | function getRSUforRackRow ($rowData = NULL) | |
1222 | { | |
bb26a59e | 1223 | if ($rowData === NULL) |
11df133a DO |
1224 | { |
1225 | showError ('Invalid argument', __FUNCTION__); | |
1226 | return NULL; | |
1227 | } | |
bb26a59e DO |
1228 | if (!count ($rowData)) |
1229 | return 0; | |
11df133a | 1230 | $counter = array ('A' => 0, 'U' => 0, 'T' => 0, 'W' => 0, 'F' => 0); |
f81a2012 | 1231 | $total_height = 0; |
dfa3c075 DO |
1232 | foreach (array_keys ($rowData) as $rack_id) |
1233 | { | |
1234 | $data = getRackData ($rack_id); | |
1235 | $total_height += $data['height']; | |
11df133a DO |
1236 | for ($unit_no = $data['height']; $unit_no > 0; $unit_no--) |
1237 | for ($locidx = 0; $locidx < 3; $locidx++) | |
1238 | $counter[$data[$unit_no][$locidx]['state']]++; | |
dfa3c075 DO |
1239 | } |
1240 | return ($counter['T'] + $counter['W'] + $counter['U']) / ($counter['T'] + $counter['W'] + $counter['U'] + $counter['F']); | |
11df133a DO |
1241 | } |
1242 | ||
f1a0477d DO |
1243 | function getObjectCount ($rackData) |
1244 | { | |
1245 | $objects = array(); | |
1246 | for ($i = $rackData['height']; $i > 0; $i--) | |
1247 | for ($locidx = 0; $locidx < 3; $locidx++) | |
1248 | if | |
1249 | ( | |
1250 | $rackData[$i][$locidx]['state'] == 'T' and | |
1251 | !in_array ($rackData[$i][$locidx]['object_id'], $objects) | |
1252 | ) | |
1253 | $objects[] = $rackData[$i][$locidx]['object_id']; | |
1254 | return count ($objects); | |
1255 | } | |
1256 | ||
9af110b4 DO |
1257 | // Perform substitutions and return resulting string |
1258 | function apply_macros ($macros, $subject) | |
1259 | { | |
1260 | $ret = $subject; | |
1261 | foreach ($macros as $search => $replace) | |
1262 | $ret = str_replace ($search, $replace, $ret); | |
1263 | return $ret; | |
1264 | } | |
1265 | ||
1266 | // Make sure the string is always wrapped with LF characters | |
1267 | function lf_wrap ($str) | |
1268 | { | |
1269 | $ret = trim ($str, "\r\n"); | |
1270 | if (!empty ($ret)) | |
1271 | $ret .= "\n"; | |
1272 | return $ret; | |
1273 | } | |
1274 | ||
e6e7d8b3 DO |
1275 | // Adopted from Mantis BTS code. |
1276 | function string_insert_hrefs ($s) | |
1277 | { | |
1278 | if (getConfigVar ('DETECT_URLS') != 'yes') | |
1279 | return $s; | |
1280 | # Find any URL in a string and replace it by a clickable link | |
1281 | $s = preg_replace( '/(([[:alpha:]][-+.[:alnum:]]*):\/\/(%[[:digit:]A-Fa-f]{2}|[-_.!~*\';\/?%^\\\\:@&={\|}+$#\(\),\[\][:alnum:]])+)/se', | |
1282 | "'<a href=\"'.rtrim('\\1','.').'\">\\1</a> [<a href=\"'.rtrim('\\1','.').'\" target=\"_blank\">^</a>]'", | |
1283 | $s); | |
1284 | $s = preg_replace( '/\b' . email_regex_simple() . '\b/i', | |
1285 | '<a href="mailto:\0">\0</a>', | |
1286 | $s); | |
1287 | return $s; | |
1288 | } | |
1289 | ||
1290 | // Idem. | |
1291 | function email_regex_simple () | |
1292 | { | |
1293 | return "(([a-z0-9!#*+\/=?^_{|}~-]+(?:\.[a-z0-9!#*+\/=?^_{|}~-]+)*)" . # recipient | |
1294 | "\@((?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?))"; # @domain | |
1295 | } | |
1296 | ||
118e4c38 DO |
1297 | // Parse AUTOPORTS_CONFIG and return a list of generated pairs (port_type, port_name) |
1298 | // for the requested object_type_id. | |
1299 | function getAutoPorts ($type_id) | |
1300 | { | |
1301 | $ret = array(); | |
1302 | $typemap = explode (';', str_replace (' ', '', getConfigVar ('AUTOPORTS_CONFIG'))); | |
1303 | foreach ($typemap as $equation) | |
1304 | { | |
1305 | $tmp = explode ('=', $equation); | |
1306 | if (count ($tmp) != 2) | |
1307 | continue; | |
1308 | $objtype_id = $tmp[0]; | |
1309 | if ($objtype_id != $type_id) | |
1310 | continue; | |
1311 | $portlist = $tmp[1]; | |
1312 | foreach (explode ('+', $portlist) as $product) | |
1313 | { | |
1314 | $tmp = explode ('*', $product); | |
1315 | if (count ($tmp) != 3) | |
1316 | continue; | |
1317 | $nports = $tmp[0]; | |
1318 | $port_type = $tmp[1]; | |
1319 | $format = $tmp[2]; | |
1320 | for ($i = 0; $i < $nports; $i++) | |
1321 | $ret[] = array ('type' => $port_type, 'name' => @sprintf ($format, $i)); | |
1322 | } | |
1323 | } | |
1324 | return $ret; | |
1325 | } | |
1326 | ||
9dfd4cc9 DO |
1327 | // Find if a particular tag id exists on the tree, then attach the |
1328 | // given child tag to it. If the parent tag doesn't exist, return FALSE. | |
1329 | function attachChildTag (&$tree, $parent_id, $child_id, $child_info) | |
1330 | { | |
1331 | foreach ($tree as $tagid => $taginfo) | |
1332 | { | |
1333 | if ($tagid == $parent_id) | |
1334 | { | |
1335 | $tree[$tagid]['kids'][$child_id] = $child_info; | |
1336 | return TRUE; | |
1337 | } | |
1338 | elseif (attachChildTag ($tree[$tagid]['kids'], $parent_id, $child_id, $child_info)) | |
1339 | return TRUE; | |
1340 | } | |
1341 | return FALSE; | |
1342 | } | |
1343 | ||
1344 | // Build a tree from the tag list and return it. | |
1345 | function getTagTree () | |
1346 | { | |
20c901a7 DO |
1347 | global $taglist; |
1348 | $mytaglist = $taglist; | |
1349 | $ret = array(); | |
1350 | while (count ($mytaglist) > 0) | |
9dfd4cc9 DO |
1351 | { |
1352 | $picked = FALSE; | |
20c901a7 | 1353 | foreach ($mytaglist as $tagid => $taginfo) |
9dfd4cc9 DO |
1354 | { |
1355 | $taginfo['kids'] = array(); | |
1356 | if ($taginfo['parent_id'] == NULL) | |
1357 | { | |
20c901a7 | 1358 | $ret[$tagid] = $taginfo; |
9dfd4cc9 | 1359 | $picked = TRUE; |
20c901a7 | 1360 | unset ($mytaglist[$tagid]); |
9dfd4cc9 | 1361 | } |
20c901a7 | 1362 | elseif (attachChildTag ($ret, $taginfo['parent_id'], $tagid, $taginfo)) |
9dfd4cc9 DO |
1363 | { |
1364 | $picked = TRUE; | |
20c901a7 | 1365 | unset ($mytaglist[$tagid]); |
9dfd4cc9 DO |
1366 | } |
1367 | } | |
1368 | if (!$picked) // Only orphaned items on the list. | |
1369 | break; | |
1370 | } | |
20c901a7 | 1371 | return $ret; |
9dfd4cc9 DO |
1372 | } |
1373 | ||
ba93bd98 DO |
1374 | function serializeTags ($trail) |
1375 | { | |
1376 | $comma = ''; | |
1377 | $ret = ''; | |
1378 | foreach ($trail as $taginfo) | |
1379 | { | |
1380 | $ret .= $comma . $taginfo['tag']; | |
1381 | $comma = ', '; | |
1382 | } | |
1383 | return $ret; | |
1384 | } | |
1385 | ||
ab379543 | 1386 | // a helper for getTrailExpansion() |
ba93bd98 DO |
1387 | function traceTrail ($tree, $trail) |
1388 | { | |
1389 | // For each tag find its path from the root, then combine items | |
1390 | // of all paths and add them to the trail, if they aren't there yet. | |
1391 | $ret = array(); | |
1392 | foreach ($tree as $taginfo1) | |
1393 | { | |
1394 | $hit = FALSE; | |
1395 | foreach ($trail as $taginfo2) | |
1396 | if ($taginfo1['id'] == $taginfo2['id']) | |
1397 | { | |
1398 | $hit = TRUE; | |
1399 | break; | |
1400 | } | |
1401 | if (count ($taginfo1['kids']) > 0) | |
1402 | { | |
1403 | $subsearch = traceTrail ($taginfo1['kids'], $trail); | |
1404 | if (count ($subsearch)) | |
1405 | { | |
1406 | $hit = TRUE; | |
1407 | $ret = array_merge ($ret, $subsearch); | |
1408 | } | |
1409 | } | |
1410 | if ($hit) | |
1411 | $ret[] = $taginfo1; | |
1412 | } | |
1413 | return $ret; | |
1414 | } | |
1415 | ||
1416 | // For each tag add all its parent tags onto the list. Don't expect anything | |
1417 | // except user's tags on the trail. | |
1418 | function getTrailExpansion ($trail) | |
1419 | { | |
20c901a7 DO |
1420 | global $tagtree; |
1421 | return traceTrail ($tagtree, $trail); | |
ba93bd98 DO |
1422 | } |
1423 | ||
1424 | // Return the list of missing implicit tags. | |
1425 | function getImplicitTags ($oldtags) | |
1426 | { | |
1427 | $ret = array(); | |
1428 | $newtags = getTrailExpansion ($oldtags); | |
1429 | foreach ($newtags as $newtag) | |
1430 | { | |
1431 | $already_exists = FALSE; | |
1432 | foreach ($oldtags as $oldtag) | |
1433 | if ($newtag['id'] == $oldtag['id']) | |
1434 | { | |
1435 | $already_exists = TRUE; | |
1436 | break; | |
1437 | } | |
1438 | if ($already_exists) | |
1439 | continue; | |
d6089951 | 1440 | $ret[] = array ('id' => $newtag['id'], 'tag' => $newtag['tag'], 'parent_id' => $newtag['parent_id']); |
ba93bd98 DO |
1441 | } |
1442 | return $ret; | |
1443 | } | |
1444 | ||
ab379543 DO |
1445 | // Minimize the trail: exclude all implicit tags and return the resulting trail. |
1446 | function getExplicitTagsOnly ($trail, $tree = NULL) | |
1447 | { | |
20c901a7 | 1448 | global $tagtree; |
ab379543 | 1449 | if ($tree === NULL) |
20c901a7 | 1450 | $tree = $tagtree; |
ab379543 DO |
1451 | $ret = array(); |
1452 | foreach ($tree as $taginfo) | |
1453 | { | |
1454 | if (isset ($taginfo['kids'])) | |
1455 | { | |
1456 | $harvest = getExplicitTagsOnly ($trail, $taginfo['kids']); | |
1457 | if (count ($harvest) > 0) | |
1458 | { | |
1459 | $ret = array_merge ($ret, $harvest); | |
1460 | continue; | |
1461 | } | |
1462 | } | |
1463 | // This tag isn't implicit, test is for being explicit. | |
1464 | foreach ($trail as $testtag) | |
1465 | if ($taginfo['id'] == $testtag['id']) | |
1466 | { | |
1467 | $ret[] = $testtag; | |
1468 | break; | |
1469 | } | |
1470 | } | |
1471 | return $ret; | |
1472 | } | |
1473 | ||
74ccacff DO |
1474 | // Maximize the trail: for each tag add all tags, for which it is direct or indirect parent. |
1475 | // Unlike other functions, this one accepts and returns a list of integer tag IDs, not | |
1476 | // a list of tag structures. | |
1477 | function complementByKids ($idlist, $tree = NULL, $getall = FALSE) | |
1478 | { | |
20c901a7 | 1479 | global $tagtree; |
74ccacff | 1480 | if ($tree === NULL) |
20c901a7 | 1481 | $tree = $tagtree; |
74ccacff DO |
1482 | $getallkids = $getall; |
1483 | $ret = array(); | |
1484 | foreach ($tree as $taginfo) | |
1485 | { | |
1486 | foreach ($idlist as $test_id) | |
1487 | if ($getall or $taginfo['id'] == $test_id) | |
1488 | { | |
1489 | $ret[] = $taginfo['id']; | |
1490 | // Once matched node makes all sub-nodes match, but don't make | |
1491 | // a mistake of matching every other node at the current level. | |
1492 | $getallkids = TRUE; | |
1493 | break; | |
1494 | } | |
1495 | if (isset ($taginfo['kids'])) | |
1496 | $ret = array_merge ($ret, complementByKids ($idlist, $taginfo['kids'], $getallkids)); | |
1497 | $getallkids = FALSE; | |
1498 | } | |
1499 | return $ret; | |
1500 | } | |
1501 | ||
2fb24351 | 1502 | function loadRackObjectAutoTags() |
ba93bd98 | 1503 | { |
2fb24351 DO |
1504 | assertUIntArg ('object_id'); |
1505 | $object_id = $_REQUEST['object_id']; | |
1506 | $oinfo = getObjectInfo ($object_id); | |
1507 | $ret = array(); | |
1508 | $ret[] = array ('tag' => '$id_' . $_REQUEST['object_id']); | |
d817ba03 | 1509 | $ret[] = array ('tag' => '$any_object'); |
2fb24351 DO |
1510 | return $ret; |
1511 | } | |
1512 | ||
f9bc186f DO |
1513 | function loadIPv4PrefixAutoTags() |
1514 | { | |
1515 | assertUIntArg ('id'); | |
41bd8c87 | 1516 | $subnet = getIPRange ($_REQUEST['id']); |
f9bc186f DO |
1517 | $ret = array(); |
1518 | $ret[] = array ('tag' => '$id_' . $_REQUEST['id']); | |
41bd8c87 | 1519 | $ret[] = array ('tag' => '$ipv4net-' . str_replace ('.', '-', $subnet['ip']) . '-' . $subnet['mask']); |
d817ba03 DO |
1520 | // FIXME: find and list tags for all parent networks |
1521 | $ret[] = array ('tag' => '$any_ipv4net'); | |
1522 | $ret[] = array ('tag' => '$any_net'); | |
41bd8c87 DO |
1523 | return $ret; |
1524 | } | |
1525 | ||
1526 | function loadRackAutoTags() | |
1527 | { | |
1528 | assertUIntArg ('rack_id'); | |
1529 | $ret = array(); | |
1530 | $ret[] = array ('tag' => '$id_' . $_REQUEST['rack_id']); | |
d817ba03 DO |
1531 | $ret[] = array ('tag' => '$any_rack'); |
1532 | return $ret; | |
1533 | } | |
1534 | ||
1535 | function loadIPv4AddressAutoTags() | |
1536 | { | |
1537 | assertIPv4Arg ('ip'); | |
1538 | $ret = array(); | |
1539 | $ret[] = array ('tag' => '$ipv4net-' . str_replace ('.', '-', $subnet['ip']) . '-32'); | |
1540 | // FIXME: find and list tags for all parent networks | |
1541 | $ret[] = array ('tag' => '$any_ipv4net'); | |
1542 | $ret[] = array ('tag' => '$any_net'); | |
1543 | return $ret; | |
1544 | } | |
1545 | ||
1546 | function loadIPv4VSAutoTags() | |
1547 | { | |
1548 | assertUIntArg ('id'); | |
1549 | $ret = array(); | |
1550 | $ret[] = array ('tag' => '$id_' . $_REQUEST['id']); | |
1551 | $ret[] = array ('tag' => '$any_ipv4vs'); | |
1552 | $ret[] = array ('tag' => '$any_vs'); | |
1553 | return $ret; | |
1554 | } | |
1555 | ||
1556 | function loadIPv4RSPoolAutoTags() | |
1557 | { | |
e2980879 | 1558 | assertUIntArg ('pool_id'); |
d817ba03 | 1559 | $ret = array(); |
6aff02cf | 1560 | $ret[] = array ('tag' => '$id_' . $_REQUEST['pool_id']); |
d817ba03 DO |
1561 | $ret[] = array ('tag' => '$any_ipv4rspool'); |
1562 | $ret[] = array ('tag' => '$any_rspool'); | |
f9bc186f DO |
1563 | return $ret; |
1564 | } | |
1565 | ||
2fb24351 DO |
1566 | function getGlobalAutoTags() |
1567 | { | |
1568 | global $remote_username, $accounts; | |
1569 | $ret = array(); | |
1570 | $user_id = 0; | |
1571 | foreach ($accounts as $a) | |
1572 | if ($a['user_name'] == $remote_username) | |
1573 | { | |
1574 | $user_id = $a['user_id']; | |
1575 | break; | |
1576 | } | |
1577 | $ret[] = array ('tag' => '$username_' . $remote_username); | |
1578 | $ret[] = array ('tag' => '$userid_' . $user_id); | |
1579 | return $ret; | |
ba93bd98 DO |
1580 | } |
1581 | ||
ab379543 DO |
1582 | // Build a tag trail from supplied tag id list and return it. |
1583 | function buildTrailFromIds ($tagidlist) | |
1584 | { | |
20c901a7 | 1585 | global $taglist; |
ab379543 DO |
1586 | $ret = array(); |
1587 | foreach ($tagidlist as $tag_id) | |
1588 | if (isset ($taglist[$tag_id])) | |
1589 | $ret[] = $taglist[$tag_id]; | |
1590 | return $ret; | |
1591 | } | |
1592 | ||
e673ee24 | 1593 | ?> |