diff --git a/lib/icinga/command.cpp b/lib/icinga/command.cpp index 298bfc5b5..3919e1886 100644 --- a/lib/icinga/command.cpp +++ b/lib/icinga/command.cpp @@ -44,6 +44,11 @@ Array::Ptr Command::GetExportMacros(void) const return m_ExportMacros; } +Array::Ptr Command::GetEscapeMacros(void) const +{ + return m_EscapeMacros; +} + bool Command::ResolveMacro(const String& macro, const Dictionary::Ptr&, String *result) const { Dictionary::Ptr macros = GetMacros(); @@ -65,6 +70,7 @@ void Command::InternalSerialize(const Dictionary::Ptr& bag, int attributeTypes) bag->Set("timeout", m_Timeout); bag->Set("macros", m_Macros); bag->Set("export_macros", m_ExportMacros); + bag->Set("escape_macros", m_EscapeMacros); } } @@ -78,5 +84,6 @@ void Command::InternalDeserialize(const Dictionary::Ptr& bag, int attributeTypes m_Macros = bag->Get("macros"); m_Macros = bag->Get("macros"); m_ExportMacros = bag->Get("export_macros"); + m_EscapeMacros = bag->Get("escape_macros"); } } diff --git a/lib/icinga/command.h b/lib/icinga/command.h index e4fedc260..ca6e782a6 100644 --- a/lib/icinga/command.h +++ b/lib/icinga/command.h @@ -47,6 +47,7 @@ public: Dictionary::Ptr GetMacros(void) const; Array::Ptr GetExportMacros(void) const; + Array::Ptr GetEscapeMacros(void) const; virtual bool ResolveMacro(const String& macro, const Dictionary::Ptr& cr, String *result) const; protected: @@ -58,6 +59,7 @@ private: Value m_Timeout; Dictionary::Ptr m_Macros; Array::Ptr m_ExportMacros; + Array::Ptr m_EscapeMacros; }; } diff --git a/lib/icinga/icinga-type.conf b/lib/icinga/icinga-type.conf index 3962611f4..5685df4b7 100644 --- a/lib/icinga/icinga-type.conf +++ b/lib/icinga/icinga-type.conf @@ -368,6 +368,9 @@ type Command { %attribute array "export_macros" { %attribute string "*" }, + %attribute array "escape_macros" { + %attribute string "*" + }, %attribute dictionary "macros" { %attribute string "*" }, diff --git a/lib/icinga/macroprocessor.cpp b/lib/icinga/macroprocessor.cpp index 26dbd41f7..dc7409a4f 100644 --- a/lib/icinga/macroprocessor.cpp +++ b/lib/icinga/macroprocessor.cpp @@ -30,12 +30,12 @@ using namespace icinga; Value MacroProcessor::ResolveMacros(const Value& str, const std::vector& resolvers, - const Dictionary::Ptr& cr, const MacroProcessor::EscapeCallback& escapeFn) + const Dictionary::Ptr& cr, const MacroProcessor::EscapeCallback& escapeFn, const Array::Ptr& escapeMacros) { Value result; if (str.IsScalar()) { - result = InternalResolveMacros(str, resolvers, cr, escapeFn); + result = InternalResolveMacros(str, resolvers, cr, escapeFn, escapeMacros); } else if (str.IsObjectType()) { Array::Ptr resultArr = boost::make_shared(); Array::Ptr arr = str; @@ -44,7 +44,7 @@ Value MacroProcessor::ResolveMacros(const Value& str, const std::vectorAdd(InternalResolveMacros(arg, resolvers, cr, EscapeCallback())); + resultArr->Add(InternalResolveMacros(arg, resolvers, cr, EscapeCallback(), Array::Ptr())); } result = resultArr; @@ -68,7 +68,7 @@ bool MacroProcessor::ResolveMacro(const String& macro, const std::vector& resolvers, - const Dictionary::Ptr& cr, const MacroProcessor::EscapeCallback& escapeFn) + const Dictionary::Ptr& cr, const MacroProcessor::EscapeCallback& escapeFn, const Array::Ptr& escapeMacros) { size_t offset, pos_first, pos_second; offset = 0; @@ -94,8 +94,20 @@ String MacroProcessor::InternalResolveMacros(const String& str, const std::vecto if (!found) Log(LogWarning, "icinga", "Macro '" + name + "' is not defined."); - if (escapeFn) - resolved_macro = escapeFn(resolved_macro); + if (escapeFn && escapeMacros) { + bool escape = false; + + ObjectLock olock(escapeMacros); + BOOST_FOREACH(const String& escapeMacro, escapeMacros) { + if (escapeMacro == name) { + escape = true; + break; + } + } + + if (escape) + resolved_macro = escapeFn(resolved_macro); + } result.Replace(pos_first, pos_second - pos_first + 1, resolved_macro); offset = pos_first + resolved_macro.GetLength(); diff --git a/lib/icinga/macroprocessor.h b/lib/icinga/macroprocessor.h index f6cea05fd..8985fef14 100644 --- a/lib/icinga/macroprocessor.h +++ b/lib/icinga/macroprocessor.h @@ -23,6 +23,7 @@ #include "icinga/i2-icinga.h" #include "icinga/macroresolver.h" #include "base/dictionary.h" +#include "base/array.h" #include #include @@ -40,7 +41,7 @@ public: typedef boost::function EscapeCallback; static Value ResolveMacros(const Value& str, const std::vector& resolvers, - const Dictionary::Ptr& cr, const EscapeCallback& escapeFn = EscapeCallback()); + const Dictionary::Ptr& cr, const EscapeCallback& escapeFn = EscapeCallback(), const Array::Ptr& escapeMacros = Array::Ptr()); static bool ResolveMacro(const String& macro, const std::vector& resolvers, const Dictionary::Ptr& cr, String *result); @@ -49,7 +50,7 @@ private: static String InternalResolveMacros(const String& str, const std::vector& resolvers, const Dictionary::Ptr& cr, - const EscapeCallback& escapeFn); + const EscapeCallback& escapeFn, const Array::Ptr& escapeMacros); }; } diff --git a/lib/icinga/pluginchecktask.cpp b/lib/icinga/pluginchecktask.cpp index bc9fe9b91..c3fee3a99 100644 --- a/lib/icinga/pluginchecktask.cpp +++ b/lib/icinga/pluginchecktask.cpp @@ -46,7 +46,7 @@ Dictionary::Ptr PluginCheckTask::ScriptFunc(const Service::Ptr& service) resolvers.push_back(service->GetHost()); resolvers.push_back(IcingaApplication::GetInstance()); - Value command = MacroProcessor::ResolveMacros(raw_command, resolvers, Dictionary::Ptr(), Utility::EscapeShellCmd); + Value command = MacroProcessor::ResolveMacros(raw_command, resolvers, Dictionary::Ptr(), Utility::EscapeShellCmd, commandObj->GetEscapeMacros()); Dictionary::Ptr envMacros = boost::make_shared(); diff --git a/lib/icinga/plugineventtask.cpp b/lib/icinga/plugineventtask.cpp index 0cfc2343e..78afaa78d 100644 --- a/lib/icinga/plugineventtask.cpp +++ b/lib/icinga/plugineventtask.cpp @@ -44,7 +44,7 @@ void PluginEventTask::ScriptFunc(const Service::Ptr& service) resolvers.push_back(service->GetHost()); resolvers.push_back(IcingaApplication::GetInstance()); - Value command = MacroProcessor::ResolveMacros(raw_command, resolvers, Dictionary::Ptr(), Utility::EscapeShellCmd); + Value command = MacroProcessor::ResolveMacros(raw_command, resolvers, Dictionary::Ptr(), Utility::EscapeShellCmd, commandObj->GetEscapeMacros()); Dictionary::Ptr envMacros = boost::make_shared(); diff --git a/lib/icinga/pluginnotificationtask.cpp b/lib/icinga/pluginnotificationtask.cpp index 6981c8c07..aec950e48 100644 --- a/lib/icinga/pluginnotificationtask.cpp +++ b/lib/icinga/pluginnotificationtask.cpp @@ -56,7 +56,7 @@ void PluginNotificationTask::ScriptFunc(const Notification::Ptr& notification, c resolvers.push_back(service->GetHost()); resolvers.push_back(IcingaApplication::GetInstance()); - Value command = MacroProcessor::ResolveMacros(raw_command, resolvers, cr, Utility::EscapeShellCmd); + Value command = MacroProcessor::ResolveMacros(raw_command, resolvers, cr, Utility::EscapeShellCmd, commandObj->GetEscapeMacros()); Dictionary::Ptr envMacros = boost::make_shared();