]> granicus.if.org Git - icinga2/commitdiff
Implemented ServiceGroup::GetMembers() and HostGroup::GetMembers().
authorGunnar Beutner <gunnar.beutner@netways.de>
Thu, 24 Jan 2013 12:21:35 +0000 (13:21 +0100)
committerGunnar Beutner <gunnar.beutner@netways.de>
Thu, 24 Jan 2013 12:21:35 +0000 (13:21 +0100)
components/compat/compatcomponent.cpp
components/compat/compatcomponent.h
lib/icinga/host.cpp
lib/icinga/host.h
lib/icinga/hostgroup.cpp
lib/icinga/hostgroup.h
lib/icinga/service.cpp
lib/icinga/servicegroup.cpp
lib/icinga/servicegroup.h

index a461818b6ac2fec6d5f433f344ded88dab2e7543..4bef9e2cb43c75ccdd93e3b672cb830ba43eb88e 100644 (file)
@@ -237,11 +237,11 @@ void CompatComponent::DumpHostObject(ofstream& fp, const Host::Ptr& host)
           << "\t" << "active_checks_enabled" << "\t" << 1 << "\n"
           << "\t" << "passive_checks_enabled" << "\t" << 1 << "\n";
 
-       set<String> parents = host->GetParents();
+       set<Host::Ptr> parents = host->GetParents();
 
        if (!parents.empty()) {
                fp << "\t" << "parents" << "\t";
-               DumpStringList(fp, parents);
+               DumpNameList(fp, parents);
                fp << "\n";
        }
 
@@ -370,90 +370,49 @@ void CompatComponent::StatusTimerHandler(void)
                 << "# This file is auto-generated. Do not modify this file." << "\n"
                 << "\n";
 
-       map<String, vector<String> > hostgroups;
-
        DynamicObject::Ptr object;
        BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Host")->GetObjects()) {
                const Host::Ptr& host = static_pointer_cast<Host>(object);
 
-               Dictionary::Ptr dict;
-               dict = host->GetGroups();
-
-               if (dict) {
-                       Value hostgroup;
-                       BOOST_FOREACH(tie(tuples::ignore, hostgroup), dict) {
-                               hostgroups[hostgroup].push_back(host->GetName());
-                       }
-               }
-
                DumpHostStatus(statusfp, host);
                DumpHostObject(objectfp, host);
        }
 
-       pair<String, vector<String > > hgt;
-       BOOST_FOREACH(hgt, hostgroups) {
-               const String& name = hgt.first;
-               const vector<String>& hosts = hgt.second;
+       BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("HostGroup")->GetObjects()) {
+               const HostGroup::Ptr& hg = static_pointer_cast<HostGroup>(object);
 
                objectfp << "define hostgroup {" << "\n"
-                        << "\t" << "hostgroup_name" << "\t" << name << "\n";
-
-               if (HostGroup::Exists(name)) {
-                       HostGroup::Ptr hg = HostGroup::GetByName(name);
-                       objectfp << "\t" << "alias" << "\t" << hg->GetAlias() << "\n"
-                                << "\t" << "notes_url" << "\t" << hg->GetNotesUrl() << "\n"
-                                << "\t" << "action_url" << "\t" << hg->GetActionUrl() << "\n";
-               }
+                        << "\t" << "hostgroup_name" << "\t" << hg->GetName() << "\n"
+                        << "\t" << "alias" << "\t" << hg->GetAlias() << "\n"
+                        << "\t" << "notes_url" << "\t" << hg->GetNotesUrl() << "\n"
+                        << "\t" << "action_url" << "\t" << hg->GetActionUrl() << "\n";
 
                objectfp << "\t" << "members" << "\t";
-
-               DumpStringList(objectfp, hosts);
-
+               DumpNameList(objectfp, hg->GetMembers());
                objectfp << "\n"
                         << "}" << "\n";
        }
 
-       map<String, vector<Service::Ptr> > servicegroups;
-
        BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Service")->GetObjects()) {
