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 Notification::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); Dictionary::Ptr locals = make_shared<Dictionary>(); locals->Set("host", host); if (service) locals->Set("service", service); if (!rule.EvaluateFilter(locals)) return false; std::ostringstream msgbuf2; msgbuf2 << "Applying notification '" << rule.GetName() << "' to object '" << checkable->GetName() << "' for rule " << di; Log(LogDebug, "icinga", msgbuf2.str()); ConfigItemBuilder::Ptr builder = make_shared<ConfigItemBuilder>(di); builder->SetType("Notification"); builder->SetName(rule.GetName()); builder->SetScope(rule.GetScope()); builder->AddExpression(make_shared<AExpression>(&AExpression::OpSet, make_shared<AExpression>(&AExpression::OpLiteral, "host_name", di), make_shared<AExpression>(&AExpression::OpLiteral, host->GetName(), di), di)); if (service) { builder->AddExpression(make_shared<AExpression>(&AExpression::OpSet, make_shared<AExpression>(&AExpression::OpLiteral, "service_name", di), make_shared<AExpression>(&AExpression::OpLiteral, service->GetShortName(), di), di)); } builder->AddExpression(rule.GetExpression()); ConfigItem::Ptr notificationItem = builder->Compile(); notificationItem->Register(); DynamicObject::Ptr dobj = notificationItem->Commit(); dobj->OnConfigLoaded(); return true; }
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; }