]> granicus.if.org Git - icinga2/commitdiff
Use dependency graph when deleting objects
authorGunnar Beutner <gunnar@beutner.name>
Tue, 25 Aug 2015 14:43:48 +0000 (16:43 +0200)
committerGunnar Beutner <gunnar@beutner.name>
Wed, 26 Aug 2015 04:35:06 +0000 (06:35 +0200)
refs #9096

lib/remote/configobjectutility.cpp
lib/remote/configobjectutility.hpp
lib/remote/deleteobjecthandler.cpp

index 2968ccdb241e2791cae901f7bce0446442d26395..1304bef0ed5068f23a4553e1b71c00d3aca93c43 100644 (file)
@@ -24,6 +24,7 @@
 #include "config/configwriter.hpp"
 #include "base/exception.hpp"
 #include "base/serializer.hpp"
+#include "base/dependencygraph.hpp"
 #include <boost/algorithm/string/split.hpp>
 #include <boost/algorithm/string/classification.hpp>
 #include <boost/algorithm/string/case_conv.hpp>
@@ -144,18 +145,29 @@ bool ConfigObjectUtility::CreateObject(const Type::Ptr& type, const String& full
        
        return true;
 }
-       
-bool ConfigObjectUtility::DeleteObject(const ConfigObject::Ptr& object, const Array::Ptr& errors)
+
+bool ConfigObjectUtility::DeleteObjectHelper(const ConfigObject::Ptr& object, bool cascade, const Array::Ptr& errors)
 {
-       if (object->GetModule() != "_api") {
+       std::vector<Object::Ptr> parents = DependencyGraph::GetParents(object);
+
+       if (!parents.empty() && !cascade) {
                if (errors)
-                       errors->Add("Object cannot be deleted because it was not created using the API.");
-                       
+                       errors->Add("Object cannot be deleted because other objects depend on it. Use cascading delete to delete it anyway.");
+
                return false;
        }
 
+       BOOST_FOREACH(const Object::Ptr& pobj, parents) {
+               ConfigObject::Ptr parentObj = dynamic_pointer_cast<ConfigObject>(pobj);
+
+               if (!parentObj)
+                       continue;
+
+               DeleteObjectHelper(parentObj, cascade, errors);
+       }
+
        Type::Ptr type = object->GetReflectionType();
-       
+
        ConfigItem::Ptr item = ConfigItem::GetObject(type->GetName(), object->GetName());
 
        try {
@@ -172,7 +184,7 @@ bool ConfigObjectUtility::DeleteObject(const ConfigObject::Ptr& object, const Ar
                        
                return false;
        }
-       
+
        String typeDir = type->GetPluralName();
        boost::algorithm::to_lower(typeDir);
        
@@ -190,4 +202,16 @@ bool ConfigObjectUtility::DeleteObject(const ConfigObject::Ptr& object, const Ar
 
        return true;
 }
-       
\ No newline at end of file
+
+bool ConfigObjectUtility::DeleteObject(const ConfigObject::Ptr& object, bool cascade, const Array::Ptr& errors)
+{
+       if (object->GetModule() != "_api") {
+               if (errors)
+                       errors->Add("Object cannot be deleted because it was not created using the API.");
+
+               return false;
+       }
+
+       return DeleteObjectHelper(object, cascade, errors);
+}
+
index 47605405229e98fdc94f7ecb051ecf9f29ae711e..f52ec8f7de33154dbb5912f1ff5ea2e67a949878 100644 (file)
@@ -44,10 +44,11 @@ public:
            const Array::Ptr& templates, const Dictionary::Ptr& attrs,
            const Array::Ptr& errors);
            
-       static bool DeleteObject(const ConfigObject::Ptr& object, const Array::Ptr& errors);
+       static bool DeleteObject(const ConfigObject::Ptr& object, bool cascade, const Array::Ptr& errors);
        
 private:
        static String EscapeName(const String& name);
+       static bool DeleteObjectHelper(const ConfigObject::Ptr& object, bool cascade, const Array::Ptr& errors);
 };
 
 }
index 232e0de8ab6b8c746816de7b5773468ce183a59d..854224e28b0163b7ac4d6e159af1fda0ab95b7f3 100644 (file)
@@ -60,6 +60,8 @@ bool DeleteObjectHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& r
 
        std::vector<ConfigObject::Ptr> objs = FilterUtility::GetFilterTargets(qd, params);
 
+       bool cascade = HttpUtility::GetLastParameter(params, "cascade");
+
        Array::Ptr results = new Array();
 
        BOOST_FOREACH(const ConfigObject::Ptr& obj, objs) {
@@ -70,9 +72,10 @@ bool DeleteObjectHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& r
 
                Array::Ptr errors = new Array();
                
-               if (!ConfigObjectUtility::DeleteObject(obj, errors)) {
+               if (!ConfigObjectUtility::DeleteObject(obj, cascade, errors)) {
                        result1->Set("code", 500);      
                        result1->Set("status", "Object could not be deleted.");
+                       result1->Set("errors", errors);
                } else {
                        result1->Set("code", 200);
                        result1->Set("status", "Object was deleted.");