]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Produce a properly indented YAML snippet
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Wed, 29 Oct 2025 10:47:35 +0000 (11:47 +0100)
committerOtto Moerbeek <otto.moerbeek@open-xchange.com>
Tue, 4 Nov 2025 12:40:38 +0000 (13:40 +0100)
Signed-off-by: Otto Moerbeek <otto.moerbeek@open-xchange.com>
pdns/recursordist/rec-rust-lib/rust/src/bridge.rs
pdns/recursordist/rec_channel_rec.cc

index 0fc9f959b6edac3d195c2d085f9212685cda89a0..7fb9990de50d05900d08e4a42504c7da35c0bb32 100644 (file)
@@ -905,22 +905,14 @@ impl Recursorsettings {
         serde_yaml::to_string(self)
     }
 
-    fn get_value_from_map(map: &serde_yaml::Mapping, fields: &[String]) -> Result<String, std::io::Error>  {
+    fn get_value_from_map(map: &serde_yaml::Mapping, fields: &[String]) -> Result<serde_yaml::Value, 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())
+                Ok(serde_yaml::Value::Mapping(map.clone()))
             }
             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())
+                    Ok(found.clone())
                 }
                 else {
                     Err(std::io::Error::other(fields[0].to_owned() + ": not found"))
@@ -942,7 +934,7 @@ impl Recursorsettings {
         }
     }
 
-    fn get_value1(value: &serde_yaml::Value, field: &[String]) -> Result<String, std::io::Error> {
+    fn get_value1(value: &serde_yaml::Value, field: &[String]) -> Result<serde_yaml::Value, std::io::Error> {
         if let Some(map) = value.as_mapping() {
             match field.len() {
                 0 => {
@@ -964,6 +956,17 @@ impl Recursorsettings {
         Err(std::io::Error::other(field[0].to_owned() + ": not a map"))
     }
 
+    fn buildnestedmaps(field: &[String], leaf: &serde_yaml::Value) -> serde_yaml::Value {
+        if field.len() == 0 {
+            return leaf.clone();
+        }
+        let submap = Self::buildnestedmaps(&field[1..], leaf);
+        let mut map = serde_yaml::Mapping::new();
+        map.insert(serde_yaml::Value::String(field[0].clone()),
+                   submap);
+        serde_yaml::Value::Mapping(map)
+    }
+
     pub fn get_value(&self, field: &[String], defaults: &str) -> Result<String, std::io::Error> {
         let value = serde_yaml::to_value(self);
         let value = match value {
@@ -971,13 +974,21 @@ impl Recursorsettings {
             Err(error) => return Err(std::io::Error::other(error.to_string()))
         };
         match Self::get_value1(&value, field) {
-            Ok(yaml) => Ok(yaml),
+            Ok(yaml) => {
+                let map = Self::buildnestedmaps(field, &yaml);
+                Ok(serde_yaml::to_string(&map).unwrap())
+            }
             Err(_) => {
                 let defaults_value: serde_yaml::Value = serde_yaml::from_str(defaults).unwrap();
-                let yaml = Self::get_value1(&defaults_value, field);
-                match yaml {
-                    Ok(yaml) => Ok("# Not explicitly set, default value(s) listed below:\n".to_owned() + &yaml),
-                    x => x
+                let value = Self::get_value1(&defaults_value, field);
+                match value {
+                    Ok(value) => {
+                        let map = Self::buildnestedmaps(field, &value);
+                        let res = serde_yaml::to_string(&map).unwrap();
+                        let msg = format!("# {}: not explicitly set, default value(s) listed below:\n{}", field[0], res);
+                        Ok(msg)
+                    },
+                    Err(x) => Err(x)
                 }
             }
         }
index f8d578760336df94c452a213434993028f89b977..3ec25490e0341d488288f2cbdfd96cb76168c55d 100644 (file)
@@ -297,8 +297,9 @@ static Answer doGet(ArgIterator begin, ArgIterator end)
 
 static Answer doGetParameter(ArgIterator begin, ArgIterator end)
 {
+  std::stringstream ret;
+  int err = 0;
   if (!g_yamlSettings) {
-    std::stringstream ret;
 
     for (auto i = begin; i != end; ++i) {
       if (::arg().parmIsset(*i)) {
@@ -307,21 +308,34 @@ static Answer doGetParameter(ArgIterator begin, ArgIterator end)
       }
       else {
         ret << *i << " not known" << endl;
+        err = 1;
       }
     }
-    return {0, ret.str()};
   }
-  auto settings = g_yamlStruct.lock();
-  rust::Vec<::rust::String> field;
-  stringtok(field, *begin, ".");
-  rust::Slice<const ::rust::String> slice{field};
-  try {
-    auto yaml = settings->get_value(slice, pdns::settings::rec::defaultsToYaml(false));
-    return {0, std::string(yaml)};
-  }
-  catch (const std::exception& stdex) {
-    return {1, std::string(stdex.what()) + '\n'};
+  else {
+    auto settings = g_yamlStruct.lock();
+    ret << "# YAML settings active" << endl;
+    if (begin == end) {
+      auto yaml = settings->get_value({}, pdns::settings::rec::defaultsToYaml(false));
+      ret << std::string(yaml);
+    }
+    else {
+      for (auto i = begin; i != end; ++i) {
+        rust::Vec<::rust::String> field;
+        stringtok(field, *i, ".");
+        rust::Slice<const ::rust::String> slice{field};
+        try {
+          auto yaml = settings->get_value(slice, pdns::settings::rec::defaultsToYaml(false));
+          ret << std::string(yaml);
+        }
+        catch (const std::exception& stdex) {
+          ret << std::string(stdex.what()) << endl;
+          err = 1;
+        }
+      }
+    }
   }
+  return {err, ret.str()};
 }
 
 /* Read an (open) fd from the control channel */