]> granicus.if.org Git - icinga2/commitdiff
Implement deleting api created objects in the cluster
authorMichael Friedrich <michael.friedrich@netways.de>
Thu, 10 Sep 2015 15:48:06 +0000 (17:48 +0200)
committerMichael Friedrich <michael.friedrich@netways.de>
Thu, 17 Sep 2015 12:20:44 +0000 (14:20 +0200)
refs #9927

lib/remote/apilistener-configsync.cpp
lib/remote/apilistener.hpp

index 1c50f701a59325cb952596b362c249f977e78287..62c9ff52d02912c89e59a90981c5905bc52de8d5 100644 (file)
@@ -43,14 +43,17 @@ void ApiListener::ConfigUpdateObjectHandler(const ConfigObject::Ptr& object, con
 {
        ApiListener::Ptr listener = ApiListener::GetInstance();
 
-       if (!listener)
+       if (!listener) {
+               Log(LogCritical, "ApiListener", "No instance available.");
                return;
+       }
 
        if (object->IsActive()) {
                /* Sync object config */
                listener->UpdateConfigObject(object, cookie);
        } else {
                /* Delete object */
+               listener->DeleteConfigObject(object, cookie);
        }
 }
 
@@ -136,6 +139,65 @@ Value ApiListener::ConfigUpdateObjectAPIHandler(const MessageOrigin::Ptr& origin
 
 Value ApiListener::ConfigDeleteObjectAPIHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params)
 {
+       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;
+       }
+
+       /* delete the object */
+       ConfigType::Ptr dtype = ConfigType::GetByName(params->Get("type"));
+
+       if (!dtype) {
+               Log(LogCritical, "ApiListener")
+                   << "Config type '" << params->Get("type") << "' does not exist.";
+               return Empty;
+       }
+
+       ConfigObject::Ptr object = dtype->GetObject(params->Get("name"));
+
+       if (object) {
+
+               if (object->GetPackage() != "_api") {
+                       Log(LogCritical, "ApiListener")
+                           << "Could not delete object '" << object->GetName() << "': Not created by the API.";
+                       return Empty;
+               }
+
+               Array::Ptr errors = new Array();
+               bool cascade = true; //TODO pass that through the cluster
+               if (!ConfigObjectUtility::DeleteObject(object, cascade, errors)) {
+                       Log(LogCritical, "ApiListener", "Could not delete object:");
+
+                       ObjectLock olock(errors);
+                       BOOST_FOREACH(const String& error, errors) {
+                               Log(LogCritical, "ApiListener", error);
+                       }
+               }
+       } else {
+               Log(LogWarning, "ApiListener")
+                   << "Could not delete non-existing object '" << params->Get("name") << "'.";
+       }
+
        return Empty;
 }
 
@@ -188,3 +250,30 @@ void ApiListener::UpdateConfigObject(const ConfigObject::Ptr& object, const Mess
        else
                RelayMessage(origin, object, message, false);
 }
+
+
+void ApiListener::DeleteConfigObject(const ConfigObject::Ptr& object, const MessageOrigin::Ptr& origin,
+    const JsonRpcConnection::Ptr& client)
+{
+       if (object->GetPackage() != "_api")
+               return;
+
+       Dictionary::Ptr message = new Dictionary();
+       message->Set("jsonrpc", "2.0");
+       message->Set("method", "config::DeleteObject");
+
+       Dictionary::Ptr params = new Dictionary();
+       params->Set("name", object->GetName());
+       params->Set("type", object->GetType()->GetName());
+       params->Set("version", object->GetVersion());
+
+       message->Set("params", params);
+
+       Log(LogWarning, "ApiListener")
+           << "Sent delete object: " << JsonEncode(params);
+
+       if (client)
+               JsonRpc::SendMessage(client->GetStream(), message);
+       else
+               RelayMessage(origin, object, message, false);
+}
index a9a4dadb2bd48d48a004f1ffc0469b6445a97bff..88943a18ff0efb81461abce1475ce04c4c485da2 100644 (file)
@@ -120,6 +120,7 @@ private:
        static void LogGlobHandler(std::vector<int>& files, const String& file);
        void ReplayLog(const JsonRpcConnection::Ptr& client);
 
+       /* filesync */
        static Dictionary::Ptr LoadConfigDir(const String& dir);
        static bool UpdateConfigDir(const Dictionary::Ptr& oldConfig, const Dictionary::Ptr& newConfig, const String& configDir, bool authoritative);
 
@@ -129,9 +130,12 @@ private:
        static bool IsConfigMaster(const Zone::Ptr& zone);
        static void ConfigGlobHandler(Dictionary::Ptr& config, const String& path, const String& file);
        void SendConfigUpdate(const JsonRpcConnection::Ptr& aclient);
-       
+
+       /* configsync */
        void UpdateConfigObject(const ConfigObject::Ptr& object, const MessageOrigin::Ptr& origin,
            const JsonRpcConnection::Ptr& client = JsonRpcConnection::Ptr());
+       void DeleteConfigObject(const ConfigObject::Ptr& object, const MessageOrigin::Ptr& origin,
+           const JsonRpcConnection::Ptr& client = JsonRpcConnection::Ptr());
 };
 
 }