From 0251df22d574aeb0cb9606ad645f1f6c5f718762 Mon Sep 17 00:00:00 2001 From: Mattia Codato Date: Tue, 21 Jul 2020 13:27:03 +0200 Subject: [PATCH] Implement notification execution --- lib/icinga/apiactions.cpp | 8 +++-- lib/icinga/clusterevents-check.cpp | 56 ++++++++++++++++++++++++++++-- 2 files changed, 59 insertions(+), 5 deletions(-) diff --git a/lib/icinga/apiactions.cpp b/lib/icinga/apiactions.cpp index 756a8ca76..02b0e451d 100644 --- a/lib/icinga/apiactions.cpp +++ b/lib/icinga/apiactions.cpp @@ -646,6 +646,9 @@ Dictionary::Ptr ApiActions::ExecuteCommand(const ConfigObject::Ptr& object, MacroResolver::OverrideMacros = nullptr; }); + /* Create execution parameters */ + Dictionary::Ptr execParams = new Dictionary(); + if (command_type == "CheckCommand") { CheckCommand::Ptr cmd = GetSingleObjectByNameUsingPermissions(CheckCommand::GetTypeName(), resolved_command, ActionsHandler::AuthenticatedApiUser); if (!cmd) @@ -677,6 +680,7 @@ Dictionary::Ptr ApiActions::ExecuteCommand(const ConfigObject::Ptr& object, User::Ptr user = GetSingleObjectByNameUsingPermissions(User::GetTypeName(), resolved_user, ActionsHandler::AuthenticatedApiUser); if (!user) return ApiActions::CreateResult(404, "Can't find a valid user for '" + resolved_user + "'."); + execParams->Set("user", user->GetName()); /* Get notification */ String notification_string = ""; @@ -692,6 +696,7 @@ Dictionary::Ptr ApiActions::ExecuteCommand(const ConfigObject::Ptr& object, Notification::Ptr notification = GetSingleObjectByNameUsingPermissions(Notification::GetTypeName(), resolved_notification, ActionsHandler::AuthenticatedApiUser); if (!notification) return ApiActions::CreateResult(404, "Can't find a valid notification for '" + resolved_notification + "'."); + execParams->Set("notification", notification->GetName()); cmd->Execute(notification, user, cr, NotificationType::NotificationCustom, ActionsHandler::AuthenticatedApiUser->GetName(), "", execMacros, false); @@ -731,8 +736,7 @@ Dictionary::Ptr ApiActions::ExecuteCommand(const ConfigObject::Ptr& object, MessageOrigin::Ptr origin = new MessageOrigin(); listener->RelayMessage(origin, checkable, updateMessage, true); - /* Create execution parameters */ - Dictionary::Ptr execParams = new Dictionary(); + /* Populate execution parameters */ if (command_type == "CheckCommand") execParams->Set("command_type", "check_command"); else if (command_type == "EventCommand") diff --git a/lib/icinga/clusterevents-check.cpp b/lib/icinga/clusterevents-check.cpp index 11143cd84..b7105066c 100644 --- a/lib/icinga/clusterevents-check.cpp +++ b/lib/icinga/clusterevents-check.cpp @@ -233,11 +233,16 @@ void ClusterEvents::ExecuteCheckFromQueue(const MessageOrigin::Ptr& origin, cons } else if (command_type == "event_command") { if (!EventCommand::GetByName(command)) { Log(LogWarning, "ClusterEvents") - << "Event command '" << command << "' does not exist."; + << "Event command '" << command << "' does not exist."; return; } - } else - return; + } else if (command_type == "notification_command") { + if (!NotificationCommand::GetByName(command)) { + Log(LogWarning, "ClusterEvents") + << "Notification command '" << command << "' does not exist."; + return; + } + } attrs->Set(command_type, params->Get("command")); attrs->Set("command_endpoint", sourceEndpoint->GetName()); @@ -271,6 +276,51 @@ void ClusterEvents::ExecuteCheckFromQueue(const MessageOrigin::Ptr& origin, cons } } else if (command_type == "event_command") { host->ExecuteEventHandler(macros, true); + } else if (command_type == "notification_command") { + /* Get user */ + User::Ptr user = new User(); + Dictionary::Ptr attrs = new Dictionary(); + attrs->Set("__name", params->Get("user")); + attrs->Set("type", User::GetTypeName()); + + Deserialize(user, attrs, false, FAConfig); + + /* Get notification */ + Notification::Ptr notification = new Notification(); + attrs->Clear(); + attrs->Set("__name", params->Get("notification")); + attrs->Set("type", Notification::GetTypeName()); + attrs->Set("command", command); + + Deserialize(notification, attrs, false, FAConfig); + + try { + CheckResult::Ptr cr = new CheckResult(); + String author = macros->Get("notification_author"); + NotificationCommand::Ptr notificationCommand = NotificationCommand::GetByName(command); + + notificationCommand->Execute(notification, user, cr, NotificationType::NotificationCustom, + author, ""); + } catch (const std::exception& ex) { + String output = "Exception occurred during notification '" + notification->GetName() + + "' for checkable '" + notification->GetCheckable()->GetName() + + "' and user '" + user->GetName() + "' using command '" + command + "': " + + DiagnosticInformation(ex, false); + double now = Utility::GetTime(); + + CheckResult::Ptr cr = new CheckResult(); + cr->SetState(ServiceUnknown); + cr->SetOutput(output); + cr->SetScheduleStart(now); + cr->SetScheduleEnd(now); + cr->SetExecutionStart(now); + cr->SetExecutionEnd(now); + + Dictionary::Ptr message = MakeCheckResultMessage(host, cr); + listener->SyncSendMessage(sourceEndpoint, message); + + Log(LogCritical, "checker", output); + } } }