mirror of
https://github.com/Icinga/icinga2.git
synced 2025-09-21 16:57:58 +02:00
parent
faf93f8ab6
commit
18a7388117
@ -24,6 +24,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);
|
REGISTER_APIFUNCTION(WantZones, config, &ApiListener::ConfigWantZonesHandler);
|
||||||
|
REGISTER_APIFUNCTION(HaveFiles, config, &ApiListener::ConfigHaveFilesHandler);
|
||||||
|
|
||||||
boost::mutex ApiListener::m_ConfigSyncStageLock;
|
boost::mutex ApiListener::m_ConfigSyncStageLock;
|
||||||
|
|
||||||
@ -551,6 +552,128 @@ Value ApiListener::ConfigHaveZonesHandler(const MessageOrigin::Ptr& origin, cons
|
|||||||
return Empty;
|
return Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Value ApiListener::ConfigHaveFilesHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params)
|
||||||
|
{
|
||||||
|
auto endpoint (origin->FromClient->GetEndpoint());
|
||||||
|
|
||||||
|
// Verify permissions and trust relationship.
|
||||||
|
if (!endpoint || (origin->FromZone && !Zone::GetLocalZone()->IsChildOf(origin->FromZone))) {
|
||||||
|
return Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
ApiListener::Ptr listener = ApiListener::GetInstance();
|
||||||
|
|
||||||
|
if (!listener) {
|
||||||
|
Log(LogCritical, "ApiListener", "No instance available.");
|
||||||
|
return Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!listener->GetAcceptConfig()) {
|
||||||
|
Log(LogWarning, "ApiListener")
|
||||||
|
<< "Ignoring information about files in zones. '" << listener->GetName() << "' does not accept config.";
|
||||||
|
return Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto fromEndpointName (origin->FromClient->GetEndpoint()->GetName());
|
||||||
|
auto fromZoneName (GetFromZoneName(origin->FromZone));
|
||||||
|
|
||||||
|
Log(LogInformation, "ApiListener")
|
||||||
|
<< "Checking information about files in zones from endpoint '" << fromEndpointName
|
||||||
|
<< "' of zone '" << fromZoneName << "'.";
|
||||||
|
|
||||||
|
Dictionary::Ptr checksums = params->Get("checksums");
|
||||||
|
auto zonesDir (GetApiZonesDir());
|
||||||
|
Dictionary::Ptr want = new Dictionary();
|
||||||
|
ObjectLock oLock (checksums);
|
||||||
|
|
||||||
|
for (auto& kv : checksums) {
|
||||||
|
if (!Zone::GetByName(kv.first)) {
|
||||||
|
Log(LogWarning, "ApiListener")
|
||||||
|
<< "Ignoring information about files in unknown zone '" << kv.first
|
||||||
|
<< "' from endpoint '" << fromEndpointName << "'.";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ignore files declarations where we have an authoritive copy in etc/zones.d, packages, etc.
|
||||||
|
if (ConfigCompiler::HasZoneConfigAuthority(kv.first)) {
|
||||||
|
Log(LogInformation, "ApiListener")
|
||||||
|
<< "Ignoring information about files in zone '" << kv.first << "' from endpoint '"
|
||||||
|
<< fromEndpointName << "' because we have an authoritative version of the zone's config.";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
String checksumsPath = zonesDir + kv.first + "/.checksums";
|
||||||
|
Dictionary::Ptr checksums;
|
||||||
|
std::ifstream fp (checksumsPath.CStr(), std::ifstream::binary);
|
||||||
|
|
||||||
|
if (fp) {
|
||||||
|
checksums = JsonDecode(String(
|
||||||
|
std::istreambuf_iterator<char>(fp), std::istreambuf_iterator<char>()
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
checksums = new Dictionary();
|
||||||
|
}
|
||||||
|
|
||||||
|
Dictionary::Ptr havePerZone = kv.second;
|
||||||
|
Array::Ptr wantPerZone = new Array();
|
||||||
|
ObjectLock oLock (havePerZone);
|
||||||
|
|
||||||
|
for (auto& kv : havePerZone) {
|
||||||
|
if (kv.second != checksums->Get(kv.first)) {
|
||||||
|
wantPerZone->Add(kv.first);
|
||||||
|
}
|
||||||
|
|
||||||
|
checksums->Remove(kv.first);
|
||||||
|
}
|
||||||
|
|
||||||
|
Log(LogNotice, "ApiListener")
|
||||||
|
<< "Compared to the information from endpoint '" << fromEndpointName
|
||||||
|
<< "' about files in zone '" << kv.first << "' there are " << wantPerZone->GetLength()
|
||||||
|
<< " file(s) to fetch the content(s) of and " << checksums->GetLength() << " file(s) to remove.";
|
||||||
|
|
||||||
|
if (!wantPerZone->GetLength() && !checksums->GetLength()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
want->Set(kv.first, wantPerZone);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!want->GetLength()) {
|
||||||
|
Log(LogNotice, "ApiListener")
|
||||||
|
<< "Compared to the information about files in zones from endpoint '"
|
||||||
|
<< fromEndpointName << "' everything is up-to-date.";
|
||||||
|
return Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonRpcConnection::Ptr client;
|
||||||
|
|
||||||
|
for (auto& conn : endpoint->GetClients()) {
|
||||||
|
client = conn;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!client) {
|
||||||
|
Log(LogNotice, "ApiListener")
|
||||||
|
<< "Compared to the information about files in zones from endpoint '"
|
||||||
|
<< fromEndpointName << "' not everything is up-to-date, but we're not connected.";
|
||||||
|
return Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log(LogInformation, "ApiListener")
|
||||||
|
<< "Compared to the information about files in zones from endpoint '" << fromEndpointName
|
||||||
|
<< "' not everything is up-to-date. Requesting files of " << want->GetLength() << " zone(s).";
|
||||||
|
|
||||||
|
client->SendMessage(new Dictionary({
|
||||||
|
{ "jsonrpc", "2.0" },
|
||||||
|
{ "method", "config::WantFiles" },
|
||||||
|
{ "params", new Dictionary({
|
||||||
|
{ "files", want }
|
||||||
|
}) }
|
||||||
|
}));
|
||||||
|
|
||||||
|
return Empty;
|
||||||
|
}
|
||||||
|
|
||||||
Value ApiListener::ConfigWantZonesHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params)
|
Value ApiListener::ConfigWantZonesHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params)
|
||||||
{
|
{
|
||||||
Log(LogNotice, "ApiListener")
|
Log(LogNotice, "ApiListener")
|
||||||
|
@ -87,6 +87,7 @@ public:
|
|||||||
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 Value ConfigWantZonesHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params);
|
||||||
|
static Value ConfigHaveFilesHandler(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 */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user