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