wip: Full opnsense deserializer almost done, works on a slightly cheated config file, next step is to try the real config file
This commit is contained in:
parent
b332723431
commit
e0acbf304b
3
harmony-rs/Cargo.lock
generated
3
harmony-rs/Cargo.lock
generated
@ -1240,6 +1240,7 @@ name = "opnsense-config"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"env_logger",
|
||||
"log",
|
||||
"russh",
|
||||
"russh-keys",
|
||||
@ -2596,7 +2597,6 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "yaserde"
|
||||
version = "0.11.1"
|
||||
source = "git+https://git.nationtech.io/NationTech/yaserde#353558737f3ef73e93164c596ff920d4344f30a3"
|
||||
dependencies = [
|
||||
"log",
|
||||
"xml-rs",
|
||||
@ -2605,7 +2605,6 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "yaserde_derive"
|
||||
version = "0.11.1"
|
||||
source = "git+https://git.nationtech.io/NationTech/yaserde#353558737f3ef73e93164c596ff920d4344f30a3"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"log",
|
||||
|
||||
@ -6,10 +6,13 @@ edition = "2021"
|
||||
[dependencies]
|
||||
serde = { version = "1.0.123", features = [ "derive" ] }
|
||||
log = { workspace = true }
|
||||
env_logger = { workspace = true }
|
||||
russh = { workspace = true }
|
||||
russh-keys = { workspace = true }
|
||||
yaserde = { git = "https://git.nationtech.io/NationTech/yaserde" }
|
||||
yaserde_derive = { git = "https://git.nationtech.io/NationTech/yaserde" }
|
||||
#yaserde = { git = "https://git.nationtech.io/NationTech/yaserde" }
|
||||
#yaserde_derive = { git = "https://git.nationtech.io/NationTech/yaserde" }
|
||||
yaserde = { path = "../../../../github/yaserde/yaserde" }
|
||||
yaserde_derive = { path = "../../../../github/yaserde/yaserde_derive" }
|
||||
xml-rs = "0.8"
|
||||
thiserror = "1.0"
|
||||
async-trait = { workspace = true }
|
||||
|
||||
@ -176,7 +176,7 @@ mod tests {
|
||||
#[tokio::test]
|
||||
async fn test_load_config_from_local_file() {
|
||||
let mut test_file_path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
||||
test_file_path.push("src/tests/data/config-full-1.xml");
|
||||
test_file_path.push("src/tests/data/config-structure.xml");
|
||||
|
||||
let config_file_path = test_file_path.to_str().unwrap().to_string();
|
||||
println!("File path {config_file_path}");
|
||||
|
||||
@ -0,0 +1,110 @@
|
||||
use xml::reader::XmlEvent;
|
||||
use yaserde::{YaDeserialize, YaSerialize};
|
||||
|
||||
use crate::modules::opnsense::{Interface, Interfaces};
|
||||
|
||||
impl YaSerialize for Interfaces {
|
||||
fn serialize<W: std::io::Write>(
|
||||
&self,
|
||||
writer: &mut yaserde::ser::Serializer<W>,
|
||||
) -> Result<(), String> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn serialize_attributes(
|
||||
&self,
|
||||
attributes: Vec<xml::attribute::OwnedAttribute>,
|
||||
namespace: xml::namespace::Namespace,
|
||||
) -> Result<
|
||||
(
|
||||
Vec<xml::attribute::OwnedAttribute>,
|
||||
xml::namespace::Namespace,
|
||||
),
|
||||
String,
|
||||
> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl YaDeserialize for Interfaces {
|
||||
fn deserialize<R: std::io::Read>(
|
||||
reader: &mut yaserde::de::Deserializer<R>,
|
||||
) -> Result<Self, String> {
|
||||
let mut interfaces = Interfaces::default();
|
||||
let mut current_interface_name = String::new();
|
||||
let mut current_interface = Interface::default();
|
||||
|
||||
let mut event = reader.next_event()?;
|
||||
loop {
|
||||
match event {
|
||||
xml::reader::XmlEvent::EndElement { name } => {
|
||||
println!(
|
||||
"Handling EndElement {}, current_interface_name: {}",
|
||||
name.local_name, current_interface_name
|
||||
);
|
||||
println!("Peeking after EndElement {:?}", reader.peek()?);
|
||||
if name.local_name == "interfaces" {
|
||||
break;
|
||||
}
|
||||
todo!("Should not hit here");
|
||||
}
|
||||
xml::reader::XmlEvent::StartElement { ref name, .. } => {
|
||||
println!("Got start Element {:?}", name);
|
||||
current_interface_name = name.local_name.clone();
|
||||
println!("About to deserialize interface from name {:?}", name);
|
||||
// TODO store names
|
||||
'inner_iface: loop {
|
||||
let peek = reader.peek()?;
|
||||
println!("Peeking before forcing next event {:?}", peek);
|
||||
|
||||
if let XmlEvent::EndElement { name } = peek {
|
||||
// TODO save the interface name and struct in the hashmap
|
||||
println!("Forcing next_event");
|
||||
reader.next_event()?;
|
||||
|
||||
let peek = reader.peek()?;
|
||||
println!("Peeking after next event deserializing {:?}", peek);
|
||||
if let XmlEvent::EndElement { name } = peek {
|
||||
println!("Got two EndElement in a row, breaking out of loop");
|
||||
break 'inner_iface;
|
||||
}
|
||||
}
|
||||
println!("Peeking before deserializing {:?}", reader.peek()?);
|
||||
let interface = <Interface as yaserde::YaDeserialize>::deserialize(reader)?;
|
||||
println!("Interface deserialized {:?}", interface);
|
||||
println!("Peeking after deserializing {:?}", reader.peek()?);
|
||||
}
|
||||
println!(
|
||||
"Done with inner interface, loop completed {:?}",
|
||||
reader.peek()?
|
||||
);
|
||||
}
|
||||
xml::reader::XmlEvent::EndDocument => break,
|
||||
_ => {
|
||||
return Err(
|
||||
"This Interfaces Deserializer does not support all XmlEvent types".into(),
|
||||
)
|
||||
}
|
||||
}
|
||||
let peek = reader.peek()?;
|
||||
|
||||
let mut read_next = true;
|
||||
if let XmlEvent::EndElement { name } = peek {
|
||||
if name.local_name == "interfaces" {
|
||||
println!("Got endElement interfaces, not reading next event");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if read_next {
|
||||
event = reader.next_event()?;
|
||||
}
|
||||
println!("Outer loop got event {:?}", event);
|
||||
println!("Outer loop got peek {:?}", reader.peek()?);
|
||||
}
|
||||
println!("Done with interfaces {:?}", interfaces);
|
||||
println!("reader peeking shows {:?}", reader.peek());
|
||||
|
||||
Ok(interfaces)
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
|
||||
mod interfaces;
|
||||
|
||||
@ -14,6 +14,10 @@ impl<'a> DhcpConfig<'a> {
|
||||
mac,
|
||||
ipaddr,
|
||||
hostname,
|
||||
descr: Some("Automatically generated".into()),
|
||||
winsserver: None,
|
||||
dnsserver: None,
|
||||
ntpserver: None,
|
||||
};
|
||||
self.opnsense.dhcpd.lan.staticmaps.push(static_map);
|
||||
}
|
||||
|
||||
@ -1,2 +1,3 @@
|
||||
pub mod opnsense;
|
||||
pub mod dhcp;
|
||||
mod deserializer;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
1421
harmony-rs/opnsense-config/src/tests/data/config-structure.xml
Normal file
1421
harmony-rs/opnsense-config/src/tests/data/config-structure.xml
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user