mirror of
https://github.com/Icinga/icinga2.git
synced 2025-09-22 17:28:02 +02:00
parent
ac1371a6f4
commit
1c4cf7c98d
@ -17,6 +17,7 @@
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <thread>
|
||||
#include <utility>
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
@ -255,6 +256,121 @@ void ApiListener::SendConfigUpdate(const JsonRpcConnection::Ptr& aclient)
|
||||
aclient->SendMessage(message);
|
||||
}
|
||||
|
||||
static Dictionary::Ptr AssembleZoneDeclaration(const String& zoneName)
|
||||
{
|
||||
auto base (ApiListener::GetApiZonesDir() + zoneName + "/");
|
||||
Dictionary::Ptr declaration = new Dictionary();
|
||||
|
||||
{
|
||||
auto file (base + ".timestamp");
|
||||
std::ifstream fp (file.CStr(), std::ifstream::binary);
|
||||
|
||||
if (!fp) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
double ts;
|
||||
|
||||
try {
|
||||
ts = Convert::ToDouble(String(std::istreambuf_iterator<char>(fp), std::istreambuf_iterator<char>()));
|
||||
} catch (const std::exception&) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
declaration->Set("timestamp", ts);
|
||||
}
|
||||
|
||||
{
|
||||
auto file (base + ".checksum");
|
||||
std::ifstream fp (file.CStr(), std::ifstream::binary);
|
||||
|
||||
if (!fp) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
String content;
|
||||
|
||||
try {
|
||||
content = String(std::istreambuf_iterator<char>(fp), std::istreambuf_iterator<char>());
|
||||
} catch (const std::exception&) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
declaration->Set("checksum", content);
|
||||
}
|
||||
|
||||
return std::move(declaration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Entrypoint for sending a file based config declaration to a cluster client.
|
||||
* This includes security checks for zone relations.
|
||||
* Loads the zone config files where this client belongs to
|
||||
* and sends the 'config::HasZones' JSON-RPC message.
|
||||
*
|
||||
* @param aclient Connected JSON-RPC client.
|
||||
*/
|
||||
void ApiListener::DeclareConfigUpdate(const JsonRpcConnection::Ptr& client)
|
||||
{
|
||||
Endpoint::Ptr endpoint = client->GetEndpoint();
|
||||
ASSERT(endpoint);
|
||||
|
||||
Zone::Ptr clientZone = endpoint->GetZone();
|
||||
|
||||
// Don't send config declarations to parent zones
|
||||
if (!clientZone->IsChildOf(Zone::GetLocalZone())) {
|
||||
return;
|
||||
}
|
||||
|
||||
Dictionary::Ptr declaration = new Dictionary();
|
||||
String zonesDir = GetApiZonesDir();
|
||||
|
||||
for (auto& zone : ConfigType::GetObjectsByType<Zone>()) {
|
||||
String zoneName = zone->GetName();
|
||||
String zoneDir = zonesDir + zoneName;
|
||||
|
||||
// Only declare child and global zones.
|
||||
if (!zone->IsChildOf(clientZone) && !zone->IsGlobal()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Zone was configured, but there's no configuration directory.
|
||||
if (!Utility::PathExists(zoneDir)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto perZone (AssembleZoneDeclaration(zoneName));
|
||||
|
||||
if (!perZone) {
|
||||
// We likely just were upgraded to v2.13 and our non-authoritive config
|
||||
// hasn't been synced from the config master, yet.
|
||||
|
||||
Log(LogNotice, "ApiListener")
|
||||
<< "Not informing endpoint '" << endpoint->GetName() << "' about "
|
||||
<< (zone->IsGlobal() ? "global " : "") << "zone '" << zoneName
|
||||
<< "' to due to yet missing/bad .timestamp/.checksum file in '" << zoneDir << "'.";
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
Log(LogInformation, "ApiListener")
|
||||
<< "Informing endpoint '" << endpoint->GetName() << "' about "
|
||||
<< (zone->IsGlobal() ? "global " : "") << "zone '" << zoneName << "'.";
|
||||
|
||||
declaration->Set(zoneName, perZone);
|
||||
}
|
||||
|
||||
if (declaration->GetLength()) {
|
||||
client->SendMessage(new Dictionary({
|
||||
{ "jsonrpc", "2.0" },
|
||||
{ "method", "config::HaveZones" },
|
||||
{ "params", new Dictionary({
|
||||
{ "zones", declaration }
|
||||
}) }
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
static bool CompareTimestampsConfigChange(const Dictionary::Ptr& productionConfig, const Dictionary::Ptr& receivedConfig,
|
||||
const String& stageConfigZoneDir)
|
||||
{
|
||||
|
@ -790,7 +790,11 @@ void ApiListener::SyncClient(const JsonRpcConnection::Ptr& aclient, const Endpoi
|
||||
bool negotiate = endpoint->GetVersion() >= 21300;
|
||||
|
||||
/* sync zone file config */
|
||||
SendConfigUpdate(aclient);
|
||||
if (negotiate) {
|
||||
DeclareConfigUpdate(aclient);
|
||||
} else {
|
||||
SendConfigUpdate(aclient);
|
||||
}
|
||||
|
||||
Log(LogInformation, "ApiListener")
|
||||
<< "Finished sending config file updates for endpoint '" << endpoint->GetName() << "' in zone '" << eZone->GetName() << "'.";
|
||||
|
@ -194,6 +194,7 @@ private:
|
||||
void SyncLocalZoneDir(const Zone::Ptr& zone) const;
|
||||
|
||||
void SendConfigUpdate(const JsonRpcConnection::Ptr& aclient);
|
||||
void DeclareConfigUpdate(const JsonRpcConnection::Ptr& aclient);
|
||||
|
||||
static Dictionary::Ptr MergeConfigUpdate(const ConfigDirInformation& config);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user