mirror of
				https://github.com/Icinga/icinga2.git
				synced 2025-11-03 21:25:56 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			303 lines
		
	
	
		
			8.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			303 lines
		
	
	
		
			8.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/* 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. */
 | 
						|
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. */
 | 
						|
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;
 | 
						|
}
 |