mirror of https://github.com/Icinga/icinga2.git
Add diagnostic_information as verbose error to config object handlers
This commit is contained in:
parent
a00197e919
commit
c4a6ab0211
|
@ -182,7 +182,7 @@ String Comment::AddComment(const Checkable::Ptr& checkable, CommentType entryTyp
|
|||
|
||||
Array::Ptr errors = new Array();
|
||||
|
||||
if (!ConfigObjectUtility::CreateObject(Comment::TypeInstance, fullName, config, errors)) {
|
||||
if (!ConfigObjectUtility::CreateObject(Comment::TypeInstance, fullName, config, errors, nullptr)) {
|
||||
ObjectLock olock(errors);
|
||||
for (const String& error : errors) {
|
||||
Log(LogCritical, "Comment", error);
|
||||
|
@ -214,7 +214,7 @@ void Comment::RemoveComment(const String& id, const MessageOrigin::Ptr& origin)
|
|||
|
||||
Array::Ptr errors = new Array();
|
||||
|
||||
if (!ConfigObjectUtility::DeleteObject(comment, false, errors)) {
|
||||
if (!ConfigObjectUtility::DeleteObject(comment, false, errors, nullptr)) {
|
||||
ObjectLock olock(errors);
|
||||
for (const String& error : errors) {
|
||||
Log(LogCritical, "Comment", error);
|
||||
|
|
|
@ -256,7 +256,7 @@ String Downtime::AddDowntime(const Checkable::Ptr& checkable, const String& auth
|
|||
|
||||
Array::Ptr errors = new Array();
|
||||
|
||||
if (!ConfigObjectUtility::CreateObject(Downtime::TypeInstance, fullName, config, errors)) {
|
||||
if (!ConfigObjectUtility::CreateObject(Downtime::TypeInstance, fullName, config, errors, nullptr)) {
|
||||
ObjectLock olock(errors);
|
||||
for (const String& error : errors) {
|
||||
Log(LogCritical, "Downtime", error);
|
||||
|
@ -309,7 +309,7 @@ void Downtime::RemoveDowntime(const String& id, bool cancelled, bool expired, co
|
|||
|
||||
Array::Ptr errors = new Array();
|
||||
|
||||
if (!ConfigObjectUtility::DeleteObject(downtime, false, errors)) {
|
||||
if (!ConfigObjectUtility::DeleteObject(downtime, false, errors, nullptr)) {
|
||||
ObjectLock olock(errors);
|
||||
for (const String& error : errors) {
|
||||
Log(LogCritical, "Downtime", error);
|
||||
|
|
|
@ -116,15 +116,14 @@ Value ApiListener::ConfigUpdateObjectAPIHandler(const MessageOrigin::Ptr& origin
|
|||
/* object does not exist, create it through the API */
|
||||
Array::Ptr errors = new Array();
|
||||
|
||||
if (!ConfigObjectUtility::CreateObject(ptype,
|
||||
objName, config, errors)) {
|
||||
if (!ConfigObjectUtility::CreateObject(ptype, objName, config, errors, nullptr)) {
|
||||
Log(LogCritical, "ApiListener")
|
||||
<< "Could not create object '" << objName << "':";
|
||||
|
||||
ObjectLock olock(errors);
|
||||
ObjectLock olock(errors);
|
||||
for (const String& error : errors) {
|
||||
Log(LogCritical, "ApiListener", error);
|
||||
}
|
||||
Log(LogCritical, "ApiListener", error);
|
||||
}
|
||||
|
||||
return Empty;
|
||||
}
|
||||
|
@ -256,7 +255,7 @@ Value ApiListener::ConfigDeleteObjectAPIHandler(const MessageOrigin::Ptr& origin
|
|||
|
||||
Array::Ptr errors = new Array();
|
||||
|
||||
if (!ConfigObjectUtility::DeleteObject(object, true, errors)) {
|
||||
if (!ConfigObjectUtility::DeleteObject(object, true, errors, nullptr)) {
|
||||
Log(LogCritical, "ApiListener", "Could not delete object:");
|
||||
|
||||
ObjectLock olock(errors);
|
||||
|
|
|
@ -98,7 +98,7 @@ String ConfigObjectUtility::CreateObjectConfig(const Type::Ptr& type, const Stri
|
|||
}
|
||||
|
||||
bool ConfigObjectUtility::CreateObject(const Type::Ptr& type, const String& fullName,
|
||||
const String& config, const Array::Ptr& errors)
|
||||
const String& config, const Array::Ptr& errors, const Array::Ptr& diagnosticInformation)
|
||||
{
|
||||
{
|
||||
boost::mutex::scoped_lock lock(ConfigPackageUtility::GetStaticMutex());
|
||||
|
@ -114,7 +114,7 @@ bool ConfigObjectUtility::CreateObject(const Type::Ptr& type, const String& full
|
|||
Utility::MkDirP(Utility::DirName(path), 0700);
|
||||
|
||||
if (Utility::PathExists(path)) {
|
||||
errors->Add("Configuration file '" + path + "' already exists.");
|
||||
errors->Add("Cannot create object '" + fullName + "'. Configuration file '" + path + "' already exists.");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -144,7 +144,10 @@ bool ConfigObjectUtility::CreateObject(const Type::Ptr& type, const String& full
|
|||
}
|
||||
|
||||
for (const boost::exception_ptr& ex : upq.GetExceptions()) {
|
||||
errors->Add(DiagnosticInformation(ex));
|
||||
errors->Add(DiagnosticInformation(ex, false));
|
||||
|
||||
if (diagnosticInformation)
|
||||
diagnosticInformation->Add(DiagnosticInformation(ex));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -161,7 +164,10 @@ bool ConfigObjectUtility::CreateObject(const Type::Ptr& type, const String& full
|
|||
}
|
||||
|
||||
if (errors)
|
||||
errors->Add(DiagnosticInformation(ex));
|
||||
errors->Add(DiagnosticInformation(ex, false));
|
||||
|
||||
if (diagnosticInformation)
|
||||
diagnosticInformation->Add(DiagnosticInformation(ex));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -169,17 +175,21 @@ bool ConfigObjectUtility::CreateObject(const Type::Ptr& type, const String& full
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ConfigObjectUtility::DeleteObjectHelper(const ConfigObject::Ptr& object, bool cascade, const Array::Ptr& errors)
|
||||
bool ConfigObjectUtility::DeleteObjectHelper(const ConfigObject::Ptr& object, bool cascade,
|
||||
const Array::Ptr& errors, const Array::Ptr& diagnosticInformation)
|
||||
{
|
||||
std::vector<Object::Ptr> parents = DependencyGraph::GetParents(object);
|
||||
|
||||
Type::Ptr type = object->GetReflectionType();
|
||||
|
||||
String name = object->GetName();
|
||||
|
||||
if (!parents.empty() && !cascade) {
|
||||
if (errors)
|
||||
errors->Add("Object '" + object->GetName() + "' of type '" + type->GetName() +
|
||||
if (errors) {
|
||||
errors->Add("Object '" + name + "' of type '" + type->GetName() +
|
||||
"' cannot be deleted because other objects depend on it. "
|
||||
"Use cascading delete to delete it anyway.");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -190,10 +200,10 @@ bool ConfigObjectUtility::DeleteObjectHelper(const ConfigObject::Ptr& object, bo
|
|||
if (!parentObj)
|
||||
continue;
|
||||
|
||||
DeleteObjectHelper(parentObj, cascade, errors);
|
||||
DeleteObjectHelper(parentObj, cascade, errors, diagnosticInformation);
|
||||
}
|
||||
|
||||
ConfigItem::Ptr item = ConfigItem::GetByTypeAndName(type, object->GetName());
|
||||
ConfigItem::Ptr item = ConfigItem::GetByTypeAndName(type, name);
|
||||
|
||||
try {
|
||||
/* mark this object for cluster delete event */
|
||||
|
@ -208,12 +218,15 @@ bool ConfigObjectUtility::DeleteObjectHelper(const ConfigObject::Ptr& object, bo
|
|||
|
||||
} catch (const std::exception& ex) {
|
||||
if (errors)
|
||||
errors->Add(DiagnosticInformation(ex));
|
||||
errors->Add(DiagnosticInformation(ex, false));
|
||||
|
||||
if (diagnosticInformation)
|
||||
diagnosticInformation->Add(DiagnosticInformation(ex));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
String path = GetObjectConfigPath(object->GetReflectionType(), object->GetName());
|
||||
String path = GetObjectConfigPath(object->GetReflectionType(), name);
|
||||
|
||||
if (Utility::PathExists(path)) {
|
||||
if (unlink(path.CStr()) < 0 && errno != ENOENT) {
|
||||
|
@ -227,7 +240,7 @@ bool ConfigObjectUtility::DeleteObjectHelper(const ConfigObject::Ptr& object, bo
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ConfigObjectUtility::DeleteObject(const ConfigObject::Ptr& object, bool cascade, const Array::Ptr& errors)
|
||||
bool ConfigObjectUtility::DeleteObject(const ConfigObject::Ptr& object, bool cascade, const Array::Ptr& errors, const Array::Ptr& diagnosticInformation)
|
||||
{
|
||||
if (object->GetPackage() != "_api") {
|
||||
if (errors)
|
||||
|
@ -236,5 +249,5 @@ bool ConfigObjectUtility::DeleteObject(const ConfigObject::Ptr& object, bool cas
|
|||
return false;
|
||||
}
|
||||
|
||||
return DeleteObjectHelper(object, cascade, errors);
|
||||
return DeleteObjectHelper(object, cascade, errors, diagnosticInformation);
|
||||
}
|
||||
|
|
|
@ -45,13 +45,15 @@ public:
|
|||
bool ignoreOnError, const Array::Ptr& templates, const Dictionary::Ptr& attrs);
|
||||
|
||||
static bool CreateObject(const Type::Ptr& type, const String& fullName,
|
||||
const String& config, const Array::Ptr& errors);
|
||||
const String& config, const Array::Ptr& errors, const Array::Ptr& diagnosticInformation);
|
||||
|
||||
static bool DeleteObject(const ConfigObject::Ptr& object, bool cascade, const Array::Ptr& errors);
|
||||
static bool DeleteObject(const ConfigObject::Ptr& object, bool cascade, const Array::Ptr& errors,
|
||||
const Array::Ptr& diagnosticInformation);
|
||||
|
||||
private:
|
||||
static String EscapeName(const String& name);
|
||||
static bool DeleteObjectHelper(const ConfigObject::Ptr& object, bool cascade, const Array::Ptr& errors);
|
||||
static bool DeleteObjectHelper(const ConfigObject::Ptr& object, bool cascade, const Array::Ptr& errors,
|
||||
const Array::Ptr& diagnosticInformation);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -74,6 +74,7 @@ bool CreateObjectHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& r
|
|||
Dictionary::Ptr result1 = new Dictionary();
|
||||
String status;
|
||||
Array::Ptr errors = new Array();
|
||||
Array::Ptr diagnosticInformation = new Array();
|
||||
|
||||
bool ignoreOnError = false;
|
||||
|
||||
|
@ -86,10 +87,22 @@ bool CreateObjectHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& r
|
|||
|
||||
String config;
|
||||
|
||||
bool verbose = false;
|
||||
|
||||
if (params)
|
||||
verbose = HttpUtility::GetLastParameter(params, "verbose");
|
||||
|
||||
/* Object creation can cause multiple errors and optionally diagnostic information.
|
||||
* We can't use SendJsonError() here.
|
||||
*/
|
||||
try {
|
||||
config = ConfigObjectUtility::CreateObjectConfig(type, name, ignoreOnError, templates, attrs);
|
||||
} catch (const std::exception& ex) {
|
||||
errors->Add(DiagnosticInformation(ex));
|
||||
errors->Add(DiagnosticInformation(ex, false));
|
||||
diagnosticInformation->Add(DiagnosticInformation(ex));
|
||||
|
||||
if (verbose)
|
||||
result1->Set("diagnostic_information", diagnosticInformation);
|
||||
|
||||
result1->Set("errors", errors);
|
||||
result1->Set("code", 500);
|
||||
|
@ -101,11 +114,14 @@ bool CreateObjectHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& r
|
|||
return true;
|
||||
}
|
||||
|
||||
if (!ConfigObjectUtility::CreateObject(type, name, config, errors)) {
|
||||
if (!ConfigObjectUtility::CreateObject(type, name, config, errors, diagnosticInformation)) {
|
||||
result1->Set("errors", errors);
|
||||
result1->Set("code", 500);
|
||||
result1->Set("status", "Object could not be created.");
|
||||
|
||||
if (verbose)
|
||||
result1->Set("diagnostic_information", diagnosticInformation);
|
||||
|
||||
response.SetStatus(500, "Object could not be created");
|
||||
HttpUtility::SendJsonBody(response, params, result);
|
||||
|
||||
|
|
|
@ -65,11 +65,12 @@ bool DeleteObjectHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& r
|
|||
} catch (const std::exception& ex) {
|
||||
HttpUtility::SendJsonError(response, params, 404,
|
||||
"No objects found.",
|
||||
HttpUtility::GetLastParameter(params, "verboseErrors") ? DiagnosticInformation(ex) : "");
|
||||
DiagnosticInformation(ex));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cascade = HttpUtility::GetLastParameter(params, "cascade");
|
||||
bool verbose = HttpUtility::GetLastParameter(params, "verbose");
|
||||
|
||||
ArrayData results;
|
||||
|
||||
|
@ -79,8 +80,9 @@ bool DeleteObjectHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& r
|
|||
int code;
|
||||
String status;
|
||||
Array::Ptr errors = new Array();
|
||||
Array::Ptr diagnosticInformation = new Array();
|
||||
|
||||
if (!ConfigObjectUtility::DeleteObject(obj, cascade, errors)) {
|
||||
if (!ConfigObjectUtility::DeleteObject(obj, cascade, errors, diagnosticInformation)) {
|
||||
code = 500;
|
||||
status = "Object could not be deleted.";
|
||||
success = false;
|
||||
|
@ -89,13 +91,18 @@ bool DeleteObjectHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& r
|
|||
status = "Object was deleted.";
|
||||
}
|
||||
|
||||
results.push_back(new Dictionary({
|
||||
Dictionary::Ptr result = new Dictionary({
|
||||
{ "type", type->GetName() },
|
||||
{ "name", obj->GetName() },
|
||||
{ "code", code },
|
||||
{ "status", status },
|
||||
{ "errors", errors }
|
||||
}));
|
||||
});
|
||||
|
||||
if (verbose)
|
||||
result->Set("diagnostic_information", diagnosticInformation);
|
||||
|
||||
results.push_back(result);
|
||||
}
|
||||
|
||||
Dictionary::Ptr result = new Dictionary({
|
||||
|
|
|
@ -77,6 +77,11 @@ bool ModifyObjectHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& r
|
|||
|
||||
Dictionary::Ptr attrs = attrsVal;
|
||||
|
||||
bool verbose = false;
|
||||
|
||||
if (params)
|
||||
verbose = HttpUtility::GetLastParameter(params, "verbose");
|
||||
|
||||
ArrayData results;
|
||||
|
||||
for (const ConfigObject::Ptr& obj : objs) {
|
||||
|
@ -100,7 +105,10 @@ bool ModifyObjectHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& r
|
|||
result1->Set("status", "Attributes updated.");
|
||||
} catch (const std::exception& ex) {
|
||||
result1->Set("code", 500);
|
||||
result1->Set("status", "Attribute '" + key + "' could not be set: " + DiagnosticInformation(ex));
|
||||
result1->Set("status", "Attribute '" + key + "' could not be set: " + DiagnosticInformation(ex, false));
|
||||
|
||||
if (verbose)
|
||||
result1->Set("diagnostic_information", DiagnosticInformation(ex));
|
||||
}
|
||||
|
||||
results.push_back(std::move(result1));
|
||||
|
|
Loading…
Reference in New Issue