From 5179faceabd8bb4ac70ee4b75dbe40cf5389f381 Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Mon, 18 Sep 2017 09:08:53 +0200 Subject: [PATCH] Implement new script functions: path_exists, glob and glob_recursive --- doc/18-library-reference.md | 59 +++++++++++++++++++++++++++++++++++++ lib/base/scriptutils.cpp | 49 ++++++++++++++++++++++++++++++ lib/base/scriptutils.hpp | 2 ++ 3 files changed, 110 insertions(+) diff --git a/doc/18-library-reference.md b/doc/18-library-reference.md index 7caa64613..f0af1138d 100644 --- a/doc/18-library-reference.md +++ b/doc/18-library-reference.md @@ -459,6 +459,65 @@ Example: <2> => basename(path) "xmpp-notification.pl" +### path\_exists + +Signature: + + function path_exists(path) + +Returns true if the specified path exists, false otherwise. + +Example: + + $ icinga2 console + Icinga 2 (version: v2.7.0) + <1> => var path = "/etc/icinga2/scripts/xmpp-notification.pl" + null + <2> => path_exists(path) + true + +### glob + +Signature: + + function glob(pathSpec, type) + +Returns an array containing all paths which match the +`pathSpec` argument. + +The `type` argument is optional and specifies which types +of paths are matched. This can be a combination of the `GlobFile` +and `GlobDirectory` constants. The default value is `GlobFile | GlobDirectory`. + + $ icinga2 console + Icinga 2 (version: v2.7.0) + <1> => var pathSpec = "/etc/icinga2/conf.d/*.conf" + null + <2> => glob(pathSpec) + [ "/etc/icinga2/conf.d/app.conf", "/etc/icinga2/conf.d/commands.conf", ... ] + +### glob\_recursive + +Signature: + + function glob_recursive(path, pattern, type) + +Recursively descends into the specified directory and returns an array containing +all paths which match the `pattern` argument. + +The `type` argument is optional and specifies which types +of paths are matched. This can be a combination of the `GlobFile` +and `GlobDirectory` constants. The default value is `GlobFile | GlobDirectory`. + + $ icinga2 console + Icinga 2 (version: v2.7.0) + <1> => var path = "/etc/icinga2/zones.d/" + null + <2> => var pattern = "*.conf" + null + <3> => glob_recursive(path, pattern) + [ "/etc/icinga2/zones.d/global-templates/templates.conf", "/etc/icinga2/zones.d/master/hosts.conf", ... ] + ### escape_shell_arg Signature: diff --git a/lib/base/scriptutils.cpp b/lib/base/scriptutils.cpp index ef70eccbf..7335c58fc 100644 --- a/lib/base/scriptutils.cpp +++ b/lib/base/scriptutils.cpp @@ -19,6 +19,8 @@ #include "base/scriptutils.hpp" #include "base/function.hpp" +#include "base/scriptframe.hpp" +#include "base/exception.hpp" #include "base/utility.hpp" #include "base/convert.hpp" #include "base/json.hpp" @@ -67,6 +69,9 @@ REGISTER_SAFE_SCRIPTFUNCTION_NS(System, escape_create_process_arg, &Utility::Esc #endif /* _WIN32 */ REGISTER_SCRIPTFUNCTION_NS(System, ptr, &ScriptUtils::Ptr, "object"); REGISTER_SCRIPTFUNCTION_NS(System, sleep, &Utility::Sleep, "interval"); +REGISTER_SCRIPTFUNCTION_NS(System, path_exists, &Utility::PathExists, "path"); +REGISTER_SCRIPTFUNCTION_NS(System, glob, &ScriptUtils::Glob, "pathspec:callback:type"); +REGISTER_SCRIPTFUNCTION_NS(System, glob_recursive, &ScriptUtils::GlobRecursive, "pathspec:callback:type"); INITIALIZE_ONCE(&ScriptUtils::StaticInitialize); @@ -80,6 +85,9 @@ void ScriptUtils::StaticInitialize(void) { ScriptGlobal::Set("MatchAll", MatchAll); ScriptGlobal::Set("MatchAny", MatchAny); + + ScriptGlobal::Set("GlobFile", GlobFile); + ScriptGlobal::Set("GlobDirectory", GlobDirectory); } String ScriptUtils::CastString(const Value& value) @@ -442,3 +450,44 @@ double ScriptUtils::Ptr(const Object::Ptr& object) { return reinterpret_cast(object.get()); } + +static void GlobCallbackHelper(std::vector& paths, const String& path) +{ + paths.push_back(path); +} + +Value ScriptUtils::Glob(const std::vector& args) +{ + if (args.size() < 1) + BOOST_THROW_EXCEPTION(std::invalid_argument("Path must be specified.")); + + String pathSpec = args[0]; + int type = GlobFile | GlobDirectory; + + if (args.size() > 1) + type = args[1]; + + std::vector paths; + Utility::Glob(pathSpec, boost::bind(&GlobCallbackHelper, boost::ref(paths), _1), type); + + return Array::FromVector(paths); +} + +Value ScriptUtils::GlobRecursive(const std::vector& args) +{ + if (args.size() < 2) + BOOST_THROW_EXCEPTION(std::invalid_argument("Path and pattern must be specified.")); + + String path = args[0]; + String pattern = args[1]; + + int type = GlobFile | GlobDirectory; + + if (args.size() > 2) + type = args[2]; + + std::vector paths; + Utility::GlobRecursive(path, pattern, boost::bind(&GlobCallbackHelper, boost::ref(paths), _1), type); + + return Array::FromVector(paths); +} diff --git a/lib/base/scriptutils.hpp b/lib/base/scriptutils.hpp index e605be5fa..313c8f4eb 100644 --- a/lib/base/scriptutils.hpp +++ b/lib/base/scriptutils.hpp @@ -56,6 +56,8 @@ public: static String MsiGetComponentPathShim(const String& component); static Array::Ptr TrackParents(const Object::Ptr& parent); static double Ptr(const Object::Ptr& object); + static Value Glob(const std::vector& args); + static Value GlobRecursive(const std::vector& args); private: ScriptUtils(void);