Add basic NAT structures
This commit is contained in:
2
virtweb_backend/src/nat/mod.rs
Normal file
2
virtweb_backend/src/nat/mod.rs
Normal file
@@ -0,0 +1,2 @@
|
||||
pub mod nat_definition;
|
||||
pub mod nat_lib;
|
39
virtweb_backend/src/nat/nat_definition.rs
Normal file
39
virtweb_backend/src/nat/nat_definition.rs
Normal file
@@ -0,0 +1,39 @@
|
||||
use std::net::{Ipv4Addr, Ipv6Addr};
|
||||
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
#[serde(tag = "type", rename_all = "lowercase")]
|
||||
pub enum NatSource<IPv> {
|
||||
Interface { name: String },
|
||||
Ip { ip: IPv },
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub enum NatProtocol {
|
||||
TCP,
|
||||
UDP,
|
||||
Both,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
#[serde(tag = "type", rename_all = "lowercase")]
|
||||
pub enum NatHostPort {
|
||||
Single { port: u16 },
|
||||
Range { start: u16, end: u16 },
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct Nat<IPv> {
|
||||
pub protocol: NatProtocol,
|
||||
pub host_addr: NatSource<IPv>,
|
||||
pub host_port: NatHostPort,
|
||||
pub guest_addr: IPv,
|
||||
pub guest_port: u16,
|
||||
pub comment: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Default)]
|
||||
pub struct NetNat {
|
||||
pub interface: String,
|
||||
pub ipv4: Option<Vec<Nat<Ipv4Addr>>>,
|
||||
pub ipv6: Option<Vec<Nat<Ipv6Addr>>>,
|
||||
}
|
61
virtweb_backend/src/nat/nat_lib.rs
Normal file
61
virtweb_backend/src/nat/nat_lib.rs
Normal file
@@ -0,0 +1,61 @@
|
||||
use crate::app_config::AppConfig;
|
||||
use crate::libvirt_rest_structures::net::{NetworkInfo, NetworkName};
|
||||
use crate::nat::nat_definition::NetNat;
|
||||
|
||||
#[derive(thiserror::Error, Debug)]
|
||||
enum NatLibError {
|
||||
#[error("Could not save nat definition, because network bridge name was not specified!")]
|
||||
MissingNetworkBridgeName,
|
||||
}
|
||||
|
||||
/// Save nat definition
|
||||
pub fn save_nat_def(net: &NetworkInfo) -> anyhow::Result<()> {
|
||||
let nat = match net.has_nat_def() {
|
||||
true => NetNat {
|
||||
interface: net
|
||||
.bridge_name
|
||||
.as_ref()
|
||||
.ok_or(NatLibError::MissingNetworkBridgeName)?
|
||||
.to_string(),
|
||||
ipv4: net
|
||||
.ip_v4
|
||||
.as_ref()
|
||||
.map(|i| i.nat.clone())
|
||||
.unwrap_or_default(),
|
||||
ipv6: net
|
||||
.ip_v6
|
||||
.as_ref()
|
||||
.map(|i| i.nat.clone())
|
||||
.unwrap_or_default(),
|
||||
},
|
||||
false => NetNat::default(),
|
||||
};
|
||||
|
||||
let json = serde_json::to_string(&nat)?;
|
||||
|
||||
std::fs::write(AppConfig::get().net_nat_path(&net.name), json)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Remove nat definition, if existing
|
||||
pub fn remove_nat_def(name: &NetworkName) -> anyhow::Result<()> {
|
||||
let nat_file = AppConfig::get().net_nat_path(name);
|
||||
if nat_file.exists() {
|
||||
std::fs::remove_file(nat_file)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Load nat definition, if available
|
||||
pub fn load_nat_def(name: &NetworkName) -> anyhow::Result<NetNat> {
|
||||
let nat_file = AppConfig::get().net_nat_path(name);
|
||||
if !nat_file.exists() {
|
||||
return Ok(NetNat::default());
|
||||
}
|
||||
|
||||
let file = std::fs::read_to_string(nat_file)?;
|
||||
|
||||
Ok(serde_json::from_str(&file)?)
|
||||
}
|
Reference in New Issue
Block a user