-               Service::Ptr service = static_pointer_cast<Service>(object);
-
-               Dictionary::Ptr dict;
-
-               dict = service->GetGroups();
-
-               if (dict) {
-                       Value servicegroup;
-                       BOOST_FOREACH(tie(tuples::ignore, servicegroup), dict) {
-                               servicegroups[servicegroup].push_back(service);
-                       }
-               }
+               const Service::Ptr& service = static_pointer_cast<Service>(object);
 
                DumpServiceStatus(statusfp, service);
                DumpServiceObject(objectfp, service);
        }
 
-       pair<String, vector<Service::Ptr> > sgt;
-       BOOST_FOREACH(sgt, servicegroups) {
-               const String& name = sgt.first;
-               const vector<Service::Ptr>& services = sgt.second;
+       BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("ServiceGroup")->GetObjects()) {
+               const ServiceGroup::Ptr& sg = static_pointer_cast<ServiceGroup>(object);
 
                objectfp << "define servicegroup {" << "\n"
-                        << "\t" << "servicegroup_name" << "\t" << name << "\n";
-
-               if (ServiceGroup::Exists(name)) {
-                       ServiceGroup::Ptr sg = ServiceGroup::GetByName(name);
-                       objectfp << "\t" << "alias" << "\t" << sg->GetAlias() << "\n"
-                                << "\t" << "notes_url" << "\t" << sg->GetNotesUrl() << "\n"
-                                << "\t" << "action_url" << "\t" << sg->GetActionUrl() << "\n";
-               }
+                        << "\t" << "servicegroup_name" << "\t" << sg->GetName() << "\n"
+                        << "\t" << "alias" << "\t" << sg->GetAlias() << "\n"
+                        << "\t" << "notes_url" << "\t" << sg->GetNotesUrl() << "\n"
+                        << "\t" << "action_url" << "\t" << sg->GetActionUrl() << "\n";
 
                objectfp << "\t" << "members" << "\t";
 
                vector<String> sglist;
-               vector<Service::Ptr>::iterator vt;
-
-               BOOST_FOREACH(const Service::Ptr& service, services) {
+               BOOST_FOREACH(const Service::Ptr& service, sg->GetMembers()) {
                        sglist.push_back(service->GetHost()->GetName());
                        sglist.push_back(service->GetAlias());
                }
index 07486b6cc3aa5e56de0e4d7359ac4b996b5d7f2b..1f645dc6c685a3a34e90c5913472088e0166564b 100644 (file)
@@ -49,6 +49,21 @@ private:
        void DumpHostStatus(ofstream& fp, const Host::Ptr& host);
        void DumpHostObject(ofstream& fp, const Host::Ptr& host);
 
+       template<typename T>
+       void DumpNameList(ofstream& fp, const T& list)
+       {
+               typename T::const_iterator it;
+               bool first = true;
+               for (it = list.begin(); it != list.end(); it++) {
+                       if (!first)
+                               fp << ",";
+                       else
+                               first = false;
+
+                       fp << (*it)->GetName();
+               }
+       }
+
        template<typename T>
        void DumpStringList(ofstream& fp, const T& list)
        {
@@ -64,7 +79,6 @@ private:
                }
        }
 
-
        void DumpServiceStatus(ofstream& fp, const Service::Ptr& service);
        void DumpServiceObject(ofstream& fp, const Service::Ptr& service);
 
index a289252d74d8d10094a39327316c408109b422b5..284d8801f4cc3aa7d787ac5c10964578dbd83a36 100644 (file)
@@ -39,6 +39,8 @@ Host::Host(const Dictionary::Ptr& properties)
 
                m_InitializerDone = true;
        }
+
+       HostGroup::InvalidateMembersCache();
 }
 
 String Host::GetAlias(void) const
@@ -70,9 +72,9 @@ Dictionary::Ptr Host::GetGroups(void) const
        return Get("hostgroups");
 }
 
