]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Allow retrieving and deleting a backend via its UUID 8657/head
authorRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 23 Dec 2019 17:15:49 +0000 (18:15 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 23 Dec 2019 17:15:49 +0000 (18:15 +0100)
Backends have a UUID since the introduction of the consistent hashing
load-balancing policy, but until now it was not possible to retrieve
or delete a backend via its UUID.

pdns/dnsdist-console.cc
pdns/dnsdist-lua-bindings.cc
pdns/dnsdist-lua.cc
pdns/dnsdistdist/docs/reference/config.rst

index c6a9b8132abac0a0607d7dcd44f7309ba2713fa7..c30030b84bc6d19096d05be34a299bcc63341592 100644 (file)
@@ -402,7 +402,7 @@ const std::vector<ConsoleKeyword> g_consoleKeywords{
   { "getQueryCounters", true, "[max=10]", "show current buffer of query counters, limited by 'max' if provided" },
   { "getResponseRing", true, "", "return the current content of the response ring" },
   { "getRespRing", true, "", "return the qname/rcode content of the response ring" },
-  { "getServer", true, "n", "returns server with index n" },
+  { "getServer", true, "id", "returns server with index 'n' or whose uuid matches if 'id' is an UUID string" },
   { "getServers", true, "", "returns a table with all defined servers" },
   { "getStatisticsCounters", true, "", "returns a map of statistic counters" },
   { "getTLSContext", true, "n", "returns the TLS context with index n" },
@@ -487,7 +487,7 @@ const std::vector<ConsoleKeyword> g_consoleKeywords{
   { "rmResponseRule", true, "id", "remove response rule in position 'id', or whose uuid matches if 'id' is an UUID string" },
   { "rmRule", true, "id", "remove rule in position 'id', or whose uuid matches if 'id' is an UUID string" },
   { "rmSelfAnsweredResponseRule", true, "id", "remove self-answered response rule in position 'id', or whose uuid matches if 'id' is an UUID string" },
-  { "rmServer", true, "n", "remove server with index n" },
+  { "rmServer", true, "id", "remove server with index 'id' or whose uuid matches if 'id' is an UUID string" },
   { "roundrobin", false, "", "Simple round robin over available servers" },
   { "sendCustomTrap", true, "str", "send a custom `SNMP` trap from Lua, containing the `str` string"},
   { "setACL", true, "{netmask, netmask}", "replace the ACL set with these netmasks. Use `setACL({})` to reset the list, meaning no one can use us" },
index 6a01adf1fc0a2f96ff0ff9bdf05889c0968cb451..b02b4232f996d4a8dadf7947b3590f5ec5a9ad3d 100644 (file)
@@ -118,6 +118,7 @@ void setupLuaBindings(bool client)
   );
   g_lua.registerMember("order", &DownstreamState::order);
   g_lua.registerMember("name", &DownstreamState::name);
+  g_lua.registerFunction<std::string(DownstreamState::*)()>("getID", [](const DownstreamState& s) { return boost::uuids::to_string(s.id); });
 
   /* dnsheader */
   g_lua.registerFunction<void(dnsheader::*)(bool)>("setRD", [](dnsheader& dh, bool v) {
index 366376ef4dd52d0d4e7f09f85ef946d593f20594..b51fd65125738b89af15dcd201c860b5f9811f18 100644 (file)
@@ -497,19 +497,29 @@ void setupLuaConfig(bool client)
       } );
 
   g_lua.writeFunction("rmServer",
-                      [](boost::variant<std::shared_ptr<DownstreamState>, int> var)
+                      [](boost::variant<std::shared_ptr<DownstreamState>, int, std::string> var)
                       {
                         setLuaSideEffect();
-                        shared_ptr<DownstreamState> server;
-                        auto* rem = boost::get<shared_ptr<DownstreamState>>(&var);
+                        shared_ptr<DownstreamState> server = nullptr;
                         auto states = g_dstates.getCopy();
-                        if(rem) {
+                        if (auto* rem = boost::get<shared_ptr<DownstreamState>>(&var)) {
                           server = *rem;
                         }
+                        else if (auto str = boost::get<std::string>(&var)) {
+                          const auto uuid = getUniqueID(*str);
+                          for (auto& state : states) {
+                            if (state->id == uuid) {
+                              server = state;
+                            }
+                          }
+                        }
                         else {
                           int idx = boost::get<int>(var);
                           server = states.at(idx);
                         }
+                        if (!server) {
+                          throw std::runtime_error("unable to locate the requested server");
+                        }
                         auto localPools = g_pools.getCopy();
                         for (const string& poolName : server->pools) {
                           removeServerFromPool(localPools, poolName, server);
@@ -725,10 +735,25 @@ void setupLuaConfig(bool client)
       return getDownstreamCandidates(g_pools.getCopy(), pool);
     });
 
-  g_lua.writeFunction("getServer", [client](int i) {
-      if (client)
+  g_lua.writeFunction("getServer", [client](boost::variant<unsigned int, std::string> i) {
+      if (client) {
         return std::make_shared<DownstreamState>(ComboAddress());
-      return g_dstates.getCopy().at(i);
+      }
+      auto states = g_dstates.getCopy();
+      if (auto str = boost::get<std::string>(&i)) {
+        const auto uuid = getUniqueID(*str);
+        for (auto& state : states) {
+          if (state->id == uuid) {
+            return state;
+          }
+        }
+      }
+      else if (auto pos = boost::get<unsigned int>(&i)) {
+        return states.at(*pos);
+      }
+
+      g_outputBuffer = "Error: no rule matched\n";
+      return std::shared_ptr<DownstreamState>(nullptr);
     });
 
   g_lua.writeFunction("carbonServer", [](const std::string& address, boost::optional<string> ourName,
index 7d40c1b552e876655440dda7411fe1e9c59ff849..14a56106e48fdbd8456386273ccc1c82db5312b3 100644 (file)
@@ -428,9 +428,12 @@ Servers
 
 .. function:: getServer(index) -> Server
 
+  .. versionchanged:: 1.5.0
+    ``index`` might be an UUID.
+
   Get a :class:`Server`
 
-  :param int index: The number of the server (as seen in :func:`showServers`).
+  :param int or str index: The number of the server (as seen in :func:`showServers`) or its UUID as a string.
   :returns:  The :class:`Server` object or nil
 
 .. function:: getServers()
@@ -438,11 +441,15 @@ Servers
   Returns a table with all defined servers.
 
 .. function:: rmServer(index)
+              rmServer(uuid)
               rmServer(server)
 
+  .. versionchanged:: 1.5.0
+    ``uuid`` selection added.
+
   Remove a backend server.
 
-  :param int index: The number of the server (as seen in :func:`showServers`).
+  :param int or str index: The number of the server (as seen in :func:`showServers`), its UUID as a string, or a server object.
   :param Server server: A :class:`Server` object as returned by e.g. :func:`getServer`.
 
 Server Functions