From: Michael Friedrich Date: Thu, 10 Sep 2015 14:54:05 +0000 (+0200) Subject: Implement object config sync permissions and modified attributes based on version X-Git-Tag: v2.4.0~319 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f9c058eca27a774e3971b104283432b4ea444936;p=icinga2 Implement object config sync permissions and modified attributes based on version refs #9927 --- diff --git a/lib/remote/apilistener-configsync.cpp b/lib/remote/apilistener-configsync.cpp index c3c44fd77..1c50f701a 100644 --- a/lib/remote/apilistener-configsync.cpp +++ b/lib/remote/apilistener-configsync.cpp @@ -59,6 +59,29 @@ Value ApiListener::ConfigUpdateObjectAPIHandler(const MessageOrigin::Ptr& origin Log(LogWarning, "ApiListener") << "Received update for object: " << JsonEncode(params); + /* check permissions */ + ApiListener::Ptr listener = ApiListener::GetInstance(); + + if (!listener) { + Log(LogCritical, "ApiListener", "No instance available."); + return Empty; + } + + if (!listener->GetAcceptConfig()) { + Log(LogWarning, "ApiListener") + << "Ignoring config update. '" << listener->GetName() << "' does not accept config."; + return Empty; + } + + Endpoint::Ptr endpoint = origin->FromClient->GetEndpoint(); + + if (!endpoint) { + Log(LogNotice, "ApiListener") + << "Discarding 'config update object' message from '" << origin->FromClient->GetIdentity() << "': Invalid endpoint origin (client not allowed)."; + return Empty; + } + + /* update the object */ ConfigType::Ptr dtype = ConfigType::GetByName(params->Get("type")); if (!dtype) { @@ -82,6 +105,30 @@ Value ApiListener::ConfigUpdateObjectAPIHandler(const MessageOrigin::Ptr& origin } //TODO-MA: modified attributes, same version + } else { + /* object exists, update its attributes if version was changed */ + if (params->Get("version") > object->GetVersion()) { + Log(LogInformation, "ApiListener") + << "Processing config update for object '" << object->GetName() + << "': Object version '" << object->GetVersion() + << "' is older than the received version '" << params->Get("version") << "'."; + + Dictionary::Ptr modified_attributes = params->Get("modified_attributes"); + + if (modified_attributes) { + ObjectLock olock(modified_attributes); + BOOST_FOREACH(const Dictionary::Pair& kv, modified_attributes) { + int fid = object->GetReflectionType()->GetFieldId(kv.first); + static_cast(object)->SetField(fid, kv.second, false, origin); + } + } + } else { + Log(LogWarning, "ApiListener") + << "Skipping config update for object '" << object->GetName() + << "': Object version '" << object->GetVersion() + << "' is more recent than the received version '" << params->Get("version") << "'."; + return Empty; + } } return Empty;