diff options
Diffstat (limited to 'lib/icinga/compatutility.cpp')
-rw-r--r-- | lib/icinga/compatutility.cpp | 302 |
1 files changed, 302 insertions, 0 deletions
diff --git a/lib/icinga/compatutility.cpp b/lib/icinga/compatutility.cpp new file mode 100644 index 0000000..40c01f3 --- /dev/null +++ b/lib/icinga/compatutility.cpp @@ -0,0 +1,302 @@ +/* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */ + +#include "icinga/compatutility.hpp" +#include "icinga/checkcommand.hpp" +#include "icinga/eventcommand.hpp" +#include "icinga/notificationcommand.hpp" +#include "icinga/pluginutility.hpp" +#include "icinga/service.hpp" +#include "base/utility.hpp" +#include "base/configtype.hpp" +#include "base/objectlock.hpp" +#include "base/convert.hpp" +#include <boost/algorithm/string/replace.hpp> +#include <boost/algorithm/string/join.hpp> + +using namespace icinga; + +/* Used in DB IDO, StatusDataWriter and Livestatus. */ +String CompatUtility::GetCommandLine(const Command::Ptr& command) +{ + Value commandLine = command->GetCommandLine(); + + String result; + if (commandLine.IsObjectType<Array>()) { + Array::Ptr args = commandLine; + + ObjectLock olock(args); + for (const String& arg : args) { + // This is obviously incorrect for non-trivial cases. + result += " \"" + EscapeString(arg) + "\""; + } + } else if (!commandLine.IsEmpty()) { + result = EscapeString(Convert::ToString(commandLine)); + } else { + result = "<internal>"; + } + + return result; +} + +String CompatUtility::GetCommandNamePrefix(const Command::Ptr& command) +/* Helper. */ +{ + if (!command) + return Empty; + + String prefix; + if (command->GetReflectionType() == CheckCommand::TypeInstance) + prefix = "check_"; + else if (command->GetReflectionType() == NotificationCommand::TypeInstance) + prefix = "notification_"; + else if (command->GetReflectionType() == EventCommand::TypeInstance) + prefix = "event_"; + + return prefix; +} + +String CompatUtility::GetCommandName(const Command::Ptr& command) +/* Used in DB IDO, StatusDataWriter and Livestatus. */ +{ + if (!command) + return Empty; + + return GetCommandNamePrefix(command) + command->GetName(); +} + +/* Used in DB IDO, StatusDataWriter and Livestatus. */ +String CompatUtility::GetCheckableCommandArgs(const Checkable::Ptr& checkable) +{ + CheckCommand::Ptr command = checkable->GetCheckCommand(); + + Dictionary::Ptr args = new Dictionary(); + + if (command) { + Host::Ptr host; + Service::Ptr service; + tie(host, service) = GetHostService(checkable); + String command_line = GetCommandLine(command); + + Dictionary::Ptr command_vars = command->GetVars(); + + if (command_vars) { + ObjectLock olock(command_vars); + for (const Dictionary::Pair& kv : command_vars) { + String macro = "$" + kv.first + "$"; // this is too simple + if (command_line.Contains(macro)) + args->Set(kv.first, kv.second); + + } + } + + Dictionary::Ptr host_vars = host->GetVars(); + + if (host_vars) { + ObjectLock olock(host_vars); + for (const Dictionary::Pair& kv : host_vars) { + String macro = "$" + kv.first + "$"; // this is too simple + if (command_line.Contains(macro)) + args->Set(kv.first, kv.second); + macro = "$host.vars." + kv.first + "$"; + if (command_line.Contains(macro)) + args->Set(kv.first, kv.second); + } + } + + if (service) { + Dictionary::Ptr service_vars = service->GetVars(); + + if (service_vars) { + ObjectLock olock(service_vars); + for (const Dictionary::Pair& kv : service_vars) { + String macro = "$" + kv.first + "$"; // this is too simple + if (command_line.Contains(macro)) + args->Set(kv.first, kv.second); + macro = "$service.vars." + kv.first + "$"; + if (command_line.Contains(macro)) + args->Set(kv.first, kv.second); + } + } + } + + String arg_string; + ObjectLock olock(args); + for (const Dictionary::Pair& kv : args) { + arg_string += Convert::ToString(kv.first) + "=" + Convert::ToString(kv.second) + "!"; + } + return arg_string; + } + + return Empty; +} + +/* Used in DB IDO, StatusDataWriter and Livestatus. */ +int CompatUtility::GetCheckableNotificationLastNotification(const Checkable::Ptr& checkable) +{ + double last_notification = 0.0; + for (const Notification::Ptr& notification : checkable->GetNotifications()) { + if (notification->GetLastNotification() > last_notification) + last_notification = notification->GetLastNotification(); + } + + return static_cast<int>(last_notification); +} + +/* Used in DB IDO, StatusDataWriter and Livestatus. */ +int CompatUtility::GetCheckableNotificationNextNotification(const Checkable::Ptr& checkable) +{ + double next_notification = 0.0; + for (const Notification::Ptr& notification : checkable->GetNotifications()) { + if (next_notification == 0 || notification->GetNextNotification() < next_notification) + next_notification = notification->GetNextNotification(); + } + + return static_cast<int>(next_notification); +} + +/* Used in DB IDO, StatusDataWriter and Livestatus. */ +int CompatUtility::GetCheckableNotificationNotificationNumber(const Checkable::Ptr& checkable) +{ + int notification_number = 0; + for (const Notification::Ptr& notification : checkable->GetNotifications()) { + if (notification->GetNotificationNumber() > notification_number) + notification_number = notification->GetNotificationNumber(); + } + + return notification_number; +} + +/* Used in DB IDO, StatusDataWriter and Livestatus. */ +double CompatUtility::GetCheckableNotificationNotificationInterval(const Checkable::Ptr& checkable) +{ + double notification_interval = -1; + + for (const Notification::Ptr& notification : checkable->GetNotifications()) { + if (notification_interval == -1 || notification->GetInterval() < notification_interval) + notification_interval = notification->GetInterval(); + } + + if (notification_interval == -1) + notification_interval = 60; + + return notification_interval / 60.0; +} + +/* Helper. */ +int CompatUtility::GetCheckableNotificationTypeFilter(const Checkable::Ptr& checkable) +{ + unsigned long notification_type_filter = 0; + + for (const Notification::Ptr& notification : checkable->GetNotifications()) { + ObjectLock olock(notification); + + notification_type_filter |= notification->GetTypeFilter(); + } + + return notification_type_filter; +} + +/* Helper. */ +int CompatUtility::GetCheckableNotificationStateFilter(const Checkable::Ptr& checkable) +{ + unsigned long notification_state_filter = 0; + + for (const Notification::Ptr& notification : checkable->GetNotifications()) { + ObjectLock olock(notification); + + notification_state_filter |= notification->GetStateFilter(); + } + + return notification_state_filter; +} + +/* Used in DB IDO, StatusDataWriter and Livestatus. */ +std::set<User::Ptr> CompatUtility::GetCheckableNotificationUsers(const Checkable::Ptr& checkable) +{ + /* Service -> Notifications -> (Users + UserGroups -> Users) */ + std::set<User::Ptr> allUsers; + std::set<User::Ptr> users; + + for (const Notification::Ptr& notification : checkable->GetNotifications()) { + ObjectLock olock(notification); + + users = notification->GetUsers(); + + std::copy(users.begin(), users.end(), std::inserter(allUsers, allUsers.begin())); + + for (const UserGroup::Ptr& ug : notification->GetUserGroups()) { + std::set<User::Ptr> members = ug->GetMembers(); + std::copy(members.begin(), members.end(), std::inserter(allUsers, allUsers.begin())); + } + } + + return allUsers; +} + +/* Used in DB IDO, StatusDataWriter and Livestatus. */ +std::set<UserGroup::Ptr> CompatUtility::GetCheckableNotificationUserGroups(const Checkable::Ptr& checkable) +{ + std::set<UserGroup::Ptr> usergroups; + /* Service -> Notifications -> UserGroups */ + for (const Notification::Ptr& notification : checkable->GetNotifications()) { + ObjectLock olock(notification); + + for (const UserGroup::Ptr& ug : notification->GetUserGroups()) { + usergroups.insert(ug); + } + } + + return usergroups; +} + +/* Used in DB IDO, StatusDataWriter, Livestatus, CompatLogger, GelfWriter, IcingaDB. */ +String CompatUtility::GetCheckResultOutput(const CheckResult::Ptr& cr) +{ + if (!cr) + return Empty; + + String output; + + String raw_output = cr->GetOutput(); + + size_t line_end = raw_output.Find("\n"); + + return raw_output.SubStr(0, line_end); +} + +/* Used in DB IDO, StatusDataWriter and Livestatus, IcingaDB. */ +String CompatUtility::GetCheckResultLongOutput(const CheckResult::Ptr& cr) +{ + if (!cr) + return Empty; + + String long_output; + String output; + + String raw_output = cr->GetOutput(); + + size_t line_end = raw_output.Find("\n"); + + if (line_end > 0 && line_end != String::NPos) { + long_output = raw_output.SubStr(line_end+1, raw_output.GetLength()); + return EscapeString(long_output); + } + + return Empty; +} + +/* Helper for DB IDO, StatusDataWriter and Livestatus. Used in StatusDataWriter. */ +String CompatUtility::EscapeString(const String& str) +{ + String result = str; + boost::algorithm::replace_all(result, "\n", "\\n"); + return result; +} + +/* Used in ExternalCommandListener and CheckResultReader. */ +String CompatUtility::UnEscapeString(const String& str) +{ + String result = str; + boost::algorithm::replace_all(result, "\\n", "\n"); + return result; +} |