]> granicus.if.org Git - icinga2/blob - lib/icinga/compatutility.cpp
Merge pull request #6727 from Icinga/feature/cluster-config-sync-stage
[icinga2] / lib / icinga / compatutility.cpp
1 /* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
2
3 #include "icinga/compatutility.hpp"
4 #include "icinga/checkcommand.hpp"
5 #include "icinga/eventcommand.hpp"
6 #include "icinga/notificationcommand.hpp"
7 #include "icinga/pluginutility.hpp"
8 #include "icinga/service.hpp"
9 #include "base/utility.hpp"
10 #include "base/configtype.hpp"
11 #include "base/objectlock.hpp"
12 #include "base/convert.hpp"
13 #include <boost/algorithm/string/replace.hpp>
14 #include <boost/algorithm/string/join.hpp>
15
16 using namespace icinga;
17
18 /* Used in DB IDO, StatusDataWriter and Livestatus. */
19 String CompatUtility::GetCommandLine(const Command::Ptr& command)
20 {
21         Value commandLine = command->GetCommandLine();
22
23         String result;
24         if (commandLine.IsObjectType<Array>()) {
25                 Array::Ptr args = commandLine;
26
27                 ObjectLock olock(args);
28                 for (const String& arg : args) {
29                         // This is obviously incorrect for non-trivial cases.
30                         result += " \"" + EscapeString(arg) + "\"";
31                 }
32         } else if (!commandLine.IsEmpty()) {
33                 result = EscapeString(Convert::ToString(commandLine));
34         } else {
35                 result = "<internal>";
36         }
37
38         return result;
39 }
40
41 String CompatUtility::GetCommandNamePrefix(const Command::Ptr& command)
42 /* Helper. */
43 {
44         if (!command)
45                 return Empty;
46
47         String prefix;
48         if (command->GetReflectionType() == CheckCommand::TypeInstance)
49                 prefix = "check_";
50         else if (command->GetReflectionType() == NotificationCommand::TypeInstance)
51                 prefix = "notification_";
52         else if (command->GetReflectionType() == EventCommand::TypeInstance)
53                 prefix = "event_";
54
55         return prefix;
56 }
57
58 String CompatUtility::GetCommandName(const Command::Ptr& command)
59 /* Used in DB IDO, StatusDataWriter and Livestatus. */
60 {
61         if (!command)
62                 return Empty;
63
64         return GetCommandNamePrefix(command) + command->GetName();
65 }
66
67 /* Used in DB IDO, StatusDataWriter and Livestatus. */
68 String CompatUtility::GetCheckableCommandArgs(const Checkable::Ptr& checkable)
69 {
70         CheckCommand::Ptr command = checkable->GetCheckCommand();
71
72         Dictionary::Ptr args = new Dictionary();
73
74         if (command) {
75                 Host::Ptr host;
76                 Service::Ptr service;
77                 tie(host, service) = GetHostService(checkable);
78                 String command_line = GetCommandLine(command);
79
80                 Dictionary::Ptr command_vars = command->GetVars();
81
82                 if (command_vars) {
83                         ObjectLock olock(command_vars);
84                         for (const Dictionary::Pair& kv : command_vars) {
85                                 String macro = "$" + kv.first + "$"; // this is too simple
86                                 if (command_line.Contains(macro))
87                                         args->Set(kv.first, kv.second);
88
89                         }
90                 }
91
92                 Dictionary::Ptr host_vars = host->GetVars();
93
94                 if (host_vars) {
95                         ObjectLock olock(host_vars);
96                         for (const Dictionary::Pair& kv : host_vars) {
97                                 String macro = "$" + kv.first + "$"; // this is too simple
98                                 if (command_line.Contains(macro))
99                                         args->Set(kv.first, kv.second);
100                                 macro = "$host.vars." + kv.first + "$";
101                                 if (command_line.Contains(macro))
102                                         args->Set(kv.first, kv.second);
103                         }
104                 }
105
106                 if (service) {
107                         Dictionary::Ptr service_vars = service->GetVars();
108
109                         if (service_vars) {
110                                 ObjectLock olock(service_vars);
111                                 for (const Dictionary::Pair& kv : service_vars) {
112                                         String macro = "$" + kv.first + "$"; // this is too simple
113                                         if (command_line.Contains(macro))
114                                                 args->Set(kv.first, kv.second);
115                                         macro = "$service.vars." + kv.first + "$";
116                                         if (command_line.Contains(macro))
117                                                 args->Set(kv.first, kv.second);
118                                 }
119                         }
120                 }
121
122                 String arg_string;
123                 ObjectLock olock(args);
124                 for (const Dictionary::Pair& kv : args) {
125                         arg_string += Convert::ToString(kv.first) + "=" + Convert::ToString(kv.second) + "!";
126                 }
127                 return arg_string;
128         }
129
130         return Empty;
131 }
132
133 /* Used in DB IDO, StatusDataWriter and Livestatus. */
134 int CompatUtility::GetCheckableNotificationLastNotification(const Checkable::Ptr& checkable)
135 {
136         double last_notification = 0.0;
137         for (const Notification::Ptr& notification : checkable->GetNotifications()) {
138                 if (notification->GetLastNotification() > last_notification)
139                         last_notification = notification->GetLastNotification();
140         }
141
142         return static_cast<int>(last_notification);
143 }
144
145 /* Used in DB IDO, StatusDataWriter and Livestatus. */
146 int CompatUtility::GetCheckableNotificationNextNotification(const Checkable::Ptr& checkable)
147 {
148         double next_notification = 0.0;
149         for (const Notification::Ptr& notification : checkable->GetNotifications()) {
150                 if (next_notification == 0 || notification->GetNextNotification() < next_notification)
151                         next_notification = notification->GetNextNotification();
152         }
153
154         return static_cast<int>(next_notification);
155 }
156
157 /* Used in DB IDO, StatusDataWriter and Livestatus. */
158 int CompatUtility::GetCheckableNotificationNotificationNumber(const Checkable::Ptr& checkable)
159 {
160         int notification_number = 0;
161         for (const Notification::Ptr& notification : checkable->GetNotifications()) {
162                 if (notification->GetNotificationNumber() > notification_number)
163                         notification_number = notification->GetNotificationNumber();
164         }
165
166         return notification_number;
167 }
168
169 /* Used in DB IDO, StatusDataWriter and Livestatus. */
170 double CompatUtility::GetCheckableNotificationNotificationInterval(const Checkable::Ptr& checkable)
171 {
172         double notification_interval = -1;
173
174         for (const Notification::Ptr& notification : checkable->GetNotifications()) {
175                 if (notification_interval == -1 || notification->GetInterval() < notification_interval)
176                         notification_interval = notification->GetInterval();
177         }
178
179         if (notification_interval == -1)
180                 notification_interval = 60;
181
182         return notification_interval / 60.0;
183 }
184
185 /* Helper. */
186 int CompatUtility::GetCheckableNotificationTypeFilter(const Checkable::Ptr& checkable)
187 {
188         unsigned long notification_type_filter = 0;
189
190         for (const Notification::Ptr& notification : checkable->GetNotifications()) {
191                 ObjectLock olock(notification);
192
193                 notification_type_filter |= notification->GetTypeFilter();
194         }
195
196         return notification_type_filter;
197 }
198
199 /* Helper. */
200 int CompatUtility::GetCheckableNotificationStateFilter(const Checkable::Ptr& checkable)
201 {
202         unsigned long notification_state_filter = 0;
203
204         for (const Notification::Ptr& notification : checkable->GetNotifications()) {
205                 ObjectLock olock(notification);
206
207                 notification_state_filter |= notification->GetStateFilter();
208         }
209
210         return notification_state_filter;
211 }
212
213 /* Used in DB IDO, StatusDataWriter and Livestatus. */
214 std::set<User::Ptr> CompatUtility::GetCheckableNotificationUsers(const Checkable::Ptr& checkable)
215 {
216         /* Service -> Notifications -> (Users + UserGroups -> Users) */
217         std::set<User::Ptr> allUsers;
218         std::set<User::Ptr> users;
219
220         for (const Notification::Ptr& notification : checkable->GetNotifications()) {
221                 ObjectLock olock(notification);
222
223                 users = notification->GetUsers();
224
225                 std::copy(users.begin(), users.end(), std::inserter(allUsers, allUsers.begin()));
226
227                 for (const UserGroup::Ptr& ug : notification->GetUserGroups()) {
228                         std::set<User::Ptr> members = ug->GetMembers();
229                         std::copy(members.begin(), members.end(), std::inserter(allUsers, allUsers.begin()));
230                 }
231         }
232
233         return allUsers;
234 }
235
236 /* Used in DB IDO, StatusDataWriter and Livestatus. */
237 std::set<UserGroup::Ptr> CompatUtility::GetCheckableNotificationUserGroups(const Checkable::Ptr& checkable)
238 {
239         std::set<UserGroup::Ptr> usergroups;
240         /* Service -> Notifications -> UserGroups */
241         for (const Notification::Ptr& notification : checkable->GetNotifications()) {
242                 ObjectLock olock(notification);
243
244                 for (const UserGroup::Ptr& ug : notification->GetUserGroups()) {
245                         usergroups.insert(ug);
246                 }
247         }
248
249         return usergroups;
250 }
251
252 /* Used in DB IDO, StatusDataWriter, Livestatus, CompatLogger, GelfWriter. */
253 String CompatUtility::GetCheckResultOutput(const CheckResult::Ptr& cr)
254 {
255         if (!cr)
256                 return Empty;
257
258         String output;
259
260         String raw_output = cr->GetOutput();
261
262         size_t line_end = raw_output.Find("\n");
263
264         return raw_output.SubStr(0, line_end);
265 }
266
267 /* Used in DB IDO, StatusDataWriter and Livestatus. */
268 String CompatUtility::GetCheckResultLongOutput(const CheckResult::Ptr& cr)
269 {
270         if (!cr)
271                 return Empty;
272
273         String long_output;
274         String output;
275
276         String raw_output = cr->GetOutput();
277
278         size_t line_end = raw_output.Find("\n");
279
280         if (line_end > 0 && line_end != String::NPos) {
281                 long_output = raw_output.SubStr(line_end+1, raw_output.GetLength());
282                 return EscapeString(long_output);
283         }
284
285         return Empty;
286 }
287
288 /* Helper for DB IDO, StatusDataWriter and Livestatus. Used in StatusDataWriter. */
289 String CompatUtility::EscapeString(const String& str)
290 {
291         String result = str;
292         boost::algorithm::replace_all(result, "\n", "\\n");
293         return result;
294 }
295
296 /* Used in ExternalCommandListener and CheckResultReader. */
297 String CompatUtility::UnEscapeString(const String& str)
298 {
299         String result = str;
300         boost::algorithm::replace_all(result, "\\n", "\n");
301         return result;
302 }