]> granicus.if.org Git - icinga2/commitdiff
Cli: Don't parse objects/changes on each AddObject() call
authorMichael Friedrich <michael.friedrich@gmail.com>
Thu, 19 Feb 2015 12:15:28 +0000 (13:15 +0100)
committerMichael Friedrich <michael.friedrich@gmail.com>
Fri, 20 Feb 2015 16:05:00 +0000 (17:05 +0100)
refs #8488

lib/cli/nodeupdateconfigcommand.cpp
lib/cli/repositoryobjectcommand.cpp
lib/cli/repositoryutility.cpp
lib/cli/repositoryutility.hpp

index 581c49d4de9bd53adc8e394348c639dd9376a6f2..741800def536f48be6a83d08c36a375250647cf1 100644 (file)
@@ -85,7 +85,12 @@ int NodeUpdateConfigCommand::Run(const boost::program_options::variables_map& vm
 
        Utility::LoadExtensionLibrary("icinga");
 
+       /* cache all existing object configs only once and pass it to AddObject() */
        std::vector<String> object_paths = RepositoryUtility::GetObjects();
+       /* cache all existing changes only once and pass it to AddObject() */
+       Array::Ptr changes = new Array();
+       RepositoryUtility::GetChangeLog(boost::bind(RepositoryUtility::CollectChange, _1, changes));
+
        std::vector<Dictionary::Ptr> nodes = NodeUtility::GetNodes();
 
        /* first make sure that all nodes are valid and should not be removed */
@@ -122,7 +127,7 @@ int NodeUpdateConfigCommand::Run(const boost::program_options::variables_map& vm
 
                                                Dictionary::Ptr host_attrs = new Dictionary();
                                                host_attrs->Set("name", host);
-                                               RepositoryUtility::RemoveObject(host, "Host", host_attrs); //this removes all services for this host as well
+                                               RepositoryUtility::RemoveObject(host, "Host", host_attrs, changes); //this removes all services for this host as well
                                        }
                                }
 
@@ -131,11 +136,11 @@ int NodeUpdateConfigCommand::Run(const boost::program_options::variables_map& vm
 
                                Dictionary::Ptr zone_attrs = new Dictionary();
                                zone_attrs->Set("name", zone);
-                               RepositoryUtility::RemoveObject(zone, "Zone", zone_attrs);
+                               RepositoryUtility::RemoveObject(zone, "Zone", zone_attrs, changes);
 
                                Dictionary::Ptr endpoint_attrs = new Dictionary();
                                endpoint_attrs->Set("name", endpoint);
-                               RepositoryUtility::RemoveObject(endpoint, "Endpoint", endpoint_attrs);
+                               RepositoryUtility::RemoveObject(endpoint, "Endpoint", endpoint_attrs, changes);
                        } else {
                                /* get the current node */
                                Dictionary::Ptr new_node = inventory->Get(old_node_name);
@@ -169,7 +174,7 @@ int NodeUpdateConfigCommand::Run(const boost::program_options::variables_map& vm
 
                                                        Dictionary::Ptr host_attrs = new Dictionary();
                                                        host_attrs->Set("name", old_host);
-                                                       RepositoryUtility::RemoveObject(old_host, "Host", host_attrs); //this will remove all services for this host too
+                                                       RepositoryUtility::RemoveObject(old_host, "Host", host_attrs, changes); //this will remove all services for this host too
                                                } else {
                                                        /* host exists, now check all services for this host */
                                                        Array::Ptr old_services = kv.second;
@@ -194,7 +199,7 @@ int NodeUpdateConfigCommand::Run(const boost::program_options::variables_map& vm
                                                                        Dictionary::Ptr service_attrs = new Dictionary();
                                                                        service_attrs->Set("name", old_service);
                                                                        service_attrs->Set("host_name", old_host);
-                                                                       RepositoryUtility::RemoveObject(old_service, "Service", service_attrs);
+                                                                       RepositoryUtility::RemoveObject(old_service, "Service", service_attrs, changes);
                                                                }
                                                        }
                                                }