-set<String> Host::GetParents(void)
+set<Host::Ptr> Host::GetParents(void)
 {
-       set<String> parents;
+       set<Host::Ptr> parents;
 
        Dictionary::Ptr dependencies = Get("dependencies");
        if (dependencies) {
@@ -82,10 +84,10 @@ set<String> Host::GetParents(void)
                BOOST_FOREACH(tie(tuples::ignore, dependency), dependencies) {
                        Service::Ptr service = Service::GetByName(dependency);
 
-                       String parent = service->GetHost()->GetName();
+                       Host::Ptr parent = service->GetHost();
 
                        /* ignore ourselves */
-                       if (parent == GetName())
+                       if (parent->GetName() == GetName())
                                continue;
 
                        parents.insert(parent);
@@ -273,3 +275,9 @@ void Host::ObjectRemovedHandler(const ConfigItem::Ptr& item)
        }
 }
 
+void Host::OnAttributeChanged(const String& name, const Value& oldValue)
+{
+       if (name == "hostgroups")
+               HostGroup::InvalidateMembersCache();
+}
+
index a8990b178ad7f91373c2eacad496b4bb63221112..971059c5de4e4b5fa3ead034d8e5a72c9f998226 100644 (file)
@@ -41,12 +41,15 @@ public:
 
        String GetAlias(void) const;
        Dictionary::Ptr GetGroups(void) const;
-       set<String> GetParents(void);
+       set<Host::Ptr> GetParents(void);
        Dictionary::Ptr GetMacros(void) const;
 
        bool IsReachable(void);
        bool IsUp(void);
 
+protected:
+       void OnAttributeChanged(const String& name, const Value& oldValue);
+
 private:
        static bool m_InitializerDone;
 
index 0838ef764e22c60e46a28069d2b24ec1806eb8d5..56a300aa4084c3d59ea46a7307b60e3aceb8e3a4 100644 (file)
@@ -21,6 +21,9 @@
 
 using namespace icinga;
 
+map<String, vector<String> > HostGroup::m_MembersCache;
+bool HostGroup::m_MembersCacheValid = true;
+
 static AttributeDescription hostGroupAttributes[] = {
        { "alias", Attribute_Config },
        { "notes_url", Attribute_Config },
@@ -64,3 +67,54 @@ HostGroup::Ptr HostGroup::GetByName(const String& name)
        return dynamic_pointer_cast<HostGroup>(configObject);
 }
 
+set<Host::Ptr> HostGroup::GetMembers(void) const
+{
+       set<Host::Ptr> hosts;
+
+       ValidateMembersCache();
+
+       BOOST_FOREACH(const String& hst, m_MembersCache[GetName()]) {
+               if (!Host::Exists(hst))
+                       continue;
+
+               Host::Ptr host = Host::GetByName(hst);
+               hosts.insert(host);
+       }
+
+       return hosts;
+}
+
+void HostGroup::InvalidateMembersCache(void)
+{
+       m_MembersCacheValid = false;
+       m_MembersCache.clear();
+}
+
+void HostGroup::ValidateMembersCache(void)
+{
+       if (m_MembersCacheValid)
+               return;
+
+       m_MembersCache.clear();
+
+       DynamicObject::Ptr object;
+       BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Host")->GetObjects()) {
+               const Host::Ptr& host = static_pointer_cast<Host>(object);
+
+               Dictionary::Ptr dict;
+               dict = host->GetGroups();
+
+               if (dict) {
+                       Value hostgroup;
+                       BOOST_FOREACH(tie(tuples::ignore, hostgroup), dict) {
+                               if (!HostGroup::Exists(hostgroup))
+                                       Logger::Write(LogWarning, "icinga", "Host group '" + hostgroup + "' used but not defined.");
+
+                               m_MembersCache[hostgroup].push_back(host->GetName());
+                       }
+               }
+       }
+
+       m_MembersCacheValid = true;
+}
+
index b0e85410378ed8ef9a21cb16067bc7cdf7919141..9f921cf0b1e6507bebc2ab65a2e45ec8a471d26b 100644 (file)
@@ -44,6 +44,15 @@ public:
        String GetAlias(void) const;
        String GetNotesUrl(void) const;
        String GetActionUrl(void) const;
