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" | ||||
| 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