diff --git a/doc/18-library-reference.md b/doc/18-library-reference.md index 9ec4acd31..490497b4a 100644 --- a/doc/18-library-reference.md +++ b/doc/18-library-reference.md @@ -908,6 +908,58 @@ function get_objects(type); Returns an array of objects whose type matches the specified type. `type` must refer to a type object. +### get_template + +Signature: + +``` +function get_template(type, name); +``` + +Returns the template with the specified type and name, or `null` if no such object exists. `type` must refer +to a type object. + +> **Note** +> +> Only the name and debug info attributes are available for templates accessed in the DSL. +> Object attributes are not available in this scope. + +You can use this functionality to check whether a template exists e.g. on a satellite endpoint +and if not, import a different template. + +``` +object Host "icinga-agent47.localdomain" { + if (get_template(Host, "master-host-tmpl")) { + import "master-host-tmpl" + } else { + import "generic-host" + } +} +``` + +### get_templates + +Signature: + +``` +function get_templates(type); +``` + +Returns an array of templates whose type matches the specified type. `type` must refer +to a type object. + +> **Note** +> +> Only the name and debug info attributes are available for templates accessed in the DSL. +> Object attributes are not available in this scope. + +You can use this function to iterate over all available template names, similar to what +the [templates API URL endpoint](12-icinga2-api.md#icinga2-api-config-templates) provides. + +``` +<1> => get_templates(Host).map(n => n.name) +[ "ssh-agent" ] +``` ## Math object diff --git a/lib/base/scriptutils.cpp b/lib/base/scriptutils.cpp index 47f2ccdea..838f20edd 100644 --- a/lib/base/scriptutils.cpp +++ b/lib/base/scriptutils.cpp @@ -14,6 +14,7 @@ #include "base/dependencygraph.hpp" #include "base/initialize.hpp" #include "base/namespace.hpp" +#include "config/configitem.hpp" #include #include #include @@ -35,6 +36,8 @@ REGISTER_FUNCTION(System, exit, &Application::Exit, "status"); REGISTER_SAFE_FUNCTION(System, typeof, &ScriptUtils::TypeOf, "value"); REGISTER_SAFE_FUNCTION(System, keys, &ScriptUtils::Keys, "value"); REGISTER_SAFE_FUNCTION(System, random, &Utility::Random, ""); +REGISTER_SAFE_FUNCTION(System, get_template, &ScriptUtils::GetTemplate, "type:name"); +REGISTER_SAFE_FUNCTION(System, get_templates, &ScriptUtils::GetTemplates, "type"); REGISTER_SAFE_FUNCTION(System, get_object, &ScriptUtils::GetObject, "type:name"); REGISTER_SAFE_FUNCTION(System, get_objects, &ScriptUtils::GetObjects, "type"); REGISTER_FUNCTION(System, assert, &ScriptUtils::Assert, "value"); @@ -407,6 +410,57 @@ Array::Ptr ScriptUtils::Keys(const Object::Ptr& obj) return new Array(std::move(result)); } +static Dictionary::Ptr GetTargetForTemplate(const ConfigItem::Ptr& item) +{ + DebugInfo di = item->GetDebugInfo(); + + return new Dictionary({ + { "name", item->GetName() }, + { "type", item->GetType()->GetName() }, + { "location", new Dictionary({ + { "path", di.Path }, + { "first_line", di.FirstLine }, + { "first_column", di.FirstColumn }, + { "last_line", di.LastLine }, + { "last_column", di.LastColumn } + }) } + }); +} + +Dictionary::Ptr ScriptUtils::GetTemplate(const Value& vtype, const String& name) +{ + Type::Ptr ptype; + + if (vtype.IsObjectType()) + ptype = vtype; + else + ptype = Type::GetByName(vtype); + + ConfigItem::Ptr item = ConfigItem::GetByTypeAndName(ptype, name); + + if (!item || !item->IsAbstract()) + return nullptr; + + DebugInfo di = item->GetDebugInfo(); + + return GetTargetForTemplate(item); +} + +Array::Ptr ScriptUtils::GetTemplates(const Type::Ptr& type) +{ + if (!type) + BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid type: Must not be null")); + + ArrayData result; + + for (const ConfigItem::Ptr& item : ConfigItem::GetItems(type)) { + if (item->IsAbstract()) + result.push_back(GetTargetForTemplate(item)); + } + + return new Array(std::move(result)); +} + ConfigObject::Ptr ScriptUtils::GetObject(const Value& vtype, const String& name) { Type::Ptr ptype; diff --git a/lib/base/scriptutils.hpp b/lib/base/scriptutils.hpp index c874ff857..7bd3e8b9d 100644 --- a/lib/base/scriptutils.hpp +++ b/lib/base/scriptutils.hpp @@ -33,6 +33,8 @@ public: static Array::Ptr Range(const std::vector& arguments); static Type::Ptr TypeOf(const Value& value); static Array::Ptr Keys(const Object::Ptr& obj); + static Dictionary::Ptr GetTemplate(const Value& vtype, const String& name); + static Array::Ptr GetTemplates(const Type::Ptr& type); static ConfigObject::Ptr GetObject(const Value& type, const String& name); static Array::Ptr GetObjects(const Type::Ptr& type); static void Assert(const Value& arg);