]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Print yaml representation for get-parameter
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Tue, 28 Oct 2025 14:11:36 +0000 (15:11 +0100)
committerOtto Moerbeek <otto.moerbeek@open-xchange.com>
Tue, 4 Nov 2025 12:40:38 +0000 (13:40 +0100)
Known issue: parameters having default vaues are not found

Signed-off-by: Otto Moerbeek <otto.moerbeek@open-xchange.com>
pdns/recursordist/rec-rust-lib/rust-bridge-in.rs
pdns/recursordist/rec-rust-lib/rust/src/bridge.rs
pdns/recursordist/rec_channel_rec.cc

index abe35bdd8be4dd879cdd4f482c0a343490e43544..9963ef2376ef6b15cde9b6fbf8c7b63560a34af8 100644 (file)
@@ -403,6 +403,7 @@ extern "Rust" {
 
     // Prdoduce a YAML formatted string given a data structure known to Serde
     fn to_yaml_string(self: &Recursorsettings) -> Result<String>;
+    fn get_value(self: &Recursorsettings, field: &Vec<String>) -> Result<String>;
     // When doing a conversion of old-style to YAML style we use a vector of OldStyle structs
     fn map_to_yaml_string(map: &Vec<OldStyle>) -> Result<String>;
     fn forward_zones_to_yaml_string(vec: &Vec<ForwardZone>) -> Result<String>;
index 89dd401ee07627335c3dff737199724a593961d3..cc218652aee6eb97efcac9ac10a6b148f48a0918 100644 (file)
@@ -905,6 +905,70 @@ impl Recursorsettings {
         serde_yaml::to_string(self)
     }
 
+    fn get_value_from_map(map: &serde_yaml::Mapping, fields: &[String]) -> Result<String, std::io::Error>  {
+        match fields.len() {
+            0 => {
+                let result = serde_yaml::to_string(map);
+                if let Err(error) = result {
+                    return Err(std::io::Error::other(error.to_string()))
+                }
+                Ok(result.unwrap())
+            }
+            1 => {
+                if let Some(found) = map.get(&fields[0]) {
+                    let result = serde_yaml::to_string(found);
+                    if let Err(error) = result {
+                        return Err(std::io::Error::other(error.to_string()));
+                    }
+                    Ok(result.unwrap())
+                }
+                else {
+                    Err(std::io::Error::other(fields[0].to_owned() + ": not found"))
+                }
+            }
+            _ => {
+                if let Some(found) = map.get(&fields[0]) {
+                    if let Some(map) = found.as_mapping() {
+                        Self::get_value_from_map(map, &fields[1..])
+                    }
+                    else {
+                        Err(std::io::Error::other(fields[0].to_owned() + ": not a mapping"))
+                    }
+                }
+                else {
+                    Err(std::io::Error::other(fields[0].to_owned() + ": not found"))
+                }
+            }
+        }
+    }
+
+    pub fn get_value(&self, field: &Vec<String>) -> Result<String, std::io::Error> {
+        let value = serde_yaml::to_value(self);
+        let value = match value {
+            Ok(value) => value,
+            Err(error) => return Err(std::io::Error::other(error.to_string()))
+        };
+        if let Some(map) = value.as_mapping() {
+            match field.len() {
+                0 => {
+                    return Self::get_value_from_map(map, field);
+                }
+                _ => {
+                    if let Some(found) = map.get(&field[0]) {
+                        let submap = serde_yaml::from_value(found.clone());
+                        let submap = match submap {
+                            Ok(submap) => submap,
+                            Err(error) => return Err(std::io::Error::other(error.to_string()))
+                        };
+                        return Self::get_value_from_map(&submap, &field[1..]);
+                    }
+                    return Err(std::io::Error::other(field[0].to_owned() + ": not found"));
+                }
+            }
+        }
+        Err(std::io::Error::other(field[0].to_owned() + ": not a map"))
+    }
+
     // validate() is implemented in the (generated) lib.rs
 }
 
index c235fd6535bab2d9a92ef8fd7e655b8c8f35f37f..6d5bc4bc194dada838226190057d1f14e82eccbd 100644 (file)
@@ -312,8 +312,15 @@ static Answer doGetParameter(ArgIterator begin, ArgIterator end)
     return {0, ret.str()};
   }
   auto settings = g_yamlStruct.lock();
-  auto yaml = settings->to_yaml_string();
-  return {0, std::string(yaml)};
+  rust::Vec<::rust::String> field;
+  stringtok(field, *begin, ".");
+  try {
+    auto yaml = settings->get_value(field);
+    return {0, std::string(yaml)};
+  }
+  catch (const std::exception& stdex) {
+    return {1, std::string(stdex.what()) + '\n'};
+  }
 }
 
 /* Read an (open) fd from the control channel */