Can extract mac rules
This commit is contained in:
		@@ -238,8 +238,8 @@ pub struct NetworkFilterRuleXML {
 | 
				
			|||||||
    pub priority: Option<i32>,
 | 
					    pub priority: Option<i32>,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Match all protocols
 | 
					    /// Match all protocols
 | 
				
			||||||
    #[serde(skip_serializing_if = "Vec::is_empty")]
 | 
					    #[serde(default, rename = "all", skip_serializing_if = "Vec::is_empty")]
 | 
				
			||||||
    pub all: Vec<NetworkFilterRuleProtocolAll>,
 | 
					    pub all_selectors: Vec<NetworkFilterRuleProtocolAll>,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Match mac protocol
 | 
					    /// Match mac protocol
 | 
				
			||||||
    #[serde(default, rename = "mac", skip_serializing_if = "Vec::is_empty")]
 | 
					    #[serde(default, rename = "mac", skip_serializing_if = "Vec::is_empty")]
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,4 +11,6 @@ enum LibVirtStructError {
 | 
				
			|||||||
    DomainExtraction(String),
 | 
					    DomainExtraction(String),
 | 
				
			||||||
    #[error("ParseFilteringChain: {0}")]
 | 
					    #[error("ParseFilteringChain: {0}")]
 | 
				
			||||||
    ParseFilteringChain(String),
 | 
					    ParseFilteringChain(String),
 | 
				
			||||||
 | 
					    #[error("NetworkFilterExtractionError: {0}")]
 | 
				
			||||||
 | 
					    NetworkFilterExtraction(String),
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,10 +5,17 @@ use crate::libvirt_lib_structures::nwfilter::{
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
use crate::libvirt_lib_structures::XMLUuid;
 | 
					use crate::libvirt_lib_structures::XMLUuid;
 | 
				
			||||||
use crate::libvirt_rest_structures::LibVirtStructError;
 | 
					use crate::libvirt_rest_structures::LibVirtStructError;
 | 
				
			||||||
use crate::libvirt_rest_structures::LibVirtStructError::StructureExtraction;
 | 
					use crate::libvirt_rest_structures::LibVirtStructError::{
 | 
				
			||||||
 | 
					    NetworkFilterExtraction, StructureExtraction,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					use crate::utils::net_utils;
 | 
				
			||||||
use lazy_regex::regex;
 | 
					use lazy_regex::regex;
 | 
				
			||||||
use std::net::{Ipv4Addr, Ipv6Addr};
 | 
					use std::net::{Ipv4Addr, Ipv6Addr};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn is_var_def(var: &str) -> bool {
 | 
				
			||||||
 | 
					    lazy_regex::regex!("^\\$[a-zA-Z0-9_]+$").is_match(var)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
 | 
					#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
 | 
				
			||||||
pub struct NetworkFilterName(pub String);
 | 
					pub struct NetworkFilterName(pub String);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -18,6 +25,47 @@ impl NetworkFilterName {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
 | 
				
			||||||
 | 
					pub struct NetworkFilterMacAddressOrVar(pub String);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl NetworkFilterMacAddressOrVar {
 | 
				
			||||||
 | 
					    pub fn is_valid(&self) -> bool {
 | 
				
			||||||
 | 
					        is_var_def(&self.0) || net_utils::is_mac_address_valid(&self.0)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl From<&String> for NetworkFilterMacAddressOrVar {
 | 
				
			||||||
 | 
					    fn from(value: &String) -> Self {
 | 
				
			||||||
 | 
					        Self(value.to_string())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn extract_mac_address_or_var(
 | 
				
			||||||
 | 
					    n: &Option<NetworkFilterMacAddressOrVar>,
 | 
				
			||||||
 | 
					) -> anyhow::Result<Option<String>> {
 | 
				
			||||||
 | 
					    if let Some(mac) = n {
 | 
				
			||||||
 | 
					        if !mac.is_valid() {
 | 
				
			||||||
 | 
					            return Err(NetworkFilterExtraction(format!(
 | 
				
			||||||
 | 
					                "Invalid mac address or variable! {}",
 | 
				
			||||||
 | 
					                mac.0
 | 
				
			||||||
 | 
					            ))
 | 
				
			||||||
 | 
					            .into());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Ok(n.as_ref().map(|n| n.0.to_string()))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn extract_nw_filter_comment(n: &Option<String>) -> anyhow::Result<Option<String>> {
 | 
				
			||||||
 | 
					    if let Some(comment) = n {
 | 
				
			||||||
 | 
					        if comment.len() > 256 || comment.contains('\"') || comment.contains('\n') {
 | 
				
			||||||
 | 
					            return Err(NetworkFilterExtraction(format!("Invalid comment! {}", comment)).into());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Ok(n.clone())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Copy, Clone)]
 | 
					#[derive(serde::Serialize, serde::Deserialize, Debug, Copy, Clone)]
 | 
				
			||||||
#[serde(rename_all = "lowercase")]
 | 
					#[serde(rename_all = "lowercase")]
 | 
				
			||||||
pub enum NetworkFilterChainProtocol {
 | 
					pub enum NetworkFilterChainProtocol {
 | 
				
			||||||
@@ -113,20 +161,20 @@ impl NetworkFilter {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    fn lib2rest_process_mac_rule(n: &NetworkFilterRuleProtocolMac) -> NetworkFilterSelector {
 | 
					    fn lib2rest_process_mac_rule(n: &NetworkFilterRuleProtocolMac) -> NetworkFilterSelector {
 | 
				
			||||||
        NetworkFilterSelector::Mac(NetworkSelectorMac {
 | 
					        NetworkFilterSelector::Mac(NetworkSelectorMac {
 | 
				
			||||||
            src_mac_addr: n.srcmacaddr.clone(),
 | 
					            src_mac_addr: n.srcmacaddr.as_ref().map(|v| v.into()),
 | 
				
			||||||
            src_mac_mask: n.srcmacmask.clone(),
 | 
					            src_mac_mask: n.srcmacmask.as_ref().map(|v| v.into()),
 | 
				
			||||||
            dst_mac_addr: n.dstmacaddr.clone(),
 | 
					            dst_mac_addr: n.dstmacaddr.as_ref().map(|v| v.into()),
 | 
				
			||||||
            dst_mac_mask: n.dstmacmask.clone(),
 | 
					            dst_mac_mask: n.dstmacmask.as_ref().map(|v| v.into()),
 | 
				
			||||||
            comment: n.comment.clone(),
 | 
					            comment: n.comment.clone(),
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn lib2rest_process_arp_rule(n: &NetworkFilterRuleProtocolArp) -> NetworkSelectorARP {
 | 
					    fn lib2rest_process_arp_rule(n: &NetworkFilterRuleProtocolArp) -> NetworkSelectorARP {
 | 
				
			||||||
        NetworkSelectorARP {
 | 
					        NetworkSelectorARP {
 | 
				
			||||||
            srcmacaddr: n.srcmacaddr.clone(),
 | 
					            srcmacaddr: n.srcmacaddr.as_ref().map(|v| v.into()),
 | 
				
			||||||
            srcmacmask: n.srcmacmask.clone(),
 | 
					            srcmacmask: n.srcmacmask.as_ref().map(|v| v.into()),
 | 
				
			||||||
            dstmacaddr: n.dstmacaddr.clone(),
 | 
					            dstmacaddr: n.dstmacaddr.as_ref().map(|v| v.into()),
 | 
				
			||||||
            dstmacmask: n.dstmacmask.clone(),
 | 
					            dstmacmask: n.dstmacmask.as_ref().map(|v| v.into()),
 | 
				
			||||||
            arpsrcipaddr: n.arpsrcipaddr.clone(),
 | 
					            arpsrcipaddr: n.arpsrcipaddr.clone(),
 | 
				
			||||||
            arpsrcipmask: n.arpsrcipmask,
 | 
					            arpsrcipmask: n.arpsrcipmask,
 | 
				
			||||||
            arpdstipaddr: n.arpdstipaddr.clone(),
 | 
					            arpdstipaddr: n.arpdstipaddr.clone(),
 | 
				
			||||||
@@ -153,7 +201,7 @@ impl NetworkFilter {
 | 
				
			|||||||
        n: &NetworkFilterRuleProtocolLayer4<IPv>,
 | 
					        n: &NetworkFilterRuleProtocolLayer4<IPv>,
 | 
				
			||||||
    ) -> anyhow::Result<NetworkSelectorLayer4<IPv>> {
 | 
					    ) -> anyhow::Result<NetworkSelectorLayer4<IPv>> {
 | 
				
			||||||
        Ok(NetworkSelectorLayer4 {
 | 
					        Ok(NetworkSelectorLayer4 {
 | 
				
			||||||
            srcmacaddr: n.srcmacaddr.clone(),
 | 
					            srcmacaddr: n.srcmacaddr.as_ref().map(|v| v.into()),
 | 
				
			||||||
            srcipaddr: n.srcipaddr,
 | 
					            srcipaddr: n.srcipaddr,
 | 
				
			||||||
            srcipmask: n.srcipmask,
 | 
					            srcipmask: n.srcipmask,
 | 
				
			||||||
            dstipaddr: n.dstipaddr,
 | 
					            dstipaddr: n.dstipaddr,
 | 
				
			||||||
@@ -179,7 +227,7 @@ impl NetworkFilter {
 | 
				
			|||||||
            // All selector
 | 
					            // All selector
 | 
				
			||||||
            selectors.append(
 | 
					            selectors.append(
 | 
				
			||||||
                &mut rule
 | 
					                &mut rule
 | 
				
			||||||
                    .all
 | 
					                    .all_selectors
 | 
				
			||||||
                    .iter()
 | 
					                    .iter()
 | 
				
			||||||
                    .map(Self::lib2rest_process_all_rule)
 | 
					                    .map(Self::lib2rest_process_all_rule)
 | 
				
			||||||
                    .collect(),
 | 
					                    .collect(),
 | 
				
			||||||
@@ -348,7 +396,7 @@ impl NetworkFilter {
 | 
				
			|||||||
            action: rule.action.to_xml(),
 | 
					            action: rule.action.to_xml(),
 | 
				
			||||||
            direction: rule.direction.to_xml(),
 | 
					            direction: rule.direction.to_xml(),
 | 
				
			||||||
            priority: rule.priority,
 | 
					            priority: rule.priority,
 | 
				
			||||||
            all: vec![],
 | 
					            all_selectors: vec![],
 | 
				
			||||||
            mac_selectors: vec![],
 | 
					            mac_selectors: vec![],
 | 
				
			||||||
            arp_selectors: vec![],
 | 
					            arp_selectors: vec![],
 | 
				
			||||||
            rarp_selectors: vec![],
 | 
					            rarp_selectors: vec![],
 | 
				
			||||||
@@ -367,18 +415,17 @@ impl NetworkFilter {
 | 
				
			|||||||
        for sel in &rule.selectors {
 | 
					        for sel in &rule.selectors {
 | 
				
			||||||
            match sel {
 | 
					            match sel {
 | 
				
			||||||
                NetworkFilterSelector::All => {
 | 
					                NetworkFilterSelector::All => {
 | 
				
			||||||
                    rule_xml.all.push(NetworkFilterRuleProtocolAll {});
 | 
					                    rule_xml.all_selectors.push(NetworkFilterRuleProtocolAll {});
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                NetworkFilterSelector::Mac(mac) => {
 | 
					                NetworkFilterSelector::Mac(mac) => {
 | 
				
			||||||
                    todo!()
 | 
					                    rule_xml.mac_selectors.push(NetworkFilterRuleProtocolMac {
 | 
				
			||||||
                    /*rule_xml.mac_selectors.push(NetworkFilterRuleProtocolMac {
 | 
					                        srcmacaddr: extract_mac_address_or_var(&mac.src_mac_addr)?,
 | 
				
			||||||
                        srcmacaddr: mac.src_mac_addr,
 | 
					                        srcmacmask: extract_mac_address_or_var(&mac.src_mac_mask)?,
 | 
				
			||||||
                        srcmacmask: mac.src_mac_mask,
 | 
					                        dstmacaddr: extract_mac_address_or_var(&mac.dst_mac_addr)?,
 | 
				
			||||||
                        dstmacaddr: mac.,
 | 
					                        dstmacmask: extract_mac_address_or_var(&mac.dst_mac_mask)?,
 | 
				
			||||||
                        dstmacmask: None,
 | 
					                        comment: extract_nw_filter_comment(&mac.comment)?,
 | 
				
			||||||
                        comment: None,
 | 
					                    })
 | 
				
			||||||
                    })*/
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                NetworkFilterSelector::Arp(_) => todo!(),
 | 
					                NetworkFilterSelector::Arp(_) => todo!(),
 | 
				
			||||||
@@ -401,12 +448,16 @@ impl NetworkFilter {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    pub fn rest2lib(&self) -> anyhow::Result<NetworkFilterXML> {
 | 
					    pub fn rest2lib(&self) -> anyhow::Result<NetworkFilterXML> {
 | 
				
			||||||
        if !self.name.is_valid() {
 | 
					        if !self.name.is_valid() {
 | 
				
			||||||
            return Err(StructureExtraction("Network filter name is invalid!").into());
 | 
					            return Err(
 | 
				
			||||||
 | 
					                NetworkFilterExtraction("Network filter name is invalid!".to_string()).into(),
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if let Some(priority) = self.priority {
 | 
					        if let Some(priority) = self.priority {
 | 
				
			||||||
            if !(-1000..=1000).contains(&priority) {
 | 
					            if !(-1000..=1000).contains(&priority) {
 | 
				
			||||||
                return Err(StructureExtraction("Network priority is invalid!").into());
 | 
					                return Err(
 | 
				
			||||||
 | 
					                    NetworkFilterExtraction("Network priority is invalid!".to_string()).into(),
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -572,19 +623,19 @@ pub struct NetworkFilterSelectorIP {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
 | 
					#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
 | 
				
			||||||
pub struct NetworkSelectorMac {
 | 
					pub struct NetworkSelectorMac {
 | 
				
			||||||
    src_mac_addr: Option<String>,
 | 
					    src_mac_addr: Option<NetworkFilterMacAddressOrVar>,
 | 
				
			||||||
    src_mac_mask: Option<String>,
 | 
					    src_mac_mask: Option<NetworkFilterMacAddressOrVar>,
 | 
				
			||||||
    dst_mac_addr: Option<String>,
 | 
					    dst_mac_addr: Option<NetworkFilterMacAddressOrVar>,
 | 
				
			||||||
    dst_mac_mask: Option<String>,
 | 
					    dst_mac_mask: Option<NetworkFilterMacAddressOrVar>,
 | 
				
			||||||
    comment: Option<String>,
 | 
					    comment: Option<String>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
 | 
					#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
 | 
				
			||||||
pub struct NetworkSelectorARP {
 | 
					pub struct NetworkSelectorARP {
 | 
				
			||||||
    srcmacaddr: Option<String>,
 | 
					    srcmacaddr: Option<NetworkFilterMacAddressOrVar>,
 | 
				
			||||||
    srcmacmask: Option<String>,
 | 
					    srcmacmask: Option<NetworkFilterMacAddressOrVar>,
 | 
				
			||||||
    dstmacaddr: Option<String>,
 | 
					    dstmacaddr: Option<NetworkFilterMacAddressOrVar>,
 | 
				
			||||||
    dstmacmask: Option<String>,
 | 
					    dstmacmask: Option<NetworkFilterMacAddressOrVar>,
 | 
				
			||||||
    arpsrcipaddr: Option<String>,
 | 
					    arpsrcipaddr: Option<String>,
 | 
				
			||||||
    arpsrcipmask: Option<u8>,
 | 
					    arpsrcipmask: Option<u8>,
 | 
				
			||||||
    arpdstipaddr: Option<String>,
 | 
					    arpdstipaddr: Option<String>,
 | 
				
			||||||
@@ -594,7 +645,7 @@ pub struct NetworkSelectorARP {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
 | 
					#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
 | 
				
			||||||
pub struct NetworkSelectorLayer4<IPv> {
 | 
					pub struct NetworkSelectorLayer4<IPv> {
 | 
				
			||||||
    srcmacaddr: Option<String>,
 | 
					    srcmacaddr: Option<NetworkFilterMacAddressOrVar>,
 | 
				
			||||||
    srcipaddr: Option<IPv>,
 | 
					    srcipaddr: Option<IPv>,
 | 
				
			||||||
    srcipmask: Option<u8>,
 | 
					    srcipmask: Option<u8>,
 | 
				
			||||||
    dstipaddr: Option<IPv>,
 | 
					    dstipaddr: Option<IPv>,
 | 
				
			||||||
@@ -645,3 +696,19 @@ pub struct NetworkFilterRule {
 | 
				
			|||||||
    priority: Option<i32>,
 | 
					    priority: Option<i32>,
 | 
				
			||||||
    selectors: Vec<NetworkFilterSelector>,
 | 
					    selectors: Vec<NetworkFilterSelector>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[cfg(test)]
 | 
				
			||||||
 | 
					mod test {
 | 
				
			||||||
 | 
					    use crate::libvirt_rest_structures::nw_filter::is_var_def;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[test]
 | 
				
			||||||
 | 
					    pub fn var_def() {
 | 
				
			||||||
 | 
					        assert!(is_var_def("$MAC"));
 | 
				
			||||||
 | 
					        assert!(is_var_def("$MAC_ADDRESS"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        assert!(!is_var_def("$$MAC"));
 | 
				
			||||||
 | 
					        assert!(!is_var_def("$$MACé"));
 | 
				
			||||||
 | 
					        assert!(!is_var_def("$$MAC@"));
 | 
				
			||||||
 | 
					        assert!(!is_var_def("$$MAC TEST"));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user