1 /* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
3 #include "icinga/servicegroup.hpp"
4 #include "icinga/servicegroup-ti.cpp"
5 #include "config/objectrule.hpp"
6 #include "config/configitem.hpp"
7 #include "base/configtype.hpp"
8 #include "base/objectlock.hpp"
9 #include "base/logger.hpp"
10 #include "base/context.hpp"
11 #include "base/workqueue.hpp"
13 using namespace icinga;
15 REGISTER_TYPE(ServiceGroup);
17 INITIALIZE_ONCE([]() {
18 ObjectRule::RegisterType("ServiceGroup");
21 bool ServiceGroup::EvaluateObjectRule(const Service::Ptr& service, const ConfigItem::Ptr& group)
23 String groupName = group->GetName();
25 CONTEXT("Evaluating rule for group '" + groupName + "'");
27 Host::Ptr host = service->GetHost();
29 ScriptFrame frame(true);
30 if (group->GetScope())
31 group->GetScope()->CopyTo(frame.Locals);
32 frame.Locals->Set("host", host);
33 frame.Locals->Set("service", service);
35 if (!group->GetFilter()->Evaluate(frame).GetValue().ToBool())
38 Log(LogDebug, "ServiceGroup")
39 << "Assigning membership for group '" << groupName << "' to service '" << service->GetName() << "'";
41 Array::Ptr groups = service->GetGroups();
43 if (groups && !groups->Contains(groupName))
44 groups->Add(groupName);
49 void ServiceGroup::EvaluateObjectRules(const Service::Ptr& service)
51 CONTEXT("Evaluating group membership for service '" + service->GetName() + "'");
53 for (const ConfigItem::Ptr& group : ConfigItem::GetItems(ServiceGroup::TypeInstance))
55 if (!group->GetFilter())
58 EvaluateObjectRule(service, group);
62 std::set<Service::Ptr> ServiceGroup::GetMembers() const
64 boost::mutex::scoped_lock lock(m_ServiceGroupMutex);
68 void ServiceGroup::AddMember(const Service::Ptr& service)
70 service->AddGroup(GetName());
72 boost::mutex::scoped_lock lock(m_ServiceGroupMutex);
73 m_Members.insert(service);
76 void ServiceGroup::RemoveMember(const Service::Ptr& service)
78 boost::mutex::scoped_lock lock(m_ServiceGroupMutex);
79 m_Members.erase(service);
82 bool ServiceGroup::ResolveGroupMembership(const Service::Ptr& service, bool add, int rstack) {
84 if (add && rstack > 20) {
85 Log(LogWarning, "ServiceGroup")
86 << "Too many nested groups for group '" << GetName() << "': Service '"
87 << service->GetName() << "' membership assignment failed.";
92 Array::Ptr groups = GetGroups();
94 if (groups && groups->GetLength() > 0) {
95 ObjectLock olock(groups);
97 for (const String& name : groups) {
98 ServiceGroup::Ptr group = ServiceGroup::GetByName(name);
100 if (group && !group->ResolveGroupMembership(service, add, rstack + 1))
108 RemoveMember(service);