Notification* PriorityNotificationQueue::waitDequeueNotification(long milliseconds)
{
    Notification::Ptr pNf;
    WaitInfo* pWI = 0;
    {
        FastMutex::ScopedLock lock(_mutex);
        pNf = dequeueOne();
        if (pNf) return pNf.duplicate();
        pWI = new WaitInfo;
        _waitQueue.push_back(pWI);
    }
    if (pWI->nfAvailable.tryWait(milliseconds))
    {
        pNf = pWI->pNf;
    }
    else
    {
        FastMutex::ScopedLock lock(_mutex);
        pNf = pWI->pNf;
        for (WaitQueue::iterator it = _waitQueue.begin(); it != _waitQueue.end(); ++it)
        {
            if (*it == pWI)
            {
                _waitQueue.erase(it);
                break;
            }
        }
    }
    delete pWI;
    return pNf.duplicate();
}
Example #2
0
Value ClusterEvents::NextNotificationChangedAPIHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params)
{
	Endpoint::Ptr endpoint = origin->FromClient->GetEndpoint();

	if (!endpoint) {
		Log(LogNotice, "ClusterEvents")
			<< "Discarding 'next notification changed' message from '" << origin->FromClient->GetIdentity() << "': Invalid endpoint origin (client not allowed).";
		return Empty;
	}

	Notification::Ptr notification = Notification::GetByName(params->Get("notification"));

	if (!notification)
		return Empty;

	if (origin->FromZone && !origin->FromZone->CanAccessObject(notification)) {
		Log(LogNotice, "ClusterEvents")
			<< "Discarding 'next notification changed' message for notification '" << notification->GetName()
			<< "' from '" << origin->FromClient->GetIdentity() << "': Unauthorized access.";
		return Empty;
	}

	double nextNotification = params->Get("next_notification");

	if (nextNotification < Utility::GetTime())
		return Empty;

	notification->SetNextNotification(nextNotification, false, origin);

	return Empty;
}
Example #3
0
void PluginNotificationTask::ScriptFunc(const Notification::Ptr& notification, const User::Ptr& user, const CheckResult::Ptr& cr, int itype,
    const String& author, const String& comment)
{
	NotificationCommand::Ptr commandObj = notification->GetCommand();

	NotificationType type = static_cast<NotificationType>(itype);

	Checkable::Ptr checkable = notification->GetCheckable();

	Dictionary::Ptr notificationExtra = make_shared<Dictionary>();
	notificationExtra->Set("type", Notification::NotificationTypeToString(type));
	notificationExtra->Set("author", author);
	notificationExtra->Set("comment", comment);

	Host::Ptr host;
	Service::Ptr service;
	tie(host, service) = GetHostService(checkable);

	MacroProcessor::ResolverList resolvers;
	resolvers.push_back(std::make_pair("user", user));
	resolvers.push_back(std::make_pair("notification", notificationExtra));
	resolvers.push_back(std::make_pair("notification", notification));
	if (service)
		resolvers.push_back(std::make_pair("service", service));
	resolvers.push_back(std::make_pair("host", host));
	resolvers.push_back(std::make_pair("command", commandObj));
	resolvers.push_back(std::make_pair("icinga", IcingaApplication::GetInstance()));

	PluginUtility::ExecuteCommand(commandObj, checkable, cr, resolvers, boost::bind(&PluginNotificationTask::ProcessFinishedHandler, checkable, _1, _2));
}
Notification* PriorityNotificationQueue::waitDequeueNotification()
{
    Notification::Ptr pNf;
    WaitInfo* pWI = 0;
    {
        FastMutex::ScopedLock lock(_mutex);
        pNf = dequeueOne();
        if (pNf) return pNf.duplicate();
        pWI = new WaitInfo;
        _waitQueue.push_back(pWI);
    }
    pWI->nfAvailable.wait();
    pNf = pWI->pNf;
    delete pWI;
    return pNf.duplicate();
}
Example #5
0
String NotificationNameComposer::MakeName(const String& shortName, const Object::Ptr& context) const
{
	Notification::Ptr notification = dynamic_pointer_cast<Notification>(context);

	if (!notification)
		return "";

	String name = notification->GetHostName();

	if (!notification->GetServiceName().IsEmpty())
		name += "!" + notification->GetServiceName();

	name += "!" + shortName;

	return name;
}
Example #6
0
void ClusterEvents::NotificationSentUserHandler(const Notification::Ptr& notification, const Checkable::Ptr& checkable, const User::Ptr& user,
	NotificationType notificationType, const CheckResult::Ptr& cr, const NotificationResult::Ptr& nr, const String& author, const String& commentText, const String& command,
	const MessageOrigin::Ptr& origin)
{
	ApiListener::Ptr listener = ApiListener::GetInstance();

	if (!listener)
		return;

	Host::Ptr host;
	Service::Ptr service;
	tie(host, service) = GetHostService(checkable);

	Dictionary::Ptr params = new Dictionary();
	params->Set("host", host->GetName());
	if (service)
		params->Set("service", service->GetShortName());
	params->Set("notification", notification->GetName());
	params->Set("user", user->GetName());
	params->Set("type", notificationType);
	params->Set("cr", Serialize(cr));
	params->Set("nr", Serialize(nr));
	params->Set("author", author);
	params->Set("text", commentText);
	params->Set("command", command);

	Dictionary::Ptr message = new Dictionary();
	message->Set("jsonrpc", "2.0");
	message->Set("method", "event::NotificationSentUser");
	message->Set("params", params);

	listener->RelayMessage(origin, nullptr, message, true);
}
Example #7
0
Notification* TimedNotificationQueue::dequeueNotification()
{
	FastMutex::ScopedLock lock(_mutex);

	NfQueue::iterator it = _nfQueue.begin();
	if (it != _nfQueue.end())
	{
		Clock::ClockDiff sleep = -it->first.elapsed();
		if (sleep <= 0)
		{
			Notification::Ptr pNf = it->second;
			_nfQueue.erase(it);
			return pNf.duplicate();
		}
	}
	return 0;
}
Example #8
0
void ClusterEvents::NextNotificationChangedHandler(const Notification::Ptr& notification, const MessageOrigin::Ptr& origin)
{
	ApiListener::Ptr listener = ApiListener::GetInstance();

	if (!listener)
		return;

	Dictionary::Ptr params = new Dictionary();
	params->Set("notification", notification->GetName());
	params->Set("next_notification", notification->GetNextNotification());

	Dictionary::Ptr message = new Dictionary();
	message->Set("jsonrpc", "2.0");
	message->Set("method", "event::SetNextNotification");
	message->Set("params", params);

	listener->RelayMessage(origin, notification, message, true);
}
void PluginNotificationTask::ScriptFunc(const Notification::Ptr& notification, const User::Ptr& user, const CheckResult::Ptr& cr, int itype,
    const String& author, const String& comment)
{
	NotificationCommand::Ptr commandObj = notification->GetNotificationCommand();

	NotificationType type = static_cast<NotificationType>(itype);

	Service::Ptr service = notification->GetService();

	Value raw_command = commandObj->GetCommandLine();

	StaticMacroResolver::Ptr notificationMacroResolver = make_shared<StaticMacroResolver>();
	notificationMacroResolver->Add("NOTIFICATIONTYPE", Notification::NotificationTypeToString(type));
	notificationMacroResolver->Add("NOTIFICATIONAUTHOR", author);
	notificationMacroResolver->Add("NOTIFICATIONAUTHORNAME", author);
	notificationMacroResolver->Add("NOTIFICATIONCOMMENT", comment);

	std::vector<MacroResolver::Ptr> resolvers;
	resolvers.push_back(user);
	resolvers.push_back(notificationMacroResolver);
	resolvers.push_back(notification);
	resolvers.push_back(service);
	resolvers.push_back(service->GetHost());
	resolvers.push_back(commandObj);
	resolvers.push_back(IcingaApplication::GetInstance());

	Value command = MacroProcessor::ResolveMacros(raw_command, resolvers, cr, Utility::EscapeShellCmd, commandObj->GetEscapeMacros());

	Dictionary::Ptr envMacros = make_shared<Dictionary>();

	Array::Ptr export_macros = commandObj->GetExportMacros();

	if (export_macros) {
		BOOST_FOREACH(const String& macro, export_macros) {
			String value;

			if (!MacroProcessor::ResolveMacro(macro, resolvers, cr, &value)) {
				Log(LogWarning, "icinga", "export_macros for notification '" + notification->GetName() + "' refers to unknown macro '" + macro + "'");
				continue;
			}

			envMacros->Set(macro, value);
		}
	}
void PluginNotificationTask::ScriptFunc(const Notification::Ptr& notification,
	const User::Ptr& user, const CheckResult::Ptr& cr, int itype,
	const String& author, const String& comment, const Dictionary::Ptr& resolvedMacros,
	bool useResolvedMacros)
{
	REQUIRE_NOT_NULL(notification);
	REQUIRE_NOT_NULL(user);

	NotificationCommand::Ptr commandObj = notification->GetCommand();

	auto type = static_cast<NotificationType>(itype);

	Checkable::Ptr checkable = notification->GetCheckable();

	Dictionary::Ptr notificationExtra = new Dictionary({
		{ "type", Notification::NotificationTypeToString(type) },
		{ "author", author },
		{ "comment", comment }
	});

	Host::Ptr host;
	Service::Ptr service;
	tie(host, service) = GetHostService(checkable);

	MacroProcessor::ResolverList resolvers;
	resolvers.emplace_back("user", user);
	resolvers.emplace_back("notification", notificationExtra);
	resolvers.emplace_back("notification", notification);
	if (service)
		resolvers.emplace_back("service", service);
	resolvers.emplace_back("host", host);
	resolvers.emplace_back("command", commandObj);
	resolvers.emplace_back("icinga", IcingaApplication::GetInstance());

	int timeout = commandObj->GetTimeout();

	PluginUtility::ExecuteCommand(commandObj, checkable, cr, resolvers,
		resolvedMacros, useResolvedMacros, timeout,
		std::bind(&PluginNotificationTask::ProcessFinishedHandler, checkable, _1, _2));
}
void DbEvents::LastNotificationChangedHandler(const Notification::Ptr& notification, const Checkable::Ptr& checkable)
{
	double now = Utility::GetTime();
	std::pair<unsigned long, unsigned long> now_bag = CompatUtility::ConvertTimestamp(now);
	std::pair<unsigned long, unsigned long> time_bag = CompatUtility::ConvertTimestamp(notification->GetNextNotification());

	Host::Ptr host;
	Service::Ptr service;
	tie(host, service) = GetHostService(checkable);

	DbQuery query1;
	if (service)
		query1.Table = "servicestatus";
	else
		query1.Table = "hoststatus";

	query1.Type = DbQueryUpdate;
	query1.Category = DbCatState;
	query1.StatusUpdate = true;
	query1.Object = DbObject::GetOrCreateByObject(checkable);

	Dictionary::Ptr fields1 = new Dictionary();
	fields1->Set("last_notification", DbValue::FromTimestamp(now_bag.first));
	fields1->Set("next_notification", DbValue::FromTimestamp(time_bag.first));
	fields1->Set("current_notification_number", notification->GetNotificationNumber());

	query1.Fields = fields1;

	query1.WhereCriteria = new Dictionary();
	if (service)
		query1.WhereCriteria->Set("service_object_id", service);
	else
		query1.WhereCriteria->Set("host_object_id", host);

	query1.WhereCriteria->Set("instance_id", 0); /* DbConnection class fills in real ID */

	DbObject::OnQuery(query1);
}
Example #12
0
void ClusterEvents::NotificationSentToAllUsersHandler(const Notification::Ptr& notification, const Checkable::Ptr& checkable, const std::set<User::Ptr>& users,
	NotificationType notificationType, const CheckResult::Ptr& cr, const String& author, const String& commentText, const MessageOrigin::Ptr& origin)
{
	ApiListener::Ptr listener = ApiListener::GetInstance();

	if (!listener)
		return;

	Host::Ptr host;
	Service::Ptr service;
	tie(host, service) = GetHostService(checkable);

	Dictionary::Ptr params = new Dictionary();
	params->Set("host", host->GetName());
	if (service)
		params->Set("service", service->GetShortName());
	params->Set("notification", notification->GetName());

	ArrayData ausers;
	for (const User::Ptr& user : users) {
		ausers.push_back(user->GetName());
	}
	params->Set("users", new Array(std::move(ausers)));

	params->Set("type", notificationType);
	params->Set("cr", Serialize(cr));
	params->Set("author", author);
	params->Set("text", commentText);

	params->Set("last_notification", notification->GetLastNotification());
	params->Set("next_notification", notification->GetNextNotification());
	params->Set("notification_number", notification->GetNotificationNumber());
	params->Set("last_problem_notification", notification->GetLastProblemNotification());
	params->Set("no_more_notifications", notification->GetNoMoreNotifications());

	Dictionary::Ptr message = new Dictionary();
	message->Set("jsonrpc", "2.0");
	message->Set("method", "event::NotificationSentToAllUsers");
	message->Set("params", params);

	listener->RelayMessage(origin, nullptr, message, true);
}
Example #13
0
Value ClusterEvents::NotificationSentToAllUsersAPIHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params)
{
	Endpoint::Ptr endpoint = origin->FromClient->GetEndpoint();

	if (!endpoint) {
		Log(LogNotice, "ClusterEvents")
			<< "Discarding 'sent notification to all users' message from '" << origin->FromClient->GetIdentity() << "': Invalid endpoint origin (client not allowed).";
		return Empty;
	}

	Host::Ptr host = Host::GetByName(params->Get("host"));

	if (!host)
		return Empty;

	Checkable::Ptr checkable;

	if (params->Contains("service"))
		checkable = host->GetServiceByShortName(params->Get("service"));
	else
		checkable = host;

	if (!checkable)
		return Empty;

	if (origin->FromZone && origin->FromZone != Zone::GetLocalZone()) {
		Log(LogNotice, "ClusterEvents")
			<< "Discarding 'sent notification to all users' message for checkable '" << checkable->GetName()
			<< "' from '" << origin->FromClient->GetIdentity() << "': Unauthorized access.";
		return Empty;
	}

	CheckResult::Ptr cr;
	Array::Ptr vperf;

	if (params->Contains("cr")) {
		cr = new CheckResult();
		Dictionary::Ptr vcr = params->Get("cr");

		if (vcr && vcr->Contains("performance_data")) {
			vperf = vcr->Get("performance_data");

			if (vperf)
				vcr->Remove("performance_data");

			Deserialize(cr, vcr, true);
		}
	}

	NotificationType type = static_cast<NotificationType>(static_cast<int>(params->Get("type")));
	String author = params->Get("author");
	String text = params->Get("text");

	Notification::Ptr notification = Notification::GetByName(params->Get("notification"));

	if (!notification)
		return Empty;

	Array::Ptr ausers = params->Get("users");

	if (!ausers)
		return Empty;

	std::set<User::Ptr> users;

	{
		ObjectLock olock(ausers);
		for (const String& auser : ausers) {
			User::Ptr user = User::GetByName(auser);

			if (!user)
				continue;

			users.insert(user);
		}
	}

	notification->SetLastNotification(params->Get("last_notification"));
	notification->SetNextNotification(params->Get("next_notification"));
	notification->SetNotificationNumber(params->Get("notification_number"));
	notification->SetLastProblemNotification(params->Get("last_problem_notification"));
	notification->SetNoMoreNotifications(params->Get("no_more_notifications"));

	ArrayData notifiedProblemUsers;
	for (const User::Ptr& user : users) {
		notifiedProblemUsers.push_back(user->GetName());
	}

	notification->SetNotifiedProblemUsers(new Array(std::move(notifiedProblemUsers)));

	Checkable::OnNotificationSentToAllUsers(notification, checkable, users, type, cr, author, text, origin);

	return Empty;
}