bool Dependency::EvaluateApplyRule(const Checkable::Ptr& checkable, const ApplyRule& rule) { DebugInfo di = rule.GetDebugInfo(); std::ostringstream msgbuf; msgbuf << "Evaluating 'apply' rule (" << di << ")"; CONTEXT(msgbuf.str()); Host::Ptr host; Service::Ptr service; tie(host, service) = GetHostService(checkable); ScriptFrame frame; if (rule.GetScope()) rule.GetScope()->CopyTo(frame.Locals); frame.Locals->Set("host", host); if (service) frame.Locals->Set("service", service); Value vinstances; if (rule.GetFTerm()) { try { vinstances = rule.GetFTerm()->Evaluate(frame); } catch (const std::exception&) { /* Silently ignore errors here and assume there are no instances. */ return false; } } else { Array::Ptr instances = new Array(); instances->Add(""); vinstances = instances; } bool match = false; if (vinstances.IsObjectType<Array>()) { if (!rule.GetFVVar().IsEmpty()) BOOST_THROW_EXCEPTION(ScriptError("Array iterator requires value to be an array.", di)); Array::Ptr arr = vinstances; Array::Ptr arrclone = arr->ShallowClone(); ObjectLock olock(arrclone); BOOST_FOREACH(const Value& instance, arrclone) { String name = rule.GetName(); if (!rule.GetFKVar().IsEmpty()) { frame.Locals->Set(rule.GetFKVar(), instance); name += instance; } if (EvaluateApplyRuleInstance(checkable, name, frame, rule)) match = true; } } else if (vinstances.IsObjectType<Dictionary>()) {
bool ScheduledDowntime::EvaluateApplyRule(const Checkable::Ptr& checkable, const ApplyRule& rule) { DebugInfo di = rule.GetDebugInfo(); std::ostringstream msgbuf; msgbuf << "Evaluating 'apply' rule (" << di << ")"; CONTEXT(msgbuf.str()); Host::Ptr host; Service::Ptr service; tie(host, service) = GetHostService(checkable); VMFrame frame; if (rule.GetScope()) rule.GetScope()->CopyTo(frame.Locals); frame.Locals->Set("host", host); if (service) frame.Locals->Set("service", service); if (!rule.EvaluateFilter(frame)) return false; Value vinstances; if (rule.GetFTerm()) { vinstances = rule.GetFTerm()->Evaluate(frame); } else { Array::Ptr instances = new Array(); instances->Add(""); vinstances = instances; } if (vinstances.IsObjectType<Array>()) { if (!rule.GetFVVar().IsEmpty()) BOOST_THROW_EXCEPTION(ConfigError("Array iterator requires value to be an array.") << errinfo_debuginfo(di)); Array::Ptr arr = vinstances; ObjectLock olock(arr); BOOST_FOREACH(const String& instance, arr) { String name = rule.GetName(); if (!rule.GetFKVar().IsEmpty()) { frame.Locals->Set(rule.GetFKVar(), instance); name += instance; } EvaluateApplyRuleInstance(checkable, name, frame, rule); } } else if (vinstances.IsObjectType<Dictionary>()) {
bool Service::EvaluateApplyRule(const Host::Ptr& host, const ApplyRule& rule) { DebugInfo di = rule.GetDebugInfo(); std::ostringstream msgbuf; msgbuf << "Evaluating 'apply' rule (" << di << ")"; CONTEXT(msgbuf.str()); ScriptFrame frame; if (rule.GetScope()) rule.GetScope()->CopyTo(frame.Locals); frame.Locals->Set("host", host); Value vinstances; if (rule.GetFTerm()) { try { vinstances = rule.GetFTerm()->Evaluate(frame); } catch (const std::exception&) { /* Silently ignore errors here and assume there are no instances. */ return false; } } else { Array::Ptr instances = new Array(); instances->Add(""); vinstances = instances; } bool match = false; if (vinstances.IsObjectType<Array>()) { if (!rule.GetFVVar().IsEmpty()) BOOST_THROW_EXCEPTION(ScriptError("Dictionary iterator requires value to be a dictionary.", di)); Array::Ptr arr = vinstances; ObjectLock olock(arr); for (const Value& instance : arr) { String name = rule.GetName(); if (!rule.GetFKVar().IsEmpty()) { frame.Locals->Set(rule.GetFKVar(), instance); name += instance; } if (EvaluateApplyRuleInstance(host, name, frame, rule)) match = true; } } else if (vinstances.IsObjectType<Dictionary>()) { if (rule.GetFVVar().IsEmpty()) BOOST_THROW_EXCEPTION(ScriptError("Array iterator requires value to be an array.", di)); Dictionary::Ptr dict = vinstances; for (const String& key : dict->GetKeys()) { frame.Locals->Set(rule.GetFKVar(), key); frame.Locals->Set(rule.GetFVVar(), dict->Get(key)); if (EvaluateApplyRuleInstance(host, rule.GetName() + key, frame, rule)) match = true; } } return match; }