]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Add "ByName" support for YAML actions
authorRemi Gacogne <remi.gacogne@powerdns.com>
Thu, 11 Jun 2026 09:10:15 +0000 (11:10 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Thu, 11 Jun 2026 09:10:15 +0000 (11:10 +0200)
Signed-off-by: Remi Gacogne <remi.gacogne@powerdns.com>
pdns/dnsdistdist/dnsdist-actions-definitions.yml
pdns/dnsdistdist/dnsdist-configuration-yaml.cc
pdns/dnsdistdist/dnsdist-response-actions-definitions.yml
regression-tests.dnsdist/test_Yaml.py

index 3fa2d3bbcd98d657f56db255664144344ef85407..f530f3e4ce47825144f06664dc3d849ba649e2f2 100644 (file)
@@ -1,6 +1,16 @@
 ---
 - name: "allow"
   description: "Let these packets go through"
+- name: "ByName"
+  skip-cpp: true
+  skip-rust: true
+  no-lua-equivalent: true
+  description: "References an already declared action by its name"
+  version_added: 2.2.0
+  parameters:
+    - name: "action_name"
+      type: "String"
+      descripton: "The action name"
 - name: "continue"
   description: "Execute the specified action and override its return with None, making it possible to continue the processing. Subsequent rules are processed after this action"
   skip-cpp: true
index 19b164ec2795895a527af6d6bf09831cf2badefc..13ef7a4a00801e622d9e6fd648929fe0a901f390 100644 (file)
@@ -2125,6 +2125,24 @@ std::shared_ptr<DNSSelector> getByNameSelector(const ByNameSelectorConfiguration
   return ptr;
 }
 
+std::shared_ptr<DNSActionWrapper> getByNameAction(const ByNameActionConfiguration& config)
+{
+  auto ptr = dnsdist::configuration::yaml::getRegisteredTypeByName<DNSActionWrapper>(config.action_name);
+  if (!ptr) {
+    throw std::runtime_error("Unable to find an action named " + std::string(config.action_name));
+  }
+  return ptr;
+}
+
+std::shared_ptr<DNSResponseActionWrapper> getByNameResponseAction(const ByNameResponseActionConfiguration& config)
+{
+  auto ptr = dnsdist::configuration::yaml::getRegisteredTypeByName<DNSResponseActionWrapper>(config.action_name);
+  if (!ptr) {
+    throw std::runtime_error("Unable to find an action named " + std::string(config.action_name));
+  }
+  return ptr;
+}
+
 #include "dnsdist-rust-bridge-actions-generated-body.hh"
 #include "dnsdist-rust-bridge-selectors-generated-body.hh"
 }
index b4c9aa5a0d22cb144b13312ce7fdc457524ad6b6..2dd48e8ad366d839eca8b95025300fce5408dab5 100644 (file)
@@ -1,6 +1,16 @@
 ---
 - name: "allow"
   description: "Let these packets go through."
+- name: "ByName"
+  skip-cpp: true
+  skip-rust: true
+  no-lua-equivalent: true
+  description: "References an already declared action by its name"
+  version_added: 2.2.0
+  parameters:
+    - name: "action_name"
+      type: "String"
+      descripton: "The action name"
 - name: "ClearRecordTypes"
   description: "Removes given type(s) records from the response. Beware you can accidentally turn the answer into a NODATA response without a SOA record in the additional section in which case you may want to use NegativeAndSOAAction() to generate an answer, see example below. Subsequent rules are processed after this action."
   skip-cpp: true
index 730707775922fbd856e1f08f61fb7fb0b40b1646..8e737a44b7aa22a03242d2db62de4db0d4504f91 100644 (file)
@@ -76,6 +76,23 @@ query_rules:
     action:
       type: "Pool"
       pool_name: "tcp-pool"
+  - name: "reply notimp to notimp1"
+    selector:
+      type: "QNameSet"
+      qnames:
+        - "notimp1.yaml.test.powerdns.com."
+    action:
+      name: "reply-with-notimp"
+      type: "RCode"
+      rcode: "NotImp"
+  - name: "reply notimp to notimp2"
+    selector:
+      type: "QNameSet"
+      qnames:
+        - "notimp2.yaml.test.powerdns.com."
+    action:
+      type: "ByName"
+      action_name: "reply-with-notimp"
 
 response_rules:
   - name: "inline RD=0 TCP gets cleared"
@@ -193,6 +210,17 @@ response_rules:
             self.assertEqual(receivedQuery, query)
             self.assertEqual(receivedResponse, response)
 
+    def testActionByName(self):
+        """
+        Yaml: Action by name
+        """
+        for name in ["notimp1.yaml.test.powerdns.com.", "notimp2.yaml.test.powerdns.com."]:
+            query = dns.message.make_query(name, "A", "IN")
+            query.flags &= ~dns.flags.RD
+            response = dns.message.make_response(query)
+            response.set_rcode(dns.rcode.NOTIMP)
+            (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
+            self.assertEqual(receivedResponse, response)
 
 class TestMixingYamlWithLua(DNSDistTest):
     _yaml_config_template = """---