diff --git a/lib/icinga/apiactions.cpp b/lib/icinga/apiactions.cpp index 608c7b200..1c2691aa7 100644 --- a/lib/icinga/apiactions.cpp +++ b/lib/icinga/apiactions.cpp @@ -19,6 +19,7 @@ #include "icinga/apiactions.hpp" #include "icinga/service.hpp" +#include "icinga/pluginutility.hpp" #include "remote/apiaction.hpp" #include "remote/httputility.hpp" #include "base/utility.hpp" @@ -26,11 +27,23 @@ using namespace icinga; +Dictionary::Ptr ApiActions::CreateResult(const int code, const String& status) { + Dictionary::Ptr result = new Dictionary(); + result->Set("code", code); + result->Set("status", status); + return result; +} + REGISTER_APIACTION(reschedule_check, "Service;Host", &ApiActions::RescheduleCheck); +REGISTER_APIACTION(process_check_result, "Service;Host", &ApiActions::ProcessCheckResult); Dictionary::Ptr ApiActions::RescheduleCheck(const DynamicObject::Ptr& object, const Dictionary::Ptr& params) { Checkable::Ptr checkable = static_pointer_cast(object); + + if (!checkable) + return ApiActions::CreateResult(404, "Cannot reschedule check for non-existent object"); + if (Convert::ToBool(HttpUtility::GetLastParameter(params, "force"))) checkable->SetForceNextCheck(true); @@ -41,8 +54,71 @@ Dictionary::Ptr ApiActions::RescheduleCheck(const DynamicObject::Ptr& object, co nextCheck = Utility::GetTime(); checkable->SetNextCheck(nextCheck); - Dictionary::Ptr result = new Dictionary(); - result->Set("code", 200); - result->Set("status", "yay"); - return result; + + return ApiActions::CreateResult(200, "Successfully rescheduled check for " + checkable->GetName()); +} + +Dictionary::Ptr ApiActions::ProcessCheckResult(const DynamicObject::Ptr& object, const Dictionary::Ptr& params) +{ + Checkable::Ptr checkable = static_pointer_cast(object); + + if (!checkable) + return ApiActions::CreateResult(404, "Cannot process passive check result for non-existent object"); + + if (!checkable->GetEnablePassiveChecks()) + return ApiActions::CreateResult(403, "Passive checks are disabled for " + checkable->GetName()); + + String name; + + Host::Ptr host; + Service::Ptr service; + tie(host, service) = GetHostService(checkable); + + if (!params->Contains("exit_status")) + return ApiActions::CreateResult(403, "Parameter 'exit_status' is required"); + + int exitStatus = HttpUtility::GetLastParameter(params, "exit_status"); + + ServiceState state; + + if (!service) { + name = host->GetName(); + if (exitStatus == 0) + state = ServiceOK; + else if (exitStatus == 1) + state = ServiceCritical; + else + return ApiActions::CreateResult(403, "Invalid 'exit_status' for Host " + name); + } else { + state = PluginUtility::ExitStatusToState(exitStatus); + name = service->GetName() + "!" + service->GetHostName(); + } + + if (!params->Contains("output")) + return ApiActions::CreateResult(400, "Parameter 'output' is required"); + + CheckResult::Ptr cr = new CheckResult(); + cr->SetOutput(HttpUtility::GetLastParameter(params, "output")); + cr->SetState(state); + + cr->SetCheckSource(HttpUtility::GetLastParameter(params, "check_source")); + cr->SetPerformanceData(HttpUtility::GetLastParameter(params, "performance_data")); + cr->SetCommand(HttpUtility::GetLastParameter(params, "command")); + cr->SetExecutionEnd(HttpUtility::GetLastParameter(params, "execution_end")); + cr->SetExecutionStart(HttpUtility::GetLastParameter(params, "execution_start")); + cr->SetScheduleEnd(HttpUtility::GetLastParameter(params, "schedule_end")); + cr->SetScheduleStart(HttpUtility::GetLastParameter(params, "schedule_start")); + + checkable->ProcessCheckResult(cr); + + if (!service) { + ObjectLock olock(checkable); + + /* Reschedule the next check. The side effect of this is that for as long + * as we receive passive results for a service we won't execute any + * active checks. */ + checkable->SetNextCheck(Utility::GetTime() + checkable->GetCheckInterval()); + } + + return ApiActions::CreateResult(200, "Successfully processed check result for " + name); } diff --git a/lib/icinga/apiactions.hpp b/lib/icinga/apiactions.hpp index 567186ccc..7682276d0 100644 --- a/lib/icinga/apiactions.hpp +++ b/lib/icinga/apiactions.hpp @@ -34,6 +34,10 @@ class I2_ICINGA_API ApiActions { public: static Dictionary::Ptr RescheduleCheck(const DynamicObject::Ptr& object, const Dictionary::Ptr& params); + static Dictionary::Ptr ProcessCheckResult(const DynamicObject::Ptr& object, const Dictionary::Ptr& params); + +private: + static Dictionary::Ptr CreateResult(const int code, const String& status); }; }