Can create network filter rules
This commit is contained in:
parent
388a1ed478
commit
81f60ce766
11
virtweb_backend/Cargo.lock
generated
11
virtweb_backend/Cargo.lock
generated
@ -1882,6 +1882,16 @@ dependencies = [
|
|||||||
"bytemuck",
|
"bytemuck",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quick-xml"
|
||||||
|
version = "0.31.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.33"
|
version = "1.0.33"
|
||||||
@ -2662,6 +2672,7 @@ dependencies = [
|
|||||||
"log",
|
"log",
|
||||||
"mime_guess",
|
"mime_guess",
|
||||||
"num",
|
"num",
|
||||||
|
"quick-xml",
|
||||||
"rand",
|
"rand",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"rust-embed",
|
"rust-embed",
|
||||||
|
@ -23,6 +23,7 @@ actix-http = "3.4.0"
|
|||||||
serde = { version = "1.0.193", features = ["derive"] }
|
serde = { version = "1.0.193", features = ["derive"] }
|
||||||
serde_json = "1.0.108"
|
serde_json = "1.0.108"
|
||||||
serde-xml-rs = "0.6.0"
|
serde-xml-rs = "0.6.0"
|
||||||
|
quick-xml = { version = "0.31.0", features = ["serialize", "overlapped-lists"] }
|
||||||
futures-util = "0.3.28"
|
futures-util = "0.3.28"
|
||||||
anyhow = "1.0.75"
|
anyhow = "1.0.75"
|
||||||
actix-multipart = "0.6.1"
|
actix-multipart = "0.6.1"
|
||||||
@ -43,4 +44,4 @@ ipnetwork = "0.20.0"
|
|||||||
num = "0.4.1"
|
num = "0.4.1"
|
||||||
rust-embed = { version = "8.1.0" }
|
rust-embed = { version = "8.1.0" }
|
||||||
mime_guess = "2.0.4"
|
mime_guess = "2.0.4"
|
||||||
dotenvy = "0.15.7"
|
dotenvy = "0.15.7"
|
||||||
|
@ -5,6 +5,7 @@ use crate::libvirt_lib_structures::nwfilter::*;
|
|||||||
use crate::libvirt_lib_structures::*;
|
use crate::libvirt_lib_structures::*;
|
||||||
use crate::libvirt_rest_structures::hypervisor::*;
|
use crate::libvirt_rest_structures::hypervisor::*;
|
||||||
use crate::libvirt_rest_structures::net::*;
|
use crate::libvirt_rest_structures::net::*;
|
||||||
|
use crate::libvirt_rest_structures::nw_filter::NetworkFilter;
|
||||||
use crate::libvirt_rest_structures::vm::*;
|
use crate::libvirt_rest_structures::vm::*;
|
||||||
use actix::{Actor, Context, Handler, Message};
|
use actix::{Actor, Context, Handler, Message};
|
||||||
use image::ImageOutputFormat;
|
use image::ImageOutputFormat;
|
||||||
@ -591,3 +592,29 @@ impl Handler<GetNWFilterXMLReq> for LibVirtActor {
|
|||||||
NetworkFilterXML::parse_xml(xml)
|
NetworkFilterXML::parse_xml(xml)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Message)]
|
||||||
|
#[rtype(result = "anyhow::Result<XMLUuid>")]
|
||||||
|
pub struct DefineNWFilterReq(pub NetworkFilter, pub NetworkFilterXML);
|
||||||
|
|
||||||
|
impl Handler<DefineNWFilterReq> for LibVirtActor {
|
||||||
|
type Result = anyhow::Result<XMLUuid>;
|
||||||
|
|
||||||
|
fn handle(&mut self, mut msg: DefineNWFilterReq, _ctx: &mut Self::Context) -> Self::Result {
|
||||||
|
let xml = msg.1.into_xml()?;
|
||||||
|
|
||||||
|
log::debug!("Define network filter:\n{}", xml);
|
||||||
|
let filter = NWFilter::define_xml(&self.m, &xml)?;
|
||||||
|
let uuid = XMLUuid::parse_from_str(&filter.get_uuid_string()?)?;
|
||||||
|
|
||||||
|
// Save a copy of the source definition
|
||||||
|
msg.0.uuid = Some(uuid);
|
||||||
|
let json = serde_json::to_string(&msg.0)?;
|
||||||
|
std::fs::write(
|
||||||
|
AppConfig::get().net_filter_definition_path(&msg.0.name),
|
||||||
|
json,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok(uuid)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use crate::libvirt_lib_structures::XMLUuid;
|
use crate::libvirt_lib_structures::XMLUuid;
|
||||||
|
use crate::libvirt_rest_structures::nw_filter::NetworkFilterName;
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use std::net::IpAddr;
|
use std::net::IpAddr;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
@ -252,6 +253,11 @@ impl AppConfig {
|
|||||||
pub fn net_definition_path(&self, name: &str) -> PathBuf {
|
pub fn net_definition_path(&self, name: &str) -> PathBuf {
|
||||||
self.definitions_path().join(format!("net-{name}.json"))
|
self.definitions_path().join(format!("net-{name}.json"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn net_filter_definition_path(&self, name: &NetworkFilterName) -> PathBuf {
|
||||||
|
self.definitions_path()
|
||||||
|
.join(format!("nwfilter-{}.json", name.0))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, serde::Serialize)]
|
#[derive(Debug, Clone, serde::Serialize)]
|
||||||
|
@ -25,9 +25,6 @@ pub async fn create(client: LibVirtReq, req: web::Json<NetworkFilter>) -> HttpRe
|
|||||||
.json("Builtin network filter rules shall not be modified!"));
|
.json("Builtin network filter rules shall not be modified!"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO : remove
|
|
||||||
return Ok(HttpResponse::Ok().json(network));
|
|
||||||
|
|
||||||
let uid = match client.update_network_filter(req.0, network).await {
|
let uid = match client.update_network_filter(req.0, network).await {
|
||||||
Ok(u) => u,
|
Ok(u) => u,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
@ -190,10 +190,11 @@ impl LibVirtClient {
|
|||||||
/// Update the information about a single domain
|
/// Update the information about a single domain
|
||||||
pub async fn update_network_filter(
|
pub async fn update_network_filter(
|
||||||
&self,
|
&self,
|
||||||
_vm_def: NetworkFilter,
|
nwf_def: NetworkFilter,
|
||||||
xml: NetworkFilterXML,
|
xml: NetworkFilterXML,
|
||||||
) -> anyhow::Result<XMLUuid> {
|
) -> anyhow::Result<XMLUuid> {
|
||||||
println!("nwfilter xml to update: {:#?}", xml);
|
self.0
|
||||||
todo!()
|
.send(libvirt_actor::DefineNWFilterReq(nwf_def, xml))
|
||||||
|
.await?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ use std::net::{Ipv4Addr, Ipv6Addr};
|
|||||||
#[derive(serde::Serialize, serde::Deserialize, Debug)]
|
#[derive(serde::Serialize, serde::Deserialize, Debug)]
|
||||||
#[serde(rename = "filterref")]
|
#[serde(rename = "filterref")]
|
||||||
pub struct NetworkFilterRefXML {
|
pub struct NetworkFilterRefXML {
|
||||||
#[serde(rename(serialize = "@filter"))]
|
#[serde(rename = "@filter")]
|
||||||
pub filter: String,
|
pub filter: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -16,225 +16,114 @@ pub struct NetworkFilterRuleProtocolAll {}
|
|||||||
#[derive(serde::Serialize, serde::Deserialize, Debug)]
|
#[derive(serde::Serialize, serde::Deserialize, Debug)]
|
||||||
#[serde(rename = "mac")]
|
#[serde(rename = "mac")]
|
||||||
pub struct NetworkFilterRuleProtocolMac {
|
pub struct NetworkFilterRuleProtocolMac {
|
||||||
#[serde(
|
#[serde(rename = "@srcmacaddr", skip_serializing_if = "Option::is_none")]
|
||||||
rename(serialize = "@srcmacaddr"),
|
|
||||||
skip_serializing_if = "Option::is_none"
|
|
||||||
)]
|
|
||||||
pub srcmacaddr: Option<String>,
|
pub srcmacaddr: Option<String>,
|
||||||
#[serde(
|
#[serde(rename = "@scmacmask", skip_serializing_if = "Option::is_none")]
|
||||||
rename(serialize = "@srcmacmask"),
|
|
||||||
skip_serializing_if = "Option::is_none"
|
|
||||||
)]
|
|
||||||
pub srcmacmask: Option<String>,
|
pub srcmacmask: Option<String>,
|
||||||
#[serde(
|
#[serde(rename = "@dstmacaddr", skip_serializing_if = "Option::is_none")]
|
||||||
rename(serialize = "@dstmacaddr"),
|
|
||||||
skip_serializing_if = "Option::is_none"
|
|
||||||
)]
|
|
||||||
pub dstmacaddr: Option<String>,
|
pub dstmacaddr: Option<String>,
|
||||||
#[serde(
|
#[serde(rename = "@dstmacmask", skip_serializing_if = "Option::is_none")]
|
||||||
rename(serialize = "@dstmacmask"),
|
|
||||||
skip_serializing_if = "Option::is_none"
|
|
||||||
)]
|
|
||||||
pub dstmacmask: Option<String>,
|
pub dstmacmask: Option<String>,
|
||||||
#[serde(
|
#[serde(rename = "@comment", skip_serializing_if = "Option::is_none")]
|
||||||
rename(serialize = "@comment"),
|
|
||||||
skip_serializing_if = "Option::is_none"
|
|
||||||
)]
|
|
||||||
pub comment: Option<String>,
|
pub comment: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(serde::Serialize, serde::Deserialize, Debug)]
|
#[derive(serde::Serialize, serde::Deserialize, Debug)]
|
||||||
#[serde(rename = "arp")]
|
#[serde(rename = "arp")]
|
||||||
pub struct NetworkFilterRuleProtocolArpXML {
|
pub struct NetworkFilterRuleProtocolArpXML {
|
||||||
#[serde(
|
#[serde(rename = "@srcmacaddr", skip_serializing_if = "Option::is_none")]
|
||||||
rename(serialize = "@srcmacaddr"),
|
|
||||||
skip_serializing_if = "Option::is_none"
|
|
||||||
)]
|
|
||||||
pub srcmacaddr: Option<String>,
|
pub srcmacaddr: Option<String>,
|
||||||
#[serde(
|
#[serde(rename = "@srcmacmask", skip_serializing_if = "Option::is_none")]
|
||||||
rename(serialize = "@srcmacmask"),
|
|
||||||
skip_serializing_if = "Option::is_none"
|
|
||||||
)]
|
|
||||||
pub srcmacmask: Option<String>,
|
pub srcmacmask: Option<String>,
|
||||||
#[serde(
|
#[serde(rename = "@dstmacaddr", skip_serializing_if = "Option::is_none")]
|
||||||
rename(serialize = "@dstmacaddr"),
|
|
||||||
skip_serializing_if = "Option::is_none"
|
|
||||||
)]
|
|
||||||
pub dstmacaddr: Option<String>,
|
pub dstmacaddr: Option<String>,
|
||||||
#[serde(
|
#[serde(rename = "@dstmacmask", skip_serializing_if = "Option::is_none")]
|
||||||
rename(serialize = "@dstmacmask"),
|
|
||||||
skip_serializing_if = "Option::is_none"
|
|
||||||
)]
|
|
||||||
pub dstmacmask: Option<String>,
|
pub dstmacmask: Option<String>,
|
||||||
#[serde(
|
#[serde(rename = "@arpsrcipaddr", skip_serializing_if = "Option::is_none")]
|
||||||
rename(serialize = "@arpsrcipaddr"),
|
|
||||||
skip_serializing_if = "Option::is_none"
|
|
||||||
)]
|
|
||||||
pub arpsrcipaddr: Option<String>,
|
pub arpsrcipaddr: Option<String>,
|
||||||
#[serde(
|
#[serde(rename = "@arpsrcipmask", skip_serializing_if = "Option::is_none")]
|
||||||
rename(serialize = "@arpsrcipmask"),
|
|
||||||
skip_serializing_if = "Option::is_none"
|
|
||||||
)]
|
|
||||||
pub arpsrcipmask: Option<u8>,
|
pub arpsrcipmask: Option<u8>,
|
||||||
#[serde(
|
#[serde(rename = "@arpdstipaddr", skip_serializing_if = "Option::is_none")]
|
||||||
rename(serialize = "@arpdstipaddr"),
|
|
||||||
skip_serializing_if = "Option::is_none"
|
|
||||||
)]
|
|
||||||
pub arpdstipaddr: Option<String>,
|
pub arpdstipaddr: Option<String>,
|
||||||
#[serde(
|
#[serde(rename = "@arpdstipmask", skip_serializing_if = "Option::is_none")]
|
||||||
rename(serialize = "@arpdstipmask"),
|
|
||||||
skip_serializing_if = "Option::is_none"
|
|
||||||
)]
|
|
||||||
pub arpdstipmask: Option<u8>,
|
pub arpdstipmask: Option<u8>,
|
||||||
|
|
||||||
#[serde(
|
#[serde(rename = "@comment", skip_serializing_if = "Option::is_none")]
|
||||||
rename(serialize = "@comment"),
|
|
||||||
skip_serializing_if = "Option::is_none"
|
|
||||||
)]
|
|
||||||
pub comment: Option<String>,
|
pub comment: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(serde::Serialize, serde::Deserialize, Debug)]
|
#[derive(serde::Serialize, serde::Deserialize, Debug)]
|
||||||
#[serde(rename = "ipvx")]
|
#[serde(rename = "ipvx")]
|
||||||
pub struct NetworkFilterRuleProtocolIpvx {
|
pub struct NetworkFilterRuleProtocolIpvx {
|
||||||
#[serde(
|
#[serde(rename = "@srcmacaddr", skip_serializing_if = "Option::is_none")]
|
||||||
rename(serialize = "@srcmacaddr"),
|
|
||||||
skip_serializing_if = "Option::is_none"
|
|
||||||
)]
|
|
||||||
pub srcmacaddr: Option<String>,
|
pub srcmacaddr: Option<String>,
|
||||||
#[serde(
|
#[serde(rename = "@srcmacmask", skip_serializing_if = "Option::is_none")]
|
||||||
rename(serialize = "@srcmacmask"),
|
|
||||||
skip_serializing_if = "Option::is_none"
|
|
||||||
)]
|
|
||||||
pub srcmacmask: Option<String>,
|
pub srcmacmask: Option<String>,
|
||||||
#[serde(
|
#[serde(rename = "@dstmacaddr", skip_serializing_if = "Option::is_none")]
|
||||||
rename(serialize = "@dstmacaddr"),
|
|
||||||
skip_serializing_if = "Option::is_none"
|
|
||||||
)]
|
|
||||||
pub dstmacaddr: Option<String>,
|
pub dstmacaddr: Option<String>,
|
||||||
#[serde(
|
#[serde(rename = "@dstmacmask", skip_serializing_if = "Option::is_none")]
|
||||||
rename(serialize = "@dstmacmask"),
|
|
||||||
skip_serializing_if = "Option::is_none"
|
|
||||||
)]
|
|
||||||
pub dstmacmask: Option<String>,
|
pub dstmacmask: Option<String>,
|
||||||
#[serde(
|
#[serde(rename = "@srcipaddr", skip_serializing_if = "Option::is_none")]
|
||||||
rename(serialize = "@srcipaddr"),
|
|
||||||
skip_serializing_if = "Option::is_none"
|
|
||||||
)]
|
|
||||||
pub srcipaddr: Option<String>,
|
pub srcipaddr: Option<String>,
|
||||||
#[serde(
|
#[serde(rename = "@srcipmask", skip_serializing_if = "Option::is_none")]
|
||||||
rename(serialize = "@srcipmask"),
|
|
||||||
skip_serializing_if = "Option::is_none"
|
|
||||||
)]
|
|
||||||
pub srcipmask: Option<u8>,
|
pub srcipmask: Option<u8>,
|
||||||
#[serde(
|
#[serde(rename = "@dstipaddr", skip_serializing_if = "Option::is_none")]
|
||||||
rename(serialize = "@dstipaddr"),
|
|
||||||
skip_serializing_if = "Option::is_none"
|
|
||||||
)]
|
|
||||||
pub dstipaddr: Option<String>,
|
pub dstipaddr: Option<String>,
|
||||||
#[serde(
|
#[serde(rename = "@dstipmask", skip_serializing_if = "Option::is_none")]
|
||||||
rename(serialize = "@dstipmask"),
|
|
||||||
skip_serializing_if = "Option::is_none"
|
|
||||||
)]
|
|
||||||
pub dstipmask: Option<u8>,
|
pub dstipmask: Option<u8>,
|
||||||
|
|
||||||
#[serde(
|
#[serde(rename = "@comment", skip_serializing_if = "Option::is_none")]
|
||||||
rename(serialize = "@comment"),
|
|
||||||
skip_serializing_if = "Option::is_none"
|
|
||||||
)]
|
|
||||||
pub comment: Option<String>,
|
pub comment: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(serde::Serialize, serde::Deserialize, Debug)]
|
#[derive(serde::Serialize, serde::Deserialize, Debug)]
|
||||||
#[serde(rename = "layer4")]
|
#[serde(rename = "layer4")]
|
||||||
pub struct NetworkFilterRuleProtocolLayer4<IPv> {
|
pub struct NetworkFilterRuleProtocolLayer4<IPv> {
|
||||||
#[serde(
|
#[serde(rename = "@srcmacaddr", skip_serializing_if = "Option::is_none")]
|
||||||
rename(serialize = "@srcmacaddr"),
|
|
||||||
skip_serializing_if = "Option::is_none"
|
|
||||||
)]
|
|
||||||
pub srcmacaddr: Option<String>,
|
pub srcmacaddr: Option<String>,
|
||||||
#[serde(
|
#[serde(rename = "@srcipaddr", skip_serializing_if = "Option::is_none")]
|
||||||
rename(serialize = "@srcipaddr"),
|
|
||||||
skip_serializing_if = "Option::is_none"
|
|
||||||
)]
|
|
||||||
pub srcipaddr: Option<IPv>,
|
pub srcipaddr: Option<IPv>,
|
||||||
#[serde(
|
#[serde(rename = "@srcipmask", skip_serializing_if = "Option::is_none")]
|
||||||
rename(serialize = "@srcipmask"),
|
|
||||||
skip_serializing_if = "Option::is_none"
|
|
||||||
)]
|
|
||||||
pub srcipmask: Option<u8>,
|
pub srcipmask: Option<u8>,
|
||||||
#[serde(
|
#[serde(rename = "@dstipaddr", skip_serializing_if = "Option::is_none")]
|
||||||
rename(serialize = "@dstipaddr"),
|
|
||||||
skip_serializing_if = "Option::is_none"
|
|
||||||
)]
|
|
||||||
pub dstipaddr: Option<IPv>,
|
pub dstipaddr: Option<IPv>,
|
||||||
#[serde(
|
#[serde(rename = "@dstipmask", skip_serializing_if = "Option::is_none")]
|
||||||
rename(serialize = "@dstipmask"),
|
|
||||||
skip_serializing_if = "Option::is_none"
|
|
||||||
)]
|
|
||||||
pub dstipmask: Option<u8>,
|
pub dstipmask: Option<u8>,
|
||||||
/// Start of range of source IP address
|
/// Start of range of source IP address
|
||||||
#[serde(
|
#[serde(rename = "@srcipfrom", skip_serializing_if = "Option::is_none")]
|
||||||
rename(serialize = "@srcipfrom"),
|
|
||||||
skip_serializing_if = "Option::is_none"
|
|
||||||
)]
|
|
||||||
pub srcipfrom: Option<IPv>,
|
pub srcipfrom: Option<IPv>,
|
||||||
/// End of range of source IP address
|
/// End of range of source IP address
|
||||||
#[serde(
|
#[serde(rename = "@srcipto", skip_serializing_if = "Option::is_none")]
|
||||||
rename(serialize = "@srcipto"),
|
|
||||||
skip_serializing_if = "Option::is_none"
|
|
||||||
)]
|
|
||||||
pub srcipto: Option<IPv>,
|
pub srcipto: Option<IPv>,
|
||||||
/// Start of range of destination IP address
|
/// Start of range of destination IP address
|
||||||
#[serde(
|
#[serde(rename = "@dstipfrom", skip_serializing_if = "Option::is_none")]
|
||||||
rename(serialize = "@dstipfrom"),
|
|
||||||
skip_serializing_if = "Option::is_none"
|
|
||||||
)]
|
|
||||||
pub dstipfrom: Option<IPv>,
|
pub dstipfrom: Option<IPv>,
|
||||||
/// End of range of destination IP address
|
/// End of range of destination IP address
|
||||||
#[serde(
|
#[serde(rename = "@dstipto", skip_serializing_if = "Option::is_none")]
|
||||||
rename(serialize = "@dstipto"),
|
|
||||||
skip_serializing_if = "Option::is_none"
|
|
||||||
)]
|
|
||||||
pub dstipto: Option<IPv>,
|
pub dstipto: Option<IPv>,
|
||||||
#[serde(
|
#[serde(rename = "@srcportstart", skip_serializing_if = "Option::is_none")]
|
||||||
rename(serialize = "@srcportstart"),
|
|
||||||
skip_serializing_if = "Option::is_none"
|
|
||||||
)]
|
|
||||||
pub srcportstart: Option<u16>,
|
pub srcportstart: Option<u16>,
|
||||||
#[serde(
|
#[serde(rename = "@srcportend", skip_serializing_if = "Option::is_none")]
|
||||||
rename(serialize = "@srcportend"),
|
|
||||||
skip_serializing_if = "Option::is_none"
|
|
||||||
)]
|
|
||||||
pub srcportend: Option<u16>,
|
pub srcportend: Option<u16>,
|
||||||
#[serde(
|
#[serde(rename = "@dstportstart", skip_serializing_if = "Option::is_none")]
|
||||||
rename(serialize = "@dstportstart"),
|
|
||||||
skip_serializing_if = "Option::is_none"
|
|
||||||
)]
|
|
||||||
pub dstportstart: Option<u16>,
|
pub dstportstart: Option<u16>,
|
||||||
#[serde(
|
#[serde(rename = "@dstportend", skip_serializing_if = "Option::is_none")]
|
||||||
rename(serialize = "@dstportend"),
|
|
||||||
skip_serializing_if = "Option::is_none"
|
|
||||||
)]
|
|
||||||
pub dstportend: Option<u16>,
|
pub dstportend: Option<u16>,
|
||||||
#[serde(rename(serialize = "@state"), skip_serializing_if = "Option::is_none")]
|
#[serde(rename = "@state", skip_serializing_if = "Option::is_none")]
|
||||||
pub state: Option<String>,
|
pub state: Option<String>,
|
||||||
|
|
||||||
#[serde(
|
#[serde(rename = "@comment", skip_serializing_if = "Option::is_none")]
|
||||||
rename(serialize = "@comment"),
|
|
||||||
skip_serializing_if = "Option::is_none"
|
|
||||||
)]
|
|
||||||
pub comment: Option<String>,
|
pub comment: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Default)]
|
#[derive(serde::Serialize, serde::Deserialize, Debug, Default)]
|
||||||
#[serde(rename = "rule")]
|
#[serde(rename = "rule")]
|
||||||
pub struct NetworkFilterRuleXML {
|
pub struct NetworkFilterRuleXML {
|
||||||
#[serde(rename(serialize = "@action"))]
|
#[serde(rename = "@action")]
|
||||||
pub action: String,
|
pub action: String,
|
||||||
#[serde(rename(serialize = "@direction"))]
|
#[serde(rename = "@direction")]
|
||||||
pub direction: String,
|
pub direction: String,
|
||||||
#[serde(rename(serialize = "@priority"))]
|
#[serde(rename = "@priority")]
|
||||||
pub priority: Option<i32>,
|
pub priority: Option<i32>,
|
||||||
|
|
||||||
/// Match all protocols
|
/// Match all protocols
|
||||||
@ -297,23 +186,15 @@ pub struct NetworkFilterRuleXML {
|
|||||||
#[derive(serde::Serialize, serde::Deserialize, Debug)]
|
#[derive(serde::Serialize, serde::Deserialize, Debug)]
|
||||||
#[serde(rename = "filter")]
|
#[serde(rename = "filter")]
|
||||||
pub struct NetworkFilterXML {
|
pub struct NetworkFilterXML {
|
||||||
#[serde(rename(serialize = "@name"))]
|
#[serde(rename = "@name")]
|
||||||
pub name: String,
|
pub name: String,
|
||||||
#[serde(
|
#[serde(rename = "@chain", skip_serializing_if = "Option::is_none", default)]
|
||||||
rename(serialize = "@chain"),
|
|
||||||
skip_serializing_if = "Option::is_none",
|
|
||||||
default
|
|
||||||
)]
|
|
||||||
pub chain: Option<String>,
|
pub chain: Option<String>,
|
||||||
#[serde(
|
#[serde(skip_serializing_if = "Option::is_none", rename = "@priority", default)]
|
||||||
skip_serializing_if = "Option::is_none",
|
|
||||||
rename(serialize = "@priority"),
|
|
||||||
default
|
|
||||||
)]
|
|
||||||
pub priority: Option<i32>,
|
pub priority: Option<i32>,
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub uuid: Option<XMLUuid>,
|
pub uuid: Option<XMLUuid>,
|
||||||
#[serde(default, rename = "filterref", skip_serializing_if = "Vec::is_empty")]
|
#[serde(default, rename = "filterref")]
|
||||||
pub filterrefs: Vec<NetworkFilterRefXML>,
|
pub filterrefs: Vec<NetworkFilterRefXML>,
|
||||||
#[serde(default, rename = "rule", skip_serializing_if = "Vec::is_empty")]
|
#[serde(default, rename = "rule", skip_serializing_if = "Vec::is_empty")]
|
||||||
pub rules: Vec<NetworkFilterRuleXML>,
|
pub rules: Vec<NetworkFilterRuleXML>,
|
||||||
@ -321,24 +202,10 @@ pub struct NetworkFilterXML {
|
|||||||
|
|
||||||
impl NetworkFilterXML {
|
impl NetworkFilterXML {
|
||||||
pub fn parse_xml<D: Display>(xml: D) -> anyhow::Result<Self> {
|
pub fn parse_xml<D: Display>(xml: D) -> anyhow::Result<Self> {
|
||||||
let xml = xml.to_string();
|
Ok(quick_xml::de::from_str(&xml.to_string())?)
|
||||||
|
}
|
||||||
|
|
||||||
// We need to put all filter refs at the same location
|
pub fn into_xml(self) -> anyhow::Result<String> {
|
||||||
let mut filter_refs = Vec::new();
|
Ok(quick_xml::se::to_string(&self)?)
|
||||||
let xml = lazy_regex::regex_replace_all!(r#"<filterref.*/>"#, &xml, |r: &str| {
|
|
||||||
filter_refs.push(r.to_string());
|
|
||||||
|
|
||||||
if r.contains('\n') {
|
|
||||||
log::warn!("A filterref contain a new line. This is a symptom of a new unsupported child attribute of <filterref /> object!");
|
|
||||||
}
|
|
||||||
|
|
||||||
""
|
|
||||||
});
|
|
||||||
|
|
||||||
let filter_refs = filter_refs.join("\n");
|
|
||||||
let xml = xml.replace("</filter>", &format!("{filter_refs}</filter>"));
|
|
||||||
log::debug!("Effective NW filter rule parsed: {xml}");
|
|
||||||
|
|
||||||
Ok(serde_xml_rs::from_str(&xml)?)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -400,10 +400,10 @@ pub struct NetworkFilterRule {
|
|||||||
/// Network filter definition
|
/// Network filter definition
|
||||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
|
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
|
||||||
pub struct NetworkFilter {
|
pub struct NetworkFilter {
|
||||||
name: NetworkFilterName,
|
pub name: NetworkFilterName,
|
||||||
chain: Option<NetworkFilterChain>,
|
chain: Option<NetworkFilterChain>,
|
||||||
priority: Option<i32>,
|
priority: Option<i32>,
|
||||||
uuid: Option<XMLUuid>,
|
pub uuid: Option<XMLUuid>,
|
||||||
/// Referenced filters rules
|
/// Referenced filters rules
|
||||||
join_filters: Vec<NetworkFilterName>,
|
join_filters: Vec<NetworkFilterName>,
|
||||||
rules: Vec<NetworkFilterRule>,
|
rules: Vec<NetworkFilterRule>,
|
||||||
|
Loading…
Reference in New Issue
Block a user