diff --git a/lib/icinga/apiactions.cpp b/lib/icinga/apiactions.cpp index 97561397e..e7d8acd88 100644 --- a/lib/icinga/apiactions.cpp +++ b/lib/icinga/apiactions.cpp @@ -686,14 +686,24 @@ Dictionary::Ptr ApiActions::ExecuteCommand(const ConfigObject::Ptr& object, CheckCommand::Ptr cmd = GetSingleObjectByNameUsingPermissions(CheckCommand::GetTypeName(), resolved_command, ActionsHandler::AuthenticatedApiUser); if (!cmd) return ApiActions::CreateResult(404, "Can't find a valid " + command_type + " for '" + resolved_command + "'."); - else + else { + CheckCommand::ExecuteOverride = cmd; + Defer resetCheckCommandOverride([]() { + CheckCommand::ExecuteOverride = nullptr; + }); cmd->Execute(checkable, cr, execMacros, false); + } } else if (command_type == "EventCommand") { EventCommand::Ptr cmd = GetSingleObjectByNameUsingPermissions(EventCommand::GetTypeName(), resolved_command, ActionsHandler::AuthenticatedApiUser); if (!cmd) return ApiActions::CreateResult(404, "Can't find a valid " + command_type + " for '" + resolved_command + "'."); - else + else { + EventCommand::ExecuteOverride = cmd; + Defer resetCheckCommandOverride([]() { + EventCommand::ExecuteOverride = nullptr; + }); cmd->Execute(checkable, execMacros, false); + } } else if (command_type == "NotificationCommand") { NotificationCommand::Ptr cmd = GetSingleObjectByNameUsingPermissions(NotificationCommand::GetTypeName(), resolved_command, ActionsHandler::AuthenticatedApiUser); if (!cmd) @@ -731,6 +741,11 @@ Dictionary::Ptr ApiActions::ExecuteCommand(const ConfigObject::Ptr& object, return ApiActions::CreateResult(404, "Can't find a valid notification for '" + resolved_notification + "'."); execParams->Set("notification", notification->GetName()); + NotificationCommand::ExecuteOverride = cmd; + Defer resetCheckCommandOverride([]() { + NotificationCommand::ExecuteOverride = nullptr; + }); + cmd->Execute(notification, user, cr, NotificationType::NotificationCustom, ActionsHandler::AuthenticatedApiUser->GetName(), "", execMacros, false); } diff --git a/lib/icinga/checkcommand.cpp b/lib/icinga/checkcommand.cpp index e0da41547..fb8032a19 100644 --- a/lib/icinga/checkcommand.cpp +++ b/lib/icinga/checkcommand.cpp @@ -8,6 +8,8 @@ using namespace icinga; REGISTER_TYPE(CheckCommand); +thread_local CheckCommand::Ptr CheckCommand::ExecuteOverride; + void CheckCommand::Execute(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros) { diff --git a/lib/icinga/checkcommand.hpp b/lib/icinga/checkcommand.hpp index 6eb6119a3..eb8f5a012 100644 --- a/lib/icinga/checkcommand.hpp +++ b/lib/icinga/checkcommand.hpp @@ -20,6 +20,8 @@ public: DECLARE_OBJECT(CheckCommand); DECLARE_OBJECTNAME(CheckCommand); + static thread_local CheckCommand::Ptr ExecuteOverride; + virtual void Execute(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr, const Dictionary::Ptr& resolvedMacros = nullptr, bool useResolvedMacros = false); diff --git a/lib/icinga/eventcommand.cpp b/lib/icinga/eventcommand.cpp index f9ab3be19..39f2d3126 100644 --- a/lib/icinga/eventcommand.cpp +++ b/lib/icinga/eventcommand.cpp @@ -7,6 +7,8 @@ using namespace icinga; REGISTER_TYPE(EventCommand); +thread_local EventCommand::Ptr EventCommand::ExecuteOverride; + void EventCommand::Execute(const Checkable::Ptr& checkable, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros) { diff --git a/lib/icinga/eventcommand.hpp b/lib/icinga/eventcommand.hpp index 95bd1095a..064cb5ad0 100644 --- a/lib/icinga/eventcommand.hpp +++ b/lib/icinga/eventcommand.hpp @@ -20,6 +20,8 @@ public: DECLARE_OBJECT(EventCommand); DECLARE_OBJECTNAME(EventCommand); + static thread_local EventCommand::Ptr ExecuteOverride; + virtual void Execute(const Checkable::Ptr& checkable, const Dictionary::Ptr& resolvedMacros = nullptr, bool useResolvedMacros = false); diff --git a/lib/icinga/notificationcommand.cpp b/lib/icinga/notificationcommand.cpp index 8ae3e82a5..d4a5fd6ab 100644 --- a/lib/icinga/notificationcommand.cpp +++ b/lib/icinga/notificationcommand.cpp @@ -7,6 +7,8 @@ using namespace icinga; REGISTER_TYPE(NotificationCommand); +thread_local NotificationCommand::Ptr NotificationCommand::ExecuteOverride; + Dictionary::Ptr NotificationCommand::Execute(const Notification::Ptr& notification, const User::Ptr& user, const CheckResult::Ptr& cr, const NotificationType& type, const String& author, const String& comment, const Dictionary::Ptr& resolvedMacros, diff --git a/lib/icinga/notificationcommand.hpp b/lib/icinga/notificationcommand.hpp index 210c91e86..f0f6899e3 100644 --- a/lib/icinga/notificationcommand.hpp +++ b/lib/icinga/notificationcommand.hpp @@ -22,6 +22,8 @@ public: DECLARE_OBJECT(NotificationCommand); DECLARE_OBJECTNAME(NotificationCommand); + static thread_local NotificationCommand::Ptr ExecuteOverride; + virtual Dictionary::Ptr Execute(const intrusive_ptr& notification, const User::Ptr& user, const CheckResult::Ptr& cr, const NotificationType& type, const String& author, const String& comment, diff --git a/lib/methods/clusterchecktask.cpp b/lib/methods/clusterchecktask.cpp index ddefa9f84..1fb02633d 100644 --- a/lib/methods/clusterchecktask.cpp +++ b/lib/methods/clusterchecktask.cpp @@ -28,7 +28,11 @@ void ClusterCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckRe if (resolvedMacros && !useResolvedMacros) return; - CheckCommand::Ptr command = checkable->GetCheckCommand(); + CheckCommand::Ptr command; + if (CheckCommand::ExecuteOverride) + command = CheckCommand::ExecuteOverride; + else + command = checkable->GetCheckCommand(); String commandName = command->GetName(); ApiListener::Ptr listener = ApiListener::GetInstance(); diff --git a/lib/methods/clusterzonechecktask.cpp b/lib/methods/clusterzonechecktask.cpp index 8b9d771e4..024288ed7 100644 --- a/lib/methods/clusterzonechecktask.cpp +++ b/lib/methods/clusterzonechecktask.cpp @@ -21,7 +21,11 @@ void ClusterZoneCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const Che REQUIRE_NOT_NULL(cr); ApiListener::Ptr listener = ApiListener::GetInstance(); - CheckCommand::Ptr command = checkable->GetCheckCommand(); + CheckCommand::Ptr command; + if (CheckCommand::ExecuteOverride) + command = CheckCommand::ExecuteOverride; + else + command = checkable->GetCheckCommand(); String commandName = command->GetName(); if (!listener) { diff --git a/lib/methods/dummychecktask.cpp b/lib/methods/dummychecktask.cpp index 56bdb790a..ae44a1d63 100644 --- a/lib/methods/dummychecktask.cpp +++ b/lib/methods/dummychecktask.cpp @@ -22,7 +22,11 @@ void DummyCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResu REQUIRE_NOT_NULL(checkable); REQUIRE_NOT_NULL(cr); - CheckCommand::Ptr command = checkable->GetCheckCommand(); + CheckCommand::Ptr command; + if (CheckCommand::ExecuteOverride) + command = CheckCommand::ExecuteOverride; + else + command = checkable->GetCheckCommand(); Host::Ptr host; Service::Ptr service; diff --git a/lib/methods/icingachecktask.cpp b/lib/methods/icingachecktask.cpp index 9901ebd3a..efbdcc3c9 100644 --- a/lib/methods/icingachecktask.cpp +++ b/lib/methods/icingachecktask.cpp @@ -26,7 +26,11 @@ void IcingaCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckRes REQUIRE_NOT_NULL(checkable); REQUIRE_NOT_NULL(cr); - CheckCommand::Ptr command = checkable->GetCheckCommand(); + CheckCommand::Ptr command; + if (CheckCommand::ExecuteOverride) + command = CheckCommand::ExecuteOverride; + else + command = checkable->GetCheckCommand(); Host::Ptr host; Service::Ptr service; diff --git a/lib/methods/pluginchecktask.cpp b/lib/methods/pluginchecktask.cpp index 9dcbd7936..0825bf1b4 100644 --- a/lib/methods/pluginchecktask.cpp +++ b/lib/methods/pluginchecktask.cpp @@ -22,7 +22,11 @@ void PluginCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckRes REQUIRE_NOT_NULL(checkable); REQUIRE_NOT_NULL(cr); - CheckCommand::Ptr commandObj = checkable->GetCheckCommand(); + CheckCommand::Ptr commandObj; + if (CheckCommand::ExecuteOverride) + commandObj = CheckCommand::ExecuteOverride; + else + commandObj = checkable->GetCheckCommand(); Host::Ptr host; Service::Ptr service; diff --git a/lib/methods/plugineventtask.cpp b/lib/methods/plugineventtask.cpp index f511480f7..7a7932a9d 100644 --- a/lib/methods/plugineventtask.cpp +++ b/lib/methods/plugineventtask.cpp @@ -21,7 +21,11 @@ void PluginEventTask::ScriptFunc(const Checkable::Ptr& checkable, { REQUIRE_NOT_NULL(checkable); - EventCommand::Ptr commandObj = checkable->GetEventCommand(); + EventCommand::Ptr commandObj; + if (EventCommand::ExecuteOverride) + commandObj = EventCommand::ExecuteOverride; + else + commandObj = checkable->GetEventCommand(); Host::Ptr host; Service::Ptr service; diff --git a/lib/methods/pluginnotificationtask.cpp b/lib/methods/pluginnotificationtask.cpp index c1eb2e3d4..79485bab2 100644 --- a/lib/methods/pluginnotificationtask.cpp +++ b/lib/methods/pluginnotificationtask.cpp @@ -25,7 +25,11 @@ void PluginNotificationTask::ScriptFunc(const Notification::Ptr& notification, REQUIRE_NOT_NULL(notification); REQUIRE_NOT_NULL(user); - NotificationCommand::Ptr commandObj = notification->GetCommand(); + NotificationCommand::Ptr commandObj; + if (NotificationCommand::ExecuteOverride) + commandObj = NotificationCommand::ExecuteOverride; + else + commandObj = notification->GetCommand(); auto type = static_cast(itype); diff --git a/lib/methods/randomchecktask.cpp b/lib/methods/randomchecktask.cpp index 0e138ffa5..083d07516 100644 --- a/lib/methods/randomchecktask.cpp +++ b/lib/methods/randomchecktask.cpp @@ -31,7 +31,11 @@ void RandomCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckRes + ". Icinga 2 has been running for " + Utility::FormatDuration(uptime) + ". Version: " + Application::GetAppVersion(); - CheckCommand::Ptr command = checkable->GetCheckCommand(); + CheckCommand::Ptr command; + if (CheckCommand::ExecuteOverride) + command = CheckCommand::ExecuteOverride; + else + command = checkable->GetCheckCommand(); String commandName = command->GetName(); ServiceState state = static_cast(Utility::Random() % 4); diff --git a/lib/methods/sleepchecktask.cpp b/lib/methods/sleepchecktask.cpp index 30a395c00..a3e62d133 100644 --- a/lib/methods/sleepchecktask.cpp +++ b/lib/methods/sleepchecktask.cpp @@ -18,7 +18,11 @@ void SleepCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResu REQUIRE_NOT_NULL(checkable); REQUIRE_NOT_NULL(cr); - CheckCommand::Ptr commandObj = checkable->GetCheckCommand(); + CheckCommand::Ptr commandObj; + if (CheckCommand::ExecuteOverride) + commandObj = CheckCommand::ExecuteOverride; + else + commandObj = checkable->GetCheckCommand(); Host::Ptr host; Service::Ptr service;