forked from NationTech/harmony
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"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
|
"env_logger",
|
||||||
"log",
|
"log",
|
||||||
"russh",
|
"russh",
|
||||||
"russh-keys",
|
"russh-keys",
|
||||||
@ -2596,7 +2597,6 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "yaserde"
|
name = "yaserde"
|
||||||
version = "0.11.1"
|
version = "0.11.1"
|
||||||
source = "git+https://git.nationtech.io/NationTech/yaserde#353558737f3ef73e93164c596ff920d4344f30a3"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"xml-rs",
|
"xml-rs",
|
||||||
@ -2605,7 +2605,6 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "yaserde_derive"
|
name = "yaserde_derive"
|
||||||
version = "0.11.1"
|
version = "0.11.1"
|
||||||
source = "git+https://git.nationtech.io/NationTech/yaserde#353558737f3ef73e93164c596ff920d4344f30a3"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"heck",
|
"heck",
|
||||||
"log",
|
"log",
|
||||||
|
|||||||
@ -6,10 +6,13 @@ edition = "2021"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
serde = { version = "1.0.123", features = [ "derive" ] }
|
serde = { version = "1.0.123", features = [ "derive" ] }
|
||||||
log = { workspace = true }
|
log = { workspace = true }
|
||||||
|
env_logger = { workspace = true }
|
||||||
russh = { workspace = true }
|
russh = { workspace = true }
|
||||||
russh-keys = { workspace = true }
|
russh-keys = { workspace = true }
|
||||||
yaserde = { 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_derive = { git = "https://git.nationtech.io/NationTech/yaserde" }
|
||||||
|
yaserde = { path = "../../../../github/yaserde/yaserde" }
|
||||||
|
yaserde_derive = { path = "../../../../github/yaserde/yaserde_derive" }
|
||||||
xml-rs = "0.8"
|
xml-rs = "0.8"
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
async-trait = { workspace = true }
|
async-trait = { workspace = true }
|
||||||
|
|||||||
@ -176,7 +176,7 @@ mod tests {
|
|||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_load_config_from_local_file() {
|
async fn test_load_config_from_local_file() {
|
||||||
let mut test_file_path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
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();
|
let config_file_path = test_file_path.to_str().unwrap().to_string();
|
||||||
println!("File path {config_file_path}");
|
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,
|
mac,
|
||||||
ipaddr,
|
ipaddr,
|
||||||
hostname,
|
hostname,
|
||||||
|
descr: Some("Automatically generated".into()),
|
||||||
|
winsserver: None,
|
||||||
|
dnsserver: None,
|
||||||
|
ntpserver: None,
|
||||||
};
|
};
|
||||||
self.opnsense.dhcpd.lan.staticmaps.push(static_map);
|
self.opnsense.dhcpd.lan.staticmaps.push(static_map);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,2 +1,3 @@
|
|||||||
pub mod opnsense;
|
pub mod opnsense;
|
||||||
pub mod dhcp;
|
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