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(); }
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; }
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(); }
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; }
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); }
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; }
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); }
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); }
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; }