void NamespaceBehavior::Remove(const Namespace::Ptr& ns, const String& field, bool overrideFrozen) { if (!overrideFrozen) { auto attr = ns->GetAttribute(field); if (dynamic_pointer_cast<ConstEmbeddedNamespaceValue>(attr)) BOOST_THROW_EXCEPTION(ScriptError("Constants must not be removed.")); } ns->RemoveAttribute(field); }
std::vector<String> ConsoleHandler::GetAutocompletionSuggestions(const String& word, ScriptFrame& frame) { std::vector<String> matches; for (const String& keyword : ConfigWriter::GetKeywords()) { AddSuggestion(matches, word, keyword); } { ObjectLock olock(frame.Locals); for (const Dictionary::Pair& kv : frame.Locals) { AddSuggestion(matches, word, kv.first); } } { ObjectLock olock(ScriptGlobal::GetGlobals()); for (const Namespace::Pair& kv : ScriptGlobal::GetGlobals()) { AddSuggestion(matches, word, kv.first); } } Namespace::Ptr systemNS = ScriptGlobal::Get("System"); AddSuggestions(matches, word, "", false, systemNS); AddSuggestions(matches, word, "", true, systemNS->Get("Configuration")); AddSuggestions(matches, word, "", false, ScriptGlobal::Get("Types")); AddSuggestions(matches, word, "", false, ScriptGlobal::Get("Icinga")); String::SizeType cperiod = word.RFind("."); if (cperiod != String::NPos) { String pword = word.SubStr(0, cperiod); Value value; try { std::unique_ptr<Expression> expr = ConfigCompiler::CompileText("temp", pword); if (expr) value = expr->Evaluate(frame); AddSuggestions(matches, word, pword, true, value); } catch (...) { /* Ignore the exception */ } } return matches; }
void ConstNamespaceBehavior::Register(const Namespace::Ptr& ns, const String& field, const Value& value, bool overrideFrozen, const DebugInfo& debugInfo) const { if (m_Frozen && !overrideFrozen) BOOST_THROW_EXCEPTION(ScriptError("Namespace is read-only and must not be modified.", debugInfo)); ns->SetAttribute(field, std::make_shared<ConstEmbeddedNamespaceValue>(value)); }
bool FilterUtility::EvaluateFilter(ScriptFrame& frame, Expression *filter, const Object::Ptr& target, const String& variableName) { if (!filter) return true; Type::Ptr type = target->GetReflectionType(); String varName; if (variableName.IsEmpty()) varName = type->GetName().ToLower(); else varName = variableName; Namespace::Ptr frameNS; if (frame.Self.IsEmpty()) { frameNS = new Namespace(); frame.Self = frameNS; } else { /* Enforce a namespace object for 'frame.self'. */ ASSERT(frame.Self.IsObjectType<Namespace>()); frameNS = frame.Self; } frameNS->Set("obj", target); frameNS->Set(varName, target); for (int fid = 0; fid < type->GetFieldCount(); fid++) { Field field = type->GetFieldInfo(fid); if ((field.Attributes & FANavigation) == 0) continue; Object::Ptr joinedObj = target->NavigateField(fid); if (field.NavigationName) frameNS->Set(field.NavigationName, joinedObj); else frameNS->Set(field.Name, joinedObj); } return Convert::ToBool(filter->Evaluate(frame)); }
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * ******************************************************************************/ #include "base/dictionary.hpp" #include "base/function.hpp" #include "base/functionwrapper.hpp" #include "base/scriptframe.hpp" #include "base/initialize.hpp" #include "base/json.hpp" using namespace icinga; static String JsonEncodeShim(const Value& value) { return JsonEncode(value); } INITIALIZE_ONCE([]() { auto jsonNSBehavior = new ConstNamespaceBehavior(); Namespace::Ptr jsonNS = new Namespace(jsonNSBehavior); /* Methods */ jsonNS->Set("encode", new Function("Json#encode", JsonEncodeShim, { "value" }, true)); jsonNS->Set("decode", new Function("Json#decode", JsonDecode, { "value" }, true)); jsonNSBehavior->Freeze(); Namespace::Ptr systemNS = ScriptGlobal::Get("System"); systemNS->SetAttribute("Json", std::make_shared<ConstEmbeddedNamespaceValue>(jsonNS)); });
std::vector<Value> FilterUtility::GetFilterTargets(const QueryDescription& qd, const Dictionary::Ptr& query, const ApiUser::Ptr& user, const String& variableName) { std::vector<Value> result; TargetProvider::Ptr provider; if (qd.Provider) provider = qd.Provider; else provider = new ConfigObjectTargetProvider(); Expression *permissionFilter; CheckPermission(user, qd.Permission, &permissionFilter); ScriptFrame permissionFrame(true); for (const String& type : qd.Types) { String attr = type; boost::algorithm::to_lower(attr); if (attr == "type") attr = "name"; if (query && query->Contains(attr)) { String name = HttpUtility::GetLastParameter(query, attr); Object::Ptr target = provider->GetTargetByName(type, name); if (!FilterUtility::EvaluateFilter(permissionFrame, permissionFilter, target, variableName)) BOOST_THROW_EXCEPTION(ScriptError("Access denied to object '" + name + "' of type '" + type + "'")); result.emplace_back(std::move(target)); } attr = provider->GetPluralName(type); boost::algorithm::to_lower(attr); if (query && query->Contains(attr)) { Array::Ptr names = query->Get(attr); if (names) { ObjectLock olock(names); for (const String& name : names) { Object::Ptr target = provider->GetTargetByName(type, name); if (!FilterUtility::EvaluateFilter(permissionFrame, permissionFilter, target, variableName)) BOOST_THROW_EXCEPTION(ScriptError("Access denied to object '" + name + "' of type '" + type + "'")); result.emplace_back(std::move(target)); } } } } if ((query && query->Contains("filter")) || result.empty()) { if (!query->Contains("type")) BOOST_THROW_EXCEPTION(std::invalid_argument("Type must be specified when using a filter.")); String type = HttpUtility::GetLastParameter(query, "type"); if (!provider->IsValidType(type)) BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid type specified.")); if (qd.Types.find(type) == qd.Types.end()) BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid type specified for this query.")); ScriptFrame frame(true); frame.Sandboxed = true; Namespace::Ptr frameNS = new Namespace(); if (query->Contains("filter")) { String filter = HttpUtility::GetLastParameter(query, "filter"); std::unique_ptr<Expression> ufilter = ConfigCompiler::CompileText("<API query>", filter); Dictionary::Ptr filter_vars = query->Get("filter_vars"); if (filter_vars) { ObjectLock olock(filter_vars); for (const Dictionary::Pair& kv : filter_vars) { frameNS->Set(kv.first, kv.second); } } frame.Self = frameNS; provider->FindTargets(type, std::bind(&FilteredAddTarget, std::ref(permissionFrame), permissionFilter, std::ref(frame), &*ufilter, std::ref(result), variableName, _1)); } else { /* Ensure to pass a nullptr as filter expression. * GCC 8.1.1 on F28 causes problems, see GH #6533. */ provider->FindTargets(type, std::bind(&FilteredAddTarget, std::ref(permissionFrame), permissionFilter, std::ref(frame), nullptr, std::ref(result), variableName, _1)); } } return result; }
bool DaemonUtility::ValidateConfigFiles(const std::vector<std::string>& configs, const String& objectsFile) { bool success; if (!objectsFile.IsEmpty()) ConfigCompilerContext::GetInstance()->OpenObjectsFile(objectsFile); if (!configs.empty()) { for (const String& configPath : configs) { try { std::unique_ptr<Expression> expression = ConfigCompiler::CompileFile(configPath, String(), "_etc"); success = ExecuteExpression(&*expression); if (!success) return false; } catch (const std::exception& ex) { Log(LogCritical, "cli", "Could not compile config files: " + DiagnosticInformation(ex, false)); Application::Exit(1); } } } /* Load cluster config files from /etc/icinga2/zones.d. * This should probably be in libremote but * unfortunately moving it there is somewhat non-trivial. */ success = true; String zonesEtcDir = Configuration::ZonesDir; if (!zonesEtcDir.IsEmpty() && Utility::PathExists(zonesEtcDir)) Utility::Glob(zonesEtcDir + "/*", std::bind(&IncludeZoneDirRecursive, _1, "_etc", std::ref(success)), GlobDirectory); if (!success) return false; /* Load package config files - they may contain additional zones which * are authoritative on this node and are checked in HasZoneConfigAuthority(). */ String packagesVarDir = Configuration::DataDir + "/api/packages"; if (Utility::PathExists(packagesVarDir)) Utility::Glob(packagesVarDir + "/*", std::bind(&IncludePackage, _1, std::ref(success)), GlobDirectory); if (!success) return false; /* Load cluster synchronized configuration files */ String zonesVarDir = Configuration::DataDir + "/api/zones"; if (Utility::PathExists(zonesVarDir)) Utility::Glob(zonesVarDir + "/*", std::bind(&IncludeNonLocalZone, _1, "_cluster", std::ref(success)), GlobDirectory); if (!success) return false; Namespace::Ptr systemNS = ScriptGlobal::Get("System"); VERIFY(systemNS); /* This is initialized inside the IcingaApplication class. */ Value vAppType; VERIFY(systemNS->Get("ApplicationType", &vAppType)); Type::Ptr appType = Type::GetByName(vAppType); if (ConfigItem::GetItems(appType).empty()) { ConfigItemBuilder builder; builder.SetType(appType); builder.SetName("app"); builder.AddExpression(new ImportDefaultTemplatesExpression()); ConfigItem::Ptr item = builder.Compile(); item->Register(); } return true; }
Namespace::Iterator icinga::end(const Namespace::Ptr& x) { return x->End(); }
Namespace::Iterator icinga::begin(const Namespace::Ptr& x) { return x->Begin(); }
void NamespaceBehavior::Register(const Namespace::Ptr& ns, const String& field, const Value& value, bool overrideFrozen, const DebugInfo& debugInfo) const { ns->SetAttribute(field, std::make_shared<EmbeddedNamespaceValue>(value)); }