mirror of
https://github.com/Icinga/icinga2.git
synced 2025-09-25 18:48:50 +02:00
config::HaveObjects: send config::WantObjects if not up-to-date
refs #8210
This commit is contained in:
parent
ee211daf76
commit
61586ed6f2
@ -14,6 +14,7 @@ using namespace icinga;
|
|||||||
|
|
||||||
REGISTER_APIFUNCTION(UpdateObject, config, &ApiListener::ConfigUpdateObjectAPIHandler);
|
REGISTER_APIFUNCTION(UpdateObject, config, &ApiListener::ConfigUpdateObjectAPIHandler);
|
||||||
REGISTER_APIFUNCTION(DeleteObject, config, &ApiListener::ConfigDeleteObjectAPIHandler);
|
REGISTER_APIFUNCTION(DeleteObject, config, &ApiListener::ConfigDeleteObjectAPIHandler);
|
||||||
|
REGISTER_APIFUNCTION(HaveObjects, config, &ApiListener::ConfigHaveObjectsAPIHandler);
|
||||||
|
|
||||||
INITIALIZE_ONCE([]() {
|
INITIALIZE_ONCE([]() {
|
||||||
ConfigObject::OnActiveChanged.connect(&ApiListener::ConfigUpdateObjectHandler);
|
ConfigObject::OnActiveChanged.connect(&ApiListener::ConfigUpdateObjectHandler);
|
||||||
@ -194,6 +195,133 @@ Value ApiListener::ConfigUpdateObjectAPIHandler(const MessageOrigin::Ptr& origin
|
|||||||
return Empty;
|
return Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Value ApiListener::ConfigHaveObjectsAPIHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params)
|
||||||
|
{
|
||||||
|
Log(LogNotice, "ApiListener")
|
||||||
|
<< "Received information about runtime objects: " << JsonEncode(params);
|
||||||
|
|
||||||
|
/* check permissions */
|
||||||
|
ApiListener::Ptr listener = ApiListener::GetInstance();
|
||||||
|
|
||||||
|
if (!listener)
|
||||||
|
return Empty;
|
||||||
|
|
||||||
|
Endpoint::Ptr endpoint = origin->FromClient->GetEndpoint();
|
||||||
|
String identity = origin->FromClient->GetIdentity();
|
||||||
|
|
||||||
|
/* discard messages if the client is not configured on this node */
|
||||||
|
if (!endpoint) {
|
||||||
|
Log(LogNotice, "ApiListener")
|
||||||
|
<< "Discarding 'config have objects' message from '" << identity << "': Invalid endpoint origin (client not allowed).";
|
||||||
|
return Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
Zone::Ptr endpointZone = endpoint->GetZone();
|
||||||
|
|
||||||
|
/* discard messages if the sender is in a child zone */
|
||||||
|
if (!Zone::GetLocalZone()->IsChildOf(endpointZone)) {
|
||||||
|
Log(LogNotice, "ApiListener")
|
||||||
|
<< "Discarding 'config have objects' message"
|
||||||
|
<< " from '" << identity << "' (endpoint: '" << endpoint->GetName() << "', zone: '" << endpointZone->GetName()
|
||||||
|
<< "'). Sender is in a child zone.";
|
||||||
|
return Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ignore messages if the endpoint does not accept config */
|
||||||
|
if (!listener->GetAcceptConfig()) {
|
||||||
|
Log(LogWarning, "ApiListener")
|
||||||
|
<< "Ignoring information about runtime objects"
|
||||||
|
<< " from '" << identity << "' (endpoint: '" << endpoint->GetName() << "', zone: '" << endpointZone->GetName()
|
||||||
|
<< "'). '" << listener->GetName() << "' does not accept config.";
|
||||||
|
return Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
Dictionary::Ptr versions (params->Get("versions"));
|
||||||
|
Dictionary::Ptr want = new Dictionary();
|
||||||
|
ObjectLock oLock (versions);
|
||||||
|
|
||||||
|
for (auto& kv : versions) {
|
||||||
|
auto type (Type::GetByName(kv.first));
|
||||||
|
|
||||||
|
if (!type) {
|
||||||
|
Log(LogWarning, "ApiListener")
|
||||||
|
<< "Bad object type in information about runtime objects from '"
|
||||||
|
<< identity << "': '" << kv.first << "'";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto ctype (dynamic_cast<ConfigType*>(type.get()));
|
||||||
|
|
||||||
|
if (!ctype) {
|
||||||
|
Log(LogWarning, "ApiListener")
|
||||||
|
<< "Bad object type in information about runtime objects from '"
|
||||||
|
<< identity << "': '" << kv.first << "'";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Dictionary::Ptr perType (kv.second);
|
||||||
|
ObjectLock oLock (perType);
|
||||||
|
|
||||||
|
for (auto& kv : perType) {
|
||||||
|
auto object (ctype->GetObject(kv.first));
|
||||||
|
|
||||||
|
if (object && object->GetVersion() >= (double)kv.second) {
|
||||||
|
Log(LogNotice, "ApiListener")
|
||||||
|
<< "Compared to the information about runtime objects from '" << identity << "' the "
|
||||||
|
<< type->GetName() << " '" << object->GetName() << "' is up-to-date.";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log(LogNotice, "ApiListener")
|
||||||
|
<< "Compared to the information about runtime objects from '" << identity << "' the " << type->GetName()
|
||||||
|
<< " '" << kv.first << "' is " << (object ? "outdated" : "missing") << ".";
|
||||||
|
|
||||||
|
Array::Ptr perType = want->Get(type->GetName());
|
||||||
|
|
||||||
|
if (!perType) {
|
||||||
|
perType = new Array();
|
||||||
|
want->Set(type->GetName(), perType);
|
||||||
|
}
|
||||||
|
|
||||||
|
perType->Add(kv.first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!want->GetLength()) {
|
||||||
|
Log(LogNotice, "ApiListener")
|
||||||
|
<< "Compared to the information about runtime objects from '" << identity << "' 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 runtime objects from '" << identity
|
||||||
|
<< "' not everything is up-to-date, but '" << identity << "' is not connected.";
|
||||||
|
return Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log(LogInformation, "ApiListener")
|
||||||
|
<< "Compared to the information about runtime objects from '" << identity
|
||||||
|
<< "' not everything is up-to-date. Requesting updates.";
|
||||||
|
|
||||||
|
client->SendMessage(new Dictionary({
|
||||||
|
{ "jsonrpc", "2.0" },
|
||||||
|
{ "method", "config::WantObjects" },
|
||||||
|
{ "params", new Dictionary({
|
||||||
|
{ "objects", want }
|
||||||
|
}) }
|
||||||
|
}));
|
||||||
|
|
||||||
|
return Empty;
|
||||||
|
}
|
||||||
|
|
||||||
Value ApiListener::ConfigDeleteObjectAPIHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params)
|
Value ApiListener::ConfigDeleteObjectAPIHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params)
|
||||||
{
|
{
|
||||||
Log(LogNotice, "ApiListener")
|
Log(LogNotice, "ApiListener")
|
||||||
|
@ -91,6 +91,7 @@ public:
|
|||||||
static void ConfigUpdateObjectHandler(const ConfigObject::Ptr& object, const Value& cookie);
|
static void ConfigUpdateObjectHandler(const ConfigObject::Ptr& object, const Value& cookie);
|
||||||
static Value ConfigUpdateObjectAPIHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params);
|
static Value ConfigUpdateObjectAPIHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params);
|
||||||
static Value ConfigDeleteObjectAPIHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params);
|
static Value ConfigDeleteObjectAPIHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params);
|
||||||
|
static Value ConfigHaveObjectsAPIHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params);
|
||||||
|
|
||||||
/* API config packages */
|
/* API config packages */
|
||||||
void SetActivePackageStage(const String& package, const String& stage);
|
void SetActivePackageStage(const String& package, const String& stage);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user