1 | <?php |
||
2 | /** |
||
3 | * alert-rules.inc.php |
||
4 | * |
||
5 | * LibreNMS alert-rules.inc.php |
||
6 | * |
||
7 | * This program is free software: you can redistribute it and/or modify |
||
8 | * it under the terms of the GNU General Public License as published by |
||
9 | * the Free Software Foundation, either version 3 of the License, or |
||
10 | * (at your option) any later version. |
||
11 | * |
||
12 | * This program is distributed in the hope that it will be useful, |
||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the |
||
15 | * GNU General Public License for more details. |
||
16 | * |
||
17 | * You should have received a copy of the GNU General Public License |
||
18 | * along with this program. If not, see <https://www.gnu.org/licenses/>. |
||
19 | * |
||
20 | * @link https://www.librenms.org |
||
21 | * |
||
22 | * @copyright 2018 Neil Lathwood |
||
23 | * @author Neil Lathwood <[email protected]> |
||
24 | */ |
||
25 | |||
26 | use Illuminate\Support\Str; |
||
27 | use LibreNMS\Alerting\QueryBuilderParser; |
||
28 | |||
29 | header('Content-type: application/json'); |
||
30 | |||
31 | if (! Auth::user()->hasGlobalAdmin()) { |
||
32 | exit(json_encode([ |
||
33 | 'status' => 'error', |
||
34 | 'message' => 'ERROR: You need to be admin', |
||
35 | ])); |
||
36 | } |
||
37 | |||
38 | $status = 'ok'; |
||
39 | $message = ''; |
||
40 | |||
41 | $builder_json = $vars['builder_json']; |
||
42 | $override_query = $vars['override_query']; |
||
43 | |||
44 | $options = [ |
||
45 | 'override_query' => $override_query, |
||
46 | ]; |
||
47 | |||
48 | if ($override_query === 'on') { |
||
49 | $query = $vars['adv_query']; |
||
50 | } else { |
||
51 | $query = QueryBuilderParser::fromJson($builder_json)->toSql(); |
||
52 | } |
||
53 | $rule_id = $_POST['rule_id']; |
||
54 | $count = $_POST['count']; |
||
55 | $delay = $_POST['delay']; |
||
56 | $interval = $_POST['interval']; |
||
57 | $mute = isset($_POST['mute']) ? $_POST['mute'] : null; |
||
58 | $invert = isset($_POST['invert']) ? $_POST['invert'] : null; |
||
59 | $name = $_POST['name']; |
||
60 | $proc = $_POST['proc']; |
||
61 | $recovery = ($vars['recovery']); |
||
62 | $invert_map = isset($_POST['invert_map']) ? $_POST['invert_map'] : null; |
||
63 | $severity = $_POST['severity']; |
||
64 | |||
65 | if (! is_numeric($count)) { |
||
66 | $count = '-1'; |
||
67 | } |
||
68 | |||
69 | $delay_sec = convert_delay($delay); |
||
70 | $interval_sec = convert_delay($interval); |
||
71 | |||
72 | if ($mute == 'on') { |
||
73 | $mute = true; |
||
74 | } else { |
||
75 | $mute = false; |
||
76 | } |
||
77 | |||
78 | if ($invert == 'on') { |
||
79 | $invert = true; |
||
80 | } else { |
||
81 | $invert = false; |
||
82 | } |
||
83 | |||
84 | $recovery = empty($recovery) ? $recovery = false : true; |
||
85 | |||
86 | if ($invert_map == 'on') { |
||
87 | $invert_map = true; |
||
88 | } else { |
||
89 | $invert_map = false; |
||
90 | } |
||
91 | |||
92 | $extra = [ |
||
93 | 'mute' => $mute, |
||
94 | 'count' => $count, |
||
95 | 'delay' => $delay_sec, |
||
96 | 'invert' => $invert, |
||
97 | 'interval' => $interval_sec, |
||
98 | 'recovery' => $recovery, |
||
99 | 'options' => $options, |
||
100 | ]; |
||
101 | |||
102 | $extra_json = json_encode($extra); |
||
103 | |||
104 | if (! is_array($vars['maps']) && $invert_map) { |
||
105 | exit(json_encode([ |
||
106 | 'status' => 'error', |
||
107 | 'message' => 'Invert map is on but no selection in devices, groups and locations match list<br />', |
||
108 | ])); |
||
109 | } |
||
110 | |||
111 | if (is_numeric($rule_id) && $rule_id > 0) { |
||
112 | if (dbUpdate( |
||
113 | [ |
||
114 | 'severity' => $severity, |
||
115 | 'extra' => $extra_json, |
||
116 | 'name' => $name, |
||
117 | 'proc' => $proc, |
||
118 | 'query' => $query, |
||
119 | 'builder' => $builder_json, |
||
120 | 'invert_map' => $invert_map, |
||
121 | ], |
||
122 | 'alert_rules', |
||
123 | 'id=?', |
||
124 | [$rule_id] |
||
125 | ) >= 0) { |
||
126 | $message = "Edited Rule: <i>$name</i>"; |
||
127 | } else { |
||
128 | $message = "Failed to edit Rule <i>$name</i>"; |
||
129 | $status = 'error'; |
||
130 | } |
||
131 | } else { |
||
132 | if (empty($name)) { |
||
133 | $status = 'error'; |
||
134 | $message = 'No rule name provided'; |
||
135 | } elseif (empty($builder_json) || empty($query)) { |
||
136 | $status = 'error'; |
||
137 | $message = 'No rules provided'; |
||
138 | } else { |
||
139 | $rule_id = dbInsert([ |
||
140 | 'rule' => '', |
||
141 | 'severity' => $severity, |
||
142 | 'extra' => $extra_json, |
||
143 | 'disabled' => 0, |
||
144 | 'name' => $name, |
||
145 | 'proc' => $proc, |
||
146 | 'query' => $query, |
||
147 | 'builder' => $builder_json, |
||
148 | 'invert_map' => $invert_map, |
||
149 | ], 'alert_rules'); |
||
150 | |||
151 | if ($rule_id) { |
||
0 ignored issues
–
show
|
|||
152 | $message = "Added Rule: <i>$name</i>"; |
||
153 | } else { |
||
154 | if (dbFetchCell('SELECT 1 FROM alert_rules WHERE name=?', [$name])) { |
||
155 | $message = "Rule named <i>$name</i> already exists"; |
||
156 | } else { |
||
157 | $message = "Failed to add Rule: <i>$name</i>"; |
||
158 | } |
||
159 | $status = 'error'; |
||
160 | } |
||
161 | } |
||
162 | }//end if |
||
163 | |||
164 | // update maps |
||
165 | if (is_numeric($rule_id) && $rule_id > 0) { |
||
166 | $devices = []; |
||
167 | $groups = []; |
||
168 | $locations = []; |
||
169 | foreach ((array) $vars['maps'] as $item) { |
||
170 | if (Str::startsWith($item, 'l')) { |
||
171 | $locations[] = (int) substr($item, 1); |
||
172 | } elseif (Str::startsWith($item, 'g')) { |
||
173 | $groups[] = (int) substr($item, 1); |
||
174 | } else { |
||
175 | $devices[] = (int) $item; |
||
176 | } |
||
177 | } |
||
178 | |||
179 | dbSyncRelationship('alert_device_map', 'rule_id', $rule_id, 'device_id', $devices); |
||
180 | dbSyncRelationship('alert_group_map', 'rule_id', $rule_id, 'group_id', $groups); |
||
181 | dbSyncRelationship('alert_location_map', 'rule_id', $rule_id, 'location_id', $locations); |
||
182 | |||
183 | //Update transport groups and transports - can't use dbSyncRelationship |
||
184 | $transports = []; |
||
185 | $groups = []; |
||
186 | foreach ((array) $vars['transports'] as $item) { |
||
187 | if (Str::startsWith($item, 'g')) { |
||
188 | $groups[] = (int) substr($item, 1); |
||
189 | } else { |
||
190 | $transports[] = (int) $item; |
||
191 | } |
||
192 | } |
||
193 | |||
194 | // Fetch transport/group mappings already in db |
||
195 | $sql = "SELECT `transport_or_group_id` FROM `alert_transport_map` WHERE `target_type`='single' AND `rule_id`=?"; |
||
196 | $db_transports = dbFetchColumn($sql, [$rule_id]); |
||
197 | $sql = "SELECT `transport_or_group_id` FROM `alert_transport_map` WHERE `target_type`='group' AND `rule_id`=?"; |
||
198 | $db_groups = dbFetchColumn($sql, [$rule_id]); |
||
199 | |||
200 | // Compare arrays to get add and removed transports/groups |
||
201 | $t_add = array_diff($transports, $db_transports); |
||
202 | $t_del = array_diff($db_transports, $transports); |
||
203 | $g_add = array_diff($groups, $db_groups); |
||
204 | $g_del = array_diff($db_groups, $groups); |
||
205 | |||
206 | // Insert any new mappings |
||
207 | $insert = []; |
||
208 | foreach ($t_add as $transport_id) { |
||
209 | $insert[] = [ |
||
210 | 'transport_or_group_id' => $transport_id, |
||
211 | 'target_type' => 'single', |
||
212 | 'rule_id' => $rule_id, |
||
213 | ]; |
||
214 | } |
||
215 | foreach ($g_add as $group_id) { |
||
216 | $insert[] = [ |
||
217 | 'transport_or_group_id' => $group_id, |
||
218 | 'target_type' => 'group', |
||
219 | 'rule_id' => $rule_id, |
||
220 | ]; |
||
221 | } |
||
222 | if (! empty($insert)) { |
||
223 | $res = dbBulkInsert($insert, 'alert_transport_map'); |
||
224 | } |
||
225 | // Remove old mappings |
||
226 | if (! empty($t_del)) { |
||
227 | $db_t_values = array_merge([$rule_id], $t_del); |
||
228 | dbDelete('alert_transport_map', 'target_type="single" AND rule_id=? AND transport_or_group_id IN ' . dbGenPlaceholders(count($t_del)), $db_t_values); |
||
229 | } |
||
230 | if (! empty($g_del)) { |
||
231 | $db_g_values = array_merge([$rule_id], $g_del); |
||
232 | dbDelete('alert_transport_map', 'target_type="group" AND rule_id=? AND transport_or_group_id IN ' . dbGenPlaceholders(count($g_del)), $db_g_values); |
||
233 | } |
||
234 | } |
||
235 | |||
236 | exit(json_encode([ |
||
237 | 'status' => $status, |
||
238 | 'message' => $message, |
||
239 | ])); |
||
240 |
In PHP, under loose comparison (like
==
, or!=
, orswitch
conditions), values of different types might be equal.For
integer
values, zero is a special case, in particular the following results might be unexpected: