config::WantObjects: send config::HaveFiles

refs #8210
This commit is contained in:
Alexander A. Klimov 2020-09-08 13:58:13 +02:00
parent 3d79fdbaf1
commit faf93f8ab6
2 changed files with 97 additions and 0 deletions

View File

@ -23,6 +23,7 @@ using namespace icinga;
REGISTER_APIFUNCTION(Update, config, &ApiListener::ConfigUpdateHandler); REGISTER_APIFUNCTION(Update, config, &ApiListener::ConfigUpdateHandler);
REGISTER_APIFUNCTION(HaveZones, config, &ApiListener::ConfigHaveZonesHandler); REGISTER_APIFUNCTION(HaveZones, config, &ApiListener::ConfigHaveZonesHandler);
REGISTER_APIFUNCTION(WantZones, config, &ApiListener::ConfigWantZonesHandler);
boost::mutex ApiListener::m_ConfigSyncStageLock; boost::mutex ApiListener::m_ConfigSyncStageLock;
@ -550,6 +551,101 @@ Value ApiListener::ConfigHaveZonesHandler(const MessageOrigin::Ptr& origin, cons
return Empty; return Empty;
} }
Value ApiListener::ConfigWantZonesHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params)
{
Log(LogNotice, "ApiListener")
<< "Received request for zones: " << JsonEncode(params);
/* check permissions */
auto listener (ApiListener::GetInstance());
if (!listener) {
return Empty;
}
auto endpoint (origin->FromClient->GetEndpoint());
auto identity (origin->FromClient->GetIdentity());
auto clientZone (endpoint->GetZone());
/* discard messages if the client is not configured on this node */
if (!endpoint) {
Log(LogNotice, "ApiListener")
<< "Discarding 'config want zones' message from '" << identity
<< "': Invalid endpoint origin (client not allowed).";
return Empty;
}
auto zone (endpoint->GetZone());
Array::Ptr zones (params->Get("zones"));
auto zonesDir (GetApiZonesDir());
Dictionary::Ptr haveFiles = new Dictionary();
ObjectLock oLock (zones);
for (auto& zoneName : zones) {
auto zone (Zone::GetByName(zoneName));
if (!zone) {
Log(LogWarning, "ApiListener")
<< "No such zone '" << zoneName << "' in zones request from '" << identity << "'.";
continue;
}
if (!zone->IsChildOf(clientZone) && !zone->IsGlobal()) {
Log(LogWarning, "ApiListener")
<< "Unauthorized access to zone '" << zoneName << "' in zones request from '" << identity << "'.";
continue;
}
String checksumsPath = zonesDir + zoneName + "/.checksums";
std::ifstream fp (checksumsPath.CStr(), std::ifstream::binary);
if (!fp) {
Log(LogWarning, "ApiListener")
<< "No local .checksums for zone '" << zoneName << "' for zones request from '" << identity << "'.";
continue;
}
Log(LogNotice, "ApiListener")
<< "Informing '" << identity << "' about files in zone '" << zoneName << "'.";
haveFiles->Set(zoneName, JsonDecode(String(
std::istreambuf_iterator<char>(fp), std::istreambuf_iterator<char>()
)));
}
if (!haveFiles->GetLength()) {
Log(LogNotice, "ApiListener")
<< "Not informing '" << identity << "' about files in any zone.";
return Empty;
}
JsonRpcConnection::Ptr client;
for (auto& conn : endpoint->GetClients()) {
client = conn;
break;
}
if (!client) {
Log(LogNotice, "ApiListener")
<< "Not informing '" << identity << "' about files in any zone as we're not connected.";
return Empty;
}
Log(LogInformation, "ApiListener")
<< "Informing '" << identity << "' about files in " << haveFiles->GetLength() << " zone(s).";
client->SendMessage(new Dictionary({
{ "jsonrpc", "2.0" },
{ "method", "config::HaveFiles" },
{ "params", new Dictionary({
{ "checksums", haveFiles }
}) }
}));
return Empty;
}
void ApiListener::HandleConfigUpdate(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params) void ApiListener::HandleConfigUpdate(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params)
{ {
/* Only one transaction is allowed, concurrent message handlers need to wait. /* Only one transaction is allowed, concurrent message handlers need to wait.

View File

@ -86,6 +86,7 @@ public:
/* filesync */ /* filesync */
static Value ConfigUpdateHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params); static Value ConfigUpdateHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params);
static Value ConfigHaveZonesHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params); static Value ConfigHaveZonesHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params);
static Value ConfigWantZonesHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params);
static void HandleConfigUpdate(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params); static void HandleConfigUpdate(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params);
/* configsync */ /* configsync */