]> granicus.if.org Git - icinga2/blob - lib/icinga/scheduleddowntime-apply.cpp
Correct current_concurrent_checks to actually running checks
[icinga2] / lib / icinga / scheduleddowntime-apply.cpp
1 /* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
2
3 #include "icinga/scheduleddowntime.hpp"
4 #include "icinga/service.hpp"
5 #include "config/configitembuilder.hpp"
6 #include "config/applyrule.hpp"
7 #include "base/initialize.hpp"
8 #include "base/configtype.hpp"
9 #include "base/logger.hpp"
10 #include "base/context.hpp"
11 #include "base/exception.hpp"
12
13 using namespace icinga;
14
15 INITIALIZE_ONCE([]() {
16         ApplyRule::RegisterType("ScheduledDowntime", { "Host", "Service" });
17 });
18
19 bool ScheduledDowntime::EvaluateApplyRuleInstance(const Checkable::Ptr& checkable, const String& name, ScriptFrame& frame, const ApplyRule& rule)
20 {
21         if (!rule.EvaluateFilter(frame))
22                 return false;
23
24         DebugInfo di = rule.GetDebugInfo();
25
26 #ifdef _DEBUG
27         Log(LogDebug, "ScheduledDowntime")
28                 << "Applying scheduled downtime '" << rule.GetName() << "' to object '" << checkable->GetName() << "' for rule " << di;
29 #endif /* _DEBUG */
30
31         ConfigItemBuilder builder{di};
32         builder.SetType(ScheduledDowntime::TypeInstance);
33         builder.SetName(name);
34         builder.SetScope(frame.Locals->ShallowClone());
35         builder.SetIgnoreOnError(rule.GetIgnoreOnError());
36
37         Host::Ptr host;
38         Service::Ptr service;
39         tie(host, service) = GetHostService(checkable);
40
41         builder.AddExpression(new SetExpression(MakeIndexer(ScopeThis, "host_name"), OpSetLiteral, MakeLiteral(host->GetName()), di));
42
43         if (service)
44                 builder.AddExpression(new SetExpression(MakeIndexer(ScopeThis, "service_name"), OpSetLiteral, MakeLiteral(service->GetShortName()), di));
45
46         String zone = checkable->GetZoneName();
47
48         if (!zone.IsEmpty())
49                 builder.AddExpression(new SetExpression(MakeIndexer(ScopeThis, "zone"), OpSetLiteral, MakeLiteral(zone), di));
50
51         builder.AddExpression(new SetExpression(MakeIndexer(ScopeThis, "package"), OpSetLiteral, MakeLiteral(rule.GetPackage()), di));
52
53         builder.AddExpression(new OwnedExpression(rule.GetExpression()));
54
55         builder.AddExpression(new ImportDefaultTemplatesExpression());
56
57         ConfigItem::Ptr downtimeItem = builder.Compile();
58         downtimeItem->Register();
59
60         return true;
61 }
62
63 bool ScheduledDowntime::EvaluateApplyRule(const Checkable::Ptr& checkable, const ApplyRule& rule)
64 {
65         DebugInfo di = rule.GetDebugInfo();
66
67         std::ostringstream msgbuf;
68         msgbuf << "Evaluating 'apply' rule (" << di << ")";
69         CONTEXT(msgbuf.str());
70
71         Host::Ptr host;
72         Service::Ptr service;
73         tie(host, service) = GetHostService(checkable);
74
75         ScriptFrame frame(true);
76         if (rule.GetScope())
77                 rule.GetScope()->CopyTo(frame.Locals);
78         frame.Locals->Set("host", host);
79         if (service)
80                 frame.Locals->Set("service", service);
81
82         Value vinstances;
83
84         if (rule.GetFTerm()) {
85                 try {
86                         vinstances = rule.GetFTerm()->Evaluate(frame);
87                 } catch (const std::exception&) {
88                         /* Silently ignore errors here and assume there are no instances. */
89                         return false;
90                 }
91         } else {
92                 vinstances = new Array({ "" });
93         }
94
95         bool match = false;
96
97         if (vinstances.IsObjectType<Array>()) {
98                 if (!rule.GetFVVar().IsEmpty())
99                         BOOST_THROW_EXCEPTION(ScriptError("Dictionary iterator requires value to be a dictionary.", di));
100
101                 Array::Ptr arr = vinstances;
102
103                 ObjectLock olock(arr);
104                 for (const Value& instance : arr) {
105                         String name = rule.GetName();
106
107                         if (!rule.GetFKVar().IsEmpty()) {
108                                 frame.Locals->Set(rule.GetFKVar(), instance);
109                                 name += instance;
110                         }
111
112                         if (EvaluateApplyRuleInstance(checkable, name, frame, rule))
113                                 match = true;
114                 }
115         } else if (vinstances.IsObjectType<Dictionary>()) {
116                 if (rule.GetFVVar().IsEmpty())
117                         BOOST_THROW_EXCEPTION(ScriptError("Array iterator requires value to be an array.", di));
118
119                 Dictionary::Ptr dict = vinstances;
120
121                 for (const String& key : dict->GetKeys()) {
122                         frame.Locals->Set(rule.GetFKVar(), key);
123                         frame.Locals->Set(rule.GetFVVar(), dict->Get(key));
124
125                         if (EvaluateApplyRuleInstance(checkable, rule.GetName() + key, frame, rule))
126                                 match = true;
127                 }
128         }
129
130         return match;
131 }
132
133 void ScheduledDowntime::EvaluateApplyRules(const Host::Ptr& host)
134 {
135         CONTEXT("Evaluating 'apply' rules for host '" + host->GetName() + "'");
136
137         for (ApplyRule& rule : ApplyRule::GetRules("ScheduledDowntime")) {
138                 if (rule.GetTargetType() != "Host")
139                         continue;
140
141                 if (EvaluateApplyRule(host, rule))
142                         rule.AddMatch();
143         }
144 }
145
146 void ScheduledDowntime::EvaluateApplyRules(const Service::Ptr& service)
147 {
148         CONTEXT("Evaluating 'apply' rules for service '" + service->GetName() + "'");
149
150         for (ApplyRule& rule : ApplyRule::GetRules("ScheduledDowntime")) {
151                 if (rule.GetTargetType() != "Service")
152                         continue;
153
154                 if (EvaluateApplyRule(service, rule))
155                         rule.AddMatch();
156         }
157 }