Skip to content

Commit

Permalink
Add nested group support for {Host,Service,User}Group.
Browse files Browse the repository at this point in the history
Fixes #5858
  • Loading branch information
Michael Friedrich authored and Michael Friedrich committed Apr 14, 2014
1 parent 3b2f931 commit f48a6b4
Show file tree
Hide file tree
Showing 14 changed files with 125 additions and 6 deletions.
3 changes: 3 additions & 0 deletions doc/4.3-object-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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

Expand Down
4 changes: 2 additions & 2 deletions lib/icinga/host.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ void Host::OnConfigLoaded(void)
HostGroup::Ptr hg = HostGroup::GetByName(name);

if (hg)
hg->AddMember(GetSelf());
hg->ResolveGroupMembership(GetSelf(), true);
}
}
}
Expand All @@ -72,7 +72,7 @@ void Host::Stop(void)
HostGroup::Ptr hg = HostGroup::GetByName(name);

if (hg)
hg->RemoveMember(GetSelf());
hg->ResolveGroupMembership(GetSelf(), false);
}
}

Expand Down
30 changes: 30 additions & 0 deletions lib/icinga/hostgroup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
2 changes: 2 additions & 0 deletions lib/icinga/hostgroup.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ class I2_ICINGA_API HostGroup : public ObjectImpl<HostGroup>
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;
Expand Down
2 changes: 2 additions & 0 deletions lib/icinga/hostgroup.ti
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ class HostGroup : DynamicObject
return m_DisplayName;
}}}
};

[config] Array::Ptr groups;
};

}
14 changes: 13 additions & 1 deletion lib/icinga/icinga-type.conf
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@

%type HostGroup {
%attribute %string "display_name"

%attribute %array "groups" {
%attribute %name(HostGroup) "*"
},
}

%type Service %inherits Checkable {
Expand All @@ -87,6 +91,10 @@

%type ServiceGroup {
%attribute %string "display_name"

%attribute %array "groups" {
%attribute %name(ServiceGroup) "*"
},
}

%type Notification {
Expand Down Expand Up @@ -149,7 +157,11 @@
}

%type UserGroup {
%attribute %string "display_name"
%attribute %string "display_name",

%attribute %array "groups" {
%attribute %name(UserGroup) "*"
},
}

%type TimePeriod {
Expand Down
2 changes: 1 addition & 1 deletion lib/icinga/service.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ void Service::OnConfigLoaded(void)
ServiceGroup::Ptr sg = ServiceGroup::GetByName(name);

if (sg)
sg->AddMember(GetSelf());
sg->ResolveGroupMembership(GetSelf(), true);
}
}

Expand Down
30 changes: 30 additions & 0 deletions lib/icinga/servicegroup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
2 changes: 2 additions & 0 deletions lib/icinga/servicegroup.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ class I2_ICINGA_API ServiceGroup : public ObjectImpl<ServiceGroup>
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;
Expand Down
2 changes: 2 additions & 0 deletions lib/icinga/servicegroup.ti
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ class ServiceGroup : DynamicObject
return m_DisplayName;
}}}
};

[config] Array::Ptr groups;
};

}
5 changes: 3 additions & 2 deletions lib/icinga/user.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -63,7 +64,7 @@ void User::Stop(void)
UserGroup::Ptr ug = UserGroup::GetByName(name);

if (ug)
ug->RemoveMember(GetSelf());
ug->ResolveGroupMembership(GetSelf(), false);
}
}
}
Expand Down
31 changes: 31 additions & 0 deletions lib/icinga/usergroup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

2 changes: 2 additions & 0 deletions lib/icinga/usergroup.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ class I2_ICINGA_API UserGroup : public ObjectImpl<UserGroup>
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;
Expand Down
2 changes: 2 additions & 0 deletions lib/icinga/usergroup.ti
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ class UserGroup : DynamicObject
return m_DisplayName;
}}}
};

[config] Array::Ptr groups;
};

}

0 comments on commit f48a6b4

Please sign in to comment.