From d98d50b1939016d03a522cb6a79834088949e913 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 30 Jun 2025 12:23:56 +0200 Subject: [PATCH] dnsdist: Add a Lua binding to get objects declared in YAML Signed-off-by: Remi Gacogne --- .../dnsdistdist/dnsdist-configuration-yaml.cc | 55 ++++++++++++++++++- .../dnsdistdist/dnsdist-configuration-yaml.hh | 3 + .../dnsdistdist/dnsdist-console-completion.cc | 1 + pdns/dnsdistdist/dnsdist-lua.cc | 2 + ...nsdist-settings-documentation-generator.py | 2 + pdns/dnsdistdist/docs/reference/config.rst | 8 +++ 6 files changed, 68 insertions(+), 3 deletions(-) diff --git a/pdns/dnsdistdist/dnsdist-configuration-yaml.cc b/pdns/dnsdistdist/dnsdist-configuration-yaml.cc index e2010a71ab..49743a17c4 100644 --- a/pdns/dnsdistdist/dnsdist-configuration-yaml.cc +++ b/pdns/dnsdistdist/dnsdist-configuration-yaml.cc @@ -49,8 +49,10 @@ #include "rust/lib.rs.h" #include "dnsdist-configuration-yaml-internal.hh" -#include #include +#include +#include +#include #endif /* HAVE_YAML_CONFIGURATION */ @@ -1150,7 +1152,6 @@ bool loadConfigurationFromFile(const std::string& fileName, [[maybe_unused]] boo loadRulesConfiguration(globalConfig); - s_registeredTypesMap.lock()->clear(); return true; } catch (const ::rust::Error& exp) { @@ -1159,13 +1160,60 @@ bool loadConfigurationFromFile(const std::string& fileName, [[maybe_unused]] boo catch (const std::exception& exp) { errlog("Error while processing YAML configuration from file %s: %s", fileName, exp.what()); } - s_registeredTypesMap.lock()->clear(); return false; #else (void)fileName; throw std::runtime_error("Unsupported YAML configuration"); #endif /* HAVE_YAML_CONFIGURATION */ } + +void addLuaBindingsForYAMLObjects([[maybe_unused]] LuaContext& luaCtx) +{ +#if defined(HAVE_YAML_CONFIGURATION) + using ReturnValue = boost::optional, std::shared_ptr, std::shared_ptr, std::shared_ptr, std::shared_ptr, std::shared_ptr, std::shared_ptr, std::shared_ptr, std::shared_ptr, std::shared_ptr>>; + + luaCtx.writeFunction("getObjectFromYAMLConfiguration", [](const std::string& name) { + ReturnValue object{boost::none}; + auto map = s_registeredTypesMap.lock(); + auto item = map->find(name); + if (item == map->end()) { + return object; + } + if (auto* ptr = std::get_if>(&item->second)) { + return ReturnValue(*ptr); + } + if (auto* ptr = std::get_if>(&item->second)) { + return ReturnValue((*ptr)->d_rule); + } + if (auto* ptr = std::get_if>(&item->second)) { + return ReturnValue((*ptr)->d_action); + } + if (auto* ptr = std::get_if>(&item->second)) { + return ReturnValue((*ptr)->d_action); + } + if (auto* ptr = std::get_if>(&item->second)) { + return ReturnValue(*ptr); + } + if (auto* ptr = std::get_if>(&item->second)) { + return ReturnValue(*ptr); + } + if (auto* ptr = std::get_if>(&item->second)) { + return ReturnValue(*ptr); + } + if (auto* ptr = std::get_if>(&item->second)) { + return ReturnValue(*ptr); + } + if (auto* ptr = std::get_if>(&item->second)) { + return ReturnValue(*ptr); + } + if (auto* ptr = std::get_if>(&item->second)) { + return ReturnValue(*ptr); + } + + return object; + }); +#endif /* HAVE_YAML_CONFIGURATION */ +} } #if defined(HAVE_YAML_CONFIGURATION) @@ -1762,4 +1810,5 @@ std::shared_ptr getByNameSelector(const ByNameSelectorConfiguration #include "dnsdist-rust-bridge-actions-generated-body.hh" #include "dnsdist-rust-bridge-selectors-generated-body.hh" } + #endif /* defined(HAVE_YAML_CONFIGURATION) */ diff --git a/pdns/dnsdistdist/dnsdist-configuration-yaml.hh b/pdns/dnsdistdist/dnsdist-configuration-yaml.hh index 467b9df99f..16153f708d 100644 --- a/pdns/dnsdistdist/dnsdist-configuration-yaml.hh +++ b/pdns/dnsdistdist/dnsdist-configuration-yaml.hh @@ -25,7 +25,10 @@ #include +class LuaContext; + namespace dnsdist::configuration::yaml { bool loadConfigurationFromFile(const std::string& fileName, bool isClient, bool configCheck); +void addLuaBindingsForYAMLObjects(LuaContext& luaCtx); } diff --git a/pdns/dnsdistdist/dnsdist-console-completion.cc b/pdns/dnsdistdist/dnsdist-console-completion.cc index f3342e8aa2..a5c7d93133 100644 --- a/pdns/dnsdistdist/dnsdist-console-completion.cc +++ b/pdns/dnsdistdist/dnsdist-console-completion.cc @@ -116,6 +116,7 @@ static std::vector s_consoleKeywor {"getListOfRangesOfNetworkInterface", true, "itf", "returns the list of network ranges configured on a given network interface, as strings"}, {"getMACAddress", true, "IP addr", "return the link-level address (MAC) corresponding to the supplied neighbour IP address, if known by the kernel"}, {"getMetric", true, "name", "Get the value of a custom metric"}, + {"getObjectFromYAMLConfiguration", true, "name", "Get an object created in YAML configuration"}, {"getOutgoingTLSSessionCacheSize", true, "", "returns the number of TLS sessions (for outgoing connections) currently cached"}, {"getPool", true, "name", "return the pool named `name`, or \"\" for the default pool"}, {"getPoolServers", true, "pool", "return servers part of this pool"}, diff --git a/pdns/dnsdistdist/dnsdist-lua.cc b/pdns/dnsdistdist/dnsdist-lua.cc index 653bf78ec7..fa2db7607e 100644 --- a/pdns/dnsdistdist/dnsdist-lua.cc +++ b/pdns/dnsdistdist/dnsdist-lua.cc @@ -38,6 +38,7 @@ #include "dnsdist-carbon.hh" #include "dnsdist-concurrent-connections.hh" #include "dnsdist-configuration.hh" +#include "dnsdist-configuration-yaml.hh" #include "dnsdist-console.hh" #include "dnsdist-console-completion.hh" #include "dnsdist-crypto.hh" @@ -3187,6 +3188,7 @@ void setupLuaBindingsOnly(LuaContext& luaCtx, bool client, bool configCheck) setupLuaInspection(luaCtx); setupLuaVars(luaCtx); setupLuaWeb(luaCtx); + dnsdist::configuration::yaml::addLuaBindingsForYAMLObjects(luaCtx); #ifdef LUAJIT_VERSION luaCtx.executeCode(getLuaFFIWrappers()); diff --git a/pdns/dnsdistdist/dnsdist-settings-documentation-generator.py b/pdns/dnsdistdist/dnsdist-settings-documentation-generator.py index f98b22b2b3..2ca36cad7a 100644 --- a/pdns/dnsdistdist/dnsdist-settings-documentation-generator.py +++ b/pdns/dnsdistdist/dnsdist-settings-documentation-generator.py @@ -142,6 +142,8 @@ If the configuration file passed to :program:`dnsdist` via the ``-C`` command-li By default, when a YAML configuration file is used, any Lua configuration file used along the YAML configuration should only contain functions, and ideally even those should be defined either inline in the YAML file or in separate files included from the YAML configuration, for clarity. It is however possible to change this behaviour using the :func:`enableLuaConfiguration` directive to enable Lua configuration directives, but it is strongly advised not to use this directive unless absolutely necessary, and to prefer doing all the configuration in either Lua or YAML but to not mix them. Note that Lua directives that can be used at runtime are always available via the :doc:`../guides/console`, regardless of whether they are enabled during configuration. +It is possible to access objects declared in the YAML configuration from the console via :func:`getObjectFromYAMLConfiguration`. + A YAML configuration file contains several sections, that are described below. ''' diff --git a/pdns/dnsdistdist/docs/reference/config.rst b/pdns/dnsdistdist/docs/reference/config.rst index 7b4a98c4fd..1b4fb9d244 100644 --- a/pdns/dnsdistdist/docs/reference/config.rst +++ b/pdns/dnsdistdist/docs/reference/config.rst @@ -2289,6 +2289,14 @@ Other functions :returns: A timespec object, see :ref:`timespec` +.. function:: getObjectFromYAMLConfiguration + + .. versionadded:: 2.0.0 + + Return a pointer to an object (:class:`KeyValueStore`, :class:`DNSAction`, class::`DNSRule`, ...) declared in the YAML configuration. + + :param str name: The name assigned to the object in the YAML configuration + .. function:: getResolvers(path) .. versionadded:: 1.8.0 -- 2.47.2