+
+       set<Host::Ptr> GetMembers(void) const;
+       static void InvalidateMembersCache(void);
+
+private:
+       static map<String, vector<String> > m_MembersCache;
+       static bool m_MembersCacheValid;
+
+       static void ValidateMembersCache(void);
 };
 
 }
index c33d4e6001083cecd4fc6235a6e7c8bdf283242b..ce67b69250b7f933f15d974017717bb23a1e359b 100644 (file)
@@ -62,7 +62,9 @@ boost::signal<void (const Service::Ptr&, const Value&)> Service::OnNextCheckChan
 
 Service::Service(const Dictionary::Ptr& serializedObject)
        : DynamicObject(serializedObject)
-{ }
+{
+       ServiceGroup::InvalidateMembersCache();
+}
 
 String Service::GetAlias(void) const
 {
@@ -583,6 +585,8 @@ void Service::OnAttributeChanged(const String& name, const Value& oldValue)
                OnCheckerChanged(GetSelf(), oldValue);
        else if (name == "next_check")
                OnNextCheckChanged(GetSelf(), oldValue);
+       else if (name == "servicegroups")
+               ServiceGroup::InvalidateMembersCache();
 }
 
 void Service::BeginExecuteCheck(const function<void (void)>& callback)
index 31b413fc43ab22701d69611d857ec58d3f0d27d1..316eb1bfd7b5be82a5470851e0a47a0b9b0104ba 100644 (file)
@@ -21,6 +21,9 @@
 
 using namespace icinga;
 
+map<String, vector<String> > ServiceGroup::m_MembersCache;
+bool ServiceGroup::m_MembersCacheValid;
+
 static AttributeDescription serviceGroupAttributes[] = {
        { "alias", Attribute_Config },
        { "notes_url", Attribute_Config },
@@ -64,3 +67,54 @@ ServiceGroup::Ptr ServiceGroup::GetByName(const String& name)
        return dynamic_pointer_cast<ServiceGroup>(configObject);
 }
 
+set<Service::Ptr> ServiceGroup::GetMembers(void) const
+{
+       set<Service::Ptr> services;
+
+       ValidateMembersCache();
+
+       BOOST_FOREACH(const String& svc, m_MembersCache[GetName()]) {
+               if (!Service::Exists(svc))
+                       continue;
+
+               Service::Ptr service = Service::GetByName(svc);
+               services.insert(service);
+       }
+
+       return services;
+}
+
+void ServiceGroup::InvalidateMembersCache(void)
+{
+       m_MembersCacheValid = false;
+       m_MembersCache.clear();
+}
+
+void ServiceGroup::ValidateMembersCache(void)
+{
+       if (m_MembersCacheValid)
+               return;
+
+       m_MembersCache.clear();
+
+       DynamicObject::Ptr object;
+       BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Service")->GetObjects()) {
+               const Service::Ptr& service = static_pointer_cast<Service>(object);
+
+               Dictionary::Ptr dict;
+               dict = service->GetGroups();
+
+               if (dict) {
+                       Value servicegroup;
+                       BOOST_FOREACH(tie(tuples::ignore, servicegroup), dict) {
+                               if (!ServiceGroup::Exists(servicegroup))
+                                       Logger::Write(LogWarning, "icinga", "Service group '" + servicegroup + "' used but not defined.");
+
+                               m_MembersCache[servicegroup].push_back(service->GetName());
+                       }
+               }
+       }
+
+       m_MembersCacheValid = true;
+}
+
index 48f2c4f6e7e2c7cdc113f2768521efb1d9e33a47..6798c69c6f074ca5a2d56a09d622dad014e87912 100644 (file)
@@ -44,6 +44,15 @@ public:
        String GetAlias(void) const;
        String GetNotesUrl(void) const;
        String GetActionUrl(void) const;
+
+       set<Service::Ptr> GetMembers(void) const;
+       static void InvalidateMembersCache(void);
+
+private:
+       static map<String, vector<String> > m_MembersCache;
+       static bool m_MembersCacheValid;
+
+       static void ValidateMembersCache(void);
 };
 
 }