Use quick-xml to serialize network definitions
This commit is contained in:
parent
e638829da7
commit
9256b76495
@ -389,7 +389,7 @@ impl Handler<DefineNetwork> for LibVirtActor {
|
|||||||
log::debug!("Define network: {:?}", msg.1);
|
log::debug!("Define network: {:?}", msg.1);
|
||||||
|
|
||||||
log::debug!("Source network structure: {:#?}", 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}");
|
log::debug!("Define network XML: {network_xml}");
|
||||||
|
|
||||||
let network = Network::define_xml(&self.m, &network_xml)?;
|
let network = Network::define_xml(&self.m, &network_xml)?;
|
||||||
|
@ -5,13 +5,9 @@ use std::net::{IpAddr, Ipv4Addr};
|
|||||||
#[derive(serde::Serialize, serde::Deserialize, Debug)]
|
#[derive(serde::Serialize, serde::Deserialize, Debug)]
|
||||||
#[serde(rename = "forward")]
|
#[serde(rename = "forward")]
|
||||||
pub struct NetworkForwardXML {
|
pub struct NetworkForwardXML {
|
||||||
#[serde(rename(serialize = "@mode"))]
|
#[serde(rename = "@mode")]
|
||||||
pub mode: String,
|
pub mode: String,
|
||||||
#[serde(
|
#[serde(default, rename = "@dev", skip_serializing_if = "String::is_empty")]
|
||||||
default,
|
|
||||||
rename(serialize = "@dev"),
|
|
||||||
skip_serializing_if = "String::is_empty"
|
|
||||||
)]
|
|
||||||
pub dev: String,
|
pub dev: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -19,7 +15,7 @@ pub struct NetworkForwardXML {
|
|||||||
#[derive(serde::Serialize, serde::Deserialize, Debug)]
|
#[derive(serde::Serialize, serde::Deserialize, Debug)]
|
||||||
#[serde(rename = "bridge")]
|
#[serde(rename = "bridge")]
|
||||||
pub struct NetworkBridgeXML {
|
pub struct NetworkBridgeXML {
|
||||||
#[serde(rename(serialize = "@name"))]
|
#[serde(rename = "@name")]
|
||||||
pub name: String,
|
pub name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,7 +31,7 @@ pub struct NetworkDNSXML {
|
|||||||
#[serde(rename = "forwarder")]
|
#[serde(rename = "forwarder")]
|
||||||
pub struct NetworkDNSForwarderXML {
|
pub struct NetworkDNSForwarderXML {
|
||||||
/// Address of the DNS server
|
/// Address of the DNS server
|
||||||
#[serde(rename(serialize = "@addr"))]
|
#[serde(rename = "@addr")]
|
||||||
pub addr: Ipv4Addr,
|
pub addr: Ipv4Addr,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,7 +39,7 @@ pub struct NetworkDNSForwarderXML {
|
|||||||
#[derive(serde::Serialize, serde::Deserialize, Debug)]
|
#[derive(serde::Serialize, serde::Deserialize, Debug)]
|
||||||
#[serde(rename = "domain")]
|
#[serde(rename = "domain")]
|
||||||
pub struct NetworkDomainXML {
|
pub struct NetworkDomainXML {
|
||||||
#[serde(rename(serialize = "@name"))]
|
#[serde(rename = "@name")]
|
||||||
pub name: String,
|
pub name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,50 +55,20 @@ fn invalid_ip() -> IpAddr {
|
|||||||
#[derive(serde::Serialize, serde::Deserialize, Debug)]
|
#[derive(serde::Serialize, serde::Deserialize, Debug)]
|
||||||
#[serde(rename = "ip")]
|
#[serde(rename = "ip")]
|
||||||
pub struct NetworkIPXML {
|
pub struct NetworkIPXML {
|
||||||
#[serde(default, rename(serialize = "@family"))]
|
#[serde(default, rename = "@family")]
|
||||||
pub family: String,
|
pub family: String,
|
||||||
#[serde(rename(serialize = "@address"))]
|
#[serde(rename = "@address")]
|
||||||
pub address: IpAddr,
|
pub address: IpAddr,
|
||||||
/// Network Prefix
|
/// Network Prefix
|
||||||
#[serde(rename(serialize = "@prefix"), default = "invalid_prefix")]
|
#[serde(rename = "@prefix", default = "invalid_prefix")]
|
||||||
pub prefix: u32,
|
pub prefix: u32,
|
||||||
/// Network Netmask. This field is never serialized, but because we can't know if LibVirt will
|
/// 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
|
/// provide us netmask or prefix, we need to handle both of these fields
|
||||||
#[serde(
|
#[serde(rename = "@netmask", default = "invalid_ip", skip_serializing)]
|
||||||
rename(serialize = "@netmask"),
|
|
||||||
default = "invalid_ip",
|
|
||||||
skip_serializing
|
|
||||||
)]
|
|
||||||
pub netmask: IpAddr,
|
pub netmask: IpAddr,
|
||||||
pub dhcp: Option<NetworkDHCPXML>,
|
pub dhcp: Option<NetworkDHCPXML>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NetworkIPXML {
|
|
||||||
pub fn into_xml(mut self) -> anyhow::Result<String> {
|
|
||||||
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("<host").unwrap();
|
|
||||||
hosts_xml.push(host_xml[start_offset..].to_string());
|
|
||||||
}
|
|
||||||
|
|
||||||
dhcp.hosts = vec![];
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut res = serde_xml_rs::to_string(&self)?;
|
|
||||||
let hosts_xml = hosts_xml.join("\n");
|
|
||||||
res = res.replace("</dhcp>", &format!("{hosts_xml}</dhcp>"));
|
|
||||||
Ok(res)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(serde::Serialize, serde::Deserialize, Debug)]
|
#[derive(serde::Serialize, serde::Deserialize, Debug)]
|
||||||
#[serde(rename = "dhcp")]
|
#[serde(rename = "dhcp")]
|
||||||
pub struct NetworkDHCPXML {
|
pub struct NetworkDHCPXML {
|
||||||
@ -114,20 +80,20 @@ pub struct NetworkDHCPXML {
|
|||||||
#[derive(serde::Serialize, serde::Deserialize, Debug)]
|
#[derive(serde::Serialize, serde::Deserialize, Debug)]
|
||||||
#[serde(rename = "host")]
|
#[serde(rename = "host")]
|
||||||
pub struct NetworkDHCPHostXML {
|
pub struct NetworkDHCPHostXML {
|
||||||
#[serde(rename(serialize = "@mac"), default)]
|
#[serde(rename = "@mac", default, skip_serializing_if = "Option::is_none")]
|
||||||
pub mac: String,
|
pub mac: Option<String>,
|
||||||
#[serde(rename(serialize = "@name"))]
|
#[serde(rename = "@name")]
|
||||||
pub name: String,
|
pub name: String,
|
||||||
#[serde(rename(serialize = "@ip"))]
|
#[serde(rename = "@ip")]
|
||||||
pub ip: IpAddr,
|
pub ip: IpAddr,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(serde::Serialize, serde::Deserialize, Debug)]
|
#[derive(serde::Serialize, serde::Deserialize, Debug)]
|
||||||
#[serde(rename = "dhcp")]
|
#[serde(rename = "dhcp")]
|
||||||
pub struct NetworkDHCPRangeXML {
|
pub struct NetworkDHCPRangeXML {
|
||||||
#[serde(rename(serialize = "@start"))]
|
#[serde(rename = "@start")]
|
||||||
pub start: IpAddr,
|
pub start: IpAddr,
|
||||||
#[serde(rename(serialize = "@end"))]
|
#[serde(rename = "@end")]
|
||||||
pub end: IpAddr,
|
pub end: IpAddr,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,25 +122,10 @@ pub struct NetworkXML {
|
|||||||
|
|
||||||
impl NetworkXML {
|
impl NetworkXML {
|
||||||
pub fn parse_xml(xml: &str) -> anyhow::Result<Self> {
|
pub fn parse_xml(xml: &str) -> anyhow::Result<Self> {
|
||||||
Ok(serde_xml_rs::from_str(xml)?)
|
Ok(quick_xml::de::from_str(xml)?)
|
||||||
}
|
}
|
||||||
pub fn into_xml(mut self) -> anyhow::Result<String> {
|
|
||||||
// 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("<ip").unwrap();
|
|
||||||
ips_xml.push(ip_xml[start_offset..].to_string());
|
|
||||||
}
|
|
||||||
self.ips = vec![];
|
|
||||||
|
|
||||||
let mut network_xml = serde_xml_rs::to_string(&self)?;
|
pub fn as_xml(&self) -> anyhow::Result<String> {
|
||||||
log::trace!("Serialize network XML start: {network_xml}");
|
Ok(quick_xml::se::to_string(self)?)
|
||||||
|
|
||||||
let ips_xml = ips_xml.join("\n");
|
|
||||||
network_xml = network_xml.replacen("</network>", &format!("{ips_xml}</network>"), 1);
|
|
||||||
Ok(network_xml)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -123,7 +123,7 @@ impl NetworkInfo {
|
|||||||
.hosts
|
.hosts
|
||||||
.iter()
|
.iter()
|
||||||
.map(|c| NetworkDHCPHostXML {
|
.map(|c| NetworkDHCPHostXML {
|
||||||
mac: c.mac.to_string(),
|
mac: Some(c.mac.to_string()),
|
||||||
name: c.name.to_string(),
|
name: c.name.to_string(),
|
||||||
ip: c.ip.into(),
|
ip: c.ip.into(),
|
||||||
})
|
})
|
||||||
@ -150,7 +150,7 @@ impl NetworkInfo {
|
|||||||
.hosts
|
.hosts
|
||||||
.iter()
|
.iter()
|
||||||
.map(|h| NetworkDHCPHostXML {
|
.map(|h| NetworkDHCPHostXML {
|
||||||
mac: "".to_string(),
|
mac: None,
|
||||||
name: h.name.to_string(),
|
name: h.name.to_string(),
|
||||||
ip: h.ip.into(),
|
ip: h.ip.into(),
|
||||||
})
|
})
|
||||||
@ -221,7 +221,7 @@ impl NetworkInfo {
|
|||||||
.hosts
|
.hosts
|
||||||
.iter()
|
.iter()
|
||||||
.map(|h| DHCPv4HostReservation {
|
.map(|h| DHCPv4HostReservation {
|
||||||
mac: h.mac.to_string(),
|
mac: h.mac.clone().unwrap_or_default(),
|
||||||
name: h.name.to_string(),
|
name: h.name.to_string(),
|
||||||
ip: extract_ipv4(h.ip),
|
ip: extract_ipv4(h.ip),
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user