/******************************************************************************
* Icinga 2 *
- * Copyright (C) 2012-2015 Icinga Development Team (http://www.icinga.org) *
+ * Copyright (C) 2012-2017 Icinga Development Team (https://www.icinga.com/) *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
#include "base/scriptframe.hpp"
#include "base/convert.hpp"
#include "base/exception.hpp"
-#include <boost/foreach.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/join.hpp>
#include <boost/algorithm/string/classification.hpp>
ObjectLock olock(arr);
- BOOST_FOREACH(const Value& arg, arr) {
+ for (const Value& arg : arr) {
/* Note: don't escape macros here. */
Value value = InternalResolveMacros(arg, resolvers, cr, missingMacro,
EscapeCallback(), resolvedMacros, useResolvedMacros, recursionLevel + 1);
ObjectLock olock(dict);
- BOOST_FOREACH(const Dictionary::Pair& kv, dict) {
+ for (const Dictionary::Pair& kv : dict) {
/* Note: don't escape macros here. */
resultDict->Set(kv.first, InternalResolveMacros(kv.second, resolvers, cr, missingMacro,
EscapeCallback(), resolvedMacros, useResolvedMacros, recursionLevel + 1));
tokens.erase(tokens.begin());
}
- BOOST_FOREACH(const ResolverSpec& resolver, resolvers) {
+ for (const ResolverSpec& resolver : resolvers) {
if (!objName.IsEmpty() && objName != resolver.first)
continue;
Value ref = resolver.second;
bool valid = true;
- BOOST_FOREACH(const String& token, tokens) {
+ for (const String& token : tokens) {
if (ref.IsObjectType<Dictionary>()) {
Dictionary::Ptr dict = ref;
if (dict->Contains(token)) {
}
ref = object->GetField(field);
+
+ Field fieldInfo = type->GetFieldInfo(field);
+
+ if (strcmp(fieldInfo.TypeName, "Timestamp") == 0)
+ ref = static_cast<long>(ref);
}
}
return false;
}
-Value MacroProcessor::InternalResolveMacrosShim(const std::vector<Value>& args, const ResolverList& resolvers,
- const CheckResult::Ptr& cr, const MacroProcessor::EscapeCallback& escapeFn, const Dictionary::Ptr& resolvedMacros,
- bool useResolvedMacros, int recursionLevel)
-{
- if (args.size() < 1)
- BOOST_THROW_EXCEPTION(std::invalid_argument("Too few arguments for function"));
-
- String missingMacro;
-
- return MacroProcessor::InternalResolveMacros(args[0], resolvers, cr, &missingMacro, escapeFn,
- resolvedMacros, useResolvedMacros, recursionLevel);
-}
-
-Value MacroProcessor::InternalResolveArgumentsShim(const std::vector<Value>& args, const ResolverList& resolvers,
- const CheckResult::Ptr& cr, const Dictionary::Ptr& resolvedMacros,
- bool useResolvedMacros, int recursionLevel)
-{
- if (args.size() < 2)
- BOOST_THROW_EXCEPTION(std::invalid_argument("Too few arguments for function"));
-
- return MacroProcessor::ResolveArguments(args[0], args[1], resolvers, cr,
- resolvedMacros, useResolvedMacros, recursionLevel);
-}
-
Value MacroProcessor::EvaluateFunction(const Function::Ptr& func, const ResolverList& resolvers,
const CheckResult::Ptr& cr, const MacroProcessor::EscapeCallback& escapeFn,
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros, int recursionLevel)
{
Dictionary::Ptr resolvers_this = new Dictionary();
- BOOST_FOREACH(const ResolverSpec& resolver, resolvers) {
+ for (const ResolverSpec& resolver : resolvers) {
resolvers_this->Set(resolver.first, resolver.second);
}
- resolvers_this->Set("macro", new Function(boost::bind(&MacroProcessor::InternalResolveMacrosShim,
- _1, boost::cref(resolvers), cr, MacroProcessor::EscapeCallback(), resolvedMacros, useResolvedMacros,
- recursionLevel + 1)));
- resolvers_this->Set("resolve_arguments", new Function(boost::bind(&MacroProcessor::InternalResolveArgumentsShim,
- _1, boost::cref(resolvers), cr, resolvedMacros, useResolvedMacros,
- recursionLevel + 1)));
+ auto internalResolveMacrosShim = [resolvers, cr, resolvedMacros, useResolvedMacros, recursionLevel](const std::vector<Value>& args) {
+ if (args.size() < 1)
+ BOOST_THROW_EXCEPTION(std::invalid_argument("Too few arguments for function"));
+
+ String missingMacro;
+
+ return MacroProcessor::InternalResolveMacros(args[0], resolvers, cr, &missingMacro, MacroProcessor::EscapeCallback(),
+ resolvedMacros, useResolvedMacros, recursionLevel);
+ };
+
+ resolvers_this->Set("macro", new Function("macro (temporary)", internalResolveMacrosShim, { "str" }));
+
+ auto internalResolveArgumentsShim = [resolvers, cr, resolvedMacros, useResolvedMacros, recursionLevel](const std::vector<Value>& args) {
+ if (args.size() < 2)
+ BOOST_THROW_EXCEPTION(std::invalid_argument("Too few arguments for function"));
+
+ return MacroProcessor::ResolveArguments(args[0], args[1], resolvers, cr,
+ resolvedMacros, useResolvedMacros, recursionLevel + 1);
+ };
+
+ resolvers_this->Set("resolve_arguments", new Function("resolve_arguments (temporary)", internalResolveArgumentsShim, { "command", "args" }));
- ScriptFrame frame(resolvers_this);
- return func->Invoke();
+ return func->InvokeThis(resolvers_this);
}
Value MacroProcessor::InternalResolveMacros(const String& str, const ResolverList& resolvers,
Array::Ptr resolved_arr = new Array();
ObjectLock olock(arr);
- BOOST_FOREACH(const Value& value, arr) {
+ for (const Value& value : arr) {
if (value.IsScalar()) {
resolved_arr->Add(InternalResolveMacros(value,
- resolvers, cr, missingMacro, EscapeCallback(), Dictionary::Ptr(),
+ resolvers, cr, missingMacro, EscapeCallback(), nullptr,
false, recursionLevel + 1));
} else
resolved_arr->Add(value);
resolved_macro = resolved_arr;
} else if (resolved_macro.IsString()) {
resolved_macro = InternalResolveMacros(resolved_macro,
- resolvers, cr, missingMacro, EscapeCallback(), Dictionary::Ptr(),
+ resolvers, cr, missingMacro, EscapeCallback(), nullptr,
false, recursionLevel + 1);
}
}
return true;
}
+void MacroProcessor::ValidateCustomVars(const ConfigObject::Ptr& object, const Dictionary::Ptr& value)
+{
+ if (!value)
+ return;
+
+ /* string, array, dictionary */
+ ObjectLock olock(value);
+ for (const Dictionary::Pair& kv : value) {
+ const Value& varval = kv.second;
+
+ if (varval.IsObjectType<Dictionary>()) {
+ /* only one dictonary level */
+ Dictionary::Ptr varval_dict = varval;
+
+ ObjectLock xlock(varval_dict);
+ for (const Dictionary::Pair& kv_var : varval_dict) {
+ if (!kv_var.second.IsString())
+ continue;
+
+ if (!ValidateMacroString(kv_var.second))
+ BOOST_THROW_EXCEPTION(ValidationError(object.get(), { "vars", kv.first, kv_var.first }, "Closing $ not found in macro format string '" + kv_var.second + "'."));
+ }
+ } else if (varval.IsObjectType<Array>()) {
+ /* check all array entries */
+ Array::Ptr varval_arr = varval;
+
+ ObjectLock ylock (varval_arr);
+ for (const Value& arrval : varval_arr) {
+ if (!arrval.IsString())
+ continue;
+
+ if (!ValidateMacroString(arrval)) {
+ BOOST_THROW_EXCEPTION(ValidationError(object.get(), { "vars", kv.first }, "Closing $ not found in macro format string '" + arrval + "'."));
+ }
+ }
+ } else {
+ if (!varval.IsString())
+ continue;
+
+ if (!ValidateMacroString(varval))
+ BOOST_THROW_EXCEPTION(ValidationError(object.get(), { "vars", kv.first }, "Closing $ not found in macro format string '" + varval + "'."));
+ }
+ }
+}
+
void MacroProcessor::AddArgumentHelper(const Array::Ptr& args, const String& key, const String& value,
bool add_key, bool add_value)
{
Array::Ptr arr = value;
ObjectLock olock(arr);
- BOOST_FOREACH(const Value& arg, arr) {
+ for (const Value& arg : arr) {
if (result.GetLength() > 0)
result += " ";
{
Value resolvedCommand;
if (!arguments || command.IsObjectType<Array>() || command.IsObjectType<Function>())
- resolvedCommand = MacroProcessor::ResolveMacros(command, resolvers, cr, NULL,
+ resolvedCommand = MacroProcessor::ResolveMacros(command, resolvers, cr, nullptr,
EscapeMacroShellArg, resolvedMacros, useResolvedMacros, recursionLevel + 1);
else {
Array::Ptr arr = new Array();
std::vector<CommandArgument> args;
ObjectLock olock(arguments);
- BOOST_FOREACH(const Dictionary::Pair& kv, arguments) {
+ for (const Dictionary::Pair& kv : arguments) {
const Value& arginfo = kv.second;
CommandArgument arg;
} catch (const std::exception& ex) {
/* tried to convert a string */
Log(LogWarning, "PluginUtility")
- << "Error evaluating set_if value '" << set_if_resolved << "': " << ex.what();
+ << "Error evaluating set_if value '" << set_if_resolved
+ << "' used in argument '" << arg.Key << "': " << ex.what();
continue;
}
}
continue;
}
- args.push_back(arg);
+ args.emplace_back(std::move(arg));
}
std::sort(args.begin(), args.end());
Array::Ptr command_arr = resolvedCommand;
- BOOST_FOREACH(const CommandArgument& arg, args) {
+ for (const CommandArgument& arg : args) {
if (arg.AValue.IsObjectType<Dictionary>()) {
- Log(LogWarning, "PluginUtility", "Tried to use dictionary in argument");
+ Log(LogWarning, "PluginUtility")
+ << "Tried to use dictionary in argument '" << arg.Key << "'.";
continue;
} else if (arg.AValue.IsObjectType<Array>()) {
bool first = true;
Array::Ptr arr = static_cast<Array::Ptr>(arg.AValue);
ObjectLock olock(arr);
- BOOST_FOREACH(const Value& value, arr) {
+ for (const Value& value : arr) {
bool add_key;
if (first) {