]> granicus.if.org Git - icinga2/commitdiff
Add nested group support for {Host,Service,User}Group.
authorMichael Friedrich <Michael.Friedrich@netways.de>
Mon, 14 Apr 2014 18:59:41 +0000 (20:59 +0200)
committerMichael Friedrich <Michael.Friedrich@netways.de>
Mon, 14 Apr 2014 19:52:01 +0000 (21:52 +0200)
Fixes #5858

14 files changed:
doc/4.3-object-types.md
lib/icinga/host.cpp
lib/icinga/hostgroup.cpp
lib/icinga/hostgroup.h
lib/icinga/hostgroup.ti
lib/icinga/icinga-type.conf
lib/icinga/service.cpp
lib/icinga/servicegroup.cpp
lib/icinga/servicegroup.h
lib/icinga/servicegroup.ti
lib/icinga/user.cpp
lib/icinga/usergroup.cpp
lib/icinga/usergroup.h
lib/icinga/usergroup.ti

index 7160492f3873e20a4b6acfabd057b00f7295047a..57ff77b1d46dfd6ffc7ef7a54a8c9cfe737a4545 100644 (file)
@@ -53,6 +53,7 @@ Attributes:
   Name            |Description
   ----------------|----------------
   display_name    |**Optional.** A short description of the host group.
+  groups          |**Optional.** An array of nested group names.
 
 ### <a id="objecttype-service"></a> Service
 
@@ -113,6 +114,7 @@ Attributes:
   Name            |Description
   ----------------|----------------
   display_name    |**Optional.** A short description of the service group.
+  groups          |**Optional.** An array of nested group names.
 
 ### <a id="objecttype-notification"></a> Notification
 
@@ -299,6 +301,7 @@ Attributes:
   Name            |Description
   ----------------|----------------
   display_name    |**Optional.** A short description of the user group.
+  groups          |**Optional.** An array of nested group names.
 
 ### <a id="objecttype-timeperiod"></a> TimePeriod
 
index 979388fcc69fbefd6303aec2cc5c63b37957fc11..45697bc47299cdcad896e77ec047711684951dc4 100644 (file)
@@ -54,7 +54,7 @@ void Host::OnConfigLoaded(void)
                        HostGroup::Ptr hg = HostGroup::GetByName(name);
 
                        if (hg)
-                               hg->AddMember(GetSelf());
+                               hg->ResolveGroupMembership(GetSelf(), true);
                }
        }
 }
@@ -72,7 +72,7 @@ void Host::Stop(void)
                        HostGroup::Ptr hg = HostGroup::GetByName(name);
 
                        if (hg)
-                               hg->RemoveMember(GetSelf());
+                               hg->ResolveGroupMembership(GetSelf(), false);
                }
        }
 
index cc0d02eaa5a851baa1d03181f916b4a69c03f21b..d24e18dab513d8e88de4afaa76ce811961d89f24 100644 (file)
@@ -46,3 +46,33 @@ void HostGroup::RemoveMember(const Host::Ptr& host)
        boost::mutex::scoped_lock lock(m_HostGroupMutex);
        m_Members.erase(host);
 }
+
+bool HostGroup::ResolveGroupMembership(Host::Ptr const& host, bool add, int rstack) {
+
+       if (add && rstack > 20) {
+               Log(LogWarning, "icinga", "Too many nested groups for group '" + GetName() + "': Host '" +
+                   host->GetName() + "' membership assignment failed.");
+
+               return false;
+       }
+
+       Array::Ptr groups = GetGroups();
+
+       if (groups && groups->GetLength() > 0) {
+               ObjectLock olock(groups);
+
+               BOOST_FOREACH(const String& name, groups) {
+                       HostGroup::Ptr group = HostGroup::GetByName(name);
+
+                       if (group && !group->ResolveGroupMembership(host, add, rstack + 1))
+                               return false;
+               }
+       }
+
+       if (add)
+               AddMember(host);
+       else
+               RemoveMember(host);
+
+       return true;
+}
index b59b8446d9090dc878a69a8efa2dfc7a991477a5..c0187c7dbd43bad04ec764476b50e94bd161a31a 100644 (file)
@@ -42,6 +42,8 @@ public:
        void AddMember(const Host::Ptr& host);
        void RemoveMember(const Host::Ptr& host);
 
+        bool ResolveGroupMembership(Host::Ptr const& host, bool add = true, int rstack = 0);
+
 private:
        mutable boost::mutex m_HostGroupMutex;
        std::set<Host::Ptr> m_Members;
index 71693eb3b19d9533105e99b7135693c78d4c0c14..43f54c8f63a5b9369b41991038b9f9ccc4a18d78 100644 (file)
@@ -13,6 +13,8 @@ class HostGroup : DynamicObject
                                return m_DisplayName;
                }}}
        };
+
+       [config] Array::Ptr groups;
 };
 
 }
index 455243371f0a70709cd00b3c360721f9d35f92d1..048d6535a6ac031a6ff2a4f77ba0260d8840b85c 100644 (file)
 
 %type HostGroup {
        %attribute %string "display_name"
+
+       %attribute %array "groups" {
+               %attribute %name(HostGroup) "*"
+       },
 }
 
 %type Service %inherits Checkable {
 
 %type ServiceGroup {
        %attribute %string "display_name"
+
+       %attribute %array "groups" {
+               %attribute %name(ServiceGroup) "*"
+       },
 }
 
 %type Notification {
 }
 
 %type UserGroup {
-       %attribute %string "display_name"
+       %attribute %string "display_name",
+
+       %attribute %array "groups" {
+               %attribute %name(UserGroup) "*"
+       },
 }
 
 %type TimePeriod {
index 0fcaecac3505ab366442d8eb7e1473d20dadd9cb..65e2d359dba34c36f55b71c391014ca254e45adb 100644 (file)
@@ -57,7 +57,7 @@ void Service::OnConfigLoaded(void)
                        ServiceGroup::Ptr sg = ServiceGroup::GetByName(name);
 
                        if (sg)
-                               sg->AddMember(GetSelf());
+                               sg->ResolveGroupMembership(GetSelf(), true);
                }
        }
 
