Start to inflate NWFilter REST api

This commit is contained in:
Pierre HUBERT 2023-12-28 15:42:43 +01:00
parent 3849b0d51d
commit f7777fe085
2 changed files with 123 additions and 36 deletions

View File

@ -1,5 +1,6 @@
use crate::controllers::{HttpResult, LibVirtReq}; use crate::controllers::{HttpResult, LibVirtReq};
use crate::libvirt_lib_structures::XMLUuid; use crate::libvirt_lib_structures::XMLUuid;
use crate::libvirt_rest_structures::NetworkFilter;
use actix_web::{web, HttpResponse}; use actix_web::{web, HttpResponse};
#[derive(serde::Serialize, serde::Deserialize)] #[derive(serde::Serialize, serde::Deserialize)]
@ -18,19 +19,16 @@ pub async fn list(client: LibVirtReq) -> HttpResult {
Ok(l) => l, Ok(l) => l,
}; };
/*let networks = networks let networks = networks
.into_iter() .into_iter()
.map(|n| NetworkInfo::from_xml(n).unwrap()) .map(|n| NetworkFilter::from_xml(n).unwrap())
.collect::<Vec<_>>();*/ .collect::<Vec<_>>();
// TODO : turn into lib structure
println!("{:#?}", networks);
Ok(HttpResponse::Ok().body(format!("{:#?}", networks))) Ok(HttpResponse::Ok().json(networks))
} }
/// Get the information about a single network filter /// Get the information about a single network filter
pub async fn get_single(client: LibVirtReq, req: web::Path<NetworkFilterID>) -> HttpResult { pub async fn get_single(client: LibVirtReq, req: web::Path<NetworkFilterID>) -> HttpResult {
let nwfilter = client.get_single_network_filter(req.uid).await?; let nwfilter = NetworkFilter::from_xml(client.get_single_network_filter(req.uid).await?)?;
// TODO : turn into lib structure Ok(HttpResponse::Ok().json(nwfilter))
Ok(HttpResponse::Ok().body(format!("{:#?}", nwfilter)))
} }

View File

