]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Add a Lua binding to get objects declared in YAML
authorRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 30 Jun 2025 10:23:56 +0000 (12:23 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 30 Jun 2025 14:48:47 +0000 (16:48 +0200)
Signed-off-by: Remi Gacogne <remi.gacogne@powerdns.com>
pdns/dnsdistdist/dnsdist-configuration-yaml.cc
pdns/dnsdistdist/dnsdist-configuration-yaml.hh
pdns/dnsdistdist/dnsdist-console-completion.cc
pdns/dnsdistdist/dnsdist-lua.cc
pdns/dnsdistdist/dnsdist-settings-documentation-generator.py
pdns/dnsdistdist/docs/reference/config.rst

index e2010a71ab5256439eef6c8589516f94520f771a..49743a17c4a55dae3d79e44dc126f8f75a106b8a 100644 (file)
 #include "rust/lib.rs.h"
 #include "dnsdist-configuration-yaml-internal.hh"
 
-#include <boost/uuid/string_generator.hpp>
 #include <variant>
+#include <boost/optional.hpp>
+#include <boost/uuid/string_generator.hpp>
+#include <boost/variant.hpp>
 
 #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<boost::variant<std::shared_ptr<DNSDistPacketCache>, std::shared_ptr<DNSRule>, std::shared_ptr<DNSAction>, std::shared_ptr<DNSResponseAction>, std::shared_ptr<NetmaskGroup>, std::shared_ptr<KeyValueStore>, std::shared_ptr<KeyValueLookupKey>, std::shared_ptr<RemoteLoggerInterface>, std::shared_ptr<ServerPolicy>, std::shared_ptr<XSKMap>>>;
+
+  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<std::shared_ptr<DNSDistPacketCache>>(&item->second)) {
+      return ReturnValue(*ptr);
+    }
+    if (auto* ptr = std::get_if<std::shared_ptr<dnsdist::rust::settings::DNSSelector>>(&item->second)) {
+      return ReturnValue((*ptr)->d_rule);
+    }
+    if (auto* ptr = std::get_if<std::shared_ptr<dnsdist::rust::settings::DNSActionWrapper>>(&item->second)) {
+      return ReturnValue((*ptr)->d_action);
+    }
+    if (auto* ptr = std::get_if<std::shared_ptr<dnsdist::rust::settings::DNSResponseActionWrapper>>(&item->second)) {
+      return ReturnValue((*ptr)->d_action);
+    }
+    if (auto* ptr = std::get_if<std::shared_ptr<NetmaskGroup>>(&item->second)) {
+      return ReturnValue(*ptr);
+    }
+    if (auto* ptr = std::get_if<std::shared_ptr<KeyValueStore>>(&item->second)) {
+      return ReturnValue(*ptr);
+    }
+    if (auto* ptr = std::get_if<std::shared_ptr<KeyValueLookupKey>>(&item->second)) {
+      return ReturnValue(*ptr);
+    }
+    if (auto* ptr = std::get_if<std::shared_ptr<RemoteLoggerInterface>>(&item->second)) {
+      return ReturnValue(*ptr);
+    }
+    if (auto* ptr = std::get_if<std::shared_ptr<ServerPolicy>>(&item->second)) {
+      return ReturnValue(*ptr);
+    }
+    if (auto* ptr = std::get_if<std::shared_ptr<XSKMap>>(&item->second)) {
+      return ReturnValue(*ptr);
+    }
+
+    return object;
+  });
+#endif /* HAVE_YAML_CONFIGURATION */
+}
 }
 
 #if defined(HAVE_YAML_CONFIGURATION)
@@ -1762,4 +1810,5 @@ std::shared_ptr<DNSSelector> getByNameSelector(const ByNameSelectorConfiguration
 #include "dnsdist-rust-bridge-actions-generated-body.hh"
 #include "dnsdist-rust-bridge-selectors-generated-body.hh"
 }
+
 #endif /* defined(HAVE_YAML_CONFIGURATION) */
index 467b9df99f4d1828bf9b771084880f39b4cb61b2..16153f708d919f5845d6e54512fc6d1bc9888558 100644 (file)
 
 #include <string>
 
+class LuaContext;
+
 namespace dnsdist::configuration::yaml
 {
 bool loadConfigurationFromFile(const std::string& fileName, bool isClient, bool configCheck);
+void addLuaBindingsForYAMLObjects(LuaContext& luaCtx);
 }
index f3342e8aa2ea5793ce9f0d0dc885fef84c5b8b36..a5c7d931333cd7939f954a2f7c4a3345522d69f5 100644 (file)
@@ -116,6 +116,7 @@ static std::vector<dnsdist::console::completion::ConsoleKeyword> 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"},
index 653bf78ec79715c6bbac6c036ab7fb72f66311ae..fa2db7607eb9dd30a0e1868a80ffb437ed69e6b3 100644 (file)
@@ -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());
index f98b22b2b300ce065e6e774bdae02500abd265c9..2ca36cad7a37b8c0916c9c4c9df02f9a78dbf00e 100644 (file)
@@ -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.
 
 '''
index 7b4a98c4fda5a411e1d104780cb63375972af50c..1b4fb9d2441c72dc531cbb11bd88482d9f65a58e 100644 (file)
@@ -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