From: Otto Moerbeek Date: Tue, 28 Oct 2025 14:11:36 +0000 (+0100) Subject: Print yaml representation for get-parameter X-Git-Tag: rec-5.4.0-alpha1~108^2~8 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=653be231d6b282c52addd95d33b1798ccae8c604;p=thirdparty%2Fpdns.git Print yaml representation for get-parameter Known issue: parameters having default vaues are not found Signed-off-by: Otto Moerbeek --- diff --git a/pdns/recursordist/rec-rust-lib/rust-bridge-in.rs b/pdns/recursordist/rec-rust-lib/rust-bridge-in.rs index abe35bdd8b..9963ef2376 100644 --- a/pdns/recursordist/rec-rust-lib/rust-bridge-in.rs +++ b/pdns/recursordist/rec-rust-lib/rust-bridge-in.rs @@ -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; + fn get_value(self: &Recursorsettings, field: &Vec) -> Result; // When doing a conversion of old-style to YAML style we use a vector of OldStyle structs fn map_to_yaml_string(map: &Vec) -> Result; fn forward_zones_to_yaml_string(vec: &Vec) -> Result; diff --git a/pdns/recursordist/rec-rust-lib/rust/src/bridge.rs b/pdns/recursordist/rec-rust-lib/rust/src/bridge.rs index 89dd401ee0..cc218652ae 100644 --- a/pdns/recursordist/rec-rust-lib/rust/src/bridge.rs +++ b/pdns/recursordist/rec-rust-lib/rust/src/bridge.rs @@ -905,6 +905,70 @@ impl Recursorsettings { serde_yaml::to_string(self) } + fn get_value_from_map(map: &serde_yaml::Mapping, fields: &[String]) -> Result { + 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) -> Result { + 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 } diff --git a/pdns/recursordist/rec_channel_rec.cc b/pdns/recursordist/rec_channel_rec.cc index c235fd6535..6d5bc4bc19 100644 --- a/pdns/recursordist/rec_channel_rec.cc +++ b/pdns/recursordist/rec_channel_rec.cc @@ -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 */