@ -5,9 +5,9 @@ use crate::libvirt_lib_structures::{
DomainCPUTopology, DomainCPUXML, DomainInputXML, DomainMemoryXML, DomainNetInterfaceXML, DomainCPUTopology, DomainCPUXML, DomainInputXML, DomainMemoryXML, DomainNetInterfaceXML,
DomainVCPUXML, DomainXML, FeaturesXML, GraphicsXML, NetIntModelXML, NetIntSourceXML, DomainVCPUXML, DomainXML, FeaturesXML, GraphicsXML, NetIntModelXML, NetIntSourceXML,
NetMacAddress, NetworkBridgeXML, NetworkDHCPHostXML, NetworkDHCPRangeXML, NetworkDHCPXML, NetMacAddress, NetworkBridgeXML, NetworkDHCPHostXML, NetworkDHCPRangeXML, NetworkDHCPXML,
NetworkDNSForwarderXML, NetworkDNSXML, NetworkDomainXML, NetworkForwardXML, NetworkIPXML, NetworkDNSForwarderXML, NetworkDNSXML, NetworkDomainXML, NetworkFilterXML, NetworkForwardXML,
NetworkXML, OSLoaderXML, OSTypeXML, TPMBackendXML, TPMDeviceXML, VideoModelXML, VideoXML, NetworkIPXML, NetworkXML, OSLoaderXML, OSTypeXML, TPMBackendXML, TPMDeviceXML, VideoModelXML,
XMLUuid, ACPIXML, OSXML, VideoXML, XMLUuid, ACPIXML, OSXML,
}; };
use crate::libvirt_rest_structures::LibVirtStructError::StructureExtraction; use crate::libvirt_rest_structures::LibVirtStructError::StructureExtraction;
use crate::utils::disks_utils::Disk; use crate::utils::disks_utils::Disk;
@ -18,6 +18,8 @@ use num::Integer;
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
use std::ops::{Div, Mul}; use std::ops::{Div, Mul};
// TODO : split into multiple files
#[derive(thiserror::Error, Debug)] #[derive(thiserror::Error, Debug)]
enum LibVirtStructError { enum LibVirtStructError {
#[error("StructureExtractionError: {0}")] #[error("StructureExtractionError: {0}")]
@ -26,6 +28,8 @@ enum LibVirtStructError {
DomainExtraction(String), DomainExtraction(String),
#[error("MBConvertError: {0}")] #[error("MBConvertError: {0}")]
MBConvert(String), MBConvert(String),
#[error("ParseFilteringChain: {0}")]
ParseFilteringChain(String),
} }
#[derive(serde::Serialize)] #[derive(serde::Serialize)]
@ -700,7 +704,8 @@ impl NetworkInfo {
} }
} }
pub enum NetworkFilterChain { #[derive(serde::Serialize, serde::Deserialize, Debug, Copy, Clone)]
pub enum NetworkFilterChainProtocol {
Root, Root,
Mac, Mac,
STP, STP,
@ -711,7 +716,75 @@ pub enum NetworkFilterChain {
IPv6, IPv6,
} }
impl NetworkFilterChainProtocol {
pub fn from_xml(xml: &str) -> anyhow::Result<Self> {
Ok(match xml {
"root" => Self::Root,
"mac" => Self::Mac,
"stp" => Self::STP,
"vlan" => Self::VLAN,
"arp" => Self::ARP,
"rarp" => Self::RARP,
"ipv4" => Self::IPv4,
"ipv6" => Self::IPv6,
_ => {
return Err(LibVirtStructError::ParseFilteringChain(format!(
"Unknown filtering chain: {xml}! "
))
.into())
}
})
}
pub fn to_xml(&self) -> String {
match self {
Self::Root => "root",
Self::Mac => "mac",
Self::STP => "stp",
Self::VLAN => "vlan",
Self::ARP => "arp",
Self::RARP => "rarp",
Self::IPv4 => "ipv4",
Self::IPv6 => "ipv6",
}
.to_string()
}
}
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
pub struct NetworkFilterChain {
protocol: NetworkFilterChainProtocol,
suffix: Option<String>,
}
impl NetworkFilterChain {
pub fn from_xml(xml: &str) -> anyhow::Result<Option<Self>> {
if xml.is_empty() {
return Ok(None);
}
Ok(Some(match xml.split_once('-') {
None => Self {
protocol: NetworkFilterChainProtocol::from_xml(xml)?,
suffix: None,
},
Some((prefix, suffix)) => Self {
protocol: NetworkFilterChainProtocol::from_xml(prefix)?,
suffix: Some(suffix.to_string()),
},
}))
}
pub fn to_xml(&self) -> String {
match &self.suffix {
None => self.protocol.to_xml(),
Some(s) => format!("{}-{s}", self.protocol.to_xml()),
}
}
}
/// Network filter definition /// Network filter definition
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
pub struct NetworkFilter { pub struct NetworkFilter {
name: String, name: String,
chain: Option<NetworkFilterChain>, chain: Option<NetworkFilterChain>,
@ -722,6 +795,24 @@ pub struct NetworkFilter {
rules: Vec<NetworkFilterRule>, rules: Vec<NetworkFilterRule>,
} }
impl NetworkFilter {
pub fn from_xml(xml: NetworkFilterXML) -> anyhow::Result<Self> {
Ok(Self {
name: xml.name,
uuid: xml.uuid,
chain: NetworkFilterChain::from_xml(&xml.chain)?,
priority: xml.priority,
join_rules: xml
.filterrefs
.iter()
.map(|i| i.filter.to_string())
.collect(),
rules: vec![], // TODO !
})
}
}
#[derive(serde::Serialize, serde::Deserialize, Debug, Copy, Clone)]
pub enum NetworkFilterAction { pub enum NetworkFilterAction {
/// matching the rule silently discards the packet with no further analysis /// matching the rule silently discards the packet with no further analysis
Drop, Drop,
@ -736,12 +827,14 @@ pub enum NetworkFilterAction {
Continue, Continue,
} }
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
pub enum NetworkFilterDirection { pub enum NetworkFilterDirection {
In, In,
Out, Out,
InOut, InOut,
} }
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
pub enum Layer4State { pub enum Layer4State {
NEW, NEW,
ESTABLISHED, ESTABLISHED,
@ -750,6 +843,7 @@ pub enum Layer4State {
NONE, NONE,
} }
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
pub enum Layer4Type { pub enum Layer4Type {
TCP, TCP,
UDP, UDP,
@ -761,6 +855,20 @@ pub enum Layer4Type {
ICMPipv6, ICMPipv6,
} }
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
pub struct NetworkFilterSelectorIP<IPv> {
srcmacaddr: Option<String>,
srcmacmask: Option<String>,
dstmacaddr: Option<String>,
dstmacmask: Option<String>,
srcipaddr: Option<IPv>,
srcipmask: Option<u8>,
dstipaddr: Option<IPv>,
dstipmask: Option<u8>,
comment: Option<String>,
}
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
pub enum NetworkFilterSelector { pub enum NetworkFilterSelector {
All, All,
Mac { Mac {
@ -781,28 +889,8 @@ pub enum NetworkFilterSelector {
arpdstipmask: Option<u8>, arpdstipmask: Option<u8>,
comment: Option<String>, comment: Option<String>,
}, },
IPv4 { IPv4(NetworkFilterSelectorIP<Ipv4Addr>),
srcmacaddr: Option<String>, IPv6(NetworkFilterSelectorIP<Ipv6Addr>),
srcmacmask: Option<String>,
dstmacaddr: Option<String>,
dstmacmask: Option<String>,
srcipaddr: Option<Ipv4Addr>,
srcipmask: Option<u8>,
dstipaddr: Option<Ipv4Addr>,
dstipmask: Option<u8>,
comment: Option<String>,
},
IPv6 {
srcmacaddr: Option<String>,
srcmacmask: Option<String>,
dstmacaddr: Option<String>,
dstmacmask: Option<String>,
srcipaddr: Option<Ipv6Addr>,
srcipmask: Option<u8>,
dstipaddr: Option<Ipv6Addr>,
dstipmask: Option<u8>,
comment: Option<String>,
},
Layer4 { Layer4 {
r#type: Layer4Type, r#type: Layer4Type,
srcmacaddr: Option<String>, srcmacaddr: Option<String>,
@ -827,6 +915,7 @@ pub enum NetworkFilterSelector {
}, },
} }
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
pub struct NetworkFilterRule { pub struct NetworkFilterRule {
action: NetworkFilterAction, action: NetworkFilterAction,
direction: NetworkFilterDirection, direction: NetworkFilterDirection,