index a7ac2782e4e17e32bffdfe61bfcd7f4fbe032df0..9cf1b40424712c1c4e24ac70ba5d48876032deea 100644 (file)
@@ -47,3 +47,33 @@ void ServiceGroup::RemoveMember(const Service::Ptr& service)
        boost::mutex::scoped_lock lock(m_ServiceGroupMutex);
        m_Members.erase(service);
 }
+
+bool ServiceGroup::ResolveGroupMembership(Service::Ptr const& service, bool add, int rstack) {
+
+       if (add && rstack > 20) {
+               Log(LogWarning, "icinga", "Too many nested groups for group '" + GetName() + "': Service '" +
+                   service->GetName() + "' membership assignment failed.");
+
+               return false;
+       }
+
+       Array::Ptr groups = GetGroups();
+
+       if (groups && groups->GetLength() > 0) {
+               ObjectLock olock(groups);
+
+               BOOST_FOREACH(const String& name, groups) {
+                       ServiceGroup::Ptr group = ServiceGroup::GetByName(name);
+
+                       if (group && !group->ResolveGroupMembership(service, add, rstack + 1))
+                               return false;
+               }
+       }
+
+       if (add)
+               AddMember(service);
+       else
+               RemoveMember(service);
+
+       return true;
+}
index 1ad725ea6439f25cc1e93a22ffc5ec7807f3d451..7e93ea5eb420875e5bee4623840b0b7200c8c9dd 100644 (file)
@@ -42,6 +42,8 @@ public:
        void AddMember(const Service::Ptr& service);
        void RemoveMember(const Service::Ptr& service);
 
+        bool ResolveGroupMembership(Service::Ptr const& service, bool add = true, int rstack = 0);
+
 private:
        mutable boost::mutex m_ServiceGroupMutex;
        std::set<Service::Ptr> m_Members;
index c07fb45936d4a30e4caf8fdafdfbb4821523f44b..5d79331eef67424c3ccbe29d6743978672944353 100644 (file)
@@ -13,6 +13,8 @@ class ServiceGroup : DynamicObject
                                return m_DisplayName;
                }}}
        };
+
+       [config] Array::Ptr groups;
 };
 
 }
index a62c4eed368150a4dff911b524010083ab050847..bd9e9a75d9546d83b925293f89223c2598f54c01 100644 (file)
@@ -45,11 +45,12 @@ void User::OnConfigLoaded(void)
                        UserGroup::Ptr ug = UserGroup::GetByName(name);
 
                        if (ug)
-                               ug->AddMember(GetSelf());
+                               ug->ResolveGroupMembership(GetSelf(), true);
                }
        }
 }
 
+
 void User::Stop(void)
 {
        DynamicObject::Stop();
@@ -63,7 +64,7 @@ void User::Stop(void)
                        UserGroup::Ptr ug = UserGroup::GetByName(name);
 
                        if (ug)
-                               ug->RemoveMember(GetSelf());
+                               ug->ResolveGroupMembership(GetSelf(), false);
                }
        }
 }
index 989bc70ff7b338f8aac8e66a267ca13024cb0155..8ff0a88fb3f0b35a0f30e1b9fb7f42dc1a8ea3bc 100644 (file)
@@ -46,3 +46,34 @@ void UserGroup::RemoveMember(const User::Ptr& user)
        boost::mutex::scoped_lock lock(m_UserGroupMutex);
        m_Members.erase(user);
 }
+
+bool UserGroup::ResolveGroupMembership(User::Ptr const& user, bool add, int rstack) {
+
+       if (add && rstack > 20) {
+               Log(LogWarning, "icinga", "Too many nested groups for group '" + GetName() + "': User '" +
+                   user->GetName() + "' membership assignment failed.");
+
+               return false;
+       }
+
+       Array::Ptr groups = GetGroups();
+
+       if (groups && groups->GetLength() > 0) {
+               ObjectLock olock(groups);
+
+               BOOST_FOREACH(const String& name, groups) {
+                       UserGroup::Ptr group = UserGroup::GetByName(name);
+
+                       if (group && !group->ResolveGroupMembership(user, add, rstack + 1))
+                               return false;
+               }
+       }
+
+       if (add)
+               AddMember(user);
+       else
+               RemoveMember(user);
+
+       return true;
+}
+
index 9359827be69e2279859632f49a4d23cda6c761cb..3338c6cda64074e24da4aa1b059deafb228791c1 100644 (file)
@@ -42,6 +42,8 @@ public:
        void AddMember(const User::Ptr& user);
        void RemoveMember(const User::Ptr& user);
 
+        bool ResolveGroupMembership(User::Ptr const& user, bool add = true, int rstack = 0);
+
 private:
        mutable boost::mutex m_UserGroupMutex;
        std::set<User::Ptr> m_Members;
index ebdf73f1f1e45fa2960f7ea77365d93005faf5f1..38606d7986bf1f4b807cd39cdee5e682be03cf9f 100644 (file)
@@ -13,6 +13,8 @@ class UserGroup : DynamicObject
                                return m_DisplayName;
                }}}
        };
+
+       [config] Array::Ptr groups;
 };
 
 }