From 56ae875861ab260b80a030f50c4aff9f9dc8fff0 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 13 Apr 2024 13:32:39 +0200 Subject: Adding upstream version 2.14.2. Signed-off-by: Daniel Baumann --- lib/icinga/apievents.cpp | 438 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 438 insertions(+) create mode 100644 lib/icinga/apievents.cpp (limited to 'lib/icinga/apievents.cpp') diff --git a/lib/icinga/apievents.cpp b/lib/icinga/apievents.cpp new file mode 100644 index 0000000..53008fd --- /dev/null +++ b/lib/icinga/apievents.cpp @@ -0,0 +1,438 @@ +/* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */ + +#include "icinga/apievents.hpp" +#include "icinga/service.hpp" +#include "icinga/notificationcommand.hpp" +#include "base/initialize.hpp" +#include "base/serializer.hpp" +#include "base/logger.hpp" + +using namespace icinga; + +INITIALIZE_ONCE(&ApiEvents::StaticInitialize); + +void ApiEvents::StaticInitialize() +{ + Checkable::OnNewCheckResult.connect(&ApiEvents::CheckResultHandler); + Checkable::OnStateChange.connect(&ApiEvents::StateChangeHandler); + Checkable::OnNotificationSentToAllUsers.connect(&ApiEvents::NotificationSentToAllUsersHandler); + + Checkable::OnFlappingChanged.connect(&ApiEvents::FlappingChangedHandler); + + Checkable::OnAcknowledgementSet.connect(&ApiEvents::AcknowledgementSetHandler); + Checkable::OnAcknowledgementCleared.connect(&ApiEvents::AcknowledgementClearedHandler); + + Comment::OnCommentAdded.connect(&ApiEvents::CommentAddedHandler); + Comment::OnCommentRemoved.connect(&ApiEvents::CommentRemovedHandler); + + Downtime::OnDowntimeAdded.connect(&ApiEvents::DowntimeAddedHandler); + Downtime::OnDowntimeRemoved.connect(&ApiEvents::DowntimeRemovedHandler); + Downtime::OnDowntimeStarted.connect(&ApiEvents::DowntimeStartedHandler); + Downtime::OnDowntimeTriggered.connect(&ApiEvents::DowntimeTriggeredHandler); + + ConfigObject::OnActiveChanged.connect(&ApiEvents::OnActiveChangedHandler); + ConfigObject::OnVersionChanged.connect(&ApiEvents::OnVersionChangedHandler); +} + +void ApiEvents::CheckResultHandler(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr, const MessageOrigin::Ptr& origin) +{ + std::vector queues = EventQueue::GetQueuesForType("CheckResult"); + auto inboxes (EventsRouter::GetInstance().GetInboxes(EventType::CheckResult)); + + if (queues.empty() && !inboxes) + return; + + Log(LogDebug, "ApiEvents", "Processing event type 'CheckResult'."); + + Dictionary::Ptr result = new Dictionary(); + result->Set("type", "CheckResult"); + result->Set("timestamp", Utility::GetTime()); + + Host::Ptr host; + Service::Ptr service; + tie(host, service) = GetHostService(checkable); + + result->Set("host", host->GetName()); + if (service) + result->Set("service", service->GetShortName()); + + result->Set("check_result", Serialize(cr)); + + result->Set("downtime_depth", checkable->GetDowntimeDepth()); + result->Set("acknowledgement", checkable->IsAcknowledged()); + + for (const EventQueue::Ptr& queue : queues) { + queue->ProcessEvent(result); + } + + inboxes.Push(std::move(result)); +} + +void ApiEvents::StateChangeHandler(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr, StateType type, const MessageOrigin::Ptr& origin) +{ + std::vector queues = EventQueue::GetQueuesForType("StateChange"); + auto inboxes (EventsRouter::GetInstance().GetInboxes(EventType::StateChange)); + + if (queues.empty() && !inboxes) + return; + + Log(LogDebug, "ApiEvents", "Processing event type 'StateChange'."); + + Dictionary::Ptr result = new Dictionary(); + result->Set("type", "StateChange"); + result->Set("timestamp", Utility::GetTime()); + + Host::Ptr host; + Service::Ptr service; + tie(host, service) = GetHostService(checkable); + + result->Set("host", host->GetName()); + if (service) + result->Set("service", service->GetShortName()); + + result->Set("state", service ? static_cast(service->GetState()) : static_cast(host->GetState())); + result->Set("state_type", checkable->GetStateType()); + result->Set("check_result", Serialize(cr)); + + result->Set("downtime_depth", checkable->GetDowntimeDepth()); + result->Set("acknowledgement", checkable->IsAcknowledged()); + + for (const EventQueue::Ptr& queue : queues) { + queue->ProcessEvent(result); + } + + inboxes.Push(std::move(result)); +} + +void ApiEvents::NotificationSentToAllUsersHandler(const Notification::Ptr& notification, + const Checkable::Ptr& checkable, const std::set& users, NotificationType type, + const CheckResult::Ptr& cr, const String& author, const String& text, const MessageOrigin::Ptr& origin) +{ + std::vector queues = EventQueue::GetQueuesForType("Notification"); + auto inboxes (EventsRouter::GetInstance().GetInboxes(EventType::Notification)); + + if (queues.empty() && !inboxes) + return; + + Log(LogDebug, "ApiEvents", "Processing event type 'Notification'."); + + Dictionary::Ptr result = new Dictionary(); + result->Set("type", "Notification"); + result->Set("timestamp", Utility::GetTime()); + + Host::Ptr host; + Service::Ptr service; + tie(host, service) = GetHostService(checkable); + + result->Set("host", host->GetName()); + if (service) + result->Set("service", service->GetShortName()); + + NotificationCommand::Ptr command = notification->GetCommand(); + + if (command) + result->Set("command", command->GetName()); + + ArrayData userNames; + + for (const User::Ptr& user : users) { + userNames.push_back(user->GetName()); + } + + result->Set("users", new Array(std::move(userNames))); + result->Set("notification_type", Notification::NotificationTypeToStringCompat(type)); //TODO: Change this to our own types. + result->Set("author", author); + result->Set("text", text); + result->Set("check_result", Serialize(cr)); + + for (const EventQueue::Ptr& queue : queues) { + queue->ProcessEvent(result); + } + + inboxes.Push(std::move(result)); +} + +void ApiEvents::FlappingChangedHandler(const Checkable::Ptr& checkable, const MessageOrigin::Ptr& origin) +{ + std::vector queues = EventQueue::GetQueuesForType("Flapping"); + auto inboxes (EventsRouter::GetInstance().GetInboxes(EventType::Flapping)); + + if (queues.empty() && !inboxes) + return; + + Log(LogDebug, "ApiEvents", "Processing event type 'Flapping'."); + + Dictionary::Ptr result = new Dictionary(); + result->Set("type", "Flapping"); + result->Set("timestamp", Utility::GetTime()); + + Host::Ptr host; + Service::Ptr service; + tie(host, service) = GetHostService(checkable); + + result->Set("host", host->GetName()); + if (service) + result->Set("service", service->GetShortName()); + + result->Set("state", service ? static_cast(service->GetState()) : static_cast(host->GetState())); + result->Set("state_type", checkable->GetStateType()); + result->Set("is_flapping", checkable->IsFlapping()); + result->Set("flapping_current", checkable->GetFlappingCurrent()); + result->Set("threshold_low", checkable->GetFlappingThresholdLow()); + result->Set("threshold_high", checkable->GetFlappingThresholdHigh()); + + for (const EventQueue::Ptr& queue : queues) { + queue->ProcessEvent(result); + } + + inboxes.Push(std::move(result)); +} + +void ApiEvents::AcknowledgementSetHandler(const Checkable::Ptr& checkable, + const String& author, const String& comment, AcknowledgementType type, + bool notify, bool persistent, double, double expiry, const MessageOrigin::Ptr& origin) +{ + std::vector queues = EventQueue::GetQueuesForType("AcknowledgementSet"); + auto inboxes (EventsRouter::GetInstance().GetInboxes(EventType::AcknowledgementSet)); + + if (queues.empty() && !inboxes) + return; + + Log(LogDebug, "ApiEvents", "Processing event type 'AcknowledgementSet'."); + + Dictionary::Ptr result = new Dictionary(); + result->Set("type", "AcknowledgementSet"); + result->Set("timestamp", Utility::GetTime()); + + Host::Ptr host; + Service::Ptr service; + tie(host, service) = GetHostService(checkable); + + result->Set("host", host->GetName()); + if (service) + result->Set("service", service->GetShortName()); + + result->Set("state", service ? static_cast(service->GetState()) : static_cast(host->GetState())); + result->Set("state_type", checkable->GetStateType()); + + result->Set("author", author); + result->Set("comment", comment); + result->Set("acknowledgement_type", type); + result->Set("notify", notify); + result->Set("persistent", persistent); + result->Set("expiry", expiry); + + for (const EventQueue::Ptr& queue : queues) { + queue->ProcessEvent(result); + } + + inboxes.Push(std::move(result)); +} + +void ApiEvents::AcknowledgementClearedHandler(const Checkable::Ptr& checkable, const String& removedBy, double, const MessageOrigin::Ptr& origin) +{ + std::vector queues = EventQueue::GetQueuesForType("AcknowledgementCleared"); + auto inboxes (EventsRouter::GetInstance().GetInboxes(EventType::AcknowledgementCleared)); + + if (queues.empty() && !inboxes) + return; + + Log(LogDebug, "ApiEvents", "Processing event type 'AcknowledgementCleared'."); + + Dictionary::Ptr result = new Dictionary(); + result->Set("type", "AcknowledgementCleared"); + result->Set("timestamp", Utility::GetTime()); + + Host::Ptr host; + Service::Ptr service; + tie(host, service) = GetHostService(checkable); + + result->Set("host", host->GetName()); + if (service) + result->Set("service", service->GetShortName()); + + result->Set("state", service ? static_cast(service->GetState()) : static_cast(host->GetState())); + result->Set("state_type", checkable->GetStateType()); + result->Set("acknowledgement_type", AcknowledgementNone); + + for (const EventQueue::Ptr& queue : queues) { + queue->ProcessEvent(result); + } + + inboxes.Push(std::move(result)); +} + +void ApiEvents::CommentAddedHandler(const Comment::Ptr& comment) +{ + std::vector queues = EventQueue::GetQueuesForType("CommentAdded"); + auto inboxes (EventsRouter::GetInstance().GetInboxes(EventType::CommentAdded)); + + if (queues.empty() && !inboxes) + return; + + Log(LogDebug, "ApiEvents", "Processing event type 'CommentAdded'."); + + Dictionary::Ptr result = new Dictionary({ + { "type", "CommentAdded" }, + { "timestamp", Utility::GetTime() }, + { "comment", Serialize(comment, FAConfig | FAState) } + }); + + for (const EventQueue::Ptr& queue : queues) { + queue->ProcessEvent(result); + } + + inboxes.Push(std::move(result)); +} + +void ApiEvents::CommentRemovedHandler(const Comment::Ptr& comment) +{ + std::vector queues = EventQueue::GetQueuesForType("CommentRemoved"); + auto inboxes (EventsRouter::GetInstance().GetInboxes(EventType::CommentRemoved)); + + if (queues.empty() && !inboxes) + return; + + Log(LogDebug, "ApiEvents", "Processing event type 'CommentRemoved'."); + + Dictionary::Ptr result = new Dictionary({ + { "type", "CommentRemoved" }, + { "timestamp", Utility::GetTime() }, + { "comment", Serialize(comment, FAConfig | FAState) } + }); + + for (const EventQueue::Ptr& queue : queues) { + queue->ProcessEvent(result); + } + + inboxes.Push(std::move(result)); +} + +void ApiEvents::DowntimeAddedHandler(const Downtime::Ptr& downtime) +{ + std::vector queues = EventQueue::GetQueuesForType("DowntimeAdded"); + auto inboxes (EventsRouter::GetInstance().GetInboxes(EventType::DowntimeAdded)); + + if (queues.empty() && !inboxes) + return; + + Log(LogDebug, "ApiEvents", "Processing event type 'DowntimeAdded'."); + + Dictionary::Ptr result = new Dictionary({ + { "type", "DowntimeAdded" }, + { "timestamp", Utility::GetTime() }, + { "downtime", Serialize(downtime, FAConfig | FAState) } + }); + + for (const EventQueue::Ptr& queue : queues) { + queue->ProcessEvent(result); + } + + inboxes.Push(std::move(result)); +} + +void ApiEvents::DowntimeRemovedHandler(const Downtime::Ptr& downtime) +{ + std::vector queues = EventQueue::GetQueuesForType("DowntimeRemoved"); + auto inboxes (EventsRouter::GetInstance().GetInboxes(EventType::DowntimeRemoved)); + + if (queues.empty() && !inboxes) + return; + + Log(LogDebug, "ApiEvents", "Processing event type 'DowntimeRemoved'."); + + Dictionary::Ptr result = new Dictionary({ + { "type", "DowntimeRemoved" }, + { "timestamp", Utility::GetTime() }, + { "downtime", Serialize(downtime, FAConfig | FAState) } + }); + + for (const EventQueue::Ptr& queue : queues) { + queue->ProcessEvent(result); + } + + inboxes.Push(std::move(result)); +} + +void ApiEvents::DowntimeStartedHandler(const Downtime::Ptr& downtime) +{ + std::vector queues = EventQueue::GetQueuesForType("DowntimeStarted"); + auto inboxes (EventsRouter::GetInstance().GetInboxes(EventType::DowntimeStarted)); + + if (queues.empty() && !inboxes) + return; + + Log(LogDebug, "ApiEvents", "Processing event type 'DowntimeStarted'."); + + Dictionary::Ptr result = new Dictionary({ + { "type", "DowntimeStarted" }, + { "timestamp", Utility::GetTime() }, + { "downtime", Serialize(downtime, FAConfig | FAState) } + }); + + for (const EventQueue::Ptr& queue : queues) { + queue->ProcessEvent(result); + } + + inboxes.Push(std::move(result)); +} + +void ApiEvents::DowntimeTriggeredHandler(const Downtime::Ptr& downtime) +{ + std::vector queues = EventQueue::GetQueuesForType("DowntimeTriggered"); + auto inboxes (EventsRouter::GetInstance().GetInboxes(EventType::DowntimeTriggered)); + + if (queues.empty() && !inboxes) + return; + + Log(LogDebug, "ApiEvents", "Processing event type 'DowntimeTriggered'."); + + Dictionary::Ptr result = new Dictionary({ + { "type", "DowntimeTriggered" }, + { "timestamp", Utility::GetTime() }, + { "downtime", Serialize(downtime, FAConfig | FAState) } + }); + + for (const EventQueue::Ptr& queue : queues) { + queue->ProcessEvent(result); + } + + inboxes.Push(std::move(result)); +} + +void ApiEvents::OnActiveChangedHandler(const ConfigObject::Ptr& object, const Value&) +{ + if (object->IsActive()) { + ApiEvents::SendObjectChangeEvent(object, EventType::ObjectCreated, "ObjectCreated"); + } else if (!object->IsActive() && !object->GetExtension("ConfigObjectDeleted").IsEmpty()) { + ApiEvents::SendObjectChangeEvent(object, EventType::ObjectDeleted, "ObjectDeleted"); + } +} + +void ApiEvents::OnVersionChangedHandler(const ConfigObject::Ptr& object, const Value&) +{ + ApiEvents::SendObjectChangeEvent(object, EventType::ObjectModified, "ObjectModified"); +} + +void ApiEvents::SendObjectChangeEvent(const ConfigObject::Ptr& object, const EventType& eventType, const String& eventQueue) { + std::vector queues = EventQueue::GetQueuesForType(eventQueue); + auto inboxes (EventsRouter::GetInstance().GetInboxes(eventType)); + + if (queues.empty() && !inboxes) + return; + + Log(LogDebug, "ApiEvents") << "Processing event type '" + eventQueue + "'."; + + Dictionary::Ptr result = new Dictionary ({ + {"type", eventQueue}, + {"timestamp", Utility::GetTime()}, + {"object_type", object->GetReflectionType()->GetName()}, + {"object_name", object->GetName()}, + }); + + for (const EventQueue::Ptr& queue : queues) { + queue->ProcessEvent(result); + } + + inboxes.Push(std::move(result)); +} -- cgit v1.2.3