@@ -231,7 +236,7 @@ int NodeUpdateConfigCommand::Run(const boost::program_options::variables_map& vm
                host_imports->Add("satellite-host"); //default host node template
                host_attrs->Set("import", host_imports);
 
-               if (!RepositoryUtility::AddObject(zone, "Host", host_attrs)) {
+               if (!RepositoryUtility::AddObject(object_paths, zone, "Host", host_attrs, changes)) {
                        Log(LogCritical, "cli")
                            << "Cannot add node host '" << zone << "' to the config repository!\n";
                }
@@ -290,7 +295,7 @@ int NodeUpdateConfigCommand::Run(const boost::program_options::variables_map& vm
                                        host_imports->Add("satellite-host"); //default host node template
                                        host_attrs->Set("import", host_imports);
 
-                                       RepositoryUtility::AddObject(host, "Host", host_attrs);
+                                       RepositoryUtility::AddObject(object_paths, host, "Host", host_attrs, changes);
                                }
 
                                /* special condition: what if the host was blacklisted before, but the services should be generated? */
@@ -348,7 +353,7 @@ int NodeUpdateConfigCommand::Run(const boost::program_options::variables_map& vm
                                        service_imports->Add("satellite-service"); //default service node template
                                        service_attrs->Set("import", service_imports);
 
-                                       if (!RepositoryUtility::AddObject(service, "Service", service_attrs))
+                                       if (!RepositoryUtility::AddObject(object_paths, service, "Service", service_attrs, changes))
                                                continue;
                                }
                        }
@@ -371,7 +376,7 @@ int NodeUpdateConfigCommand::Run(const boost::program_options::variables_map& vm
                Log(LogInformation, "cli")
                    << "Adding endpoint '" << endpoint << "' to the repository.";
 
-               if (!RepositoryUtility::AddObject(endpoint, "Endpoint", endpoint_attrs)) {
+               if (!RepositoryUtility::AddObject(object_paths, endpoint, "Endpoint", endpoint_attrs, changes)) {
                        Log(LogCritical, "cli")
                            << "Cannot add node endpoint '" << endpoint << "' to the config repository!\n";
                }
@@ -406,7 +411,7 @@ int NodeUpdateConfigCommand::Run(const boost::program_options::variables_map& vm
                Log(LogInformation, "cli")
                    << "Adding zone '" << zone << "' to the repository.";
 
-               if (!RepositoryUtility::AddObject(zone, "Zone", zone_attrs)) {
+               if (!RepositoryUtility::AddObject(object_paths, zone, "Zone", zone_attrs, changes)) {
                        Log(LogCritical, "cli")
                            << "Cannot add node zone '" << zone << "' to the config repository!\n";
                }
index 650791528dfcf99f38701c58f128d065c7a1c81f..e50b45faa13b4ed187e594c2ac31a9b4295b403c 100644 (file)
@@ -176,10 +176,19 @@ int RepositoryObjectCommand::Run(const boost::program_options::variables_map& vm
 
        if (m_Command == RepositoryCommandAdd) {
                Utility::LoadExtensionLibrary("icinga");
-               RepositoryUtility::AddObject(name, m_Type, attrs);
+
+               std::vector<String> object_paths = RepositoryUtility::GetObjects();
+
+               Array::Ptr changes = new Array();
+               RepositoryUtility::GetChangeLog(boost::bind(RepositoryUtility::CollectChange, _1, changes));
+
+               RepositoryUtility::AddObject(object_paths, name, m_Type, attrs, changes);
        } else if (m_Command == RepositoryCommandRemove) {
+               Array::Ptr changes = new Array();
+               RepositoryUtility::GetChangeLog(boost::bind(RepositoryUtility::CollectChange, _1, changes));
+
                /* pass attrs for service->host_name requirement */
-               RepositoryUtility::RemoveObject(name, m_Type, attrs);
+               RepositoryUtility::RemoveObject(name, m_Type, attrs, changes);
        } else if (m_Command == RepositoryCommandSet) {
                Log(LogWarning, "cli")
                    << "Not supported yet. Please check the roadmap at https://dev.icinga.org\n";
index cd3c5974a5bd636c36063d0c8a1d8e28fd2b7c2d..12a44f8681793f654408522e6e87c327a1f285f9 100644 (file)
@@ -199,9 +199,8 @@ public:
 };
 
 /* modify objects and write changelog */
-bool RepositoryUtility::AddObject(const String& name, const String& type, const Dictionary::Ptr& attrs)
+bool RepositoryUtility::AddObject(const std::vector<String>& object_paths, const String& name, const String& type, const Dictionary::Ptr& attrs, const Array::Ptr& changes)
 {
-       std::vector<String> object_paths = GetObjects();
        String pattern;
 
        if (type == "Service")
@@ -264,7 +263,7 @@ bool RepositoryUtility::AddObject(const String& name, const String& type, const
                }
        }
 
-       if (CheckChangeExists(change)) {
+       if (CheckChangeExists(change, changes)) {
                Log(LogWarning, "cli")
                    << "Change '" << change->Get("command") << "' for type '"
                    << change->Get("type") << "' and name '" << change->Get("name")
@@ -273,10 +272,13 @@ bool RepositoryUtility::AddObject(const String& name, const String& type, const
                return false;
        }
 
+       /* store the cached change */
+       changes->Add(change);
+
        return WriteObjectToRepositoryChangeLog(path, change);
 }
 
-bool RepositoryUtility::RemoveObject(const String& name, const String& type, const Dictionary::Ptr& attrs)
+bool RepositoryUtility::RemoveObject(const String& name, const String& type, const Dictionary::Ptr& attrs, const Array::Ptr& changes)
 {
        /* add a new changelog entry by timestamp */
        String path = GetRepositoryChangeLogPath() + "/" + Convert::ToString(Utility::GetTime()) + "-" + type + "-" + SHA256(name) + ".change";
@@ -289,7 +291,7 @@ bool RepositoryUtility::RemoveObject(const String& name, const String& type, con
        change->Set("command", "remove");
        change->Set("attrs", attrs); //required for service->host_name
 
-       if (CheckChangeExists(change)) {
+       if (CheckChangeExists(change, changes)) {
                Log(LogWarning, "cli")
                    << "Change '" << change->Get("command") << "' for type '"
                    << change->Get("type") << "' and name '" << change->Get("name")
@@ -298,6 +300,9 @@ bool RepositoryUtility::RemoveObject(const String& name, const String& type, con
                return false;
        }
 
+       /* store the cached change */
+       changes->Add(change);
+
        return WriteObjectToRepositoryChangeLog(path, change);
 }
 
@@ -307,16 +312,12 @@ bool RepositoryUtility::SetObjectAttribute(const String& name, const String& typ
        return true;
 }
 
-bool RepositoryUtility::CheckChangeExists(const Dictionary::Ptr& change)
+bool RepositoryUtility::CheckChangeExists(const Dictionary::Ptr& change, const Array::Ptr& changes)
 {
        Dictionary::Ptr attrs = change->Get("attrs");
 
-       Array::Ptr changelog = new Array();
-
-       GetChangeLog(boost::bind(RepositoryUtility::CollectChange, _1, changelog));
-
-       ObjectLock olock(changelog);
-       BOOST_FOREACH(const Dictionary::Ptr& entry, changelog) {
+       ObjectLock olock(changes);
+       BOOST_FOREACH(const Dictionary::Ptr& entry, changes) {
                if (entry->Get("type") != change->Get("type"))
                        continue;
 
index 2f8480195e37525beafe7e5770b1b378d852a25c..7e24cdd7ff8b1160f2128a2d0555eb12282d7311 100644 (file)
@@ -52,18 +52,23 @@ public:
 
        static void PrintChangeLog(std::ostream& fp);
 
-       static bool AddObject(const String& name, const String& type, const Dictionary::Ptr& attrs);
-       static bool RemoveObject(const String& name, const String& type, const Dictionary::Ptr& attrs);
+       static bool AddObject(const std::vector<String>& object_paths, const String& name, const String& type, const Dictionary::Ptr& attrs, const Array::Ptr& changes);
+       static bool RemoveObject(const String& name, const String& type, const Dictionary::Ptr& attrs, const Array::Ptr& changes);
 
-       static bool CheckChangeExists(const Dictionary::Ptr& change);
+       static bool CheckChangeExists(const Dictionary::Ptr& change, const Array::Ptr& changes);
 
        static bool SetObjectAttribute(const String& name, const String& type, const String& attr, const Value& val);
 
        static bool CommitChangeLog(void);
        static bool ClearChangeLog(void);
        static bool ChangeLogHasPendingChanges(void);
+       static bool GetChangeLog(const boost::function<void (const Dictionary::Ptr&, const String&)>& callback);
+       static void CollectChangeLog(const String& change_file, std::vector<String>& changelog);
+       static void CollectChange(const Dictionary::Ptr& change, Array::Ptr& changes);
 
        static std::vector<String> GetObjects(void);
+       static void CollectObjects(const String& object_file, std::vector<String>& objects);
+
 private:
        RepositoryUtility(void);
 
@@ -75,17 +80,13 @@ private:
            const Value& val, const Dictionary::Ptr& attrs);
 
        /* repository.d */
-       static void CollectObjects(const String& object_file, std::vector<String>& objects);
        static bool WriteObjectToRepository(const String& path, const String& name, const String& type, const Dictionary::Ptr& item);
        static Dictionary::Ptr GetObjectFromRepository(const String& filename);
 
        /* changelog */
-       static void CollectChangeLog(const String& change_file, std::vector<String>& changelog);
        static bool WriteObjectToRepositoryChangeLog(const String& path, const Dictionary::Ptr& item);
        static Dictionary::Ptr GetObjectFromRepositoryChangeLog(const String& filename);
 
-       static bool GetChangeLog(const boost::function<void (const Dictionary::Ptr&, const String&)>& callback);
-       static void CollectChange(const Dictionary::Ptr& change, Array::Ptr& changes);
        static void CommitChange(const Dictionary::Ptr& change, const String& path);
        static void ClearChange(const Dictionary::Ptr& change, const String& path);