mirror of https://github.com/Icinga/icinga2.git
parent
81a0bc6f1b
commit
b2715943c6
|
@ -115,7 +115,7 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void ConfigObject::ModifyAttribute(const String& attr, const Value& value)
|
void ConfigObject::ModifyAttribute(const String& attr, const Value& value, bool updateVersion)
|
||||||
{
|
{
|
||||||
Dictionary::Ptr original_attributes = GetOriginalAttributes();
|
Dictionary::Ptr original_attributes = GetOriginalAttributes();
|
||||||
bool updated_original_attributes = false;
|
bool updated_original_attributes = false;
|
||||||
|
@ -184,6 +184,8 @@ void ConfigObject::ModifyAttribute(const String& attr, const Value& value)
|
||||||
ValidateField(fid, newValue, utils);
|
ValidateField(fid, newValue, utils);
|
||||||
|
|
||||||
SetField(fid, newValue);
|
SetField(fid, newValue);
|
||||||
|
|
||||||
|
if (updateVersion)
|
||||||
SetVersion(GetVersion() + 1);
|
SetVersion(GetVersion() + 1);
|
||||||
|
|
||||||
if (updated_original_attributes)
|
if (updated_original_attributes)
|
||||||
|
|
|
@ -53,7 +53,7 @@ public:
|
||||||
Value GetExtension(const String& key);
|
Value GetExtension(const String& key);
|
||||||
void ClearExtension(const String& key);
|
void ClearExtension(const String& key);
|
||||||
|
|
||||||
void ModifyAttribute(const String& attr, const Value& value);
|
void ModifyAttribute(const String& attr, const Value& value, bool updateVersion = true);
|
||||||
void RestoreAttribute(const String& attr);
|
void RestoreAttribute(const String& attr);
|
||||||
bool IsAttributeModified(const String& attr) const;
|
bool IsAttributeModified(const String& attr) const;
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "remote/jsonrpc.hpp"
|
#include "remote/jsonrpc.hpp"
|
||||||
#include "base/configtype.hpp"
|
#include "base/configtype.hpp"
|
||||||
#include "base/json.hpp"
|
#include "base/json.hpp"
|
||||||
|
#include "base/convert.hpp"
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
|
@ -85,51 +86,66 @@ Value ApiListener::ConfigUpdateObjectAPIHandler(const MessageOrigin::Ptr& origin
|
||||||
}
|
}
|
||||||
|
|
||||||
/* update the object */
|
/* update the object */
|
||||||
ConfigType::Ptr dtype = ConfigType::GetByName(params->Get("type"));
|
String objType = params->Get("type");
|
||||||
|
String objName = params->Get("name");
|
||||||
|
int objVersion = Convert::ToLong(params->Get("version"));
|
||||||
|
|
||||||
|
ConfigType::Ptr dtype = ConfigType::GetByName(objType);
|
||||||
|
|
||||||
if (!dtype) {
|
if (!dtype) {
|
||||||
Log(LogCritical, "ApiListener")
|
Log(LogCritical, "ApiListener")
|
||||||
<< "Config type '" << params->Get("type") << "' does not exist.";
|
<< "Config type '" << objType << "' does not exist.";
|
||||||
return Empty;
|
return Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigObject::Ptr object = dtype->GetObject(params->Get("name"));
|
ConfigObject::Ptr object = dtype->GetObject(objName);
|
||||||
|
|
||||||
if (!object) {
|
if (!object) {
|
||||||
|
/* object does not exist, create it through the API */
|
||||||
Array::Ptr errors = new Array();
|
Array::Ptr errors = new Array();
|
||||||
if (!ConfigObjectUtility::CreateObject(Type::GetByName(params->Get("type")),
|
if (!ConfigObjectUtility::CreateObject(Type::GetByName(objType),
|
||||||
params->Get("name"), params->Get("config"), errors)) {
|
objName, params->Get("config"), errors)) {
|
||||||
Log(LogCritical, "ApiListener", "Could not create object:");
|
Log(LogCritical, "ApiListener")
|
||||||
|
<< "Could not create object '" << objName << "':";
|
||||||
|
|
||||||
ObjectLock olock(errors);
|
ObjectLock olock(errors);
|
||||||
BOOST_FOREACH(const String& error, errors) {
|
BOOST_FOREACH(const String& error, errors) {
|
||||||
Log(LogCritical, "ApiListener", error);
|
Log(LogCritical, "ApiListener", error);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
/* object was created, update its version to its origin */
|
||||||
|
ConfigObject::Ptr newObj = dtype->GetObject(objName);
|
||||||
|
if (newObj)
|
||||||
|
newObj->SetVersion(objVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO-MA: modified attributes, same version
|
|
||||||
} else {
|
} else {
|
||||||
/* object exists, update its attributes if version was changed */
|
/* object exists, update its attributes if version was changed */
|
||||||
if (params->Get("version") > object->GetVersion()) {
|
if (objVersion > object->GetVersion()) {
|
||||||
Log(LogInformation, "ApiListener")
|
Log(LogInformation, "ApiListener")
|
||||||
<< "Processing config update for object '" << object->GetName()
|
<< "Processing config update for object '" << object->GetName()
|
||||||
<< "': Object version '" << object->GetVersion()
|
<< "': Object version " << object->GetVersion()
|
||||||
<< "' is older than the received version '" << params->Get("version") << "'.";
|
<< " is older than the received version " << objVersion << ".";
|
||||||
|
|
||||||
Dictionary::Ptr modified_attributes = params->Get("modified_attributes");
|
Dictionary::Ptr modified_attributes = params->Get("modified_attributes");
|
||||||
|
|
||||||
if (modified_attributes) {
|
if (modified_attributes) {
|
||||||
ObjectLock olock(modified_attributes);
|
ObjectLock olock(modified_attributes);
|
||||||
BOOST_FOREACH(const Dictionary::Pair& kv, modified_attributes) {
|
BOOST_FOREACH(const Dictionary::Pair& kv, modified_attributes) {
|
||||||
int fid = object->GetReflectionType()->GetFieldId(kv.first);
|
/* update all modified attributes
|
||||||
static_cast<Object::Ptr>(object)->SetField(fid, kv.second, false, origin);
|
* but do not update the object version yet.
|
||||||
|
* This triggers cluster events otherwise.
|
||||||
|
*/
|
||||||
|
object->ModifyAttribute(kv.first, kv.second, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* keep the object version in sync with the sender */
|
||||||
|
object->SetVersion(objVersion);
|
||||||
} else {
|
} else {
|
||||||
Log(LogWarning, "ApiListener")
|
Log(LogWarning, "ApiListener")
|
||||||
<< "Skipping config update for object '" << object->GetName()
|
<< "Discarding config update for object '" << object->GetName()
|
||||||
<< "': Object version '" << object->GetVersion()
|
<< "': Object version " << object->GetVersion()
|
||||||
<< "' is more recent than the received version '" << params->Get("version") << "'.";
|
<< " is more recent than the received version " << objVersion << ".";
|
||||||
return Empty;
|
return Empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -807,6 +807,11 @@ void ApiListener::ReplayLog(const JsonRpcConnection::Ptr& client)
|
||||||
logStream->Close();
|
logStream->Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (count > 0) {
|
||||||
|
Log(LogInformation, "ApiListener")
|
||||||
|
<< "Replayed " << count << " messages.";
|
||||||
|
}
|
||||||
|
|
||||||
Log(LogNotice, "ApiListener")
|
Log(LogNotice, "ApiListener")
|
||||||
<< "Replayed " << count << " messages.";
|
<< "Replayed " << count << " messages.";
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue