]> 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>
Thu, 3 Jul 2025 12:46:30 +0000 (14:46 +0200)
Signed-off-by: Remi Gacogne <remi.gacogne@powerdns.com>
(cherry picked from commit d98d50b1939016d03a522cb6a79834088949e913)
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 3b27cd5d4b60bcb8d7ee9217d65807e8ac6804dd..6aa29ab2b21af9ff36d05918f098bc6e3e1d1e4e 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 */
 
@@ -1165,7 +1167,6 @@ bool loadConfigurationFromFile(const std::string& fileName, [[maybe_unused]] boo
 
     loadRulesConfiguration(globalConfig);
 
-    s_registeredTypesMap.lock()->clear();
     return true;
   }
   catch (const ::rust::Error& exp) {
@@ -1174,13 +1175,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)
@@ -1777,4 +1825,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 458d890533f57cc9a65c24ba6b949786b1ed18ce..bf0980242b628bc67237edf733307626227d40de 100644 (file)
@@ -115,6 +115,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 1a869a78716b94fcc1d427de76c18d753150ebb6..3dc3592ef67b34a6630ed62d0c82116e976fc522 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"
@@ -3195,6 +3196,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 a3934abd2829cb68761a6c326db3343286aa1e3b..c5eb392382521a4084e560acb42f899e43e524aa 100644 (file)
@@ -2264,6 +2264,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