mirror of
https://github.com/Icinga/icinga2.git
synced 2025-07-26 23:24:09 +02:00
Merge pull request #10161 from Icinga/authBYhost-10157
ApiListener::UpdateObjectAuthority(): distribute auth. by object's host
This commit is contained in:
commit
4e08adc532
@ -633,15 +633,12 @@ The algorithm works like this:
|
|||||||
* Set the authority (true or false)
|
* Set the authority (true or false)
|
||||||
|
|
||||||
The object authority calculation works "offline" without any message exchange.
|
The object authority calculation works "offline" without any message exchange.
|
||||||
Each instance alculates the SDBM hash of the config object name, puts that in contrast
|
Each instance calculates the SDBM hash of the config object name. However, for objects bound to some
|
||||||
modulo the connected endpoints size.
|
host, i.e. the object name is composed of `<host_name>!<object_name>`, the SDBM hash is calculated based
|
||||||
This index is used to lookup the corresponding endpoint in the connected endpoints array,
|
on the host name only instead of the full object name. That way, each child object like services, downtimes,
|
||||||
including the local endpoint. Whether the local endpoint is equal to the selected endpoint,
|
etc. will be assigned to the same endpoint as the host object itself. The resulting hash modulo (`%`) the number of
|
||||||
or not, this sets the authority to `true` or `false`.
|
connected endpoints produces the index of the endpoint which is authoritative for this config object. If the
|
||||||
|
endpoint at this index is equal to the local endpoint, the authority is set to `true`, otherwise it is set to `false`.
|
||||||
```cpp
|
|
||||||
authority = endpoints[Utility::SDBM(object->GetName()) % endpoints.size()] == my_endpoint;
|
|
||||||
```
|
|
||||||
|
|
||||||
`ConfigObject::SetAuthority(bool authority)` triggers the following events:
|
`ConfigObject::SetAuthority(bool authority)` triggers the following events:
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@ void ApiListener::UpdateObjectAuthority()
|
|||||||
|
|
||||||
std::vector<Endpoint::Ptr> endpoints;
|
std::vector<Endpoint::Ptr> endpoints;
|
||||||
Endpoint::Ptr my_endpoint;
|
Endpoint::Ptr my_endpoint;
|
||||||
|
int hostChildrenInheritObjectAuthority = 0;
|
||||||
|
|
||||||
if (my_zone) {
|
if (my_zone) {
|
||||||
my_endpoint = Endpoint::GetLocalEndpoint();
|
my_endpoint = Endpoint::GetLocalEndpoint();
|
||||||
@ -38,6 +39,10 @@ void ApiListener::UpdateObjectAuthority()
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
endpoints.push_back(endpoint);
|
endpoints.push_back(endpoint);
|
||||||
|
|
||||||
|
if (endpoint == my_endpoint || endpoint->GetCapabilities() & static_cast<uint_fast64_t>(ApiCapabilities::HostChildrenInheritObjectAuthority)) {
|
||||||
|
++hostChildrenInheritObjectAuthority;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
double startTime = Application::GetStartTime();
|
double startTime = Application::GetStartTime();
|
||||||
@ -65,10 +70,24 @@ void ApiListener::UpdateObjectAuthority()
|
|||||||
|
|
||||||
bool authority;
|
bool authority;
|
||||||
|
|
||||||
if (!my_zone)
|
if (my_zone) {
|
||||||
|
auto name (object->GetName());
|
||||||
|
|
||||||
|
// If all endpoints know this algorithm, we can use it.
|
||||||
|
if (hostChildrenInheritObjectAuthority == endpoints.size()) {
|
||||||
|
auto exclamation (name.FindFirstOf('!'));
|
||||||
|
|
||||||
|
// Pin child objects of hosts (HOST!...) to the same endpoint as the host.
|
||||||
|
// This reduces cross-object action latency withing the same host.
|
||||||
|
if (exclamation != String::NPos) {
|
||||||
|
name.erase(name.Begin() + exclamation, name.End());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
authority = endpoints[Utility::SDBM(name) % endpoints.size()] == my_endpoint;
|
||||||
|
} else {
|
||||||
authority = true;
|
authority = true;
|
||||||
else
|
}
|
||||||
authority = endpoints[Utility::SDBM(object->GetName()) % endpoints.size()] == my_endpoint;
|
|
||||||
|
|
||||||
#ifdef I2_DEBUG
|
#ifdef I2_DEBUG
|
||||||
// //Enable on demand, causes heavy logging on each run.
|
// //Enable on demand, causes heavy logging on each run.
|
||||||
|
@ -640,10 +640,6 @@ 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 (
|
|
||||||
(uint_fast64_t)ApiCapabilities::ExecuteArbitraryCommand | (uint_fast64_t)ApiCapabilities::IfwApiCheckCommand
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Processes a new client connection.
|
* Processes a new client connection.
|
||||||
*
|
*
|
||||||
@ -774,7 +770,7 @@ void ApiListener::NewClientHandlerInternal(
|
|||||||
{ "method", "icinga::Hello" },
|
{ "method", "icinga::Hello" },
|
||||||
{ "params", new Dictionary({
|
{ "params", new Dictionary({
|
||||||
{ "version", (double)l_AppVersionInt },
|
{ "version", (double)l_AppVersionInt },
|
||||||
{ "capabilities", (double)l_MyCapabilities }
|
{ "capabilities", (double)ApiCapabilities::MyCapabilities }
|
||||||
}) }
|
}) }
|
||||||
}), yc);
|
}), yc);
|
||||||
|
|
||||||
@ -813,7 +809,7 @@ void ApiListener::NewClientHandlerInternal(
|
|||||||
{ "method", "icinga::Hello" },
|
{ "method", "icinga::Hello" },
|
||||||
{ "params", new Dictionary({
|
{ "params", new Dictionary({
|
||||||
{ "version", (double)l_AppVersionInt },
|
{ "version", (double)l_AppVersionInt },
|
||||||
{ "capabilities", (double)l_MyCapabilities }
|
{ "capabilities", (double)ApiCapabilities::MyCapabilities }
|
||||||
}) }
|
}) }
|
||||||
}), yc);
|
}), yc);
|
||||||
|
|
||||||
@ -1801,6 +1797,10 @@ Value ApiListener::HelloAPIHandler(const MessageOrigin::Ptr& origin, const Dicti
|
|||||||
endpoint->SetIcingaVersion(nodeVersion);
|
endpoint->SetIcingaVersion(nodeVersion);
|
||||||
endpoint->SetCapabilities((double)params->Get("capabilities"));
|
endpoint->SetCapabilities((double)params->Get("capabilities"));
|
||||||
|
|
||||||
|
if (endpoint->GetZone() == Zone::GetLocalZone()) {
|
||||||
|
UpdateObjectAuthority();
|
||||||
|
}
|
||||||
|
|
||||||
if (nodeVersion == 0u) {
|
if (nodeVersion == 0u) {
|
||||||
nodeVersion = 21200;
|
nodeVersion = 21200;
|
||||||
}
|
}
|
||||||
|
@ -70,6 +70,9 @@ enum class ApiCapabilities : uint_fast64_t
|
|||||||
{
|
{
|
||||||
ExecuteArbitraryCommand = 1u << 0u,
|
ExecuteArbitraryCommand = 1u << 0u,
|
||||||
IfwApiCheckCommand = 1u << 1u,
|
IfwApiCheckCommand = 1u << 1u,
|
||||||
|
HostChildrenInheritObjectAuthority = 1u << 2u,
|
||||||
|
|
||||||
|
MyCapabilities = ExecuteArbitraryCommand | IfwApiCheckCommand | HostChildrenInheritObjectAuthority
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user