From 7c004af6beb34e66a153dc3fa0c6bde2309d8092 Mon Sep 17 00:00:00 2001 From: Mattia Codato Date: Wed, 5 Aug 2020 14:08:54 +0200 Subject: [PATCH] Check child endpoint versions and check child zone can access to the target endpoint --- lib/icinga/apiactions.cpp | 18 +++++++++++++++-- lib/icinga/clusterevents.cpp | 38 ++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/lib/icinga/apiactions.cpp b/lib/icinga/apiactions.cpp index 86c8616d2..cf77aea4b 100644 --- a/lib/icinga/apiactions.cpp +++ b/lib/icinga/apiactions.cpp @@ -817,12 +817,26 @@ Dictionary::Ptr ApiActions::ExecuteCommand(const ConfigObject::Ptr& object, Zone::Ptr localZone = Zone::GetLocalZone(); for (const Zone::Ptr& zone : ConfigType::GetObjectsByType()) { /* Fetch immediate child zone members */ - if (zone->GetParent() == localZone) { + if (zone->GetParent() == localZone && zone->CanAccessObject(endpointPtr->GetZone())) { std::set endpoints = zone->GetEndpoints(); for (const Endpoint::Ptr& childEndpoint : endpoints) { if (childEndpoint->GetIcingaVersion() < 21300) { - return ApiActions::CreateResult(400, "Endpoint '" + childEndpoint->GetName() + "' has version < 2.13."); + /* Update execution */ + double now = Utility::GetTime(); + pending_execution->Set("exit", 2); + pending_execution->Set("output", "Endpoint '" + childEndpoint->GetName() + "' has version < 2.13."); + pending_execution->Set("start", now); + pending_execution->Set("end", now); + pending_execution->Remove("pending"); + + checkable->SetExecutions(executions); + listener->RelayMessage(origin, checkable, updateMessage, true); + + Dictionary::Ptr result = new Dictionary(); + result->Set("checkable", checkable->GetName()); + result->Set("execution", uuid); + return ApiActions::CreateResult(202, "Accepted", result); } } } diff --git a/lib/icinga/clusterevents.cpp b/lib/icinga/clusterevents.cpp index 93d2a762e..b1426ae76 100644 --- a/lib/icinga/clusterevents.cpp +++ b/lib/icinga/clusterevents.cpp @@ -633,6 +633,44 @@ Value ClusterEvents::ExecuteCommandAPIHandler(const MessageOrigin::Ptr& origin, return Empty; } + /* Check if the child endpoints have Icinga version >= 2.13 */ + for (const Zone::Ptr& zone : ConfigType::GetObjectsByType()) { + /* Fetch immediate child zone members */ + if (zone->GetParent() == localZone && zone->CanAccessObject(endpointZone)) { + std::set endpoints = zone->GetEndpoints(); + + for (const Endpoint::Ptr& childEndpoint : endpoints) { + if (childEndpoint->GetIcingaVersion() < 21300) { + /* Update execution */ + double now = Utility::GetTime(); + Dictionary::Ptr execution = new Dictionary(); + execution->Set("exit", 2); + execution->Set("output", "Endpoint '" + childEndpoint->GetName() + "' has version < 2.13."); + execution->Set("start", now); + execution->Set("end", now); + + Dictionary::Ptr executionsToBroadcast = new Dictionary(); + executionsToBroadcast->Set(params->Get("source"), execution); + + Dictionary::Ptr updateParams = new Dictionary(); + updateParams->Set("host", params->Get("host")); + if (params->Contains("service")) + updateParams->Set("service", params->Get("service")); + updateParams->Set("executions", executionsToBroadcast); + + Dictionary::Ptr updateMessage = new Dictionary(); + updateMessage->Set("jsonrpc", "2.0"); + updateMessage->Set("method", "event::UpdateExecutions"); + updateMessage->Set("params", executionsToBroadcast); + + listener->RelayMessage(nullptr, nullptr, updateMessage, true); + + return Empty; + } + } + } + } + Dictionary::Ptr execMessage = new Dictionary(); execMessage->Set("jsonrpc", "2.0"); execMessage->Set("method", "event::ExecuteCommand");