mirror of https://github.com/Icinga/icinga2.git
parent
9e29936b8f
commit
40ac05c182
|
@ -1288,6 +1288,7 @@ params | Dictionary
|
||||||
|
|
||||||
Key | Type | Description
|
Key | Type | Description
|
||||||
---------------------|-------------|------------------
|
---------------------|-------------|------------------
|
||||||
|
capabilities | Number | Bitmask, see `lib/remote/apilistener.hpp`.
|
||||||
version | Number | Icinga 2 version, e.g. 21300 for v2.13.0.
|
version | Number | Icinga 2 version, e.g. 21300 for v2.13.0.
|
||||||
|
|
||||||
##### Functions
|
##### Functions
|
||||||
|
|
|
@ -821,11 +821,11 @@ Dictionary::Ptr ApiActions::ExecuteCommand(const ConfigObject::Ptr& object,
|
||||||
std::set<Endpoint::Ptr> endpoints = zone->GetEndpoints();
|
std::set<Endpoint::Ptr> endpoints = zone->GetEndpoints();
|
||||||
|
|
||||||
for (const Endpoint::Ptr& childEndpoint : endpoints) {
|
for (const Endpoint::Ptr& childEndpoint : endpoints) {
|
||||||
if (childEndpoint->GetIcingaVersion() < 21300) {
|
if (!(childEndpoint->GetCapabilities() & (uint_fast64_t)ApiCapabilities::ExecuteArbitraryCommand)) {
|
||||||
/* Update execution */
|
/* Update execution */
|
||||||
double now = Utility::GetTime();
|
double now = Utility::GetTime();
|
||||||
pending_execution->Set("exit", 126);
|
pending_execution->Set("exit", 126);
|
||||||
pending_execution->Set("output", "Endpoint '" + childEndpoint->GetName() + "' has version < 2.13.");
|
pending_execution->Set("output", "Endpoint '" + childEndpoint->GetName() + "' doesn't support executing arbitrary commands.");
|
||||||
pending_execution->Set("start", now);
|
pending_execution->Set("start", now);
|
||||||
pending_execution->Set("end", now);
|
pending_execution->Set("end", now);
|
||||||
pending_execution->Remove("pending");
|
pending_execution->Remove("pending");
|
||||||
|
|
|
@ -641,7 +641,7 @@ Value ClusterEvents::ExecuteCommandAPIHandler(const MessageOrigin::Ptr& origin,
|
||||||
std::set<Endpoint::Ptr> endpoints = zone->GetEndpoints();
|
std::set<Endpoint::Ptr> endpoints = zone->GetEndpoints();
|
||||||
|
|
||||||
for (const Endpoint::Ptr &childEndpoint : endpoints) {
|
for (const Endpoint::Ptr &childEndpoint : endpoints) {
|
||||||
if (childEndpoint->GetIcingaVersion() < 21300) {
|
if (!(childEndpoint->GetCapabilities() & (uint_fast64_t)ApiCapabilities::ExecuteArbitraryCommand)) {
|
||||||
double now = Utility::GetTime();
|
double now = Utility::GetTime();
|
||||||
Dictionary::Ptr executedParams = new Dictionary();
|
Dictionary::Ptr executedParams = new Dictionary();
|
||||||
executedParams->Set("execution", params->Get("source"));
|
executedParams->Set("execution", params->Get("source"));
|
||||||
|
@ -650,7 +650,7 @@ Value ClusterEvents::ExecuteCommandAPIHandler(const MessageOrigin::Ptr& origin,
|
||||||
executedParams->Set("service", params->Get("service"));
|
executedParams->Set("service", params->Get("service"));
|
||||||
executedParams->Set("exit", 126);
|
executedParams->Set("exit", 126);
|
||||||
executedParams->Set("output",
|
executedParams->Set("output",
|
||||||
"Endpoint '" + childEndpoint->GetName() + "' has version < 2.13.");
|
"Endpoint '" + childEndpoint->GetName() + "' doesn't support executing arbitrary commands.");
|
||||||
executedParams->Set("start", now);
|
executedParams->Set("start", now);
|
||||||
executedParams->Set("end", now);
|
executedParams->Set("end", now);
|
||||||
|
|
||||||
|
|
|
@ -522,6 +522,8 @@ static const auto l_AppVersionInt (([]() -> unsigned long {
|
||||||
+ boost::lexical_cast<unsigned long>(match[3].str());
|
+ boost::lexical_cast<unsigned long>(match[3].str());
|
||||||
})());
|
})());
|
||||||
|
|
||||||
|
static const auto l_MyCapabilities (ApiCapabilities::ExecuteArbitraryCommand);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Processes a new client connection.
|
* Processes a new client connection.
|
||||||
*
|
*
|
||||||
|
@ -667,7 +669,8 @@ void ApiListener::NewClientHandlerInternal(
|
||||||
{ "jsonrpc", "2.0" },
|
{ "jsonrpc", "2.0" },
|
||||||
{ "method", "icinga::Hello" },
|
{ "method", "icinga::Hello" },
|
||||||
{ "params", new Dictionary({
|
{ "params", new Dictionary({
|
||||||
{ "version", (double)l_AppVersionInt }
|
{ "version", (double)l_AppVersionInt },
|
||||||
|
{ "capabilities", (double)l_MyCapabilities }
|
||||||
}) }
|
}) }
|
||||||
}), yc);
|
}), yc);
|
||||||
|
|
||||||
|
@ -705,7 +708,8 @@ void ApiListener::NewClientHandlerInternal(
|
||||||
{ "jsonrpc", "2.0" },
|
{ "jsonrpc", "2.0" },
|
||||||
{ "method", "icinga::Hello" },
|
{ "method", "icinga::Hello" },
|
||||||
{ "params", new Dictionary({
|
{ "params", new Dictionary({
|
||||||
{ "version", (double)l_AppVersionInt }
|
{ "version", (double)l_AppVersionInt },
|
||||||
|
{ "capabilities", (double)l_MyCapabilities }
|
||||||
}) }
|
}) }
|
||||||
}), yc);
|
}), yc);
|
||||||
|
|
||||||
|
@ -1643,6 +1647,7 @@ Value ApiListener::HelloAPIHandler(const MessageOrigin::Ptr& origin, const Dicti
|
||||||
|
|
||||||
if (endpoint) {
|
if (endpoint) {
|
||||||
endpoint->SetIcingaVersion((double)params->Get("version"));
|
endpoint->SetIcingaVersion((double)params->Get("version"));
|
||||||
|
endpoint->SetCapabilities((double)params->Get("capabilities"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include <boost/asio/ip/tcp.hpp>
|
#include <boost/asio/ip/tcp.hpp>
|
||||||
#include <boost/asio/spawn.hpp>
|
#include <boost/asio/spawn.hpp>
|
||||||
#include <boost/asio/ssl/context.hpp>
|
#include <boost/asio/ssl/context.hpp>
|
||||||
|
#include <cstdint>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
namespace icinga
|
namespace icinga
|
||||||
|
@ -38,6 +39,35 @@ struct ConfigDirInformation
|
||||||
Dictionary::Ptr Checksums;
|
Dictionary::Ptr Checksums;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the version reported by icinga::Hello is not enough to tell whether
|
||||||
|
* the peer has a specific capability, add the latter to this bitmask.
|
||||||
|
*
|
||||||
|
* Note that due to the capability exchange via JSON-RPC and the state storage via JSON
|
||||||
|
* the bitmask numbers are stored in IEEE 754 64-bit floats.
|
||||||
|
* The latter have 53 digit bits which limit the bitmask.
|
||||||
|
* Not to run out of bits:
|
||||||
|
*
|
||||||
|
* Once all Icinga versions which don't have a specific capability are completely EOL,
|
||||||
|
* remove the respective capability checks and assume the peer has the capability.
|
||||||
|
* Once all Icinga versions which still check for the capability are completely EOL,
|
||||||
|
* remove the respective bit from icinga::Hello.
|
||||||
|
* Once all Icinga versions which still have the respective bit in icinga::Hello
|
||||||
|
* are completely EOL, remove the bit here.
|
||||||
|
* Once all Icinga versions which still have the respective bit here
|
||||||
|
* are completely EOL, feel free to re-use the bit.
|
||||||
|
*
|
||||||
|
* completely EOL = not supported, even if an important customer of us used it and
|
||||||
|
* not expected to appear in a multi-level cluster, e.g. a 4 level cluster with
|
||||||
|
* v2.11 -> v2.10 -> v2.9 -> v2.8 - v2.7 isn't here
|
||||||
|
*
|
||||||
|
* @ingroup remote
|
||||||
|
*/
|
||||||
|
enum class ApiCapabilities : uint_fast64_t
|
||||||
|
{
|
||||||
|
ExecuteArbitraryCommand = 1u
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ingroup remote
|
* @ingroup remote
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
|
/* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
|
||||||
|
|
||||||
#include "base/configobject.hpp"
|
#include "base/configobject.hpp"
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
library remote;
|
library remote;
|
||||||
|
|
||||||
|
@ -24,6 +25,9 @@ class Endpoint : ConfigObject
|
||||||
[state] "unsigned long" icinga_version {
|
[state] "unsigned long" icinga_version {
|
||||||
default {{{ return 0; }}}
|
default {{{ return 0; }}}
|
||||||
};
|
};
|
||||||
|
[state] uint_fast64_t capabilities {
|
||||||
|
default {{{ return 0; }}}
|
||||||
|
};
|
||||||
|
|
||||||
[no_user_modify] bool connecting;
|
[no_user_modify] bool connecting;
|
||||||
[no_user_modify] bool syncing;
|
[no_user_modify] bool syncing;
|
||||||
|
|
Loading…
Reference in New Issue