]> granicus.if.org Git - icinga2/blob - lib/icinga/servicegroup.cpp
Merge pull request #6999 from Icinga/bugfix/compiler-warnings
[icinga2] / lib / icinga / servicegroup.cpp
1 /* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
2
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"
12
13 using namespace icinga;
14
15 REGISTER_TYPE(ServiceGroup);
16
17 INITIALIZE_ONCE([]() {
18         ObjectRule::RegisterType("ServiceGroup");
19 });
20
21 bool ServiceGroup::EvaluateObjectRule(const Service::Ptr& service, const ConfigItem::Ptr& group)
22 {
23         String groupName = group->GetName();
24
25         CONTEXT("Evaluating rule for group '" + groupName + "'");
26
27         Host::Ptr host = service->GetHost();
28
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);
34
35         if (!group->GetFilter()->Evaluate(frame).GetValue().ToBool())
36                 return false;
37
38         Log(LogDebug, "ServiceGroup")
39                 << "Assigning membership for group '" << groupName << "' to service '" << service->GetName() << "'";
40
41         Array::Ptr groups = service->GetGroups();
42
43         if (groups && !groups->Contains(groupName))
44                 groups->Add(groupName);
45
46         return true;
47 }
48
49 void ServiceGroup::EvaluateObjectRules(const Service::Ptr& service)
50 {
51         CONTEXT("Evaluating group membership for service '" + service->GetName() + "'");
52
53         for (const ConfigItem::Ptr& group : ConfigItem::GetItems(ServiceGroup::TypeInstance))
54         {
55                 if (!group->GetFilter())
56                         continue;
57
58                 EvaluateObjectRule(service, group);
59         }
60 }
61
62 std::set<Service::Ptr> ServiceGroup::GetMembers() const
63 {
64         boost::mutex::scoped_lock lock(m_ServiceGroupMutex);
65         return m_Members;
66 }
67
68 void ServiceGroup::AddMember(const Service::Ptr& service)
69 {
70         service->AddGroup(GetName());
71
72         boost::mutex::scoped_lock lock(m_ServiceGroupMutex);
73         m_Members.insert(service);
74 }
75
76 void ServiceGroup::RemoveMember(const Service::Ptr& service)
77 {
78         boost::mutex::scoped_lock lock(m_ServiceGroupMutex);
79         m_Members.erase(service);
80 }
81
82 bool ServiceGroup::ResolveGroupMembership(const Service::Ptr& service, bool add, int rstack) {
83
84         if (add && rstack > 20) {
85                 Log(LogWarning, "ServiceGroup")
86                         << "Too many nested groups for group '" << GetName() << "': Service '"
87                         << service->GetName() << "' membership assignment failed.";
88
89                 return false;
90         }
91
92         Array::Ptr groups = GetGroups();
93
94         if (groups && groups->GetLength() > 0) {
95                 ObjectLock olock(groups);
96
97                 for (const String& name : groups) {
98                         ServiceGroup::Ptr group = ServiceGroup::GetByName(name);
99
100                         if (group && !group->ResolveGroupMembership(service, add, rstack + 1))
101                                 return false;
102                 }
103         }
104
105         if (add)
106                 AddMember(service);
107         else
108                 RemoveMember(service);
109
110         return true;
111 }