From 17d277ff16d8f349fbcc5268ad162ffab11ce0c0 Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Tue, 29 Apr 2014 10:32:06 +0200 Subject: [PATCH] Implement the "order" attribute for command arguments. Refs #5933 --- itl/command-common.conf | 1 + lib/icinga/icinga-type.conf | 1 + lib/icinga/pluginutility.cpp | 61 ++++++++++++++++++++++++++++++------ 3 files changed, 53 insertions(+), 10 deletions(-) diff --git a/itl/command-common.conf b/itl/command-common.conf index 489892aa6..fa1a38974 100644 --- a/itl/command-common.conf +++ b/itl/command-common.conf @@ -203,6 +203,7 @@ object CheckCommand "ssh" { "host" = { value = "$ssh_address$" skip_key = true + order = -1 } } diff --git a/lib/icinga/icinga-type.conf b/lib/icinga/icinga-type.conf index ead1ea7f0..cedebc460 100644 --- a/lib/icinga/icinga-type.conf +++ b/lib/icinga/icinga-type.conf @@ -210,6 +210,7 @@ %attribute %number "optional" %attribute %number "skip_key" %attribute %string "set_if" + %attribute %number "order" } }, %attribute %dictionary "env" { diff --git a/lib/icinga/pluginutility.cpp b/lib/icinga/pluginutility.cpp index f5a401d23..8e1c04e99 100644 --- a/lib/icinga/pluginutility.cpp +++ b/lib/icinga/pluginutility.cpp @@ -36,6 +36,33 @@ using namespace icinga; +struct CommandArgument +{ + int Order; + bool SkipKey; + bool SkipValue; + String Key; + String Value; + + CommandArgument(void) + : Order(0), SkipKey(false), SkipValue(false) + { } + + bool operator<(const CommandArgument& rhs) const + { + return GetNormalizedOrder() < rhs.GetNormalizedOrder(); + } + +private: + int GetNormalizedOrder(void) const + { + if (Order == 0) + return 0; + else + return -(1 / Order); + } +}; + void PluginUtility::ExecuteCommand(const Command::Ptr& commandObj, const Checkable::Ptr& checkable, const MacroProcessor::ResolverList& macroResolvers, const boost::function& callback) @@ -53,20 +80,24 @@ void PluginUtility::ExecuteCommand(const Command::Ptr& commandObj, const Checkab } if (raw_arguments) { + std::vector args; + ObjectLock olock(raw_arguments); BOOST_FOREACH(const Dictionary::Pair& kv, raw_arguments) { - const String& argname = kv.first; const Value& arginfo = kv.second; + CommandArgument arg; + arg.Key = kv.first; + bool optional = false; - bool skip_key = false; String argval; if (arginfo.IsObjectType()) { Dictionary::Ptr argdict = arginfo; argval = argdict->Get("value"); optional = argdict->Get("optional"); - skip_key = argdict->Get("skip_key"); + arg.SkipKey = argdict->Get("skip_key"); + arg.Order = argdict->Get("order"); String set_if = argdict->Get("set_if"); @@ -82,14 +113,17 @@ void PluginUtility::ExecuteCommand(const Command::Ptr& commandObj, const Checkab else argval = arginfo; + if (argval.IsEmpty()) + arg.SkipValue = true; + String missingMacro; - String argresolved = MacroProcessor::ResolveMacros(argval, macroResolvers, + arg.Value = MacroProcessor::ResolveMacros(argval, macroResolvers, checkable->GetLastCheckResult(), &missingMacro); if (!missingMacro.IsEmpty()) { if (!optional) { String message = "Non-optional macro '" + missingMacro + "' used in argument '" + - argname + "' is missing while executing command '" + commandObj->GetName() + + arg.Key + "' is missing while executing command '" + commandObj->GetName() + "' for object '" + checkable->GetName() + "'"; Log(LogWarning, "methods", message); @@ -107,11 +141,18 @@ void PluginUtility::ExecuteCommand(const Command::Ptr& commandObj, const Checkab continue; } - Array::Ptr command_arr = command; - if (!skip_key) - command_arr->Add(argname); - if (!argval.IsEmpty()) - command_arr->Add(argresolved); + args.push_back(arg); + } + + std::sort(args.begin(), args.end()); + + Array::Ptr command_arr = command; + BOOST_FOREACH(const CommandArgument& arg, args) { + if (!arg.SkipKey) + command_arr->Add(arg.Key); + + if (!arg.SkipValue) + command_arr->Add(arg.Value); } } -- 2.40.0