From c3d9f6c17b9113a64f6892e8fde127bf8654f70b Mon Sep 17 00:00:00 2001 From: Mattia Codato Date: Fri, 10 Jul 2020 16:51:45 +0200 Subject: [PATCH] Add ExecuteActionTask --- lib/methods/CMakeLists.txt | 1 + lib/methods/executeactiontask.cpp | 77 +++++++++++++++++++++++++++++++ lib/methods/executeactiontask.hpp | 32 +++++++++++++ 3 files changed, 110 insertions(+) create mode 100644 lib/methods/executeactiontask.cpp create mode 100644 lib/methods/executeactiontask.hpp diff --git a/lib/methods/CMakeLists.txt b/lib/methods/CMakeLists.txt index 9fde9fddb..7bb2fbf6a 100644 --- a/lib/methods/CMakeLists.txt +++ b/lib/methods/CMakeLists.txt @@ -17,6 +17,7 @@ set(methods_SOURCES randomchecktask.cpp randomchecktask.hpp timeperiodtask.cpp timeperiodtask.hpp sleepchecktask.cpp sleepchecktask.hpp + executeactiontask.cpp exceptionchecktask.hpp ) if(ICINGA2_UNITY_BUILD) diff --git a/lib/methods/executeactiontask.cpp b/lib/methods/executeactiontask.cpp new file mode 100644 index 000000000..c40a7ba24 --- /dev/null +++ b/lib/methods/executeactiontask.cpp @@ -0,0 +1,77 @@ +/* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */ + +#include "methods/executeactiontask.hpp" +#include "icinga/pluginutility.hpp" +#include "icinga/checkcommand.hpp" +#include "icinga/clusterevents.hpp" +#include "icinga/macroprocessor.hpp" +#include "icinga/icingaapplication.hpp" +#include "remote/apilistener.hpp" +#include "base/configtype.hpp" +#include "base/logger.hpp" +#include "base/function.hpp" +#include "base/utility.hpp" +#include "base/process.hpp" +#include "base/convert.hpp" + +using namespace icinga; + +void ExecuteActionTask::ProcessFinishedHandler(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr, const Value& commandLine, const ProcessResult& pr) +{ + Checkable::CurrentConcurrentChecks.fetch_sub(1); + Checkable::DecreasePendingChecks(); + + if (pr.ExitStatus > 3) { + Process::Arguments parguments = Process::PrepareCommand(commandLine); + Log(LogWarning, "PluginCheckTask") + << "Check command for object '" << checkable->GetName() << "' (PID: " << pr.PID + << ", arguments: " << Process::PrettyPrintArguments(parguments) << ") terminated with exit code " + << pr.ExitStatus << ", output: " << pr.Output; + } + + String output = pr.Output.Trim(); + + std::pair co = PluginUtility::ParseCheckOutput(output); + cr->SetCommand(commandLine); + cr->SetOutput(co.first); + cr->SetPerformanceData(PluginUtility::SplitPerfdata(co.second)); + cr->SetState(PluginUtility::ExitStatusToState(pr.ExitStatus)); + cr->SetExitStatus(pr.ExitStatus); + cr->SetExecutionStart(pr.ExecutionStart); + cr->SetExecutionEnd(pr.ExecutionEnd); + + Host::Ptr host; + Service::Ptr service; + tie(host, service) = GetHostService(checkable); + + Dictionary::Ptr executedParams = new Dictionary(); + executedParams->Set("host", host->GetName()); + if (service) + executedParams->Set("service", service->GetShortName()); + + /* TODO set the execution UUID */ + /*executedParams->Set("execution", uuid);*/ + + executedParams->Set("check_result", cr); + + /* FIXME command endpoint was overwrite by macro? */ + Endpoint::Ptr commandEndpoint = checkable->GetCommandEndpoint(); + bool local = !commandEndpoint || commandEndpoint == Endpoint::GetLocalEndpoint(); + if (local) { + MessageOrigin::Ptr origin = new MessageOrigin(); + ClusterEvents::ExecutedCommandAPIHandler(origin, executedParams); + } else { + ApiListener::Ptr listener = ApiListener::GetInstance(); + + if (listener) { + Dictionary::Ptr executedMessage = new Dictionary(); + executedMessage->Set("jsonrpc", "2.0"); + executedMessage->Set("method", "event::ExecutedCommand"); + executedMessage->Set("params", executedParams); + + listener->SyncSendMessage(commandEndpoint, executedMessage); + } else { + Log(LogCritical, "ExecuteActionTask") << "Api listener not found"; + } + } +} diff --git a/lib/methods/executeactiontask.hpp b/lib/methods/executeactiontask.hpp new file mode 100644 index 000000000..6717bef31 --- /dev/null +++ b/lib/methods/executeactiontask.hpp @@ -0,0 +1,32 @@ +/* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */ + +#ifndef EXECUTEACTIONTASK_H +#define EXECUTEACTIONTASK_H + +#include "methods/i2-methods.hpp" +#include "base/process.hpp" +#include "icinga/service.hpp" + +namespace icinga +{ + +/** + * Implements service checks based on external plugins. + * + * @ingroup methods + */ +class ExecuteActionTask +{ +public: + + static void ProcessFinishedHandler(const Checkable::Ptr& service, + const CheckResult::Ptr& cr, const Value& commandLine, const ProcessResult& pr); + static thread_local String ExecutionUUID; +private: + + ExecuteActionTask(); +}; + +} + +#endif /* EXECUTEACTIONTASK_H */