From 9256b764957fedc52365be2771f6dc473960a416 Mon Sep 17 00:00:00 2001 From: Pierre Hubert Date: Tue, 2 Jan 2024 14:31:34 +0100 Subject: [PATCH] Use quick-xml to serialize network definitions --- virtweb_backend/src/actors/libvirt_actor.rs | 2 +- .../src/libvirt_lib_structures/network.rs | 85 ++++--------------- .../src/libvirt_rest_structures/net.rs | 6 +- 3 files changed, 22 insertions(+), 71 deletions(-) diff --git a/virtweb_backend/src/actors/libvirt_actor.rs b/virtweb_backend/src/actors/libvirt_actor.rs index 8e67d1d..ddb5745 100644 --- a/virtweb_backend/src/actors/libvirt_actor.rs +++ b/virtweb_backend/src/actors/libvirt_actor.rs @@ -389,7 +389,7 @@ impl Handler for LibVirtActor { log::debug!("Define network: {:?}", msg.1); log::debug!("Source network structure: {:#?}", msg.1); - let network_xml = msg.1.into_xml()?; + let network_xml = msg.1.as_xml()?; log::debug!("Define network XML: {network_xml}"); let network = Network::define_xml(&self.m, &network_xml)?; diff --git a/virtweb_backend/src/libvirt_lib_structures/network.rs b/virtweb_backend/src/libvirt_lib_structures/network.rs index 6bc275e..d7817ef 100644 --- a/virtweb_backend/src/libvirt_lib_structures/network.rs +++ b/virtweb_backend/src/libvirt_lib_structures/network.rs @@ -5,13 +5,9 @@ use std::net::{IpAddr, Ipv4Addr}; #[derive(serde::Serialize, serde::Deserialize, Debug)] #[serde(rename = "forward")] pub struct NetworkForwardXML { - #[serde(rename(serialize = "@mode"))] + #[serde(rename = "@mode")] pub mode: String, - #[serde( - default, - rename(serialize = "@dev"), - skip_serializing_if = "String::is_empty" - )] + #[serde(default, rename = "@dev", skip_serializing_if = "String::is_empty")] pub dev: String, } @@ -19,7 +15,7 @@ pub struct NetworkForwardXML { #[derive(serde::Serialize, serde::Deserialize, Debug)] #[serde(rename = "bridge")] pub struct NetworkBridgeXML { - #[serde(rename(serialize = "@name"))] + #[serde(rename = "@name")] pub name: String, } @@ -35,7 +31,7 @@ pub struct NetworkDNSXML { #[serde(rename = "forwarder")] pub struct NetworkDNSForwarderXML { /// Address of the DNS server - #[serde(rename(serialize = "@addr"))] + #[serde(rename = "@addr")] pub addr: Ipv4Addr, } @@ -43,7 +39,7 @@ pub struct NetworkDNSForwarderXML { #[derive(serde::Serialize, serde::Deserialize, Debug)] #[serde(rename = "domain")] pub struct NetworkDomainXML { - #[serde(rename(serialize = "@name"))] + #[serde(rename = "@name")] pub name: String, } @@ -59,50 +55,20 @@ fn invalid_ip() -> IpAddr { #[derive(serde::Serialize, serde::Deserialize, Debug)] #[serde(rename = "ip")] pub struct NetworkIPXML { - #[serde(default, rename(serialize = "@family"))] + #[serde(default, rename = "@family")] pub family: String, - #[serde(rename(serialize = "@address"))] + #[serde(rename = "@address")] pub address: IpAddr, /// Network Prefix - #[serde(rename(serialize = "@prefix"), default = "invalid_prefix")] + #[serde(rename = "@prefix", default = "invalid_prefix")] pub prefix: u32, /// Network Netmask. This field is never serialized, but because we can't know if LibVirt will /// provide us netmask or prefix, we need to handle both of these fields - #[serde( - rename(serialize = "@netmask"), - default = "invalid_ip", - skip_serializing - )] + #[serde(rename = "@netmask", default = "invalid_ip", skip_serializing)] pub netmask: IpAddr, pub dhcp: Option, } -impl NetworkIPXML { - pub fn into_xml(mut self) -> anyhow::Result { - let mut hosts_xml = vec![]; - - if let Some(dhcp) = &mut self.dhcp { - for host in &dhcp.hosts { - let mut host_xml = serde_xml_rs::to_string(&host)?; - - // In case of IPv6, mac address should not be specified - host_xml = host_xml.replace("mac=\"\"", ""); - - // strip xml tag - let start_offset = host_xml.find("", &format!("{hosts_xml}")); - Ok(res) - } -} - #[derive(serde::Serialize, serde::Deserialize, Debug)] #[serde(rename = "dhcp")] pub struct NetworkDHCPXML { @@ -114,20 +80,20 @@ pub struct NetworkDHCPXML { #[derive(serde::Serialize, serde::Deserialize, Debug)] #[serde(rename = "host")] pub struct NetworkDHCPHostXML { - #[serde(rename(serialize = "@mac"), default)] - pub mac: String, - #[serde(rename(serialize = "@name"))] + #[serde(rename = "@mac", default, skip_serializing_if = "Option::is_none")] + pub mac: Option, + #[serde(rename = "@name")] pub name: String, - #[serde(rename(serialize = "@ip"))] + #[serde(rename = "@ip")] pub ip: IpAddr, } #[derive(serde::Serialize, serde::Deserialize, Debug)] #[serde(rename = "dhcp")] pub struct NetworkDHCPRangeXML { - #[serde(rename(serialize = "@start"))] + #[serde(rename = "@start")] pub start: IpAddr, - #[serde(rename(serialize = "@end"))] + #[serde(rename = "@end")] pub end: IpAddr, } @@ -156,25 +122,10 @@ pub struct NetworkXML { impl NetworkXML { pub fn parse_xml(xml: &str) -> anyhow::Result { - Ok(serde_xml_rs::from_str(xml)?) + Ok(quick_xml::de::from_str(xml)?) } - pub fn into_xml(mut self) -> anyhow::Result { - // A issue with the IPs definition serialization needs them to be serialized aside - let mut ips_xml = Vec::with_capacity(self.ips.len()); - for ip in self.ips { - log::debug!("Serialize {ip:?}"); - let ip_xml = ip.into_xml()?; - // strip xml tag - let start_offset = ip_xml.find("", &format!("{ips_xml}"), 1); - Ok(network_xml) + pub fn as_xml(&self) -> anyhow::Result { + Ok(quick_xml::se::to_string(self)?) } } diff --git a/virtweb_backend/src/libvirt_rest_structures/net.rs b/virtweb_backend/src/libvirt_rest_structures/net.rs index 64e6d86..7094cef 100644 --- a/virtweb_backend/src/libvirt_rest_structures/net.rs +++ b/virtweb_backend/src/libvirt_rest_structures/net.rs @@ -123,7 +123,7 @@ impl NetworkInfo { .hosts .iter() .map(|c| NetworkDHCPHostXML { - mac: c.mac.to_string(), + mac: Some(c.mac.to_string()), name: c.name.to_string(), ip: c.ip.into(), }) @@ -150,7 +150,7 @@ impl NetworkInfo { .hosts .iter() .map(|h| NetworkDHCPHostXML { - mac: "".to_string(), + mac: None, name: h.name.to_string(), ip: h.ip.into(), }) @@ -221,7 +221,7 @@ impl NetworkInfo { .hosts .iter() .map(|h| DHCPv4HostReservation { - mac: h.mac.to_string(), + mac: h.mac.clone().unwrap_or_default(), name: h.name.to_string(), ip: extract_ipv4(h.ip), })